![]() |
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 |