NEWS, EDITORIALS, REFERENCE

Subscribe to C64OS.com with your favorite RSS Reader
January 11, 2019#77 Reference

C64 KERNAL ROM: Making Sense

Post Archive Icon

The KERNAL is the heart of the Commodore 8-Bit computer family. Although each machine's KERNAL is slightly different, there is also substantial overlap in code and design.

The C64's KERNAL provides a standard jump table with 39 routines from $FF81 and $FFF3. The order of the entries in the jump table is stable, but not particularly logically organized. Most websites and books, including the C64 Programmers Reference Guide, list the routines in alphabetical order, or in the order in which they appear in the jump table. This makes it easy to find the details of any routine, if you already know which routine you want to use, but it can often lead to confusion trying to understand the relationship between the routines. Especially because many of them have similar sounding names, and in some cases similar functionality.

To improve clarity, and facilitate understanding of how the KERNAL should be used, I have grouped the routines into 7 conceptual KERNAL modules, shown in the table below.

C64 OS provides includable assembly headers which define labels for the KERNAL routines in each module. C64 OS itself is an extension of the KERNAL, and relies on the KERNAL for many tasks. For example, C64 OS's File module adds a thin abstraction layer over the KERNAL's file table and logical file numbering system. A C64 OS application that makes use of C64 OS File References can extract the logical file number from the file and use it to make manual KERNAL calls. The relationship of the KERNAL ROM to C64 OS, including a compatibility table, is discussed at the end of this post.

KERNAL Modules

Module Routines Include
File 6 ker_file.s
I/O 8 ker_io.s
IEC 9 ker_iec.s
Memory 6 ker_mem.s
Keyboard 3 ker_key.s
Screen 4 ker_scr.s
Time 3 ker_tim.s

I have never seen the routines grouped as these 7 modules before, but to me, they most logically and thematically fall into these groupings, which helps to understand how to use them.


File (6 Routines)

Among other things, the KERNAL recognizes 6 device types. Two of those device types, the Keyboard and Screen, it implements directly. And it provides implementations of the communications protocols with the other devices which may or may not be connected to the computer.

Each device is referenced by a unique device number, from 0 to 30. Device types are recognized by their fixed address or the address range they fall within. Some devices also support a secondary address, which is used to send it low-level commands.

Devices Table

Device I/O Device Number Secondary Address
Keyboard Input 0
Datasette Both 1 0, 1, 2
RS232 Both 2
Screen Both 3
Printers Output 4, 5 0, 7
Plotters Output 6, 7
Disk Drives Both 8... 30 0, 1, 2... 14, 15

The KERNAL provides a thin abstraction layer to reference devices, and in some cases subdivisions of a device. The abstract entity is called a logical file. Commodore may have been influenced by Unix, which treats everything—including devices—as files. On some devices, such as a Datasette or Disk Drive, logical files can also be associated with actual files, which are named collections of data stored on physical media.

 

The 4 main File routines allow you to open and close logical files by associating them with an underlying physical device, and optionally with a secondary address on that device. Each logical file is assigned a unique file number from 1 to 127. The KERNAL supports opening up to 10 logical files simultaneously.

There are 2 additional File routines that allow you to load and save data to and from Datasette or Disk Drive, to and from memory. Attempting to load or save to or from any other device type results in an Illegal Device Number error.

Routine Description   Routine Description
SETLFS Set logical file number, device number and secondary address   OPEN Open logical file
SETNAM Set filename or command string CLOSE Close logical file
LOAD Load data from disk/tape into memory, or
Verify data on disk/tape with memory
SAVE Save memory to disk/tape

File Routines

