Strings and Charsets

String Module KERNAL Calls


RegPtr → Pointer to C-String
RegWrd ← 16-bit String Length

Takes a pointer to a NULL-terminated string. Returns a 16-bit length in a RegWrd.


X → ZP Pointer to Source C-String
Y → ZP Pointer to Destination C-String
A → 16-bit Length to Copy

Copies memory of length A, from one memory area to another. The source and destination memory addresses must be stored in two zero page pointers before calling this routine.


A → An ASCII encoded character
A ← A PETSCII encoded conversion

Converts a byte of ASCII to PETSCII.


A → A PETSCII encoded character
A ← An ASCII encoded conversion

Converts a byte of PETSCII to ASCII.


A → A PETSCII encoded character
A ← A Screen Code representation

Converts a PETSCII character to its corresponding Screen Code.


A → A Mixed Case PETSCII Character
A ← A Lower Case PETSCII Character

Converts a PETSCII character of unknown case to lower case.


A → A Mixed Case PETSCII Character
A ← An Upper Case PETSCII Character

Converts a PETSCII character of unknown case to upper case.

Main Character Set

For an in-depth discussion of PETSCII see the programming reference Commodore 64 PETSCII Codes. See also the technical discussion of Screen Codes in the programming reference Commodore 64 Screen Codes.

C64 OS, like a regular C64, is based upon PETSCII not ASCII. I at first found PETSCII to be confusing and I didn't fully appreciate why the machine doesn't just use ASCII. But I have since come to appreciate the elegance of PETSCII, and its intimate relationship to the KERNAL ROM's Screen Editor, and even such low-level features as the C64's ability to blink the text cursor.

Both PETSCII and Screen Codes are divided into 8 blocks of 32 bytes. The upper 4 blocks parallel the lower 4 blocks, such that block 1 and block 5 form a pair, as do blocks 2 and 6, 3 and 7, and 4 and 8.

In PETSCII, blocks 1 and 5 are for control codes. Blocks 2 and 6 are symbolic (numbers and typographic symbols, and graphical symbols respectively.) Blocks 3 and 7 are alphabetic, lower and upper case, respectively. And lastly, blocks 4 and 8 are undefined.

In Screen Codes, all 256 values have a visual representation. The upper 4 blocks are the reverse of the lower 4 blocks. Blocks 1 and 3 are for alphabetic symbols, lower and upper case, respectively. Blocks 2 and 4 are symbolic, (numbers and typographic symbols, and graphical symbols respectively.)

Typable Characters

C64 OS's keyboard driver enables the user to type only those characters found in PETSCII blocks 2, 3 and 7. These are, numbers and typographical symbols, lower case and upper case letters, and some of the PETSCII characters in those blocks are changed to their more standard ASCII equivalents.

C64 OS does not use the C64's Character ROM, but replaces it with a character set in RAM, stored below part of I/O, which the VIC-II can always see, and which is otherwise a complicated area of memory for your C64 program to use.

C64 OS divides the character set into two loadable chunks which are stored in the charsets folder of the system folder. The first chunk is named charset.o, and covers the first 3 blocks of Screen Codes, lower case letters, numbers and typographical symbols, and upper case letters. These are loaded in by the Booter, and their reverse is programmatically generated into blocks 5, 6 and 7. This standard character set replaces several non-standard characters from the C64 Character ROM with more standard ASCII equivalents.

