Well, this is rather odd but maybe a developer out there might find this useful one day:
Someone who shall remain nameless was struggling to find an elusive and nasty bug which only happened after hours of gameplay on real hardware and asked me whether I could maybe override the reset vector so that he could tweak it to jump into some debug code for some sort of forensic search of what is going on. As it happens I tried this before: on the Atari VCS a ‘bus stuffing’ technique is sometimes used and I tried a variant, just to change a bit in a specific adr. provided by the vectrex rom to be able to take over the system right at the start. This did not work reliably, though.
However, I remembered that there is an unused line even better suited: the NMI line. As far as I know this one was never used on the Vectrex and it is indeed quite hard to find a reason to use it: the non maskable interrupt will interrupt absolutely everything, esp. drawing routines, after all. But for a debug ‘what the heck is going on’ fallback this one is ideal since this way the 6809 registers are preserved. So I thought I hook up a button and see how reliable it would be to use. The problem I immediately thought of was button bounce and therefore stack problems, after all memory is scarce.
Turns out the simplest version – just hooking up any odd button to nmi/gnd – works just fine with a bit of software handling. The trick is to store the stack pointer away the first time around, use a bogus one for a while afterwards and delay a bit to ignore any later bounce. Here is the version where I’ve pressed and tested the nmi a few hundred times to check that it always works with my setup:
NMI_HANDLER cmps #$E000
bge NMI_HANDLER_BOUNCE
sts nmi_stack_ptr
NMI_HANDLER_BOUNCE
lds #$F000
ldx #30000
NMI_HANDLER_DELAY
leax 1,x
bne NMI_HANDLER_DELAY
ldx nmi_stack_ptr
lda ,x
sta nmi_cc
ldd 1,x
std nmi_d
lda 3,x
sta nmi_dp
ldd 4,x
std nmi_x
ldd 6,x
std nmi_y
ldd 8,x
std nmi_u
ldd 10,x
std nmi_pc
tfr x,s
; from here on: reaction to nmi
So esp. nmi_stack_ptr is always correct which means the absolute first bounce is not fast enough to stop the lds #$f000 afterwards. As a test I’ve put the code into the 6809 disassembler cart. (v1.0) and when pressing nmi it now switches to a debug page where the register values when NMI was pressed are displayed.
This is so simple you could easily hook up a button to a simple eprom cart., for example, but I cannot really think of a good reason as to why one should do that. To enter an options menu, maybe ?