SETLFS
DescriptionSet logical file number, device number and secondary address
Jump addr$FFBA
Vector addr
Real code$FE00
Stack use2
EntryA → logical file number
X → device number
Y → secondary address
UseA/X/Y
Return
SETNAM
DescriptionSet filename or command string
Jump addr$FFBD
Vector addr
Real code$FDF9
Stack use0
EntryA → string length
X/Y → pointer to string
UseA/X/Y
Return
LOAD
DescriptionLoad or Verify data
SetupSETLFS, SETNAM
Jump addr$FFD5
Vector addr$0330
Real code$F49E
Stack use0
EntryA → load=0, verify=1
If secondary address = 0,
X/Y → pointer to start address
UseA/X/Y
ReturnX/Y ← pointer to last byte loaded
C ← error=1
If error, A ← error number
OPEN
DescriptionOpen logical file
SetupSETLFS, SETNAM
Jump addr$FFC0
Vector addr$031A
Real code$F34A
Stack use0
Entry
UseA/X/Y
ReturnC ← error=1
If error, A ← error number
CLOSE
DescriptionClose logical file
Jump addr$FFC3
Vector addr$031C
Real code$F291
Stack use0
EntryA → logical file number
UseA/X/Y
Return
SAVE
DescriptionSave memory to disk/tape
SetupSETLFS, SETNAM
Jump addr$FFD8
Vector addr$0332
Real code$F5DD
Stack use0
EntryA → ZP pointer to start address
X/Y → End address
UseA/X/Y
ReturnC ← error=1
If error, A ← error number

I/O (8 Routines)

The KERNAL operates on a general design principle; data is streamed from the system's input channel to the output channel. Opened logical files (see File Module) are assigned to the input and output channels. Attempting to assign an input-only device to the output channel or vice versa results in an error. (See Devices Table)

The default configuration assigns the keyboard as the input device and the screen as the output device. This is why, when a C64 is turned on, typing on the keyboard results in characters appearing on the screen.

The 8 routines in the I/O KERNAL module assign logical files to channels, read and write bytes to and from the channels, check for channel status messages and restore default channel assignments.

Routine Description   Routine Description
CHKIN Assign the current input channel   CHRIN Read byte from input channel
CHKOUT Assign the current output channel CHROUT Write byte to output channel
CLRCHN Restore default I/O channels CLALL Close all files, restore default I/O channels
READST Read I/O status byte IOINIT Initialize CIA & IRQ

Status Values

Hex Bit Serial I/O Tape I/O
$80 7 Device Not Present
$40 6 EOI status End of file
$20 5 Checksum error
$10 4 Verify error Unrecoverable read error
$08 3 Long block
$04 2 Short block
$02 1 Read timeout
$01 0 Write timeout

I/O Routines

CHKIN
DescriptionAssign the current input channel
SetupOPEN
Jump addr$FFC6
Vector addr$031E
Real code$F20E
Stack use0
EntryX → logical file number
Use
Return
CHKOUT
DescriptionAssign the current output channel
SetupOPEN
Jump addr$FFC9
Vector addr$0320
Real code$F250
Stack use0
EntryX → logical file number
Use
Return
CLRCHN
DescriptionRestore default I/O channels
Jump addr$FFCC
Vector addr$0322
Real code$F333
Stack use9
Entry
UseA/X
Return
READST
DescriptionRead I/O status byte
Jump addr$FFB7
Vector addr
Real code$FE07
Stack use2
Entry
UseA
ReturnA ← status byte
CHRIN
DescriptionRead byte from input channel
SetupCHKIN (optional)
Jump addr$FFCF
Vector addr$0324
Real code$F147
Stack use0
Entry
UseA/Y
ReturnA ← byte read
CHROUT
DescriptionWrite byte to output channel
SetupCHKOUT (optional)
Jump addr$FFD2
Vector addr$0326
Real code$F1CA
Stack use0
EntryA → byte to write
Use
ReturnC ← error=1
ST ← error number
CLALL
DescriptionClose all files, restore default I/O channels
Jump addr$FFE7
Vector addr$032C
Real code$F32F
Stack use11
Entry
UseA/X
Return
IOINIT
DescriptionInitialize CIA & IRQ
Jump addr$FF84
Vector addr
Real code$FDA3
Stack use0
Entry
UseA/X/Y
Return

IEC (9 Routines)

A major part of the KERNAL is dedicated to IEC serial bus communications. The IEC bus is a variant of IEEE-488, used by Commodore, which you can read about here. The bus allows multiple devices to be chained together to one C64, in a master/slave arrangement. The C64 is the master, which tells individual slave devices when to talk and when to listen.

