Boot
Power-on and reset, from the vectors at the top of bank $C0 (seen by the CPU as bank $00) to
the start of the game loop. All of it is matched: the reset code, the interrupt stubs and
vectors, the ROM header, MainInit in bank $FD, and the cold init at the start of GameLoop.
See also: Frame cycle and NMI, ROM Map, Architecture.
Vectors
The vector table RomVectors ($00:FFE0–$FFFF) uses only four entries; every other slot is
$FFFF:
| Vector | Address | Target |
|---|---|---|
| Native BRK | $FFE6 |
BRK_Handler ($00:FF18) |
| Native NMI | $FFEA |
NMI_Stub ($00:FF10) |
| Native IRQ | $FFEE |
IRQ_Stub ($00:FF14) |
| Emulation COP | $FFF4 |
BRK_Handler |
| Emulation RESET | $FFFC |
Reset ($00:FF00) |
The emulation-mode NMI is unused: the NMI is off after reset during the three instructions
Reset runs in emulation mode.
Reset($00:FF00):SEI,CLC,XCE(native mode),JML MainInit. TheSEIis for the soft resets, which arrive in native mode:Menu_PollPad($C2:8523) jumps here when L+R+Select+Start are held, and two unmatched sites in banks$C3and$CFdo too.NMI_Stub/IRQ_Stub: the native vectors can only point into bank$00, so these jump on through 4-byte trampolines in WRAM ($7E:0500,$7E:0504) that the game rewrites as it changes mode.BRK_Handler: a crash trap; it reads a fixed address forever and never returns (the read is what a bus trace or debugger would see, inferred).
The cartridge header ($00:FFB0–$FFDF, RomExtHeader to RomChecksum) reads: maker "C3",
game code "ACTE", title "CHRONO TRIGGER", HiROM + FastROM ($31), ROM + RAM + battery, 4 MB of
ROM, 8 KB of save RAM, North America, version 1.0.
MainInit
MainInit ($FD:C000, 215 bytes) puts the CPU and PPU into a known state in five steps. Every
register write goes through a relocated direct page, so each store is two bytes:
- CPU mode, stack (S =
$06FF), DB =$00, DP =$4200($FD:C000–$C013); - the CPU I/O registers through DP =
$4200($FD:C014–$C035); - DP =
$2100, the screen into forced blank ($FD:C036–$C041); - the PPU registers through DP =
$2100($FD:C042–$C0D2); most are zeroed; JML GameLoop($FD:C0D3).
It leaves with interrupts, NMI, DMA and HDMA off. It is also reached by JML MainInit at
$C0:418D, in Evt_OpFF96_Reset (event opcode $FF $96), after InitHW: the game restarts
from its cold start. Ppu_SetBgLayout ($FD:C0D7), right after it, sets a fixed
background layout the same way.
GameLoop's cold init
GameLoop ($C0:000E) installs the interrupt trampolines (InstallNMI: JML NmiHandler into
$7E:0500; InstallIRQ: JML IrqHandler into $7E:0504), sets DP = $0100, runs InitHW
(interrupts off, forced blank, NMI, DMA and HDMA off, DB = $00), and clears WRAM with
ClearRAMDMA in three blocks ($7E:0000–04FF, $7E:0700–FFFF, $7F:5080–A0FF), leaving
the trampolines and the stack alone. ClearRAMDMA ($C0:2DF1) fills with DMA channel 7 from the PPU's
Mode 7 multiply result (MPYL), which reads 0 because both operands are 0. Then it starts the sound driver
(JSL Audio_DriverInit, bank $C7) and sends bank $C2 its start-up command
(JSL BankC2_Entry8004), and falls into GameLoop_Main.
GameLoop is reached a second time by BRL from Scene_Unk0283 (probably the game-over path).
The review of MainInit noted that its name is probably wrong, since it starts with an init
sequence rather than a loop.
Functions
| Address | Function | Size | Status | Notes |
|---|---|---|---|---|
$C0:FF00 | Reset | 16 | verified | target of the emulation-mode RESET vector ($FFFC) |
$C0:FF10 | NMI_ | 4 | verified | Native-mode interrupt stubs ($FF10–$FF17) |
$C0:FF14 | IRQ_ | 4 | verified | |
$C0:FF18 | BRK_ | 8 | verified | native BRK and emulation-mode COP both land here |
$FD:C000 | MainInit | 215 | verified | Called via: JML from Reset ($00:FF03), which also carries the soft resets, and JML $FDC000 at $C0:418D (Evt_OpFF96_Reset, after JSR InitHW and S=$06FF). |