| Chase H.Q. | Routines |
| Prev: 9DF4 | Up: Map | Next: 9F47 |
|
Three parts. First one 2 by 14 back buffer sprite per remaining turbo boost, at successive column offsets; the last one uses the current frame of the spin animation and the rest use frame 0, the resting position. Then the speed, which is scaled from the internal 0 to 511 by 82% before the ten thousands, thousands and hundreds digits are extracted and plotted. Last the time, distance and score digit groups, each drawn by the same shared routine.
Used by the routine at bonus_string.
|
||||
| plot_turbos_and_digits | 9E11 | LD A,($A170) | If no turbo boosts remain, jump to plot_scores_only | |
| 9E14 | AND A | |||
| 9E15 | JR Z,plot_speed_only | |||
| 9E17 | LD C,A | Preserve number of turbo boosts in C | ||
| 9E18 | LD A,($A24E) | Read boost time remaining and set flags | ||
| 9E1B | AND A | |||
| 9E1C | LD HL,$76F0 | Point HL at base of turbo sprites | ||
| 9E1F | JR Z,ptad_turbo_setup | Avoid frame increment and address calculation if possible | ||
| 9E21 | LD A,$00 | Get frame number (0, 1 or 2) | ||
| 9E23 | INC A | |||
| 9E24 | CP $03 | |||
| 9E26 | JR NZ,plot_turbos_and_digits_0 | |||
| 9E28 | XOR A | |||
| plot_turbos_and_digits_0 | 9E29 | LD ($9E22),A | Self modify frame number | |
| 9E2C | JR Z,ptad_turbo_setup | Avoid frame address calculation if possible | ||
| 9E2E | LD DE,$0038 | 56 bytes per frame | ||
| 9E31 | LD B,A | Calculate the frame address | ||
| plot_turbos_and_digits_1 | 9E32 | ADD HL,DE | ||
| 9E33 | DJNZ plot_turbos_and_digits_1 | |||
| ptad_turbo_setup | 9E35 | LD ($9E45),HL | Self modify 9E44 to load SP with address of frame | |
| 9E38 | LD ($9E79),SP | Self modify 9E78 to restore SP once drawing is done | ||
| 9E3C | LD A,$E1 | Low byte of back buffer draw address | ||
|
Draw a whole frame of turbo sprite.
Note that the frame data is stored in memory inverted (bottom first), so we draw the bottom row first and then proceed upwards.
|
||||
| ptad_turbo_loops | 9E3E | LD SP,$76F0 | Base address of frames | |
| 9E41 | DEC C | Temporarily decrement the number of turbos remaining to draw | ||
| 9E42 | JR NZ,plot_turbos_and_digits_2 | All but the final turbo sprite use the zeroth frame | ||
| 9E44 | LD SP,$0000 | SP is pointed at frame data (self modified) | ||
| plot_turbos_and_digits_2 | 9E47 | INC C | Restore number of turbos | |
| 9E48 | LD H,$FE | Form back buffer position | ||
| 9E4A | LD L,A | |||
| 9E4B | EX AF,AF' | Preserve partial back buffer position | ||
| 9E4C | LD B,$0E | Height of frame | ||
|
Draw a scanline of frame.
|
||||
| ptad_turbo_scanline | 9E4E | POP DE | Pop some frame data off the stack (E is mask data, D is bitmap data) | |
| 9E4F | LD A,(HL) | Write to screen: Screen = (Screen AND Mask) OR Bitmap | ||
| 9E50 | AND E | |||
| 9E51 | OR D | |||
| 9E52 | LD (HL),A | |||
| 9E53 | INC L | Advance screen address to next column | ||
| 9E54 | POP DE | (Repeat) | ||
| 9E55 | LD A,(HL) | |||
| 9E56 | AND E | |||
| 9E57 | OR D | |||
| 9E58 | LD (HL),A | |||
| 9E59 | DEC L | Step back | ||
|
Move to next scanline (longer form).
|
||||
| 9E5A | LD A,H | Save for checking in a moment | ||
| 9E5B | DEC H | Move to next scanline (visually upwards) | ||
| 9E5C | AND $0F | Would it have rolled over into the top nibble? | ||
| 9E5E | JP NZ,plot_turbo_continue | No - continue | ||
|
It rolled over.
|
||||
| 9E61 | LD A,H | Put back the bit stolen by rollover | ||
| 9E62 | ADD A,$10 | |||
| 9E64 | LD H,A | |||
| 9E65 | LD A,L | Move to next chunk of 16 scanlines | ||
| 9E66 | SUB $20 | |||
| 9E68 | LD L,A | |||
| 9E69 | JP NC,plot_turbo_continue | Continue if it didn't roll over | ||
| 9E6C | LD A,H | Otherwise move to the next chunk of 128 scanlines (would put us outside the back buffer) | ||
| 9E6D | SUB $10 | |||
| 9E6F | LD H,A | |||
| plot_turbo_continue | 9E70 | DJNZ ptad_turbo_scanline | Loop until out of rows | |
| 9E72 | EX AF,AF' | Restore back buffer draw address | ||
| 9E73 | ADD A,$02 | Advance screen address to next turbo position | ||
| 9E75 | DEC C | Decrement number of turbos | ||
| 9E76 | JR NZ,ptad_turbo_loops | Loop until none are left | ||
| 9E78 | LD SP,$0000 | Restore original SP (self modified) | ||
| plot_speed_only | 9E7B | LD DE,$4132 | Point DE at speed digits screen position (144, 9) | |
| 9E7E | EXX | Bank | ||
| 9E7F | LD DE,($A24A) | Load speed into DE | ||
|
Scale internal speed (0..511) to displayed speed by multiplying by 82 then discarding the bottom two digits.
|
||||
| 9E83 | LD HL,$0000 | Initialise counter | ||
| 9E86 | LD B,$07 | Do 7 digits / iterations | ||
| 9E88 | LD A,$52 | Multiplier of 82 (a percentage: speed * multiplier / 100 = displayed speed) | ||
| ptad_speed_multiply_loop | 9E8A | RLA | Shift one bit out | |
| 9E8B | JR NC,plot_turbos_and_digits_3 | Jump if not adding | ||
| 9E8D | ADD HL,DE | Add | ||
| plot_turbos_and_digits_3 | 9E8E | ADD HL,HL | Double | |
| 9E8F | DJNZ ptad_speed_multiply_loop | Loop | ||
|
Count 10,000s.
|
||||
| 9E91 | LD BC,$2710 | 10000 | ||
| 9E94 | LD DE,$FFFF | Initialise D and E counters to -1 | ||
| 9E97 | XOR A | ?Clear carry flag? | ||
| ptad_speed_10000s_loop | 9E98 | INC D | Increment counter | |
| 9E99 | SBC HL,BC | Decrease total by 10,000 | ||
| 9E9B | JR NC,ptad_speed_10000s_loop | Loop until HL goes negative | ||
| 9E9D | ADD HL,BC | Correct for overshoot | ||
|
Count 1,000s.
|
||||
| 9E9E | AND A | ?Clear carry flag? | ||
| 9E9F | LD BC,$03E8 | 1000 | ||
| plot_speed_1000s_loop | 9EA2 | INC E | Increment counter | |
| 9EA3 | SBC HL,BC | Decrease total by 1,000 | ||
| 9EA5 | JR NC,plot_speed_1000s_loop | Loop until total goes negative | ||
| 9EA7 | ADD HL,BC | Correct for overshoot | ||
|
Count 100s.
|
||||
| 9EA8 | XOR A | Initialise counter (to zero not -1 as in previous cases) | ||
| 9EA9 | LD BC,$0064 | 100 | ||
| ptad_speed_100s_loop | 9EAC | INC A | Increment counter | |
| 9EAD | SBC HL,BC | Decrease total by 100 | ||
| 9EAF | JR NC,ptad_speed_100s_loop | Loop until total goes negative | ||
| 9EB1 | DEC A | Correct for starting early | ||
|
Plot speed digits.
We divide by 100 here by throwing away the bottom two digits.
|
||||
| 9EB2 | PUSH AF | Stack 100s counter | ||
| 9EB3 | LD A,E | Stack 1,000s counter | ||
| 9EB4 | PUSH AF | |||
| 9EB5 | LD A,D | Get 10,000s counter | ||
| 9EB6 | CALL ledfont_plot | Plot a digit for 10,000s | ||
| 9EB9 | POP AF | |||
| 9EBA | CALL ledfont_plot | Plot a digit for 1,000s | ||
| 9EBD | POP AF | |||
| 9EBE | CALL ledfont_plot | Plot a digit for 100s | ||
|
Time.
|
||||
| 9EC1 | LD DE,$412F | Point DE at time digits screen position (120, 9) | ||
| 9EC4 | EXX | Bank | ||
| 9EC5 | LD DE,$A17E | Point DE at time_bcd (one BCD byte) | ||
| 9EC8 | LD HL,$A180 | Point HL at time_digits + 1 | ||
| 9ECB | LD B,$01 | One pair of digits | ||
| 9ECD | CALL ptad_led_digits | Call ptad_led_digits | ||
|
Distance.
|
||||
| 9ED0 | LD DE,$A256 | Point DE at distance_bcd + 1 (the second of two BCD bytes) | ||
| 9ED3 | LD A,($A189) | L = Distance byte from first 'hazard' (the perp) | ||
| 9ED6 | LD L,A | |||
| 9ED7 | LD A,($A199) | H = High byte of distance | ||
| 9EDA | LD H,A | |||
|
Count 1000s (no loop here - it's not required)
|
||||
| 9EDB | LD BC,$03E8 | 1,000 | ||
| 9EDE | SBC HL,BC | Decrease total by 1,000 | ||
| 9EE0 | LD A,$10 | BCD "10" | ||
| 9EE2 | JR NC,plot_turbos_and_digits_4 | Jump if distance >= 1,000 | ||
| 9EE4 | ADD HL,BC | Otherwise correct for overshoot | ||
| 9EE5 | XOR A | BCD "00" | ||
|
Count 100s
|
||||
| plot_turbos_and_digits_4 | 9EE6 | LD BC,$0064 | 100 | |
| ptad_scores_distance_100s_loop | 9EE9 | INC A | Increment counter | |
| 9EEA | SBC HL,BC | Decrease total by 100 | ||
| 9EEC | JP NC,ptad_scores_distance_100s_loop | Loop until total goes negative | ||
| 9EEF | ADD HL,BC | Correct for overshoot | ||
| 9EF0 | DEC A | Correct for starting early | ||
| 9EF1 | LD (DE),A | distance_bcd[1] = counter | ||
|
Count 10s
|
||||
| 9EF2 | LD C,$0A | 10 (B's already zero) | ||
| 9EF4 | AND A | ?Clear carry flag? | ||
| 9EF5 | LD A,$F0 | A = $F0 (BCD) | ||
| ptad_scores_distance_10s_loop | 9EF7 | ADD A,$10 | Increment counter | |
| 9EF9 | AND A | ?Clear carry flag? | ||
| 9EFA | SBC HL,BC | Decrease total by 10 | ||
| 9EFC | JP NC,ptad_scores_distance_10s_loop | Loop until total goes negative | ||
| 9EFF | ADD HL,BC | Correct for overshoot | ||
| 9F00 | OR L | OR in the remainder | ||
| 9F01 | DEC DE | distance_bcd[0] = A | ||
| 9F02 | LD (DE),A | |||
| 9F03 | LD DE,$4191 | Point DE at distance digits screen position (136,33) | ||
| 9F06 | EXX | Bank | ||
| 9F07 | LD DE,$A256 | Point DE at distance_bcd + 1 (two BCD bytes) | ||
| 9F0A | LD HL,$A184 | Point HL at distance_digits + 3 | ||
| 9F0D | LD B,$02 | Two pairs of digits (4 digits) | ||
| 9F0F | CALL ptad_led_digits | Call ptad_led_digits | ||
| 9F12 | LD DE,$4126 | Point DE at score digits screen position | ||
| 9F15 | EXX | Bank | ||
| 9F16 | LD DE,$8005 | Point DE at score (four BCD bytes) | ||
| 9F19 | LD HL,$A17C | Point HL at score digits (eight bytes) | ||
| 9F1C | LD B,$04 | B = 4 | ||
|
Plots scoreboard digits (DE -> BCD) only if different than recorded values (HL -> byte per digit). B is the count.
|
||||
| ptad_led_digits | 9F1E | LD A,(DE) | Read a pair of digits (BCD) | |
| 9F1F | LD C,A | Save digits for later | ||
| 9F20 | RRCA | Unpack a BCD digit | ||
| 9F21 | RRCA | |||
| 9F22 | RRCA | |||
| 9F23 | RRCA | |||
| 9F24 | AND $0F | |||
| 9F26 | CP (HL) | If different than stored then plot | ||
| 9F27 | JR NZ,ptad_led_plot_1st | |||
| 9F29 | EXX | Move screen position | ||
| 9F2A | INC E | |||
| 9F2B | EXX | |||
| ptad_led_next_half | 9F2C | DEC HL | Move to next recorded value | |
| 9F2D | LD A,C | Examine next digit | ||
| 9F2E | AND $0F | |||
| 9F30 | CP (HL) | If different than stored then plot | ||
| 9F31 | JR NZ,ptad_led_plot_2nd | |||
| 9F33 | EXX | Move screen position | ||
| 9F34 | INC E | |||
| 9F35 | EXX | |||
| ptad_led_next_whole | 9F36 | DEC HL | Move to next recorded value | |
| 9F37 | DEC DE | Move to next digits | ||
| 9F38 | DJNZ ptad_led_digits | Loop until B is zero | ||
| 9F3A | RET | Return | ||
| ptad_led_plot_1st | 9F3B | LD (HL),A | Update drawn digit | |
| 9F3C | CALL ledfont_plot | Plot the digit | ||
| 9F3F | JR ptad_led_next_half | Jump back to handle next digit (second half of a pair) | ||
| ptad_led_plot_2nd | 9F41 | LD (HL),A | Update drawn digit | |
| 9F42 | CALL ledfont_plot | Plot the digit | ||
| 9F45 | JR ptad_led_next_whole | Jump back to handle hext digit (next whole pair) | ||
| Prev: 9DF4 | Up: Map | Next: 9F47 |