All device numbers from 4 to 30 are assigned to the IEC serial bus, although this can be overridden by use of the vectors specified for routines in the File and I/O KERNAL modules.

Each device must have its unique device number manually configured. In addition to the device number, the IEC protocol can send a secondary address and command string, the meaning and use of which are device specific. The 9 IEC KERNAL routines implement this protocol by timed manipulation of CIA 2. It is rarely necessary to use any of these calls directly, as they are abstracted and called automatically by higher-level routines in the File and I/O KERNAL modules.

For maximum device compatibility, direct use of these routines should be avoided, unless the device type is detected and determined to actually reside on the physical IEC bus.

Routine Description   Routine Description
TALK Command an IEC device to talk   LISTEN Command an IEC device to listen
TALKSA Specify the talking device's secondary address SECOND Specify the listening device's secondary address
UNTLK Command IEC devices to stop talking UNLSN Command IEC devices to stop listening
ACPTR Read one byte from talking device CIOUT Write one byte to listening device
SETTMO Toggle IEC BUS timeout      

IEC Routines

TALK
DescriptionCommand an IEC device to talk
Jump addr$FFB4
Vector addr
Real code$ED09
Stack use0
EntryA → device number
UseA
Return
TALKSA
DescriptionSend secondary address after talk
SetupTALK
Jump addr$FF96
Vector addr
Real code$EDC7
Stack use0
EntryA → secondary address
UseA
Return
UNTLK
DescriptionCommand IEC devices to stop talking
Jump addr$FFAB
Vector addr
Real code$EDEF
Stack use0
Entry
UseA
Return
ACPTR
DescriptionRead one byte from talking device
SetupTALKSA
Jump addr$FFA5
Vector addr
Real code$EE13
Stack use13
Entry
UseA
ReturnA ← byte
C ← error=1
ST ← error number
LISTEN
DescriptionCommand an IEC device to listen
Jump addr$FFB1
Vector addr
Real code$ED0C
Stack use0
EntryA → device number
UseA
Return
SECOND
DescriptionSpecify the listening device's secondary address
SetupLISTEN
Jump addr$FF93
Vector addr
Real code$EDB9
Stack use0
EntryA → secondary address
UseA
Return
UNLSN
DescriptionCommand IEC devices to stop listening
Jump addr$FFAE
Vector addr
Real code$EDFE
Stack use0
Entry
UseA
Return
CIOUT
DescriptionWrite one byte to listening device
SetupSECOND
Jump addr$FFA8
Vector addr
Real code$EDDD
Stack use0
EntryA → byte
Use
ReturnC ← error=1
ST ← error number
SETTMO
DescriptionToggle IEC BUS timeout
Jump addr$FFA2
Vector addr
Real code$FE21
Stack use0
EntryA bit7 → enable=0
A bit7 → disable=1
UseA
ReturnA

MEMORY (6 Routines)

The memory map differs between the various Commodore 8-Bit computers. They have different amounts of ram and their I/O chips reside at different places. Additionally, BASIC is by default configured to use as much free memory as is available.

These 6 Memory routines allow you to reliably locate where the I/O chips are mapped, test and determine the quantity of RAM available, configure how much and in what range of that RAM BASIC should use. It also helps you to configure the KERNAL's ram vectors, by backing them up, replacing them with a custom table, and restoring them to defaults.

Routine Description   Routine Description
MEMTOP Read/set top of BASIC memory   VECTOR Read/set I/O vectors
MEMBOT Read/set bottom of BASIC memory RESTOR Restore default I/O vectors
RAMTAS RAM test and search memory end IOBASE Read the base address of I/O chips

Memory Routines

