Why Machine Language?
Sooner or later, many programmers find that they want to learn machine language. BASIC is a fine general-purpose tool, but it has its limitations. Machine language (often called assembly language) performs much faster. BASIC is fairly easy to learn, but most beginners do not realize that machine language can also be easy. And, just as learning Italian goes faster if you already know Spanish, if a programmer already knows BASIC, much of this knowledge will make learning machine language easier. There are many similarities.
This book is designed to teach machine language to those who have a working knowledge of BASIC. For example, Chapter 9 is a list of BASIC statements. Following each is a machine language routine which accomplishes the same task. In this way, if you know what you want to do in BASIC, you can find out how to do it in machine language.
To make it easier to write programs in machine language (called "ML" from here on), most programmers use a special program called an assembler. This is where the term "assembly language" comes from. ML and assembly language programs are both essentially the same thing. Using an assembler to create ML programs is far easier than being forced to look up and then POKE each byte into RAM memory. That's the way it used to be done, when there was too little memory in computers to hold languages (like BASIC or Assemblers) at the same time as programs created by those languages. That old style hand-programming was very laborious.
There is an assembler (in BASIC) at the end of this book which will work on most computers which use Microsoft BASIC, including the Apple, PET/CBM, VIC, and the Commodore 64. There is also a separate version for the Atari. It will let you type in ML instructions (like INC 2) and will translate them into the right numbers and POKE them for you wherever in memory you decide you want your ML program. Instructions are like BASIC commands; you build an ML program using the ML "instruction set." A complete table of all the 6502 ML instructions can be found in Appendix A.
It's a little premature, but if you're curious, INC 2 will increase the number in your computer's second memory cell by one. If the number in cell 2 is 15, it will become a 16 after INC 2. Think of it as "increment address two."
Throughout the book we'll be learning how to handle a variety of ML instructions, and the "Simple Assembler" program will be of great help. You might want to familiarize yourself with it. Knowing what it does (and using it to try the examples in this book), you will gradually build your understanding of ML, hexadecimal numbers, and the new possibilities open to the computerist who knows ML.
Seeing It Work
Chapters 2 through 8 each examine a major aspect of ML where it differs from the way BASIC works. In each chapter, examples and exercises lead the programmer to a greater understanding of the methods of ML programming. By the end of the book, you should be able to write, in ML, most of the programs and subroutines you will want or need.
Let's examine some advantages of ML, starting with the main one - ML runs extremely fast.
Here are two programs which accomplish the same thing. The first is in ML, and the second is in BASIC. They get results at very different speeds indeed, as you'll see:
169 1 160 0 153 0 128 153 0 129 153 130 153 0 131 200 208 241 96
5 FOR I=1 TO 1000: PRINT "A";: NEXT I
These two programs both print the letter "A" 1000 times on the screen. The ML version takes up 28 bytes of Random Access Memory (RAM). The BASIC version takes up 45 bytes and takes about 30 times as long to finish the job. If you want to see how quickly the ML works, you can POKE those numbers somewhere into RAM and run the ML program with a SYS (Commodore computers) or USR (Atari) or CALL (Apple). In both BASIC and ML, many instructions are followed by an argument. The instructions SYS and CALL have numbers as their arguments. In these cases, the instruction is going to turn control of the computer over to the address given as the argument. There would be an ML program waiting there. To make it easy to see this ML program's speed, we'll load it into memory without yet knowing much about it.
A disassembly is like a BASIC program's LISTing. You can give the starting address of an ML program to a disassembler and it will translate the numbers in the computer's memory into a readable series of ML instructions. See Appendix D for a disassembler that you can use to examine and study ML programs.
Here's what the PET/CBM version looks like when it has been translated by a disassembler:
Program I-I. Disassembly.
., 0360 A9 01 LDA #$01
., 0362 A0 00 LDY #$00
., 0364 99 00 80 STA $8000,Y
., 0367 99 00 81 STA $8100,Y
., 036A 99 00 82 STA $8200,Y
., 036D 99 00 83 STA $8300,Y
., 0370 C8 INY
., 0371 D0 F1 BNE $0364
., 0373 60 RTS
The following BASIC programs (called loaders) POKE the ML instructions (and their arguments) into memory for you:
Program 1-2. PET Version.
1 REM PET VERSION
800 FOR AD=864TO883:READ DA:POKE AD
810 PRINT"SYS 864 TO ACTIVATE"
Program 1-3. VIC Version.
1 REM VIC VERSION
800 FOR AD=864TO885:READDA:POKEAD,D
805 PRINT"SYS 864 TO ACTIVATE"
810 DATA 160, 0, 169, 1, 153, 0
820 DATA 30, 153, 0, 31, 169, 6
830 DATA 153, 0, 150, 153, 0, 151
840 DATA 200, 208, 237, 96
Program 1-4. 64 Version.
Newer model 64's need to have the color registers set before running this program to see the effect on the full screen.
1 REM COMMODORE 64 VERSION
800 FOR AD=40000TO40019:READDA:POKE
805 PRINT"SYS 40000 TO ACTIVATE"
Program 1-5. Apple Version.
100 FOR I = 770 TO 789: READ A: POKE I,A: NE
110 PRINT "CALL 770 TO ACTIVATE "
120 DATA 169,129,162,0,157,0,4,157,0,5,157,0
Program 1-6. Atari Version.
100 FOR I=1536 TO 1561:READ A:POKE I,A:NEXT I
110 PRINT "A=USR(1536) TO ACTIVATE "
120 DATA 165,88,133,0,165,89,133,1,169
130 DATA 33,162,4,160,0,145,0,200,208,251,230
140 DATA 1,202,208,244,104,96
After running this program, type the SYS or USR or CALL as instructed and the screen will instantly fill. From now on, when we mention SYS, Atari owners should mentally substitute USR and Apple owners should think CALL.
BASIC stands for Beginners All-purpose Symbolic Instruction Code. Because it is all-purpose, it cannot be the perfect code for any specific job. The fact that ML speaks directly to the machine, in the machine's language, makes it the more efficient language. This is because however cleverly a BASIC program is written, it will require extra running time to finish a job.
For example, PRINT involves BASIC in a series of operations which ML avoids. BASIC must ask and answer a series of questions. Where is the text located that is to be PRINTed? Is it a variable? Where is the variable located? How long is it? Then, it must find the proper location on the screen to place the text. However, as we will discover, ML does not need to hunt for a string variable. And the screen addresses do not require a complicated series of searches in an ML program. Each of these tasks, and others, slow BASIC down because it must serve so many general purposes. The screen fills slowly because BASIC has to make many more decisions about every action it attempts than does ML.
Inserting ML For Speed
A second benefit which you derive from learning ML is that your understanding of computing will be much greater. On the abstract level, you will be far more aware of just how computers work. On the practical level, you will be able to choose between BASIC or ML, whichever is best for the purpose at hand. This choice between two languages permits far more flexibility and allows a number of tasks to be programmed which are clumsy or even impossible in BASIC. Quite a few of your favorite BASIC programs would benefit from a small ML routine, "inserted" into BASIC with a SYS, USR, or CALL, to replace a heavily used, but slow, loop or subroutine. Large sorting tasks, smooth animation, and many arcade-type games must involve ML.
BASIC Vs. Machine Language
BASIC itself is made up of many ML programs stored in your computer's Read Only Memory (ROM) or sometimes loaded into RAM from disk. BASIC is a group of special words such as STOP or RUN, each of which stands for a cluster of ML instructions. One such cluster might sit in ROM (unchanging memory) just waiting for you to type LIST. If you do type in that word, the computer turns control over to the ML routine which accomplishes a program listing. The BASIC programmer understands and uses these BASIC words to build a program. You hand instructions over to the computer relying on the convenience of referring to all those pre-packaged ML routines by their BASIC names. The computer, however, always follows a series of ML instructions. You cannot honestly say that you truly understand computing until you understand the computer's language: machine language.
Another reason to learn ML is that custom programming is then possible. Computers come with a disk operating system (DOS) and BASIC (or other "higher-level" languages). After a while, you will likely find that you are limited by the rules or the commands available in these languages. You will want to add to them, to customize them. An understanding of ML is necessary if you want to add new words to BASIC, to modify a word processor (which was written in ML), or to personalize your computer - to make it behave precisely as you want it to.
BASIC's Strong Points
Of course, BASIC has its advantages and, in many cases, is to be preferred over ML. BASIC is easier to analyze, particularly because it often includes REM statements which reveal the functions of the program's parts. REMs also make BASIC easier to modify. This could make it the language of choice if the program must frequently be partially rewritten or updated to conform to changing conditions. For example, a program which calculates a payroll might well have at the beginning a series of data statements which contain the tax rates. BASIC DATA statements can be easily altered so that the program will reflect the current rates. If the payroll program runs fast enough in BASIC, there is no advantage to translating it into ML.
BASIC is also simpler to debug (to get all the problems ironed out so that it works as it should). In Chapter 3 we will examine some ML debugging techniques which work quite well, but BASIC is the easier of the two languages to correct. For one thing, BASIC often just comes out and tells you your programming mistakes by printing out error messages on the screen.
Contrary to popular opinion, ML is not necessarily a memory-saving process. ML can use up about as much memory as BASIC does when accomplishing the same task. Short programs can be somewhat more compact in ML, but longer programs generally use up bytes fast in both languages. However, worrying about using up computer memory is quickly becoming less and less important. In a few years, programmers will probably have more memory space available than they will ever need. In any event, a talent for conserving bytes, like skill at trapping wild game, will likely become a victim of technology. It will always be a skill, but it seems as if it will not be an everyday necessity.
So, which language is best? They are both best - but for different purposes. Many programmers, after learning ML, find that they continue to construct programs in BASIC, and then add ML modules where speed is important. But perhaps the best reason of all for learning ML is that it is fascinating and fun.
Return to Table of Contents | Previous Chapter | Next Chapter