Jet Set Willy: Routine at 89AD

| Routines

89AD: Main loop (1)

Used by the routines at 8912 and 8B07.
89AD | CALL $898B | Draw the remaining lives
89B0 | LD HL,$5E00 | Copy the contents of the attribute buffer at 5E00 (the attributes for the empty room) into the attribute buffer at 5C00
89B3 | LD DE,$5C00
89B6 | LD BC,$0200
89B9 | LDIR
89BB | LD HL,$7000 | Copy the contents of the screen buffer at 7000 (the tiles for the empty room) into the screen buffer at 6000
89BE | LD DE,$6000
89C1 | LD BC,$1000
89C4 | LDIR
89C6 | CALL $90C0 | Move the rope and guardians in the current room
89C9 | LD A,($85DF) | Pick up the game mode indicator from 85DF
89CC | CP $03 | Is Willy's head down the toilet?
89CE | CALL NZ,$8DD3 | If not, move Willy
89D1 | LD A,($85CF) | Pick up Willy's y-coordinate from 85CF
89D4 | CP $E1 | Has Willy just moved up a ramp or a rope past the top of the screen?
89D6 | CALL NC,$94B0 | If so, move Willy into the room above
89D9 | LD A,($85DF) | Pick up the game mode indicator from 85DF
89DC | CP $03 | Is Willy's head down the toilet?
89DE | CALL NZ,$95C8 | If not, check and set the attribute bytes for Willy's sprite in the buffer at 5C00, and draw Willy to the screen buffer at 6000
89E1 | LD A,($85DF) | Pick up the game mode indicator from 85DF
89E4 | CP $02 | Is Willy on his way to the toilet?
89E6 | CALL Z,$9584 | If so, check whether he's reached it yet
89E9 | CALL $9534 | Deal with special rooms (Master Bedroom, The Bathroom)
89EC | CALL $91BE | Draw the rope, arrows and guardians in the current room
89EF | CALL $94F9 | Move the conveyor in the current room (if there is one)
89F2 | CALL $93D1 | Draw the items in the current room (if there are any) and collect any that Willy is touching
This entry point is used by the routine at 90B6.
89F5 | LD HL,$6000 | Copy the contents of the screen buffer at 6000 to the display file
89F8 | LD DE,$4000
89FB | LD BC,$1000
89FE | LDIR
8A00 | LD A,($85DF) | Pick up the game mode indicator from 85DF
8A03 | AND $02 | Now A=1 if Willy is running to the toilet or already has his head down it, 0 otherwise
8A05 | RRCA
8A06 | LD HL,$85D2 | Set Willy's animation frame at 85D2 to 1 or 3 if Willy is running to the toilet or already has his head down it; this has the effect of moving Willy at twice his normal speed as he makes his way to the toilet (using animation frames 2 and 0)
8A09 | OR (HL)
8A0A | LD (HL),A
8A0B | LD A,($85CD) | Pick up the screen flash counter (unused and always 0) from 85CD
8A0E | OR A | Is it zero?
8A0F | JR Z,$8A26 | Jump if so (this jump is always made)
The next section of code is never executed.
8A11 | DEC A | Decrement the screen flash counter at 85CD
8A12 | LD ($85CD),A
8A15 | RLCA | Move bits 0-2 into bits 3-5 and clear all the other bits
8A16 | RLCA
8A17 | RLCA
8A18 | AND $38
8A1A | LD HL,$5C00 | Set every attribute byte in the buffer at 5C00 to this value
8A1D | LD DE,$5C01
8A20 | LD BC,$01FF
8A23 | LD (HL),A
8A24 | LDIR
Normal service resumes here.
8A26 | LD HL,$5C00 | Copy the contents of the attribute buffer at 5C00 to the attribute file
8A29 | LD DE,$5800
8A2C | LD BC,$0200
8A2F | LDIR
8A31 | LD IX,$857F | Print the current time (see 857F) at (19,25)
8A35 | LD DE,$5079
8A38 | LD C,$06
8A3A | CALL $9680
8A3D | LD IX,$857C | Print the number of items collected (see 857C) at (19,16)
8A41 | LD DE,$5070
8A44 | LD C,$03
8A46 | CALL $9680
8A49 | LD A,($85CB) | Increment the minute counter at 85CB
8A4C | INC A
8A4D | LD ($85CB),A
8A50 | JR NZ,$8AAB | Jump unless the minute counter has ticked over to 0
A minute of game time has passed. Update the game clock accordingly.
8A52 | LD IX,$857F | Point IX at the current time at 857F
8A56 | INC (IX+$04) | Increment the units digit of the minute
8A59 | LD A,(IX+$04) | Pick up the new units digit
8A5C | CP $3A | Was it '9' before?
8A5E | JR NZ,$8AAB | Jump if not
8A60 | LD (IX+$04),$30 | Set the units digit of the minute to '0'
8A64 | INC (IX+$03) | Increment the tens digit of the minute
8A67 | LD A,(IX+$03) | Pick up the new tens digit
8A6A | CP $36 | Was it '5' before?
8A6C | JR NZ,$8AAB | Jump if not
8A6E | LD (IX+$03),$30 | Set the tens digit of the minute to '0'
8A72 | LD A,(IX+$00) | Pick up the tens digit of the hour
8A75 | CP $31 | Is it currently '1'?
8A77 | JR NZ,$8A99 | Jump if not
8A79 | INC (IX+$01) | Increment the units digit of the hour
8A7C | LD A,(IX+$01) | Pick up the new units digit
8A7F | CP $33 | Was it '2' before?
8A81 | JR NZ,$8AAB | Jump if not
8A83 | LD A,(IX+$05) | Pick up the 'a' or 'p' of 'am/pm'
8A86 | CP $70 | Is it 'p'?
8A88 | JP Z,$87CA | If so, quit the game (it's 1am)
8A8B | LD (IX+$00),$20 | Set the tens digit of the hour to ' ' (space)
8A8F | LD (IX+$01),$31 | Set the units digit of the hour to '1'
8A93 | LD (IX+$05),$70 | Change the 'a' of 'am' to 'p'
8A97 | JR $8AAB |
8A99 | INC (IX+$01) | Increment the units digit of the hour
8A9C | LD A,(IX+$01) | Pick up the new units digit
8A9F | CP $3A | Was it '9' before?
8AA1 | JR NZ,$8AAB | Jump if not
8AA3 | LD (IX+$01),$30 | Set the units digit of the hour to '0'
8AA7 | LD (IX+$00),$31 | Set the tens digit of the hour to '1'
Now check whether any non-movement keys are being pressed.
8AAB | LD BC,$FEFE | Read keys SHIFT-Z-X-C-V
8AAE | IN A,(C)
8AB0 | LD E,A | Save the result in E
8AB1 | LD B,$7F | Read keys B-N-M-SS-SPACE
8AB3 | IN A,(C)
8AB5 | OR E | Combine the results
8AB6 | AND $01 | Are SHIFT and SPACE being pressed?
8AB8 | JP Z,$87CA | If so, quit the game
8ABB | LD A,($85E0) | Increment the inactivity timer at 85E0
8ABE | INC A
8ABF | LD ($85E0),A
8AC2 | JR Z,$8AD1 | Jump if the inactivity timer is now 0 (no keys have been pressed for a while)
8AC4 | LD B,$FD | Read keys A-S-D-F-G
8AC6 | IN A,(C)
8AC8 | AND $1F | Are any of these keys being pressed?
8ACA | CP $1F
8ACC | JR Z,$8B17 | Jump if not
8ACE | LD DE,$0000 | Prepare the delay counters in D and E for the pause loop that follows
The following loop pauses the game until any key except A, S, D, F or G is pressed.
8AD1 | LD B,$02 | Read every half-row of keys except A-S-D-F-G
8AD3 | IN A,(C)
8AD5 | AND $1F | Are any of these keys being pressed?
8AD7 | CP $1F
8AD9 | JR NZ,$8B07 | If so, resume the game
8ADB | INC E | Increment the delay counter in E
8ADC | JR NZ,$8AD1 | Jump back unless it's zero
8ADE | INC D | Increment the delay counter in D
8ADF | JR NZ,$8AD1 | Jump back unless it's zero
8AE1 | LD A,($85E3) | Pick up the WRITETYPER key counter from 85E3
8AE4 | CP $0A | Has WRITETYPER been keyed in yet?
8AE6 | CALL NZ,$8AEB | If not, cycle the INK and PAPER colours
8AE9 | JR $8AD1 | Jump back to the beginning of the pause loop