Machine Language: First Steps
This concludes a three-part series on getting started in machine language.
In the two previous episodes, our intrepid hero, F. R. Vescent, has coded the following bar graph program in machine language:
027A A2 30 LDX #$30 027C A0 00 LDY #$00 027E E8 YLOOP INX 027F E0 3A CPX #$3A 0281 D0 02 BNE SKIP 0283 A2 30 LDX #$30 0285 8A SKIP TXA 0286 20 D2 FF JSR $FFD2 0289 C8 INY 028A CC 00 03 CPY $0300 028D 90 EF BCC YLOOP 028F A9 0D LDA #$0D 0291 20 D2 FF JSR $FFD2 0294 60 RTS
After finishing the coding job, he enters it into memory using the machine language monitor like this:
.: 027A A2 30 A0 00 E8 E0 3A D0 .: 0282 02 A2 30 8A 20 D2 FF C8 .: 028A CC 00 03 90 EF A9 0D 20 .: 0292 D2 FF 60 .. .. .. .. ..
With the machine language program in place, F. R. returns to BASIC and writes:
200 DATA 15, 10, 30, 35, 28, 28, 15, 0 210 READ V : IF V = 0 GOTO 300 220 POKE 768, V 230 SYS 634 270 GOTO 210 300 END
The program runs properly, but the machine language is in the first cassette buffer, and this makes it hard to SAVE. F. R. uses the following piece of trickery to make the ML coding more tractable: He types:
FOR J = 634 TO 660 : PRINT PEEK(J) ; : NEXT J
634 is the address of the start of the ML program ($027A) and 660 is the address of the last byte ($0294). So what F. R. is doing is writing a line to cause the program to be dumped, byte by byte, to the screen. He will get something like:
162 48 160 0 232 224 58...
There will be two spaces between each pair of numbers. Now F. R. does some clever screen editing. He places the cursor just before the 4 of 48, and presses the DEL key and the comma. Now the two numbers read 162,48 ... and F. R. moves the cursor ahead to just before the 160 and repeats the sequence. Eventually, he gets a long line of numbers with commas between. He does not press RETURN, but backs up to the beginning of the line and types several Insert keys; now he has room to enter the extra information "110 DATA". Now he presses RETURN and the bytes of his machine language program are entered as part of a DATA statement.
There's another line left over and he must repeat the editing sequence to create a 120 DATA ... line and complete the DATA recording of his program. Now he types in line 100:
100 FOR J = 634 TO 660 : READ M : POKE J, M : NEXT J
The whole program should now read:
100 FOR J = 634 TO 660 : READ M : POKE J, M : NEXT J 110 DATA 162, 48, 160, 0, 232, 224, 58, 208, 2, 162, 48, 138, 32, 210, 255, 200, 204, 0 120 DATA 3, 144, 239, 169, 13, 32, 210, 255 200 DATA 15, 10, 30, 35, 28, 28, 15, 0 210 READ V : IF V = 0 GOTO 300 220 POKE 768, V 230 SYS 634 270 GOTO 210 300 END
Now: whenever we say RUN, the machine language program is POKEd into place (line 100) before the main program uses it. We may now safely SAVE the BASIC program to tape or disk without worrying about how to save the machine language part. The BASIC program makes its own machine language where it needs it.
Serious programmers will think of more efficient ways to convert the program into easily SAVEable code. More advanced machine language programmers will find better ways than DATA statements. But this is a start.
We've traced a machine language program through its conception, assembly, and implementation. It's not too hard a job, and there are aids to help you along the way.
This example was picked because it presented a fairly easy challenge. Even so, it took us three installments to see it through. The bigger jobs are not much harder; most of the work was in the housekeeping.
For beginners who have never followed the whole process through, it's a worthwhile exercise. Once you've seen the trick done, you can see how to do your own.