MEMTOP
DescriptionRead/set top of BASIC memory
Jump addr$FF99
Vector addr
Real code$FE25
Stack use2
EntryC → read memtop=1
C → set memtop=0
If set memtop
X/Y → pointer to memory top
UseX/Y
ReturnIf read memtop
X/Y ← pointer to memory top
MEMBOT
DescriptionRead/set bottom of BASIC memory
Jump addr$FF9C
Vector addr
Real code$FE34
Stack use0
EntryC → read membot=1
C → set membot=0
If set membot
X/Y → pointer to memory bottom
UseX/Y
ReturnIf read membot
X/Y ← pointer to memory bottom
RAMTAS
DescriptionRAM test and search memory end
Jump addr$FF87
Vector addr
Real code$FD50
Stack use0
Entry
UseA/X/Y
ReturnSets pointer to tape buffer
Sets the screen memory page
Sets pointers to start and end of memory
VECTOR
DescriptionRead/set I/O vectors
Jump addr$FF8D
Vector addr
Real code$FD1A
Stack use2
EntryC → memory table to vectors=0
C → vectors to memory table=1
X/Y → pointer to memory table
UseA/Y
Return
RESTOR
DescriptionRestore default I/O vectors
Jump addr$FF8A
Vector addr
Real code$FD15
Stack use2
Entry
Use
ReturnVector table is restored from ROM
IOBASE
DescriptionRead the base address of I/O chips
Jump addr$FFF3
Vector addr
Real code$E500
Stack use2
Entry
UseX/Y
ReturnX/Y ← Pointer to CIA 1 ($DC00)

KEYBOARD (3 Routines)

A C64 has a built-in keyboard, however it is just a matrix of switches connected to Ports A and B of CIA 1. (See How the C64 Keyboard Works.) The KERNAL implements all of the software routines necessary to make the keyboard a device. The matrix scanning routine is part of the KERNAL's IRQ interrupt service routine, which converts key presses into PETSCII characters and stores them in the 10-byte keyboard buffer ($0277–$0280).

RS-232 shares some properties in common with the keyboard. Namely, there is no custom RS-232 hardware, there is only CIA 2 which is connected to the user port. All RS-232 behavior is implemented by software routines provided by the KERNAL and the NMI interrupt service routine. Similarly to the keyboard buffer, the KERNAL puts incoming RS-232 bytes into a buffer in memory. The location of the RS-232 buffer, though, can be configured.

There are two routines for reading a byte from the input channel, GETIN and CHRIN. These routines have different behavior and different error conditions depending on the input device. GETIN has unique behavior only for the keyboard (Device 0) and RS-232 (Device 2). For all other devices, GETIN is merely an alias to CHRIN. Therefore, I have chosen to categorize GETIN in the keyboard KERNAL module, even though it can also be used with RS-232, or even with the other devices.

When GETIN is used with the keyboard as the input device, it returns the next character waiting in the keyboard buffer. If the buffer is empty, it returns 0 (ASCII NULL). It works the same way for RS-232, returning the next byte in the RS-232 buffer, or 0 if the buffer is empty. Using CHRIN with the keyboard enters a special routine that is used primarily by BASIC for getting data for INPUT statements. When BASIC calls CHRIN to input from the keyboard, the keyboard buffer is continuously output to the screen until return is pressed. This allows the user to populate an entire line buffer (80 characters) before the data is processed.

Routine Description   Routine Description
GETIN Read a byte from the input channel   SCNKEY Scan the keyboard matrix
STOP Check the stop key    

Keyboard Routines

GETIN
DescriptionRead a byte from the input channel
Jump addr$FFE4
Vector addr$032A
Real code$F13E
Stack use0
Entry
UseA/X/Y
ReturnIf Keyboard or RS-232
A ← next byte in buffer or 0 if buffer is empty.
If any other device, see CHRIN.
STOP
DescriptionCheck the stop key
Jump addr$FFE1
Vector addr$0328
Real code$F6ED
Stack use0
Entry
UseA (X if STOP is used)
ReturnZ ← stop pressed=1
Z ← stop not pressed=0
Closes open channels by calling CLRCHN.
SCNKEY
DescriptionScan the keyboard matrix
Jump addr$FF9F
Vector addr
Real code$EA87
Stack use0
Entry
UseA/X/Y
Return
* SCNKEY is called automatically by the default IRQ interrupt service routine. However if you replace the IRQ ISR but want to continue getting keyboard input, call this routine as part of a new interrupt service routine. The keyboard buffer will continue to be populated as the user types.

