| Chase H.Q. | Routines |
| Prev: A4F6 | Up: Map | Next: A60E |
|
Two passes over up to 21 road slots. The first walks object_positions and turns the run of per-slot sizes into running totals, so each entry ends up holding where that slot's strip of objects starts.
The second reads the lanes byte for each slot from the road buffer and pushes a left and right pair of 16-bit x positions onto a stack growing down from $EB00. Bits 1 and 0 of the lane offset choose the table the left boundary comes from and bits 7 to 2 choose the one for the right; fork slots use the centre and centre right tables directly.
|
||||
| layout_objects | A579 | LD HL,$E34F | Load address of object_positions | |
| A57C | LD B,$15 | 21 iterations [max no of objects on-screen? max no of stripes?] | ||
|
object_positions is individual sizes. Turn them into positions.
|
||||
| A57E | XOR A | Initialise total to zero | ||
| lo_loop1 | A57F | ADD A,(HL) | Increment total by (HL) | |
| A580 | LD (HL),A | Write total back in place | ||
| A581 | INC L | |||
| A582 | DJNZ lo_loop1 | Loop lo_loop1 while B > 0 | ||
|
Setup addresses.
|
||||
| A584 | LD ($A60B),SP | Save SP to restore on exit (self modify) | ||
| A588 | LD SP,$EB00 | Load SP with $EB00 - where results will be stored (end of - stack is descending) | ||
| A58B | LD D,$EE | Point DE at road buffer | ||
| A58D | LD A,($A240) | Load road_buffer_offset.lo into A | ||
| A590 | ADD A,$40 | Add 64 so it's the lanes data offset | ||
| A592 | LD E,A | Finalised DE now points into lanes data | ||
| A593 | LD IY,$E34F | Load address of object_positions | ||
| A597 | LD B,$15 | 21 iterations | ||
| A599 | LD A,($A265) | Load fork_visible | ||
| A59C | AND A | Set flags | ||
| A59D | JP Z,lo_positions_loop | Jump to lo_positions_loop if zero (passing iterations in B) | ||
|
Otherwise the road fork is visible.
|
||||
| lo_fork_visible | A5A0 | LD A,($A266) | Load fork_countdown | |
| A5A3 | AND A | Set flags | ||
| A5A4 | JR Z,lo_forking | Jump to lo_forking if forking | ||
|
Fork is visible but not forking as yet.
|
||||
| A5A6 | LD B,A | Set iterations to fork_countdown | ||
| lo_positions_loop | A5A7 | LD A,(DE) | Read a lanes byte | |
| A5A8 | EXX | Bank | ||
| A5A9 | LD E,A | Copy lanes byte to E | ||
|
L = ~(IY[0] * 2). The doubling is the 16-bit stride of the x-position tables and the complement reverses the direction of travel through them: for a slot depth of N the pair of bytes read is the word at index 127 - N, counting back from the far end of the 128-entry table. ~(2N) is always odd, which is why the reads below take the high byte first and step down to the low one.
|
||||
| A5AA | LD A,(IY+$00) | Read from current index in object_positions array | ||
| A5AD | ADD A,A | Double it for the 16-bit table stride | ||
| A5AE | CPL | Complement to index back from the end of the table | ||
| A5AF | LD L,A | Move result to L | ||
|
Read left hand offset bits (0+1).
|
||||
| A5B0 | LD A,E | Copy lanes byte to A | ||
| A5B1 | AND $03 | Isolate left hand offset bits | ||
| A5B3 | JR NZ,lo_a5bf | Jump if there's a left hand offset | ||
|
Otherwise no left hand offset is set.
|
||||
| A5B5 | LD H,$E8 | Set HL to left hand table address: $E8xx | ||
| A5B7 | LD B,(HL) | Load BC from the table | ||
| A5B8 | DEC L | |||
| A5B9 | LD C,(HL) | |||
| A5BA | PUSH BC | Store left hand value - then fallthrough | ||
| lo_set_right_hand | A5BB | LD H,$EC | Set HL to right hand table - $ECxx | |
| A5BD | JR lo_load_and_store_right | Jump to lo_load_and_store_right | ||
|
The left hand position of the road in A is 1/2/3 here. Use that to select table $E8xx/$E9xx/$EAxx.
|
||||
| lo_a5bf | A5BF | ADD A,$E7 | Set table high byte to $E7 + A | |
| A5C1 | LD H,A | |||
|
Sampled HL = $E869 $E865 $E863 $E861 (road drawing left)
|
||||
| A5C2 | LD B,(HL) | Load BC from the table | ||
| A5C3 | DEC L | |||
| A5C4 | LD C,(HL) | |||
| A5C5 | PUSH BC | Store left hand value | ||
| A5C6 | RL E | Shift bit 7 of lanes byte into carry (checked later) | ||
| A5C8 | BIT 7,E | Test former bit 6; set if tunnel, dirt track or fork (carry preserved) | ||
| A5CA | JP Z,lo_normal_road | Jump to lo_normal_road if clear | ||
| A5CD | JR C,lo_set_right_hand | Jump to lo_set_right_hand if carry (dirt track or fork) | ||
|
Otherwise it's a tunnel piece.
|
||||
| A5CF | LD A,$03 | Set lane shift amount for 3 lanes | ||
| A5D1 | JR lo_set_table_right | Jump to lo_set_table_right | ||
| lo_normal_road | A5D3 | LD A,$03 | Set lane shift amount for 3 lanes | |
| A5D5 | JR C,lo_set_table_right | Jump to lo_set_table_right if 3 lane or 3/4 lane widening/narrowing | ||
|
Otherwise it's 2 lane or 2/3 lane widening/narrowing.
|
||||
| A5D7 | DEC A | Set lane shift amount for 2 lanes | ||
| lo_set_table_right | A5D8 | ADD A,H | Add A to table high byte | |
| A5D9 | LD H,A | |||
| lo_load_and_store_right | A5DA | LD C,(HL) | Load BC from the table | |
| A5DB | INC L | |||
| A5DC | LD B,(HL) | |||
| A5DD | PUSH BC | Store right hand value | ||
| A5DE | EXX | Unbank | ||
| A5DF | INC IY | Advance object_positions pointer | ||
| A5E1 | INC E | Advance lanes pointer | ||
| A5E2 | DJNZ lo_positions_loop | Loop to lo_positions_loop while B > 0 | ||
|
$EB00 now contains pairs of 16-bit left,right object positions.
|
||||
| A5E4 | LD A,($A266) | Load fork_countdown | ||
| A5E7 | AND A | Set flags | ||
| A5E8 | JP Z,lo_return | Jump to lo_return if zero (no fork) | ||
|
Otherwise we're about to fork.
|
||||
| lo_forking | A5EB | LD A,($A266) | Calculate (21 - fork_countdown) | |
| A5EE | CPL | |||
| A5EF | ADD A,$16 | |||
| A5F1 | JR Z,lo_return | Jump to lo_return if zero [no fork, or not about to fork?] | ||
| A5F3 | LD B,A | Set iterations to above | ||
| A5F4 | LD H,$EB | Set up to read from $EBxx | ||
| lo_fork_loop | A5F6 | LD A,(IY+$00) | L = ~(IY[0] * 2), the same reversed word index as lo_positions_loop forms | |
| A5F9 | ADD A,A | |||
| A5FA | CPL | |||
| A5FB | LD L,A | |||
| A5FC | DEC H | Step back by 256 to read from $EAxx (centre table) | ||
| A5FD | LD D,(HL) | Load DE from table (reading high byte first) | ||
| A5FE | DEC L | |||
| A5FF | LD E,(HL) | |||
| A600 | PUSH DE | Store left hand value | ||
| A601 | INC H | Restore pointer to read from $EBxx (centre right) | ||
| A602 | LD E,(HL) | Load DE from table (reading low byte first) | ||
| A603 | INC L | |||
| A604 | LD D,(HL) | |||
| A605 | PUSH DE | Store right hand value | ||
| A606 | INC IY | Advance object_positions pointer | ||
| A608 | DJNZ lo_fork_loop | Loop lo_fork_loop while B > 0 | ||
| lo_return | A60A | LD SP,$0000 | Restore original stack pointer (self modified above) | |
| A60D | RET | Return | ||
| Prev: A4F6 | Up: Map | Next: A60E |