| Chase H.Q. | Routines |
| Prev: CBCE | Up: Map | Next: CDD6 |
|
|
||||
|
Point IY at the road buffer's height data. (The "unpacked map 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 multiply | 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 | B = 21 | ||
| 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 muliplicand | ||
| 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 | HL++ (wrapping around) | ||
| CDAD | EXX | Bank | ||
| CDAE | LD (DE),A | Write A to the table at $E3xx | ||
| CDAF | INC E | DE++ (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 -ve values to 96.
|
||||
| CDB7 | LD HL,$E336 | destination | ||
| CDBA | LD DE,$E301 | source | ||
| CDBD | LD BC,$1560 | B = 21 iterations, C = 96 limit | ||
| bht_loop2 | CDC0 | LD A,(DE) | Read from table just built | |
| CDC1 | CP C | Jump if A is positive | ||
| CDC2 | JP P,build_height_table_0 | |||
| CDC5 | LD C,A | Otherwise it's negative, so C = 96 | ||
| build_height_table_0 | 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 |