| The Hobbit (v1.0) | Routines |
| Prev: 9769 | Up: Map | Next: 9873 |
|
This is The Hobbit's famous 'independent characters' system. Every character in the table at C9BA gets a turn after the player.
Each entry of that table is 7 bytes: the character's object number (0 if the character is dead or gone), a count used by 99B4, the address of the character's current place in its behaviour program, the address of its reaction table, and a 'stubbornness' value used by 8F9E.
For each living character, the character becomes the current actor (B5DB, $B5FC) and the room it starts the turn in is noted ($B5E7). Output is switched on only if Bilbo can see the character (9D77), so the player sees only what happens in front of him. If Bilbo is in the dark, the first character to do anything in his room produces 'you hear a noise.' instead (AF19).
A character that is inside something (held by an object rather than standing in a room) tries to get out first (9A71).
Then the character's behaviour program is run. Each instruction starts with a byte whose low nibble is its type and whose high bits are flags: bit 4 'jump afterwards to the address that follows', bit 5 'do this only once' (the instruction is cleared to 0 after use), bit 6 'do not take orders at this point'. The types are:
Before the program, if the player has given the character an order (88FD) and the current instruction allows it (bit 6 clear), the order is obeyed instead (8907, 9929).
A character stops after 6 instructions in one turn (9769). At the end the player becomes the actor again, with output switched on.
|
||||
| 976C | CALL $9A5D | Note Bilbo's room and whether he is in the dark | ||
| 976F | LD IY,$C9BA | IY = the first entry of the character table | ||
| 9773 | XOR A | Reset the count of instructions tried by this character | ||
| 9774 | LD ($9769),A | |||
| 9777 | LD A,(IY+$00) | A = the character's object number | ||
| 977A | CP $FF | End of the table? | ||
| 977C | JP Z,$9864 | Yes: all done | ||
| 977F | CP $00 | 0 means a dead character or an empty slot | ||
| 9781 | JP Z,$985C | Skip it | ||
| 9784 | LD ($B5DB),A | Make the character the current actor | ||
| 9787 | CALL $9ECB | A = its room, IX = its record | ||
| 978A | LD ($B5FC),IX | Its record is the actor's record... | ||
| 978E | LD ($B5E7),A | ...and its room is the room it starts the turn in | ||
| 9791 | SUB A | Switch output off until we know Bilbo can see | ||
| 9792 | LD ($B5F3),A | |||
| 9795 | PUSH IY | |||
| 9797 | LD IY,$C00B | IY = Bilbo's record | ||
| 979B | CALL $9D77 | Can Bilbo see the character? | ||
| 979E | POP IY | |||
| 97A0 | JR Z,$97C3 | No: its actions will not be printed | ||
| 97A2 | LD A,($976A) | Has "you hear a noise" already been printed this turn? | ||
| 97A5 | CP $02 | |||
| 97A7 | JR Z,$97C3 | Yes: keep quiet | ||
| 97A9 | LD A,$01 | Output on: Bilbo can see what the character does | ||
| 97AB | LD ($B5F3),A | |||
| 97AE | LD A,($976A) | Is Bilbo in the dark ($976A = 1)? | ||
| 97B1 | CP $01 | |||
| 97B3 | JR NZ,$97C3 | No: carry on | ||
| 97B5 | INC A | Yes: remember that the noise has been heard ($976A = 2) | ||
| 97B6 | LD ($976A),A | |||
| 97B9 | LD HL,$AF19 | "you hear a noise." | ||
| 97BC | CALL $72D4 | |||
| 97BF | SUB A | And switch output off: Bilbo sees nothing | ||
| 97C0 | LD ($B5F3),A | |||
| 97C3 | LD A,$FF | Is the character held by something? | ||
| 97C5 | CP (IX+$01) | |||
| 97C8 | JP NZ,$9A71 | Yes: try to get out instead (9A71) | ||
|
This entry point is used by the routine at 9A71.
|
||||
| 97CB | LD IX,($B5FC) | IX = the character's record | ||
| 97CF | CALL $88FD | Has the player given it an order? | ||
| 97D2 | LD A,$00 | $B5E5 = 1 if so, 0 if not | ||
| 97D4 | JR NZ,$97D7 | |||
| 97D6 | INC A | |||
| 97D7 | LD ($B5E5),A | |||
|
This entry point is used by the routine at 98CF.
|
||||
| 97DA | LD L,(IY+$02) | HL = where the character has got to in its behaviour program | ||
| 97DD | LD H,(IY+$03) | |||
|
This entry point is used by the routine at 98CF.
|
||||
| 97E0 | LD A,($9769) | Has the character already tried six instructions this turn? | ||
| 97E3 | CP $06 | |||
| 97E5 | JR Z,$985C | Yes: that is enough, next character | ||
| 97E7 | LD A,(HL) | A = the instruction byte | ||
| 97E8 | LD DE,$0004 | DE = 4, the length of an action instruction | ||
| 97EB | PUSH HL | IX = the instruction | ||
| 97EC | POP IX | |||
| 97EE | AND $0F | The low nibble is the instruction type | ||
| 97F0 | CP $05 | Types 0-4 are actions | ||
| 97F2 | JR NC,$9826 | Types 5 and up: go and decode them | ||
| 97F4 | LD A,($B5E5) | An action instruction. Is an order from the player waiting? | ||
| 97F7 | CP $01 | |||
| 97F9 | JR NZ,$981A | No: carry out the program | ||
| 97FB | BIT 6,(HL) | Does this instruction refuse orders (bit 6)? | ||
| 97FD | JR NZ,$981A | Yes: carry out the program | ||
| 97FF | SUB A | The order is being dealt with now | ||
| 9800 | LD ($B5E5),A | |||
| 9803 | INC A | |||
| 9804 | CALL $8907 | Match the order to an action and objects | ||
| 9807 | JR Z,$981A | It cannot be done: carry on with the program instead | ||
| 9809 | LD A,$01 | The order will be obeyed for real | ||
| 980B | LD ($B5EB),A | |||
| 980E | LD ($B5EC),A | |||
| 9811 | LD HL,$985C | Arrange to go on to the next character afterwards | ||
| 9814 | PUSH HL | |||
| 9815 | PUSH IX | |||
| 9817 | JP $9929 | Do it (9921), then return to 985C | ||
| 981A | LD A,(HL) | Fetch the instruction type again | ||
| 981B | AND $0F | |||
| 981D | CP $04 | Type 4: an action without objects | ||
| 981F | JP Z,$98CF | |||
| 9822 | JR C,$9883 | Types 0-3: an action with objects, or a routine | ||
| 9824 | JR $985C | (Not reached) | ||
| 9826 | CP $0E | Type $0E: go to | ||
| 9828 | JR NZ,$9838 | |||
| 982A | LD E,(IX+$01) | Store the address that follows as the new program position | ||
| 982D | LD (IY+$02),E | |||
| 9830 | LD E,(IX+$02) | |||
| 9833 | LD (IY+$03),E | |||
| 9836 | JR $97DA | And carry on from there, in the same turn | ||
| 9838 | CP $0C | Type $0C: change behaviour on a named action | ||
| 983A | JR NZ,$9847 | |||
| 983C | LD B,(IX+$01) | B = the action | ||
| 983F | LD A,(IY+$00) | A = this character | ||
| 9842 | CALL $99FB | Switch to its reaction for that action | ||
| 9845 | JR $97DA | Carry on | ||
| 9847 | CP $0F | Type $0F: pick a behaviour at random | ||
| 9849 | JR NZ,$9850 | |||
| 984B | CALL $99B4 | |||
| 984E | JR $97DA | Carry on | ||
| 9850 | CP $00 | Type 0 would skip the instruction here, but types below 5 never get this far | ||
| 9852 | JR NZ,$9857 | |||
| 9854 | ADD HL,DE | |||
| 9855 | JR $97E0 | |||
| 9857 | SUB A | Any other type: return to the default behaviour (reaction table entry 0)... | ||
| 9858 | LD E,A | |||
| 9859 | CALL $99C3 | ...and end this character's turn | ||
| 985C | LD DE,$0007 | Next character: entries are 7 bytes long | ||
| 985F | ADD IY,DE | |||
| 9861 | JP $9773 | |||
| 9864 | SUB A | All characters done: Bilbo is the actor again | ||
| 9865 | LD ($B5DB),A | |||
| 9868 | INC A | Output back on | ||
| 9869 | LD ($B5F3),A | |||
| 986C | LD HL,$C00B | The actor's record is Bilbo's | ||
| 986F | LD ($B5FC),HL | |||
| 9872 | RET | |||
| Prev: 9769 | Up: Map | Next: 9873 |