docs: Add information about interrupt handling

This commit is contained in:
slederer 2024-11-05 01:27:01 +01:00
parent 8a2aa5c863
commit e2f6154879

View file

@ -109,12 +109,16 @@ Note:
|LOADREG|register spec|load from special register| |LOADREG|register spec|load from special register|
|STOREREG|register spec|store X to special register| |STOREREG|register spec|store X to special register|
|FPADJ|10-bit signed constant|adjust FP register| |FPADJ|10-bit signed constant|adjust FP register|
### Register Specification ### Register Specification
|Spec|Description| |Spec|Description|
|----|-----------| |----|-----------|
|FP | Frame Pointer Register| |FP | Frame Pointer Register|
|BP | Base Pointer Register | |BP | Base Pointer Register |
|RP | Return Stack Pointer | |RP | Return Stack Pointer |
|IV | Interrupt Vector Register |
|IR | Interrupt Return Register (readonly) |
|ESP | Eval Stack Pointer (readonly) |
### Comparison Selectors ### Comparison Selectors
|Sel|Description | Function | |Sel|Description | Function |
@ -126,6 +130,31 @@ Note:
|GE | greater or equal| Y >= X | |GE | greater or equal| Y >= X |
|GT | greater than | 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 ## Instruction Reference
### BRANCH ### BRANCH
#### Description #### Description
@ -1200,6 +1229,9 @@ Load content of a register onto the stack.
|FP | Frame Pointer Register|0000| |FP | Frame Pointer Register|0000|
|BP | Base Pointer Register |0001| |BP | Base Pointer Register |0001|
|RP | Return Stack Pointer |0010| |RP | Return Stack Pointer |0010|
|IV | Interrupt Vector Register |0011|
|IR | Interrupt Return Register |0100|
|ESP | Eval Stack Pointer |0101|
#### Examples #### Examples
Get content of BP register: 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| |FP | Frame Pointer Register|0000|
|BP | Base Pointer Register |0001| |BP | Base Pointer Register |0001|
|RP | Return Stack Pointer |0010| |RP | Return Stack Pointer |0010|
|IV | Interrupt Vector Register |0011|
It is not possible to write to the _IR_ and _ESP_ registers.
#### Examples #### Examples
Set BP register to 2000 (hexadecimal): Set BP register to 2000 (hexadecimal):