Apple Assembler

by Craig Kirkwood
(Reprinted From The Australian Apple Review April 1986)

LAST MONTH WE LOOKED AT the components of a microcomputer, discussed the use of high level languages and learnt how to access the Apple's "mini assembler" from the monitor. That's all well and good, but let's extend our knowledge a little further and take a closer look at the heart of the Apple; presenting the 6502.

The 6502 microprocessor was originally designed by a company called MOS Technology Inc., who were a "breakaway" group from the giant American manufacturer Motorola:Since then other companies such as Synertek and Rockwell have also produced them. The original bipolar version has been superceded by several CMOS versions of the chip which boast higher clock speeds and increased instruction sets . Suffice to say at this stage that they are all very similar and the differences in instruction sets between different versions of the same chip will not affect the newcomer.

It is this microprocessor which adorns the insides of several popular microcomputers (hereinafter affectionately called "micro") including the Apple ][ series.

Astute readers may wonder why I use the word "microcomputer" instead of that tired cliche "personal computer". Permit me to explain myself. Firstly, I believe that most personal computers are anything but "personal", with the possible exception of the Mac, and secondly my dislike of the expression is more or less historical. In the bad ol' days before personal computers, we had only "mini computers", those monstrous machines filling rooms and corridors which were (and still are) anything but user friendly. Minis, and their even bigger brothers, mainframes, are necessary in industry where the sharing of information among what may be anything up to several thousand employees requires a fast and powerful machine. Minis, of course, require terminals and with the advent of the first microprocessor these terminals began to become more and more intelligent. At the same time, there developed a need for a "one man" machine for small businesses and hobbyists. Enter the microcomputer.

The early micros were called just that, microcomputers. These were the Tandy TRS 80's and not far behind - the Apple ]['s. There were others and just who was first I'm not sure but they represented what were soon to become known as personal computers. The phrase didn't really catch on though until the belated but well timed entry into the market of the big, bold, blue IBM PC. And since then the word microcomputer has all but faded into oblivion. The 6502 microprocessor is an "8 bit" device, this means it can deal with 8 bits or one "byte" of data at a time. It has 16 address lines and can therefore access a total of 65536 memory locations directly. Figure 1 shows a pinout of the chip showing the data and address lines as well as the various control signals, clocks and power supply. These signals aren't particularly important at this stage, however an understanding of the internal structure of the chip is more so.

Figure 2 shows a programming model of the 6502. It shows several blocks, known as registers, starting with the accumulator, then the x-register, the y-register, the stack pointer, and finally the program counter. These are all part of the internal memory of the CPU. They also provide a good example of the internal workings of almost all microprocessors. Variations, of course, are great but all CPU's share in common the use of internal dynamic memory locations within the package itself. You may be wondering how the initials CPU represent the word "microprocessor" . Well, in fact they don't. CPU actually stands for "central processing unit" which is again historical and originally referred to the "brain" used in mini computers which actually took up several circuit boards rather than one IC package, as is the case with the relatively recent invention of the microprocessor. The correct mnemonic is in fact MPU (microprocessor unit) but to be consistent with most texts and my own bad habits I will continue to refer to it as the CPU. In this outline I will endeavour to keep the description of the structure broad enough to be general whilst pointing out those features peculiar to the 6502. The registers of the CPU are vital to the operation of a program. They can be broadly categorised into three types:

 

GENERAL USE - These can be used for anything you like and are usually involved in most of the CPU's instructions. The accumulator is a general use register.

lNTENDED USE - These have one thing they do particularly well but can also be used for other purposes. The X and Y registers are examples

DEDICATED USE -These have only one use and cannot normally be used for any other purpose. The stack pointer, program counter and flag (or status) register are examples.

Some CPU's have many more registers of varying sizes. The Zilog Z80, for example, another very popular CPU among micro's, has several registers which can be used to emulate 16 bit processing. True 16 bit processors such as Intels 80286 and Motorola 68000 family have incredibly complex architectures making assembler programming a very difficult task. More recent chips have other areas of memory available as well as serial ports and "memory management" capabilities.

Let's take a closer look at what each component does. The accumulator, as already mentioned, is a general purpose register. It is often used to receive data from the "address space" (memory/input output), to hold intermediate results of calculations, and to be the source of data to be stored in the address space. Most commands that involve arithmetic, logic, or testing will end up with the result in the accumulator. The name is yet again historical and relates to the days of early serial bit-at-a-time computers where the accumulator was a funnel through which everything had to go. The X and Y registers are general purpose registers which do their share of comparisons and logic operations as well as the very useful task of indexing; I will expand on this a little later.

The stack pointer is a dedicated use register which keeps track of a vital area of memory called the "stack". The stack is an area, external to the CPU (stored on the first "page" of memory) used for fast and easy storage of data. Every time something is put on or taken off the stack the stack pointer is incremented or decremented accordingly. Placing data on the stack only requires one instruction, making it a very useful programming tool. The program counter is the 6502's only 16 bit register. It needs to be that long since it is used to store a 16 bit address. The program counter always points to the next instruction to be executed. It is incremented upon competition of an instruction.

The flag register contains the condition or "status" of the CPU after an instruction has been executed. The flags have a significant use in programming. They can be used to direct program flow by "testing" them and making a decision depending on their condition. The meaning of each flag is as follows:

N - Negative result. The previous instruction resulted in a negative value when this flag is set (logic 1).

v- Overflow. Indicates that the result of an addition or a subtraction requires more bits than available in the 8 bit register used to contain the result.

B- Software interrupt. This flag is used to differentiate between a software BRK and a hardware interrupt.

D- Decimal. When this flag is set the result of an arithmetic instruction should be interpreted as BCD (binary coded decimal)

I-Interrupt. This flag is used to"mask" or hide a maskable interrupt. Interrupts will be explained in future issues.

Z- Zero. When set the result of an instruction (operation or comparison) was zero.

C- Carry. This indicates an arithmetic carry or borrow occurred during an operation. Carry, somewhat confusingly, is also used to "catch" the remaining bit in a shift instruction.

Before we dive into the instruction set of the 6502, we need to have an understanding of the way in which the memory is arranged.

We know the CPU is equipped to address a total of 64K memory locations (lK = 1024 bytes). Because of the addressing features of the 6502, it is convenient to partition the memory into logical "pages".

A page is simply a block of 256 bytes. Thus memory locations 0 to 255 are page 0 of memory. This first page is referred to as zero page and is used a lot in assembler programming. The next page is used for the stack but the remainder of the address space is unconstrained by design. On the Apple, certain areas of memory are used for other specific tasks such as housing DOS and BASIC variables. The reference manual contains a detailed description of the use of memory and what areas are available for user programs. To access a particular memory location we must first select the page and then the location within that page (this is actually done in reverse order). This requires a total of four hex digits.

We have a total of 256 pagesof memory each containing 256 bytes, thus we need a number between 0 and 255 to select the page and another to select the location on the page. 255 decimal corresponds to $FF in hexadecimal, consequently location $FF FF represents the highest memory location (and largest value) we will ever need. When dealing with memory don't forget to include zero as the first location. Zero is a perfectly respectable number in computing! Right, let's take a look at our first assembly language instruction.

 

LDA $A56B

This instruction says: LoaD the Accumulator with the contents of memory location $A56B ($ implies hex notation). When this instruction is executed, a copy of the data held in location $A5 on page $6B is transferred along the "data bus" to the accumulator. In this example we have used Absolute Addressing. There are 12 main addressing modes on the 6502 each of which have certain advantages and disadvantages and have specific uses. I will introduce them all eventually, by example.

The above example takes three bytes of memory. By that I mean the CPU will require three locations to store the instruction in memory when it is assembled (translated to hex machine code); i.e. one byte to store the code for "LDA" and the remainder to store the 2 byte address. Other addressing modes take more or less memory and consequently may be faster or slower to execute. Here is another example using Immediate Addressing.

LDA #$2B

This is the same instruction but using a different addressing mode. The instruction says LoaD the Accumulator immediately with the value $2B. The hash sign before the operand implies immediate addressing. It requires no memory access since it doesn't need to store or fetch anything. It uses only 2 bytes to assemble the instruction.

Here is another instruction using a slightly different addressing mode. The command is to STore the Accumulator at memory location $9F. This copies the contents of the accumulator to the required destination (as with the first example, the data held in the accumulator is only copied- not taken away or destroyed). You may notice that the address to which the data is to be copied is only 2 digits, we haven't specified the page address. Aha!

This brings us to Zero page Addressing. When we access zero page there is no need to specify the page address since it is automatically assumed to be zero. Consequently we have eliminated the third byte and are left with a faster 2 byte instruction. We have saved ourselves one whole microsecond! You may indeed laugh but reducing the amount of time involved in executing instructions is of prime concern in large programs, particularly in commercial applications. Fast and efficient programming is always important no matter what language is used.

TAX TAY TXA TYA

These are all single byte instructionsand use Inherent Addressing. TAX instructs the CPU to transfer a copy of the contents of the accumulator to the X register. TAY is the same except transfer to the Y register, TXA transfers from the X register to the accumulator and TAY - you guessed it transfer from the Y register to the accumulator. Inherent addressing means the address is inherent in the instruction; i.e. there is no need for an operand to specify where the data is to be transferred from or to.

Don't be concerned if these instructions seem meaningless at this stage, their significance will be revealed once we develop an understanding of the device.

So far then, we have seen that there are a number of different ways to manipulate data with the 6502. The other addressing modes and instructions will be discussed in future issues. In the mean time, however, the reference manual provides a list of the instruction set to ponder over.

I've also included a bibliography of some of the better texts on assembly language and microprocessors:

Micro Cookbook, Vol 2 Machine Language Programming. Don Lancaster Howard Sams & Co. Very good. Don Lancaster has written several texts on digital electronics. His conversational style is very readable.

An Introduction to Microcomputers, Vol 1 - Basic Concepts Adam Osborne McGraw Hill If you have any interest in the subject at all, this book is essential. Written by a true authority on the subject, Adam Osborne was the founder of the Osborne computer company (one of the earliest manufacturers of microcomputers).

Programming the 6502 Advanced Programming for the 6502 Interfacing the 6502 Assembly Language Programming for the Apple ][ Rodney Zaks Sybex Inc. These four books provide a total course in programming in 6502 few texts on various microprocessors. Between the first three he covers everything from basic concepts to complex data structures, interrupts and VO programming techniques. The fourth book isn't as good but covers many of the above topics in relation to the Apple.

The Art of Electronics Paul Horowitz & Winfield Hill Cambridge University Press This book was originally written for a one semester course in electronics at Cambridge University.'Although much of it is not relevant here, I have found it very informative on some of the principles of digital electronics and microprocessors. The authors take a detailed look at the Intel 8085 and discuss many micro support chips.


Return To Article Index / Return To Index

@