Thom Brown's pl-cbmbasic extends PostgreSQL by statically recompiling the original 1982 Commodore 64 BASIC V2 ROM directly into C, running the interpreter natively inside the database backend without emulation overhead. The extension maps C64 disk I/O commands like OPEN and INPUT# to SQL queries through a "Device 8" interface, achieving roughly 15-microsecond call times while remaining restricted to superusers and stateless invocations.
PostgreSQL Extension Runs the Real 1982 Commodore 64 BASIC ROM Natively
A new PostgreSQL extension lets you run the original Commodore 64 BASIC V2 interpreter directly inside the database backend. It is not a modern reimplementation. It is not an emulator. The actual 1982 BASIC ROM, compiled straight to C and linked into the extension's shared library.
Thom Brown, known on GitHub as darkixion, built pl-cbmbasic to sit alongside PL/pgSQL, PL/Python, and the usual suspects. The project is drawing retro computing enthusiasts and database engineers in equal measure. The hook is technical, not nostalgic.
How the ROM Actually Runs
Brown leaned on an existing project called cbmbasic by Michael Steil (mist64). Steil already solved the heavy lifting. He took the original 6502 machine code, the KERNAL system library, and the BASIC interpreter, then statically recompiling them into plain C. Brown just vendors that C straight into his PostgreSQL extension.
Every invocation follows the same pattern. The extension zeroes out a 64KB RAM array, resets the CPU registers, and jumps to BASIC's $E394 entry point. No temp files. No pipes. Just a memset and a function call. The whole pipeline costs roughly 15 to 20 microseconds. A fork/exec approach would hit a few milliseconds per call. On modern hardware, the recompiled ROM runs about a thousand times faster than the 1 MHz 6502 it was written for.
Head here to read Steil's original repository if you want to dig into the recompilation process.
Talking to the Database via Device 8
On an actual Commodore 64, data lived on disk drives marked by device number. Device 8 was the standard 1541 disk drive. Brown mapped device 8 straight to the database.
You OPEN a file handle, pass a SQL statement as the filename, and read results with INPUT#. Secondary address 15 routes write-only operations like INSERT or UPDATE through a DOS command channel that returns a familiar status record. Arguments get injected on lines 0 through 9 before your actual code runs. A float8 parameter becomes a CBM 40-bit float. A boolean shows up as -1 or 0. When the program exits, the handler walks BASIC's own variable table to pull return values back into SQL types.
Keep in mind that the extension ships with a validator that catches BASIC V2's quirks at CREATE FUNCTION time. Variable names longer than two characters get collapsed. Identifiers containing keywords like total (which hides TO) or budget (which swallows GET) get rejected outright. Lines max out at 63,999. The project also patches the STOP KERNAL call. That is the routine BASIC polls before every single statement. Brown swapped it for CHECK_FOR_INTERRUPTS(), so runaway loops respect PostgreSQL's query cancellation and statement_timeout.
The Catch and the Constraints
It is a rather ambitious integration, though you should know it comes with real limitations. The language is marked untrusted, which means only superusers can create functions. The 40-bit float format loses precision past roughly 9 digits, so bigint values get truncated. There is no persistent state between calls since each invocation power-cycles the emulated machine. The whole thing is not thread-safe either, relying on process globals that fit PostgreSQL's process-per-backend model but block recursion. You are also locked into a 78-character column limit when pushing data through device 8, and physical keyboard input simply does not exist.
The repository currently holds three stars and two commits on main. It is early. The core logic works, the regression tests pass, and the architectural idea holds up under scrutiny. If you want to see how to pipe a query through BASIC V2 and get results back, the source lives on GitHub under pl-cbmbasic. Brown's documentation covers the call handler, the validator, and the device-8 SQL channel built on fopencookie() and PostgreSQL's SPI.
It is not going to replace PL/pgSQL for your production workloads. But as a proof of concept for what happens when you treat a 40-year-old interpreter as compilable code instead of a museum piece, it does the job.