SCREEN (4 Routines)

Just as the keyboard is transformed into a device by routines in the KERNAL, so is the screen. The VIC-II chip, when in character mode, merely renders whatever screencodes are in the 1000 bytes of screen memory, with the 1000 bytes of color data in color memory.

A non-trivial amount of code in the KERNAL is devoted to implementing the screen editor. The screen editor consists of a table of 80-column logical lines which are drawn and moved through screen memory. Positioning of the cursor, inserting new characters in a line, manipulating color memory, PETSCII control codes, and insertion, quotation and reverse modes, are all part of the screen editor.

The screen editor maintains a positional cursor, which allows the screen to be abstracted into a generic I/O device. Reading a byte from the screen finds the screencode at the position of the cursor, and converts and returns its PETSCII equivalent, then advances the cursor. Writing to the screen as a device works similarly. Writing a PETSCII character converts the character to a screencode, and will reverse it if reverse mode is on, and then outputs the character to screen memory at the position of the cursor, then advances the cursor.

The 4 SCREEN routines are used to initialize the screen, reads its dimensions (which vary depending on the Commodore 8-Bit computer), read and move the cursor, and enable or disable the messages (two different types) that the KERNAL prints to the screen as user feedback.

Routine Description   Routine Description
CINT Initialize the screen   PLOT Read/set cursor position
SCREEN Read screen dimensions in cols/rows SETMSG Configure output of KERNAL messages

Screen Routines

CINT
DescriptionInitialize the screen
Jump addr$FF81
Vector addr
Real code$FF5B
Stack use0
Entry
UseA/X/Y
ReturnInitializes VIC-II registers
Clears the screen
Initializes screen line table
Initializes main interrupt timer
SCREEN
DescriptionRead screen dimensions in cols/rows
Jump addr$FFED
Vector addr
Real code$E505
Stack use2
Entry
UseX/Y
ReturnX ← Columns (40)
Y ← Rows (25)
PLOT
DescriptionRead/set cursor position
Jump addr$FFF0
Vector addr
Real code$E50A
Stack use2
EntryC → Set=0
C → Get=1
X → Row
Y → Column
UseX/Y
ReturnX ← Row
Y ← Column
SETMSG
DescriptionConfigure output of KERNAL messages
Jump addr$FF90
Vector addr
Real code$FE18
Stack use0
EntryA → bit7=1 error messages on
A → bit6=1 control messages on
UseA
Return

TIME (3 Routines)

The KERNAL keeps track of time using a 3-byte Jiffy Clock. A Jiffy is a short unit of time, in computing normally the length of time between two ticks of the system timer interrupt, or in electronics the cycle period of the AC mains. On an NTSC C64 (not sure about PAL), CIA 1 is configured to produce an interrupt every 1/60th of a second, which corresponds closely with the screen refresh rate and the cycle period of North American AC power. On every interrupt, the Jiffy Clock is ticked up. When it reaches the equivalent of 24 hours worth of jiffies, it is reset to zero.

There is a bug in the timer which, even if left to run under perfect conditions, would lose one Jiffy (1/60th of a second) per 24 hour period. In practice, this is completely irrelevant because the Jiffy Clock stops ticking entirely any time the IRQ is temporarily masked. Despite this general unreliability as a realtime clock, the Jiffy Clock is useful in a variety of small ways.

The 3 TIME routines allow you to read and set the Jiffy Clock. And, if you reimplement the IRQ interrupt service routine, calling UDTIM in your ISR will tick the Jiffy Clock. The STOP routine, in the Keyboard KERNAL module, does not scan the keyboard. It checks a stop key flag. This flag is set by the UDTIM routine. If UDTIM is not being regularly called, therefore, STOP will not work as expected.

Routine Description   Routine Description
SETTIM Set the Jiffy Clock   RDTIM Read the Jiffy Clock
UDTIM Tick the Jiffy Clock up    

