| Chase H.Q. | Game status buffer |
| Prev: A0CC | Up: Map | Next: A27A |
|
|
||||
| mode_128k | A139 | DEFB $00 | 0/1 => 48K/128K mode | |
| current_stage_number | A13A | DEFB $01 | Current stage number | |
| start_speech_cycle | A13B | DEFB $04 | Used by 8424. Starts at 4 and cycles 3, 2, 1 with each restart of the game, varying the speech sample played at stage start | |
| overtake_bonus_bcd | A13C | DEFB $00 | Overtake combo bonus counter. BCD. This increases by 2 for each overtake and is reset on a crash. | |
| credits | A13D | DEFB $00 | Number of credits remaining (2 for a new game) | |
|
Data copied to $A16D+.
|
||||
| saved_game_state | A13E | DEFB $01 | Copied to spawn_accumulator | |
| A13F | DEFB $64 | Copied to idle_timer | ||
| A140 | DEFB $FF | Copied to user_input_mask | ||
| A141 | DEFB $03 | Copied to turbos | ||
| A142 | DEFW $0054 | Copied to horizon_level | ||
| A144 | DEFB $14 | Copied to perp_halt_counter | ||
| A145 | DEFB $FF | Copied to displayed_gear | ||
| A146 | DEFB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF | Copied to score_digits | ||
| A14E | DEFB $0F | Copied to time_sixteenths | ||
| A14F | DEFB $60 | Copied to time_bcd | ||
| A150 | DEFB $FF,$FF | Copies to time_digits | ||
| A152 | DEFB $FF,$FF,$FF,$FF | Copied to distance_digits | ||
| A156 | DEFB $01 | Copied to no_objects_counter | ||
| A157 | DEFW $59BF | Copied to horizon_attribute | ||
| A159 | DEFB $00 | Copied to hazards[0].0 | ||
| A15A | DEFB $64 | Copied to hazards[0].1 (distance low byte) | ||
| A15B | DEFB $00 | Copied to hazards[0].2 | ||
| A15C | DEFB $00 | Copied to hazards[0].3 | ||
| A15D | DEFB $00 | Copied to hazards[0].4 | ||
| A15E | DEFB $47 | Copied to hazards[0].5 | ||
| A15F | DEFB $00 | Copied to hazards[0].6 | ||
| A160 | DEFB $00 | Copied to hazards[0].7 | ||
| A161 | DEFB $2C | Copied to hazards[0].8 | ||
| A162 | DEFW $0000 | Copied to hazards[0].9 (car LOD) | ||
| A164 | DEFW perp_behaviour | Copied to hazards[0].11 (== perp_behaviour) | ||
| A166 | DEFW $003C | Copied to hazards[0].13 (horz pos) | ||
| A168 | DEFB $FF | Copied to hazards[0].15 | ||
| A169 | DEFB $00 | Copied to hazards[0].16 | ||
| A16A | DEFB $03 | Copied to hazards[0].17 (distance high byte) | ||
| A16B | DEFB $02 | Copied to hazards[0].18 | ||
| A16C | DEFB $00 | Copied to hazards[0].19 | ||
|
Usually 1. Oscillates 0/1 when the road forks. Adjusts horizontal position of the untaken road.
|
||||
| spawn_accumulator | A16D | DEFB $00 | Used by BC36 | |
| idle_timer | A16E | DEFB $00 | Idle timer. Counts down from 100. Recommences whenever the hero car is stopped. When it hits zero Raymond will say "LET'S GET MOVIN' MAN!" and it will be reset to 100. | |
| user_input_mask | A16F | DEFB $00 | User input mask, set to $C0 (Quit+Pause) when perp is fully smashed, or $FF otherwise | |
| turbos | A170 | DEFB $00 | Number of turbo boosts remaining (3 for a new game) | |
| horizon_level | A171 | DEFW $0000 | Height of the horizon, accumulated by scroll_horizon from the road's incline and signed by the direction of travel. Read a byte at a time: the high byte is the horizon's row, the low byte its sub-row phase. | |
| perp_halt_counter | A173 | DEFB $00 | A counter decremented while slowing down the caught perp. This is set to 20 by #$87ED then decremented by 8BC6. | |
| displayed_gear | A174 | DEFB $00 | Low/high gear flag. | |
| score_digits | A175 | DEFB $00,$00,$00,$00,$00,$00,$00,$00 | Score digits. One digit per byte, least significant first. A cache of what is on screen, so that unchanged digits are not replotted. | |
| time_sixteenths | A17D | DEFB $00 | Frames left in the current second of the countdown. Counts from $F to $0, and time_bcd is decremented when it hits zero. | |
| time_bcd | A17E | DEFB $00 | Time remaining. Stored as BCD. | |
| time_digits | A17F | DEFB $00,$00 | Time remaining as displayed. Stored as one digit per byte. | |
| distance_digits | A181 | DEFB $00,$00,$00,$00 | Distance as displayed. Stored as one digit per byte. | |
| no_objects_counter | A185 | DEFB $00 | If set causes no objects or hazards to be emitted. | |
| horizon_attribute | A186 | DEFW $0000 | Attribute address of horizon. Points to last attribute on the line which shows the ground. (e.g. $59DF) | |
|
Table of spawned vehicles and/or objects
A hazard is anything on the road: a moving object like the perp or an NPC car, or a fixed one like a barrier or a tumbleweed. Six slots of 20 bytes each. Slot 0 is always the perp car; spawn_cars and spawn_hazards allocate from slots 1 to 5 by scanning for the first with +0 clear. The Z80 always reaches these fields as (IX+n), never by absolute address, which is why the layout is given as byte offsets.
+0 (byte) Slot allocation flag: $FF when used, $00 when free. advance_hazard clears it once the object has passed the camera.
+1 (byte) Approach counter, running 21 down to 0 as the object nears. Advanced by the whole-units part of +13 each frame. advance_hazard retires the slot once it reaches 23 and only draws the object below 20. It doubles as the low byte of the road-buffer column while the object is drawn, and perp_behaviour reads the perp's copy as a road-buffer offset when comparing hazard positions.
+2 (byte) Horizontal screen position: the low byte of the computed road X.
+3 (byte) Horizontal clip flag: the high byte of that same X. Zero means on screen, negative clipped off the left edge, positive clipped off the right. check_collision rejects any hazard whose clip byte is non-zero, and the plot routine picks its entry point from the sign.
+4 (byte) Fractional part of the approach distance. Decremented each frame by the low byte of +13, and each borrow carries into +1. It is also the multiplicand for the perspective column at +6, so it doubles as the sub-row depth within the current distance step.
+5 (byte) Position across the road, 0 to 255 left to right (observed values 5..216). hazard_handler slides it five units a frame toward the lane position at +18, which is what makes a traffic car drift between lanes rather than jump.
+6 (byte) Perspective-scaled column, (+4 * height delta) >> 8, recomputed each frame by advance_hazard. It selects the sprite's column and the road-edge row the object is drawn against, less the wobble at +16.
+7 (byte) Hit sequence timer. Zero when nothing is happening, positive while a vehicle hit is in progress, negative for the perp's post-hit cooldown: perp_behaviour sets it to $FC (-4) and counts back up to zero, ignoring input meanwhile.
+8 (byte) Collision box width, used for the bounding-box overlap test in check_collision.
+9 (word) Address of the object's bitmap table (the LOD). spawn_cars overwrites it with a random vehicle from the stage's table.
+11 (word) Address of the hit handler called once per frame by advance_hazard after the object is drawn: perp_behaviour for the perp, hazard_handler for traffic and hazard_hit for barriers and tumbleweeds.
+13 (word) Fixed-point approach rate. The high byte is whole distance units per frame, added to +1; the low byte is fractional units per frame, subtracted from +4, where each borrow carries a further unit into +1. hazard_hit decays it by 1/32 a frame while an object wobbles away from a collision.
+15 (byte) What kind of object this is, and how far through a hit it is. $80 marks a spawned vehicle and $FF the perp, so bit 7 set means "is a vehicle", which is how spawn_cars counts the traffic already on screen. For a static hazard it is the hit state machine instead: 0 untouched, 2 wobbling, 1 finished.
+16 (byte) Horizontal wobble offset during a hit, indexed out of table_acdb by hazard_hit and subtracted from +6 as the object is drawn, so a struck barrier shudders and settles.
+17 (byte) Lane index, or for the perp the high byte of +1. For a traffic car it is the lane currently occupied, which perp_behaviour compares against its own lane to decide whether to swerve. While a static hazard is being hit it is reused again, as the running index into table_acdb.
+18 (byte) Target lane, or the wobble countdown. hazard_handler slides +5 toward this lane's position until the two agree; for a hazard mid-wobble it is instead the frame countdown, and the effect ends when it reaches zero.
+19 (byte) Sprite plot mode: 0 normal, 1 inverted. hazard_hit toggles it every frame of the wobble, flipping the sprite vertically to fake a barrier tumbling.
|
||||
| hazard_0 | A188 | DEFS $14 | ||
| hazard_1 | A19C | DEFS $14 | ||
| hazard_2 | A1B0 | DEFS $14 | ||
| hazard_3 | A1C4 | DEFS $14 | ||
| hazard_4 | A1D8 | DEFS $14 | ||
| hazard_5 | A1EC | DEFS $14 | ||
|
Padding: 19 bytes, one short of another 20-byte hazard slot, before the AY register soft copy at ay_chan_a_pitch
|
||||
| A200 | DEFS $13 | |||
|
AY registers 0..11 [128K]
|
||||
| ay_chan_a_pitch | A213 | DEFW $0000 | 0,1: Channel A pitch (fine,coarse=lo,hi) | |
| ay_chan_b_pitch | A215 | DEFW $0000 | 2,3: Channel B pitch (fine,coarse=lo,hi) | |
| ay_chan_c_pitch | A217 | DEFW $0000 | 4,5: Channel C pitch (fine,coarse=lo,hi) - used for engine tone/drone | |
| ay_noise_pitch | A219 | DEFB $00 | 6: Noise pitch | |
| ay_mixer | A21A | DEFB $00 | 7: Mixer | |
| ay_chan_a_vol | A21B | DEFB $00 | 8: Channel A volume | |
| ay_chan_b_vol | A21C | DEFB $00 | 9: Channel B volume | |
| ay_chan_c_vol | A21D | DEFB $00 | 10: Channel C volume | |
| ay_env_fine | A21E | DEFB $00 | 11: Envelope fine duration | |
|
End of AY registers
|
||||
| A21F | DEFB $00 | Unused? | ||
| dont_draw_screen_attrs | A220 | DEFB $00 | If this is non-zero then draw_screen_attributes won't run. | |
|
Affects collision detection on the left hand side.
|
||||
| inhibit_collision_detection | A221 | DEFB $00 | ABCE, check_hazard_collisions reads | |
| n_hazards | A222 | DEFB $00 | Number of hazard slots currently in use. | |
| displayed_stage | A223 | DEFB $00 | Stage number as shown on the scoreboard. Stored as ASCII. | |
|
0 => no helicopter 1 => moves to left 2 => bobs around in the air 3/4 => moves from left 5 => bobs around in the air
|
||||
| helicopter_control | A224 | DEFB $00 | Set to 1 -> helicopter moves out to the left, gets set to zero. Set to 3/4 -> Helicopter moves in from left, gets set to five. move_helicopter, drive_helicopter reads AB96, C013 writes | |
| dont_spawn_cars | A225 | DEFB $00 | Inhibits cars from spawning. | |
| correct_fork | A226 | DEFB $00 | Holds the correct direction to take at forks (1 => left, 2 => right). | |
| floating_arrow | A227 | DEFB $00 | Shows the floating left/right arrow (0 => off, 1 => left, 2 => right). | |
| cherry_light | A228 | DEFB $00 | Shows the flashing cherry light on top of the car (0 => off, else on). | |
| time_up_state | A229 | DEFB $00 | 1 => out of time; 2 => "TIME UP" message is printed; 3 => "CONTINUE THIS MISSION" message is printed and a countdown runs; 4 => countdown elapsed; 0 otherwise | |
| car_y | A22A | DEFB $00 | Car Y offset. Usually zero. Higher values move the car upwards. Used when the car pulls in after catching a perp. Used by draw_masked_sprite_rel_car and others | |
| overtake_bonus_counter | A22B | DEFB $00 | Number of cars overtaken since a bonus was last awarded. Used by calc_overtake_bonus and others. | |
| trigger_bonus_flag | A22C | DEFB $00 | Bonus flag (1 triggers the effect) | |
| bonus_counter | A22D | DEFB $00 | Counter for bonus flash effect (counts 8..0) | |
| sighted_flag | A22E | DEFB $00 | Set to 1 when the perp has been sighted. Enables flashing lights and the smash bar. | |
| hand_flag | A22F | DEFB $00 | Set to 1 by start_chase. This starts the anim where the cherry light is put on the roof. Set to 2 by fully_smashed. This shows the "stop" hand. | |
| perp_caught_phase | A230 | DEFB $00 | Set to > 0 by fully_smashed when the perp has been caught. handle_perp_caught progresses this through stages 1..6 until the cars are slowed to a halt and the bonuses are printed. Used by send_playfield. Inhibits car spawning. | |
| transition_control | A231 | DEFB $00 | Transition/fade control/counter. Set to zero when fill_attributes has run. Set to 4 while transitioning. Also 2 sometimes. Set to 1 when the perp has been caught and we're drawing mugshots. | |
| smash_level | A232 | DEFB $00 | Set to 0..6 if (0..3, 4..6, 7..10, 11..13, 14..16, 17+) smashes | |
| smash_counter | A233 | DEFB $00 | Smash counter (0..20) | |
| counter_A | A234 | DEFB $00 | Cycles 0-1-2-3 as the game runs. Used to animate turbo smoke and helicopter blades. | |
| counter_B | A235 | DEFB $00 | Cycles 0-1 as the game runs (used to flash the red/blue lights) | |
| counter_C | A236 | DEFB $00 | Cycles 0-1-2-3 as the game runs - at half rate | |
|
These seem to get altered even when no sound is being produced.
|
||||
| sfx_index | A237 | DEFB $00 | Current sound effect index | |
| sfx_priority | A238 | DEFB $00 | Current sound effect priority | |
| siren_enabled | A239 | DEFB $00 | Enables siren. Used by F265 [128K] | |
| turbo_sfx_noise_pitch | A23A | DEFB $00 | Copy of noise pitch. Used by F2F6 [128K] | |
| tunnel_sfx | A23B | DEFB $00 | Set to 5 when we're in a tunnel. Used to modulate sfx. | |
| trigger_right_hand_passed_object_sfx | A23C | DEFB $00 | 8909, BE28 reads. csc_store_sfx_trigger, BDFF, BE2C writes. | |
| trigger_left_hand_passed_object_sfx | A23D | DEFB $00 | Set whenever an object passes the hero's car. BE33 reads. 890F, A3D2, BDFC, BE37 writes. | |
| off_road | A23E | DEFB $00 | 0 => Fully on-road, 1 => One wheel off-road, 2 => Both wheels off-road [samples: B104, B40C reads csc_store_off_road, fc_not_fork_set, B07D, B322, B404, B443 writes] | |
| fast_counter | A23F | DEFB $00 | This is a very fast counter that increments only when the car is in motion. Typically the top three bits are masked off and used to index other tables. When this rolls over the road_buffer_offset increments so it's really the lowest byte of the road offset. | |
| road_buffer_offset | A240 | DEFW $0000 | Current offset (in bytes) into the road buffer at $EE00..$EEFF. Much of the code treats this as a byte. Used by url_read_road_height, BBF7, 87E0. | |
| curvature_byte | A242 | DEFB $00 | Current curvature byte (minus 16) [BE3E reads BC17,rm_save_curvature_byte writes] | |
| height_byte | A243 | DEFB $00 | Current height byte (minus 16) [BE90 reads BC1A,rm_save_height_byte writes] | |
| leftside_byte | A244 | DEFB $00 | [BF9E reads BC1D,rm_leftside_count_resume writes] | |
| rightside_byte | A245 | DEFB $00 | Current rightside byte [rm_rightside reads BC20,rm_rightside_count_resume writes] | |
| hazards_byte | A246 | DEFB $00 | Current hazards byte (minus one) [BFE7 reads BC23,rm_set_hazards writes] | |
| lanes_counter_byte | A247 | DEFB $00 | [BEDB reads BC26,BF15,rm_lanes_count_resume writes] | |
| on_dirt_track | A248 | DEFB $00 | Set to 1 when on dirt track. [choose_dirt_and_stones reads C457,dr_c526 writes] | |
| fork_taken | A249 | DEFB $00 | Set to 0 if no fork, or the left fork was taken, or 1 if the right fork was taken. [$A539,$B988,$BAE0,$BB6E reads lr_check_correct_fork_taken,BC2C writes] | |
| speed | A24A | DEFW $0000 | Speed (0..511). Max when in low gear =~ $E6 (230), high gear =~ $168 (360), turbo =~ $1FF (511). In practice I see maximums of 188 / 295 / 419 (82% of original value...) | |
| inclined_counter | A24C | DEFB $00 | Counts 3/2/1/0 when the hero car is ascending or descending. mhc_speed_set reads mhc_set_inclined writes | |
| cornering | A24D | DEFB $00 | Set while cornering hard enough to squeal. Gates the tyre-squeal SFX and whether turbo smoke is drawn this frame. B3B4, B432 reads mhc_set_cornering, B314, ahc_crashed writes | |
| boost | A24E | DEFB $00 | Turbo boost time remaining (60..0) | |
| smoke | A24F | DEFB $00 | Smoke time remaining. This is set to 4 on low-to-high gear changes and to 3 when the hero car lands after a jump. This isn't set for turbo boosts however. | |
| turn_speed | A250 | DEFB $00 | Turn speed (0/1/2 => straight/turn/turn hard) ignoring direction | |
| flip_car | A251 | DEFB $00 | 1 => Horizontally flip the hero car, 0 => Don't | |
| gear_lockout | A252 | DEFB $00 | Locks out repeated gear changes. Counts down 3-2-1-0 | |
| gear | A253 | DEFB $00 | 0 => Low gear, 1 => High gear | |
| allow_spawning | A254 | DEFB $00 | If non-zero this permits cars, hazards and dust/stones to spawn. It can be 0, 1 or 2, depending on the hero car's speed. Reset to zero when the hero car is stopped. | |
| distance_bcd | A255 | DEFB $00,$00 | Distance as BCD (2 bytes / 4 digits, little endian) | |
| var_a257 | A257 | DEFB $00 | Unused | |
| incline | A258 | DEFB $00 | Road incline $FF/$FE/$FD if the road is climbing, $00 if level, $01/$02/$03 if the road is descending | |
| prev_road_height | A259 | DEFB $00 | Previous frame's road height, which B92B subtracts to get the incline | |
| horizon_y_accum | A25A | DEFB $00 | Horizon movement accumulated from changes in incline; goes 0, 1, 2 | |
| horizon_y_step | A25B | DEFB $00 | Amount the horizon moves vertically each frame | |
| current_curvature | A25C | DEFB $00 | This holds the road curvature byte at the position of the hero car. -ve when curving left or +ve when curving right. $FA..$06 in multiples of two. | |
| horizon_curve_index | A25D | DEFB $00 | Index into horizon_table for the horizon. Saw: 8/16/24 | |
| horizon_x_scroll | A25E | DEFB $00 | Horizon scroll phase, counting down 4-3-2-1 / 3-2-1 / 2-1 while the road curves. Reloaded from horizon_table by scroll_horizon. | |
| horizontal_adjust | A25F | DEFW $0000 | Repeatedly set to zero in mhc_straight_road. If altered this changes the car's position on the road. It's mainly zero but occasionally gets set to one. +ve shifts the hero car left, -ve shifts it right. | |
| horizon_scroll_sub | A261 | DEFB $00 | Fractional part of the horizon's horizontal scroll, used by B297. 0 when there is no motion | |
| curvature_ticks | A262 | DEFB $00 | Frames elapsed on the current curve, pacing the horizon scroll in B284. 0 when there is no motion | |
| right_turn | A263 | DEFB $00 | Right turning force (0..36) | |
| left_turn | A264 | DEFB $00 | Left turning force (0..36) | |
| fork_visible | A265 | DEFB $00 | Used by BC2C -- set to $60 when the forked road becomes visible, zero otherwise | |
| fork_countdown | A266 | DEFB $00 | Used by A3A6 -- counts down from 21 when the forked road approaches, zero when the fork actually starts or otherwise | |
| fork_distance | A267 | DEFW $0000 | Counts 0..255 during road forks | |
| fork_in_progress | A269 | DEFB $00 | Used by BC29. Set to 1 while the road forks. | |
| quit_state | A26A | DEFB $00 | 0 if not quitting, or 1/2 depending on quit state | |
| start_speech | A26B | DEFB $00 | Index of speech sample to play preceded by N zero bits and a one bit. | |
| road_pos | A26C | DEFW $0000 | Road position of car. Left..Right = $1E2...$03A. ~$109 is centre. | |
| road_curvature_ptr | A26E | DEFW $0000 | Address of the previous curvature data byte | |
| road_height_ptr | A270 | DEFW $0000 | Address of the previous height data byte | |
| road_lanes_ptr | A272 | DEFW $0000 | Address of the previous lane data byte | |
| road_rightside_ptr | A274 | DEFW $0000 | Address of the previous right object data byte | |
| road_leftside_ptr | A276 | DEFW $0000 | Address of the previous left object data byte | |
| road_hazard_ptr | A278 | DEFW $0000 | Address of the previous hazard object data byte | |
| Prev: A0CC | Up: Map | Next: A27A |