| Chase H.Q. | Routines |
| Prev: B059 | Up: Map | Next: B318 |
|
Called every frame to advance the hero car's physical state. While the car is airborne the jump counter feeds the pitch and the vertical position from the jump table. The boost timer, the smoke counter and the gear change lockout are counted down here too.
The speed limit is computed from the gear, the boost and whether the car is off road, corrected by the pitch when the car is inclined, then the speed is clamped to 0..511. Left and right turning forces accumulate from the user's input and are capped against the current speed. Curvature scroll ticks become a road_pos delta. The last two things written are turn_speed (0/1/2) and flip_car, which the sprite renderer reads.
Used by the routines at main_loop and drive_attract_demo.
|
||||
| move_hero_car | B063 | LD A,$00 | Load jump counter. Self modified by 8827 and B965. Highest is 8. | |
| B065 | AND A | Jump to mhc_set_jump_offset if the jump counter is zero | ||
| B066 | JR Z,mhc_set_jump_offset | |||
|
Hero car is jumping.
|
||||
| mhc_jumping | B068 | DEC A | Decrement the jump counter in (self modified) move_hero_car | |
| B069 | LD ($B064),A | |||
| B06C | JR NZ,mhc_midair | Jump to mhc_midair if we're still jumping | ||
|
Hero car has landed.
|
||||
| mhc_landed | B06E | LD A,$03 | smoke = 3 | |
| B070 | LD ($A24F),A | |||
| B073 | LD BC,$0203 | Effect 2 (car landing), Priority 3 | ||
| B076 | CALL start_sfx | Call start_sfx | ||
|
Hero car is in mid-air, or has just landed.
|
||||
| mhc_midair | B079 | LD HL,$0000 | Point HL at entry in jump(ing) table. Self modified by B96C and B092. Default is $B055. | |
| B07C | XOR A | off_road = 0 | ||
| B07D | LD ($A23E),A | |||
| B080 | LD A,($A0D5) | Clear up/down/left/right bits of user input (stop the player from turning when in mid-air) | ||
| B083 | AND $F0 | |||
| B085 | LD ($A0D5),A | |||
|
The low bytes of the hero_car_jump_table entries are the car's pitch (0/3/6).
|
||||
| B088 | LD A,(HL) | Self modify the 'ADD A,x' at #$B5AF to load the car's pitch | ||
| B089 | LD ($B5B0),A | |||
| B08C | INC HL | |||
|
The high bytes of the entries are the car's jump offset (-13..13).
|
||||
| B08D | LD A,($B5AB) | A = *$B5AB + *HL++ -- Self modified value in draw_hero_car | ||
| B090 | ADD A,(HL) | |||
| B091 | INC HL | |||
| B092 | LD ($B07A),HL | Update HL jump table entry address above @ mhc_midair | ||
| mhc_set_jump_offset | B095 | LD ($B5AB),A | Self modify 'SUB x' @ B5AA to be the new car jump offset | |
| B098 | LD HL,$A24E | Load address of boost timer | ||
| B09B | LD A,(HL) | Jump to mhc_smoke if a turbo boost is not in effect | ||
| B09C | AND A | |||
| B09D | JR Z,mhc_smoke | |||
| B09F | DEC (HL) | Decrement boost timer | ||
| B0A0 | JR NZ,mhc_smoke | Jump to mhc_smoke if boost timer is non-zero | ||
| B0A2 | LD A,($A170) | Decrement turbo boost count [POKE $B0A5,0 for Infinite turbos] | ||
| B0A5 | DEC A | |||
| B0A6 | LD ($A170),A | |||
|
Handle smoke effect.
|
||||
| mhc_smoke | B0A9 | INC HL | HL now points at smoke | |
| B0AA | LD A,(HL) | Jump if smoke is zero | ||
| B0AB | AND A | |||
| B0AC | JR Z,mhc_gear_change | |||
| B0AE | DEC (HL) | Decrement smoke | ||
|
Handle gear changes.
|
||||
| mhc_gear_change | B0AF | LD A,($A0D5) | Read user input | |
| B0B2 | LD C,A | Preserve it in C | ||
| B0B3 | LD A,($B326) | Read from the 'LD A,x' @ ahc_check_crashed (crashed flag) | ||
| B0B6 | AND A | Jump if zero | ||
| B0B7 | JR Z,mhc_b0bd | |||
|
Otherwise the crashed flag is set.
|
||||
| B0B9 | LD A,C | Change user input to be ONLY the fire/gear flag (if set) | ||
| B0BA | AND $10 | |||
| B0BC | LD C,A | |||
| mhc_b0bd | B0BD | LD A,C | A = C | |
| B0BE | PUSH AF | Preserve the modified user input for later | ||
| B0BF | BIT 4,A | Test fire/gear flag | ||
| B0C1 | LD HL,$A253 | Load address of gear flag | ||
| B0C4 | LD A,($A252) | Load gear_lockout | ||
| B0C7 | JR Z,mhc_b0d7 | Jump if fire/gear is unset | ||
|
Fire/gear was set.
|
||||
| B0C9 | AND A | Jump if gear_lockout is set -- lock out gear changes while set | ||
| B0CA | JR NZ,mhc_b0d7 | |||
| B0CC | LD A,(HL) | Toggle gear flag | ||
| B0CD | XOR $01 | |||
| B0CF | LD (HL),A | |||
| B0D0 | LD A,$04 | Smoke time remaining | ||
| B0D2 | JR Z,mhc_b0d7 | Jump if low gear | ||
| B0D4 | LD ($A24F),A | Set smoke counter | ||
| mhc_b0d7 | B0D7 | SUB $01 | Decrement A -- SUB, not DEC A, because JR C below tests the carry flag DEC A wouldn't set | |
| B0D9 | JR C,mhc_b0de | Jump if negative result | ||
| B0DB | LD ($A252),A | gear_lockout = A | ||
| mhc_b0de | B0DE | LD A,(HL) | Read current gear flag | |
| B0DF | EX AF,AF' | Bank it | ||
| B0E0 | LD HL,($A24A) | Read current speed | ||
| B0E3 | PUSH HL | Stack current speed | ||
| B0E4 | LD DE,$0078 | Jump if speed >= 120 | ||
| B0E7 | SBC HL,DE | |||
| B0E9 | JR NC,mhc_done_idle | |||
|
Going slowly here (<120).
|
||||
| mhc_going_slow | B0EB | LD A,($A230) | Jump if perp_caught_phase > 0 -- Don't do idle handling if we're slowing while catching the perp | |
| B0EE | AND A | |||
| B0EF | JR NZ,mhc_done_idle | |||
|
Handle idle timer.
|
||||
| mhc_idle_timer | B0F1 | LD HL,$A16E | Load address of idle timer | |
| B0F4 | DEC (HL) | Decrement idle timer | ||
| B0F5 | JR NZ,mhc_done_idle | Jump if non-zero | ||
| mhc_reset_idle_timer | B0F7 | LD (HL),$64 | Reset idle timer to 100 | |
| B0F9 | LD A,$0A | Set priority to 10 | ||
| B0FB | LD HL,$98F8 | Point HL at get_moving_chatter (Raymond: "LET'S GET MOVIN' MAN!") | ||
| B0FE | CALL start_chatter | Call start_chatter (priority 10) | ||
| mhc_done_idle | B101 | POP HL | Pop current speed | |
| B102 | LD D,H | Save current speed in DE for later | ||
| B103 | LD E,L | |||
| B104 | LD A,($A23E) | Load the off-road flag | ||
| B107 | AND A | Jump if zero (fully on-road) | ||
| B108 | JR Z,mhc_done_offroad | |||
|
Handle off-road (A can be 1 or 2 here).
|
||||
| mhc_offroad | B10A | LD BC,$0078 | Set max speed for when one wheel off-road (120 => ~100?) | |
| B10D | DEC A | Jump if off-road was one | ||
| B10E | JR Z,mhc_chose_offroad_speed | |||
| B110 | LD BC,$006E | Set max speed for when both wheels off-road (110 => ~90?) | ||
| mhc_chose_offroad_speed | B113 | AND A | Clear carry | |
| B114 | SBC HL,BC | 16-bit subtract only for result in flags | ||
| B116 | LD H,D | Restore current speed saved earlier | ||
| B117 | LD L,E | |||
| B118 | JR C,mhc_done_offroad | Jump if current speed (HL) < max speed (DE) -- already within the off-road cap, so nothing to shed | ||
|
Decelerate in proportion to speed while off-road: the delta is speed / 32, kept to four bits and forced to at least 1, then negated. If it's NOPped out then going offroad will cause max speed.
|
||||
| mhc_offroad_reduce_speed | B11A | LD A,L | Current speed low byte | |
| B11B | RR H | Bottom bit of H moves to carry | ||
| B11D | RLA | A <<= 4 -- 9 bit rotate left through carry | ||
| B11E | RLA | |||
| B11F | RLA | |||
| B120 | RLA | |||
| B121 | AND $0F | A = -((A & $0F) | 1) -- top four bits of speed... at least one | ||
| B123 | OR $01 | |||
| B125 | NEG | |||
| B127 | LD C,A | BC = $FF00 | A -- speed delta (slowing) | ||
| B128 | LD B,$FF | |||
| B12A | JP mhc_check_brake | Jump to mhc_check_brake | ||
| mhc_done_offroad | B12D | LD A,($A24E) | Load turbo boost time remaining (60..0) | |
| B130 | AND A | Test | ||
| B131 | EX AF,AF' | Bank with flags | ||
| B132 | AND A | Test previously banked copy of gear flag | ||
| B133 | JR NZ,mhc_high_gear | Jump if in high gear | ||
| mhc_low_gear | B135 | LD BC,$01D6 | BC = 470 -- max speed? | |
| B138 | EX AF,AF' | Unbank turbo boost with flags | ||
| B139 | JR NZ,mhc_low_gear_slowing | Jump if turbo boost in effect -- Uses banked flags | ||
|
No turbo boost.
|
||||
| B13B | LD BC,$00E6 | BC = 230 -- max speed? | ||
| mhc_low_gear_slowing | B13E | SBC HL,BC | HL -= BC | |
| B140 | JP NC,mhc_low_gear_accelerating | Jump if HL was >= BC -- speed > limit value | ||
| B143 | LD A,L | BC = ~HL + 1 = -HL | ||
| B144 | CPL | |||
| B145 | LD C,A | |||
| B146 | LD A,H | |||
| B147 | CPL | |||
| B148 | LD B,A | |||
| B149 | INC BC | |||
| B14A | LD A,C | A = C | ||
| B14B | SRL B | Shift a bit out of B into A? | ||
| B14D | RRA | |||
| B14E | SRL B | and again -- B must now be zero | ||
| B150 | RRA | |||
| B151 | RRA | Then divide by 4? | ||
| B152 | RRA | |||
| B153 | AND $3F | C = (A & $3F) | 1 | ||
| B155 | OR $01 | |||
| B157 | LD C,A | |||
| B158 | JR mhc_check_brake | Jump to mhc_check_brake | ||
| mhc_low_gear_accelerating | B15A | LD A,L | A = L | |
| B15B | SRL H | A = HL >> 4 | ||
| B15D | RRA | |||
| B15E | SRL H | |||
| B160 | RRA | |||
| B161 | RRA | |||
| B162 | RRA | |||
| B163 | AND $1F | A = -((A & $1F) | 1) | ||
| B165 | OR $01 | |||
| B167 | NEG | |||
| B169 | LD C,A | BC = $FF00 | A -- speed delta (slowing) | ||
| B16A | LD B,$FF | |||
| B16C | JR mhc_check_brake | Jump to mhc_check_brake | ||
| mhc_high_gear | B16E | LD BC,$00DC | BC = 220 -- max speed? | |
| B171 | SBC HL,BC | 16-bit subtract only for result in flags | ||
| B173 | LD H,D | Restore current speed saved earlier | ||
| B174 | LD L,E | |||
| B175 | JR NC,mhc_high_gear_accelerating | Jump if current speed (HL) < max speed (DE) | ||
| mhc_high_gear_slowing | B177 | LD BC,$01D6 | BC = 470 -- max speed? | |
| B17A | EX AF,AF' | Unbank turbo boost with flags | ||
| B17B | JR NZ,mhc_low_gear_slowing | Jump if turbo boost in effect -- Uses banked flags | ||
| B17D | LD A,E | A = DE >> 4 | ||
| B17E | LD B,D | |||
| B17F | SRL B | |||
| B181 | RRA | |||
| B182 | SRL B | |||
| B184 | RRA | |||
| B185 | RRA | |||
| B186 | RRA | |||
| B187 | OR $01 | C = (A | 1) & $1F | ||
| B189 | AND $1F | |||
| B18B | LD C,A | |||
| B18C | JR mhc_check_brake | Jump to mhc_check_brake | ||
| mhc_high_gear_accelerating | B18E | LD BC,$02B7 | BC = 695 -- max speed? | |
| B191 | EX AF,AF' | Unbank turbo boost with flags | ||
| B192 | JR NZ,mhc_low_gear_slowing | Jump if turbo boost in effect -- Uses banked flags | ||
| B194 | LD BC,$0168 | BC = 360 -- max speed? | ||
| B197 | JP mhc_low_gear_slowing | Use mhc_low_gear_slowing | ||
| mhc_check_brake | B19A | POP AF | Get modified user input (stored by B0BE) | |
| B19B | PUSH AF | |||
| B19C | RRA | Is BRAKE pressed? (bit 2 / down) | ||
| B19D | RRA | |||
| B19E | RRA | |||
| B19F | JR NC,mhc_not_braking | Jump to mhc_not_braking if not pressed | ||
|
Braking
|
||||
| B1A1 | LD BC,$FFEC | Speed delta is -20 to slow down | ||
| B1A4 | JR mhc_calc_speed | Jump to mhc_calc_speed | ||
| mhc_not_braking | B1A6 | RRA | Is ACCELERATE pressed? (bit 3 / up) | |
| B1A7 | JR C,mhc_calc_speed | Jump if so {what's in BC? must be the speed delta from earlier} | ||
|
Not accelerating
|
||||
| B1A9 | LD BC,$FFF6 | Speed delta is -10 to gradually slow | ||
| mhc_calc_speed | B1AC | LD H,D | Copy speed from DE | |
| B1AD | LD L,E | |||
| B1AE | AND A | Clear carry | ||
| B1AF | ADC HL,BC | Change speed | ||
| B1B1 | JP P,mhc_speed_set | Jump if still positive or zero | ||
|
Cope with speed going negative
|
||||
| B1B4 | LD HL,$0000 | HL = $0000 | ||
|
HL = new speed
|
||||
| mhc_speed_set | B1B7 | LD A,($A24C) | A = inclined_counter - 1 (SUB, not DEC A, because the JR NC below tests the carry flag DEC A wouldn't set) | |
| B1BA | SUB $01 | |||
| B1BC | JR NC,mhc_set_inclined | Jump if A is now >= 0 | ||
|
"inclined" counter went -ve
|
||||
| B1BE | LD A,($B5B0) | A = $B5B0 -- read self modified value in draw_hero_car that sets the car's pitch (0/3/6) | ||
| B1C1 | AND A | Jump if zero (pitch is level) | ||
| B1C2 | JR Z,mhc_set_inclined | |||
| B1C4 | LD C,A | C = A -- temp save A | ||
| B1C5 | LD A,H | Jump if HL (new speed) is zero | ||
| B1C6 | OR L | |||
| B1C7 | JR Z,mhc_set_inclined | |||
|
new speed is non-zero
|
||||
| B1C9 | LD A,C | BC = (C - 5) | 1 -- 0/3/6 in C => -5/-1/1 in BC | ||
| B1CA | SUB $05 | |||
| B1CC | OR $01 | |||
| B1CE | LD C,A | |||
| B1CF | LD B,$00 | |||
| B1D1 | JP P,mhc_positive | Jump if result is positive | ||
| B1D4 | DEC B | BC = $FF00 | A -- otherwise widen as negative | ||
| mhc_positive | B1D5 | LD D,H | Copy speed from HL to DE | |
| B1D6 | LD E,L | |||
| B1D7 | ADD HL,BC | Increment speed ... by a value computed from car's pitch ... accelerating slowly when going upwards? | ||
| B1D8 | LD BC,$02B7 | Speed threshold 695 | ||
| B1DB | PUSH HL | Save it | ||
| B1DC | SBC HL,BC | Reduce speed by threshold | ||
| B1DE | POP HL | Restore it | ||
| B1DF | JR C,mhc_b1e2 | Jump if speed < 695, which it always is. B1EC caps the stored speed at 511, the largest acceleration any path above adds is 63 and the pitch term here adds at most 1, so the speed cannot exceed 575 by this point | ||
| B1E1 | EX DE,HL | Unreachable: restore the pre-increment speed | ||
| mhc_b1e2 | B1E2 | LD A,$03 | Set inclined to 3 | |
| mhc_set_inclined | B1E4 | LD ($A24C),A | inclined_counter = A | |
| B1E7 | LD A,H | A = H | ||
| B1E8 | CP $02 | CP 2 | ||
| B1EA | JR C,mhc_b1ef | |||
| B1EC | LD HL,$01FF | Cap speed to $1FF | ||
| mhc_b1ef | B1EF | LD ($A24A),HL | Set speed to HL | |
| B1F2 | POP HL | Restore HL -- the user input flags, popped earlier | ||
| B1F3 | LD A,($A263) | B = right_turn | ||
| B1F6 | LD B,A | |||
| B1F7 | LD A,($A264) | C = left_turn | ||
| B1FA | LD C,A | |||
| B1FB | LD A,($B064) | A = *$B064 -- Read jump counter [self modified] | ||
| B1FE | AND A | Jump to mhc_b253 if non-zero | ||
| B1FF | JP NZ,mhc_b253 | |||
|
Testing the user input flags in H: steering is ignored while the car is airborne (jump counter non-zero, checked above)
|
||||
| B202 | RR H | Shift LSB out of H | ||
| B204 | JR C,mhc_b21a | Jump to mhc_b21a if set | ||
| B206 | RR H | Shift new LSB out of H | ||
| B208 | JR C,mhc_b22c | Jump to mhc_b22c if set | ||
|
Reduce left turning force A = ((C >= 9) ? C - 9 : 0) = MAX(C - 9, 0) This instr is hit continuously
|
||||
| B20A | LD A,C | A = C - 9 -- left turning force from earlier | ||
| B20B | SUB $09 | |||
| B20D | JR NC,mhc_store_left_turning_force | Jump if C >= 9 | ||
| B20F | XOR A | A = 0 -- clamp | ||
| mhc_store_left_turning_force | B210 | LD C,A | C = A | |
|
Reduce right turning force A = ((B >= 9) ? B - 9 : 0) = MAX(B - 9, 0)
|
||||
| B211 | LD A,B | A = B - 9 -- right turning force from earlier | ||
| B212 | SUB $09 | |||
| B214 | JR NC,mhc_store_right_turning_force | Jump to mhc_b217 if B >= 9 | ||
| B216 | XOR A | A = 0 -- clamp | ||
| mhc_store_right_turning_force | B217 | LD B,A | B = A | |
| B218 | JR mhc_handle_speed | Jump to mhc_handle_speed | ||
|
B = ((B + 4 >= 36) ? 36 : B + 4) = MIN(36, B + 4) -- 36 is the max turning force
|
||||
| mhc_b21a | B21A | LD A,B | A = B + 4 | |
| B21B | ADD A,$04 | |||
| B21D | LD B,$24 | Jump if A >= 36 | ||
| B21F | CP B | |||
| B220 | JR NC,mhc_b223 | |||
| B222 | LD B,A | B = A | ||
|
C = ((C >= B) ? C - B : 0) = MAX(C - B, 0)
|
||||
| mhc_b223 | B223 | LD A,C | C -= B | |
| B224 | SUB B | |||
| B225 | LD C,A | |||
| B226 | JR NC,mhc_handle_speed | Jump to mhc_handle_speed if C >= B | ||
| B228 | LD C,$00 | C = 0 | ||
| B22A | JR mhc_handle_speed | Jump to mhc_handle_speed | ||
|
C = ((C + 4 >= 36) ? 36 : C + 4) = MIN(36, C + 4)
|
||||
| mhc_b22c | B22C | LD A,C | A = C + 4 | |
| B22D | ADD A,$04 | |||
| B22F | LD C,$24 | C = 36 | ||
| B231 | CP C | Jump to mhc_b235 if A >= 36 | ||
| B232 | JR NC,mhc_b235 | |||
| B234 | LD C,A | C = A | ||
|
B = ((B >= C) ? B - C : 0) = MAX(B - C, 0)
|
||||
| mhc_b235 | B235 | LD A,B | B -= C | |
| B236 | SUB C | |||
| B237 | LD B,A | |||
| B238 | JR NC,mhc_handle_speed | Jump to mhc_handle_speed if B >= C | ||
| B23A | LD B,$00 | B = 0 | ||
| mhc_handle_speed | B23C | LD HL,($A24A) | Load speed into HL | |
| B23F | LD A,L | Speed low byte | ||
| B240 | RR H | Bottom bit of H moves to carry (H now unused) | ||
| B242 | RRA | Halve speed, shifting carry in as MSB | ||
|
Divide by 2.666 but not quite right? Or is it twice that?
|
||||
| B243 | SRL A | A >>= 2 | ||
| B245 | SRL A | |||
| B247 | LD L,A | L = A | ||
| B248 | SRL L | L >>= 1 | ||
| B24A | ADD A,L | A += L | ||
| B24B | CP B | Jump if A >= B | ||
| B24C | JR NC,mhc_b24f | |||
| B24E | LD B,A | B = A | ||
| mhc_b24f | B24F | CP C | Jump if A >= C | |
| B250 | JR NC,mhc_b253 | |||
| B252 | LD C,A | C = A | ||
| mhc_b253 | B253 | PUSH BC | Store turning forces for later mhc_reset_turning_forces | |
| B254 | LD BC,$0000 | BC = $0000 | ||
| B257 | LD E,B | E = B, i.e. zero | ||
| B258 | LD A,($A25C) | Load current_curvature | ||
| B25B | OR A | Set flags | ||
| B25C | JP Z,mhc_straight_road | Jump to mhc_straight_road if zero | ||
| B25F | JP P,mhc_scroll_horizon | Jump to mhc_scroll_horizon if positive | ||
|
Negative scroll => scroll horizon right.
|
||||
| mhc_scroll_right | B262 | INC E | E++ -- i.e. 1 | |
| B263 | NEG | A = -A | ||
|
Positive scroll => scroll horizon left.
|
||||
| mhc_scroll_horizon | B265 | LD HL,$B827 | horizon_table - 1: the curvature magnitude added next is 1-based, so curvature 1 selects the first byte | |
| B268 | LD C,A | BC = A -- B is zero at this point | ||
| B269 | ADD HL,BC | HL += BC | ||
| B26A | LD A,($A261) | A = horizon_scroll_sub | ||
| B26D | LD C,A | C = A | ||
| B26E | EX AF,AF' | |||
| B26F | LD A,($A23F) | A = fast_counter - C | ||
| B272 | SUB C | |||
| B273 | AND A | Set flags | ||
| B274 | JR Z,mhc_straight_road | Jump if zero | ||
| B276 | LD C,(HL) | C = *HL | ||
| mhc_b277_loop | B277 | SUB C | A -= C | |
| B278 | JR C,mhc_b280 | Jump if carry | ||
| B27A | INC B | B++ | ||
| B27B | EX AF,AF' | |||
| B27C | ADD A,C | A += C | ||
| B27D | EX AF,AF' | |||
| B27E | JR mhc_b277_loop | Jump to mhc_b277_loop (above) | ||
| mhc_b280 | B280 | LD A,B | A = B | |
| B281 | AND A | Jump to mhc_b295 if A is zero | ||
| B282 | JR Z,mhc_b295 | |||
| B284 | LD HL,$A262 | HL = curvature_ticks | ||
| B287 | ADD A,(HL) | A += *HL | ||
| B288 | LD (HL),A | *HL = A | ||
| B289 | LD A,B | A = B * 3 | ||
| B28A | ADD A,A | |||
| B28B | ADD A,B | |||
| B28C | LD B,$00 | B = 0 | ||
| B28E | RR E | Bottom bit of E moves to carry | ||
| B290 | JR NC,mhc_b295 | Jump if clear | ||
| B292 | DEC B | B-- | ||
| B293 | NEG | A = -A | ||
| mhc_b295 | B295 | LD C,A | C = A | |
| B296 | EX AF,AF' | Bank the scroll amount just copied to C into A'. sh_curved_road in scroll_horizon reads it back; nothing between here and there executes EX AF,AF', so it survives. Only written when this path is reached, i.e. curvature is non-zero and ticks have elapsed | ||
| B297 | LD ($A261),A | horizon_scroll_sub = A [the value unbanked by the EX above] | ||
|
No curvature - No scroll required?
|
||||
| mhc_straight_road | B29A | LD HL,($A25F) | HL = horizontal_adjust + BC | |
| B29D | ADD HL,BC | |||
| B29E | LD DE,$0000 | horizontal_adjust = 0 | ||
| B2A1 | LD ($A25F),DE | |||
| B2A5 | LD A,($B326) | A = *$B326 -- Read self modified op in animate_hero_car -- crashed flag | ||
| B2A8 | AND A | Set flags | ||
| B2A9 | JR Z,mhc_reset_turning_forces | Jump to mhc_b2ad if zero | ||
| B2AB | EX DE,HL | DE <> HL | ||
| B2AC | LD D,H | D = H [must be a delta] | ||
| mhc_reset_turning_forces | B2AD | POP BC | Restore turning forces | |
| B2AE | LD A,B | right_turn = B | ||
| B2AF | LD ($A263),A | |||
| B2B2 | LD A,C | left_turn = C | ||
| B2B3 | LD ($A264),A | |||
| B2B6 | SUB B | A -= B | ||
| B2B7 | JP P,mhc_b2bb | Jump to mhc_b2bb if positive | ||
| B2BA | DEC D | Otherwise decrement D | ||
| mhc_b2bb | B2BB | LD E,A | E = A >> 1 | |
| B2BC | SRA E | |||
| B2BE | ADD HL,DE | HL += DE | ||
| B2BF | OR A | Set flags | ||
| B2C0 | JR Z,mhc_set_cornering | Jump to mhc_set_cornering if zero | ||
| B2C2 | JP P,mhc_check_cornering | Jump if positive | ||
| B2C5 | NEG | A = -A | ||
| mhc_check_cornering | B2C7 | CP $11 | Compare A to 17 | |
| B2C9 | LD A,$00 | A = 0 -- cornering = 0 | ||
| B2CB | JR C,mhc_set_cornering | Jump to mhc_set_cornering if A < 17 | ||
| B2CD | BIT 7,H | Jump if H bit 7 clear | ||
| B2CF | JR Z,mhc_b2db | |||
| B2D1 | BIT 7,D | Jump to mhc_set_cornering if D bit 7 set | ||
| B2D3 | JR NZ,mhc_set_cornering | |||
| B2D5 | BIT 7,H | Jump to mhc_set_cornering if H bit 7 clear -- bug? already tested above | ||
| B2D7 | JR Z,mhc_set_cornering | |||
| B2D9 | JR mhc_is_cornering | Jump to mhc_is_cornering | ||
| mhc_b2db | B2DB | BIT 7,D | Jump to mhc_set_cornering if D bit 7 clear | |
| B2DD | JR Z,mhc_set_cornering | |||
| B2DF | BIT 7,H | Jump to mhc_set_cornering if H bit 7 set | ||
| B2E1 | JR NZ,mhc_set_cornering | |||
| mhc_is_cornering | B2E3 | LD A,$01 | A = 1 | |
| mhc_set_cornering | B2E5 | LD ($A24D),A | cornering = A | |
| B2E8 | LD BC,($A26C) | road_pos += HL [must be a delta] | ||
| B2EC | ADD HL,BC | |||
| B2ED | LD ($A26C),HL | |||
| B2F0 | LD D,$01 | D = 1 -- flip flag | ||
| B2F2 | LD A,E | A = E -- E holds half the (right_turn - left_turn) delta set at mhc_b2bb | ||
| B2F3 | OR A | Set flags -- OR A and AND A are equivalent here (both test sign/zero and clear carry); the choice is stylistic | ||
| B2F4 | JP P,mhc_decide_turn_speed | Jump if positive | ||
| B2F7 | DEC D | D-- -- flip flag -> 0 | ||
| B2F8 | NEG | A = -A | ||
| mhc_decide_turn_speed | B2FA | CP $0C | Compare A to 12 | |
| B2FC | LD B,$02 | 2 => Turn hard | ||
| B2FE | JR NC,mhc_exit | Jump to mhc_exit if A >= 12 | ||
| B300 | DEC B | 1 => Turn | ||
| B301 | CP $06 | Compare A to 6 | ||
| B303 | JR NC,mhc_exit | Jump to mhc_exit if A >= 6 | ||
| B305 | DEC B | 0 => Straight | ||
| mhc_exit | B306 | LD A,B | turn_speed = B -- should be 0/1/2 | |
| B307 | LD ($A250),A | |||
| B30A | LD A,D | flip_car = D -- should be 0/1 | ||
| B30B | LD ($A251),A | |||
| B30E | LD A,($B064) | A = *$B064 -- Read jump counter [self modified] | ||
| B311 | AND A | Return if zero | ||
| B312 | RET Z | |||
| B313 | XOR A | cornering = 0 -- reset cornering if jumping | ||
| B314 | LD ($A24D),A | |||
| B317 | RET | Return | ||
| Prev: B059 | Up: Map | Next: B318 |