BASIC MACHINE CODE FOR THE ZX81

Discussion about ZX80 / ZX81 Software
David G
Posts: 387
Joined: Thu Jul 17, 2014 7:58 am
Location: 21 North, 156 West

BASIC MACHINE CODE FOR THE ZX81

Post by David G »

A beginner's series from SyncWare News, a 1984 newsletter

A delightful series, well written

CHAPTER 1 from Volume 2 Number 1 pages 8-10

Page 8
BASILS' COMPENDIUM

BASIC MACHINE CODE FOR THE ZX-81/TS1000

John (Basil) Wentworth
1413 Elliston Drive
Bloomington, In. 47401

As the title implies, this series is designed to introduce the beginner to the basics of machine coding. The beginner in machine language that is. We must assume that you already have a working knowledge of BASIC.

As the title also implies, I will try as much as possible to relate machine code programming to the concepts of BASIC, with which you are already familiar. (I'm tempted to refer to this as Basil's Compendium on Machine Code, but I'll forego that conceit).

WHY MACHINE CODE?

Since you're already familiar with BASIC, you may wonder, why bother learning smother, more foreign language? The answer of course is SPEED, and more economical use of of memory, not to mention the fun of learning itself.

Think of computing as traveling in a foreign country. Machine language is the native language of the computer. If you have ever traveled abroad, then you are aware that is very convenient to have some knowledge of the local language. Although the residents of say, Barcelona (especially Barcelona!) are very courteous, and will make every effort to understand your language, you'll get your point across a lot faster if you speak Spanish. Again, a big part of the fun of traveling is a chance to try the language.

It is the same with computers. By knowing BASIC (an intermediate language), you're already halfway there. BASIC is akin to Pidgin, which was developed to help English-speakers to communicate with Chinese and Melanesian people (that's your history lesson for today).

Let us use a system similar to that used by many modern language schools - we'll learn to 'say' something useful, without worrying for the moment about vocabularies and the rules of the grammar. Like the beginning language student, or someone playing the violin by ear, we'll know how to make that single statement, but we won't be able to apply that knowledge to any other situation for some time yet. Don't panic though, we'll learn the rules as we go along. It's just that you might not lose interest so fast if we teach you to do something first.

Start by keying in the rudimentary loader program shown in figure 1-1. SAVE this program. We're going to use it several times, and it's a better than even bet that you will damage it before you get through with this lesson.
to be continued...
Attachments
Page 8.jpg
User avatar
XavSnap
Posts: 1940
Joined: Sat May 10, 2008 4:23 pm
Location: 'Zx81 France' Fb group.

Re: BASIC MACHINE CODE FOR THE ZX81

Post by XavSnap »

More infos on "SyncWare News"... to help GOOGLE.
Thanks David, it's a pretty cool series of articles.
Full of mysterious machine code listings.
Xavier ...on the Facebook groupe : "Zx81 France"(fr)
David G
Posts: 387
Joined: Thu Jul 17, 2014 7:58 am
Location: 21 North, 156 West

Re: BASIC MACHINE CODE FOR THE ZX81

Post by David G »

Xav, your SyncWare News Type-In Campaign brought this newsletter to my attention. Later I will update the Type-Ins campaign. For now, I am going through the BASIC MACHINE CODE series and trying out all the examples, trying to understand how they work


...CHAPTER 1 continued

Page 9
THE 1 REM STATEMENT

The backbone of this machine code program is a 1 REM statement, which holds the individual instructions of the program. You won't recognize them unless you already know the language, but they're there just the same.

We start out with a rough draft of the statement, as shown in figure 1-2. Figure 1-2 A shows the statement itself, while figure 1-2B tells you how it's built. The symbol '(GR S)' means 'Graphics S' (shift 9, shift S), and so on.

Code: Select all

FIG. 1-2. 1 REM for Progtop - First Draft

   1 REM ..½RNDY.W5.¶RND7û4.7. FA
