![]() |
Routines |
| Prev: 8BBA | Up: Map | Next: 8D05 |
|
Used by the routine at 8ABB. This routine checks the keyboard and joystick, and moves Willy left or right if necessary.
|
||||||||
| 8BDD | LD A,($806B) | Pick up the airborne status indicator from 806B | ||||||
| 8BE0 | CP $0C | Has Willy just landed after falling from too great a height? | ||||||
| 8BE2 | JP NC,$8D06 | If so, kill him | ||||||
| 8BE5 | LD E,$FF | Initialise E to 0xFF (all bits set); it will be used to hold keyboard and joystick readings | ||||||
| 8BE7 | XOR A | Reset the airborne status indicator at 806B (Willy has landed safely) | ||||||
| 8BE8 | LD ($806B),A | |||||||
| 8BEB | LD A,($8044) | Pick up the attribute byte of the conveyor tile for the current cavern from 8044 | ||||||
| 8BEE | CP (HL) | Does the attribute byte of the left-hand cell below Willy's sprite match that of the conveyor tile? | ||||||
| 8BEF | JR Z,$8BF5 | Jump if so | ||||||
| 8BF1 | INC HL | Point HL at the right-hand cell below Willy's sprite | ||||||
| 8BF2 | CP (HL) | Does the attribute byte of the right-hand cell below Willy's sprite match that of the conveyor tile? | ||||||
| 8BF3 | JR NZ,$8BFB | Jump if not | ||||||
| 8BF5 | LD A,($806F) | Pick up the direction byte of the conveyor definition from 806F (0=left, 1=right) | ||||||
| 8BF8 | SUB $03 | Now E=0xFD (bit 1 reset) if the conveyor is moving left, or 0xFE (bit 0 reset) if it's moving right | ||||||
| 8BFA | LD E,A | |||||||
| 8BFB | LD BC,$DFFE | Read keys P-O-I-U-Y (right, left, right, left, right) into bits 0-4 of A | ||||||
| 8BFE | IN A,(C) | |||||||
| 8C00 | AND $1F | Set bit 5 and reset bits 6 and 7 | ||||||
| 8C02 | OR $20 | |||||||
| 8C04 | AND E | Reset bit 0 if the conveyor is moving right, or bit 1 if it's moving left | ||||||
| 8C05 | LD E,A | Save the result in E | ||||||
| 8C06 | LD BC,$FBFE | Read keys Q-W-E-R-T (left, right, left, right, left) into bits 0-4 of A | ||||||
| 8C09 | IN A,(C) | |||||||
| 8C0B | AND $1F | Keep only bits 0-4, shift them into bits 1-5, and set bit 0 | ||||||
| 8C0D | RLC A | |||||||
| 8C0F | OR $01 | |||||||
| 8C11 | AND E | Merge this keyboard reading into bits 1-5 of E | ||||||
| 8C12 | LD E,A | |||||||
| 8C13 | LD B,$F7 | Read keys 1-2-3-4-5 ('5' is left) into bits 0-4 of A | ||||||
| 8C15 | IN A,(C) | |||||||
| 8C17 | RRCA | Rotate the result right and set bits 0-2 and 4-7; this ignores every key except '5' (left) | ||||||
| 8C18 | OR $F7 | |||||||
| 8C1A | AND E | Merge this reading of the '5' key into bit 3 of E | ||||||
| 8C1B | LD E,A | |||||||
| 8C1C | LD B,$EF | Read keys 0-9-8-7-6 ('8' is right) into bits 0-4 of A | ||||||
| 8C1E | IN A,(C) | |||||||
| 8C20 | OR $FB | Set bits 0, 1 and 3-7; this ignores every key except '8' (right) | ||||||
| 8C22 | AND E | Merge this reading of the '8' key into bit 2 of E | ||||||
| 8C23 | LD E,A | |||||||
| 8C24 | LD A,($8459) | Collect the Kempston joystick indicator from 8459 | ||||||
| 8C27 | OR A | Is the joystick connected? | ||||||
| 8C28 | JR Z,$8C34 | Jump if not | ||||||
| 8C2A | LD BC,$001F | Collect input from the joystick | ||||||
| 8C2D | IN A,(C) | |||||||
| 8C2F | AND $03 | Keep only bits 0 (right) and 1 (left) and flip them | ||||||
| 8C31 | CPL | |||||||
| 8C32 | AND E | Merge this reading of the joystick right and left buttons into bits 0 and 1 of E | ||||||
| 8C33 | LD E,A | |||||||
|
At this point, bits 0-5 in E indicate the direction in which Willy is being moved or trying to move. If bit 0, 2 or 4 is reset, Willy is being moved or trying to move right; if bit 1, 3 or 5 is reset, Willy is being moved or trying to move left.
|
||||||||
| 8C34 | LD C,$00 | Initialise C to 0 (no movement) | ||||||
| 8C36 | LD A,E | Copy the movement bits into A | ||||||
| 8C37 | AND $2A | Keep only bits 1, 3 and 5 (the 'left' bits) | ||||||
| 8C39 | CP $2A | Are any of these bits reset? | ||||||
| 8C3B | JR Z,$8C3F | Jump if not | ||||||
| 8C3D | LD C,$04 | Set bit 2 of C: Willy is moving left | ||||||
| 8C3F | LD A,E | Copy the movement bits into A | ||||||
| 8C40 | AND $15 | Keep only bits 0, 2 and 4 (the 'right' bits) | ||||||
| 8C42 | CP $15 | Are any of these bits reset? | ||||||
| 8C44 | JR Z,$8C48 | Jump if not | ||||||
| 8C46 | SET 3,C | Set bit 3 of C: Willy is moving right | ||||||
| 8C48 | LD A,($806A) | Pick up Willy's direction and movement flags from 806A | ||||||
| 8C4B | ADD A,C | Point HL at the entry in the left-right movement table at 8408 that corresponds to the direction Willy is facing, and the direction in which he is being moved or trying to move | ||||||
| 8C4C | LD C,A | |||||||
| 8C4D | LD B,$00 | |||||||
| 8C4F | LD HL,$8408 | |||||||
| 8C52 | ADD HL,BC | |||||||
| 8C53 | LD A,(HL) | Update Willy's direction and movement flags at 806A with the entry from the left-right movement table | ||||||
| 8C54 | LD ($806A),A | |||||||
|
That is left-right movement taken care of. Now check the jump keys.
|
||||||||
| 8C57 | LD BC,$7EFE | Read keys SHIFT-Z-X-C-V and B-N-M-SS-SPACE | ||||||
| 8C5A | IN A,(C) | |||||||
| 8C5C | AND $1F | Are any of these keys being pressed? | ||||||
| 8C5E | CP $1F | |||||||
| 8C60 | JR NZ,$8C7B | Jump if so | ||||||
| 8C62 | LD B,$EF | Read keys 0-9-8-7-6 into bits 0-4 of A | ||||||
| 8C64 | IN A,(C) | |||||||
| 8C66 | AND $09 | Keep only bits 0 (the '0' key) and 3 (the '7' key) | ||||||
| 8C68 | CP $09 | Is '0' or '7' being pressed? | ||||||
| 8C6A | JR NZ,$8C7B | Jump if so | ||||||
| 8C6C | LD A,($8459) | Collect the Kempston joystick indicator from 8459 | ||||||
| 8C6F | OR A | Is the joystick connected? | ||||||
| 8C70 | JR Z,$8C83 | Jump if not | ||||||
| 8C72 | LD BC,$001F | Collect input from the joystick | ||||||
| 8C75 | IN A,(C) | |||||||
| 8C77 | BIT 4,A | Is the fire button being pressed? | ||||||
| 8C79 | JR Z,$8C83 | Jump if not | ||||||
|
A jump key or the fire button is being pressed. Time to make Willy jump.
|
||||||||
| 8C7B | XOR A | Initialise the jumping animation counter at 806E | ||||||
| 8C7C | LD ($806E),A | |||||||
| 8C7F | INC A | Set the airborne status indicator at 806B to 1: Willy is jumping | ||||||
| 8C80 | LD ($806B),A | |||||||
|
This entry point is used by the routine at 8ABB.
|
||||||||
| 8C83 | LD A,($806A) | Pick up Willy's direction and movement flags from 806A | ||||||
| 8C86 | AND $02 | Is Willy moving? | ||||||
| 8C88 | RET Z | Return if not | ||||||
| 8C89 | LD A,($806A) | Pick up Willy's direction and movement flags from 806A | ||||||
| 8C8C | AND $01 | Is Willy facing right? | ||||||
| 8C8E | JP Z,$8CCA | Jump if so | ||||||
|
Willy is moving left.
|
||||||||
| 8C91 | LD A,($8069) | Pick up Willy's animation frame from 8069 | ||||||
| 8C94 | OR A | Is it 0? | ||||||
| 8C95 | JR Z,$8C9C | If so, jump to move Willy's sprite left across a cell boundary | ||||||
| 8C97 | DEC A | Decrement Willy's animation frame at 8069 | ||||||
| 8C98 | LD ($8069),A | |||||||
| 8C9B | RET | |||||||
|
Willy's sprite is moving left across a cell boundary. In the comments that follow, (x,y) refers to the coordinates of the top-left cell currently occupied by Willy's sprite.
|
||||||||
| 8C9C | LD HL,($806C) | Collect Willy's attribute buffer coordinates from 806C | ||||||
| 8C9F | DEC HL | Point HL at the cell at (x-1,y+1) | ||||||
| 8CA0 | LD DE,$0020 | |||||||
| 8CA3 | ADD HL,DE | |||||||
| 8CA4 | LD A,($803B) | Pick up the attribute byte of the wall tile for the current cavern from 803B | ||||||
| 8CA7 | CP (HL) | Is there a wall tile in the cell pointed to by HL? | ||||||
| 8CA8 | RET Z | Return if so without moving Willy (his path is blocked) | ||||||
| 8CA9 | LD A,($8068) | Pick up Willy's y-coordinate from 8068 | ||||||
| 8CAC | AND $0F | Does Willy's sprite currently occupy only two rows of cells? | ||||||
| 8CAE | JR Z,$8CB9 | Jump if so | ||||||
| 8CB0 | LD A,($803B) | Pick up the attribute byte of the wall tile for the current cavern from 803B | ||||||
| 8CB3 | ADD HL,DE | Point HL at the cell at (x-1,y+2) | ||||||
| 8CB4 | CP (HL) | Is there a wall tile in the cell pointed to by HL? | ||||||
| 8CB5 | RET Z | Return if so without moving Willy (his path is blocked) | ||||||
| 8CB6 | OR A | Clear the carry flag for subtraction | ||||||
| 8CB7 | SBC HL,DE | Point HL at the cell at (x-1,y+1) | ||||||
| 8CB9 | LD A,($803B) | Pick up the attribute byte of the wall tile for the current cavern from 803B | ||||||
| 8CBC | OR A | Clear the carry flag for subtraction | ||||||
| 8CBD | SBC HL,DE | Point HL at the cell at (x-1,y) | ||||||
| 8CBF | CP (HL) | Is there a wall tile in the cell pointed to by HL? | ||||||
| 8CC0 | RET Z | Return if so without moving Willy (his path is blocked) | ||||||
| 8CC1 | LD ($806C),HL | Save Willy's new attribute buffer coordinates (in HL) at 806C | ||||||
| 8CC4 | LD A,$03 | Change Willy's animation frame at 8069 from 0 to 3 | ||||||
| 8CC6 | LD ($8069),A | |||||||
| 8CC9 | RET | |||||||
|
Willy is moving right.
|
||||||||
| 8CCA | LD A,($8069) | Pick up Willy's animation frame from 8069 | ||||||
| 8CCD | CP $03 | Is it 3? | ||||||
| 8CCF | JR Z,$8CD6 | If so, jump to move Willy's sprite right across a cell boundary | ||||||
| 8CD1 | INC A | Increment Willy's animation frame at 8069 | ||||||
| 8CD2 | LD ($8069),A | |||||||
| 8CD5 | RET | |||||||
|
Willy's sprite is moving right across a cell boundary. In the comments that follow, (x,y) refers to the coordinates of the top-left cell currently occupied by Willy's sprite.
|
||||||||
| 8CD6 | LD HL,($806C) | Collect Willy's attribute buffer coordinates from 806C | ||||||
| 8CD9 | INC HL | Point HL at the cell at (x+2,y) | ||||||
| 8CDA | INC HL | |||||||
| 8CDB | LD DE,$0020 | Prepare DE for addition | ||||||
| 8CDE | LD A,($803B) | Pick up the attribute byte of the wall tile for the current cavern from 803B | ||||||
| 8CE1 | ADD HL,DE | Point HL at the cell at (x+2,y+1) | ||||||
| 8CE2 | CP (HL) | Is there a wall tile in the cell pointed to by HL? | ||||||
| 8CE3 | RET Z | Return if so without moving Willy (his path is blocked) | ||||||
| 8CE4 | LD A,($8068) | Pick up Willy's y-coordinate from 8068 | ||||||
| 8CE7 | AND $0F | Does Willy's sprite currently occupy only two rows of cells? | ||||||
| 8CE9 | JR Z,$8CF4 | Jump if so | ||||||
| 8CEB | LD A,($803B) | Pick up the attribute byte of the wall tile for the current cavern from 803B | ||||||
| 8CEE | ADD HL,DE | Point HL at the cell at (x+2,y+2) | ||||||
| 8CEF | CP (HL) | Is there a wall tile in the cell pointed to by HL? | ||||||
| 8CF0 | RET Z | Return if so without moving Willy (his path is blocked) | ||||||
| 8CF1 | OR A | Clear the carry flag for subtraction | ||||||
| 8CF2 | SBC HL,DE | Point HL at the cell at (x+2,y+1) | ||||||
| 8CF4 | LD A,($803B) | Pick up the attribute byte of the wall tile for the current cavern from 803B | ||||||
| 8CF7 | OR A | Clear the carry flag for subtraction | ||||||
| 8CF8 | SBC HL,DE | Point HL at the cell at (x+2,y) | ||||||
| 8CFA | CP (HL) | Is there a wall tile in the cell pointed to by HL? | ||||||
| 8CFB | RET Z | Return if so without moving Willy (his path is blocked) | ||||||
| 8CFC | DEC HL | Point HL at the cell at (x+1,y) | ||||||
| 8CFD | LD ($806C),HL | Save Willy's new attribute buffer coordinates (in HL) at 806C | ||||||
| 8D00 | XOR A | Change Willy's animation frame at 8069 from 3 to 0 | ||||||
| 8D01 | LD ($8069),A | |||||||
| 8D04 | RET | |||||||
| Prev: 8BBA | Up: Map | Next: 8D05 |