~2.1k
lines of assembly
One source file
Menu, chrome, games, helpers — regression-tested with the core.
Tomato OS
Tomato OS boots on the FPGA computer, draws the wallpapered desktop, reads the controls, and runs games — including Sudoku. I wrote it in Tomato’s own assembly language. These captures are the HDMI stream, not a phone pointed at a monitor.
ALU verification, whole-machine simulation, and FPGA demonstrations are different evidence. Tomato OS exercises keypad MMIO, tile RAM, HDMI timing, the menu loop, and the current 256 × 32-bit FPGA register file. The CPU writes an 80×60 character field over a bitmap wallpaper; a separate scanout block reads it and drives the monitor. No GPU — games are loops in asm.
The clip above is the full tour: boot into Desktop v1.2, walk the application list, and open the games people ask about first — Tetris, Snake, Racer, Sudoku, Fibonacci — all painted by the CPU and scanned out over the DVI PMOD. Same recording lives in the gallery under Tomato OS.
Five Nexys buttons wired as a D-pad through rtl/board/keypad.v. Center (N17) is Enter. One physical press emits one key event — after fixing a bench that counted hundreds of repeats from a single push (dispatch). In Sudoku, Enter cycles the digit 1…9 then blank.
| Button | Keycode | In the shell |
|---|---|---|
| Up / Down | 0x1E / 0x1F | Move menu highlight |
| Center | 0x0D | Select · Enter screen · cycle digits in Sudoku |
| Left | 0x11 | Back to menu |
| Left / Right | 0x11 / 0x10 | Steer in Snake, Tetris, and Racer |
Keyboard MMIO lives at 0x780000: word 0 is the keycode (reading consumes it), word 1 is the ready flag. The Nexys 7-segment display follows the last nonzero writeback or store — so it is not stuck at zero while the shell waits for a key.
Boot splash runs once. Then Desktop v1.2: applications on the left, preview and credits on the right. Tomato OS v3.0 currently has fourteen entries, each dispatched through a jump table. Envelop is linked with its setup data and bounded remote executor.
| Entry | What it does |
|---|---|
| System info | What is Tomato — quirks table |
| Palette | 16-color swatch chart for the tile attribute field |
| Font chart | CP437-ish glyph grid — every drawable character |
| Keypad test | Live keycodes on screen — bench tool for the D-pad |
| Fibonacci | Running integers; 7-seg tracks the result |
| Snake | Tile paint, timing, keypad input |
| Tetris | Board in low RAM · piece rotation · line clears |
| About Tomato | Credits, Penn Engineering |
| Memory map | Bus windows the CPU can name |
| Sudoku | Arrows move · Enter cycles 1–9 · gold clues fixed |
| ALU Studio | MASKADD / XORAND vs reference sequences |
| Racer | Steer through traffic |
| Envelop | Queued messaging through a nearby verified bridge; local browser demo uses simulated peripherals |
| Compiler | Inspect and exercise supported instruction compilation |
Framebuffer window at 0x300000 — 80×60 cells, each an 8×8 pixel tile, composited over the Ghana wallpaper ROM. One word per cell (videoout.v):
Attributes with a black background fit in one ADDI — any tile with bg = 0 is 0x0FFF < 4096. Splash / wallpaper art is converted for the character field with software/os/tools/build_wallpaper.py (OS assets README).
Everything an LA reaches must sit under 4096 — it assembles to ADDI rd, r0, addr. Prose and pointer tables above that line use .word label instead.
| Region | Address | Use |
|---|---|---|
| Code | 0x0000 | Program and helpers |
| Strings | 0x0640 | Menus, tables, jump targets |
| Tunables | 0x0F00 | Bench pokes game speeds before reset |
| Scratch | 0x0F08 | Mutable OS state |
| Tetris board | 0x0F20 | One 10-bit row mask per word |
| Snake body | 0x0F40 | 128 packed cells |
| Tile art | 0x1200 | Ghana flag map (4800 words) |
| Framebuffer | 0x300000 | 80×60 tile RAM |
| Keypad | 0x780000 | MMIO data + ready |
Without hardware, print the framebuffer in simulation: make -C hardware/fpga/core os. Regression: make -C hardware/fpga/core test boots the OS image and checks menu + games. Or skip all of it: run the shipped firmware in your browser — no install, no FPGA.
Tomato OS and microcode are baked into the bitstream as literal Verilog — not loaded from SD card at runtime. After editing the asm, re-burn before synthesising.
On HDMI
Still frames from the same HDMI path — menu chrome, games, and the quirks table. The live tour is the demo at the top of this page.
~2.1k
lines of assembly
Menu, chrome, games, helpers — regression-tested with the core.
80×60
text field
Tile RAM at 0x300000. Scanout is separate silicon.
14
menu entries · OS v3.0
Indexed dispatch — new screen is one table row.