ST 7...PI LPRINT S..TAN 

A. How It Looks

   1 REM . . (GR S) RND Y . W 5 
(GR W) RND 7 y 4 . 7 . FAST 7 .
 . . PI LPRINT S . . TAN 

B. How It Is Done
i struggled to enter the REM line as shown typed out here. Does anyone know how to enter keywords like FAST in the middle of a REM line? I have forgotten the technique ...

Fig 1-2. 1 REM for Progtop - First Draft
Fig 1-2. 1 REM for Progtop - First Draft

Code: Select all

FIG. 1-1. The Rudimentary Loader

10 REM PROOFREADING THE PROGRAM
20 FOR F=16514 TO 16527
30 PRINT F;TAB 7;PEEK F;TAB 11;CHR$ PEEK F;
40 PRINT TAB 16;(F+14);TAB 23;PEEK (F+14);TAB 27;CHR$ PEEK (F+14)
50 NEXT F
60 STOP
100 REM POKEING THE VACANCIES
110 INPUT A
120 PRINT A;TAB 6;
130 LET A=A+16500
140 INPUT B
150 POKE A,B
160 PRINT PEEK A
170 GOTO 110
Fig_1-1_16K.p
ZX81 Type-in
(1.23 KiB) Downloaded 117 times
With the 1statement roughed in, proofread it by GOTO 10. You should get the read out shown in figure 1-3. If not, then EDIT and make the necessary changes.

Code: Select all

