Draw a digit. It reads it.
Hold button 1 and draw a digit with the joystick. Lift the pen and the Vectrex reads it: the answer in the corner, a bar for every digit, and the 12×12 grid the network saw. It runs on a Motorola 6809 at 1.5 MHz. No coprocessor, no cloud, no co-anything.
Trained on the PC, using MNIST’s 60,000 handwritten digits. It reads on the 6809 itself.

The machine
Stock hardware. Nothing added.
Plenty of Vectrex projects run modern code on a modern processor and use the Vectrex as a display. This one runs entirely on the console’s own 6809, from an ordinary 12 KB cartridge image.
- PiTrex (a Raspberry Pi in the Vectrex)
- VecFever (an ARM in the cartridge)
- Vectrex32 (a PIC32 in the cartridge)
- any memory expansion
- the 1982 6809, its 1 KB, the BIOS
- a joystick (or a light pen)
Watch it
The demo draws a 1, a 7, a 0 and a 4 with a scripted joystick, and the cartridge reads each one. It was recorded frame by frame in MAME. The glow is a phosphor-decay filter: a real vector tube glows, and MAME’s 60 Hz capture of a 50 Hz console needs it to look whole.
The colours come from the overlay: Vectrex games came with a printed plastic film over the screen, and VecNIST has one too (overlay/vecnist.png).
Get the ROM
857a5285ac59c64ded7ebcad4223b208A standard Vectrex cartridge image. Tested in MAME; not yet tested on a real Vectrex.
No Vectrex? Try it in MAME.
If you don’t have a Vectrex, try it for yourself in MAME. It needs the
Vectrex BIOS (vectrex.zip) in its ROM path.
mame vectrex -cart vecnist.bin
The BIOS shows its own screen for about ten seconds, then the title, then the game. The joystick is the arrow keys (or a gamepad); MAME’s buttons 1–4 are the Vectrex’s.
How it reads
- The joystick moves a cursor, and every move is kept as a point: up to 220 of them in the 1 KB, as strokes. Each frame the Vectrex steers the beam along them again, because there is no frame buffer to keep them in.
- When a stroke ends, the drawing’s bounding box is fitted into 9 cells. A reciprocal table does the scaling,
so it’s one
MULper point and no division. The box is centred in a 12×12 grid of bits, and consecutive points are joined cell by cell. - Layer 1: every inked cell adds its row of 64 weights into 64 sums. It’s only additions, because the inputs are 0 or 1.
- Layer 2: each of the ten scores sums 64 activations times their weights, each product one
MUL, into 24 bits. The highest score is the answer. - On the PC, MNIST’s thick scanned digits are thinned to one-pixel strokes and pushed through the very same integer steps, so the network trains on what a joystick draws.
Build it yourself
git clone https://github.com/magneato/vecnist cd vecnist ./setup.sh # lwasm, MAME, Python + numpy (and checks for the Vectrex BIOS) ./build.sh # build/vecnist.bin, checked against Vide's own assembler if Vide is installed ./run.sh # play it in MAME (./run.sh --video vecnist.mp4 records the demo)
The folder is also a Vide project (VecNISTProjectProperty.xml). Link
it into Vide’s projects folder and assemble it there; the bytes are the same as lwasm’s. To retrain,
run ./get_mnist.sh and then python3 train/vecnist.py train (about 40 seconds on a PC).