Character ROM C64 OS charset.o
British Pound (£) Backslash (\)
Up Arrow (↑) Caret (^)
Left Arrow (←) Underscore (_)
Graphic Full-Width Dash Backtick (`)
Graphic Left Half Hatch Pipe (|)
Graphic Full Height and Width PLUS Left Brace ({)
Graphic Looks Like a Pipe Right Brace (})
Graphic Full Hatch Tilde (~)

Charset.o is not intended to be modified during the lifetime of C64 OS. It is installed into memory by the Booter, and it is not restored by any other runtime process. If an application corrupts or changes this part of memory, the character set will remain permanently modified, across different applications, until either an application intentionally restores the original charset.o, or until C64 OS is rebooted.

It is NOT recommended to ever change the main character set.

User Interface Character Set

The 4th block of Screen Codes is loaded from a completely different file. The booter installs this block from ui.charset, which is also found in the system folder's charsets folder.

ui.charset is programmatically reversed and copied into block 8. This block is designated for use in creating custom user interface elements. The following characters are defined already by C64 OS.

Note: The assignment of these characters to their block index is tentative. As more of them get defined, I'll likely rearrange them so they are grouped more logically into families.
Block Index Designated Use
0 Undefined
1 Commodore Logo
2 Up Arrow
3 Down Arrow
4 Right Arrow
5 Left Arrow
6 Clock Face / RAM Chip
7 Cycle Button
8 Undefined
9 Undefined
Toolkit Widgets
10 Check Box (Unchecked)
11 Check Box (Checked)
12 Radio Button (Unselected)
13 Radio Button (Selected)
Utility Panel
14 Panel Close Button
15 Panel Title Bar
16 Copyright Symbol
Menu System
17 Check Mark
18 Hamburger Menu
Toolkit Widgets
19 Slider Track
20 Slider Nub
21 Tab/Button Separator
22 Undefined
Customizable 3x3
23 Application Specific
24 Application Specific
25 Application Specific
26 Application Specific
27 Application Specific
28 Application Specific
29 Application Specific
30 Application Specific
31 Application Specific

Typically you want all the characters from the lower 4 blocks to be mirrored, in reverse, in the upper 4 blocks. The magic of this is that any character can be reversed, or the reverse can be reversed back to the original, simply by toggling bit 7 of the byte. The reason each character usually needs to be available in reverse is because you don't know in what context the character will be used on the screen. For example, most text and toolkit widgets that get used on a utility panel will be in reverse. The reason is because the C64's text mode only has one common background color, and so the only way to distinguish the panel from the rest of the screen is to define the rectangle out of reversed characters.

There are some exceptions however. Certain characters are only ever intended to be used in a very narrow context. For example, the Clock Face is used only to show the CPU Busy animation. Therefore, not only is it animated and only occasionally visible, but it also only appears in reverse in the top left corner of the menu bar. Similarly, there is a special RAM Chip icon that is only intended to be used in the status bar, also in reverse, to show the current available ram. Because each of these two characters only has one version, there is no use in taking up two separate characters for their unused reverse representation. Instead, the RAM Chip icon is only in Block 8 at the same index that the Clock Face is at in Block 4.

Application Specific Custom Characters

The last 9 characters of Block 4 are specifically designated as Application Specific. This means that the System's UI will not depend on these characters. And any application that is needs custom UI elements, or to display an icon or other small bitmap, is free to use these characters in any way imaginable.

Additionally, the same 9 characters in Block 8 are also designated as Application Specific. They could be used to reverse the 9 characters from Block 4, but within the context of a specific application their use will be even more prescribed, allowing you to use all 18 independently.

Application Specific characters can also be used by a Utility. However, there is some small risk that the characters will already be in use by the underlying application. If a Utility chooses to overwrite these characters with its own, it must back them up first, then modify them, and restore them when the utility is closed. This could result in some subtle garbling of certain characters in the underlying application, but it might still be worth it. Especially if the Utility will only be used momentairly. While the utility is open it partially obscures the application below, potentially disturbs some of the app's custom characters, but then they spring back to normal when the utility disappears from the screen.

Standard Application Icon

Every Application bundle can have an icon.charset file, which contains a 3x3 character icon. Various other Applications and Utilities may load the icon from an Application bundle to get an iconic representation of the app. Each character consists of 8 bytes of data, so each icon.charset file is 72 bytes.

Missing Icon, icon charset.
Example of a 3x3 charset icon. This one is used by About This App when an app's icon is missing.

C64 OS comes bundled with an "About This App" utility. When the Utility is launched, if it is not provided with a file reference to a specific application bundle, it will by default access the bundle of the currently running application. The App Launcher application allows the user to inspect the About Info and App Icon of any selected application on the desktop. This utility is an example of one which backs up the 9 characters it will use, then loads in the App's custom icon to display it on the About This App panel. It restores the 9 characters from backup when it is quit.

1x2 Number Set

C64 OS also provides a 1x2 Number Set, the digits 0 to 9. Each digit is one character wide by two characters tall, or 8x16 pixels.

Alternative 1x2 Number Set.

These oversize characters cannot just be loaded in and used liberally as you would regular characters. They have to be used within the available space for custom characters. Because each of these 1x2 characters requires 2 character cells, to hold the complete set would require 20 custom characters, but the character set only provides 18.

But it is still possible to use these in many clever ways. For example, the Today utility shows the two-digit date using these characters, simply because it looks nice and adds some visual variation to the text screen. Only two digits are ever showed at a time. The panel's UI therefore can commit just 4 custom characters show the date. To use those four characters the complete set of 20 characters (160 bytes) can be loaded elsewhere in memory, and then only the two digits that need to be displayed are copied into character set memory.

Another example use in C64 OS is the Time utility. This includes a timer and stop watch feature which shows 6 digits at a time, 2 for hours, 2 for minutes, 2 for seconds. These 6 digits, then, require 12 custom characters in the character set.

Use of 12 Custom Characters to show six 1x2 characters simultaneously.

The blue squares show the 12 custom characters necessary to show six double-high digits at the same time in a user interface.

The on-paper design of the 1x2 charset.
The on-paper backup and conversion from digital design to hexadecimal

Next Section: Math and Floating Point

Table of Contents

This document is subject to revision updates.

Last modified: Sep 20, 2022