Interrupts:
Posted: 18 Nov 2019, 03:59
Whilst finishing this BASIC compiler I am working on, one of the things I have been implementing is a time sliced architecture that allows a chained set of routines to run in a real time fashion. e.g. I want my audio routines, (sound and MIDI), to playback uninterrupted and at the correct tick rate no matter what is going on in the user's code or being displayed on the screen, or even what scanline mode the screen is in.
This is not a trivial task, either I leave it up to the programmer to insert tickMidi() and tickAudio calls in every processor intensive routine, (which is what I did in Tetronis, not fun), or I build in a seamless system that does it for you automatically, (which I have done).
So currently every intensive tight loop in the runtime, (mostly graphics stuff, busy waits, etc), has a call to a stub routine which by default is just a RET. Calling functions like PLAY MIDI <address> will insert the appropriate runtime function's address into this stub and voila you have seamless time-slicing of real time critical routines.
Ok, that's all well and good, but there's no free lunch and there are some drawbacks:
Interrupts...
Well, specifically, one vertical blank interrupt for vCPU code built into the ROM; how would it be done and what would be required?
Does anyone have thoughts, ideas, additions? Obviously we could rely on Marcel to do everything when it comes to Native code, or we could help push it in a community driven direction.
This is not a trivial task, either I leave it up to the programmer to insert tickMidi() and tickAudio calls in every processor intensive routine, (which is what I did in Tetronis, not fun), or I build in a seamless system that does it for you automatically, (which I have done).
So currently every intensive tight loop in the runtime, (mostly graphics stuff, busy waits, etc), has a call to a stub routine which by default is just a RET. Calling functions like PLAY MIDI <address> will insert the appropriate runtime function's address into this stub and voila you have seamless time-slicing of real time critical routines.
Ok, that's all well and good, but there's no free lunch and there are some drawbacks:
- it costs cycles even when the stub routine is just a RET.
- if the user's code itself is processor intensive without calling any runtime functions, then they need to insert appropriate TICK MIDI/AUDIO calls in their loops.
- every new non trivial runtime routine needs to have this architecture built into it.
Interrupts...
Well, specifically, one vertical blank interrupt for vCPU code built into the ROM; how would it be done and what would be required?
- 2 bytes in zero page allocated for user VBLANK address.
- Native code that runs at vertical blank that saves vPC into vLR and saves vAC, (maybe even vTMP?), on the stack.
- Native code that copies VBLANK address to vPC and calls dispatch.
- Native code that restores vPC from vLR, etc etc
Does anyone have thoughts, ideas, additions? Obviously we could rely on Marcel to do everything when it comes to Native code, or we could help push it in a community driven direction.