![]() |
Routines |
| Prev: 7D9A | Up: Map | Next: 7E13 |
|
Used by the routines at MAIN_LOOP_MONSTERS and ENTER_ROOM.
Everything the game does happens here. It walks two tables of records and the player's room's list, and hands each record to DISPATCH_ACTOR, which finds its handler from its sprite byte; there is no other structure above this. Monsters, doors, objects, the player and even the sound effects are all just records this loop reaches.
The three are treated differently. From $EAA8 to $EE60 are eight-byte records -- objects, collectables, the drop controller -- and those are only dispatched if their room matches the player's. From $EE60 to $EEE0 are the sixteen-byte monster records, dispatched every pass whatever room they are in, which is how creatures keep moving around a castle you cannot see. The doors and furniture, sixteen-byte records from $EEE0 with a half in each of two rooms, are not walked at all: ROOM_LIST_PASS dispatches the ones the player's room's list names. On the first pass in a room the first two walks are skipped. Measured in the simulator, a pass in room $00 takes about 1.7 frames: a fifth of it this loop's own walk over the objects, with a FRAMES check between each, and a seventh INERT_SPRITE's delay in the three empty monster slots.
Two details in the first three instructions are worth more than they look. The stack pointer is reset at the top of every pass, so no handler has to leave the stack as it found it -- which is what lets LOSE_FOOD_SIXTEEN abandon its caller and jump straight to the death routine. And the EI here is where the DI at the entry point is finally lifted: everything before this runs with interrupts off.
|
||||
| MAIN_LOOP | 7DC3 | LD SP,$5E00 | Reset the stack every pass; handlers need not balance it. | |
| 7DC6 | EI | Interrupts on. This is where the DI at ENTRY is undone. | ||
| 7DC7 | XOR A | Count of actors in the player's room, recounted each pass. | ||
| 7DC8 | LD ($5E25),A | |||
| 7DCB | LD IX,$EAA8 | The first table: objects and sounds, eight bytes each. | ||
| 7DCF | LD A,($5E14) | |||
| 7DD2 | BIT 0,A | |||
| 7DD4 | JR NZ,MAIN_LOOP_0 | |||
| 7DD6 | LD IX,$EEE0 | Never used: on the first pass in a room the loop goes straight to the room list, which reloads IX. | ||
| 7DDA | JR ROOM_LIST_PASS | |||
| MAIN_LOOP_0 | 7DDC | LD A,($5C78) | ||
| 7DDF | LD C,A | |||
| 7DE0 | LD A,($5E03) | |||
| 7DE3 | CP C | |||
| 7DE4 | CALL NZ,FRAME_TICK | |||
| 7DE7 | LD A,($EA91) | Only things in the player's room are dispatched from this one. | ||
| 7DEA | CP (IX+$01) | |||
| 7DED | LD HL,NEXT_OBJECT | The return address goes in HL, and the dispatch is a jump rather than a call. | ||
| 7DF0 | JP Z,DISPATCH_ACTOR | |||
| NEXT_OBJECT | 7DF3 | LD DE,$0008 | Eight bytes to the next record. | |
| 7DF6 | ADD IX,DE | |||
| 7DF8 | PUSH IX | Until the monster table is reached. | ||
| 7DFA | POP HL | |||
| 7DFB | LD DE,$EE60 | |||
| 7DFE | AND A | |||
| 7DFF | SBC HL,DE | |||
| 7E01 | JR C,MAIN_LOOP_0 | |||
|
This entry point is used by the routine at MAIN_LOOP_MONSTERS.
|
||||
| NEXT_MONSTER | 7E03 | LD A,($5C78) | ||
| 7E06 | LD C,A | |||
| 7E07 | LD A,($5E03) | |||
| 7E0A | CP C | |||
| 7E0B | CALL NZ,FRAME_TICK | |||
| 7E0E | LD HL,MAIN_LOOP_MONSTERS | |||
| 7E11 | JR DISPATCH_ACTOR | |||
| Prev: 7D9A | Up: Map | Next: 7E13 |