CRT Basic - a BASIC interpreter

Table of Contents

1. Introduction

crtbasic.png

CRT Basic is an interpreter for the BASIC programming language, written in pure Java. It runs classic .bas programs.

When started from commandline, it opens new graphical window where you will see program output. When window is resized, it scales virtual display with program output. When you click on the window, it will grab mouse cursor and will redirect mouse movement and button presses to the running BASIC program.

Press CTRL + F10 to release mouse cursor.

You can find here collection of example BASIC programs that are compatible with CRT Basic.

2. Quick start

To compile and install CRT Basic you need following dependencies:

  • Java JDK 21 or newer (set JAVA_HOME if it is not the default java)
  • Apache Maven (mvn on PATH)

Installation procedure:

cd /path/to/crtbasic/project
sudo ./install.sh                     # installs system-wide under /usr/local

The installer builds the jar with Maven and installs it under /usr/local, so every user on the machine gets it:

File Purpose
/usr/local/share/crtbasic/crt-basic.jar the interpreter itself
/usr/local/bin/crtbasic launcher script: exec java -jar ... "$@"
/usr/local/share/applications/crtbasic.desktop "Open With" entry for .bas files (hidden from the app menu)

No PATH setup is needed: /usr/local/bin is on the default PATH for all users.

Now you can run BASIC programs like this:

crtbasic my-program.bas

3. Architecture at a glance

A .bas file flows through a classic interpreter pipeline. The lexer is tolerant of DOS file realities (CP437 charset, CRLF line endings). The parser produces an AST of immutable records. An interpreter currently tree-walks the AST directly — an interim solution until the planned bytecode compiler and VM land. Program output goes to a virtual VGA device: indexed-color framebuffer, bitmap text console, palettes and video pages. Input arrives through a shared keyboard queue fed by the Swing window or by headless drivers.

Package Responsibility
lexer Source text → tokens
parser Tokens → AST (recursive descent)
ast Statement/expression record types
interp Executes the AST (interim tree-walker; bytecode VM planned)
video Virtual VGA: modes, framebuffer, text, drawing, palette
input Keyboard queue shared by all frontends
audio SOUND timing model (no audio output yet)
frontend Swing window: live screen view + key capture

For the full walkthrough see Architecture.

4. Language coverage

The interpreter supports a practical, growing subset of structured BASIC:

  • Graphics: SCREEN (modes 0, 1, 2, 7–13), PSET, POINT, LINE (plain, B, BF), CIRCLE (with aspect), PAINT, GET, PUT (PSET/XOR/OR/AND), PALETTE via OUT to the DAC ports, PCOPY.
  • Text: PRINT (with ; and , zones), LOCATE, COLOR, CLS, VIEW PRINT, CSRLIN, POS.
  • Control flow: FOR/NEXT (with STEP), single-line and block IF/THEN/ELSE/END IF, WHILE/WEND, DO...LOOP (WHILE/UNTIL on either end), GOTO and labels, SELECT CASE, END, SYSTEM.
  • Procedures: SUB and FUNCTION with by-reference parameters, CALL, DECLARE, DIM SHARED, DEFINT and siblings.
  • Data: DIM (multi-dimensional arrays, AS type), ERASE, DATA=/=READ.
  • Error handling: ON ERROR GOTO, RESUME / RESUME NEXT.
  • Files: OPEN ... FOR INPUT, CLOSE, INPUT #, LINE INPUT #, EOF().
  • Input and time: INKEY$, INPUT$, TIMER, TIME$, RANDOMIZE, RND (the classic 24-bit generator, bit-exact).
  • Sound: SOUND is modeled as a timing device (18.2 ticks/s, one-note queue); no audible output yet.

Anything not yet supported fails loudly with the offending line number — that is deliberate: the error message is the to-do list. Known gaps include console INPUT, CIRCLE arcs, GOSUB, DRAW and audio output.

The full reference is on the Language page.

5. The virtual VGA

Program output lands on a virtual VGA card modeled after real hardware:

  • Indexed pixels: one byte per pixel = palette index, exactly like mode 13h video memory. PALETTE tricks and color cycling work because remapping a palette entry recolors every pixel using it.
  • Text is pixels: there is no separate text plane. PRINT blits CP437 glyph bitmaps into the framebuffer, painting the whole glyph cell in every mode — which is why printing spaces erases text, exactly as vintage programs rely on.
  • Video pages: SCREEN 7–10 have multiple pages; drawing targets the active page while the monitor shows the visual page.
  • Pixel-exact drawing: LINE reproduces the classic DDA rasterizer including its clipping and endpoint bias, and CIRCLE follows the classic rounding rules (half-up rounding, SINGLE-precision aspect value).

Details and diagrams: Video subsystem.

6. Driving programs without a human

The headless path is the heart of the project:

# Run offscreen, cap at 100k statements, dump the screen
crtbasic game.bas --headless --screenshot=out.png --steps=100000

# Raw indexed pixels for byte-level comparison
crtbasic game.bas --headless --raw=out.raw

# Scripted play-testing: feed keystrokes, then inspect variables
java -cp target/classes:target/test-classes eu.svjatoslav.crtbasic.drivers.GameDriver \
    game.bas --keys="RR~~~LL~" --screenshot=end.png --vars=score%,lives%

The GameDriver feeds a scripted key sequence to a running game and prints chosen variables afterwards. Combined with statement budgets and framebuffer dumps, an agent can play-test keyboard-driven games entirely on its own.

See Agent integration.

7. Building and testing

cd /path/to/crtbasic
mvn package
java -jar target/crt-basic-*-SNAPSHOT.jar program.bas
mvn test          # JUnit: video semantics, drawing primitives, end-to-end runs

The install.sh script builds the jar and installs it to ~/.local/share/crtbasic together with a crtbasic launcher in ~/.local/bin and a desktop entry that makes .bas files open with the interpreter (set CRT_BASIC_PREFIX to install elsewhere).

A demo renderer (test sources) writes showcase frames for visual verification:

java -cp target/classes:target/test-classes eu.svjatoslav.crtbasic.video.VideoDemoMain
# frames appear in /tmp/crt-basic-demo/

8. Further reading

9. Source code

This program is free software: released under Creative Commons Zero (CC0) license

Program author:

Getting the source code:

Created: 2026-08-31 ma 01:26

Validate