Time Routines

SETTIM
DescriptionSet the Jiffy Clock
Jump addr$FFDB
Vector addr
Real code$F6E4
Stack use2
EntryA → Most Significant Byte
X → Middle Significant Byte
Y → Least Significant Byte
UseA/X/Y
Return
UDTIM
DescriptionTick the Jiffy Clock up
Jump addr$FFEA
Vector addr
Real code$F69B
Stack use0
Entry
UseA/X
Return
RDTIM
DescriptionRead the Jiffy Clock
Jump addr$FFDE
Vector addr
Real code$F6DD
Stack use2
Entry
UseA/X/Y
Return * A ← Least Significant Byte
X ← Middle Significant Byte
Y ← Most Significant Byte

* NOTE: The Jiffy Clock is stored in three zero page addresses: $A0, $A1 and $A2. RDTIM loads the accumulator from $A2, the X register from $A1, and the Y register from $A0. Usually multi-byte numbers are stored little endian on the C64. However, the Jiffy Clock is stored big endian.

The C64 Programmer's Reference Guide erroneously states that RDTIM puts the most significant byte in the accumulator.


The KERNAL and C64 OS

The C64's KERNAL ROM is used by C64 OS. The default state expects the KERNAL to be patched in. However you are free to patch it out at any time, and are not required mask IRQs when you do so. In fact, it would detrimental to mask IRQs unless you absolutely have to. C64 OS will automatically patch the KERNAL back in during the IRQ service routine, and restore its state upon returning to your code. However, if you patch the KERNAL out, you are required to patch it back in before returning to or calling system code, as the rest of the system expects it to be patched in.

Despite using the KERNAL, parts of it are irrelevant under C64 OS, and parts of it have been superseded by newer implementations in the C64 OS KERNAL.

FILE

The FILE module is used pretty much as normal. The C64 OS File module provides a thin wrapper around most of these calls. When using LOAD, you have to be careful that the data loaded in will not overwrite memory that is already allocated. If you do use LOAD carefully, you must also use the C64 OS Memory routine PGMARK to mark as allocated the pages of memory that were loaded into.

I/O

The I/O module is used almost the same in C64 OS. It is unsafe to use CLALL, however, as you cannot be sure that a Utility, or the System itself, does not have a file open. If you call CLALL, all files will be closed but their corresponding C64 OS file references will be left marked as open, with invalid Logical File Numbers assigned to them.

You should also never call IOINIT, as this would change the configuration of the CIA and IRQ handler and likely crash the system. C64 OS provides a clean way to quit back to BASIC.

IEC

The IEC routines interact explicitly with the IEC bus. For maximum compatibility with other drive types, these routines should be avoided. For example, the IDE64 programming documentation states that you must not use any of these routines. For C64 OS, I would follow that practice. C64 OS routines never call these routines, prefering to call FILE and I/O routines instead.

There is, however, a way to use these routines safely. C64 OS maintains a detected drives table, containing device numbers corresponding with detected physical drive types (1541, 1571, 1581, CMD HD, CMD RamLink, CMD FD, IDE64, SD2IEC, etc.) If you consult that table, and determine that the drive is on the IEC bus, it's reasonably safe and compatible to use these IEC specific routines.

MEMORY

This part of the KERNAL is more or less irrelevant. MEMTOP and MEMBOT are specifically for configuring what BASIC can use. RAMTAS is called as part of starting up and resetting a C64. IOBASE only made sense for maintaining BASIC program compatibility between different Commodore 8-Bit computers. IOBASE on a C64 hasn't changed in 35 years, and isn't going to change any time soon. RESTOR should not be used, as C64 OS overrides some of the KERNAL's vectors. Restoring these to their defaults will cause problems. If you are careful and know what you're doing, you can use VECTOR, although it is recommended to use VECTOR to backup the current VECTOR table first, before using it to replace them with your own.

The KERNAL ROM's memory module is mostly irrelevant, not because memory management has become less important, but because C64 OS provides a Memory module that is significantly more sophisticated, which entirely supersedes these KERNAL routines.

