Sequential files are files to which we can write arbitrary data and read it back later. We can even append data to the file later without having to re-write the whole file.
This works with the Datasette (tape drive) as well as floppy drives. Here’s how to do it in CBM BASIC 7.0:
Creating Sequential Files
The C128 has a few special commands up its sleeve to aid us in this task. Here we create a new file using the DOPEN keyword and write 100 statements to it.
10 dopen#1,"@seq test",w 20 for i=1 to 100 30 a$="record"+str$(i) 40 print#1,a$ 50 print "writing ";a$ 60 next 70 close 1
We’re creating a new sequential file (SEQ extension rather than the usual PRG), using the w after the filename so that BASIC knows to create the file. The @ sign in front of the file name makes sure this file is overwritten every time we run the programme – omit it if you don’t want that functionality.
Next we create a loop and generate a variable spelling RECORD 1, RECORD 2, etc. That’s your data. Each entry may be up to 127 characters in length (I believe) and is saved to the file by using the PRINT# keyword. Anything we could print to the screen, we can also print to a file.
With each new PRINT# command, a carriage return is saved to disk. This can come in handy when we’re reading the data back in. If you need special characters to separate your data, feel free to use them.
Appending data to Sequential Files
If we need to add anything to the file (much like Linux would add to the end of a text file using the “greater than” symbol), we can use the APPEND# keyword:
10 append#1,"seq test" 20 for i=101 to 150 30 a$="record"+str$(i) 40 print#1,a$ 50 print "appending ";a$ 60 next 70 close 1
APPEND# opens the file for adding data and positions the pointer after the last entry in our file. We’ll do something very similar as above, creating records 101 to 150 and adding them to the file. Make sure to CLOSE the file so all data is saved to disk.
Reading Sequential Data
Much like PRINT# can be used to write data to disk, we can use INPUT# to read data back – almost equivalent to the INPUT keyword get get user input from a keyboard. The only difference is that out input comes from a different device:
10 dopen#1,"seq test" 20 for i=1 to 150 30 input#1,a$ 40 print a$ 50 next 60 close 1
Here we open our file with DOPEN# and grab each entry in the file using the INPUT# keyword. This will automatically position the next INPUT# when a carriage return is received (CHR$(13)).
This will work just fine as long as the original data does not contain any special characters, like a scary comma. If you need such characters, or if you want to ignore the carriage return, you can also use the GET# command to read one character at a time from disk. This is dramatically slower though.
Notice that there’s no “end of file” marker as such: right now we need to know how many entries there are and read them accordingly. Reading beyond the data in our file will simply repeat the last record (on real devices) or crash your system (on VICE).
I appreciate your posting this; I’ve been relearning Commodore BASIC and these pages have helped. Something I wanted to add for the next person reading this, I learned today if you try to use a string variable (let’s say, f$) for your filename, you can’t just replace the filename with your variable like in these statements:
5 input “filename”;f$
10 dopen#1,f$,w (omitting “,w” for append/read)
Even if you include “@” in your string, for some reason it won’t work. You will have to type it out as:
5 input “filename”;f$
10 dopen#1,”@”+f$,w
I don’t know why the interpreter won’t accept it but it caused a little heartache until I realized it.
Thanks again!
Oh nice – thank you for sharing! And have fun retro coding those lovely old Commodore machines 🙂