BigEd wrote:
The indirect jump is rather a good tool here. JMP (somevector) allows you to put two bytes in a well-known location, and it will either do the usual thing (because the OS initialised those two bytes) or a new thing (because some program wrote its own handler address to those two bytes.)
It's good practice, just before writing your new value to the two-byte vector, to first read the value that's there and put it in your own exit routine, so your new code will fall through to the pre-existing code if it finds it has nothing to do, or if it's done with what it's doing.
Acorn's MOS actually chains IRQ handling through two vectors - an early one, which a user can use for very time-critical purposes, at the risk of delaying, say, ACIA handlings, and a late one, which comes after all the OS business, whereby the user can do things without adding latency to the OS.
This system works very well and it's very easy to add your own handler for a specific interrupt, the user code looks something like this:
Code:
.myirq1v
BIT &FE6D \ Check for user VIA interrupt
BVS handletimer1irq \ Is it a timer 1 interrupt?
JMP (savedirq1v) \ Chain to the old irq1v handler
So it's very easy to intercept a specific interrupt and pass everything else to the OS - especially if you don't still need the OS to process the interrupt you're handling.
Acorn's MOS also has a third vector, in addition to the two BigEd mentioned above, called the "event vector", which is even easier for user code to deal with - alongside the OS's usual handling of interrupts, it also passes specific events through this vector. For example, one event is vsync, another is a 100Hz clock tick, another is a key being pressed. For each of these it sets the A register (I think) to a code that identifies the event type, and calls the user handler via the "eventv" vector. This means the user code can immediately process the events without having to interrogate hardware directly. See more notes here:
https://tobylobster.github.io/mos/mos/S-s14.html#SP25Finally, to reduce the latency when handling disc and network interrupts, these are connected to the NMI pin, and the NMI vector at FFFA points into RAM at 0D00, which is initialised with RTI on startup. The disc and network software copy various NMI handlers to that RAM location to deal with different types of events (e.g. reading from disc and writing to disc use different handlers). So it is possible to use this sort of system, but it has to be carefully managed.