Jet Set Willy: Routine at 90C0

| Routines

90C0: Move the rope and guardians in the current room

Used by the routine at 89AD.
90C0 | LD IX,$8100 | Point IX at the first byte of the first entity buffer at 8100
The entity-moving loop begins here.
90C4 | LD A,(IX+$00) | Pick up the first byte of the current entity's buffer
90C7 | CP $FF | Have we already dealt with every entity?
90C9 | RET Z | Return if so
90CA | AND $03 | Keep only bits 0 and 1 (which determine the type of entity)
90CC | JP Z,$91B6 | Jump to consider the next entity buffer if this one belongs to an arrow or is unused
90CF | CP $01 | Is this a horizontal guardian?
90D1 | JP Z,$9133 | Jump if so
90D4 | CP $02 | Is this a vertical guardian?
90D6 | JP Z,$917F | Jump if so
We are dealing with a rope.
90D9 | BIT 7,(IX+$00) | Is the rope currently swinging right to left?
90DD | JR Z,$90FF | Jump if so
The rope is swinging left to right.
90DF | LD A,(IX+$01) | Pick up the animation frame index
90E2 | BIT 7,A | Is the rope currently swinging away from the centre?
90E4 | JR Z,$90F5 | Jump if so
The rope is swinging left to right, towards the centre (0x84<=A<=0xB6).
90E6 | SUB $02 | Subtract 2 from the animation frame index in A
90E8 | CP $94 | Is it still 0x94 or greater?
90EA | JR NC,$911D | If so, use it as the next animation frame index
90EC | SUB $02 | Subtract 2 from the animation frame index again
90EE | CP $80 | Is it 0x80 now?
90F0 | JR NZ,$911D | If not, use it as the next animation frame index
90F2 | XOR A | The rope has reached the centre, so the next animation frame index is 0
90F3 | JR $911D | Jump to set it
The rope is swinging left to right, away from the centre (0x00<=A<=0x34).
90F5 | ADD A,$02 | Add 2 to the animation frame index in A
90F7 | CP $12 | Is it now 0x12 or greater?
90F9 | JR NC,$911D | If so, use it as the next animation frame index
90FB | ADD A,$02 | Add 2 to the animation frame index again
90FD | JR $911D | Use this value as the next animation frame index
The rope is swinging right to left.
90FF | LD A,(IX+$01) | Pick up the animation frame index
9102 | BIT 7,A | Is the rope currently swinging away from the centre?
9104 | JR NZ,$9115 | Jump if so
The rope is swinging right to left, towards the centre (0x04<=A<=0x36).
9106 | SUB $02 | Subtract 2 from the animation frame index in A
9108 | CP $14 | Is it still 0x14 or greater?
910A | JR NC,$911D | If so, use it as the next animation frame index
910C | SUB $02 | Subtract 2 from the animation frame index again
910E | OR A | Is it 0 now?
910F | JR NZ,$911D | If not, use it as the next animation frame index
9111 | LD A,$80 | The rope has reached the centre, so the next animation frame index is 0x80
9113 | JR $911D | Jump to set it
The rope is swinging right to left, away from the centre (0x80<=A<=0xB4).
9115 | ADD A,$02 | Add 2 to the animation frame index in A
9117 | CP $92 | Is it now 0x92 or greater?
9119 | JR NC,$911D | If so, use it as the next animation frame index
911B | ADD A,$02 | Add 2 to the animation frame index again
Now A holds the rope's next animation frame index.
911D | LD (IX+$01),A | Update the animation frame index
9120 | AND $7F | Reset bit 7
9122 | CP (IX+$07) | Does A match the eighth byte of the rope's buffer (0x36)?
9125 | JP NZ,$91B6 | If not, jump to consider the next entity
9128 | LD A,(IX+$00) | Flip bit 7 of the first byte of the rope's buffer: the rope has just changed direction and will now swing back towards the centre
912B | XOR $80
912D | LD (IX+$00),A
9130 | JP $91B6 | Jump to consider the next entity
We are dealing with a horizontal guardian.
9133 | BIT 7,(IX+$00) | Is the guardian currently moving left to right?
9137 | JR NZ,$915C | Jump if so
This guardian is moving right to left.
9139 | LD A,(IX+$00) | Update the guardian's animation frame (in bits 5 and 6 of the first byte of its buffer)
913C | SUB $20
913E | AND $7F
9140 | LD (IX+$00),A
9143 | CP $60 | Is it time to update the x-coordinate of the guardian sprite?
9145 | JR C,$91B6 | If not, jump to consider the next entity
9147 | LD A,(IX+$02) | Pick up the sprite's current screen x-coordinate (0-31)
914A | AND $1F
914C | CP (IX+$06) | Has the guardian reached the leftmost point of its path?
914F | JR Z,$9156 | Jump if so
9151 | DEC (IX+$02) | Decrement the sprite's x-coordinate
9154 | JR $91B6 | Jump to consider the next entity
9156 | LD (IX+$00),$81 | The guardian will now start moving left to right
915A | JR $91B6 | Jump to consider the next entity
This guardian is moving left to right.
915C | LD A,(IX+$00) | Update the guardian's animation frame (in bits 5 and 6 of the first byte of its buffer)
915F | ADD A,$20
9161 | OR $80
9163 | LD (IX+$00),A
9166 | CP $A0 | Is it time to update the x-coordinate of the guardian sprite?
9168 | JR NC,$91B6 | If not, jump to consider the next entity
916A | LD A,(IX+$02) | Pick up the sprite's current screen x-coordinate (0-31)
916D | AND $1F
916F | CP (IX+$07) | Has the guardian reached the rightmost point of its path?
9172 | JR Z,$9179 | Jump if so
9174 | INC (IX+$02) | Increment the sprite's x-coordinate
9177 | JR $91B6 | Jump to consider the next entity
9179 | LD (IX+$00),$61 | The guardian will now start moving right to left
917D | JR $91B6 | Jump to consider the next entity
We are dealing with a vertical guardian.
917F | LD A,(IX+$00) | Flip bit 3 of the first byte of the guardian's buffer (if bit 4 is set, the guardian's animation frame is updated on every pass through this routine; otherwise, it is updated on every second pass when bit 3 is set)
9182 | XOR $08
9184 | LD (IX+$00),A
9187 | AND $18 | Are bits 3 and 4 both reset now?
9189 | JR Z,$9193 | Jump if so
918B | LD A,(IX+$00) | Update the guardian's animation frame (in bits 5-7 of the first byte of its buffer)
918E | ADD A,$20
9190 | LD (IX+$00),A
9193 | LD A,(IX+$03) | Update the guardian's y-coordinate
9196 | ADD A,(IX+$04)
9199 | LD (IX+$03),A
919C | CP (IX+$07) | Has the guardian reached the lowest point of its path (maximum y-coordinate)?
919F | JR NC,$91AE | If so, jump to change its direction of movement
91A1 | CP (IX+$06) | Compare the new y-coordinate with the minimum value (the highest point of its path)
91A4 | JR Z,$91A8 | If they match, jump to change the guardian's direction of movement
91A6 | JR NC,$91B6 | If the new y-coordinate is above the minimum value, jump to consider the next entity
91A8 | LD A,(IX+$06) | Make sure that the guardian's y-coordinate is set to its minimum value
91AB | LD (IX+$03),A
91AE | LD A,(IX+$04) | Negate the y-coordinate increment; this changes the guardian's direction of movement
91B1 | NEG
91B3 | LD (IX+$04),A
The current entity has been dealt with. Time for the next one.
91B6 | LD DE,$0008 | Point IX at the first byte of the next entity's buffer
91B9 | ADD IX,DE
91BB | JP $90C4 | Jump back to deal with it