Routines |
Prev: 90C0 | Up: Map | Next: 93BB |
91BE | LD IX,$8100 | Point IX at the first byte of the first entity buffer at 8100 | ||
The drawing loop begins here.
|
||||
91C2 | LD A,(IX+$00) | Pick up the first byte of the current entity's buffer | ||
91C5 | CP $FF | Have we already dealt with every entity? | ||
91C7 | RET Z | Return if so | ||
91C8 | AND $07 | Keep only bits 0-2 (which determine the type of entity) | ||
91CA | JP Z,$93B3 | Jump to consider the next entity buffer if this one is not being used | ||
91CD | CP $03 | Is this a rope? | ||
91CF | JP Z,$92A4 | Jump if so | ||
91D2 | CP $04 | Is this an arrow? | ||
91D4 | JR Z,$9237 | Jump if so | ||
We are dealing with a horizontal or vertical guardian.
|
||||
91D6 | LD E,(IX+$03) | Point DE at the entry in the screen buffer address lookup table at 8200 that corresponds to the guardian's y-coordinate | ||
91D9 | LD D,$82 | |||
91DB | LD A,(DE) | Copy the LSB of the screen buffer address to L | ||
91DC | LD L,A | |||
91DD | LD A,(IX+$02) | Pick up the guardian's x-coordinate from bits 0-4 of the third byte of its buffer | ||
91E0 | AND $1F | |||
91E2 | ADD A,L | Adjust the LSB of the screen buffer address in L for the guardian's x-coordinate | ||
91E3 | LD L,A | |||
91E4 | LD A,E | Copy the fourth byte of the guardian's buffer to A | ||
91E5 | RLCA | H=0x5C or 0x5D; now HL holds the address of the guardian's current location in the attribute buffer at 5C00 | ||
91E6 | AND $01 | |||
91E8 | OR $5C | |||
91EA | LD H,A | |||
91EB | LD DE,$001F | Prepare DE for later addition | ||
91EE | LD A,(IX+$01) | Pick up the second byte of the guardian's buffer | ||
91F1 | AND $0F | Keep only bits 0-2 (INK colour) and 3 (BRIGHT value) | ||
91F3 | ADD A,$38 | Push bit 3 up to bit 6 | ||
91F5 | AND $47 | Keep only bits 0-2 (INK colour) and 6 (BRIGHT value) | ||
91F7 | LD C,A | Save this value in C temporarily | ||
91F8 | LD A,(HL) | Pick up the room attribute byte at the guardian's location from the buffer at 5C00 | ||
91F9 | AND $38 | Keep only bits 3-5 (PAPER colour) | ||
91FB | XOR C | Merge the INK colour and BRIGHT value from C | ||
91FC | LD C,A | Copy this attribute value to C | ||
91FD | LD (HL),C | Set the attribute bytes in the buffer at 5C00 for the top two rows of cells occupied by the guardian's sprite | ||
91FE | INC HL | |||
91FF | LD (HL),C | |||
9200 | ADD HL,DE | |||
9201 | LD (HL),C | |||
9202 | INC HL | |||
9203 | LD (HL),C | |||
9204 | LD A,(IX+$03) | Pick up the fourth byte of the guardian's buffer | ||
9207 | AND $0E | Does the guardian's sprite occupy only two rows of cells at the moment? | ||
9209 | JR Z,$920F | Jump if so | ||
920B | ADD HL,DE | Set the attribute bytes in the buffer at 5C00 for the third row of cells occupied by the guardian's sprite | ||
920C | LD (HL),C | |||
920D | INC HL | |||
920E | LD (HL),C | |||
920F | LD C,$01 | Prepare C for the call to 9456 later on | ||
9211 | LD A,(IX+$01) | Now bits 5-7 of A hold the animation frame mask | ||
9214 | AND (IX+$00) | 'AND' on the current animation frame (bits 5-7) | ||
9217 | OR (IX+$02) | 'OR' on the base sprite index (bits 5-7) | ||
921A | AND $E0 | Keep only bits 5-7 | ||
921C | LD E,A | Point DE at the graphic data for the guardian's current animation frame (see AB00) | ||
921D | LD D,(IX+$05) | |||
9220 | LD H,$82 | Point HL at the guardian's current location in the screen buffer at 6000 | ||
9222 | LD L,(IX+$03) | |||
9225 | LD A,(IX+$02) | |||
9228 | AND $1F | |||
922A | OR (HL) | |||
922B | INC HL | |||
922C | LD H,(HL) | |||
922D | LD L,A | |||
922E | CALL $9456 | Draw the guardian | ||
9231 | JP NZ,$90B7 | Kill Willy if the guardian collided with him | ||
9234 | JP $93B3 | Jump to consider the next entity | ||
We are dealing with an arrow.
|
||||
9237 | BIT 7,(IX+$00) | Is the arrow travelling left to right? | ||
923B | JR NZ,$9244 | Jump if so | ||
923D | DEC (IX+$04) | Decrement the arrow's x-coordinate | ||
9240 | LD C,$2C | The sound effect for an arrow travelling right to left is made when the x-coordinate is 44 | ||
9242 | JR $9249 | |||
9244 | INC (IX+$04) | Increment the arrow's x-coordinate | ||
9247 | LD C,$F4 | The sound effect for an arrow travelling left to right is made when the x-coordinate is 244 | ||
9249 | LD A,(IX+$04) | Pick up the arrow's x-coordinate (0-255) | ||
924C | CP C | Is it time to make the arrow sound effect? | ||
924D | JR NZ,$9262 | Jump if not | ||
924F | LD BC,$0280 | Prepare the delay counters (B=0x02, C=0x80) for the arrow sound effect | ||
9252 | LD A,($80DE) | Pick up the border colour for the current room from 80DE | ||
9255 | OUT ($FE),A | Produce the arrow sound effect | ||
9257 | XOR $18 | |||
9259 | DJNZ $9259 | |||
925B | LD B,C | |||
925C | DEC C | |||
925D | JR NZ,$9255 | |||
925F | JP $93B3 | Jump to consider the next entity | ||
9262 | AND $E0 | Is the arrow's x-coordinate in the range 0-31 (i.e. on-screen)? | ||
9264 | JP NZ,$93B3 | If not, jump to consider the next entity | ||
9267 | LD E,(IX+$02) | Point DE at the entry in the screen buffer address lookup table at 8200 that corresponds to the arrow's y-coordinate | ||
926A | LD D,$82 | |||
926C | LD A,(DE) | Pick up the LSB of the screen buffer address | ||
926D | ADD A,(IX+$04) | Adjust it for the arrow's x-coordinate | ||
9270 | LD L,A | Point HL at the arrow's current location in the attribute buffer at 5C00 | ||
9271 | LD A,E | |||
9272 | AND $80 | |||
9274 | RLCA | |||
9275 | OR $5C | |||
9277 | LD H,A | |||
9278 | LD (IX+$05),$00 | Initialise the collision detection byte (0x00=off, 0xFF=on) | ||
927C | LD A,(HL) | Pick up the room attribute byte at the arrow's location | ||
927D | AND $07 | Keep only bits 0-2 (INK colour) | ||
927F | CP $07 | Is the INK white? | ||
9281 | JR NZ,$9286 | Jump if not | ||
9283 | DEC (IX+$05) | Activate collision detection | ||
9286 | LD A,(HL) | Set the INK colour to white at the arrow's location | ||
9287 | OR $07 | |||
9289 | LD (HL),A | |||
928A | INC DE | Pick up the MSB of the screen buffer address for the arrow's location | ||
928B | LD A,(DE) | |||
928C | LD H,A | Point HL at the top pixel row of the arrow's location in the screen buffer at 6000 | ||
928D | DEC H | |||
928E | LD A,(IX+$06) | Draw the top pixel row of the arrow | ||
9291 | LD (HL),A | |||
9292 | INC H | Point HL at the middle pixel row of the arrow's location in the screen buffer at 6000 | ||
9293 | LD A,(HL) | Pick up the graphic byte that's already here | ||
9294 | AND (IX+$05) | Has the arrow hit anything that has white INK (e.g. Willy)? | ||
9297 | JP NZ,$90B7 | If so, kill Willy | ||
929A | LD (HL),$FF | Draw the shaft of the arrow | ||
929C | INC H | Point HL at the bottom pixel row of the arrow's location in the screen buffer at 6000 | ||
929D | LD A,(IX+$06) | Draw the bottom pixel row of the arrow | ||
92A0 | LD (HL),A | |||
92A1 | JP $93B3 | Jump to consider the next entity | ||
We are dealing with a rope.
|
||||
92A4 | LD IY,$8200 | Point IY at the first byte of the screen buffer address lookup table at 8200 | ||
92A8 | LD (IX+$09),$00 | Initialise the second byte in the following entity buffer to zero; this will count the segments of rope to draw | ||
92AC | LD A,(IX+$02) | Initialise the fourth byte of the rope's buffer; this holds the x-coordinate of the cell in which the segment of rope under consideration will be drawn | ||
92AF | LD (IX+$03),A | |||
92B2 | LD (IX+$05),$80 | Initialise the sixth byte of the rope's buffer to 0x80 (bit 7 set); the value held here is used to draw the segment of rope under consideration | ||
The following loop draws each segment of the rope from top to bottom.
|
||||
92B6 | LD A,(IY+$00) | Point HL at the location of the segment of rope under consideration in the screen buffer at 6000 | ||
92B9 | ADD A,(IX+$03) | |||
92BC | LD L,A | |||
92BD | LD H,(IY+$01) | |||
92C0 | LD A,($85D6) | Pick up the rope status indicator at 85D6 | ||
92C3 | OR A | Is Willy on the rope, or has he recently jumped or dropped off it? | ||
92C4 | JR NZ,$92D6 | Jump if so | ||
92C6 | LD A,(IX+$05) | Pick up the drawing byte | ||
92C9 | AND (HL) | Is this segment of rope touching anything else that's been drawn so far (e.g. Willy)? | ||
92CA | JR Z,$930E | Jump if not | ||
92CC | LD A,(IX+$09) | Copy the segment counter into the rope status indicator at 85D6 | ||
92CF | LD ($85D6),A | |||
92D2 | SET 0,(IX+$0B) | Signal: Willy is on the rope | ||
92D6 | CP (IX+$09) | Does the rope status indicator at 85D6 match the segment counter? | ||
92D9 | JR NZ,$930E | Jump if not | ||
92DB | BIT 0,(IX+$0B) | Is Willy on the rope (and clinging to this particular segment)? | ||
92DF | JR Z,$930E | Jump if not | ||
92E1 | LD B,(IX+$03) | Copy the x-coordinate of the cell containing the segment of rope under consideration to B | ||
92E4 | LD A,(IX+$05) | Pick up the drawing byte in A | ||
92E7 | LD C,$01 | The value in C will specify Willy's next animation frame; initialise it to 1 | ||
92E9 | CP $04 | Is the set bit of the drawing byte in bit 0 or 1? | ||
92EB | JR C,$92FC | Jump if so | ||
92ED | LD C,$00 | Assume that Willy's next animation frame will be 0 | ||
92EF | CP $10 | Is the set bit of the drawing byte in bit 2 or 3? | ||
92F1 | JR C,$92FC | Jump if so | ||
92F3 | DEC B | Decrement the x-coordinate | ||
92F4 | LD C,$03 | Assume that Willy's next animation frame will be 3 | ||
92F6 | CP $40 | Is the set bit of the drawing byte in bit 4 or 5? | ||
92F8 | JR C,$92FC | Jump if so | ||
92FA | LD C,$02 | Willy's next animation frame will be 2 (the set bit of the drawing byte is in bit 6 or 7) | ||
92FC | LD ($85D2),BC | Set Willy's animation frame at 85D2, and temporarily store his x-coordinate at 85D3 | ||
9300 | LD A,IYl | Update Willy's y-coordinate at 85CF to account for his change of location as the rope moves | ||
9302 | SUB $10 | |||
9304 | LD ($85CF),A | |||
9307 | PUSH HL | Save HL briefly | ||
9308 | CALL $8E9C | Update Willy's attribute buffer address at 85D3 to account for his change of location as the rope moves | ||
930B | POP HL | Restore the screen buffer address of the segment of rope under consideration to HL | ||
930C | JR $930E | Make a redundant jump to the next instruction | ||
930E | LD A,(IX+$05) | Draw a pixel of the rope to the screen buffer at 6000 | ||
9311 | OR (HL) | |||
9312 | LD (HL),A | |||
9313 | LD A,(IX+$09) | Point HL at the relevant entry in the second half of the rope animation table at 8300 | ||
9316 | ADD A,(IX+$01) | |||
9319 | LD L,A | |||
931A | SET 7,L | |||
931C | LD H,$83 | |||
931E | LD E,(HL) | Add its value to IY; now IY points at the entry in the screen buffer address lookup table at 8200 that corresponds to the next segment of rope to consider | ||
931F | LD D,$00 | |||
9321 | ADD IY,DE | |||
9323 | RES 7,L | Point HL at the relevant entry in the first half of the rope animation table at 8300 | ||
9325 | LD A,(HL) | Pick up its value | ||
9326 | OR A | Is it zero? | ||
9327 | JR Z,$9350 | Jump if so | ||
9329 | LD B,A | Copy the rope animation table entry value to B; this will count the rotations of the drawing byte | ||
932A | BIT 7,(IX+$01) | Is the rope currently right of centre? | ||
932E | JR Z,$9341 | Jump if so | ||
9330 | RLC (IX+$05) | Rotate the drawing byte left once | ||
9334 | BIT 0,(IX+$05) | Did that push the set bit from bit 7 into bit 0? | ||
9338 | JR Z,$933D | Jump if not | ||
933A | DEC (IX+$03) | Decrement the x-coordinate for the cell containing this segment of rope | ||
933D | DJNZ $9330 | Jump back until the drawing byte has been rotated as required | ||
933F | JR $9350 | Jump to consider the next segment of rope | ||
9341 | RRC (IX+$05) | Rotate the drawing byte right once | ||
9345 | BIT 7,(IX+$05) | Did that push the set bit from bit 0 into bit 7? | ||
9349 | JR Z,$934E | Jump if not | ||
934B | INC (IX+$03) | Increment the x-coordinate for the cell containing this segment of rope | ||
934E | DJNZ $9341 | Jump back until the drawing byte has been rotated as required | ||
9350 | LD A,(IX+$09) | Pick up the segment counter | ||
9353 | CP (IX+$04) | Have we drawn every segment of the rope yet? | ||
9356 | JR Z,$935E | Jump if so | ||
9358 | INC (IX+$09) | Increment the segment counter | ||
935B | JP $92B6 | Jump back to draw the next segment of rope | ||
Now that the entire rope has been drawn, deal with Willy's movement along it.
|
||||
935E | LD A,($85D6) | Pick up the rope status indicator at 85D6 | ||
9361 | BIT 7,A | Has Willy recently jumped off the rope or dropped off the bottom of it (A>=0xF0)? | ||
9363 | JR Z,$936F | Jump if not | ||
9365 | INC A | Update the rope status indicator at 85D6 | ||
9366 | LD ($85D6),A | |||
9369 | RES 0,(IX+$0B) | Signal: Willy is not on the rope | ||
936D | JR $93B3 | Jump to consider the next entity | ||
936F | BIT 0,(IX+$0B) | Is Willy on the rope? | ||
9373 | JR Z,$93B3 | If not, jump to consider the next entity | ||
9375 | LD A,($85D0) | Pick up Willy's direction and movement flags from 85D0 | ||
9378 | BIT 1,A | Is Willy moving up or down the rope? | ||
937A | JR Z,$93B3 | If not, jump to consider the next entity | ||
937C | RRCA | XOR Willy's direction bit (0=facing right, 1=facing left) with the rope's direction bit (0=swinging right to left, 1=swinging left to right) | ||
937D | XOR (IX+$00) | |||
9380 | RLCA | |||
9381 | RLCA | Now A=1 if Willy is facing the same direction as the rope is swinging (he will move down the rope), or -1 otherwise (he will move up the rope) | ||
9382 | AND $02 | |||
9384 | DEC A | |||
9385 | LD HL,$85D6 | Increment or decrement the rope status indicator at 85D6 | ||
9388 | ADD A,(HL) | |||
9389 | LD (HL),A | |||
938A | LD A,($80EB) | Pick up the number of the room above from 80EB and copy it to C | ||
938D | LD C,A | |||
938E | LD A,($8420) | Pick up the number of the current room from 8420 | ||
9391 | CP C | Is there a room above this one? | ||
9392 | JR NZ,$939B | Jump if so | ||
9394 | LD A,(HL) | Pick up the rope status indicator at 85D6 | ||
9395 | CP $0C | Is it 0x0C or greater? | ||
9397 | JR NC,$939B | Jump if so | ||
9399 | LD (HL),$0C | Set the rope status indicator at 85D6 to 0x0C (there is nowhere to go above this rope) | ||
939B | LD A,(HL) | Pick up the rope status indicator at 85D6 | ||
939C | CP (IX+$04) | Compare it with the length of the rope | ||
939F | JR C,$93B3 | If Willy is at or above the bottom of the rope, jump to consider the next entity | ||
93A1 | JR Z,$93B3 | |||
93A3 | LD (HL),$F0 | Set the rope status indicator at 85D6 to 0xF0 (Willy has just dropped off the bottom of the rope) | ||
93A5 | LD A,($85CF) | Round down Willy's y-coordinate at 85CF to the nearest multiple of 8; this might move him upwards a little, but ensures that his actual pixel y-coordinate is a multiple of 4 before he starts falling | ||
93A8 | AND $F8 | |||
93AA | LD ($85CF),A | |||
93AD | XOR A | Initialise the airborne status indicator at 85D1 | ||
93AE | LD ($85D1),A | |||
93B1 | JR $93B3 | Make a redundant jump to the next instruction | ||
The current entity has been dealt with. Time for the next one.
|
||||
93B3 | LD DE,$0008 | Point IX at the first byte of the next entity's buffer | ||
93B6 | ADD IX,DE | |||
93B8 | JP $91C2 | Jump back to deal with it |
Prev: 90C0 | Up: Map | Next: 93BB |