| Routines

62D0: Move the characters

Used by the routine at F6B4.
62D0 | CALL $62D6 | Move one character
62D3 | CALL $62D6 | Move the next character
62D6 | LD HL,$7FFC |
62D9 | LD A,(HL) | A=number of the character last moved (0xB7-0xD1, 0xD3-0xD6)
62DA | INC A | A=number of the next character to move
62DB | CP $D2 | Is it ERIC?
62DD | JR Z,$62DA | Jump if so (we don't want to move ERIC!)
62DF | CP $D7 | Have we completed an entire cast movement cycle?
62E1 | JR C,$62E5 | Jump if not
62E3 | LD A,$B7 | Back to 0xB7 (little girl no. 1) if so
62E5 | CP $C6 | Are we dealing with little girls 1-7 or little boys 1-8?
62E7 | JR NC,$6310 | Jump if not
It's the turn of one of the little girls (0xB7-0xBD), or one of the first 8 little boys (0xBE-0xC5). But if the part of the play area currently on-screen is somewhere this character never ventures into, we skip ahead to the next suitable candidate. Specifically, the following characters are skipped depending on the value of X (the leftmost column of the skool on-screen):
X | Skip
--- | ---
X<=72 | girls 1-7 (0xB7-0xBD)
80<=X<=112 | girls 4-7 and boys 1-3 (0xBB-0xC0)
X>=120 | boys 1-8 (0xBE-0xC5)
62E9 | LD E,A | E=character number (0xB7-0xC5)
62EA | LD D,$BE | 0xBE=little boy no. 1
62EC | LD A,($7FFF) | A=leftmost column of the play area on screen
62EF | CP $50 | This is the x-coordinate of the middle of the assembly hall stage
62F1 | JR NC,$62FA | Jump if we can't see to the left of this
We are deep into the boys' skool, where no girls ever set foot.
62F3 | LD A,E | A=character number (0xB7-0xC5)
62F4 | CP D | Is this a little boy?
62F5 | JR NC,$6310 | Move him if so
62F7 | LD A,D | Otherwise bypass the little girls and skip ahead to little boy no. 1 (0xBE)
62F8 | JR $6310
The leftmost column of the play area on screen is at least 80.
62FA | CP $78 | This x-coordinate is about halfway between the tree and the gate
62FC | LD A,E | A=character number (0xB7-0xC5)
62FD | JR C,$6306 | Jump if we can't see the first half of the girls' playground
The leftmost column of the play area on screen is at least 120. Little boys 1-8 never set foot here.
62FF | CP D | Is this a little girl?
6300 | JR C,$6310 | Move her if so
6302 | LD A,$C6 | Otherwise bypass little boys 1-8 and skip ahead to little boy no. 9 (0xC6)
6304 | JR $6310
The leftmost column of the play area on screen is between 80 and 112. Little girls 4-7 and little boys 1-3 never visit these parts.
6306 | CP $BA | Is this little girl no. 1-3?
6308 | JR C,$6310 | Move her if so
630A | CP $C1 | Is this little boy no. 4-8?
630C | JR NC,$6310 | Move him if so
630E | LD A,$C1 | Otherwise bypass little girls 4-7 and little boys 1-3 and skip ahead to little boy no. 4 (0xC1)
We've now determined which character to move next. His character number is in A.
6310 | LD (HL),A | Store the number of the character to be moved next in 7FFC
6311 | LD H,A | Point HL at byte 0x1E of this character's buffer
6312 | LD L,$1E
6314 | DEC (HL) | Is it time to consider a change in walking speed?
6315 | JR NZ,$6339 | Jump if not
It's time to consider a change in walking speed. If the character is a boy or girl, decide whether they will walk or run for the next little while.
6317 | CALL $6291 | A=random number
631A | AND $1F | 0x00<=A<=0x1F
631C | ADD A,$20 | 0x20<=A<=0x3F
631E | RRA | 0x10<=A<=0x1F (and the carry flag is set if the random number was odd)
631F | LD (HL),A | Place this number into byte 0x1E of the character's buffer
6320 | SBC A,A | A=0x00 if the random number was even, 0xFF otherwise
6321 | DEC L | L=0x1D
6322 | AND $80 | A=0x00 (character will walk) or 0x80 (character will run if he's a kid)
6324 | OR (HL) | Superimpose the current contents of byte 0x1D
6325 | BIT 6,(HL) | Is this a human character (0xB7<=H<=0xD1)?
6327 | JR NZ,$632D | Jump if not
We're dealing with a human character. Bit 4 of byte 0x1D of the character's buffer is never set, but if it were, it would make the character run until the current command list routine has finished. Check bit 4 of byte 0x1D now.
6329 | BIT 4,(HL) | Bit 4 of byte 0x1D is unused and always reset
632B | JR Z,$6331 | Always make this jump
632D | OR $80 | Ensure that bit 7 of byte 0x1D is set for non-human characters
632F | JR $6337 |
6331 | BIT 5,(HL) | Is this an adult character (0xC8<=H<=0xCD)?
6333 | JR Z,$6337 | Jump if not
6335 | AND $7F | Ensure that bit 7 of byte 0x1D is reset for adult characters (to make them walk)
6337 | LD (HL),A | Restore byte 0x1D with bit 7 set (run) or reset (walk) as appropriate
6338 | INC L | L=0x1E
Now to determine whether to move the character this time round. The answer will be yes if byte 0x1E (which is decremented on each pass through this routine) is even, or bit 7 of byte 0x1D is set (indicating that the character is either running or non-human).
6339 | BIT 0,(HL) | Is the counter at byte 0x1E currently even?
633B | JR Z,$6341 | Jump if so (half the time)
633D | DEC L | L=0x1D
633E | BIT 7,(HL) | Is the character both human and not running?
6340 | RET Z | Return if so
The character shall be moved. From this point, the following steps are taken:
Step | Action
--- | ---
1 | If there is an uninterruptible subcommand routine address in bytes 0x11 and 0x12 of the character's buffer, jump to it
2 | If there is a continual subcommand routine address in bytes 0x17 and 0x18 of the character's buffer, call it (and then return to step 3)
3 | If there is an interruptible subcommand routine address in bytes 0x09 and 0x0A of the character's buffer, jump to it
4 | Restart the command list if bit 0 of byte 0x1D of the character's buffer is set (and carry on to step 5)
5 | If there is a primary command routine address in bytes 0x03 and 0x04 of the character's buffer, jump to it
6 | Remove any continual subcommand routine address from bytes 0x17 and 0x18 of the character's buffer
7 | Collect the next primary command routine address from the command list, place it into bytes 0x03 and 0x04 of the character's buffer, and jump to it
The address of one of the following uninterruptible subcommand routines (or an entry point thereof) may be present in bytes 0x11 and 0x12 of the character's buffer:
Address | Description
--- | ---
5F08 | Make HAYLEY hit ERIC
6670 | Deal with a character who's been dethroned (1)
667F | Deal with a character who's been dethroned (2)
6697 | Deal with a character who is looking for a seat
6D25 | Make a boy sit still until assembly is finished
70B7 | Make a character open or close a door
720A | Control the bike when ERIC's not sitting on the saddle
74C8 | Control the descent of the water, sherry or conker
7596 | Deal with a character who has been knocked over
76AC | Control the flight of a catapult pellet
77B3 | Deal with BOY WANDER when he is firing
7813 | Deal with ANGELFACE when he is hitting
7854 | Deal with the frog when it has been knocked out of a cup
78BA | Control the frog
7966 | Control a female character while she's standing on a chair or jumping (1)
7974 | Make a female character stand on a chair or start jumping
7A16 | Control a mouse
D224 | Make a character do nothing
F3B2 | Control an open desk lid
F88B | Control a stinkbomb cloud
F8F5 | Make MR WACKER find a window to open after smelling a stinkbomb
F9D8 | Control water fired from the pistol
FAAF | Control a watered plant
The address of one of the following continual subcommand routines (or an entry point thereof) may be present in bytes 0x17 and 0x18 of the character's buffer:
Address | Description
--- | ---
775B | Make BOY WANDER fire his catapult now and then
F4CC | Make ALBERT keep an eye out for ERIC during lessons
F7DF | Make ANGELFACE stalk HAYLEY
F804 | Make ANGELFACE or BOY WANDER hit or fire now and then
The address of one of the following interruptible subcommand routines (or an entry point thereof) may be present in bytes 0x09 and 0x0A of the character's buffer:
Address | Description
--- | ---
63ED | Guide a character to an intermediate destination
6438 | Guide a character up a staircase
644D | Guide a character down a staircase
680F | Make a teacher wipe a blackboard
6880 | Make a character write on a blackboard
6A08 | Make a character speak
7E7B | Make MISS TAKE chase ERIC (2)
F017 | Make EINSTEIN speak
F09B | Make a teacher find the truant ERIC
F54A | Make MR WACKER find the truant ERIC
The address of one of the following primary command routines (or an entry point thereof) may be present in bytes 0x03 and 0x04 of the character's buffer:
Address | Description
--- | ---
6464 | Make a character go to a location
64D7 | Make a character go to a random location
66C0 | Make a character find a seat
6D00 | Control a boy during assembly
717C | Make a character open or close a door
7CD0 | Make a character walk up and down until a certain time
7CE1 | Make a character walk up and down a few times or until a certain time
7EF1 | Make BOY WANDER write on a blackboard
D224 | Make a character do nothing
F000 | Control EINSTEIN during class
F073 | Restart the command list or make a teacher tell the kids to sit down
F0B8 | Restart the command list
F0BF | Make a teacher find ERIC if he's absent during dinner
F0DA | Control a teacher during assembly
F100 | Make a teacher conduct a class
F250 | Make MR WACKER put the kids in detention
F460 | Make the next command be the start of the command list
F46C | Restart the command list unless the boys' skool door is closed
F487 | Jump forward in the command list if the boys' skool door or the gate is closed
F49C | Wait till everyone has gone past the gate or the boys' skool door
F7D7 | Place a continual subcommand routine address into a character's buffer
F80D | Restart the command list unless it's time for assembly
6341 | LD L,$12 | Jump if there is an uninterruptible subcommand routine address in bytes 0x11 and 0x12 of the character's buffer
6343 | LD A,(HL)
6344 | AND A
6345 | JR NZ,$6387
6347 | LD L,$18 | Jump if there is no continual subcommand routine address in bytes 0x17 and 0x18 of the character's buffer
6349 | LD A,(HL)
634A | AND A
634B | JR Z,$6358
634D | PUSH HL | Save the character number
634E | LD BC,$6357 | Push 6357 (the address of the entry point to return to) onto the stack
6351 | PUSH BC
6352 | LD B,A | Collect the address of the continual subcommand routine from bytes 0x17 and 0x18 of the character's buffer into BC and push it onto the stack
6353 | DEC L
6354 | LD C,(HL)
6355 | PUSH BC
6356 | RET | JP (BC) and then return to 6357 below
6357 | POP HL | Restore the character number to H
This entry point is used by the routine at 6394.
6358 | LD L,$0A | Jump if there is an interruptible subcommand routine address in bytes 0x09 and 0x0A of the character's buffer
635A | LD A,(HL)
635B | AND A
635C | JR NZ,$6387
If we get here, that means there's no uninterruptible subcommand routine address in bytes 0x11 and 0x12 and no interruptible subcommand routine address in bytes 0x09 and 0x0A of the character's buffer at the moment. We take this opportunity to check whether a command list restart has been requested, by inspecting bit 0 of byte 0x1D. This bit is set in the following routines on particular occasions:
Routine | Occasion
--- | ---
7D3E | MISS TAKE needs to chase ERIC out of the girls' skool
F09B | A teacher must find the absent ERIC during class, dinner or assembly
F4CC | MR WACKER must find the truant ERIC
F532 | MR WACKER must find and expel ERIC
F74D | Lesson has ended
In addition, a command in the command list may have requested a restart (see F073, F0B8, F46C and F80D).
635E | LD L,$1D | Check bit 0 of byte 0x1D: do we need to restart the command list?
6360 | BIT 0,(HL)
6362 | JR Z,$6371 | Jump if not
6364 | RES 0,(HL) | Reset bit 0 of byte 0x1D now that we are going to restart
6366 | LD D,H | D=character number
6367 | LD L,$1B | Point HL at where the address of the character's current command list is held
6369 | LD E,$19 | Point DE at where the address of the place reached in the character's current command list is held
636B | LDI | Copy the former into the latter (thus returning to the start of the command list)
636D | LDI
636F | JR $637B |
6371 | LD L,$04 | Jump if there is a primary command routine address in bytes 0x03 and 0x04 of the character's buffer
6373 | LD A,(HL)
6374 | AND A
6375 | JR NZ,$6387
There is no primary command routine address in bytes 0x03 and 0x04 of the character's buffer, which means it's time to move to the next command in the list.
6377 | LD L,$1D | Reset bit 3 of byte 0x1D, indicating that this character may not be considered for teleportation for the remainder of this lesson (see 61C2)
6379 | RES 3,(HL)
637B | RES 4,(HL) | Reset bit 4 of byte 0x1D, indicating that the character should no longer run if he was doing so (though this bit is unused and always reset)
637D | LD L,$18 | Remove the address of any continual subcommand routine from bytes 0x17 and 0x18 of the character's buffer
637F | LD (HL),$00
This entry point is used by the routine at F7D7.
6381 | LD L,$03 | Collect the routine address of the next command in the character's current command list and place it into bytes 0x03 and 0x04 of the buffer
6383 | CALL $6264
6386 | INC L | L=0x04
6387 | LD B,(HL) | Collect the command routine address from bytes 0x03 and 0x04, bytes 0x09 and 0x0A, or bytes 0x11 and 0x12 of the character's buffer into BC
6388 | DEC L
6389 | LD C,(HL)
638A | PUSH BC | Make an indirect jump to this address
638B | RET