DragWx wrote: ↑Mon Mar 20, 2023 7:33 pm
Yes, modifying the CINV vector is the only way to supply your own IRQ handler (and there's no way to bypass the short "preamble" baked into the kernal rom), so always make sure it points to a valid IRQ handler or else Fun Stuff™ happens.
Also of note, the CINV vector's memory address is part of the C64's original API, so I think it's safe to always count on it being the same between kernal revisions.
This is mostly true, and likely to be completely true as of hardware revision 2.
tl;dr: If you want the all the ugly details, keep reading, otherwise just assume that CINV is the only way to implement IRQs, and that CINV will be always invoked with the ROM bank set to 0.
At present, the kernal and BASIC ROM banks (0 and 4, respectively) have handlers for IRQs baked into them, but not all ROM banks have the interrupt vectors or logic. If other ROM banks are selected, this means allowing an IRQ to occur may result in a system crash.
If you explore cartridges, their memory uses the same address region as ROM banks, and as a result they can currently implement their own IRQ handling logic, even bypassing the kernal's default preamble. Simply make sure the appropriate cartridge bank is selected when the IRQ occurs.
But be aware that this behavior is likely to change in the future.
That having been said, and looking towards the future, Wavicle seems likely to take over the hardware design of the X16 for the gen-2 hardware, and he strongly wants to add a feature that would force the X16 to always reference bank 0 for interrupts. There are good technical reasons for this, particularly when it comes to interrupts that may happen early in the boot process and create race conditions. As far as the kernal is concerned, we're confident enough that this hardware change will occur to have already changed the kernal preamble to account for this change. If/when this change occurs, it would also mean that cartridges could no longer implement their own whole-cloth interrupt handlers, requiring them to go through CINV, and CINV would always execute with the current ROM bank set to 0.