From e2f6154879cf28ea302d7a3c02318fc3c5a95a8c Mon Sep 17 00:00:00 2001 From: slederer Date: Tue, 5 Nov 2024 01:27:01 +0100 Subject: [PATCH] docs: Add information about interrupt handling --- doc/tridoracpu.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/doc/tridoracpu.md b/doc/tridoracpu.md index b0c5bb6..d00574a 100644 --- a/doc/tridoracpu.md +++ b/doc/tridoracpu.md @@ -109,12 +109,16 @@ Note: |LOADREG|register spec|load from special register| |STOREREG|register spec|store X to special register| |FPADJ|10-bit signed constant|adjust FP register| + ### Register Specification |Spec|Description| |----|-----------| |FP | Frame Pointer Register| |BP | Base Pointer Register | |RP | Return Stack Pointer | +|IV | Interrupt Vector Register | +|IR | Interrupt Return Register (readonly) | +|ESP | Eval Stack Pointer (readonly) | ### Comparison Selectors |Sel|Description | Function | @@ -126,6 +130,31 @@ Note: |GE | greater or equal| Y >= X | |GT | greater than | Y > X | +## Interrupt Handling +The CPU has a single interrupt line _irq_. Multiple interrupt sources are handled by the interrupt controller. Interrupts need to be enabled in the interrupt controller before any interrupt is signaled to the CPU. See the [Interrupt Controller Documentation](irqctrl.md) for details. + +If an interrupt occurs (i.e. the _irq_ line is high), the address of the next instruction is copied into _IR_ (the interrupt return register). +Then the program counter is set to the value of _IV_ (the interrupt vector register). + +So the _IV_ register should contain the address of the interrupt handler routine, and the address to return to +from the interrupt is written to the _IR_ register. + +If the interrupt occurs during the last cycle of an instruction, the interrupt will be acted upon one instruction later (i.e. the instruction after the next instruction). + +If another interrupt occurs when an interrupt handler is running, _IR_ will be overwritten, so without further precautions, nested interrupts are not supported. +The interrupt controller will not allow further interrupts until the pending interrupt is acknowledged, so that should not not a problem. + +The interrupt handler must preserve the contents of all registers on return, and will use the same evaluation stack so it is advisable that it uses +as few eval stack slots as possible. + +The interrupt handler schould also check the interrupt controller registers for multiple interrupt sources that may be active, and also re-enable interrupts in the interrupt controller at the end. + +To return from an interrupt, you can execute the following instruction sequence: +``` + LOADREG IR + JUMP +``` + ## Instruction Reference ### BRANCH #### Description @@ -1200,6 +1229,9 @@ Load content of a register onto the stack. |FP | Frame Pointer Register|0000| |BP | Base Pointer Register |0001| |RP | Return Stack Pointer |0010| +|IV | Interrupt Vector Register |0011| +|IR | Interrupt Return Register |0100| +|ESP | Eval Stack Pointer |0101| #### Examples Get content of BP register: @@ -1229,6 +1261,9 @@ Set register to value of the topmost stack element, which is removed afterwards. |FP | Frame Pointer Register|0000| |BP | Base Pointer Register |0001| |RP | Return Stack Pointer |0010| +|IV | Interrupt Vector Register |0011| + +It is not possible to write to the _IR_ and _ESP_ registers. #### Examples Set BP register to 2000 (hexadecimal):