| Chase H.Q. | Routines |
| Prev: CBCE | Up: Map | Next: CDD6 |
|
Called once a frame from the main loop. It reads the road buffer's height channel and the perspective Y scale table, and produces three things.
The loop at CD64 walks 21 rows of the height channel, accumulating the incline seen so far in C. Each row's perspective scale is multiplied by the magnitude of that accumulator using the shift-and-add routine at bht_multiplier, negating the multiplier when the accumulator is negative, and added to the row's base scale entry. The results are written to $E300 onwards, with $A0 left as a sentinel after the twenty-first.
The loop at bht_loop2 copies those 21 entries to $E336, tracking a running minimum that starts at 96, so the copy never rises above the closest road point seen so far.
Finally the accumulator is rounded down to a multiple of 8 and stored at $E34B, and the difference from the previous frame's value at $E34C. The latter is written by walking the pointer off the end of the height table rather than by a direct store, so it is invisible to a search for $E34C. update_screen scrolls the sky and ground colour boundary from $E34D, which lags that delta by a frame.
|
||||
|
Point IY at the road buffer's height data.
|
||||
| build_height_table | CD3A | LD IYh,$EE | Set the high byte of IY to road buffer memory region ($EExx) | |
| CD3D | LD A,($A240) | Load road_buffer_offset into A | ||
| CD40 | ADD A,$20 | Add 32 so it's the height data offset (wrapping around) | ||
| CD42 | LD IYl,A | IY is now the road buffer height data pointer | ||
| CD44 | LD C,(IY+$00) | Read the current height byte into C | ||
|
The height byte is the byte B from the map data but converted like so: ((B & 15) - 8). Heights are therefore 0 for level road, 7 for max downslope, -8 for max upslope.
build A - an index into the road drawing tables.
See similar code at 917A.
|
||||
| CD47 | LD A,($A23F) | A = fast_counter & $E0 -- top three bits | ||
| CD4A | AND $E0 | |||
|
Scale 0..223 (in steps of 16) to 0..153, reducing A by 31.25%, mapping the incoming value to the 7x22 byte tables. So fast_counter indexes the rows of the table.
|
||||
| CD4C | LD L,A | Copy for reducing | ||
| CD4D | LD B,A | Copy to be a multiplier later | ||
| CD4E | RRC L | Divide A by 4 and subtract -- nothing will rotate out due to AND $E0 | ||
| CD50 | RRC L | |||
| CD52 | SUB L | |||
| CD53 | RRC L | Divide A by 16 and subtract | ||
| CD55 | RRC L | |||
| CD57 | SUB L | |||
|
Look up that value in the vertical table.
|
||||
| CD58 | LD L,A | Point HL into road drawing tables at ($E600 | (A + 1)) | ||
| CD59 | INC L | |||
| CD5A | LD H,$E6 | |||
| CD5C | LD A,B | Multiplier = (fast_counter & $E0) from above | ||
|
Multiplicand is the height byte from the map (7 max downslope, 0 level, -8 max upslope).
|
||||
| CD5D | CALL scale_curvature_or_height | Call multiply (A = multiplier, C = multiplicand) result in A | ||
| CD60 | NEG | Negate result and copy to C | ||
| CD62 | LD C,A | |||
| CD63 | EXX | Bank | ||
|
This builds the look-up table at $E301. Assuming it's a height table.
|
||||
| CD64 | LD B,$15 | 21 iterations | ||
| CD66 | LD DE,$E301 | DE = $E301 | ||
| bht_loop | CD69 | EXX | Unbank | |
| CD6A | LD E,(HL) | E = *HL * 2 -- HL points at $E6xx (road drawing tables) | ||
| CD6B | SLA E | |||
| CD6D | PUSH HL | Preserve HL | ||
| CD6E | LD D,$00 | DE is now the value from table, widened | ||
| CD70 | LD L,D | Initialise result to zero | ||
| CD71 | LD H,L | |||
| CD72 | LD A,C | A = negated multiply result from above | ||
| CD73 | ADD A,(IY+$00) | A += *IY -- a height byte | ||
| CD76 | LD C,A | C = A | ||
| CD77 | JR Z,bht_continue | Jump to bht_continue if zero (since multiply by zero is a no-op) | ||
| CD79 | JP P,bht_multiplier | Jump if positive | ||
|
Otherwise handle negative case.
|
||||
| CD7C | LD A,E | E = -E; D = $FF -- negate multiplier | ||
| CD7D | DEC D | |||
| CD7E | NEG | |||
| CD80 | LD E,A | |||
| CD81 | LD A,C | A = -C -- negate multiplicand | ||
| CD82 | NEG | |||
|
Multiplier.
|
||||
| bht_multiplier | CD84 | ADD A,A | Throw sign bit away? | |
| bht_bit6 | CD85 | ADD A,A | Shift out a high bit of multiplicand | |
| CD86 | JR NC,bht_bit5 | Copy multiplier (from DE) if a bit shifted out | ||
| CD88 | LD L,E | |||
| CD89 | LD H,D | |||
| CD8A | ADD HL,HL | Shift result up to prepare for next bit | ||
| bht_bit5 | CD8B | ADD A,A | Shift out a high bit of multiplicand | |
| CD8C | JR NC,bht_bit4 | Add multiplier (from DE) if a bit shifted out | ||
| CD8E | ADD HL,DE | |||
| bht_bit4 | CD8F | ADD HL,HL | Shift result up to prepare for next bit | |
| CD90 | ADD A,A | Repeat | ||
| CD91 | JR NC,bht_bit3 | |||
| CD93 | ADD HL,DE | |||
| bht_bit3 | CD94 | ADD HL,HL | ||
| CD95 | ADD A,A | Repeat | ||
| CD96 | JR NC,bht_bit2 | |||
| CD98 | ADD HL,DE | |||
| bht_bit2 | CD99 | ADD HL,HL | ||
| CD9A | ADD A,A | Repeat | ||
| CD9B | JR NC,bht_bit1 | |||
| CD9D | ADD HL,DE | |||
| bht_bit1 | CD9E | ADD HL,HL | ||
| CD9F | ADD A,A | Repeat | ||
| CDA0 | JR NC,bht_bit0 | |||
| CDA2 | ADD HL,DE | |||
| bht_bit0 | CDA3 | ADD HL,HL | ||
| CDA4 | ADD A,A | Repeat | ||
| CDA5 | JR NC,bht_cda8 | |||
| CDA7 | ADD HL,DE | |||
| bht_cda8 | CDA8 | ADD HL,HL | ||
| CDA9 | LD A,H | A = H -- top byte of result | ||
| bht_continue | CDAA | POP HL | Restore HL | |
| CDAB | ADD A,(HL) | A += *HL -- HL points at $E6xx (road drawing data) | ||
| CDAC | INC L | Advance to next byte of HL while wrapping around | ||
| CDAD | EXX | Bank | ||
| CDAE | LD (DE),A | Write A to the table at $E3xx | ||
| CDAF | INC E | Increment address of entry in table (wrapping around) | ||
| CDB0 | INC IYl | IYl++ (wrapping around) | ||
| CDB2 | DJNZ bht_loop | Loop to bht_loop while B | ||
| CDB4 | LD A,$A0 | Final byte is always $A0 | ||
| CDB6 | LD (DE),A | |||
|
Copy the table to $E336 while setting negative values to 96[?]
|
||||
| CDB7 | LD HL,$E336 | Load address of destination | ||
| CDBA | LD DE,$E301 | Load address of source (height table?) | ||
| CDBD | LD BC,$1560 | B = 21 iterations, C = 96 limit/minimum? | ||
| bht_loop2 | CDC0 | LD A,(DE) | Read from table just built | |
| CDC1 | CP C | Jump to bht_write_it if (A - C) is positive | ||
| CDC2 | JP P,bht_write_it | |||
| CDC5 | LD C,A | Otherwise it's negative, so use A | ||
| bht_write_it | CDC6 | LD (HL),C | Write it | |
| CDC7 | INC L | HL++ (wrapping around) | ||
| CDC8 | INC E | DE++ (wrapping around) | ||
| CDC9 | DJNZ bht_loop2 | Loop to bht_loop2 while B | ||
|
Final bytes.
|
||||
| CDCB | LD A,C | C = A = (C + 3) & $F8 | ||
| CDCC | ADD A,$03 | |||
| CDCE | AND $F8 | |||
| CDD0 | LD C,A | |||
| CDD1 | SUB (HL) | A -= *HL | ||
| CDD2 | LD (HL),C | *HL = C | ||
| CDD3 | INC L | HL++ (wrapping around) | ||
| CDD4 | LD (HL),A | *HL = A | ||
| CDD5 | RET | Return | ||
| Prev: CBCE | Up: Map | Next: CDD6 |