KERNAL I/O Routines
The Commodore 64’s built-in service desk
The C64’s KERNAL ROM exposes a patchable API for keyboard, screen, tape, disk, and serial I/O—perfect for BASIC and assembly alike.
The KERNAL ROM provides 39 entry points for device handling and system services. Commodore designed it as a stable “API” so BASIC, machine-code programs, and third-party cartridges could rely on consistent routines. The spelling is Commodore’s own. Jim Butterfield, writing in 1984, said its origin “seems to be lost in legend” — “it was originally an acronym, standing for something like ‘Keyboard Entry Read, Network and Link’” — and chose to keep “Commodore’s word” rather than correct it to “kernel”.
Fast facts
- Entry points: located at
$FF81–$FFF3, accessible via JMP vectors stored in RAM for easy patching. - Devices: numbered channels handle keyboard (0), Datasette (1), RS-232 (2), screen (3), serial-bus printer (4), and disk drive (8); any number from 4 up goes out over the serial bus.
- User port: not a numbered KERNAL device — it’s hardware on CIA#2 ports.
- Compatibility: the same KERNAL concept appears in the VIC-20, PET, C16, and C128 families.
Common KERNAL entry points
| Address | Name | Purpose |
|---|---|---|
$FF81 |
SCINIT | Initialise screen editor |
$FF84 |
IOINIT | Initialise I/O chips (CIA, VIC-II, SID) |
$FF87 |
RAMTAS | Test RAM and clear |
$FF8A |
RESTOR | Restore default I/O vectors |
$FFA5 |
ACPTR | Read byte from serial bus |
$FFA8 |
CIOUT | Send byte to serial bus |
$FFB7 |
READST | Read status of serial bus |
$FFBA |
SETLFS | Set logical file number, device, secondary address |
$FFBD |
SETNAM | Set filename |
$FFC0 |
OPEN | Open a file |
$FFC3 |
CLOSE | Close a file |
$FFC6 |
CHKIN | Set channel for input |
$FFC9 |
CHKOUT | Set channel for output |
$FFCC |
CLRCHN | Clear all channels |
$FFCF |
CHRIN | Read character from current input |
$FFD2 |
CHROUT | Output character to current output |
$FFD5 |
LOAD | Load file into memory |
$FFD8 |
SAVE | Save memory to file |
$FFE1 |
STOP | Test for STOP key pressed |
$FFE4 |
GETIN | Get character from keyboard buffer (non-blocking) |
$FFED |
SCREEN | Get screen dimensions (40, 25 in A, X) |
$FFF0 |
PLOT | Set or get cursor position |
Core services
- OPEN/CLOSE:
OPENandCLOSEmanage logical file numbers and devices. - GET/CHRIN: read characters from keyboard, tape, or disk.
- CHROUT: output characters, including control codes for screen formatting.
- LOAD/SAVE: high-level routines to move data between memory and mass storage.
The manual’s case for it
The Programmer’s Reference Guide calls the KERNAL “the operating system of the Commodore 64” and, more precisely, “a standardized JUMP TABLE to the input, output, and memory management routines in the operating system”. Its argument for going through the table rather than calling into ROM directly is stability: “the locations of each routine in ROM may change as the system is upgraded. But the KERNAL jump table will always be changed to match”, so that “if the KERNAL or BASIC is changed, your machine language programs will still work”. The second promise is portability — using the 39 routines makes it “easier to translate your programs from one Commodore computer to another”. The table sits “on the last page of memory, in read-only memory”; the vectors it jumps through live in RAM, set up at power-on and restorable with RESTOR.
Why patch it?
Cartridges and fastloaders replace selected vectors to accelerate disk/tape access or add tooling. Understanding the KERNAL is essential for compatibility and for falling back gracefully when hardware mods are absent.