VIC-20 Software: Working Within a Small, Expandable Computer
The VIC-20 is best approached as a family of related memory configurations, not as a smaller Commodore 64. Its 6502-family CPU, BASIC prompt, cartridge slot, cassette connector, and friendly keyboard invite experimentation, but a program that fits an unexpanded machine can have very different limits from one written for an 8K, 16K, or 32K expansion. Good VIC-20 software makes those limits visible: it checks the machine it expects, chooses data representations carefully, and leaves the user a safe way back to BASIC.
What starts when the machine starts
With no cartridge asserting control, the VIC-20 enters Commodore BASIC V2. BASIC is an interpreter in ROM; the KERNAL ROM supplies standard services such as keyboard input, screen output, serial I/O, cassette routines, timing, and interrupt handling. The character-generator ROM supplies the familiar PETSCII glyphs. ROM is not free general-purpose RAM: it contains code and character shapes, while a BASIC program, its variables, the screen, and a machine-code program need writable memory.
On a stock VIC-20, only about 3.5K is available to BASIC after the system uses part of the 5K RAM. At the prompt, PRINT FRE(0) reports the currently free BASIC bytes. That is a useful measurement, not a promise that software will run: cartridges can map ROM into address space, and an expansion can change where BASIC begins and where video memory is placed. Reset before trying another title if a program, cartridge, or loader says it requires a particular configuration.
Memory configurations are part of the software title
| Configuration | Practical consequence | Do not assume |
|---|---|---|
| Unexpanded | Programs must be compact; many tape titles were designed for it. | That an “8K” image will fit or load normally. |
| 3K RAM expansion | Adds a small low-memory area; some programs explicitly require it. | That it is interchangeable with an 8K block. |
| 8K/16K/24K/32K expansions | May provide RAM in different address blocks and give BASIC far more workspace. | That every 16K cartridge or modern RAM expansion maps identically. |
Original expansion cartridges and modern multi-RAM cartridges can select different blocks. A preservation entry’s stated RAM requirement and load address are therefore essential. A program whose documentation says “+8K” normally means a particular conventional mapping, not merely any eight kilobytes somewhere. Unlike the C64’s fixed 64K main-memory design, VIC-20 releases commonly exist in distinct unexpanded and expanded variants; use the one matching the selected RAM layout.
Screen, characters, and colour
The VIC-I chip presents a 22-column by 23-row text screen: 506 character cells. In the usual unexpanded arrangement the screen matrix begins at $1E00 (decimal 7680), and the corresponding active colour cells begin at $9600 (decimal 38400), within colour RAM decoded across $9400–$97FF. The screen holds character codes; it does not hold pixel art. Each colour cell holds a four-bit value, while the VIC registers select shared background, border, and auxiliary colours. The normal character set is ROM-based; writable RAM can hold a custom character set when memory and the VIC setup permit it.
That organization explains the visual character of much VIC-20 software: animated characters, careful use of PETSCII, and a small display can be fast and memory-efficient. It also explains why direct addresses in a listing are configuration-sensitive. A program with a relocated screen or custom character RAM should document its configuration rather than silently poking values intended for another machine.
A safe first BASIC experiment
The following listing only writes its own text to the ordinary screen and waits for a key. It neither saves nor changes memory maps. Type it at a cleared BASIC prompt, then use LIST to inspect it and RUN to execute it. STOP returns to BASIC.
10 PRINT CHR$(147)
20 PRINT "VIC-20: 22 BY 23 CHARACTERS"
30 PRINT "FREE BASIC BYTES:";FRE(0)
40 PRINT
50 PRINT "PRESS ANY KEY TO RETURN"
60 GET A$:IF A$="" THEN 60
CHR$(147) is the PETSCII clear-screen control code. The semicolon in line 30 keeps the number on the same line. This example deliberately does not POKE hardware. For a small screen demonstration, BASIC can use PRINT and PETSCII first; direct screen writes are rewarding only after the relevant memory configuration is understood.
Machine code without trampling BASIC
6502 machine code is fast, but placing bytes at an arbitrary address can overwrite BASIC text, variables, the screen, or an expansion-dependent area. A small teaching routine can use the cassette buffer at $033C only when no tape operation is in progress. This is temporary workspace, not a general program-storage recommendation: a cassette operation may overwrite it, and larger routines need an explicitly planned memory configuration.
This illustrative 6502 source simply returns immediately. Assemble it for $033C, inspect the output, and do not use cassette I/O while it is there:
; Temporary cassette-buffer example
* = $033C
safe_return:
RTS
From BASIC, SYS 828 calls code at $033C; an RTS returns to the interpreter. Save BASIC work before experimenting. Do not paste decimal POKEs from an unknown listing, and do not use SYS unless the load address, machine, and RAM map agree. A cross-assembler plus a monitor or emulator debugger makes labels, disassembly, and breakpoints safer than guessing.
How VIC-20 programs arrived
Consumer software appeared on cassette, ROM cartridge, and disk. Datasette tapes are sequential and slow but inexpensive. A stock VIC-20 uses Commodore's serial bus for drives such as the 1540 and compatible 1541 configurations; IEEE-488 drives require a separate interface and are not the normal requirement. Cartridge games start at power-on because their ROM maps into the address space. Fast loaders and copy protection can still depend on a particular drive, region, or memory expansion.
LOAD : load the next tape program (device 1)
SAVE "MYPROGRAM",1 : save a BASIC program to tape
LOAD "$",8 : load a directory from disk device 8
LIST : display that loaded directory
LOAD "PROGRAM",8 : load a BASIC program from device 8
RUN
LOAD "CODE",8,1 : load at the address stored in the file
SAVE "MYPROGRAM",8 : save a BASIC program to device 8
Device 1 is the Datasette; disk drives conventionally begin at device 8. The final ,1 is a secondary address telling LOAD to honor the file's stored load address, which is commonly needed for machine-language data but should not be added blindly to an ordinary BASIC load. A loaded directory replaces the BASIC program currently in memory, so save your work first. A machine-language program may need a documented SYS address or its own loader rather than RUN.
When using original media, clean and align hardware only with competent guidance, preserve the original before repeated loading, and avoid repeatedly adjusting heads to “fix” a doubtful tape. Archive formats describe different things: .prg usually contains a load address followed by program bytes; .t64 is a container for tape-file records rather than a recording of physical pulses; .tap captures tape pulse timing; .crt represents a cartridge image; and .d64 is a 1541-style disk image. The suffix alone does not prove platform, RAM requirement, or legitimacy. Keep a checksum, source, and notes about the expansion setting with each item.
Creative software and its constraints
VIC-20 games include cartridge arcade designs and cassette adventures, strategy, educational, and type-in programs. Their importance is not a chart of “best” titles: they show how designers turned a 22-by-23 display, limited sound, and variable RAM into readable rules and quick feedback. Home productivity software similarly had to trade features for memory: word processing, data entry, and personal finance often used compact records and disks or tapes for persistence. The machine was also a learning platform, where magazines published BASIC and assembly listings that taught users to read, modify, and debug code.
The present-day scene continues that practice. Demos and new games use custom character graphics, timing, compression, and bank-aware memory plans, sometimes targeting 32K expansions or cartridges. A new production should say plainly whether it targets an unexpanded VIC-20, a specific RAM block arrangement, or a modern hardware feature. Calling it “VIC-20 compatible” without that qualification makes preservation and repair harder.
Using originals, emulators, and modern tools responsibly
VICE is a widely used emulator family with a VIC-20 model; configure its RAM expansion and attach the appropriate image type before judging a program. Emulators are excellent for making a working copy, inspecting a load address, and learning with snapshots, but an emulator’s permissive setting can conceal a requirement real hardware lacks. For physical machines, devices such as SD2IEC-class storage, tape adapters, cartridge loaders, and RAM cartridges vary in what they emulate. Read the device documentation and begin with copies, not irreplaceable originals.
Modern development commonly uses a text editor, a cross-assembler such as ACME, ca65, or Kick Assembler where supported, an emulator, and version control. CBM PRG Studio and similar IDEs can help organize BASIC, assembly, and character data. Build scripts should emit a clearly named .prg or cartridge image, record its load address, and test the intended RAM configuration.
ROM dumps and commercial program images are usually copyrighted even when the hardware is old. Obtain firmware and software from your own legally made dumps, rights holders, licensed re-releases, or archives that clearly state authorization; do not treat an emulator download as a license. The VIC-20 User’s Manual, VICE documentation, and the Zimmer’s Commodore archive are useful starting points for technical and historical research. Verify an archive’s rights statement separately.
Checklist before loading
- Identify the image type, claimed machine, load address, and exact RAM requirement.
- Save your own BASIC work or power-cycle before changing cartridges or memory settings.
- Set the emulator or hardware expansion deliberately; do not substitute a C64 image or assumptions.
- Load a copy, retain provenance and checksums, and stop if a title asks for an unexplained overwrite.
- Document what worked: machine revision, RAM blocks, storage device, and software version.
dispelled