| Chase H.Q. | Routines |
| Prev: CBC5 | Up: Map | Next: CD3A |
|
Builds the table for one section of road at a time; layout_road (layout_road) calls it multiple times per invocation, once for each section (main road, fork branches).
|
||||
|
This gets hit during road forks (where the roads bend outwards).
|
||||
| build_curve_table_forked | CBCE | LD HL,$EEEC | Load two table high-bytes: $EE, $EC | |
| CBD1 | LD DE,$44ED | Load $ED $44 => Opcode of NEG instruction for CC21 | ||
| CBD4 | JR build_curve_table_self_modify | Jump forward | ||
|
This entry point is used by the routine at layout_road.
|
||||
| build_curve_table | CBD6 | LD HL,$EDE9 | Load two table high-bytes: $ED, $E9 | |
| CBD9 | LD DE,$0000 | Load opcodes of two NOP instructions for CC21 | ||
| build_curve_table_self_modify | CBDC | LD ($CC21),DE | Write pair of instructions in DE to CC21 | |
| CBE0 | LD A,H | Self modify 'LD HL' @ CC70 to load ($<H>00) e.g. $ED00 or $EE00 | ||
| CBE1 | LD ($CC72),A | |||
| CBE4 | LD A,L | Self modify 'LD HL' @ CCA5 to load ($<L>00) e.g. $E900 or $EC00 | ||
| CBE5 | LD ($CCA7),A | |||
|
Using road_buffer_offset as a full address here.
|
||||
| CBE8 | LD HL,($A240) | Load road_buffer_offset into HL | ||
| CBEB | LD C,(HL) | Read a curvature data byte | ||
|
See similar code at CD47.
|
||||
| CBEC | LD A,($A23F) | Load fast_counter | ||
| CBEF | AND $E0 | Isolate top three bits | ||
| CBF1 | LD B,A | Move result to B | ||
|
Map B (0,32,64,96,...,224) to (0,22,44,66,...,154)
|
||||
| CBF2 | RRC B | Divide by 4 and subtract | ||
| CBF4 | RRC B | |||
| CBF6 | SUB B | |||
| CBF7 | RRC B | Divide by 16 and subtract | ||
| CBF9 | RRC B | |||
| CBFB | SUB B | |||
|
Index the road animation table persp_x_scale_right.
|
||||
| CBFC | ADD A,$B0 | IY = persp_x_scale_right + A | ||
| CBFE | LD IYl,A | |||
| CC00 | LD A,$E6 | |||
| CC02 | ADC A,$00 | |||
| CC04 | LD IYh,A | |||
|
Multiply C by the top three bits of A then divide by 8 (with rounding) on return.
|
||||
| CC06 | CALL scale_curvature_or_height | Call multiply (result in A) | ||
| CC09 | NEG | A = (128 - A) & $FE | ||
| CC0B | ADD A,$80 | |||
| CC0D | AND $FE | |||
| CC0F | LD IXl,A | IX = $E500 + A -- point into inward_bend_table | ||
| CC11 | LD IXh,$E5 | |||
| CC14 | LD DE,$E320 | -> table_e320 | ||
| CC17 | LD B,$16 | 20 iterations | ||
| CC19 | EXX | Bank | ||
| CC1A | LD DE,($A26C) | Read road position | ||
|
SP is regular stack here.
|
||||
| CC1E | PUSH DE | Stack it | ||
| CC1F | EXX | Unbank | ||
| bct_loop | CC20 | LD A,(HL) | Read road buffer byte | |
| CC21 | NOP | Self modified above - Set to NOP (if non-forked) or NEG (if forked) | ||
| CC22 | NOP | |||
| CC23 | INC L | Advance road buffer pointer (wrapping) | ||
| CC24 | EXX | Bank | ||
| CC25 | ADD A,IXl | IX.low += A -- point into bend table | ||
| CC27 | LD IXl,A | |||
| CC29 | LD HL,$0000 | Initialise a multiplier result | ||
|
Subtract road_pos in DE from table entry, result in BC.
|
||||
| CC2C | LD A,(IX+$00) | Reads low byte from the inward_bend_table table (inward_bend_table) | ||
| CC2F | SUB E | C = A - E | ||
| CC30 | LD C,A | |||
| CC31 | LD A,(IX+$01) | Reads high byte | ||
| CC34 | SBC A,D | B = A - D (with carry) | ||
| CC35 | LD B,A | |||
|
Sampled IY = $E71E $E71F $E720 ..
|
||||
| CC36 | LD A,(IY+$00) | Load from somewhere in persp_x_scale_right[] | ||
| CC39 | INC IY | Advance | ||
|
This is a multiplier of HL (distance shift value computed above) by A (value from $E600Vertical perspective weights — Y scale by speed and distance+).
|
||||
| CC3B | ADD A,A | Shift left | ||
| CC3C | JR NC,bct_mult1 | Top bit not set | ||
| CC3E | LD H,B | Copy distance shift value | ||
| CC3F | LD L,C | |||
| CC40 | ADD HL,HL | Double it | ||
| bct_mult1 | CC41 | ADD A,A | Shift topmost bit out | |
| CC42 | JR NC,bct_mult2 | Jump if top bit not set | ||
| CC44 | ADD HL,BC | Otherwise HL += BC | ||
| bct_mult2 | CC45 | ADD HL,HL | Repeat | |
| CC46 | ADD A,A | |||
| CC47 | JR NC,bct_mult3 | |||
| CC49 | ADD HL,BC | |||
| bct_mult3 | CC4A | ADD HL,HL | Repeat | |
| CC4B | ADD A,A | |||
| CC4C | JR NC,bct_mult4 | |||
| CC4E | ADD HL,BC | |||
| bct_mult4 | CC4F | ADD HL,HL | Repeat | |
| CC50 | ADD A,A | |||
| CC51 | JR NC,bct_mult5 | |||
| CC53 | ADD HL,BC | |||
| bct_mult5 | CC54 | ADD HL,HL | Repeat | |
| CC55 | ADD A,A | |||
| CC56 | JR NC,bct_cc59 | |||
| CC58 | ADD HL,BC | |||
| bct_cc59 | CC59 | LD A,H | A = H | |
| CC5A | RL L | L <<= 1 | ||
| CC5C | LD H,$00 | H = 0 | ||
| CC5E | ADC A,H | L = A + H + carry | ||
| CC5F | LD L,A | |||
| CC60 | ADD A,A | A <<= 1 | ||
| CC61 | JR NC,bct_topbitclear | Jump if top bit not set | ||
| CC63 | DEC H | H = $FF - make negative | ||
| bct_topbitclear | CC64 | RRA | A >>= 1 | |
| CC65 | ADD HL,DE | HL += DE | ||
| CC66 | EX DE,HL | Swap (DE is result) | ||
| CC67 | EXX | Unbank | ||
| CC68 | LD (DE),A | *DE++ = A | ||
| CC69 | INC E | |||
| CC6A | DJNZ bct_loop | Loop back to bct_loop to read buffer byte bit | ||
| CC6C | POP DE | Pop road position | ||
| CC6D | LD B,$00 | B = 0 -- not self modified | ||
| CC6F | EXX | Bank | ||
| CC70 | LD HL,$ED00 | SELF MODIFIED output address $ED00 or $EE00 | ||
| CC73 | CALL build_curve_table_fill | Call build_curve_table_fill | ||
| CC76 | LD A,($A23F) | Load fast_counter | ||
| CC79 | AND $E0 | Take top three bits | ||
| CC7B | LD B,A | Move result to B | ||
|
Reduce B 0..31 => 0..21.
|
||||
| CC7C | RRC B | Divide by 4 and subtract | ||
| CC7E | RRC B | |||
| CC80 | SUB B | |||
| CC81 | RRC B | Divide by 16 and subtract | ||
| CC83 | RRC B | |||
| CC85 | SUB B | |||
|
Index the road animation table persp_x_delta_left.
|
||||
| CC86 | ADD A,$60 | HL = $E700 + $60 + A | ||
| CC88 | LD L,A | |||
| CC89 | LD H,$E7 | |||
| CC8B | JR NC,bct_build_table_e320 | Jump if A+$60 had no carry | ||
| CC8D | INC H | Add carry otherwise | ||
|
Adds one of the entries somewhere in persp_x_delta_left to the 22 bytes at $E320.
|
||||
| bct_build_table_e320 | CC8E | LD DE,$E320 | Address of table_e320 (written to) | |
| CC91 | LD B,$16 | 22 iterations | ||
| bct_build_table_e320_loop | CC93 | LD A,(DE) | Load an entry from table_e320 | |
|
This reads from (somewhere in) persp_x_delta_left in sequence.
|
||||
| CC94 | ADD A,(HL) | Increment it by (HL) | ||
| CC95 | LD (DE),A | Write back to (DE) | ||
| CC96 | INC HL | Increment entry address in persp_x_delta_left | ||
| CC97 | INC E | Increment entry address in table_e320 | ||
| CC98 | DJNZ bct_build_table_e320_loop | Loop while B > 0 | ||
|
This controls the vanishing point. Decrease this value for wider roads - but the road might appear to bend left... Consider that this is $127 but $109 is the centre.
|
||||
| CC9A | LD HL,($A26C) | HL = road_pos - 295 | ||
| CC9D | LD DE,$FED9 | |||
| CCA0 | ADD HL,DE | |||
| CCA1 | EX DE,HL | Swap result to DE | ||
| CCA2 | LD B,$00 | Initialise total/counter | ||
| CCA4 | EXX | Unbank | ||
| CCA5 | LD HL,$E900 | SELF MODIFIED destination address $E900 or $EC00 | ||
|
Called as subroutine, also fallthrough.
|
||||
| build_curve_table_fill | CCA8 | LD IY,$E300 | Address of height table (22 bytes long) | |
| CCAC | LD B,$15 | 21 iterations | ||
| CCAE | LD ($CCF5),SP | Save SP to restore on exit (self modify) | ||
| CCB2 | LD SP,HL | Put address in SP (so we can use PUSH for speed) | ||
| bct_loop_ccb3 | CCB3 | EXX | Bank | |
| CCB4 | LD A,B | A = B - 2 + IY[0] - IY[1]; IY++ | ||
| CCB5 | SUB $02 | |||
| CCB7 | ADD A,(IY+$00) | |||
| CCBA | INC IYl | |||
| CCBC | SUB (IY+$00) | |||
| CCBF | JP M,bct_endbit_negative | Jump to bct_endbit_negative if M | ||
| CCC2 | ADD A,$02 | A += 2 | ||
| CCC4 | LD (IY+$4E),A | IY[$4E] = A -- in table_e320? | ||
| CCC7 | SUB B | A -= B | ||
| CCC8 | LD C,A | C = A | ||
| CCC9 | LD B,A | B = A | ||
| CCCA | LD L,(IY+$1F) | L = IY[$1F] | ||
| CCCD | BIT 7,L | Test bit 7 of L | ||
| CCCF | JR Z,bct_increment_case | Jump if clear | ||
| CCD1 | LD A,L | L = -L | ||
| CCD2 | NEG | |||
| CCD4 | LD L,A | |||
| CCD5 | LD A,B | A = B | ||
| CCD6 | CP L | A < L ? | ||
| CCD7 | LD A,$1B | Opcode for DEC DE | ||
| CCD9 | JR C,bct_endbit_A | Jump to bct_endbit_A if A < L | ||
| CCDB | JP bct_do_self_modify | Jump to bct_do_self_modify | ||
| bct_increment_case | CCDE | CP L | A < L ? | |
| CCDF | LD A,$13 | Opcode for INC DE | ||
| CCE1 | JR C,bct_endbit_A | Jump to bct_endbit_A if A < L | ||
| bct_do_self_modify | CCE3 | LD ($CCED),A | Self modify instruction below | |
| CCE6 | LD A,B | A = B >> 1 | ||
| CCE7 | RRA | |||
| bct_loop_cce8 | CCE8 | ADD A,L | A += L | |
| CCE9 | CP C | A < C ? | ||
| CCEA | JR C,bct_ccee | Jump if A < C | ||
| CCEC | SUB C | A -= C | ||
| CCED | INC DE | Self modified: could be INC DE or DEC DE | ||
| bct_ccee | CCEE | PUSH DE | Store the current state of DE to table | |
| CCEF | DJNZ bct_loop_cce8 | Loop to bct_loop_cce8 while B > 0 | ||
| CCF1 | EXX | Unbank | ||
| CCF2 | DJNZ bct_loop_ccb3 | Loop to bct_loop_ccb3 while B > 0 | ||
| bct_exit | CCF4 | LD SP,$0000 | Restore original SP (self modified by CCAE) | |
| CCF7 | RET | Return | ||
|
A is opcode of instruction (INC DE/DEC DE) B is max iterations C is ? L is ? DE is ?
|
||||
| bct_endbit_A | CCF8 | LD ($CCFC),A | Self modify instruction below | |
| CCFB | XOR A | Initialise total to zero | ||
| bct_loop_ccfc | CCFC | INC DE | Self modified: could be INC DE or DEC DE | |
| CCFD | ADD A,C | Increment total by C | ||
| CCFE | JR C,bct_carried_or_a_ge_l | Jump if overflow | ||
| CD00 | CP L | Otherwise, loop if A < L | ||
| CD01 | JR C,bct_loop_ccfc | |||
| bct_carried_or_a_ge_l | CD03 | SUB L | Decrement A by L | |
| CD04 | PUSH DE | Push the current state of DE to table | ||
| CD05 | DJNZ bct_loop_ccfc | Loop to bct_loop_ccfc while B > 0 | ||
| CD07 | EXX | Unbank | ||
| CD08 | DJNZ bct_loop_ccb3 | Loop to bct_loop_ccb3 while B > 0 | ||
| CD0A | JR bct_exit | Exit via bct_exit | ||
| bct_endbit_negative | CD0C | LD (IY+$4E),$01 | IY[$4E] = 1 | |
| CD10 | INC A | A++ | ||
| CD11 | JR Z,bct_endbit_C | Jump to bct_endbit_C if zero | ||
| CD13 | INC A | A++ | ||
| CD14 | LD B,A | B = A | ||
| CD15 | LD A,(IY+$1F) | A = IY[$1F] | ||
| CD18 | LD L,A | L = A | ||
| CD19 | ADD A,A | A <<= 1 | ||
| CD1A | SBC A,A | H = A - A - carry -- sign extend? | ||
| CD1B | LD H,A | |||
| CD1C | ADD HL,DE | HL += DE | ||
| CD1D | EX DE,HL | swap | ||
| CD1E | PUSH DE | push result? | ||
| CD1F | EXX | Bank/Unbank? | ||
| CD20 | DEC B | Decrement loop counter -- Why not using DJNZ? | ||
| CD21 | JP NZ,bct_loop_ccb3 | Loop to bct_loop_ccb3 while B > 0 | ||
| CD24 | JP bct_exit | Exit via bct_exit | ||
| bct_endbit_C | CD27 | LD B,A | ||
| CD28 | LD A,(IY+$1F) | |||
| CD2B | LD L,A | |||
| CD2C | ADD A,A | |||
| CD2D | SBC A,A | |||
| CD2E | LD H,A | |||
| CD2F | ADD HL,DE | |||
| CD30 | EX DE,HL | |||
| CD31 | PUSH DE | |||
| CD32 | EXX | |||
| CD33 | DEC B | |||
| CD34 | JP NZ,bct_loop_ccb3 | |||
| CD37 | JP bct_exit | |||
| Prev: CBC5 | Up: Map | Next: CD3A |