Basil’s Compendium: A Few No-Nos

A Few NO-NOs

This chapter will explain the three instructions that it would be wise to avoid in ZX81 machine coding. In decreasing order of importance, they are 118, 126, and sometimes 11. But first to our little digression.

The bad news is that I don’t have any “fun” program for you this time. The good news is that I’m going to suggest a little technique that will help you to keep track of the ones that you already have.

Figure 7-1 gives you an idea of how all those utility programs can be stacked up into a series. Leave Line 1 vacant for the moment, and enter all your utility routines as shown in lines 100, 110, 120, etc. If you want, use line numbers 1000, 1100, etc., or any other numbers–but it’s most convenient to use line numbers beginning with the digit “1” (for reasons that will soon become apparent).

Line 10 gives an index to the series. This is optional, as are the “operating instructions” that are interpolated between the successive machine code routines. Now, when you want to invoke a machine code routine, just bring the selected routine down into the EDIT position, and put it into position as line number 1. (Which is easier to do if the line number already begins with 1.) And there you are, ready to go.

Fig. 7-1 Stacking the routines
Fig. 7-1 Stacking the routines

You’ll also notice that I added the name of each machine code line at the end of the routine. This is completely kosher–once the computer has encountered and complied with the RETURN instruction, it doesn’t matter what additional garbage (or other verbiage) is included.

And now back to the lesson.

Before going through the next steps, SAVE any material in the computer that you may want to keep.

Now, suppose you want to LET BC=118. Or, in machine code jargon, Load BC with 118. Use the loader program we introduced last time, making sure that you have enough nulls, and enter Line 100 as

100 LET P$="6.0.14.118.201."

and RUN. You’ll notice that the program proofreads perfectly all right, and that PRINT USR 16514 gives 118, just as you expected. Now LIST the program, and bring line 1 down into the EDIT position. Where’d everybody go?!!!

Just to make sure how much we lost, PRINT USR 16514 again. Well, at least that much still works. Now LIST 10. There’s the rest of the program, so I guess we haven’t done anything fatal. Let’s change the program to

100 LET P$="14.118.6.0.201."

and RUN. Again the proofread is OK. PRINT USR 16514, and you’ll see that it doesn’t matter whether we load B or C first, as long as we’re telling the computer separately what to put into each byte. But pay attention to that “as long as” proviso. When we get around to loading both registers with a single command, it’s going to matter very much which one we mention first.

But now LIST the program again. More confusion! And if you need further proof that something funny is afoot, try to EDIT line 1.

So here’s no-no number one: stay away from 118! Think of it as the computer’s unlucky number.

The reason for this crazy behavior is that the ZX81, whenever it sees a 118, thinks that it has reached the end of a line. The number 118 is one of those “housekeeping” indicators that we talked about a few chapters ago.

And there’s a further reason why we want to avoid 118’s–some of our programs are going to use the presence of a 118 as an indicator of the end of the line, just as the computer does. And those programs would be just as confused by a spurious 118 as the computer’s display was.

It shouldn’t be too hard to avoid 118’s. After all, there are only two reasons you’d ever want to use 118–or any other number–in a computer program: as an instruction or as data. And you’ll never want to use 118 as an instruction. Let me phrase that a little more emphatically–NEVER use 118 as an instruction.

And why not? If you’ll look up 118 (or 76h) in the table of instructions for the Z80 chip, you’ll find that it results in HALT. A very useful command, you might think–after all, BASIC programs use STOP every day. The difference is that you can always give a new command after a STOP in BASIC, to get things going again. But if you use HALT during a machine code operation, there’s no way to get the computer’s attention to resume operations. (The TS1000 uses the HALT instruction as an aid in creating the display file and setting interrupts. An example is given in SWN 2/2 pg. 17. The byte after the HALT tells the computers where to go.) So, you won’t want to use 118 as a command very often. About once in a lifetime would be enough. But what if you want to use it as data?

Usually, the easiest way to avoid using 118 as data is to load the appropriate register with 117 and then add 1 to it. That’s the approach I usually use. There’s even a special instruction, called INCREMENT, that increases the contents of a selected register by 1. Or you may choose to use some other dodge. But it’s usually worth while to find some way around the 118’s of computer life.

There’s another number, 126 (7Eh), that it’s best to avoid, too. To see it at work, use the loader program to enter the following series into 1 REM:

6.0.14.125.201.

Now LIST, and look at the first line. All in order? And notice that PRINT USR 16514 gives 125, just as you’d expect. Now change the 125 to 126, and try again. The proofread is as you’d expect, and PRINT USR 16514 gives the predicted value of 126, but look at what line 1 gives when you LIST it!

What happened to those missing bytes? Well, that’s another of ZX81’s little quirks. The symbol 126 is used by the ZX81 to tell itself that the next few bytes are to be construed as making up a number, and are not to be displayed in the normal fashion. To add injury to insult, if you try PRINT USR 16514 after EDITing this line, you’re likely to crash the program.

“Crash”, in case you don’t know by now, is a rather picturesque term for what happens when the program goes completely out of control, and can’t be recaptured. You’ve already seen what happens when you fool around with one of the “housekeeping” bytes. Another sure way to crash is to use 118 as an instruction, as we discussed above. Yet another is to write a machine code sequence without a RETURN.

Luckily, it’s the program that crashes, rather than the computer. The ZX81’s hardware is not damaged at all by a crash, other than the wear and tear on the plug as you pull it out to start over. But a crash can do incalculable damage to your equanimity–and it could put a strain on your marriage, if your spouse happens to be within earshot.

Getting back to our friend, 126. It’s usually easy enough to avoid using it as data. Unfortunately, however, it represents a very useful instruction. There are ways, however, to get around that instruction, and I’d suggest that you take advantage of them.

One other sometime no-no is number 11. The CHR$ of 11 is “, the simple quotation mark. As long as you’re working with REM statements, as we will be for some time, this little guy is harmless. But if you’re storing your machine code in a string, as someday it may happen, he’s likely to give you trouble.

And on that ominous note, I’ll leave you for now. There will be more.