• Skip to main content
  • Skip to header right navigation
  • Skip to site footer
Retro Game Coders

Retro Game Coders

Retro computer/console game + dev community

  • Home
  • About
  • Blog
  • Retro Resources
    • Retro Gaming Timeline
    • Browser C64 Emulator
    • Best Retro YouTube Channels
    • New Retro Books
    • Raspberry Pi Amiga Emulation
    • MiSTer FPGA Tutorial
    • BMC64 C64 Pi
  • Contact
Home » Programming

C64 DOS Commands – Commodore BASIC Programming Part 5

Commodore 64 BASIC Programming Series

Part 1: Introduction to Commodore BASIC

Part 1.5: Installing CBM Prg Studio on Mac/Linux

Part 2: Commodore BASIC Commands GOSUB and FOR Loops

Part 3: If/Then, Game Logic and Cursor Movement

Part 4: The Magic of POKE

Commodore might have built game-changing (heh) video game features in the C64, but their background was firmly in the business market, especially the small business market. Therefore it is hardly surprising that they included rudimentary Disk Operating System commands into the Commodore 64.

For games too, loading data is important. Today we call game data “assets” – things like sprites, level data, music, graphics, and so on. While listing out this data as part of the program in DATA statements works, it soon becomes cumbersome.

In this article we will look at how we can use these disk and file access features within our Commodore 64 BASIC programs

Commodore 64 File Types

The C64 has these four file types. Really, it is 3 with a variation on Sequential called USR.

We have already been using the PRG type as that is what our BASIC programs are saved as. PRG files can also be used for data and loaded using the LOAD,8,1 command as the first two bytes set the address in RAM to place the file.

SEQ, or Sequential files are the simplest type. They must be read from the beginning in order to get to the part you need. Think of them like documents or plain text files.

Unlike SEQ, you can access individual REL records directly thanks to an index stored on disk (“side-sectors”). REL files are organized as fixed-length records, and records can only be up to a maximum of 254 bytes in size due to the maximum sector size of the disk format.

Back in the day, programs rarely used the USR file type. They are essentially a SEQ file for our needs.

PRGProgram
SEQSequential
RELRelative / Random-Access
USRUser
Commodore 64 File Types

C64 DOS Commands

Before we can send any file or disk commands, first we must open the appropriate channel:

OPEN 15,8,15

This takes the following three parameters:

  1. File number – for referencing the file in future commands. In assembly it is referred to as the Logical Address.
  2. Device number – specific device attached to the computer. By default, the first disk drive is device 8, the second device 9. In assembly this is called the Physical Address.
  3. Secondary address – the communication channel. This is passed to the device in the range 0 to 14 when reading or writing data, or we use 15 as the “command channel”, which is used to send DOS commands.

Once we have an open channel we can issue commands:


Format: 
PRINT#15,"NO:FILENAME,XX" 
Rename: 
PRINT# 15,"RO:FILE2=FILE1"
Backup: 
PRINT#15,"CO:FILE2=O:FILE1"
Delete: 
PRINT#15,"SO:FILENAME"

How to use the CMD Command to Save Your Tokenized BASIC Program as an ASCII Text File

Confusingly for many, Commodore BASIC programs are NOT plain text files. They are converted, or “tokenized”, into PRG files. This means you can’t just load one up into your text editor.

What we can do though is output our tokenized BASIC to a Sequential file by redirecting the output using CMD, and then we can load that newly generated file instead.

OPEN8,8,8,"NEWFILE,S,W":CMD8:LIST

Followed by

PRINT#8:CLOSE8

To display the saved text file we simply load the Seq file:

10 OPEN8,8,8, "NEWFILE,S,R"
20 FORI=0TO1:GET#8,A$: PRINTA$;
30 I=ST:NEXT:CLOSE8:END

Loading Binary Data into C64 Memory

Just as we can load a program into the memory address it was saved to, we can do the same with data. That, of course, means we must have saved the data with a header containing the address that it should be loaded into.

In CBM PRG Studio we can save our game’s custom characters to a specific load address
10 REM LOAD DATA
20 IF A=0 THEN PRINT CHR$(147)"START"
30 IF A>0 THEN PRINT "LOAD FILE"A
40 A=A+1:ON A GOTO 50,60,70
50 LOAD "CHARS.BIN",8,1
60 POKE 53272,(PEEK(53272)AND240)+12
70 PRINT “{CLEAR}DONE!"

Strangely, each LOAD command in BASIC resets the program counter and restarts the program, so we have to keep track of which load we are currently on using a variable, in this case we increment A.

Finding the Current Drive Number

The drive we are using right now is stored at the memory address 186 so we can PEEK that to determine which drive number to reference:

CD=PEEK(186)

Some commands do change what is returned by PEEKing 186, but always to a number less than 8, therefore the best approach would be to do:

CD=PEEK(186):IF CD<8 THEN CD=8

We will start building out more game data routines next time

If you like it, share it! (Please - because it really helps)

  • X
Category: ProgrammingTag: basic, c64, commodore, programming
Previous Post:getting-started-with-trseLow-Level and Assembly Programming in Turbo Rascal (TRSE)
Next Post:Loading Game Data – Commodore BASIC Programming Part 6

Retro Game Coders

Retro computer/console game + dev community by Chris Garrett

  • Facebook
  • Twitter
  • Instagram
  • YouTube

Maker Hacks ・ Geeky Game Master

© Copyright 2021 Chris Garrett

Privacy ﹒ Terms of Service

Return to top