[WIP] Implement interrupts
I tried implementing interrupts. There is still some work to do.
SVC, STI and LPS instructions now work.
SVC and timer interrupts are implemented.
Also added two test programs:
-
interrupts.asm–entrysets up theSWthen jumps to some code, that triggers twoSVCinterrupts. -
interrupts_timer.asm– main loop printsA, and is interrupted by interrupt handler that printsTIM. Then the timer is reset to random value. It should be used with-a addons/out/make/rand.jar
I also changed SVC instruction in asm so that it can both r1 and r2 can be used. This seems logical to me (interrupt code can hold a whole byte) and might be a mistake in Beck's book, since the processor is very hypotethical. Although I haven't read the relevant chapters in the book as precisely this time and may have missed something.
All current programs should work out-of-the-box, since the processor starts in privileged mode and all interrupts are masked. Those two states can only be changed by writing to SW, which is very hard to do accidentally (to my knowledge only method is with LPS instruction). There is still question about faults that wrote an erro to the logger (for example invalid opcode, addressing or division by zero). If the program interrupt is enabled, the behaviour is quite clear. In other cases (default) should the error still be output or should we just silently continue executing?
Early comments are appreciated.
TODO:
- software interrupts (not all have to be done at the same time). Division by zero should be simple.
- privileged instructions (probably very simple – just check
MODEinSWbefore executing an instruction. Should also need a software interrupt.) - memory protection and segments (not sure about difficulity and amount of work)
- processes (there is an
IDinSWset by the "kernel" – not sure if anything has to be done in vm) - idle processor state – now it can be interrupted
- busy waiting (
label J label) should maybe not stop the processor if interrupts are enabled. - hardware interrupts – should probably be done in addons (also they could support memory mapped devices easier. I think keyboard, for example, has raw access to memory which is not the most elegant approach. It should be supported first-class by the simulator [another device class in java?]) I am also unsure about the implementation. Should each "device" get its own interrupt line and deassert the interrupt itself when the software has cleared it?
When implementing privileged instructions (which was generally quite simple), I noticed that fetch/decode and execute steps should be separated. Fetch and decode steps cannot be sensibly separated as F2 and F34 instructions need partial decoding before fetching again (F3 even twice and F4 thrice).
I can't find where pseudo halt is implemented. I think it should happen only if timer and hardware interrupts are disabled. Only in that case could a busy wait not be interrupted.
Also there seems to be an idle flag in SW. Does that mean that instructions would not be executed if the processor would be in idle state?
TODO (GUI):
- add timer to CPU view
- split SW (like the whole instruction or nxbpe bits)
I'm happy with the changes and I'm done for now. @jetomit and @jurem you are welcome to test all four examples and play with them (sometimes you can change SW to mask or unmask certain interrupts and observer the behaviour) and possibly review the changes to the code (I know it's a big merge request). I will squash the commits and clean the code a bit more if you are happy with the changes, before the PR can be merged. It was a fun weekend project (took about 8 hours) and I hope now a student can write an entire OS for their bachelor's.
TODO (GUI):
* add timer to CPU view * split SW (like the whole instruction or nxbpe bits)
done