| Chase H.Q. | Routines |
| Prev: BDC1 | Up: Map | Next: C0E1 |
|
Resets this frame's sound effect triggers and the allow-spawning counter, then works out how many times to advance the cyclic road buffer.
At normal speed, meaning the high byte of the speed is zero, the buffer advances once only when the fast counter overflows after the speed has been added to it. At high speed, meaning that high byte is odd, the buffer is advanced once before the addition and a second time if the addition overflows. The advancing itself, and the decoding of each data channel, is left to rm_cycle_buffer_offset.
|
||||
| read_map | BDFB | XOR A | Prepare to clear | |
| BDFC | LD ($A23D),A | Clear trigger_left_hand_passed_object_sfx | ||
| BDFF | LD ($A23C),A | Clear trigger_right_hand_passed_object_sfx | ||
| BE02 | LD ($A254),A | Clear allow_spawning | ||
| BE05 | LD HL,$A23F | Load address of fast_counter | ||
| BE08 | LD DE,($A24A) | Load speed | ||
| BE0C | LD A,E | Copy bottom byte of speed | ||
| BE0D | RR D | Jump if bit 0 of the speed's high byte is clear. In practice D is 0 or 1, so this is a "speed < 256" test | ||
| BE0F | JR NC,rm_check_speed | |||
|
Otherwise we're going fast. The buffer is cycled once here unconditionally, and again below if accumulating the speed into fast_counter carries, so a fast frame can advance the road twice.
|
||||
| BE11 | PUSH AF | Preserve registers over next call | ||
| BE12 | PUSH HL | |||
| BE13 | CALL rm_cycle_buffer_offset | Call rm_cycle_buffer_offset/rm_cycle_buffer_offset | ||
| BE16 | POP HL | Restore | ||
| BE17 | POP AF | |||
| rm_check_speed | BE18 | ADD A,(HL) | Increment fast_counter by bottom byte of current speed | |
| BE19 | LD (HL),A | |||
| BE1A | LD A,$00 | Set flag to disallow car spawning | ||
| BE1C | JP NC,rm_exit | Jump to rm_exit if fast_counter didn't carry (meaning we're going slow or have stopped) | ||
|
This entry point is used by the routine at set_up_stage.
|
||||
| rm_cycle_buffer_offset | BE1F | INC HL | Set HL to address of road_buffer_offset | |
| BE20 | LD A,(HL) | Load, increment and update road_buffer_offset.lo (wrapping around) | ||
| BE21 | INC A | |||
| BE22 | LD (HL),A | |||
| BE23 | ADD A,$5F | Point HL at first byte of right hand object data | ||
| BE25 | LD L,A | |||
| BE26 | LD H,$EE | |||
| BE28 | LD A,($A23C) | Set trigger_right_hand_passed_object_sfx | ||
| BE2B | OR (HL) | |||
| BE2C | LD ($A23C),A | |||
| BE2F | LD A,L | Point HL at first byte of left hand object data | ||
| BE30 | ADD A,$20 | |||
| BE32 | LD L,A | |||
| BE33 | LD A,($A23D) | Set trigger_left_hand_passed_object_sfx | ||
| BE36 | OR (HL) | |||
| BE37 | LD ($A23D),A | |||
|
-- CURVATURE --
|
||||
| BE3A | LD A,L | Step back 96 bytes to the now-end of curvature? | ||
| BE3B | SUB $60 | |||
| BE3D | LD L,A | |||
|
The top nibble of each byte is a counter. The bottom nibble is curvature data.
|
||||
| BE3E | LD A,($A242) | Decrement down the counter nibble | ||
| BE41 | SUB $10 | |||
| BE43 | JR NC,rm_save_curvature_byte | Jump to rm_save_curvature_byte if curvature_byte >= 16 | ||
|
Load a new curvature byte.
|
||||
| BE45 | LD DE,($A26E) | Read and increment address of curvature data | ||
| BE49 | INC DE | |||
| BE4A | LD A,(DE) | Read a curvature byte | ||
| BE4B | OR A | Jump to rm_curvature_regular_byte if non-zero | ||
| BE4C | JR NZ,rm_curvature_regular_byte | |||
|
Handle curvature escape byte.
|
||||
| rm_curvature_escape_byte | BE4E | EX DE,HL | HL is now address of escape byte | |
| BE4F | INC HL | Increment, read command byte, increment again | ||
| BE50 | LD A,(HL) | |||
| BE51 | INC HL | |||
| BE52 | AND A | Jump to rm_curvature_jump_command if command byte is zero | ||
| BE53 | JR Z,rm_curvature_jump_command | |||
| BE55 | DEC A | Jump to rm_curvature_one_command if command byte is one | ||
| BE56 | JR Z,rm_curvature_one_command | |||
|
Otherwise it must be a fork road command (byte == 2).
|
||||
| BE58 | LD C,(HL) | Load address of left route's curvature data | ||
| BE59 | INC HL | |||
| BE5A | LD B,(HL) | |||
| BE5B | INC HL | |||
| BE5C | LD ($BB95),BC | Self modify 'LD HL,$xxxx' @ BB94 to load the address | ||
| BE60 | LD A,(HL) | Load address of right route's curvature data | ||
| BE61 | INC HL | |||
| BE62 | LD H,(HL) | |||
| BE63 | LD L,A | |||
| BE64 | LD ($BBC2),HL | Self modify 'LD HL,$xxxx' @ BBC1 to load the address | ||
| BE67 | LD HL,$E2C6 | HL = forked_road_curvature -> forked road left curvature data | ||
| BE6A | JR rm_read_curvature | Jump to rm_read_curvature | ||
|
Handle a command byte of one: use the default (self-modified) map curvature address.
|
||||
| rm_curvature_one_command | BE6C | LD HL,$0000 | HL = <map curvature address> -- Self modified by ef_set_handlers | |
| BE6F | JR rm_read_curvature | Jump to rm_read_curvature | ||
|
Handle a command byte of zero: jump to the address given in next two bytes.
|
||||
| rm_curvature_jump_command | BE71 | LD A,(HL) | HL = wordat(HL) | |
| BE72 | INC HL | |||
| BE73 | LD H,(HL) | |||
| BE74 | LD L,A | |||
| rm_read_curvature | BE75 | EX DE,HL | DE is now map curvature address | |
| BE76 | LD A,(DE) | Read a curvature byte (regular, not an escape) | ||
| rm_curvature_regular_byte | BE77 | LD ($A26E),DE | road_curvature_ptr = DE | |
| BE7B | SUB $10 | A -= 16 -- decrement counter in top nibble | ||
| rm_save_curvature_byte | BE7D | LD ($A242),A | curvature_byte = A | |
| BE80 | AND $0F | Isolate direction bits | ||
| BE82 | BIT 3,A | Jump to rm_set_curvature if (A & (1<<3)) is zero -- bit 3 => left (so jump if right) | ||
| BE84 | JR Z,rm_set_curvature | |||
| BE86 | AND $07 | A = -(A & 7) -- Left direction becomes -ve | ||
| BE88 | NEG | |||
|
Write the direction into the cyclic road buffer.
|
||||
| rm_set_curvature | BE8A | ADD A,A | *HL = A * 2 -- Sampled HL: $EEA9 [in cyclic road buffer] | |
| BE8B | LD (HL),A | |||
|
-- HEIGHT --
|
||||
| BE8C | LD A,L | L += 32 | ||
| BE8D | ADD A,$20 | |||
| BE8F | LD L,A | |||
|
The top nibble of each byte is a counter. The bottom nibble is height data.
|
||||
| BE90 | LD A,($A243) | A = height_byte - 16 | ||
| BE93 | SUB $10 | |||
| BE95 | JR NC,rm_save_height_byte | Jump to rm_save_height_byte if height_byte >= 16 | ||
| BE97 | LD DE,($A270) | Read and increment address of height data | ||
| BE9B | INC DE | |||
| BE9C | LD A,(DE) | Read a height byte | ||
| BE9D | OR A | Jump to rm_height_regular_byte if non-zero | ||
| BE9E | JR NZ,rm_height_regular_byte | |||
|
Handle height escape byte.
|
||||
| BEA0 | EX DE,HL | HL is now address of escape byte | ||
| BEA1 | INC HL | Increment, read command byte, increment again | ||
| BEA2 | LD A,(HL) | |||
| BEA3 | INC HL | |||
| BEA4 | AND A | Jump to rm_height_jump_command if command byte is zero | ||
| BEA5 | JR Z,rm_height_jump_command | |||
| BEA7 | DEC A | |||
| BEA8 | JR Z,rm_height_one_command | Jump to rm_height_one_command if command byte is one | ||
|
Otherwise it must be a fork road command (byte == 2).
|
||||
| BEAA | LD C,(HL) | Load address of left route's height data | ||
| BEAB | INC HL | |||
| BEAC | LD B,(HL) | |||
| BEAD | INC HL | |||
| BEAE | LD ($BB98),BC | Self modify 'LD DE,$xxxx' @ BB97 to load the address | ||
| BEB2 | LD A,(HL) | Load address of right route's height data | ||
| BEB3 | INC HL | |||
| BEB4 | LD H,(HL) | |||
| BEB5 | LD L,A | |||
| BEB6 | LD ($BBC5),HL | Self modify 'LD DE,$xxxx' @ BBC4 to load the address | ||
| BEB9 | LD HL,$E2CC | HL = forked_road_height -> forked road height data | ||
| BEBC | JR rm_read_height | Jump to rm_read_height | ||
| rm_height_one_command | BEBE | LD HL,$0000 | HL = <something> -- Self modified by BBCF | |
| BEC1 | JR rm_read_height | Jump to rm_read_height | ||
| rm_height_jump_command | BEC3 | LD A,(HL) | HL = wordat(HL) | |
| BEC4 | INC HL | |||
| BEC5 | LD H,(HL) | |||
| BEC6 | LD L,A | |||
| rm_read_height | BEC7 | EX DE,HL | DE is now height address | |
| BEC8 | LD A,(DE) | Read a height byte (regular, not an escape) | ||
| rm_height_regular_byte | BEC9 | LD ($A270),DE | road_height_ptr = DE | |
| BECD | SUB $10 | A -= 16 -- decrement counter in top nibble | ||
| rm_save_height_byte | BECF | LD ($A243),A | height_byte = A | |
| BED2 | AND $0F | *HL = (A & 15) - 8 -- Sampled HL: $EEC9 [in cyclic road buffer] | ||
| BED4 | SUB $08 | |||
| BED6 | LD (HL),A | |||
| BED7 | LD A,L | L += 32 | ||
| BED8 | ADD A,$20 | |||
| BEDA | LD L,A | |||
|
-- LANES --
Lanes bytes are counted (like RLE).
|
||||
| BEDB | LD A,($A247) | Decrement the lanes counter | ||
| BEDE | SUB $01 | |||
| BEE0 | JR NC,rm_lanes_count_resume | Jump to rm_lanes_count_resume if non-zero | ||
|
Lanes counter hit zero, so reload.
|
||||
| BEE2 | LD DE,($A272) | Read and increment address of lanes data | ||
| BEE6 | INC DE | |||
| BEE7 | LD A,(DE) | Read a lanes byte | ||
| BEE8 | OR A | Jump to rm_lanes_regular_byte if non-zero | ||
| BEE9 | JR NZ,rm_lanes_regular_byte | |||
|
Handle lanes escape byte.
|
||||
| BEEB | EX DE,HL | HL is now address of escape byte | ||
| BEEC | INC HL | Increment, read command byte, increment again | ||
| BEED | LD A,(HL) | |||
| BEEE | INC HL | |||
| BEEF | AND A | Jump to rm_lanes_jump_command if command byte is zero | ||
| BEF0 | JR Z,rm_lanes_jump_command | |||
| BEF2 | DEC A | Jump to rm_lanes_one_command if command byte is one | ||
| BEF3 | JR Z,rm_lanes_one_command | |||
|
Otherwise it must be a fork road command (byte == 2).
|
||||
| BEF5 | LD C,(HL) | Load address of left route's lanes data | ||
| BEF6 | INC HL | |||
| BEF7 | LD B,(HL) | |||
| BEF8 | INC HL | |||
| BEF9 | LD ($BB9B),BC | Self modify 'LD BC,$xxxx' @ BB9A to load the address | ||
| BEFD | LD A,(HL) | Load address of right route's lanes data | ||
| BEFE | INC HL | |||
| BEFF | LD H,(HL) | |||
| BF00 | LD L,A | |||
| BF01 | LD ($BBC8),HL | Self modify 'LD BC,$xxxx' @ BBC7 to load the address | ||
| BF04 | LD HL,$E2D1 | HL = forked_road_lanes -> forked road lanes data | ||
| BF07 | JR rm_read_lanes | Jump to rm_read_lanes | ||
| rm_lanes_one_command | BF09 | LD HL,$0000 | HL = $0000 -- This looks setup for it as others, but doesn't seem to be self modified. | |
| BF0C | JR rm_read_lanes | Jump to rm_read_lanes | ||
| rm_lanes_jump_command | BF0E | LD A,(HL) | HL = wordat(HL) | |
| BF0F | INC HL | |||
| BF10 | LD H,(HL) | |||
| BF11 | LD L,A | |||
| rm_read_lanes | BF12 | EX DE,HL | DE is now lanes address | |
| BF13 | LD A,(DE) | Read a lanes byte (regular, not an escape) | ||
| rm_lanes_regular_byte | BF14 | DEC A | lanes_counter_byte = (lanes byte) - 1 | |
| BF15 | LD ($A247),A | |||
| BF18 | INC DE | road_lanes_ptr = ++DE | ||
| BF19 | LD ($A272),DE | |||
|
Store (map byte & $F7) to cyclic road buffer (HL).
|
||||
| BF1D | LD A,(DE) | *HL = *DE & $F7 | ||
| BF1E | AND $F7 | |||
| BF20 | LD (HL),A | |||
|
Store (map byte & $FB) to LD A below.
|
||||
| BF21 | LD A,(DE) | A = *DE & $FB | ||
| BF22 | AND $FB | |||
| BF24 | LD ($BF2D),A | Self modify 'LD A,$xx' @ BF2C (below) | ||
| BF27 | JR rm_lanes_done | Jump to rm_lanes_done | ||
|
Resume updating lanes data.
|
||||
| rm_lanes_count_resume | BF29 | LD ($A247),A | Store decremented lanes counter | |
| BF2C | LD A,$00 | A = <self modified value> -- Self modified above AND below | ||
| BF2E | LD C,A | C = A -- Save temporarily | ||
| BF2F | AND $0C | Jump to rm_lanes_bf39 if (A & $0C) is zero | ||
| BF31 | JR Z,rm_lanes_bf39 | |||
|
(bottom two bits significant) $F3 is complement of $0C
|
||||
| BF33 | LD A,C | A = C & $F3 -- discard bit 3 only? | ||
| BF34 | AND $F3 | |||
| BF36 | LD ($BF2D),A | Self modify 'LD A,$xx' @ BF2C (above) | ||
| rm_lanes_bf39 | BF39 | LD (HL),C | Store to cyclic road buffer (HL) | |
| rm_lanes_done | BF3A | LD A,L | L += 32 | |
| BF3B | ADD A,$20 | |||
| BF3D | LD L,A | |||
|
-- SKIPPING ALL OBJECTS AND HAZARDS --
|
||||
| BF3E | LD A,($A185) | Decrement no_objects_counter | ||
| BF41 | DEC A | |||
| BF42 | JR Z,rm_rightside | Jump to rm_rightside if it's zero | ||
|
Clear the right side, left side and hazards
|
||||
| BF44 | LD C,$00 | HL[ 0] = 0 | ||
| BF46 | LD (HL),C | |||
| BF47 | LD A,L | |||
| BF48 | ADD A,$20 | |||
| BF4A | LD L,A | |||
| BF4B | LD (HL),C | HL[32] = 0 | ||
| BF4C | ADD A,$20 | |||
| BF4E | LD L,A | |||
| BF4F | LD (HL),C | HL[64] = 0 | ||
| BF50 | LD A,$01 | Reset no_objects_counter to 1 | ||
| BF52 | JP rm_all_hazards | Jump to rm_all_hazards | ||
|
-- RIGHT-SIDE OBJECTS --
The top nibble of each byte is a counter. The bottom nibble is rightside data.
|
||||
| rm_rightside | BF55 | LD A,($A245) | A = rightside_byte - 16 | |
| BF58 | SUB $10 | |||
| BF5A | JR NC,rm_rightside_count_resume | Jump to rm_rightside_count_resume if rightside_byte >= 16 | ||
|
Rightside counter hit zero, so reload.
|
||||
| BF5C | LD DE,($A274) | Read and increment address of rightside data | ||
| BF60 | INC DE | |||
| BF61 | LD A,(DE) | Read a rightside byte | ||
| BF62 | AND A | Jump to rm_rightside_regular_byte if non-zero | ||
| BF63 | JR NZ,rm_rightside_regular_byte | |||
|
Handle rightside escape byte.
|
||||
| BF65 | EX DE,HL | HL is now address of escape byte | ||
| BF66 | INC HL | Increment, read command byte, increment again | ||
| BF67 | LD A,(HL) | |||
| BF68 | INC HL | |||
| BF69 | AND A | Jump to rm_rightside_jump_command if command byte is zero | ||
| BF6A | JR Z,rm_rightside_jump_command | |||
| BF6C | DEC A | Jump to rm_rightside_one_command if command byte is one | ||
| BF6D | JR Z,rm_rightside_one_command | |||
|
Otherwise it must be a fork road command (byte == 2).
|
||||
| BF6F | LD C,(HL) | Load address of left route's rightside data | ||
| BF70 | INC HL | |||
| BF71 | LD B,(HL) | |||
| BF72 | INC HL | |||
| BF73 | LD ($BB8E),BC | Set modify 'LD DE,$xxxx' @ BB8D to load the address | ||
| BF77 | LD A,(HL) | Load address of right route's rightside data | ||
| BF78 | INC HL | |||
| BF79 | LD H,(HL) | |||
| BF7A | LD L,A | |||
| BF7B | LD ($BBBB),HL | Self modify 'LD DE,$xxxx' @ BBBA to load the address | ||
| BF7E | LD HL,$E2C1 | HL = fork_leftrightobjs_loop | ||
| BF81 | JR rm_read_rightside | Jump to rm_read_rightside | ||
| rm_rightside_one_command | BF83 | LD HL,$0000 | HL = $0000 -- This looks setup for it as others, but doesn't seem to be self modified. | |
| BF86 | JR rm_read_rightside | Jump to rm_read_rightside | ||
| rm_rightside_jump_command | BF88 | LD A,(HL) | HL = wordat(HL) | |
| BF89 | INC HL | |||
| BF8A | LD H,(HL) | |||
| BF8B | LD L,A | |||
| rm_read_rightside | BF8C | EX DE,HL | DE is now lanes address | |
| BF8D | LD A,(DE) | Read a rightside byte (regular, not an escape) | ||
| rm_rightside_regular_byte | BF8E | LD ($A274),DE | road_rightside_ptr = DE | |
| BF92 | SUB $10 | A -= 16 | ||
| rm_rightside_count_resume | BF94 | LD ($A245),A | rightside_byte = A -- Store decremented rightside counter | |
| BF97 | AND $0F | *HL = A & $0F -- Write to cyclic road buffer | ||
| BF99 | LD (HL),A | |||
| BF9A | LD A,L | L += 32 | ||
| BF9B | ADD A,$20 | |||
| BF9D | LD L,A | |||
|
-- LEFT-SIDE OBJECTS --
|
||||
| BF9E | LD A,($A244) | A = leftside_byte - 16 | ||
| BFA1 | SUB $10 | |||
| BFA3 | JR NC,rm_leftside_count_resume | Jump to rm_leftside_count_resume if leftside_byte >= 16 | ||
| BFA5 | LD DE,($A276) | DE = road_leftside_ptr + 1 | ||
| BFA9 | INC DE | |||
| BFAA | LD A,(DE) | Read a lanes byte | ||
| BFAB | AND A | Jump to rm_leftside_regular_byte if non-zero | ||
| BFAC | JR NZ,rm_leftside_regular_byte | |||
|
Handle leftside escape byte.
|
||||
| BFAE | EX DE,HL | HL is now address of escape byte | ||
| BFAF | INC HL | Increment, read command byte, increment again | ||
| BFB0 | LD A,(HL) | |||
| BFB1 | INC HL | |||
| BFB2 | AND A | Jump to rm_leftside_jump_command if command byte is zero | ||
| BFB3 | JR Z,rm_leftside_jump_command | |||
| BFB5 | DEC A | Jump to rm_leftside_one_command if command byte is one | ||
| BFB6 | JR Z,rm_leftside_one_command | |||
|
Otherwise it must be a fork road command (byte == 2).
|
||||
| BFB8 | LD C,(HL) | Load address of left route's leftside data | ||
| BFB9 | INC HL | |||
| BFBA | LD B,(HL) | |||
| BFBB | INC HL | |||
| BFBC | LD ($BB91),BC | Self modify 'LD BC,$xxxx' @ BB90 | ||
| BFC0 | LD A,(HL) | Load address of right route's leftside data | ||
| BFC1 | INC HL | |||
| BFC2 | LD H,(HL) | |||
| BFC3 | LD L,A | |||
| BFC4 | LD ($BBBE),HL | Self modify 'LD BC,$xxxx' @ BBBD | ||
| BFC7 | LD HL,$E2C0 | HL = fork_leftrightobjs | ||
| BFCA | JR rm_read_leftside | Jump to rm_read_leftside | ||
| rm_leftside_one_command | BFCC | LD HL,$0000 | HL = $0000 -- This looks setup for it as others, but doesn't seem to be self modified. | |
| BFCF | JR rm_read_leftside | Jump to rm_read_leftside | ||
| rm_leftside_jump_command | BFD1 | LD A,(HL) | HL = wordat(HL) | |
| BFD2 | INC HL | |||
| BFD3 | LD H,(HL) | |||
| BFD4 | LD L,A | |||
| rm_read_leftside | BFD5 | EX DE,HL | DE is now lanes address | |
| BFD6 | LD A,(DE) | Read a leftside byte (regular, not an escape) | ||
| rm_leftside_regular_byte | BFD7 | LD ($A276),DE | road_leftside_ptr = DE | |
| BFDB | SUB $10 | A -= 16 | ||
| rm_leftside_count_resume | BFDD | LD ($A244),A | leftside_byte = A -- Store decremented leftside counter | |
| BFE0 | AND $0F | *HL = A & $0F -- Write to cyclic road buffer | ||
| BFE2 | LD (HL),A | |||
| BFE3 | LD A,L | L += 32 | ||
| BFE4 | ADD A,$20 | |||
| BFE6 | LD L,A | |||
|
-- HAZARDS --
|
||||
| BFE7 | LD A,($A246) | A = hazards_byte - 1 (a counter) | ||
| BFEA | SUB $01 | |||
| BFEC | JR NC,rm_set_hazards | Jump to rm_set_hazards if counter >= 1 | ||
|
Otherwise decode...
|
||||
| BFEE | LD DE,($A278) | DE = road_hazard_ptr + 1 | ||
| BFF2 | INC DE | |||
| rm_restart_hazards_read | BFF3 | LD A,(DE) | Read a hazards byte | |
| BFF4 | AND A | Jump to rm_hazards_regular_byte if non-zero | ||
| BFF5 | JR NZ,rm_hazards_regular_byte | |||
|
Handle hazards escape byte.
|
||||
| BFF7 | EX DE,HL | HL is now address of escape byte | ||
| BFF8 | INC HL | Increment, read command byte, increment again | ||
| BFF9 | LD A,(HL) | |||
| BFFA | INC HL | |||
| BFFB | AND A | Jump to rm_hazards_jump_command if command byte is zero | ||
| BFFC | JR Z,rm_hazards_jump_command | |||
| BFFE | DEC A | |||
| BFFF | JR Z,rm_hazards_one_command | Jump to rm_hazards_one_command if command byte is one | ||
| C001 | DEC A | Jump to rm_hazards_fork_road_command if command byte is two | ||
| C002 | JR Z,rm_hazards_fork_road_command | |||
| C004 | DEC A | |||
| C005 | CP $07 | Jump to rm_hazards_set_hazard_command if command byte is < 10 -- 3..9 | ||
| C007 | JR C,rm_hazards_set_hazard_command | |||
| C009 | CP $0A | Jump to rm_hazards_set_arrow_command if command byte is < 13 -- 10..12 | ||
| C00B | JR C,rm_hazards_set_arrow_command | |||
| C00D | CP $0C | Jump to rm_hazards_spawning_command if command byte is < 15 -- 13..14 | ||
| C00F | JR C,rm_hazards_spawning_command | |||
| C011 | SUB $0B | Otherwise helicopter_control = A - 11 | ||
| C013 | LD ($A224),A | |||
| C016 | JR rm_do_restart | Jump to rm_do_restart | ||
|
Handle car spawning commands (13/14 = enable/disable car spawning).
|
||||
| rm_hazards_spawning_command | C018 | SUB $0A | dont_spawn_cars = A - 10 (13/14 in map data) | |
| C01A | LD ($A225),A | |||
| C01D | JR rm_do_restart | Jump to rm_do_restart | ||
|
Handle floating arrow commands (10/11/12 = off/left/right).
|
||||
| rm_hazards_set_arrow_command | C01F | SUB $07 | floating_arrow = A - 7 (10/11/12 in map data) | |
| C021 | LD ($A227),A | |||
| C024 | JR Z,rm_do_restart | Jump to rm_do_restart if zero | ||
| C026 | LD ($A226),A | correct_fork = A (0 or 1) | ||
| rm_do_restart | C029 | EX DE,HL | ||
| C02A | JR rm_restart_hazards_read | Jump to rm_restart_hazards_read | ||
|
Handle hazard commands (3 = off, 4/5/6 = tumbleweeds left/right/both, 7/8/9 => barriers)
When on left it uses lane 1, on right it uses lane 4, both it uses lane 2 and 3.
|
||||
| rm_hazards_set_hazard_command | C02C | LD ($C059),A | Self modify 'LD (HL),xxxx' at C058 to load A [which is command_no-3] | |
| C02F | JR rm_read_hazards | Jump to rm_read_hazards | ||
| rm_hazards_fork_road_command | C031 | LD C,(HL) | Load address of left route's hazards data -- Sampled HL: $5F26 (road fork) | |
| C032 | INC HL | |||
| C033 | LD B,(HL) | |||
| C034 | INC HL | |||
| C035 | LD ($BB8B),BC | Self modify 'LD HL,$xxxx' @ BB8A | ||
| C039 | LD A,(HL) | Load address of right route's hazards data | ||
| C03A | INC HL | |||
| C03B | LD H,(HL) | |||
| C03C | LD L,A | |||
| C03D | LD ($BBB8),HL | Self modify 'LD HL,$xxxx' @ BBB7 | ||
| C040 | LD HL,$E2B8 | HL = fork_hazards | ||
| C043 | JR rm_read_hazards | Jump to rm_read_hazards | ||
| rm_hazards_one_command | C045 | LD HL,$0000 | HL = 0 | |
| C048 | JR rm_read_hazards | Jump to rm_read_hazards | ||
| rm_hazards_jump_command | C04A | LD A,(HL) | HL = wordat(HL) [Sampled HL: $6292 $6107 $61BC $600F] | |
| C04B | INC HL | |||
| C04C | LD H,(HL) | |||
| C04D | LD L,A | |||
| rm_read_hazards | C04E | EX DE,HL | DE is now hazards address | |
| C04F | LD A,(DE) | Read a hazards byte (regular, not an escape) | ||
| rm_hazards_regular_byte | C050 | LD ($A278),DE | Update road_hazard_ptr | |
| C054 | DEC A | Decrement counter | ||
| rm_set_hazards | C055 | LD ($A246),A | Update counter | |
| C058 | LD (HL),$00 | Write <current hazard command - self modified> to the cyclic road buffer | ||
| C05A | LD A,$02 | no_objects_counter = 2 | ||
| rm_all_hazards | C05C | LD ($A185),A | Set no_objects_counter to A | |
| C05F | CALL update_road_level | Call update_road_level to update the road level | ||
| C062 | LD IX,$A188 | Point IX at hazards[0] | ||
| C066 | LD DE,$0014 | Stride of hazards is 20 bytes | ||
| C069 | LD BC,$0600 | 6 iterations in B & clear overtake counter in C | ||
| rm_hazard_loop | C06C | RLC (IX+$00) | If the hazard is active then jump to rm_active_hazard | |
| C070 | JR C,rm_active_hazard | |||
| rm_hazard_loop_continue | C072 | ADD IX,DE | Move to next hazard | |
| C074 | DJNZ rm_hazard_loop | Loop while B | ||
| C076 | LD A,C | Copy overtake counter | ||
| C077 | LD HL,$A22B | Point HL at overtake_bonus_counter | ||
| C07A | LD HL,$A22B | Bug: duplicated instruction | ||
| C07D | LD (HL),A | Store the number of cars overtaken [only cars!] | ||
| C07E | JR rm_hazard_continue | Jump to rm_hazard_continue | ||
|
Could be any active hazard here.
|
||||
| rm_active_hazard | C080 | LD A,(IX+$0F) | A = IX[15] + 1 | |
| C083 | INC A | |||
| C084 | JR Z,rm_decrement_distance | Jump to rm_decrement_distance if zero | ||
| C086 | DEC (IX+$01) | IX[1]-- -- buffer offset/distance | ||
| C089 | JP NZ,rm_hazard_loop_continue | Jump to rm_hazard_loop_continue if non-zero | ||
| C08C | LD (IX+$00),$00 | Mark the hazard entry unused | ||
| C090 | RLA | Top bit of A set if hazard is vehicle | ||
| C091 | JR NC,rm_hazard_loop_continue | Jump to rm_hazard_loop_continue if no carry - hazard is not vehicle | ||
|
Overtook a car.
|
||||
| C093 | INC C | Increment overtake counter | ||
| C094 | JR rm_hazard_loop_continue | Jump to rm_hazard_loop_continue | ||
|
Not perp specific: every occupied hazard slot has its distance decremented here each time the road buffer cycles, so this runs whenever hazards are in play.
|
||||
| rm_decrement_distance | C096 | LD A,(IX+$01) | Decrement the low byte of the distance | |
| C099 | SUB $01 | |||
| C09B | LD (IX+$01),A | |||
| C09E | JR C,rm_decrement_distance_high_byte | If the decrement carried (went 0 -> 255) jump to rm_decrement_distance_high_byte | ||
| C0A0 | JR NZ,rm_hazard_loop_continue | Jump to rm_hazard_loop_continue if non-zero | ||
|
Low byte of distance was zero.
|
||||
| C0A2 | LD A,(IX+$11) | Load distance high byte | ||
| C0A5 | AND A | Jump to rm_hazard_loop_continue if non-zero | ||
| C0A6 | JR NZ,rm_hazard_loop_continue | |||
|
Both low and high bytes were zero - player has caught up with the perp. This will bump the perp forward so the player can never actually overtake them.
|
||||
| C0A8 | LD (IX+$01),$01 | Set perp to be just one unit away | ||
| C0AC | LD (IX+$04),$FF | Set distance high byte to 255 -- how's that work? | ||
| C0B0 | JR rm_hazard_loop_continue | Jump to rm_hazard_loop_continue | ||
| rm_decrement_distance_high_byte | C0B2 | LD A,(IX+$11) | Decrement the high byte of the distance | |
| C0B5 | DEC A | |||
| C0B6 | LD (IX+$11),A | |||
| C0B9 | JR rm_hazard_loop_continue | Jump to rm_hazard_loop_continue | ||
| rm_hazard_continue | C0BB | LD A,$00 | A = <self modified> -- Self modified by A977 + A9A0 only | |
| C0BD | AND A | Jump to rm_allow_car_spawning if zero | ||
| C0BE | JP Z,rm_allow_car_spawning | |||
|
Some sort of block copy.
|
||||
| C0C1 | LD HL,$ED73 | HL = $ED73 -- Source+2. This must be a buffer pointer at this point | ||
| C0C4 | LD DE,$ED77 | DE = $ED77 -- Destination+2 | ||
| C0C7 | LD BC,$0026 | BC = 38 -- Bytes? | ||
| rm_c0ca_loop | C0CA | DEC HL | HL -= 2 | |
| C0CB | DEC HL | |||
| C0CC | DEC DE | DE -= 2 | ||
| C0CD | DEC DE | |||
| C0CE | LDD | *DE-- = *HL--; BC-- | ||
| C0D0 | LDD | *DE-- = *HL--; BC-- | ||
|
Reached when the dirt/stones scroll flag is set: it shifts the fork x-position buffer down by one entry so the particles travel with the road.
|
||||
| C0D2 | JP PE,rm_c0ca_loop | Loop to rm_c0ca while B != 0 (LDD sets P/V if BC != 0) | ||
| C0D5 | INC HL | *++HL = 0 (since B is zero) | ||
| C0D6 | LD (HL),B | |||
| rm_allow_car_spawning | C0D7 | LD A,$01 | Set flag to allow car spawning | |
| rm_exit | C0D9 | LD HL,$A254 | Increment allow_spawning by A (which should be 0 or 1) | |
| C0DC | ADD A,(HL) | |||
| C0DD | LD (HL),A | |||
| C0DE | JP check_hazard_collisions | Exit via check_hazard_collisions/check_hazard_collisions | ||
| Prev: BDC1 | Up: Map | Next: C0E1 |