In May last year I wrote a forum post on Proboard (interrupt-driven-wangle). I always wanted to write a little bit in more detail about it, but somehow never did. Probably because of Vectorblade.
Wangle is a “game” by Graham Toal, which amongst other things has to do some intensive calculations. With intensive I mean in the range of a couple of hundred THOUSAND 6809 cycles.
The game itself worked nonetheless quite well, but it had some “screen blanking” during those calculation phases.
Now Graham and I had been talking about interrupt driven Vectrex output before (3 years before Wangle display-lists-direct-drawing) – and that game and the circumstances brought it back to our thoughts (routines-suspend-using-timer-interrupts and interrupt-driven-wangle)
The original discussion was about to build a programming environment using “C” in which an aspiring vectrex programmer would be able to “dispatch” drawings to a (vectrex-) software modul, which would represent some sort of DVG (Digital Vector Generator) unit (like in the arcade machines) – which would run in a different “thread” – and would thus seperate the vectrex “drawing” from the vectrex “programming”.
I did some sort of protoype (see links in forum), but somehow the project was lost in time and space.
(But IMHO the whole technique was more an experiment in what could be done, rather than a usable approach to vectrex programming).
Anyway, with Wangle in mind it would be good to:
- realize complex computations which take more than a usual vectrex round
- at the same time being able to display the “last completely computed output”
The 6809 CPU is not capable of multiple parallel working threads such as todays processors. The 6809 can only follow “serial” instruction flows.
However the 6809 is capapable of so called interrupts. As the name suggests an “interrupt” is an unplanned discontinuation of the current program flow.
Usually the states of all registers are saved, the program counter is set to a predefined position, the interrupt “program” is executed, the registers are restored to the settings before the interrupt occured and the program continues at exactly the same position where it was interrupted.
Causes for interrupts can include:
– timer reaches zero (periphal interrupts)
– user action (e.g. button press)
– programmed (software interrupts)
The different reasons for interrupts are handled by different program parts. These parts are usually called “interrupt handlers“.
The vectrex BIOS alows us to configure these interrupt handlers using special RAM locations.
Further for easier handling the 6809 processor has a special “interrupt flag” that by switching alows it to either ignore interrupts or to accept interrupts.
During interrupt “handling” usually all further interrupts are disabled.
Interlude: Vector drawing
Drawing vectors with the vectrex hardware needs to be very exact!
Depending on the circumstances the user can discern when vectors are drawn with a difference in the timing frame of only one processor cycle – 1/ 1500000 of a second!
Amongst other things – this means the programmer MUST ensure, that vector drawing is never “interrupted” otherwise a clean display can not be guaranteed.
Per default the BIOS and nearly all Vectrex programs have interrupts disabled – otherwise the clean display would suffer!
(Exceptions to the rule: Lightpen programs, 3d-imager programs)
Back to our “problem” – a little visualization:
With the explained background:
The plan to realize the above goes as follows:
- all vectrex output (vectors) is realized within an interrupt handler (which can not be interrupted and thus is able to cleanly display)
- the computation is realized as the main program, which can be interrupted
The program parts than execute as follows:
The execution “style” might be a bit counter intuitive. First initialization:
- initialize the program
– configure timer T2 to issue an interrupt when it reaches zero
(T2 times one vectrex round)
– set interrupt handler
– configure the 6809 processor to enable interrupts
– start main program
One vectrex “round” goes like this:
- the main program only computes “new values” and finished with a statement, that “waits for the next interrupt” (or gets interrupted during coomputation)
- while the main program executes it is interrupted each time the timer T2 reaches zero
- than it displays all vectors within the interrupt, when finished displaying
- it returns from the interrupt
- and thus continues the main program
Did I mention that we did all that in “C”?
… and a link to the proboard post, which includes a link to the sourcecode:
In wangle I set the vectrex round to be slower than 50Hz.
It must be assured, that the interrupt handler takes less time than one round – otherwise the computation would never finish!