Yesterday, I presented here the GCE Vectrex game console. Although I remember that a CPU extension was supposed to be sold to convert the console into a computer, it never saw the day. But, as mentioned in my previous post, it is possible to write your own game – or general-purpose program if you are foolish enough – for the Vectrex today. One solution I tested to so is the Vectrex32 cartridge. As a follow-up, I decided to go a bit deeper on how to use the Vectrex32 to write your code!

First, a few words about the module’s architecture. At its core, there is a 32-bit PIC microcontroller (PIC32MZ2048EFH064). In addition to its 2 MB of flash memory and 512 KB of RAM, it is accessing to 2KB of a dual-port memory, which, is also interfaced with the Motorola 6809 CPU of the Vectrex. Because of the high cost of dual-port memory, only 2 KB is used (in contrast, the Vectrex has only 1 KB or traditional RAM). Once you developed your BASIC program (for GSBASIC), you need to transfer it onto the cartridge, which shows up in your system as a USB drive and a USB serial interface. From the cartridge, the PIC runs (via interpretation) the code, and all the Vectrex-specific code calls are generating 6809 instructions, and BIOS calls into the Vectrex! Brilliant. And for this use, 2 KB should be enough to receive these commands – including audio-related ones. Also, keep in mind that as a Vectrex game developer you want to limit the number of objects you want the Vectrex to render on the screen so you can avoid flickering. Note that although the default frame rate of the Vectrex is set to 30 fps, you can set any arbitrary values at any time. The Vectrex simply can or cannot comply. But, in general, you can dynamically tweak this value in your code. In the demo code, look for the SetFrameRate() calls to see how, and how it translates in the video of the run.


Vectrex as co-processor

The Vectrex32 handles a lot for you so that you can focus on your game’s code. For instance, it provides a convenient way to automatically perform advanced graphic operations such as 2D and 3D transformations, play tunes, etc. The Vectrex on its side also has some ingenious capabilities for setting the scaling during the draw – an elegant way to overcome the limitation imposed by the use of 8-bit signed integers to represent coordinates and offsets. In general, the way the Vectrex draws reminds me of many graphics description languages such as PostScript – alas, without using a stack, that would have been so cool. Yeah, it’s BASIC, not FORTH. I will not get into all the finesse here, and if you are interested, you can look into the documentation on-line to learn more about I/O capabilities, user controls, timing, etc. As the last word, I will signal the ability to inject 6809 machine language into the 2KB dual-ported memory and have it executed, as-is, by the Vectrex’s CPU. And yeah, screw it up, and you will crash your Vectrex (just press reset to re-start, no harm done). I reassure you, when you operate on the PIC side, debugging the BASIC code is a bit more evolved, and you obtain explicit error messages and source code locations. So, to direct the native 6809 to load $FF into the A register and call the subroutine at $CD71, define machine_code = {$86, $FF, $BD, $71, $CD} and use codeSprite = CodeSprite(machine_code). Voila! If you have a Vectrex, now you know how you can expand its software library on your own!

' Hello World! Program
call IntensitySprite(127)
call ScaleSprite(50)

call MoveSprite(5, 10)
call TextSprite("HELLO WORLD!")

square = LinesSprite({ _
 {MoveTo, 5, 5}, _
 {DrawTo, -5, 5}, _
 {DrawTo, -5, -5}, _
 {DrawTo, 5, -5}, _
 {DrawTo, 5, 5}})

for i = 0.0 to 20.0
   call SpriteSetMagnification(square, i)
   c = WaitForFrame(JoystickNone, ControllerNone, JoystickNone)
next i

for i = 0.0 to 360.0
   call SpriteSetRotation(square, i)
   c = WaitForFrame(JoystickNone, ControllerNone, JoystickNone)
next i

for i = 1.0 to 100.0
   call SetFrameRate(i)
   c = WaitForFrame(JoystickNone, ControllerNone, JoystickNone)
next i