An Afterlife User's Guide to the C64
Introduction: Part I
The Commodore 64 shipped with an official User's Guide, and many aftermarket books have been written about how to use and get the most out of your C64. What else is there to write on this subject?
In the year 2021, not only is the Commodore 64 forty years old, but the modern computing environments we're used to have made the C64 seem even more foreign than it would have seemed to computer enthusiasts back in the 80s. In my discussions online, at trade shows and in private correspondence, I have learned that although many people are still interested in and passionate about their C64, many lack a deep or comfortable familiarity with actually using one.
The goal of this document is not to be a comprehensive guide to everything your C64 can do. Rather, it is to reorient a modern computer user to the most important ways that the C64 works. It gives simple tips and tricks to help you understand what your C64 is doing, and how you can approach it in order to accomplish common tasks.
To use your C64 effectively, take this wisdom to heart:
You must unlearn what you have learned. Yoda, The Empire Strikes Back, A long time ago.
C64 Breadbin left, C64c right
Part I: The C64
What is the Commodore 64?
The answer to this seemingly obvious question—it's a computer—gets muddled by the complexity and baggage that the word "computer" has taken on over the decades. Today many things are computers: a phone, a watch, a laptop, a PC, an iPad, a microwave oven, a thermostat, a WiFi router, a TV, a security camera, a stereo speaker set, an SD Card.
In the early 80s a computer in your home was a novelty. Your Commodore 64 was likely the only computing device in your entire house. It was an open canvas of unlimited potential. And that is how it should be seen today. Don't compare your C64 to modern computers, instead try to see it for what it is. Your Commodore 64 is a computer, but it's more open and more raw than any other computer of the last 30 years. Spend enough time with it, acclimatize to its pace, and you will soon catch yourself marveling at how fast it is. And then you'll double take and wonder how you ever got to that feeling.
One of the great pleasures of the Commodore 64 is how simple it is. Give it some time, have confidence in yourself, and you will be able to learn about every aspect of your C64 in a deep and satisfying way.
Setup Real Hardware
If you're an emulator guy, that's fine. But if this guide is for you, it's time to pull the real hardware out of the closet and set it up. Many people contend that they don't have room for real hardware. This is the wrong attitude. It's like saying you don't have room to exercise, or you don't have time to eat a healthy diet. Before anything, you need to commit to the C64 as a first class citizen. When you do that, you will make the space for real hardware.
The truth is, a C64 doesn't take up a lot of space. A large CRT display takes up some appreciable amount of space, and I do recommend that you use a CRT display. But a C64 can still be connected to most modern TVs with a minimal investment, such as a C64-to-S-Video cable. If your TV doesn't support S-Video, you can get a relatively inexpensive S-Video-to-VGA or S-Video-to-HDMI converter box.
A montage of real Commodore 64 setups (with original Commodore monitors)
At its minimum a Commodore 64 consists of a rugged keyboard, that's plugged into the wall, with a single cable running to your TV. You probably have room to prop the C64 on its end beside the TV when you're not using it. So stop making excuses that you don't have space, and make the effort to find space. Once you have a real physical Commodore 64, out of its box and in plain view, it will become much easier to sit down and spend time with it. And that is the only way that you will rekindle a relationship with this special machine.
There are many reasons why using real hardware—even a modern reproduction or reimplementation, in FPGA for instance—will improve your relationship with your C64. An emulated Commodore 64 will always be a second class citizen to the host computer. And frankly, it will always look a bit silly, with its 16 colors and low resolution constrained to a tiny window surrounded by a more modern machine. What you can do with the computer outside that window will forever draw your attention away from your C64. Imagine trying to have a relationship with your wife, by only ever relaying messages to her via a 20-year-old bikini model. This is not a ticket to a healthy relationship with someone you love.
With the relationship advice now behind us, let's get into some details.
A Brief Overview of the Ports
The Commodore 64 is what came to be known as a wedge computer design. The mainboard is inside the same case that houses the keyboard. The various ports are arranged around the sides and back of the case, connecting to different places on the mainboard. The closest equivalent to this in modern computers is the bottom half of a laptop, without the top half that has the display.
The Right Side
On the right side of the computer, from front to back, you find:
- Control Port 1
- Control Port 2
- Power Switch
- Power Port
A Breadbin C64, Right Side
Control Ports
The control ports accept standard joysticks with DB9 female connectors. These are compatible with Atari and Amiga controllers, although not with Sega Genesis controllers. To safely use a Sega Genesis controller on a C64 it is necessary to modify the controller or to use an adapter.
For two-player games, joysticks can be plugged into both control ports. However, for one-player games, it is much more common that control port 2 is used. This seems counterintuitive, why wouldn't a one-player game use control port 1? Some do, although most don't. A mouse, on the other hand, can technically be programmed for control port 2, but in practice almost all software uses it on control port 1. This unofficial standard is quite convenient, as a mouse can be left in port 1 and a joystick in port 2, and only for the rare game is it necessary to change this arrangement.
Power PortThe power port is a round, 7-pin DIN connnector which provides ground, 5VDC and 9VAC. Original brown, beige or black brick and wedge power supplies can no longer be safely used to power your C64. Especially if you are just pulling your C64 out of the closet after many years, you need to take one of two measures to ensure the good and continued health of your computer.
- Build or buy a new power supply, or
- Build or buy an overvoltage protector
Both of these options are available for purchase in a number of forms. Check the Commodore 8-Bit Buyer's Guide to see what is available. Most of the items can be found either on Ebay or from one of the vendors listed in the vendors section.
A new power supply is more expensive, but is the superior option. An overvoltage protector is less expensive, and plugs between the C64 and the original power supply. Original power supplies are prone to failure that produces excessive voltage that damages the Commodore 64. An overvoltage protector is a kill switch that prevents excessive voltage from reaching the vulnerable components in the computer.
The Back Side
If you turn the Commodore 64 around to look at the back side, you find the following ports from left to right:
- Expansion Port
- Channel Selector
- RF Audio/Video Jack
- Video Port
- IEC Serial Port
- Cassette Port
- User Port
A C64c, Back Side
Expansion Port
The Expansion Port gives complete access to the CPU's main buses, plus a number of other control and signaling lines. This port can be used for a variety of expansions from a simple plugin game cartridge, to a SuperCPU accelerator.
It is not uncommon to add a port expander to the expansion port, allowing for 3 or 4 expansion devices to be connected to it at the same time. Extra hardware that is powered from the computer increases the load on the power supply. For proper behavior a heavy duty power supply is recommended for anything more than a single cartridge.
Channel selector, RF Audio/VideoThe channel selector and RF audio/video output jack are rarely used today. They can be used to connect the C64 to a television's RF or antenna connector. However, this provides the lowest quality of video output. It is not uncommon for people to remove the RF modulator from their C64 and replace it with a higher quality modulator that improves not only the quality of RF output but the output from the video port as well.
Video PortThe Video port requires a C64 video cable. If you don't have one of these, there are many still commercially available. This port carries composite video output which is a step up in quality from RF output. It also carries S-Video (chroma and luma on separate lines) for the best quality output. C64 video cables are available today that terminate with a standard S-Video mini DIN connector. More traditional cables have these as two RCA jacks and require an extra adapter to connect them to a standard S-Video port. There is also a wide variety of adapters to convert S-Video to VGA, HDMI, SCART, etc., for TVs and monitors with those connectors.
A stock C64 also outputs mono audio on the video port. It is not uncommon to update a C64 for stereo output, and there is a pin on the video port that is reserved for this if an internal stereo modification is made.
IEC Serial PortThe IEC Serial Port is for connecting storage devices and printers (or printer adapters.) The IEC serial bus supports multiple devices which can be daisy chained one to the next. This port can be used to connect 5.25" floppy disk drives, 3.5" floppy disk drives, hard drives, SD Card drives and more. Storage is discussed in Part II of this guide.
Cassette PortThe Cassette Port is used primarily for connecting a tape drive, also called a datasette. Although these drives are more popular in Britain and parts of Europe than they are in North America, commercial releases of games are often still made to cassette. The cassette port is sometimes also used as a source of 5V DC power for other devices.
User PortThe User Port is a versatile, programmable, multi-purpose port. Some C64 users who use the machine exclusively for games have never used this port and wonder why it even exists. But without it the C64 would be greatly impoverished as a general purpose computer. The user port can be used for RS-232 communications, out of the box. It can also be used as a parallel port much like the parallel port found on the PC or Amiga. And the user port can also be programmed to implement other buses, such as I2C. Many expansion devices exist for the user port, from digital audio output and digital audio sampling, to dial-up modems and WiFi modems, to parallel printer adapters, 4-player joystick adapters and more.
The Commodore 64 Keyboard
There are several differences between the C64's keyboard and a modern keyboard that you have to get used to, but you will get used to them; the human brain is remarkably adaptable. If you spend time using your C64, the layout of its keyboard soon becomes second nature as it works its way into muscle memory.
A disadvantage to using an emulator is that the keyboard of a Mac or PC is just not the same as the keyboard on a genuine C64. Interacting with a C64 using an actual C64's keyboard makes the experience much more natural and authentic.
An Aldi C64
The Cursor Keys
One of the most jarring differences about a C64's keyboard is its cursor keys. Immediately below the return key are found three keys in a row:
(Right)Shift, Vertical Cursor, Horizontal Cursor.
Just like with many keys that show two symbols on the top surface, one above the other, pushing the key on its own results in the lower symbol, but combining the key with shift gives you the upper symbol.
On each cursor key are two arrows. The vertical key has up and down arrows, the horizontal key has left and right arrows. The down arrow and the right arrow occupy the lower half of the keys, while the up and left arrows occupy the upper half of those keys. Naturally then, pushing the cursor keys on their own moves the cursor down and right. You can think of this as a diagonal leading away from the home position, the upper left corner of the screen.
The fingers of your right hand should naturally rest on all three keys: index finger on the shift key, middle finger on the vertical cursor, ring finger on the horizontal cursor key. Holding shift while pushing the keys selects the upper symbol on each key, up and left, respectively. If you think of the unmodified keys as moving you away from the home position, then you can think of the shifted cursor keys as moving you diagonally towards the home position.
Have patience with yourself, and (without looking at them) practice using the cursor keys whenever you can. You're going to use them a lot, if they feel frustrating or foreign you won't have an enjoyable experience. But as you get used to them, the arrangement melts into the background of your awareness, and you will begin to use them intuitively and reflexively. Sometimes, after I've been using my C64 exclusively for several days, when I first sit down at my work computer, I accidentally try to use the C64's cursor keys on a Mac keyboard. It doesn't take much to mentally switch back and forth, but if you can make that mistake at all it means you have truly nativized to the C64's cursor keys. When this happens, you should recognize the moment and take a bit of pride in the accomplishment.
The RUN/STOP Key
Many people and even publications have referred to this key with the single word "runstop." Perhaps because it is beside the "shift lock" key, whose words appear on two lines but which are always said together.
This is a misreading. The Stop key's label parallels the Home and Delete keys. All three of these keys execute their bottom function when used unmodified, and their secondary, top function when used with the Shift key. Thus, Delete becomes Insert if used with Shift, Home becomes Clear, and when used with Shift, Stop becomes Run. This behavior is just like the cursor keys, too. Down becomes Up and Right becomes Left.
Stop is roughly the C64's version of "escape." It is used to stop a process that is underway. It can be used to stop a BASIC program that is running (under most circumstances), but it can also be used to stop other processes. For example, if you list a BASIC program, push Stop to stop it from listing all the way to the end. If a program is being loaded (in the usual way) push Stop to stop it from continuing to load. Not all, of course, but many other programs use the Stop key as a standard way to interrupt and stop a long running process.
The run function of the key is much less common. On a stock C64 it loads and runs the first program found on a cassette tape. Dating from the days and places where tape drives were very common, this made it exceedingly easy to get started. Just hold the Shift key and push the Run/Stop key, then follow the on-screen instructions. Popular KERNAL replacements, like JiffyDOS, update the default behavior of the run function to be more useful to users of disk drives and harddrives. JiffyDOS is discussed in Part II of this guide.
The RESTORE Key
This mysterious key is one you won't find on most other computers. There are 66 keys on the keyboard in total, composed of 64 keys arranged in a logical 8-by-8 matrix. But this leaves 2 keys unaccounted for. The first is the Shift Lock key, which is a mechanically latching key that, as far as the computer is concerned, is identical to holding down the left Shift key. That leaves just one key left over: The Restore key.
The Restore key is not part of the 8-by-8 key matrix, but instead connects the CPU's NMI line to ground. Pushing Restore forces the CPU to run a special interrupt subroutine. Unfortunately, this can lead to crashing or interfering with the proper functioning of some software. If you don't need to use restore, it's best to leave it alone.
Under normal circumstances, the NMI service routine checks to see if the Stop key is being held down. If it is, the computer undergoes a warm restart. The BASIC program is ended, open files are closed, screen colors are restored, any sounds are silenced, the screen is cleared and you are returned to a prompt. This doesn't always work, though, because it is ultimately under software control. A program could intentionally or even accidentally change the behavior of the NMI. Nonetheless, if you get stuck, it's often worth a try to hold the Stop key and tap the Restore key a few times.
The Commodore Key
The Commodore key is found at the bottom left of the keyboard. This is a general modifier key, it is used in a multitude of ways depending on the program you're using. You can think of it as the rough equivalent of one of the Amiga keys on an Amiga, or the Command key on a Mac. From the command prompt, the Commodore key has another unique function that we'll discuss below.
The Space Key
Although this is an unofficial standard, it is common enough that it bears mentioning. There are many screens you will find yourself at, in games, or demos, or program introduction screens where something is going on, some music or graphics, or some text to read, but it isn't progressing to the next step automatically, and has no other indication about what you are supposed to do. 9 times out of 10, or perhaps more often than that, you press the space bar to proceed.
Or in the parlance of hip demo coders, you "slap the long one." This is surprisingly unintuitive to users who are new to the C64 (or returning after a long time away,) but it is second nature to comfortable C64 users, because it is very common across a wide range of software. It also makes a certain amount of sense. It is the largest key and protrudes below all the other keys, and is therefore particularly easy to push.
Other Miscellaneous Keyboard Features
We won't go through every key, one at a time, although if you are interested in a more detailed breakdown of what every key and every key combination does on a freshly booted Commodore 64, I recommend the post, Key Map to Screen Editor.
There is no tab key. Where you would typically find tab, you instead find the Control key. There are only 4 function keys, which combine with Shift to produce 8 programmable functions. On a stock C64, the function keys do not have any default behavior. They are however widely used in software that you will encounter. The function keys on a Commodore 64 are much more commonly used and with a wider range of purposes than they are on a modern PC or Mac. Also, due to their vertical orientation and because the C64 lacks page up and page down keys, the function keys are often employed to scroll content.
Some special symbols are not where you would expect them. The double quote mark is found above the 2. And the @ sign typically found above the 2 is on its own key. The parentheses are found above the 8 and 9, rather than the the 9 and 0 keys. And the asterisk which is typically found above the 8 is on its own key beside the @ key. The apostrophe is above the 7.
The plus and minus keys are in reverse order. The equals is on its own key. And there are numerous other subtle differences.
These subtle differences taken together make using a C64 via a real C64 keyboard much more natural than using a C64 via a PC or Mac keyboard, such as in an emulator. The keycaps on a PC keyboard simply don't match up to the keycaps on a C64's keyboard. Emulators generally take one of two approaches to deal with this. Either they map the symbols to the symbols, which rearranges the positions of the keys and can lead to inexplicable keyboard controls in some C64 software, or they try to produce a spatial mapping.
With the spatial mapping, you are often left guessing which PC key maps to which C64 key, because not only do the keycaps not match, the number of keys don't match either. For example, to the right of the zero key on a C64 there are 5 keys, whereas to the right of the zero key on a PC there are only 3 keys. To the right of the L key on a C64 there are 4 keys, but only 3 on a PC. So, even with a so-called spatial mapping, where exactly should those extra keys get mapped to? No solution is perfect.
The other very obvious and idiosyncratic feature of a C64 keyboard is the presence of graphic symbols and other command words on the front surface of the keys (sometimes on the top surface of later models, like later C64c's and the C128.) Even if you use the C64 a lot, unless you spend all your time drawing in PETSCII, you probably won't develop a muscle memory for where they all are. Without having them printed on the keycaps, guessing which ones are where on a PC keyboard is an exercise in frustration.
The User Interface of a Commodore 64
The beauty of a Commodore 64 is in its simplicity. Unless the C64 is broken, it cannot fail to boot up. There are no software configuration options that can be done incorrectly that can prevent the computer from reaching its standard user interface. An additional beauty of the C64 is that it powers on and is ready to accept input in approximately 2 seconds.
No expansion hardware—no extra devices—are necessary to use a C64 in its most essential form. An almost endless array of additional hardware may be added to the base machine, but they are always just add-ons that augment and improve the computer in various ways.
When the C64 is powered on, with a flip of the switch on the right side just past control port 2, it undergoes an initial reset phase. This tests the RAM, initializes all of the I/O chips to default values, outputs a standard introductory screen, and presents you with the READY prompt.
A Stock C64, Power-On Screen
What's up with 38,911 bytes free? That's only 38KB, I thought this machine had 64KB of RAM.
The C64's built-in operating system can only use 40KB of RAM. Of that, the first 2KB are used as workspace memory for the operating system, leaving 38KB free for your BASIC programs. Other C64 software that you can load and run, including other operating systems, such as C64 OS, can and do make use of the full 64KB and can even make use add-on RAM expansions.
A deeper discussion of main memory and expanded memory is discussed later, in Part II of this guide.
Typical Command Line Interfaces on Other Computers
Many people are familiar with command line interfaces. They are available today on Mac and Windows via their respective Terminal applications, and the Amiga offers the Amiga Shell. Linux installations on PCs sometimes don't include a graphical user interface at all and boot directly to a command line interface, just as pre-Windows PCs boot directly to the MS-DOS command prompt. All of these command line interfaces have something in common, but they are all unlike how the C64's READY prompt works.
On a typical command line, the first word entered is a command, followed by arguments that are provided to the command. Usually there are several commands built into the shell, such as alias, unalias, cd, echo and others. But every command you enter that is not one of the limited set of built-in commands is immediately looked up as a filename from storage devices. A command shell has a configurable variable called path, which lists directory paths on storage devices that are to be searched for an executable program whose filename matches the command typed in. The first match found is automatically loaded in and run. Its behavior is modified by the arguments that followed it on the command line, and usually the program outputs something to the screen and exits automatically back to the prompt. Not always, of course, because this can also be used to launch long running processes, or even programs that take over the display and change the video mode, etc., as was common with MS-DOS games.
The Commodore 64 is completely different. It does not function like these more typical command line interfaces, at all. The above was given for context and comparison.
The Full Screen Editor
The C64 contains two main ROM chips. The KERNAL and BASIC. The KERNAL is the lower-level of the two, and provides the main foundations of the C64's operating system. BASIC is a high-level interpreted programming language, whose commands are implemented by making calls to the routines found in the KERNAL.
When you type on the keyboard at the READY prompt, you are using a combination of features implemented by the KERNAL and by BASIC. The KERNAL provides an interface known as the full screen editor. Unlike typical command line interfaces that limit your text input to a single-line editor, the C64's full screen editor allows you to freely move the cursor anywhere you want on the screen. Usually you will move the cursor with the cursor keys. But some special keys also move the cursor. For example, the Home key moves the cursor to the home position, the top left corner of the screen.
The full screen editor maintains a variety of state properties. The most obvious are the character set mode, the current text color (represented by the color of the blinking cursor) and the reverse character mode. Additionally, but less obviously, the editor remembers whether you are in standard mode, quote mode, or insertion mode, and also maintains something called a linked line table. Let's briefly go over each of these features of the full screen editor.
Character set modesThe Commodore 64 includes a ROM chip that contains two character sets. The default character set at startup is Uppercase/Graphics. In this character set, letters typed without the Shift key appear in uppercase character glyphs. Letters typed with the Shift key appear as special graphic symbols. The alternative is the Lowercase/Uppercase character set, in which unshifted letters appear in lowercase character glyphs, and shifted letters appear as uppercase letters.
You can switch between the two character sets at any time by holding the Shift key and tapping the Commodore key, or vice versa. The whole screen is immediately redrawn using the newly selected character set. If you see text on the screen, but only some letters of words are in uppercase and all the others are a strange smattering of graphic symbols, there's a good chance you're just in the wrong character set mode.
A program that needs to run in one character set or the other will switch to the appropriate character set automatically. However, some programs still allow you to change character sets. This usually results in the user interface of the program looking broken. If you accidentally change into the wrong character set it's very handy to know how to switch back: SHIFT+COMMODORE.
Text color and reverse modeThe C64 can display 16 colors. You can change the current text color by holding the control key and pressing the numbers from 1 to 8, to select the first 8 colors. To select from the second set of 8 colors, hold the Commodore key and press the numbers 1 to 8. Reverse mode causes the shape of the character to take the background color, while the square block around the character takes the currently selected text color. Reverse mode is turned on with CTRL+9 and turned off with CTRL+0.
Quote modeChanges of text color, turning reverse on and off, even moving the cursor up, down, left or right or going to the home position, among other behaviors, are each the result of single PETSCII characters being processed by the full screen editor. Typically, as you type on the keyboard each character is processed as it is typed. However, when you are in quote mode characters are not processed immediately, but are captured in a string to be processed later. Let's see how that works.
Quote mode is turned on simply by typing a quotation mark. It remains on, until you either:
- Push RETURN, or
- Type another quotation mark
Try this: Type a quotation mark. Now push the cursor down key several times. Notice that rather than the cursor actually moving down, a strange symbol (a reversed Q) is output to the screen instead. That symbol represents the PETSCII code for cursor down that is captured in the quoted string. Type another quotation mark to exit quote mode. Now you'll notice that the cursor keys go back to moving the cursor around.
Insertion modeInsertion mode is even more mysterious to people unfamiliar with the Commodore 64. When not in quote mode, each time you push the insert key an insertion counter is incremented. When the insertion counter is greater than zero, the screen editor is in insertion mode. Each following key press is captured as though in quote mode, but also decrements the insertion counter. When the insertion counter reaches zero, insertion mode ends automatically.
Try this: Push insert 5 times. Now push cursor down key 5 times. Five times you will see the same cursor down symbol you saw in quote mode. But when you push cursor down once more, the cursor actually moves down.
If you don't know about quote and insertion modes, and you don't know how you got into them or how to get out of them, they can be a source of confusion. They are actually very useful, because the full screen editor is used for programming in BASIC. A full explanation for how useful they can be is beyond the scope of this guide.
Here's a useful tip. If you find yourself in quote mode or insertion mode and you want to get out of it quickly without inputting any additional characters, hold the Shift key and press RETURN.
The linked line tableYou are free to move the cursor anywhere around the screen, but because of this you might think the screen behaves like a single text field, like a standard text editor would. But this is not the case. The full screen editor divides the screen into a series of linked lines. A line can be either one or two physical screen lines.
To see how this works, push RETURN and then type any single character as the first character on that line. Now cursor left once so the insertion point is blinking on the character you just typed. Now hold down the insert key (SHIFT and INS/DEL together). The character you typed gets pushed across the screen towards the right. When it reaches the end of the line it wraps around to the start of the next line. Continue to hold the insert key down. The character gets pushed to the right end of the second line, but then suddenly it stops. The character has reached the end of the second line, and the screen editor has linked those two screen lines together into a single logical line. (Watch out, you're now in insert mode! Just push SHIFT+RETURN to leave insert mode.)
Whenever you delete a character on a line, all of the characters to the right of the deletion to the end of the logical line are pulled left one space. If the number of characters in a logical line take up less than 2 screen lines, the screen editor automatically updates the linked line table so that only one physical screen line is used. I give you this information because when you are aware of it, the behavior of the full screen editor becomes more transparent.
The BASIC Environment
BASIC is so integral to the user interface of the Commodore 64 that you cannot avoid using BASIC, unless the only thing you do is draw PETSCII art pictures using the graphic symbols and the full screen editor.
To understand how the C64 works, we have to compare it to the description given earlier about typical command line interfaces found on other computers. Most commands, on other command line interfaces, send the computer off searching the storage devices for a filename that matches the command. But the Commodore 64 does not require any storage devices, so this behavior wouldn't make any sense.
The Commodore 64 (like other Commodore 8-bit machines) comes with BASIC installed in a ROM chip on the mainboard. While typing on the screen you are interacting with the KERNAL's full screen editor, which is manipulating the linked line table. As you type, you are effectively loading up an 80 character line buffer. Whenever you push RETURN, the contents of that line buffer are sent off immediately to be interpreted by BASIC.
Therefore, the only valid commands that you can enter are the set of BASIC programming commands or keywords. This is a very constrained set, although it is possible to extend BASIC with either hardware or software. You can't just type the name of a program, you can only enter BASIC commands.
Direct Mode and Program Mode
Whenever you push RETURN on a line, that line gets processed by the BASIC interpreter. The line is processed in sequence from left to right. There are 3 valid ways for a line to start:
- A number
- A command keyword
- A full colon
If anything other than a number, a keyword or a full colon is encountered, the BASIC interpreter ouputs:
?SYNTAX ERROR
If a number is encountered first, the rest of the line gets interpreted, but its contents are not executed right away. Instead they are added to the current program. The BASIC environment allows for a single BASIC program to be in memory at a time. A program consists of a list of commands to be executed one after the next. Each line in the list has a number, and the lines are always arranged in numeric order from smallest to largest.
If a keyword is encountered first, the line gets interpreted, and then the line gets executed right away. Any line that gets executed right away is said to be in direct mode. Execution in direct mode does not disturb any BASIC program currently in memory. (Except for the NEW command, whose express purpose is to clear memory of the existing program.)
The full colon is a special symbol that separates BASIC statements, allowing more than one statement to exist in the same line. This is useful both in program mode and direct mode as we'll see.
Commodore BASIC v2 (the version of BASIC built into the Commodore 64) has a lexicon of 71 commands. Only some of these are allowed to be used in direct mode. If you try to use a command in direct mode that is only supported in program mode BASIC outputs:
?ILLEGAL DIRECT ERROR
Using Direct Mode
Everyone who has ever used a Commodore 64 has used BASIC in direct mode. It's nearly impossible not to. To load the first program on a cassette drive, you enter the following command:
load
This is a BASIC command. When you press RETURN on that line, it is sent to BASIC to be interpreted. It doesn't start with a number, so it checks to see if load is a keyword. It is, so it begins executing that command in direct mode. The syntax of this command allows it to take zero, one or more arguments. As BASIC executes the command it searches for valid arguments following it on the line. It stops searching for more arguments if it encounters the end of the line or a full colon. Either of these indicate the end of this BASIC statement.
Although load is most frequently used in direct mode, it is perfectly valid to include load as a command in a program. Before proceeding to discuss more BASIC commands and what they do, we need to introduce a few more concepts that are important for understanding how the Commodore 64 works.
Devices and Channels
The Commodore 64 can address up to 31 devices. Each number from 0 to 30 can be used to uniquely identify one device. Device numbers are assigned as follows:
Device | I/O | Device # |
---|---|---|
Keyboard | Input | 0 |
Datasette | Both | 1 |
RS-232 | Both | 2 |
Screen | Both | 3 |
Printer | Output | 4 |
Printer | Output | 5 |
Plotter | Output | 6 |
Plotter | Output | 7 |
Storage Devices | Both | 8... 30 |
The keyboard and the screen are built-in devices. One datasette may be connected to the cassette port. RS-232 is used to communicate with other RS-232 devices connected to the User Port. Printers and Plotters are connected to the IEC serial bus. In order to connect two printers, at least one of them must provide the option to change its address from 4 to 5. Storage devices, including disk drives, hard drives, Compact Flash and SD Card drives, are typically connected to the IEC serial bus, but some special high speed storage devices can be connected to the Expansion Port. Each storage device must be manually configured with a unique device address from 8 to 30.
Early disk drives can only have their address changed with an internal modification and are configured as device 8 by default. Later disk drives provide DIP switches to configure their address from 8 to 11. More advanced, mass-storage devices, such as hard drives and SD card drives, can be assigned via software any address from 8 to 30.
ChannelsThe C64 has a simple data connection model. The computer has one input channel and one output channel. Data is read in from the input channel and fed out the output channel. By default, after the computer is first turned on, the keyboard is assigned to the input channel, and the screen is assigned to the output channel. Although the reality is a bit more messy, this is an elegant conceptual explanation for why characters typed on the keyboard appear on the screen.
Using BASIC commands you can change the assignment of the output channel, which provides interesting opportunities that we will explore. Whenever the channels are cleared and reset, they revert to their defaults of keyboard input and screen output.
Logical FilesIn order to gain access to a device, either for input or for output, a connection must first be opened. When you're finished with a connection, it should be closed. The BASIC commands open and close are used for this. There is more to explain before going into detail about these commands.
In Commodore's terminology, an open connection to a device is called a logical file. Such a connection may be—but is not necessarily—associated with a conventional file. It is best to think of a logical file as a connection to a device that provides or accepts a stream of data.
The KERNAL allows up to 10 logical files open at the same time. Each connection is assigned a logical file number when it is opened. A logical file number is an identifier or a handle on that connection and is arbitrarily assigned. When you open a logical file you can use any number not currently in use, from 1 to 127. That number is then occupied. Numbers 128 to 255 have a special purpose and cannot usually be used without some side effect. When a logical file is closed, its identifying number is freed up to be used again.
Secondary AddressesSome storage devices, such as disk drives, hard drives and others (but not the datasette) can support multiple connections. In order to distinguish those connections, the drive supports channels of its own. When opening a logical file to a device, depending on the device, you may have to specify which channel of the device to use. This specification is called a secondary address. The primary address is the device number, the secondary address then refers to some part or feature of that device.
Secondary addresses are not arbitrarily chosen. The meaning and the use of a secondary address depends entirely on the device you're connecting to. We'll see examples of this shortly.
Additional Connection InformationSome devices can also take or require additional information to establish the connection. For example, when opening an RS-232 connection, a single extra byte is required whose bits specify the baud rate, the number of bits per word, the number of stop bits and whether or not to include a parity bit.
The additional information that can be provided to storage devices is more complicated and is discussed in more detail in Part II of this guide. In short, though, when you open a connection to a storage device to read a file, you have to specify the filename.
Routing and Redirecting Data
When no other program is running and the Commodore 64 is waiting at the READY prompt, the computer is spending most of its time repeatedly checking if anything has been typed on the keyboard. As soon as a byte of input is available from the keyboard it directs it to the screen, and, unless RETURN is pressed, it goes right back to the loop that checks for more keyboard input.
There are other processes that produce data to be output. For example, if a BASIC program is in memory, the list command sends the program listing to the output channel. Because the screen is assigned to the output channel the program listing typically appears on the screen. A print command, similarly, sends its string to the output channel.
It is possible, however, to change what device is assigned to the output channel. Interesting possibilities arise from this. For example, if we could assign a printer to the output channel then a program listing would be printed to paper instead of the screen. And a simple print statement could be used to print out any string we want to type. If we could assign an RS-232 connection to the output channel, we could send our output to a modem, or to another C64 over a null modem cable. It's pretty cool that this is built right into the C64's unassuming command line interface.
Routing is done via Logical Files
In order to send data out to a printer, you must first open a connection to the printer and assign a logical file number to refer to that connection. This can be done in direct mode, so you don't need a BASIC program and it won't disturb any BASIC program already in memory. A printer can be set as either device 4 or device 5, or there could be two printers hooked up at the same time. You choose which printer to use by its device number. Enter the following at the READY prompt.
open1,4
This opens a connection to the printer set as device 4 and assigns logical file 1 to the connection. If you have already assigned logical file 1 to an open connection, you get the following error:
?FILE OPEN ERROR
Either you forgot to close that connection or, if you want both connections open at the same time, you have to choose a different logical file number that isn't in use. When the computer first attempts to send data to a device, if the device isn't there you get this:
?DEVICE NOT PRESENT ERROR
This would happen, for example, if you tried to send data to device 4 but your printer is actually set as device 5.
Now we can change the standard output channel to the printer, by means of the logical file number and its open connection. This is done with the cmd command. Like this:
cmd1
Things you type on the keyboard are still sent to the screen, but all other output automatically generated by the computer will be sent to the device assigned to the output channel. This includes the READY prompt, so the word READY will be sent to the printer. If you type list to list a BASIC program in memory, the listing will be sent to the printer, followed by the next READY prompt. To send strings of your own choosing you can use the print command, like this:
print"Hello there!"
This will send Hello there! to the printer. And remember, a redirection of the output channel doesn't have to go to a printer. It could go to an RS-232 connection or to an open file on a storage device.
To restore the screen as the default output device, you use the print# command with the logical file number currently assigned to the output device. We used logical file number 1 to open the connection to the printer, so we would using the following to undo the cmd command:
print#1
The screen is now assigned to the standard output channel again. But the connection to the printer is still open, with logical file number 1 still assigned to that connection. You don't have to close the connection if you have more to print. You should leave the connection open until you are truly done with it. You could, for example, open connections to two different devices and alternate sending output to them. When you're finished with a connection, you use the close command with the logical file number of the connection you want to close. That logical file number gets freed up to be used again.
close1
Getting a bit more control
It's pretty cool that you can use cmd to redirect the general output channel to a different device. On the other hand, it's a bit of a blunt instrument. You get error messages and the READY prompt itself being sent out to your modem or your printer. It would be nice to have control over each individual byte sent to the output device.
For this, there is the print# command, which we saw earlier, used to end the cmd output redirection. After you open a connection to a device, you can send a string directly to that device without redirecting the output channel. First open the connection to the printer:
open1,4
Then send a single and precise string to that device via its logical file number, without reassigning the standard output channel:
print#1,"Hello there!"
You can continue to send more data with subsequent print# commands before issuing the close command when you're done. The two commands print and print# work very similarly. The main difference is that the former sends its data to the output channel, whereas the latter sends its data to the specified connection.
Here's a tip. Both print# and print automatically output a carriage return following the string you specify. So if you issue three print# commands like this:
print#1,"Hello there!" print#1,"I can print" print#1,"right from the READY prompt."
This will result in three separate lines. It's handy if you want to output on separate lines, but if you want to issue multiple print commands such that the strings immediately follow one another, you can add a semi-colon at the end to supress the carriage return. But don't forget to include appropriate spaces at the ends of lines.
print#1,"Hello there! "; print#1,"I can print "; print#1,"right from the READY prompt."
The above three print# commands will print out the following on a single line, with a single carriage return at the end of all of it.
Hello there! I can print right from the READY prompt.
This is a small taste of how you can quite easily open connections to different devices that can be connected to your Commodore 64, and how you can direct or send data out to them. The possibilities multiply vertiginously if you allow yourself to write even a very short program. With only a 4 or 5 line program, data can be read in from one or more devices and sent out to one or more other devices. With this you could, for example, read a text file from storage and output it to the printer. Or read a file from storage and transmit it via a modem. Or take data coming in from a modem and output it to a printer, allowing one computer to print to another computer's printer, through a network. Neat stuff, right?
Writing data to a printer or a modem is cool—especially when you consider that today that modem can be a WiFi modem—but it may not seem overly practical. This is probably not something you would do every day. What is much more practical is that all of this can be applied to writing data out to files on storage devices.
We started by talking about printers and RS-232 connections because they are conceptually simpler than storage devices. A printer accepts a single stream of data. An RS-232 connection can accept or provide a single stream of data. But storage devices, and all that you can do with them, are more complicated. The discussion of storage devices is found in Part II of this guide.
Programming in BASIC
When you get a computer today you expect it to do a bunch of standard things and to do them faster and better than your last computer. But when you got a computer in the distant past, like when you got your first Commodore 64, something was different. One's attitude to their new computer wasn't just, "give me what I want." Nor was it to just take all that you could have without giving anything back.
It was exciting to get a computer; it was a whole new world. You got it to explore what you could do with a computer, often in contrast to not having one at all. At the same time, it was much more of a two-way relationship. What you could do with your new prize involved putting a lot of yourself into the computer.
Computers used to come with a User Manual. Now, there is an adage in user interface design that if you have to show the user what to do, you've already failed. Sadly, this is no longer a two-way relationship. It's the relationship of an employer to his employee, or a king to his servant. It's an entitled attitude of, "do everything for me, and I don't want to have to do anything."
On the Commodore 64 and other computers of its era—before the onslaught of the commercial software industrial complex—there was no difference between programming a computer and using a computer. Programming your computer was how you use your computer. But on the other hand, programming then was not like programming now. When your goal is to explore, to learn, and to get your computer to do something interesting, there is no wrong way to program.
The BASIC programming language, built into a C64, only has 71 commands. There are no libraries, there are no dependencies, there are no patches and no versions. Bugs in the BASIC ROM have been explored, documented and explained, but they have also just been lived with for 40 years. Learning to program your Commodore 64 is fun, rewarding and educational. It can be challenging, but with a good book and some patience, it is not frustrating or overwhelming.
While writing this section, I found this short program. It's a kind of colorful "screen saver" visualization.
Isn't that cool? Doesn't that make you happy? Well, here's the source code. Just 15 lines of BASIC. A little bit of arithmethic inside some nested loops. Zero dependencies. You don't even need a storage device, it's so brief you could easily type it in from a sheet of paper. And it runs the same way on every Commodore 64 ever made.
It is peaceful and satisfying to see something so simple make something so beautiful.
In a guide such as this one, there isn't enough space or time to get into the details, but there are many wonderful books available to learn how to program your Commodore 64 in BASIC.
A sensible place to start is with Commodore's own:
C64 Programmer's Reference Guide, Chapter 1, BASIC Programming Rules
If you're ready to dive into something more thorough, this book by Compute! is one of the best:
Programming the Commodore 64, The Definitive Guide
In fact, there are even some amazing online interactive tutorials, such as:
The Lost Ways of Programming: Commodore 64 BASIC
This concludes Part I.
In Part II, we'll look at the essentials of what you need to know when adding storage devices and some other important expansion hardware to your C64.
Part II: Beyond the C64
Table of Contents
This document is subject to revision updates.
Last modified: Sep 20, 2022