Interrupts are events that interrupt the execution of a program from an external source. Interrupts are divided into maskable interrupts and non-maskable interrupts (NMI) i.e. reset. Exceptions are events that interrupt the execution of a program that are generated by the program execution. For example dividing a number by zero would generate a "Zero Division" exception. Otherwise interrupts and exceptions are almost identical. But interrupts take precedence over exceptions. The v810 handles interrupts and exceptions through an interrupt table. When a given interrupt/exception is generated the current PC and PSW registers are saved in the EIPC/EIPSW registers. And when a NMI or Duplexed exception is generated the PC and PSW are stored in the FEPC/FEPSW registers. Next the exception cause register (ECR) is filled in with the interrupt/exception number, the PSW Int Level is set to 1+current interrupt level, the PSW EP and ID bits are set to 1 and the PC is updated to point to the interrupt handler vector.
In order for a maskable interrupt to occur the NP bit of the PSW must be 0, the EP bit of the PSW must be zero, the ID bit of the PSW must be zero. And the interrupt being fired must have an id greater than or equal to the Interrupt Level stored in the PSW.
Table 1: Interrupt/Exception Table
| Interrupt/Exception name | Classification | Code | Handler Address | Restore PC |
| Reset | Interrupt | 0xFFF0 | 0xFFFFFFF0 | undefined |
| NMI | Interrupt | 0xFFD0 | 0xFFFFFFD0 | next PC 1) |
| Duplexed Exception | Exception | 2) | 0xFFFFFFD0 | current PC |
| Address trap | Exception | 0xFFC0 | 0xFFFFFFC0 | current PC |
| Trap instruction (0x1n) | Exception | 0xFFBn | 0xFFFFFFB0 | next PC |
| Trap instruction (0x0n) | Exception | 0xFFAn | 0xFFFFFFA0 | next PC |
| Invalid OpCode | Exception | 0xFF90 | 0xFFFFFF90 | current PC |
| Divide by Zero | Exception | 0xFF80 | 0xFFFFFF80 | current PC |
| FIV (float invalid op) | Exception | 0xFF70 | 0xFFFFFF60 | current PC |
| FDZ (float zero divide) | Exception | 0xFF68 | 0xFFFFFF60 | current PC |
| FOV (float overflow) | Exception | 0xFF64 | 0xFFFFFF60 | current PC |
| FUD (float underflow)3) | Exception | 0xFF62 | 0xFFFFFF60 | current PC |
| FPR (float degradation)4) | Exception | 0xFF61 | 0xFFFFFF60 | current PC |
| FRO (float reserved op) | Exception | 0xFF60 | 0xFFFFFF60 | current PC |
| INT level n (n = 0 to 15) | Interrupt | 0xFEn0 | 0xFFFFFFn0 | next PC 5) |
The v810 is not set up to handle more than one interrupt at a time, it can handle up to 2 exceptions. In order to support multiple interrupts at a time your interrupt code must:
- disable all further interrupts by setting the ID bit of the PSW to 1
- save the EIPC and EIPSW registers
- clear the EP bit from the PSW
- finally re-enable interrupts by setting the ID bit to 0 in the PSW
Note that, if you want to use interrupts in your project, you have to use the latest version of gccVB (vb_v810_gcc_03).
Discussion