Prev: 8BBA Up: Map Next: 8D05
8BDD: Move Willy (2)
Used by the routine at 8ABB. This routine checks the keyboard and joystick, and moves Willy left or right if necessary.
Input
HL Attribute buffer address of the left-hand cell below Willy's sprite
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