Interesting. I have read the thread... and a lot more. The fog is beginning to lift...
Yes, the ARM system exceptions are definitely how this should be done. Specifically, SVC (SuperVisor Call) at vector 11 should be used. So I then had a look at your Teensyduino "attachInterruptVector" - a one-liner which sets an array "_VectorsRam[irq + 16] = function;" (where function is an address of the handler routine).
Then the penny dropped. The vector table no longer resides in FLASH at address 0000_0000h, but I guess that Teensyduino relocates this into RAM - even before a user sketch code runs. It has to be so? Or else a user could not dynamically change it
!
Looking at your "attachInterruptVector" this won't work for the first 16 vectors (unless you pass a negative irq number). But I should be able to use "_VectorRam[11] = function" (or an ASM equivalent). Being RAM I should have the priviledge necessary to address it in user mode, before I make the SVC call. We shall see.
Consequent from the fog dispersal, I read that SVC is exactly the same opcode as the former SWI instruction. It appears to have been "rebranded" in Cortex-M3 resultant on some other changes. I dropped a "SVC #0" instruction into my ASM just to see if it would assemble under gcc - and lo and behold - it did.
The puzzle on "multiple software interrupts" is also clear now. Its the info in the opcode information field - the "#0" bit. Your SVC handler has to go back and read the actual opcode instruction info field (in FLASH) to know which of the "multiple software interrupts" was actually intended. And this gets a bit hairy because you have to deduct either "4" or "2" from the LR register inside the handler to know where the opcode instruction can be found - which of these two values depends on whether your code is running under ARM (32 bit) Instructions of Thumb2 (16 bit) instructions.
For anyone reading this reply, its the Teensy mcu response to interpretting the SVC opcode that does the mode switch from "user mode" to "supervisor mode". What appears to happen is that the CPSR register gets "saved" temporarily into a new one called SPSR (ready for the return journey), and the CPSR is magically altered to show the new mode as well as having the INTERRUPT DISABLE FLAG set. This all happens before the SVC handler routine commences. Once under way, you then have to write a SWITCH function (after you have calculated which of the multiple software interrupts was intended) to perform the specific task requested. Finally, when exiting your SVC handler you must use "MOVS pc, lr" (or equivalent) as the last instruction - this restores the original CPSR from that saved one in SPSR before passing you back to the instruction that follows "SVC #0" (which switches you back into user mode and re-allows whatever interrupts were permitted).
Reading ARM literature, the terms "interrupt" and "exception" get mixed together - "interrupt" appears to be a response to an external event (such as a pin change) and "exception" is a response to an internal software event (such as a divide by zero). They work in almost the same way - perhaps the "mode" switch is the difference. This might explain why IRQ94 exists - the literature calls this a "software interrupt". Being at the end of the vector table, I guess that it won't mode switch, which means that I could
not have used this as I intended in the original post. Glad I spotted this now!
If I ever get to read the original Oscillator Register at 4006_5000h, then I will post an example back on this forum thread, so that others can see how to do it.
All this reminds me of those bygone lazy summer days of the DOS "Int 21h" call - jeez was that really 30 years ago...