| Chase H.Q. | Routines |
| Prev: AD51 | Up: Map | Next: AECF |
|
This includes all cars, barriers, tumbleweeds, etc.
n_hazards is zeroed, then all six slots are walked and the active ones passed to advance_hazard, which advances the hazard's distance, projects it into perspective, inserts it into the depth sorted draw list and fires its hit handler.
|
||||
| advance_hazards | ADA0 | XOR A | n_hazards = 0 | |
| ADA1 | LD ($A222),A | |||
| ADA4 | LD IYh,$E3 | IY = $E3xx | ||
| ADA7 | LD IX,$A188 | Point IX at hazards[0] | ||
| ADAB | LD DE,$0014 | Stride of hazards is 20 bytes | ||
| ADAE | LD B,$06 | 6 iterations | ||
| ah_loop | ADB0 | RLC (IX+$00) | Set carry if the hazard is active | |
| ADB4 | EXX | Bank | ||
| ADB5 | CALL C,advance_hazard | Call advance_hazard if hazard active | ||
| ADB8 | EXX | Unbank | ||
| ADB9 | ADD IX,DE | Advance to next hazard | ||
| ADBB | DJNZ ah_loop | Loop while iterations remain -- B > 0 | ||
| ADBD | RET | Return | ||
| advance_hazard | ADBE | LD C,(IX+$0E) | C = IX[14] -- top byte of horz position or accel? | |
|
Distance? If I disable this calculation and $A18C remains zero then the perp car cannot be caught up with. IX[4] here is e.g. $A18C. IX[13] here is e.g. $A195 which is the perp's speed
|
||||
| ADC1 | LD A,(IX+$04) | IX[4] -= IX[13] -- bottom byte of speed | ||
| ADC4 | SUB (IX+$0D) | |||
| ADC7 | LD (IX+$04),A | |||
| ADCA | JR NC,ah_adcd | If IX[4] was < IX[13] then C++ | ||
| ADCC | INC C | |||
| ah_adcd | ADCD | LD A,(IX+$01) | C += IX[1] -- buffer offset/distance | |
| ADD0 | ADD A,C | |||
| ADD1 | LD C,A | |||
| ADD2 | LD A,(IX+$0F) | A = IX[15] + 1 -- counter? | ||
| ADD5 | INC A | |||
| ADD6 | JR NZ,ah_adf0 | Jump to ah_adf0 if non-zero | ||
| ADD8 | LD A,(IX+$11) | A = IX[17] -- byte that indexes table_acdb | ||
| ADDB | JR NC,advance_hazards_1 | Jump if no carry (carry not set by INC A, but ADD A,C) | ||
| ADDD | INC A | Jump if ++A < 4 | ||
| ADDE | CP $04 | |||
| ADE0 | JR C,advance_hazards_0 | |||
| ADE2 | DEC A | A-- | ||
| ADE3 | LD C,$FF | C = $FF -- gets put in distance related field | ||
| advance_hazards_0 | ADE5 | LD (IX+$11),A | IX[17] = A -- set lane? | |
| advance_hazards_1 | ADE8 | AND A | Set flags | |
| ADE9 | LD A,C | A = C | ||
| ADEA | JR Z,ah_adfa | Jump if zero | ||
| ADEC | LD (IX+$01),A | IX[1] = A -- buffer offset/distance | ||
| ADEF | RET | Return | ||
| ah_adf0 | ADF0 | LD A,C | A = C | |
| ADF1 | CP $17 | Jump if A < 23 -- still visible? | ||
| ADF3 | JR C,ah_adfa | |||
|
Wipe the hazard
|
||||
| ADF5 | LD (IX+$00),$00 | IX[0] = 0 -- hazard slot now spare | ||
| no_op | ADF9 | RET | Return (used as just a RET elsewhere) | |
| ah_adfa | ADFA | LD (IX+$01),A | IX[1] = A -- buffer offset/distance | |
| ADFD | CP $14 | Return if A >= 20 | ||
| ADFF | RET NC | |||
| AE00 | DEC A | A-- | ||
| AE01 | JR NZ,ah_ae24 | Jump if non-zero | ||
| AE03 | LD A,($A23F) | A = ~(fast_counter & $E0) | ||
| AE06 | AND $E0 | |||
| AE08 | CPL | |||
| AE09 | CP (IX+$04) | Jump if A >= IX[4] | ||
| AE0C | JR NC,ah_ae23 | |||
| AE0E | LD B,(IX+$0F) | B = IX[15] + 1 | ||
| AE11 | INC B | |||
| AE12 | JR Z,ah_ae20 | Jump if zero | ||
|
Wipe the hazard because car overtaken?
|
||||
| AE14 | LD (IX+$00),$00 | IX[0] = 0 -- hazard slot now spare | ||
| AE18 | RL B | |||
| AE1A | RET NC | Return if no carry | ||
| AE1B | LD HL,$A22B | Increment overtake_bonus_counter | ||
| AE1E | INC (HL) | |||
| AE1F | RET | Return | ||
| ah_ae20 | AE20 | LD (IX+$04),A | IX[4] = A | |
| ah_ae23 | AE23 | XOR A | A = 0 | |
| ah_ae24 | AE24 | ADD A,$4E | A += $4E | |
|
$E300..$E316 is regularly accessed. $E300 is always $60, $E316 is always $A0
|
||||
| AE26 | LD IYl,A | IY.low = A -- i.e. $E300 | A | ||
| AE28 | LD A,(IY+$01) | A = IY[1] | ||
| AE2B | LD C,A | C = A | ||
| AE2C | SUB (IY+$00) | A -= IY[0] -- A is now the delta between adjacent elements | ||
|
Multiplier. DE = multiplier. A = multiplicand. HL = result.
|
||||
| AE2F | LD D,$00 | DE = A; HL = 0 | ||
| AE31 | LD H,D | |||
| AE32 | LD L,D | |||
| AE33 | LD E,A | |||
| AE34 | LD A,(IX+$04) | A = IX[4] | ||
| AE37 | LD B,$08 | B = 8 -- iterations of multiply loop | ||
| ah_ae39_loop | AE39 | RLA | Test top bit | |
| AE3A | JR NC,ah_not_set | If it carried out then add | ||
| AE3C | ADD HL,DE | |||
| ah_not_set | AE3D | ADD HL,HL | Double | |
| AE3E | DJNZ ah_ae39_loop | Loop | ||
| AE40 | LD A,H | A = H -- high part of result | ||
| AE41 | RRA | |||
| AE42 | LD (IX+$06),A | IX[6] = A | ||
| AE45 | NEG | A = ~((C - A) << 1) | ||
| AE47 | ADD A,C | |||
| AE48 | ADD A,A | |||
| AE49 | CPL | |||
| AE4A | LD L,A | HL = $E800 | A (road drawing left) | ||
| AE4B | LD H,$E8 | |||
| AE4D | LD D,(HL) | D = *HL | ||
| AE4E | DEC L | HL-- | ||
| AE4F | LD E,(HL) | E = *HL | ||
| AE50 | LD H,$EC | H = $EC | ||
| AE52 | LD A,(HL) | A = *HL | ||
| AE53 | INC L | L++ | ||
| AE54 | LD H,(HL) | H = *HL | ||
| AE55 | LD L,A | L = A | ||
| AE56 | AND A | Clear carry | ||
| AE57 | LD ($AE71),DE | Self modify 'LD HL,xxxx' @ AE70 | ||
| AE5B | SBC HL,DE | HL -= DE | ||
| AE5D | EX DE,HL | Swap | ||
| AE5E | LD HL,$0000 | HL = 0 | ||
| AE61 | LD A,(IX+$05) | A = IX[5] | ||
|
Another multiplier.
|
||||
| AE64 | LD B,$08 | B = 8 | ||
| ah_ae66 | AE66 | RLA | A <<= 1 | |
| AE67 | JR NC,ah_ae6a | If it carried out then add | ||
| AE69 | ADD HL,DE | |||
| ah_ae6a | AE6A | ADD HL,HL | Double | |
| AE6B | DJNZ ah_ae66 | Loop | ||
| AE6D | LD A,H | A = H | ||
| AE6E | RRA | |||
| AE6F | LD C,A | C = A | ||
| AE70 | LD HL,$0000 | HL = <self modified> + BC | ||
| AE73 | ADD HL,BC | |||
| AE74 | LD (IX+$02),L | wordat(IX + 2) = HL | ||
| AE77 | LD (IX+$03),H | |||
| AE7A | CALL check_collision | Call check_collision (result ignored) | ||
| AE7D | LD D,(IX+$01) | D = IX[1] -- buffer offset/distance | ||
| AE80 | LD E,(IX+$04) | E = IX[4] -- possibly a distance low byte? | ||
| AE83 | LD HL,$A222 | Load address of n_hazards | ||
| AE86 | LD A,(HL) | Load n_hazards | ||
| AE87 | INC (HL) | Increment n_hazards | ||
| AE88 | LD HL,$E900 | Load address of (road centre left?) table | ||
| AE8B | AND A | Jump to ah_no_hazards if n_hazards was zero | ||
| AE8C | JR Z,ah_no_hazards | |||
| AE8E | LD B,A | Iterations | ||
|
Loop starts (loop for all hazards)
|
||||
| ah_ae8f | AE8F | LD A,D | A = D | |
| AE90 | CP (HL) | Compare to *HL | ||
| AE91 | INC L | L++ | ||
| AE92 | JR C,ah_ae9a | Jump if A < *HL | ||
| AE94 | JR NZ,ah_aeab | Jump if A != *HL | ||
| AE96 | LD A,E | A = E | ||
| AE97 | CP (HL) | Compare to *HL | ||
| AE98 | JR C,ah_aeab | Jump if A < *HL | ||
| ah_ae9a | AE9A | INC L | L += 3 | |
| AE9B | INC L | |||
| AE9C | INC L | |||
| AE9D | DJNZ ah_ae8f | Loop | ||
| ah_no_hazards | AE9F | LD (HL),D | wordat(HL) = DE; HL += 2 | |
| AEA0 | INC L | |||
| AEA1 | LD (HL),E | |||
| AEA2 | INC L | |||
| AEA3 | PUSH IX | DE = IX | ||
| AEA5 | POP DE | |||
| AEA6 | LD (HL),E | wordat(HL) = DE; HL++ | ||
| AEA7 | INC L | |||
| AEA8 | LD (HL),D | |||
| AEA9 | JR ah_call_handler | Jump | ||
| ah_aeab | AEAB | PUSH DE | Preserve DE | |
| AEAC | LD A,B | A = B * 4 | ||
| AEAD | ADD A,A | |||
| AEAE | ADD A,A | |||
| AEAF | LD C,A | BC = A | ||
| AEB0 | LD B,$00 | |||
| AEB2 | ADD A,$02 | A += 2 + L | ||
| AEB4 | ADD A,L | |||
| AEB5 | LD E,A | E = A | ||
| AEB6 | SUB $04 | A -= 4 | ||
| AEB8 | LD L,A | L = A | ||
| AEB9 | LD D,H | D = H | ||
| AEBA | LDDR | Do *HL-- = *DE-- until BC == 0 | ||
| AEBC | EX DE,HL | |||
| AEBD | PUSH IX | DE = IX | ||
| AEBF | POP DE | |||
| AEC0 | LD (HL),D | wordat(HL) = DE; HL -= 2 | ||
| AEC1 | DEC L | |||
| AEC2 | LD (HL),E | |||
| AEC3 | DEC L | |||
| AEC4 | POP DE | Restore DE | ||
| AEC5 | LD (HL),E | *HL = E | ||
| AEC6 | DEC L | L-- | ||
| AEC7 | LD (HL),D | *HL = D | ||
| ah_call_handler | AEC8 | LD L,(IX+$0B) | HL = wordat(IX + 11) | |
| AECB | LD H,(IX+$0C) | |||
| AECE | JP (HL) | Jump there | ||
| Prev: AD51 | Up: Map | Next: AECF |