KEYBOARD

The KERNAL ROM has only very basic support for input devices. It does not provide input drivers for anything on the two built-in controller ports. It does not provide input for joysticks or mice, and its keyboard input system is limited only to populating the keyboard buffer with PETSCII values. If two keyboard combinations resolve to the same PETSCII value (Control M and RETURN both resolve to $0D), there is no way to distinguish the two.

C64 OS completely replaces SCNKEY with a new keyboard matrix scanner, and divides the results into two types of events: Key Commands, and Printable Key Events. Printable Key Events are buffered in the same 10-key keyboard buffer used by the KERNAL, and can be retrieved with GETIN. However, this call removes the character from the buffer. C64 OS provides routines to allow you to read the current event in the buffer, without removing it. This is used to allow the event to propagate through different levels of the OS, before being removed at the end of the current iteration of the main event loop. C64 OS also provides mouse input, and will likely provide joystick input drivers as well.

STOP can be used as normal. If it interrupts one of C64 OS's FREAD or FWRITE routines, a C64 OS exception will be thrown.

SCREEN

The KERNAL's screen editor is not used by C64 OS. If the Screen device is set as the current input or output device, it will be used as a pipe to read or write data from or to a Toolkit widget that is in keyboard focus. Selecting the Screen as the output device, while a Toolkit text area is in focus, and then repeatedly calling CHROUT will insert characters into the text area.

CINT should never be used. SCREEN can be used, although it is not terribly useful. C64 OS provides SCREEN_COLS and SCREEN_ROWS constants. PLOT should never be used, as it manipulates screen editor variables in workspace memory that are used for other purposes by C64 OS. SETMSG is used by the C64 OS Booter to disable KERNAL messages, and it should not be used to turn messages back on.

TIME

C64 OS uses the same Jiffy Clock as the KERNAL ROM. Therefore, it is safe to call RDTIM and SETTIM. However, C64 OS calls UDTIM inside a larger context, which includes updating other variables. You should avoid calling UDTIM manually.

C64 OS also provides a Timers module. You can read more here about how timers work in C64 OS. The Timers module mostly obviates the need to manually use the Jiffy Clock for common timer functions.


KERNAL Compatibility in C64 OS


FILE Module
Routine Compatible Deprecated Do Not Use
SETLFS    
SETNAM    
OPEN    
CLOSE    
LOAD    
SAVE    
I/O Module
Routine Compatible Deprecated Do Not Use
CHKIN    
CHKOUT    
CHRIN    
CHROUT    
CLRCHN    
READST    
CLALL    
IOINIT    
IEC Module
Routine Compatible Deprecated Do Not Use
TALK    
TALKSA    
UNTLK    
ACPTR    
LISTEN    
SECOND    
UNLSN    
CIOUT    
SETTMO    
MEMORY Module
Routine Compatible Deprecated Do Not Use
MEMTOP    
MEMBOT    
RAMTAS    
VECTOR    
RESTOR    
IOBASE    
KEYBOARD Module
Routine Compatible Deprecated Do Not Use
GETIN    
STOP    
SCNKEY    
SCREEN Module
Routine Compatible Deprecated Do Not Use
CINT    
SCREEN    
PLOT    
SETMSG    
TIME Module
Routine Compatible Deprecated Do Not Use
SETTIM    
RDTIM    
UDTIM    

Statistics

  • Compatible: 16 of 39 (41%)
  • Deprecated: 12 of 39 (31%)
  • Do Not Use: 11 of 39 (28%)

Do you like what you see?

You've just read one of my high-quality, long-form, weblog posts, for free! First, thank you for your interest, it makes producing this content feel worthwhile. I love to hear your input and feedback in the forums below. And I do my best to answer every question.

I'm creating C64 OS and documenting my progress along the way, to give something to you and contribute to the Commodore community. Please consider purchasing one of the items I am currently offering or making a small donation, to help me continue to bring you updates, in-depth technical discussions and programming reference. Your generous support is greatly appreciated.

Greg Naçu — C64OS.com

Want to support my hard work? Here's how!