16514  27  .    16528  35  7
16515  27  .    16529  27  .
16516  10  _    16530  229 FAST
16517  64  RND  16531  35  7
16518  62  Y    16532  27  .
16519  27  .    16533  27  .
16520  60  W    16534  27  .
16521  33  5    16535  66  PI
16522  130 [    16336  225 LPRIN
T
16523  64  RND  16537  56  S
16524  35  7    16538  27  .
16525  190 y    16539  27  .
16526  32  4    16540  201 TAN
16527  27  .    16541  118 ?

Fig. 1-3. Proofreading the Provisional 1 REM
Fig. 1-3. Proofreading the Provisional 1 REM
Fig. 1-3. Proofreading the Provisional 1 REM

Next up: Finishing the 1 REM and exploring what its machine code does, it's a bit wondrous
User avatar
mrtinb
Posts: 1906
Joined: Fri Nov 06, 2015 5:44 pm
Location: Denmark
Contact:

Re: BASIC MACHINE CODE FOR THE ZX81

Post by mrtinb »

To type undisplayable words, you start with a THEN, and add the word, and delete the THEN afterwards.
Martin
https://zx.rtin.be
ZX81, Lambda 8300, Commodore 64, Mac G4 Cube
David G
Posts: 387
Joined: Thu Jul 17, 2014 7:58 am
Location: 21 North, 156 West

Re: BASIC MACHINE CODE FOR THE ZX81

Post by David G »

thanks Martin, that technique works

Code: Select all

1 REM [shift-3]
Now i see that any of the red words (on the ZX81 keyboard) can be entered with SHIFT. Including FAST and LPRINT


To enter PI, first use FUNCTION key (shift-ENTER/NEWLINE)

Code: Select all

1 REM [shift-NEWLINE, M]
FUNCTION works for any of the keywords on the bottom of the keys
David G
Posts: 387
Joined: Thu Jul 17, 2014 7:58 am
Location: 21 North, 156 West

Re: BASIC MACHINE CODE FOR THE ZX81

Post by David G »

FILLING THE VACANCIES

There are some bytes of the program that can't be easily entered from the keyboard, which for the moment we have denoted by dots, to serve as placeholders. The subprogram at line 100 will help us to fill these vacancies with the proper numbers. Enter GOTO 100, and key in the numbers given in figure 1-4. When you have finished, input Z to break with an error 2/110.

Code: Select all

Fig. 1-4. Poking The Vacancies

14 237
15 75
19 117
27 252
29 86
32 94
33 235
34 237
38 241
39 119
Finally, proofreading via GOTO 10, should get the readout of figure 1-5. Check it carefully, and correct any mistakes. (Use CONT to see the rest of the listing.)

You'll notice that a new column of information has been added. This column, which gives what are known as mnemonics, will not be on the display. It is given to help those of you who already know something about machine code to analyze the program. Don't worry if it all looks like gibberish to you. All will become clear in due course.
Fig. 1-5. Proofreading the Final 1 REM
Fig. 1-5. Proofreading the Final 1 REM

WHAT DOES IT DO?

So now that we have the program set up, what can we do with it? Well, try setting the cursor to line 150 and RAND USR 16514. LIST the program. Try it again with the cursor set on line 100. Add other lines, such as 2000 REM, 6900 REM, etc., and try lopping them off, one by one.

PROGTOP_16K.P
PROGTOP (final program of Chapter 1)
(1.21 KiB) Downloaded 148 times

I call this program PROGTOP, because it sets a top on the program (similar to ram top for the top of ram), and it can be very handy. So now you have an idea of the economy and speed of machine code. Remember, the program for all of that lopping off is in the 27 bytes of the 1 REM. Bit by bit, as you read this series, you'll find out what's going on in that line.

There's one big difference between your computer and a resident of Barcelona. If you say 'soy listo' in a restaurant on the Ramblas, the waiter will smile and say to himself: "This turista says that he is a clever guy, but que va! He really means 'estoy listo' - that he's ready." It's NOT the same with your computer. As in BASIC, since the computer is a literal minded creature, it does what you tell it and not what you meant. What you say is what you get. There's a fortune waiting for the person who invents a workable DWIM (do what I mean) button. The trouble is, just as machine code is more powerful than BASIC, the significance of your mistakes is multiplied as well.

EQUIPMENT NEEDED

The material in this series is designed for all ZX-80(8K) through TS1500 computers (some of the listings will work on the 2068 with appropriate address changes although untested at this time). Please read ZX81 to include the entire family.

Since machine code deals directly with the CPU - Central Processing unit - the basic principles here apply to any Z80 based computer. However, access to the CPU may be different from one computer to another. You should have 16K or more of RAM in order to use the loader programs to be described, along with tape or disc equipment for SAVEing programs. I strongly urge you to use a notebook and pen to keep permanent notes. If you learn anything at all from this series, then you're likely to find yourself consulting your notes again and again.

STUDY MATERIALS

There are two books that I have found invaluable. One is the instruction manual that came with my ZX81, especially the few pages that list the ZX81 character set (ZX81ers beware of the graphic character typo in your manual). The other is the outstanding "Programming the Z80" by Rodney Zaks (Sybex Inc., 2344 Sixth St. Berkely, Ca. 94710). This is a scary book, because of it's large scope. I hope however, that by the time you have finished reading this series, you'll find Mr. Zaks' volume comprehensible as well as comprehensive.

One other study technique is to get out all those magazine articles on machine code programming that you passed over the first time around. Read them again, in the light of what you will be learning here. Analyze the programs presented, adapt them to your own needs and improve them if you can, See you next time.
thoughts:
  • Did Basil invent the term DWIM way back in 1984?
  • I had the Rodney Zaks Z80 book. Yeah it wasn't the best but it was BIG. I kept it next to my ZX81 along with the ZX81 BASIC manual and the programmer's Reference Card. The folding card was the most-used
  • What is the "graphic character typo" in the ZX81 manual? [edit: discussed here]
and
  • what does Progtop actually do??? Explore and try it
Last edited by David G on Wed Aug 03, 2022 11:14 pm, edited 1 time in total.
User avatar
1024MAK
Posts: 5101
Joined: Mon Sep 26, 2011 10:56 am
Location: Looking forward to summer in Somerset, UK...

Re: BASIC MACHINE CODE FOR THE ZX81

Post by 1024MAK »

Yeah, the keyboard operation for entering BASIC keywords, functions, operators and symbols on both the ZX81 and the ZX Spectrum 16K/48K/+ are similar, but slightly different.

Although where they are on the keyboards between the Zeddy and the Speccy are different and still catches me out…

Mark
ZX81 Variations
ZX81 Chip Pin-outs
ZX81 Video Transistor Buffer Amp

:!: Standby alert :!:
There are four lights!
Step up to red alert. Sir, are you absolutely sure? It does mean changing the bulb :!:
Looking forward to summer later in the year.
User avatar
1024MAK
Posts: 5101
Joined: Mon Sep 26, 2011 10:56 am
Location: Looking forward to summer in Somerset, UK...

Re: BASIC MACHINE CODE FOR THE ZX81

Post by 1024MAK »

David G wrote: Wed Jul 20, 2022 11:16 pm
  • What is the "graphic character typo" in the ZX81 manual?
I can’t remember, I tend to use the keyboard on the machine to work out which graphic character I want, but the there are multiple versions/reprints, so a mistake may not appear in later versions/reprints.

Mark
ZX81 Variations
ZX81 Chip Pin-outs
ZX81 Video Transistor Buffer Amp

:!: Standby alert :!:
There are four lights!
Step up to red alert. Sir, are you absolutely sure? It does mean changing the bulb :!:
Looking forward to summer later in the year.
David G
Posts: 387
Joined: Thu Jul 17, 2014 7:58 am
Location: 21 North, 156 West

Chapter 1 summary - BASIC MACHINE CODE FOR THE ZX81

Post by David G »

thoughts/conclusion/summary

I found it difficult to enter this program from the type-in listing. A large part of this difficulty is in the way SyncWare News layed out the article, with the Figures not in the instructions where needed, but all together at the end. And partly due to how Basil showed the REM line. We shall see in subsequent chapters how he improves this rudimentary loader into a very, very nice type-in technique


Basil uses the old guideline of "don't put a NEWLINE in your REM statement". But his code uses NEWLINE (118). So his code has a 117 (one less than NEWLINE) and then at run time increments it to 118. This allows the BASIC program to LIST normally (if there was a 118 in the REM, LIST would stop there, and to LIST the rest of the program you'd need to type LIST 2)

So what does the PROGTOP Machine Code do? The MC takes the Line Number of a BASIC line and puts a NEWLINE in it's place -- not to end the line, but as the Line Number. Unexpectedly, this "hides" the top lines. They are still there, but won't LIST, EDIT or GOTO. Sort of a curious effect of ZX81 BASIC

He might use this as a starting point for a more useful Machine Code (MC) routine later in the series. As the series continues, we shall see ...
Page 8 scan
Page 8 scan
Page 9 scan
Page 9 scan
Page 10 scan
Page 10 scan


For those who know machine code, or those who are curious, here are my comments on the code:

Code: Select all

1 REM _asm
  // Disassembly: 27 bytes @ $4082 (16514)
         LD      BC,(E_PPC)  ;$400A Number of current line (with program cursor)
         LD      A,75H       ;one less than NEWLINE
         INC     A           ;make it NEWLINE  ($76/118)
         LD      HL,4082H    ;PROGRAM+5 ;address of first character of REM 1 (after the REM)
    LOOP:INC     HL
         CP      (HL)        ;Look for the NEWLINE
         JR      NZ,LOOP     ;loop until found
         INC     HL
         LD      D,(HL)      ;Load DE with the found Line Number
         PUSH    HL          ;save Line Number address
         INC     HL
         LD      E,(HL)
         EX      DE,HL
         SBC     HL,BC       ;(E_PPC) Current Line Number
         POP     HL          ;Restore
         JR      C,LOOP      ;not matching, look again
         LD      (HL),A      ;put a NEWLINE as the first byte of the Line Number. This would make it LINE 30208 + (118*256) which is invalid (lines go up to 9999 in ZX81 BASIC)
         RET                 ;The NEWLINE will cause LIST to stop listing the program, effectively hiding all lines from here to the end
 END _asm
David G
Posts: 387
Joined: Thu Jul 17, 2014 7:58 am
Location: 21 North, 156 West

Chapter 2 - BASIC MACHINE CODE

Post by David G »

Ch. 2 - BASIC MACHINE CODE FOR THE ZX81

BASIC MACHINE CODE FOR THE ZX81 A beginner's series

CHAPTER 2
* PEEK, POKE & USR
* ZX/TS Memory
* ZX/TS Character Set
* The USR Command

from SyncWare News Volume 2 Number 2 pages 9-10
BASILS' COMPENDIUM

John (Basil) Wentworth
1413 Elliston Drive
Bloomington, In. 47401

PEEK, POKE & USR

This chapter will review the operation of the ZX81 memory, it will discuss PEEK and POKE and it will introduce the USR command.

First, let's take a look at another utility program on a "play-by-ear" basis, just to keep up the interest. This one is the classic line renumber program. (Fred Nachbaur would call it a half-program, since it does not make appropriate adjustments in GOTO and GOSUB destinations, but it's still pretty impressive--especially when you remember that it is only 34 bytes long.)

Now, enter the "rough draft" 1 REM line shown in Figure 2-1,
Fig 2-1 REM FOR RENUMBER -FIRST DRAFT-
Fig 2-1 REM FOR RENUMBER -FIRST DRAFT-

and proof read it via the rudimentary loader program of Figure 2-2, (Keep in mind that it will not run until all the periods (.) have been poked with the data in table 2-4. The first column is the address + 16500 and the second column is the data to be poked.-ed.) You'll find the loader a little different from the one in the last issue, in that only one column of figures is displayed now. There's nothing sinister in this change — it's just that the new form is easier to work with when it has to handle a number of different programs. The number of bytes has also been changed, of course, to fit the length of the new program.

Code: Select all

FIGURE 2-2. THE RUDIMENTARY LOADER

  10 REM PROOFREADING THE PROGRAM
  20 FOR F=16514 TO 16547
  30 PRINT F;TAB 6; PEEK F;TAB 10;CHR$ PEEK F
  40 NEXT F
  50 STOP
 100 REM POKEING THE VACANCIES
 110 INPUT A
 120 PRINT A;TAB 6;
 130 LET A=A+16500
 140 INPUT B
 150 POKE A,B
 160 PRINT PEEK A
 170 GOTO 110
After you've proofread the line (Figure 2-3),
Fig 2-3 PROOFREADING THE PROVISIONAL 1 REM
Fig 2-3 PROOFREADING THE PROVISIONAL 1 REM

POKE in the vacancies, as shown in Figure 2-4,

Code: Select all

  FIGURE 2-4.
POKING THE VACANCIES

 ADRESS VALUE
 +16500
  21  117
  26  252
  33  248
  34  112
  36  113
  42  68
  43  77
  45  195
and proofread the final version as per Figure 2-5.
Fig 2-5 PROOFREADING THE FINAL 1 REM
Fig 2-5 PROOFREADING THE FINAL 1 REM

Now you'll find that the command, RAND USR 16514, changes all your program lines into a neat sequence. It probably louses up your whole program if it has any GOSUBs or GOTOs in it though.

If you want a different line number sequence, you can change the interval between line numbers by POKEing the desired number into 16539. You can change the number of the second line by POKEing your desires to 16515. (All line numbers must be less than 256, of course.) Line number one will remain unchanged, no matter what you do with the program. Now, back to our general discussion.

ZX/TS Memory

You will remember that your computer stores information in the form of "bytes," each of which is an integer between 0 and 255, inclusive. Every time you press a key (except for SHIFT, DELETE, and such), that keystroke is translated into the appropriate byte, and stored in memory. (Sometimes the computer volunteers a few extra bytes that you didn't ask for. We'll call them "housekeeping" bytes, and discuss them later on.)

To see what these bytes look like, enter and RUN the mini-program shown in Figure 2-6. Note that 16509 is the address of the first byte of the program.

16509 is the address of the first program byte. That's a number worth remembering!

Code: Select all

FIGURE 2-6. A PEEK AT THE MEMORY

 200 FOR M=16509 TO 19558
 210 PRINT PEEK M;" ";
 220 NEXT M
What you see on the screen is the contents of the first 50 bytes in the program area of the RAM. With a few exceptions, these bytes correspond to the keystrokes that you entered. These exceptions, the housekeeping bytes that we mentioned above, are very important to the writer of machine code. Don't worry, we'll get around to them before too long.

The PEEK command lets you look at the contents of any memory location. POKE, on the other hand, lets you change the contents of any RAM location you choose, to any number you specify (0 to 255 inclusive).

To watch POKE at work, leave the program of Figure 2-6 in the computer, and enter the command:

Code: Select all

POKE 16518,35
You'll find that line ten [sic:200] has been changed to read:

Code: Select all

 200 FOR M=16709 TO 16558
To see the significance of the bytes stored in memory, restore line 10 [200] to its original form, and change line 20 [210] to read:

Code: Select all

 210 PRINT CHR$ PEEK M;
RUN the program. Do you see the words and characters that you recognize from the program? The apparently meaningless stuff represents those "housekeeping" bytes.

ZX/TS Character Set

If your going to use the El Minimo Loader, described later on (which we have been using with our demonstration programs, without telling you about it), it will be useful for you to understand the computer's character set.

The entire set is printed in your Instruction book. Alternatively, you can look at the character corresponding to any number N (always 0 to 255, inclusive) by using the command:

Code: Select all

    PRINT CHR$ N
You can print out the whole set by the program in Figure 2-7, if you prefer.

To understand the POKE exercise you just went through, enter the command:

Code: Select all

    PRINT CHR$ 35
The computer will return the symbol 7. Maybe you have deduced that 16518 is the address of the digit that you just changed from 5 to 7.

The USR Command

The trigger for a machine code routine is the symbol USR (under the L key). USR must always be followed by a memory location telling the computer where to start executing the machine code. For the moment, let's represent that address by LL.

Whenever the computer senses this trigger, as in PRINT USR LL, RAND USR LL, LET A=USR LL or the like, it reacts like a Pavlovian dog, jumping into the memory at LL, and scooting through the program like a mad fiend, at a speed of tens of thousands of operations per second. If there are no instructions to the contrary, the sequence of operations will follow the program bytes in the order in which they occur.

If the program (as per listing) encounters the RETurn instruction (address 16529 or 16533), the computer will RETurn to BASIC. If there are no valid RETurn addresses (the Stack Pointer, SP, will contain the address that the computer will RETurn to), well, you are on your own. Stand by to pull the plug. At this point, of course, you have lost everything in memory. Believe me, it's easier to include RETurn (extra, well placed RETurns won't hurt you).

If the trigger command is PRINT USR LL, the machine code routine will end by printing the value of a variable (register) known as BC. More precisely, it will print:

Code: Select all

C + 256 * B
based on the values that the registers B and C have taken at the time the program RETurns to BASIC. If the USR command does not include PRINT, the output may be in the form of some other action based on the value of BC. For instance, GOTO, USR LL and LIST USR LL are both perfectly valid commands, as long as LL has a value that can be handled by the computer.

In all cases, the computer will enter the machine code at LL, execute the machine code until it meets a RETurn, and then try to execute the BASIC command, substituting the final value of BC for USR LL.

That's all for now, but there will be more.

Code: Select all

FIGURE 2-7. THE ZX81/TS1000 CHARACTER SET

 300 FOR M=0 TO 255
 310 PRINT CHR$ M;" ";
 320 NEXT M
Attachments
Fig_2-1_2K.p
The Provisional REM (RENUMBER program)
(587 Bytes) Downloaded 108 times
Post Reply