Everyone's Machine Language Guide, Part 1
NOTE: This is the first of Roger Wagner's Assembly Lines column which began its illustrious run in the October, 1980 issue. The OCR and reprint processing of this article was made possible in part by the support of STAP Project Backer, Chris Torrence. Chris is a currently working (with the support and interest of Roger) on "Roger Wagner's Assembly Lines: The Missing Volume" (or whatever it will be called). This new publication will bring together the Assembly Lines columns from Softalk magazine that did not make it to book form prior to the end of Softalk Publishing.
One often gets the impression that programming in assembly language is some very difficult and obscure technique used only by "those advanced programmers." As it happens, assembly language is merely different, and if you have successfully used Integer or Applesoft Basic to do some programming, there's no reason why you can't use assembly language to your advantage in your own programs.
This series will take a rather unorthodox approach to explaining assembly programming. Since you are presumably somewhat familiar with Basic, we will draw many parallels between various assembly language techniques and their Basic counterparts.
An important factor in learning anything new is a familiar framework into which to fit the new information. Your knowledge of Basic will provide that framework.
We will also try to describe initially only those technical details of the microprocessor operations as are needed to accomplish our immediate goals. The rest will be filled in as we move to more involved techniques.
The first of the technical details is the general structure, or architecture, of the Apple itself. The heart of the system is the 6502 microprocessor. This device operates by scanning through a given range of memory addresses. At each location it finds some particular value. Depending on what it finds, it executes a given operation. This operation could be adding some numbers, storing a number somewhere, or any of a variety of other tasks. These interpreted values are often called opcodes.
In the old days, programmers would ply their trade by loading each opcode, one at a time, into successive memory locations. After a while, someone invented an easier way, using short abbreviated words (called mnemonics) for the operations. The computer would then figure out which values to use and supervise the storing of these values in consecutive memory locations. This wonder is what is generally called an assembler. It allows us to interact with the computer in a more natural way. In fact, Basic itself can be thought of as an extreme case of the assembler. We just use words like PRINT and INPUT to describe a whole set of the operations needed to accomplish our desired action.
In some ways, assembly language is even easier than Basic. There are only fifty-five commands to learn, as opposed to more than one hundred in Basic. Also, machine code runs very fast and generally is more compact in the amount of memory needed to carry out a given operation. This opens up many possibilities for programs that would either run too slowly or take up too much room in Basic.
How the 6502 Talks to Itself. Probably the most unfamiliar part of dealing with the Apple in regard to machine level operations is the way addresses and numbers in general are treated. Unless you lead an unusually charmed life, at some point in your dealings with your Apple you have had it abruptly stop what it was doing and show you something like this:
8BF2- A=03 X=9D Y=00 P=36 S = F2
This occurs when some machine level process suddenly encounters a break in its operation, usually from an unwanted modification of memory. Believe it or not, the Apple is actually trying to tell us something here. Unfortunately, it's rather like being a tourist and having someone shout, "Alaete quet beideggen!" at you.* It doesn't mean much unless you know the lingo, so to speak...
* "Watch where you're stepping, you nerd!" (in case you're not familiar with this particular dialect.)
What has happened is that the Apple has encountered the break we mentioned, and in the process of recovering, has provided us with some information as to where the break occurred and what the status of the computer was at that crucial moment. This is rather like the last cryptic words from the recently departed.
The leftmost part of the message is of great importance. This is where the break in the operation occurred. Now, just what do we mean by the word where? Remember all that concern about whether you have a 16K, 32K, or 48K Apple? The concern was about the number of usable memory locations in your machine. This idea becomes clearer through the use of a memory map, such as the one shown in figure 1.
Inside the Apple are many electronic units that will store number values we give them. By numbering these units, we give each one a unique address. This way we can specify any particular unit or memory location, either to inquire about its contents or to alter those contents by storing a new number there.
In the Apple there are a total of 65,536 of these memory locations (incidentally called bytes). The chart gives us a way of graphically representing each possible spot in the computer.
When the computer shows us an address, it does not do it in a way similar to the numbers on the left of the memory map, but rather in the fashion of the ones on the right. You may well remark here: "I didn't know 'BFFF' was a number; it sounds more like a wet sneaker…"
To understand this notation, let's see how the 6502 counts. If we place our byte at the first available location, it's address is $0. The dollar sign is used in this case to show that we are not counting in our familiar decimal notation, but rather in hexadecimal (base sixteen) notation, usually called "hex," which is how the computer displays and accepts data at the monitor level.
After byte $0, successive locations are labeled in the usual pattern up to $9. At this point the computer uses the characters A through F for the next six locations. The location right after $F is $10. This is not to be confused with "ten." It represents the decimal number sixteen. The pattern repeats itself as in usual counting with:
$10, 11, 12, 13... 19, 1A, 1B...1E, 1F, 20
This method should be accepted just as a fact of life with the Apple for the time being. If you really can't stand not knowing the details of the reasoning behind this scheme, there are quite a number of books on number theory and number bases that you might peruse. Many books on assembly language also spend a chapter or two on this. It will be sufficient for our purposes, though, just to understand that $1F is as legitimate a number as 31.
The hex number $FF (255) is the largest value a single byte can hold. A block of 256 bytes (for instance $0 to $FF) is often called a page of memory. In figure 2, all the addresses from $0 to $FF are shown in block b. Four of these blocks together, as in c, make up 1K of memory. As you can see, there are actually 1,024 bytes in 1K. Thus a 48K machine actually has 49,050 bytes of RAM.
Block d of figure 2 shows the Apple's entire range again. If you do not have a full 48K of memory, then the missing range will just appear to hold a constant value (usually $FF), and you will not be able to store any particular value there.
The range from $C000 to $FFFF is all reserved for hardware. This means that any data stored in this range is of a permanent nature and cannot be altered by the user. Some areas are actually a physical connection to things like the speaker or game switches. Others, like $E000 to $FFFF are filled in by the chips in the machine called ROMs.
ROM stands for read only memory. These chips hold the machine language routines that make up either Applesoft or Integer, depending on whether you have an Apple Plus or the standard model. One of them is also the monitor, which is what initializes the Apple when it is first turned on so you can talk to it, and also handles your input when you're at the monitor level.
Now that break message should have at least a little meaning.
8BF2- A = 03 X = 9D Y = 00 P=36 S = F2
The 8BF2 is an address in memory. Rather like a "catch-22," it says that the break actually occurred at the address given minus two (8BF2 - 2 = 8BF0). For reasons that aren't worth going into here, the monitor always prints out a break address in this plus-two fashion.
What about the rest of the message? Consider the next three items:
A = 03 X = 9D Y = 00
The 6502, in addition to being able to address the various memory locations in the Apple, has a number of internal registers. These are units inside the 6502 itself that can store a given number value, and they are individually addressable in much the same way memory is. The difference is that instead of being given a hexadecimal address, they are called the x-register, the y-register, and the accumulator. In our error message, we are being told the status of these three registers at the break.
Figure 3 summarizes what we know so far. The 6502 is a microprocessor chip that has the ability to scan through a given range of memory, which we will generally specify by using hex notation for the addresses. Depending on the values it finds in each location as it scans through, it will perform various operations. As an additional feature to its operation, it has a number of internal registers, namely the x and y registers, and the accumulator. Memory-related operations are best done by entering the monitor level of the Apple (usually with a CALL-151 or RESET) and using the various routines available to us.
Next issue, we'll look at what an assembler actually does, and specifically how to use the Apple's mini-assembler. This assembler is present in any standard Apple with Integer Basic, or in an Apple II Plus with the Integer Basic firmware card. If you don't have either of these, I recommend getting one of the many assembler software packages available. If you're on a limited budget, there is a free one in many user group libraries called by a variety of names including Randy's Weekend Assembler, Ted II, and Assembler 3. 2. Get in touch with the librarian for your local group if you don't already have a copy. Otherwise, see your local computer store and get their advice on a good assembler. There are many opinions and I won't go into a review here.
In the meantime, you might also look at page 49 in the most recent Apple II Reference Manual. It has an excellent discussion of the monitor commands and also of the mini-assember.
Meet you here next issue!