Let’s have a look at some nice Commodore 64 keyboard buffer tricks. The keyboard buffer is normally used by the system to store apart keystrokes while the system is busy. Those keystrokes will be processed at a later time.
Thus, if you are trying to type in a few letters while the system cannot receive your input, what you are typing usually is not lost. ASCII codes of typed-in characters are stored in the keyboard buffer.
For instance, if you try to type something while a FOR… NEXT loop is running, you will see what you have typed in right after the FOR… NEXT loop ends.
Given the features of Commodore 8 bit computers screen editors, the keyboard buffer can be used for very nice things, like automatically sending commands to the BASIC interpreter.
Usually, this feature is used to issue a LOAD command from within a program, so that the current program can load another program. That’s not a command running from within a program, rather it’s some sort of automatic command entry feature.
Let’s have a look at the following program:
10 printchr$(147)"poke 53280,"c 15 printchr$(17)chr$(17)"goto 10" 20 c=c+1:if c=256 then c=0 25 poke 631,19:poke 632,13:poke 633,13:rem home and two returns on keyb. buff. 30 poke198,3:rem process three keypresses from the keyboard buffer
Apparently, the program seems to be just a sequence. It just prints information on the screen, it changes some memory locations, then it ends.
However, the program will run as if there was a loop inside it.
The keyboard buffer starts from 631 decimal and ends to 640 decimal. Up to 10 keypresses can be stored on it.
We can poke ASCII codes on these locations at will. Then, a POKE to location 198 will tell the operating system to get up to 10 keystrokes from those locations.
For instance, if we issue the following line from direct mode:
poke 631,65:poke 632,67:poke 633,69:poke198,3
the word “ace” will appear, like if you just typed it.
Any ASCII code can be stored on the keyboard buffer, including control characters such as HOME and RETURN. Those two are quite useful to send BASIC commands automatically. That’s just what the previous border color changing program actually does. This program PRINTs the commands on screen, then it sends them to the BASIC interpreter by hitting RETURN just over those commands on screen. It’s just some sort of automatic typist.
You must pay attention to print information properly. For instance, when you enter a command in direct mode, the computer prints an empty line, then the READY prompt. That’s why two CURSOR DOWN control characters are printed on line 15 of the above program. This way, the “automatic cursor” will be just over the command “GOTO 10” when a RETURN from the keyboard buffer will be retrieved.
Something more advanced
Since BASIC lines can be deleted from direct mode, why not try to delete BASIC lines by using the automatic methods we have just seen?
After all, it’s just a matter of printing a few line numbers on screen, then cleverly use the keyboard buffer to make the computer automatically hit RETURN over those line numbers. Well, it’s a bit more than that.
From direct mode, assign a variable a value other than 0. Then, try to delete a line number, let’s say 10, even if no program is on memory. Now, print the variable you have previously assigned a value. You just get 0. The previous value has gone.
Why that happens? When you delete a line, the BASIC interpreter must resize the whole BASIC memory, including both the program and the variable storage area. As a result, variables are cleared.
So, we can use the keyboard buffer technique to automatically delete BASIC lines, but we must be careful. We must preserve variables used by our BASIC lines delete routine.
The idea is to use a BASIC program that will live along with the BASIC program you will write. Lines above 60000 are seldom used by programmers, so those lines are reserved for some BASIC utilities. Of course, you may accidentally delete a line that is part of those utilities, but we will take this risk. After all, we are just demonstrating some tricks dealing with the keyboard buffer.
There are two utilities available. The first one, starting from line 60000, can be used to delete BASIC lines from a given range. For instance, you can delete lines ranging from a given line number to another line number, with the desired step. For instance, you may use this utility to clear lines from 100 to 120, in steps of 5. That means, lines 100, 105, 110, 115 and 120 will be deleted.
As you can see from the code, the program sends several commands to the BASIC interpreter using this kind of “automated direct mode”.
On each iteration, the program prints a line number, then the assignments for the variables – so that those are kept “alive”. Finally, a GOTO statement is sent so that the next line number can be deleted.
After information on the screen has been printed, the program sends the required control characters on the keyboard buffer, then stops.
Whenever the READY prompt appears, the system processes the characters on the keyboard buffer. As a result, the cursor is set to the home position, then RETURN is depressed by the system three times. As a result, all commands on screen are sent to the BASIC interpreter via direct mode. And since we have a GOTO statement, program execution resumes.
Although by no means fast, the program seems to work fine.
Creating DATA lines
The program also has the ability to automatically create DATA lines. For instance, if you want to do some music with BASIC, you may need some DATA lines to enter music data.
Furthermore, you may also like formatted null values on data statements, so that entering actual numeric values will be much easier. For instance, if you have to type in a machine language program from an old magazine, then automatically creating DATA lines with empty three-digit zeroes may be quite useful.
Suppose we want to create 11 lines, from 100 to 200 with a step of 10, with DATA entries containing six three-digit zeroes. Here’s how to input data on the program and the output we get:
Let’s have a look at the code.
On line 60055, an empty zero with a comma is created. For instance, if you want three digit zeroes, a “000,” string will be created.
On line 60065, the data for the DATA statements is created. That is, a string representing a sequence of zeroes and commas is created. This string is called S$. The requested number of zeroes is put on DATA statements. If they are too much for a logical line, exceeding zeroes are truncated. The LEFT$ function is used for that.
Line 60080 eliminates the unwanted comma that may be found at the end of the data string.
Lines from 60090 to 60100 are used to adjust the data string if truncation led to unwanted zeroes. The string is scanned so that if there is an incomplete number at the end of data, this is deleted. For instance, if we have a data string such as:
those lines make sure that the two zeroes at the end of the string and the comma are truncated.
Lines from 60115 take care of entering DATA lines on program memory. DATA lines are created.
How to get rid from the utilities?
OK, we have created the DATA lines we needed. Or, we have finished writing our BASIC program, deleting useless lines in the process. Now, how can we get rid of the mess starting from line 60000?
No, you don’t need another BASIC lines deleting utility…
The code from line 60185 will take care of that. But, how can a BASIC program be able to delete only a part of itself? Again, automatic direct commands with the help of the keyboard buffer is what really helps here.
This routine first makes use of the BASIC lines deleting routine to delete parts of the program that are not needed at the moment. So, the code that takes care of creating DATA statements can be deleted with no problems. This is what line 60195 does. Notice the flag AD: this variable is used so that the routine from line 60005 can be exited. Notice that while deleting lines, this variable is always preserved as well.
Now, lines 60200 and 60205 will finish the job, deleting the remaining part of the utilities. These lines just print some line numbers, then delete them by hitting return over them. I had to cope with the 10 characters limit on the keyboard buffer, but I was lucky.
Now you only have what you need in memory: your BASIC program and/or the data statements you have previously created by using the now defunct utilities.
Is all of this stuff USEFUL?
Maybe not. Nowadays, certainly it isn’t. But, this kind of approach may have had some sense back in the days.
Suppose you are not a machine language coder and you have no BASIC lines delete utility at hand. Then, you could come up with your own utility, similar to the one presented here. It is not fast, it does a poor job compared to machine language, but at least it works. And it is certainly better than deleting a bunch of BASIC lines manually.
For instance, if you have to write a musical program with a lot of musical data, you can do as follows. You can load these BASIC utilities, then write the program, maybe create DATA lines with the help of the DATA lines utility, and save the whole thing on disk. Then, when the program is finished, you can create an additional polished version with the BASIC utilities removed. But, if you want to play another tune, you can just load back the version with the utilities from line 60000 attached. Then, you can delete the lines with the old musical data, and start entering musical data for the new tune.
Yes, back then, such an approach could have been somewhat useful. And my simple programs demonstrate that you could actually write a BASIC lines delete utility even with no machine language aid. And after all, finding a way of using BASIC for a task that seemed machine language-only may be regarded as something interesting.