BASIC MACHINE CODE FOR THE ZX81
Re: BASIC MACHINE CODE FOR THE ZX81
Thanks David.
Xavier ...on the Facebook groupe : "Zx81 France"(fr)
Chapter 3 - BASIC MACHINE CODE
And now! A machine/code to turn text into inverse
Ch. 3 - BASIC MACHINE CODE FOR THE ZX81
BASIC MACHINE CODE FOR THE ZX81 A beginner's series
CHAPTER 3
* Type-in: the "play by ear" utility program
* Where to Put the Program
* What we Need
** to successfully store machine code in the BASIC program
** to enter and proofread it
** to have it run successfully
** to be able to modify and extend the code later
from SyncWare News Volume 2 Number 3 Jan.-Feb. '85 pages 21-23
Next, the article talks about POKEing the vacancies. To do that:
* GOTO 1500
* When the L prompt appears, type in the first number and press NEWLINE/ENTER
* Type the second number and NEWLINE
* when done, Enter a letter (e.g. X) to break out of the loop
strangely enough as the code is:DEC BC doesn't update the Z flag, yet it works. How is it able to work successfully?
* The article "Memotext in RAM" was by Fred Nachbaur of British Columbia.
Fred discusses about how to "Generate a REM..." meaning a long REM
* use a REM generator utility
* or ... Fred's Easy Way
Ch. 3 - BASIC MACHINE CODE FOR THE ZX81
BASIC MACHINE CODE FOR THE ZX81 A beginner's series
CHAPTER 3
* Type-in: the "play by ear" utility program
* Where to Put the Program
* What we Need
** to successfully store machine code in the BASIC program
** to enter and proofread it
** to have it run successfully
** to be able to modify and extend the code later
from SyncWare News Volume 2 Number 3 Jan.-Feb. '85 pages 21-23
There is a typo in that listing. It should be like this:BASIL'S COMPENDIUM
John (Basil) Wentworth
1413 Elliston Drive
Bloomington, In. 47401
Where to Put the Program
This chapter will list some requirements for the place where we will put the machine code, and will show you how to find a memory location that meets those requirements. But first, our "play by ear" utility program.
The "rough draft" 1 REM line and the proofreading program are shown in Figures 3-1 and 3-2, respectively
Code: Select all
FIGURE 3-1. 1 REM for BLACKTOP -FIRST DRAFT- HOW IT LOOKS 1 REM . CHR$ .E'RNDY.WUyC.Y..."4.TAN HOW IT IS DONE 1 REM (GR 1) CHR$ (GR 2) E (SHIFT SPACE) RND Y . W 7 (INVERSE Y) C . Y (INVERSE SPACE) (GR Y) . " 4 . TAN
When I typed it in, the typo become apparentand the readout for proofreading is in Figure 3-3.Code: Select all
FIGURE 3-2. THE RUDIMENTARY LOADER 1000 REM PROOFREADING THE PROGRAM 1020 FOR F=16514 TO 16534 1030 PRINT F;TAB 6;PEEK F;TAB 10 ;CHR$ PEEK F 1040 NEXT F 1050 STOP 1500 REM POKING THE VACANCIES 1510 INPUT A 1520 PRINT A; TAB 6; 1525 LET A=A+16500 1530 INPUT B 1540 POKE A,B 1550 PRINT PEEK A 1560 GOTO 1510
Next, the article talks about POKEing the vacancies. To do that:
* GOTO 1500
* When the L prompt appears, type in the first number and press NEWLINE/ENTER
* Type the second number and NEWLINE
* when done, Enter a letter (e.g. X) to break out of the loop
When that is done, RUN to proofread againAfter you POKE the vacancies, according to Figure 3-4,Code: Select all
FIGURE 3-4. POKING THE VACANCIES 21 117 26 252 30 119 33 242
Again, after typing it out, it looks different. CHR$ 12 is the Pound Sterling sign, not the apostrophe ('). I cannot think of how they generated the screenshot in the newsletter, there is no apostrophe on the ZX81! Is there?the final proofreading should checkout with Figure 3-5.
It works!I know that's awfully fast, but it's just a repeat of what you have done in the previous chapters. If you're still having a problem with this procedure, then get in touch with me directly. I'll be glad to be of service.
When you have the final 1 REM line in place, add the following two lines to your program:Then, GOTO 1000 and watch the fun.Code: Select all
1000 PRINT AT 10,3;"BASIL LOVES JOCELYN" 1010 RAND USR 16514
strangely enough as the code is:
Code: Select all
DEC BC
JR NZ,-14
END OF CHAPTER 3And now the lesson.
What We Need
Where in ram are we going to store our machine code? We must satisfy two conditions.
1. The machine code routine must not
interfere with the normal running of the
computer itself.
2. The running of the computer must not
interfere with the machine code.
Live and let live. For convenience, we'd like to impose a few more conditions, including:
3. The program should be easily entered,
proofread and edited.
4. It should be possible to SAVE the
program.
5. It should be expandable. We should be
able to add more subroutines as they become
necessary.
For the moment, let's shelve number 5, and concentrate on the first four conditions. We'll get back to number 5 later on.
Recall that the USR command must specify the starting address of the machine code routine. Much as GOTO and GOSUB have to be followed by a number (or an expression which the computer can evaluate as a number), so does the USR command require a number or expression equal to a number. This means that we'll have to know (or compute) the address of the first byte of machine code every time we want to invoke it.
"What do you mean, every time?" I hear you cry. "Doesn't my code stay put?" Well, that depends. Let's try a little experiment.
Suppose your program consists of a line of 27's. It never will, of course, but 27 is the code of a character that's easy to spot (pardon the pun; try PRINT CHR$ 27). Let's put a line of 27's into the computer. Try this:OOPS! The computer won't accept it. So, let's give in to the computer on this point, and use up an extra byte. Try:Code: Select all
10......
If you're really vindictive, POKE 16513,27. GOTCHA! There's that line that the computer wouldn't accept. Don't ever try to EDIT that line. It's much easier to include the REM. It takes up only one extra byte, doesn't get in the way and makes things much easier all around (like salvaging the program if you ever inadvertently get the line down into the edit position).Code: Select all
10 REM ......
So, now you have,Let's see what the memory contents look like. Use the program of Figure 3-6.Code: Select all
10 REM ......
See those 27's starting at 16514? Now add another line:Code: Select all
FIGURE 3-6. WHERE ARE THE 27'S? 10 REM ...... 100 FOR M=16509 TO 16530 110 PRINT M;" ";PEEK M 120 NEXT M
Run the program again. The 27's have moved up to memory locations starting at 16520! Change line 1 to:Code: Select all
1 REM
Run the program again and notice that the 27's have moved once again. Well, it's going to be pretty hard to find a starting address that keeps moving around, but don't give up.Code: Select all
1 REM ABC
Let's try something else. Delete line 1 and Run the program again. Not surprisingly, the 27's are back at 16514. Now, change the number of the REM from 10 to 1. Run it again. Notice that there is no change in the location of the 27's. Now, add:Run the program again and notice that there is still no change in position of the 27's.Code: Select all
10 REM ABC
And here's the conclusion that we draw from this maneuvering:
The address of the first byte in the
first statement of the program does not
depend on the line number of that
statement, nor is it changed by the
addition of any program lines numbered
higher than the first line.
So, what are you to do? Put your machine code in a 1 REM, and the first byte after the REM will always have the same address, namely 16514, unless of course, you put a 0 REM in front of it. (We're going to show you how and why to use line 0 one of these days.)
Ok, now let's do something stupid, just to demonstrate a point. Don't worry, it won't do any harm, other than to crash (guaranteed) the program in memory. So, if you have any program material that you care about, SAVE it now, before continuing.
Ready? Enter the lineand then POKE 16514,27. Now, LIST the program.Code: Select all
1 REM
Don't say that I didn't warn you. It's an interesting picture, but it's not the sort of program you want to use every day. You can't even get rid of it without turning off the computer.
What happened? Well, the computer was using 16514 for one of those "housekeeping" bytes (end of line marker), and was thrown off balance when you asked it to something else with that byte.
What we have to do is lay claim to some space for our machine code, and to do it before the computer starts using that space for its own purposes. The way we do this Is to fill all the bytes we need after the REM with characters of our own choosing. There are various ways to accomplish this (*see SWN 2/2, Memotext in ram or the article by Chuck Peterson on generating a big REM).
Enough preliminaries. Next time, we'll actually write a real (though simple) program in machine code.
* The article "Memotext in RAM" was by Fred Nachbaur of British Columbia.
Fred discusses about how to "Generate a REM..." meaning a long REM
* use a REM generator utility
* or ... Fred's Easy Way
If you had to type in an [eight thousand] 8K REM statement a character at a time, it would probably be enough to make you give up computing for good.
Fortunately, you can use a couple tricks to help matters immeasurably...
Re: Chapter 3 - BASIC MACHINE CODE
And the ZX81 Type-ins for Chapter 3
- Attachments
-
- BLACKTOP_Final_1K.p
- M/C demo that inverts text
- (232 Bytes) Downloaded 61 times
Re: Chapter 3 - BASIC MACHINE CODE
Maybe the American user thought a pound sign was useless to him, but really needed the apostrophe, to write American (where it's quite common). Maybe the author of the article just created an EPROM replacement for the ROM, where this single char was changed. Then it would be an apostrophe both on screen and on print. Maybe the EPROM replacement was well known in the user group, so it was accepted in their newsletter. I'm just speculating.David G wrote: ↑Wed Aug 03, 2022 11:45 pm Again, after typing it out, it looks different. CHR$ 12 is the Pound Sterling sign, not the apostrophe ('). I cannot think of how they generated the screenshot in the newsletter, there is no apostrophe on the ZX81! Is there?
Re: Chapter 3 - BASIC MACHINE CODE
That thought had crossed my mind, but I immediately discounted it as crazy
But this speculation makes it seem plausible. Maybe someone knows if they used custom EPROMs back in 1984
But this speculation makes it seem plausible. Maybe someone knows if they used custom EPROMs back in 1984
Maybe the EPROM replacement was well known in the user group, so it was accepted in their newsletter. I'm just speculating.
Chapter 4 - BASIC MACHINE CODE
BASIC MACHINE CODE FOR THE ZX81 A beginner's series
Chapter 4 - BASIC MACHINE CODE
This chapter I found difficult to understand. One problem is the figures are scattered around the text, not really Basil's fault but more of the newsletter layout. So here I've re-arranged the Figures in the text to flow better
The other problem with this chapter is Basil chose a learn-by-doing style. So I really had to work at these to understand them. In a previous thread we had trouble understanding the main type-in program from this chapter:
CHAPTER 4 from SyncWare News Volume 2 Number 4 Mar.-Apr. '85 pages 15-17
Chapter 4 - BASIC MACHINE CODE
This chapter I found difficult to understand. One problem is the figures are scattered around the text, not really Basil's fault but more of the newsletter layout. So here I've re-arranged the Figures in the text to flow better
The other problem with this chapter is Basil chose a learn-by-doing style. So I really had to work at these to understand them. In a previous thread we had trouble understanding the main type-in program from this chapter:
Well here it is in all it's glory (and within context of the full chapter). The program does work as described. With perseverance I have learned a few new tricks of m/c for the ZX81[Zx81:Type-Ins] "SyncWare News" campaign...
"BASIL's Compendium"
Syncware Newsv2.4
Not sure what it is... Scan the BASIC room to find a REM, scan a "<" in it then a ">" and destroy the MC h eader!
CHAPTER 4 from SyncWare News Volume 2 Number 4 Mar.-Apr. '85 pages 15-17
To be continued ...BASIL'S COMPENDIUM
John (Basil) Wentworth
1413 Elliston Drive
Bloomington, In. 47401
LET A= ...
This installment will teach you how to enter an actual program in machine code. But first, a "fun" program - a rather lengthy one, this time.
You'll notice that we have changed the loader program again, as shown in Figure 4-1. After the experience you've had in the first three chapters, you should be able to combine the operations of POKEing the vacancies and proofreading the program.
The program we're giving you this time will enable you to delete blocks of program material in a single operation. All you do is mark the beginning of the section to be deleted withand the end withCode: Select all
N1 REM >
where N1 and N2 are line numbers. Then RAND USR 16514 will lump all the material between the markers into one line which can be deleted at one go.Code: Select all
N2 REM <
The rough draft of the 1 REM statement is shown in Figure 4-2, and the final listing in Figure 4-3. While you're proofreading the statement, the display will stop for you wherever you have included a period, and wait for you to INPUT the final number (which may, of course, actually be 27). When the screen is full, just CONTINUE to get the following bytes.
As before, the mnemonics, which are included for the Information of more experienced programmers, will not appear on your listing.
One word of caution: DON'T use this program in the SLOW mode. It's very likely to crash if you do, since this program pre-empts some of the the computer's capabilities that are required to make the SLOW mode work.
Code: Select all
FIGURE 4-1. LOADER/PROOFREAD PROGRAM 1000 LET F=16513 1010 LET F=F+1 1020 PRINT F;" "; 1030 IF PEEK F<>27 THEN GOTO 1060 1040 INPUT A 1050 POKE F,A 1060 PRINT PEEK F,CHR$ PEEK F 1065 IF PEEK F=113 THEN STOP 1070 GOTO 1010
Code: Select all
FIGURE 4-2. ROUGH DRAFT OF 1 REM 1 REM '<>5}RNDYuW<>7<>û TAB ÁR ND<>û¡COS YREM <>û¬TAB ³RNDY><>û²TA B ãRND<>FAST AT W<>û²TAB ³RND<> FAST LPRINT GOSUB PI777VAL <>LPRINT <>t¤<>u¦TAN ' HOW IT LOOKS 1 REM <> 5 , RND Y . W <> 7 <> y (SPACE) TAB (GR G) RND <> y (GR 1) COS Y , <> y (GR 5) TAB (GR Y) RND Y > <> y (GR T) TAB c TAB (GR Y) RND <> FAST LPRINT , PI 7 7 7 VAL <> LPRINT <> . (GR 4) <> . (GR U) TAN HOW IT IS DONE
Now back to lessons.Code: Select all
FIGURE 4-3. FINAL LISTING OF 1 REM 16514 221 <> LD IX, 16515 33 5 16509 15516 125 ? 16517 64 RND 16518 62 Y LD A 16519 117 ? 117 16520 60 W INC A 16521 221 <> INC IX 16522 35 7 16523 221 <> CP (IX+0) 16524 190 y 16525 0 16526 194 TAB JP NZ, 16527 137 [BLACK/GRAY BARS]16521 16528 64 RND 16529 221 <> CP(IX+1) 16530 190 y 16531 1 16532 200 COS RET Z 16533 62 Y LD A, 16534 234 REM 234 16535 221 <> CP(IX+5) 16536 190 y 16537 5 | 16538 194 TAB JP NZ, 16539 134 [\ graphic] 16518 16540 64 RND 16541 62 Y LD A, 16542 18 > 18 16543 221 <> CP(IX+8) 16544 190 y 16545 6 / 16546 194 TAB JP NZ, 16547 168 c 16552 16548 64 RND 16549 221 <> PUSH IX 16550 229 FAST 16551 193 AT POP BC 16552 60 W INC A 16553 221 <> CP(IX+6) 16554 190 y 16555 6 [/ graphic] 16556 194 TAB JP NZ, 16557 134 [\ graphic] 16518 16558 64 RND 16559 221 <> PUSH IX 16560 229 FAST 16561 225 LPRINT POP HL 16562 237 GOSUB SBC HL,BC 16563 66 PI 16564 35 7 INC HL 15555 35 7 INC HL 16566 35 7 INC HL 16567 197 VAL PUSH BC 16568 221 <> POP IX 16569 225 LPRINT 16578 221 <> LD(IX+4),H 16571 116 ? 16572 4 [SW DOT] 16573 221 <> LD(IX+3),L 16574 117 ? 16575 3 [NORTH BAR] 16576 201 TAN RET
- Attachments
-
- FIG_4-3_1_REM_(MERGE_LINES).p
- (407 Bytes) Downloaded 61 times
Re: Chapter 4 - BASIC MACHINE CODE
This program "1 REM" is an odd one. I named it "MERGE LINES" because takes some of your program lines, which you have marked, it bunches them together under one line number. Which you can then delete all at once. Interesting, but is it useful? I'm guessing Basil will use this as a stepping stone to something further advanced ...
Re: Chapter 4 - BASIC MACHINE CODE (page 16)
Re: Chapter 4 - BASIC MACHINE CODE (page 16)
BASIC MACHINE CODE FOR THE ZX81 A beginner's series
CHAPTER 4 continued from SyncWare News Volume 2 Number 4 Mar.-Apr. '85 page 16
BASIC MACHINE CODE FOR THE ZX81 A beginner's series
CHAPTER 4 continued from SyncWare News Volume 2 Number 4 Mar.-Apr. '85 page 16
TO BE CONTINUED...Now back to lessons.
You've carved out some turf for yourself - so what do you do with it? You may remember an earlier declaration that the output of a machine language routine is what the computer calls BC; i.e.So how do we make B and C reflect any value that we can use?Code: Select all
C+256*B
For the moment, think of B and C as simple variables. What we want to do is to assign values to them. The Z80 machine code instructions that we want are:
LET B=m is 6,m
and LET C=n is 14,n
And RETURN, which we must not forget, is 201.
Note that the instructions (6,14) and the data (m,n) are mixed into the program. There is no difference between them, as far as mortal eye can see. The computer knows, though, from the context.
If it receives an instruction of 6 or 14, for instance, it'll interpret the next byte as data, whether you mean it to or not.
Now we're ready for our first, very simple, program. After reserving at least 5 nulls in a 1 REM statement (see the previous chapter, if you've forgotten how), POKE in the sequence shown in
Figure 4-4. Give the command PRINT (not RAND) USR 16514, and there's your answer: 256.Code: Select all
FIGURE 4-4. SETTING B AND C MEANING POKE 16514,6 LET B= POKE 16515,1 1 POKE 16516,14 LET C= POKE 16517,0 0 [POKE 16518,201 RET] PRINT USR 16514 PRINT 256*B+C
Now another one, as in Figure 4-5. Note that you don't have to delete the previous material - the new entries will overwrite the old bytes.
Before printing the output, what do you expect it to be? Enter PRINT USR 16514, and check your prediction.Code: Select all
FIGURE 4-5. SETTING B AND C MEANING POKE 16514,6 LET B= POKE 16515,0 0 POKE 16516,14 LET C= POKE 16517,1 1 [POKE 16518,201 RET] PRINT USR 16514 PRINT 256*B+C
It should have beenCode: Select all
256*B(=0)+C(=1)=1
Re: Chapter 4 - BASIC MACHINE CODE (page 16 continued)
BASIC MACHINE CODE FOR THE ZX81 A beginner's series
CHAPTER 4 continued from SyncWare News Volume 2 Number 4 Mar.-Apr. '85 page 16
CHAPTER 4 continued from SyncWare News Volume 2 Number 4 Mar.-Apr. '85 page 16
But all this POKEing is getting to be a bit tedious, isn't it? (You'll notice that I stalwartly resist the temptation to make a pun on poking fun.) Plus the danger of losing your place
and skipping a byte. With the further disadvantage that you can't proofread the program.Code: Select all
FIGURE 4-6. A SIMPLE LOADER 1 REM ........... 1000 FOR M=16514 TO 17000 1010 PRINT M; " ", 1020 INPUT A 1030 POKE M,A 1040 PRINT PEEK M 1050 NEXT M **** DON/T WORRY; WE WON/T USE ALL 457 BYTES. SEE THE TEXT ON THIS POINT.
It has probably already occurred to you that this is an appropriate place to use a loop. So let's build a very simple loader program, like the one in Figure 4-6.
To try it out, let's go through the two programs we wrote above. First, RUN the program of Figure 4-6, and then INPUT in succession:The Z, or any other letter that the computer will not interpret as a number (NOT M or A, which have already been assigned values by the computer), will cause the program to STOP, with an error report of 2/1120, meaning "I don't recognize that as a defined value for A". And that's the way you get out of the loop without having to go through all 487 INPUTS.Code: Select all
6,1,14,0,201,Z
Now you have the contents of the whole 1 REM statement displayed on the screen, as shown in Figure 4-7, so you can proofread it - including making sure that it includes the all-important 201, for RETURN. If it's the way you want it, PRINT USR 16514. And there's the 256, just as before.Code: Select all
FIGURE 4-7. PROOFREADING 16514 6 16515 1 16516 14 16517 0 16518 201
If you do find an error in the program, POKE in the proper value, as, for instance, POKE 16516,14. If your program is to be more than 22 bytes long, use CONTINUE when the screen is filled. Or you can add 1005 SCROLL, if you prefer.
If you want to proofread a program after POKEing in a correction, use the following procedure:
1. Disable lines 1030 and 1040. You can do this either by deleting the lines or by inserting a REM at the beginning of each line, right after the line number.
2. If you have included a SCROLL, either disable it or put the computer into SLOW mode.
3. RUN the program.
Chapter 4 - BASIC MACHINE CODE: El Minimo
BASIC MACHINE CODE FOR THE ZX81 A beginner's series
CHAPTER 4 conclusion from SyncWare News page 17
* To enter graphics mode: press GRAPHICS (which is SHIFT-9)
* To enter "CODE 1" from the chart (where it says "GR 1"), press SHIFT-1
* In the brackets is my description of the graphics symbol (in SyncWare it uses a picture of the symbol)
CHAPTER 4 conclusion from SyncWare News page 17
Here's my take on how to enter the special characters:El Minimo
The following experiment will help you to understand what goes on when you store your machine code in REM. It'll also give you a clue to the way we've been writing those "fun" programs at the head of each chapter.
I call this loading technique "EL MINIMO" because it's just about the most compact program loading system possible.
EnterIf you'll look at the listing of the character set in your manual, or if you'll check each character by PRINT CODE "...", you'll find that the codes of these respective characters are, to nobody's surprise, 6,0,14,1, and 201.Code: Select all
1 REM (Gr T) (space) : (Grl) TAN
This is in fact the series of numbers that has been entered into memory, starting at 16514.
Try PRINT USR 16514 for this program, and again after you have exchanged the places of the 0 and the 1.
You may find it more convenient to use this technique for building up your 1 REM statement, as we have been doing in the "fun" programs. If so, you'll find it useful to add a little more information to your ZX81 manual. You'll notice that the table of the character set as listed in the manual shows the graphics symbols for Codes 1-10 and 128-138 (with an error in the entry for 135, at least in my copy). However, it's not too easy to find these symbols on the keyboard, so I wrote into the manual the keystroke needed to produce each of these symbols. They're listed in Figure 4-8.
Incidentally, if you want to enter keywords, like RUN (CHR$ 247), REM (234), FOR (235), and the like directly from the keyboard, you can do it by preceding the character with THEN, which conditions the ZX81 to interpret the next keystroke as a command. You'll have to delete the THENs from the final program, of course.
And that's it for now. There will be more.
* To enter graphics mode: press GRAPHICS (which is SHIFT-9)
* To enter "CODE 1" from the chart (where it says "GR 1"), press SHIFT-1
* In the brackets is my description of the graphics symbol (in SyncWare it uses a picture of the symbol)
Code: Select all
FIGURE 4-8. KEYING THE GRAPHICS SYMBOLS
CODE CHR$ KEYSTROKE
0 ' ' SPACE
1 [NW DOT] GR 1
2 [NE DOT] GR 2
3 [NORTH BAR] GR 7
4 [SW DOT] GR 4
5 [WEST BAR] GR 5
6 [SLASH] GR T
7 [INVERSE SW DOT] GR E
8 [GRAY SQUARE] GR A
9 [GRAY SOUTH BAR] GR D
10 [GRAY NORTH BAR] GR S
128 [BLACK SQUARE] INV SPACE
129 [INVERSE NW DOT] GR Q
130 [INVERSE NE DOT] GR W
131 [SOUTH BAR] GR 6
132 [INVERSE SW DOT] GR R
133 [EAST BAR] GR 8
134 [BACKSLASH] GR Y
135 [SE DOT] GR 3
136 [INVERSE GRAY SQUARE] GR H
137 [BLACK/GRAY BARS] GR G
138 [GRAY/BLACK BARS] GR F