![]() |
How the game is put together |
Pentagram is Knight Lore's engine carrying a new game. The drawing, the depth sort, the collision code, the player's movement and much of the rest are Knight Lore's, sometimes to the instruction; the rooms, the quest and everything that moves or is fired or falls are new. This page is the map of the whole: where things are, what runs when, and which parts come from where. Knight Lore's own page describes the engine as it was.
The tape's one block of code and data loads at $5E00 and runs to $D89D; the loader enters it at its first byte, with the stack just below. Everything the game keeps is laid out from there up: the level data and the sprites first, then the variables and the object records -- all zero on the tape -- and the code. Above the code are the screen buffer, which every picture is drawn into before it is copied to the screen, and tables the game builds each time it starts. The system variables are not used and the ROM is never called -- its bytes are read only as random numbers -- since the game reads the keyboard and makes its sounds itself; and it runs with interrupts off, turning them on only while paused.
| Addresses | What |
|---|---|
| $5E00-$5E06 | the entry: DI, the stack below $5E00, and a jump to START |
| $5E07-$696C | the three room sizes, then the room directory (ROOMS): 139 records, one per room |
| $696D-$6DD6 | the scenery templates and their table, then the object templates and theirs (OBJECT_TABLE) |
| $6DD7-$6F2E | the graphic table: a word per graphic number, the sprite it draws |
| $6F2F-$A708 | the sprites, end to end, with the font among them (FONT) |
| $A709-$A76E | the variables, zero on the tape |
| $A76F-$AE2E | 54 object records of 32 bytes: the player's legs and body, two bolts, two things from the sky, and 48 for the room |
| $AE2F-$AF86 | the update-routine table, a word per graphic number |
| $AF87-$D88E | the code, with its small tables among it -- the quest records (QUEST_START, copied to QUEST_RECORDS for a game), the collectables' places (SPOTS) and targets (TARGETS), the notes and the tunes |
| $D88F-$F08E | the screen buffer, bottom row first; its first bytes are the last of the tape block |
| $F100-$FFFF | tables the game builds at every start (MAKE_TABLES): bits reversed, and each byte shifted by one to seven bits |
START is four loops, one inside another. A game: the variables and records cleared, the drawing tables built, five lives, the menu, the start tune, the quest records set out afresh with the collectables put in five places chosen at random (NEW_QUEST), and one of four start rooms chosen (CHOOSE_START). A life: RESTART_PLAYER copies the player template over his two records and takes a life, and with none left it is the game over. A room: the quest things of the room he left are filed back in their records (QUEST_OUT_OF_ROOM), the room is built into the object records (ENTER_ROOM), the quest things that are in it are put in with it (QUEST_INTO_ROOM), the room is marked as one where things may or may not fall (BAN_DROPS), and the drop timer is set (RESET_DROP_TIMER). A turn: perhaps something falls (SKY_DROP), then every one of the 54 records has its update routine run, and OBJECT_DONE draws what changed and waits.
Walking through an arch jumps straight back to the room loop, dropping two return addresses from the stack by hand (EXIT_LOW_U); a death is noticed at the end of a turn, when both of his records have emptied, and goes back to the life loop.
An object record's first byte is its graphic number, and that number is both what is drawn (through the graphic table, GRAPHICS) and what runs: UPDATES has a word per graphic, the routine the main loop jumps to with IX on the record and the address of OBJECT_DONE on the stack. So an object animates, or changes its behaviour, by changing its own first byte: the bolt steps through 151, 150 and 149, a quest item goes up by four when it is done, anything that dies becomes graphic 64, the puff, and then 1, which the drawing code empties. The table, read from the snapshot, routine by routine:
| Routine | Graphics |
|---|---|
| PUFF | 64-70 |
| END_PUFF | 71 |
| BOLT | 60, 149-151 |
| STILL_DEADLY | 23, 30, 74-75 |
| NOTHING | 0-5, 18-22, 24-27, 29, 31, 58-59, 61-62, 83, 94-111 |
| PLAYER_LEGS | 32-39 |
| PLAYER_TOP | 40-47 |
| DRAW_AT_L8 | 57 |
| DRAW_AT_L8_D4 | 53-56 |
| DRAW_AT_L8_D2 | 12-15, 52 |
| SECOND_PILLAR | 7, 9 |
| FIRST_PILLAR | 6, 8 |
| JUMP_L16_D8 | 10-11, 76, 82, 152-159 |
| JUMP_L16_D12 | 77 |
| HOMER | 48-51, 160-167 |
| COLLECTABLE | 144-148 |
| SPIKES | 28 |
| HEAVY_BLOCK | 91 |
| SLIDING_TABLE | 73 |
| PUSHABLE | 63, 72, 79 |
| SINKING_BLOCK | 78 |
| LIFT | 84 |
| BOBBER | 85 |
| DEADLY_BOBBER | 86 |
| DEADLY_PACER_U | 92 |
| PACER_U | 87 |
| DEADLY_PACER_V | 93 |
| PACER_V | 88 |
| PENTAGRAM_PIECE | 121-135 |
| SPIDER | 89 |
| QUEST_ITEM | 112-119 |
| WELL | 120 |
| BUCKET | 90 |
| ROAMER | 16-17 |
| SKY_ROAMER | 80-81 |
| SKY_WALKER | 168-171 |
| CRUMBLING_BLOCK | 136-139 |
| CONVEYOR_PLUS_U | 140 |
| CONVEYOR_MINUS_U | 141 |
| CONVEYOR_PLUS_V | 142 |
| CONVEYOR_MINUS_V | 143 |
Most routines end the same way: set their own drawing offset, move through the collision code, and if anything moved, mark the object and what it overlaps to be drawn again (the end of HOMER). Scenery and anything else that never changes has NOTHING, a RET.
Every turn does the same work whatever is happening -- all 54 records are visited, empty or not -- and then OBJECT_DONE waits six units of about 33,000 T-states less the drawing the turn has done, so that a quiet room does not run faster than a busy one. A busy room, with six units of drawing or more, runs as fast as it can. Watched in the emulator, standing still for 50 turns: 123 frames in the empty room 30, with two units of waiting a turn, and 122 in the cluttered start room, with none.
RANDOM is one byte. It is stirred with the refresh register once before the menu, and after every object's turn with R, the turn counter and a byte of the ROM that the turn counter points at (OBJECT_DONE). Since R counts instructions, how long each update took feeds the next number. The start room, the collectables' places, what falls and where, and which way a spider turns all come from it.
| Part | Whose |
|---|---|
| The main loop and its pacing | Knight Lore's, with the same wait of six units less the drawing done; the stack is no longer reset for each object |
| Drawing: projection, turning sprites round in place, masking through the shift tables, wiping only what moved | Knight Lore's (how a moving object is drawn), with a clamp at the left edge of the screen added and the draw list not grown to fit (a bug) |
| The depth sort | Knight Lore's, with the same 27-entry table (depth sorting); boxes that intersect are no longer a special case |
| Collision: Z, then U, then V, a unit at a time, harm passed both ways | Knight Lore's (collision), plus conveyors, a mark on what the player stands on, and carrying for lifts |
| The player: turning, walking, jumping, the legs and the body | Knight Lore's, less the werewolf, the sounds of turning and falling, and the exit test |
| Arches | Knight Lore's shape, but the arch itself sends him on, to the room in its own record |
| Picking up and putting down | Knight Lore's queue of three, searching all 48 room records rather than Knight Lore's two |
| The menu, the text printer, the border | Knight Lore's, nearly instruction for instruction, one menu line shorter |
| The tune player and its notes | Knight Lore's, to the byte |
| The room directory and its builder | Pentagram's own: rooms of any number, doorways carrying their destinations |
| The quest records | Pentagram's own: eighteen things that remember their room and place from visit to visit |
| Firing, bolts, scoring | Pentagram's own; Knight Lore has no weapon |
| Things from the sky, homers | Pentagram's own |
| The well, the bucket, the pentagram, the collectables | Pentagram's own |
| Sound effects in play | Pentagram's own: a note a turn from a short sequence |
| Reading the controls | Pentagram's own reader; Knight Lore's keyboard routine |
The records went from Knight Lore's 40 to 54 and the code that walks them followed, but the list of what to draw did not: the bugs have what happens when room 87, the fullest, has a few things added to it. There is no day and night, no transformation, no cauldron and no clock.