If this is a "patched ROM" (i.e. a patched commercial ROM), please do not upload it here -- it will be deleted by a mod immediately citing copyright. An IPS patch would be fine.
There's nothing wrong with using
rti as code at a vector point. But it sounds like the commercial ROM just set unused vectors to $FFFF (this is probably because Nintendo mandated that "unused portions of a ROM be filled with $FF" even though tons of games didn't do this -- it just made it easier on the EPROM and mask ROM process (hardware folks please correct me if I'm wrong)).
Either way, I can assure you that VBlank is tied to NMI, not IRQ. Geiger's SNES9x with debugging capabilities, although runs extremely wonky in present-day OSes (Windows 7 up), will give you vector information. I think there's a modified bsnes-classic that has some debugging capability as well.
Chrono Trigger has a special place in my heart, filed under "games that really made my (technical) life hell" (for a couple reasons), so I'm already gritting my teeth. ;)
Edit: these are the official vectors from Chrono Trigger (MD5 and filename:
a2bc447961e52fd2227baed164f729dc Chrono Trigger (U) [!].sfc). "8-bit" means emulation mode, "16-bit" means native mode.
Code: Select all
Vectors:
8 Bit 16 Bit
ABT $00:FFFF $00:FFFF
BRK $00:FFFF $00:FF18
COP $00:FF18 $00:FFFF
IRQ $00:FFFF $00:FF14
NMI $00:FFFF $00:FF10
RES $00:FF00
Review of the actual code at vectors $FF18 (native mode BRK and emulation mode COP), and $FFFF (a placeholder vector, i.e. isn't used), tell me the following:
The $FF18 vector contains an infinite loop that just does an
lda $abcdef infinitely (i.e. something you could easily witness/see in a debugger or possibly on a hardware ICE):
Code: Select all
$00/FF18 AF EF CD AB LDA $ABCDEF[$AB:CDEF] A:0000 X:0000 Y:0000 P:envMXdIzC
$00/FF1C 80 FA BRA $FA [$FF18] A:0000 X:0000 Y:0000 P:envMXdIzC
The $FFFF vector is worthless: $00FFFF (contains $FF) and $000000 (direct page, so it's going to vary). So, this is as I suspected: it's just filling unused vectors with $FFFF.
The RESET vector at $FF00, however, is legitimate:
Code: Select all
$00/FF00 78 SEI A:0000 X:0000 Y:0000 P:EnvMXdIzc
$00/FF01 18 CLC A:0000 X:0000 Y:0000 P:EnvMXdIzc
$00/FF02 FB XCE A:0000 X:0000 Y:0000 P:EnvMXdIzc
$00/FF03 5C 00 C0 FD JMP $FDC000[$FD:C000] A:0000 X:0000 Y:0000 P:envMXdIzC
$FD/C000 C2 10 REP #$10 A:0000 X:0000 Y:0000 P:envMXdIzC
The NMI and IRQ vectors for emulation mode are set to $FFFF because the game *immediately* inhibits IRQs and switches to native mode (see above RESET code). This is important because the NMI and IRQ vectors in native mode jump to code located in RAM:
Code: Select all
$00/FF10 5C 00 05 00 JMP $000500[$00:0500] A:0000 X:0000 Y:0000 P:envMXdIzC
$00/FF14 5C 04 05 00 JMP $000504[$00:0504] A:0000 X:0000 Y:0000 P:envMXdIzC
In other words: Chrono Trigger, during run-time, almost certainly modifies $000500 to $000503 to a long jump (5C xx xx xx) to a location of its choosing, allowing for different kinds of VBlank and IRQ handling routines to be used. Common technique.
Finally: breakpoints for vectors often requires that you add breakpoints for bank $00 addresses, not higher banks ($80 or $C0). Bank $00 is where the vectors are loaded from in the actual CPU (the vectors are only 16-bit, as you know). Quoting WDC documentation, with the relevant part underlined:
When an interrupt is first received, the processor finishes the currently executing instruction and pushes the double-byte program counter (which now points to the instruction following the one being executed when the interrupt was received) and the status flag byte onto the stack. Since the 6502 and 65C02 have only a sixteen-bit program counter, only a sixteen-bit program counter address is pushed onto the stack; naturally, this is the way the 65802 and 65816 behave when in emulation mode as well. The native-mode 65802 and 65816 must (and do) also push the program counter bank register, since it is changed to zero when control is transferred through the bank zero interrupt vectors.
"Program counter bank register" refers to what's known as
K, or alternately
PCB (program counter bank). This refers to the bank code is currently executing out of. Do not confuse it with
B (data bank register).