....|....|....|....|....|....|...|....|....|....|....|....|....|.....
                    Alphanso's Assembler Assylum
                 Assembly Language for the Beginner

.;SHARON...THIS IS A NEW SERIES. THE 1ST LINE OF TITLE SHOULD BE BIG
.;         AND THE SECOND LINE AS A SORT OF 'SUB TITLE'... OK?

                    by Dave Heyliger - AMUS Staff

    So me and the 'Fonz' decided that there is a desparate need to
have everyone completely destroying their monitor and operating
system through the use of the destructive tool called assembly
language. Yes, beleive it or not AMUS fans, this is yet another one
of those 'how-to' type series dedicated to the end-user out there who
is ready to explore the internal guts of their machine. This series
will introduce you to assembly language programming on the Motorola
68000 microprocessor (you know.. the one inside your Alpha). I am
determined to give you step-by-step, byte-by-byte explainations that
will take most of the mystery out of assembly programming. Get
psyched, get pumped, (and get everyone off the machine!) cuz it's
gonna get ugly! (We assembly language programmers use 'Rambo' type
lingo when we get excited). Charge!!!

Hardware before Software

    An assembly language program 'talks' directly to the hardware.
You have the power to change almost anything with incredible speed
and power. In fact, you actually have to know the hardware of the
machine before any coding or programming can occur, so let's take a
quick look at the Motorola 68000 (simplified):

                               Motorola 68000
                  +----------------------------------+
                  | ################################ | D0
                  | ################################ | D1 
                  | ################################ | D2       Data
                  | ################################ | D3     Registers
                  | ################################ | D4
                  | ################################ | D5
                  | ################################ | D6
                  | ################################ | D7
                  |                                  |
                  | ################################ | A0
                  | ################################ | A1
                  | ################################ | A2     Address
                  | ################################ | A3    Registers
               ---|-################################ | A4
               |  | ################################ | A5
               |  | ################################ | A6
               |  |                                  |
               |  | ################################ | A7
               |  |                 ################ | SR
               |  +----------------------------------+
               |
               V   32 bit magnified picture of register A4
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   31                               15             7               0
                                                   |----  byte  ----|
                                     |-----------  word   ----------|
    |-------------------------  long word  -------------------------|


    Basically, the Motorola 68000 contains DATA registers and ADDRESS
registers (D and A registers). There are 8 data registers and 8
address registers, and although they may look the same, the machine
will handle these registers differently. Obviously, addresses will be
stored in the A registers, and 'data' will be stored in the D
registers. Each register consists of 32 bits that may be either ON or
OFF. This is how the computer stores all types of information (see
Heyliger's Highlights, Nov. '85).
    There are different ways to 'talk' to the registers: you may tell
the register that you are only interested in a byte (8 bits), a word
(16 bits) or a long word (32 bits). The default for most commands to
the registers are long words (the example program below talks to the
registers in bytes).
    Before I discuss the address registers, it might be helpful to
understand how the computer stores information in MEMORY. Basically,
your computer contains a series of tiny electronic storage cells. You
could think of these cells being contained in an ARRAY. Each element
in the array is a memory cell that can hold a byte of data. To access
the individual memory cells, you could simulate an access just as in
BASIC with an index (or pointer) to the array. Let's look at it
graphically:

        individual byte 
                       \
 MEMORY [ ]  [ ]  [ ]  [ ]  [ ]  [ ]  [ ]  [ ]  [ ]  [ ]....(array)
         0    1    2    3    4    5    6    7    8    9 ....(index)

If you knew that memory location 5 had a value of 'sum' stored in it,
then sum := memory[5]. Think of the '5' as the memory ADDRESS. Since
your computer has quite a bit of storage (perhaps a few megabytes),
the array index value can be quite large (0..1,000,000+).
Fortunately, the 68000 has address registers that can contain such
large values so that they can still hold the 'pointer' to the
location in memory. Also, if the value of 'sum' takes more than one
byte to store the entire value, the byte(s) following location number
5 will contain the rest of the data. When the computer is asked to
retrieve this data (and the computer realizes that it is more that
one byte long), it will retrieve the correct number of bytes starting
at location 5 and continue up to the last byte of 'sum'.
    The way in which addresses are stored (i.e., what NUMBER is in
any A register at any one time) is not too important. We'll see that
the machine will place addresses into the A registers with the
'correct' NUMBER. More important is to understand how we TELL the
computer to 'go get an address'. The example programs will go into
this detail further. Nine times out of ten, the NUMBER in an A
register that represents a valid address of one of your memory
locations inside your computer  will be POINTING  to that memory
location (the actual physical byte). Again, the examples in this
series will repeatively demonstrate pointing etc.
    The D registers are the exact opposite. We WANT to know what
NUMBER is in them, and we can also directly tell the computer to put
any number we want into any of the D registers. D means DATA or
numbers, whether these numbers represent characters, values, RAD50,
or whatever. Sample programming will further enlighten you.
    A few extra notes on the 16 registers. Notice that I set the A7
register off from the rest of the address registers. This register is
used to POINT to a STACK if the user has so defined one. A STACK is
very useful when developing subroutines etc. If you don't know what a
stack is, you will learn in the months ahead. Also, there is one more
register that has not been covered, and this register is the Status
Register. When you do addition, subtraction, or move data between
registers, certain bits inside the Status Register will be turned on
or off depending on if the move involved a zero, if the subtraction
was a negitive result, etc. This will allow you to do GOTO's just
like in BASIC just by checking these bits (usually called FLAGS).

AMOS/L Makes Life Easier

    The people who designed the 68000 came up with certain 'commands'
that the processor would understand. These commands are usually
refered to as the 'instruction set'. Every 68000, whether it is in an
Alpha Micro, a MacIntosh, or any other machine, will support the
standard instruction set. So far so good.
    AMOS/L has supplied the assembly programmer with a very large set
of MONITOR calls, which act just like an instruction from the
instruction set, but are UNIQUE to the Alpha Micro and have their own
unique name. These puppies are a real life saver. You can read about
these calls in the AMOS/L MONITOR CALLS Software Manual (you will
NEED this manual, along with AlphaFIX Manual, and the Assembly
Language Programmers Manual, and, the 100/L Instruction Set Software
Manual... get 'em from AMUS).

Learning from Examples

    Now before I go on, I must tell you that I am no pro at this
stuff. The way I have been learning is by READING other peoples
programs. I recommend this approach strongly. In fact, what I suggest
you do is to look at all of the .M68 programs from your AMUS tape
that are in the [100,51] and [100,52] P,PN's. Most of these have
comments (brief as they may be) so you can go through them
step-by-step (using your manuals). You can learn very fast by reading
other programs.
    With that in mind, let's disect a really simple program that
simply prints the ASCII characters (ABC...xyz) to your screen. Note:
all *.LIT files on you computer were 'created' by writing  SOURCE
code (VUEing a .M68 file), and then ASSEMBLING the source code file,
and so that is what we will do below. Here is your first example
program, ASCII.M68:

;*****************************************************
;* ASCII.M68 - Prints the ASCII letters to the screen
;*
;* Produces: ASCII.LIT
;*
;* Useage: ASCII [cr]
;*
;*  by Dave Heyliger - AMUS Staff
;*****************************************************

        OBJNAM  ASCII.LIT                       ;Final name will be this

        SEARCH SYS                              ;Here is where all of the
        SEARCH SYSSYM                           ;MONITOR calls unique to
        SEARCH TRM                              ;AMOS live, so get them.


TOP:    PHDR    -1,0,PH$REE!PH$REU              ;Re-entrant and re-useable.
        MOVB    #65.,D1                         ;MOVe to reg. D1 a decimal 65

LOOP:   TTY                                     ;MON. call to 'print' D1 out
        ADDB    #1.,D1                          ;ADD (byte) a decimal 1 to D1
        CMPB    D1,#123.                        ;See if D1 = decimal 123
        BNE     LOOP                            ;If D1 <> 123, branch to LOOP
        CRLF                                    ;D1 = 123.. simulate a return
        EXIT                                    ;and jump back to AMOS

        END                                     ;End of assembly code.


Line-by-Line, Byte-by-Byte

    The top of this program contains comments that tell the reader of
the file what the program name is, how one is to use it, and any
other information the creator feels necessary. Notice the ";" at the
start of each comment line. Also notice that comment lines may occur
anywhere in the file.

OBJNAM
    OBJect File NAMe. This one-liner will allow the programmer to
specify what the output file will be called. If you know it will be a
'.LIT' file, then you may omit this line due to the default of
{filename.M68} --> {filename.LIT}. If you were creating a subroutine
for basic, you would have OBJNAM {file}.SBR, for example.

SEARCH SYS,SYSSYM,TRM
    SEARCH (in DSK0: 7,7) SYS.UNV, SYSSYM.UNV, and TRM.UNV. It is in
these files that all of the 'gizmo' monitor calls are defined, and so
you will ALWAYS want to search these three files, even if you DON'T
use them (a good 'just in case' practice). Therefore, every program
you read will probably have these three SEARCH lines.

TOP:  PHDR   -1,0,PH$REE!PH$REU
    First item to notice is the useage of TOP: as a LABEL. You may
use any name you like for a label, with the following restrictions:
1) it must end with a colon :  2) 6 characters maximum in length, and
3) start your label in the first column. Labels are important in that
the computer will 'mark' all program lines that have labels and
remember where they are in the program. PHDR - this stands for
Program HeaDeR. It is not a mandatory line, but this line will define
certain characteristics of the program and will be checked if the
program was to be loaded into system memory or user memory. Since all
of the programs we will generate will be RE-ENTRANT and RE-USEABLE,
we will always include this information in the program header line.
The (-1) means you must be logged-on the computer, the (0) means zero
privilege (don't worry about it), and PH$REE = re-entrant, PH$REU =
re-useable. Re-entrant and re-useable (in basic terms) means that the
program can be run anywhere in any one user's memory partition and
still work, i.e., it is NOT memory dependent. The "!" will set BOTH
of these 'flags' ON in the Header Status word (more of this in later
articles).

MOVB     #65.,D1
    Our first real instruction! When reading instructions, most
'flow' from left to right. MOVB means MOVe Byte (so 8 full bits will
be moved). The #65. tell the computer 'this is the value of the Byte
I am going to MOVe'. The "#" means 'number', and the "." means
decimal. If we had left off the ".", an octal 65 (decimal 53) would
be the byte in question. Finally, we are MOVing the Byte to data
register D1. To read the entire line as the computer would understand
it: 'move a byte whose value is 65 decimal into the D1 register'. Why
are we moving a 65 into D1? Well, recall that the decimal ASCII value
of 'A' is 65. 65 is our 'starting point' of our ASCII characters. The
D1 register will hold this number for us (think of the register D1 as
a variable starting out at a value of 65).

LOOP: TTY
    Another label and our first MONITOR call! Remember, a monitor
call is a pre-defined Alpha Micro command that will perform something
for us. TTY simply means 'take the character in the D1 register and
blast it to the screen, and then continue with the next instruction'.
But you say "there isn't a character in D1, there is a number". You
would be right. However, all characters are represented as numbers,
and since the computer knows it is looking at a 'character', bingo!
See how simple these monitor calls make our life?!!

ADDB     #1.,D1
    This is an easy one. It looks like an ADD, but with a twist. It
is an ADD Byte (so we really are only looking at the rightmost 8 bits
in the data register when we ADD the number to follow). The Byte to
ADD is a decimal 1, and the register we are ADDing it to is the D1
register. We are ADDing one to D1 because 'B' is decimal value 66,
'C' is a 67, etc.

CMPB     D1,#123.
    Another instruction, CoMPare Byte. This means that we will be
comparing two Bytes of information. Whenever a CoMPare is performed,
the Status FLAGS are effected (keep on reading...). So, in this line
of the program, the computer reads this as 'CoMPare Bytes... one of
the bytes is in D1, and the other byte is a decimal 123'. Nothing in
any of the registers is affected, i.e. D1 still will have a 66 on the
first time around ('z' is ASCII 123).

BNE      LOOP
    Branch if Not Equal. Branch if what is not equal?? OK, here's the
poop: on any CoMPare line, the Status FLAGS are effected. Internally
inside the processor, a CoMPare will subtract whatever we are
comparing and then set the FLAGS accordingly, while at the same time,
it will throw away the results AND leave the stuff we are comparing
alone (WOW! Maybe you should read that again!). SO... the computer
will 'subtract' the value 123 from D1, and if it is a ZERO (meaning
the two values were indeed equal), the ZERO FLAG (one of the bits in
the Status register) will be SET (turned 'on'). Let's make life easy
and not worry too much about what other FLAGS the Status Register
has, OK? For now, just remember that there is a ZERO flag, and it
will be SET to ON if a CoMPare produces an 'invisible' result of zero
(puff-pant). The Branch on Not Equal will look directly at the ZERO
FLAG, and if it is NOT set (meaning the subtraction was not equal to
zero), then Branch back to the line marked by LOOP. "OH!", you say,
"a GOTO". How right you are! 

CRLF
    Another monitor call. This baby will simulate a Carriage Return
Line Feed. When will this occur? Well, the statement directly before
this is the Branch if Not Equal. If the ZERO flag IS set, then the
branch will NOT happen, and the program 'falls through' to this
monitor call.

EXIT
    Another simple one. EXIT this silly program and return to AMOS.

END
    This marks the end of the source for ASCII.M68


Getting your Program to Run

    I strongly suggest that you type this short program in using VUE,
(VUE ASCII.M68) and then ASSEMBLE the program. Assemble is very
similar to COMPIL for a BASIC program. To assemble the program, type
a 'G' from the '>' in VUE, or type at the dot "M68 ASCII". The
assembler (a program on the Alpha) will then take your .M68 file and
create your .LIT file. Notice that you will see 'SEARCHING...'
appear, since we told the computer to SEARCH for our monitor calls.
Also notice how the assembler will report to you any errors, and the
final size (in bytes) of your program. Again, type in this program so
that you may see how the assembler works! When you have typed it in
and assembled the program, type in ASCII at the dot and watch the
program do its stuff.

Enough for One Day

    Well, that will just about do it for the first of this series. If
you DON'T have those manuals I mentioned, you WILL need them! Next
time, we will do some work with the Address registers, and define in
more detail the re-entrant and re-useable programming structure.
There is a ton of small topics to be covered, so be patient with me.
If after reading this action-packed article you are just dying for
more information, I suggest the book "68000 ASSEMBLY LANGUAGE
PROGRAMMING" by Kane, Hawkins, and Leventhal (Osborne/McGraw-Hill).
This book discusses the general use of the 'instruction set', but has
no information on the monitor calls that AMOS provides.
    Well, the Fonz and I are ready to cruse the Boulder Mall for
chicks and chips (the chips are the Fonz' idea), so I'll see you
machine crazed junkies next month. And remember, send chocolate
covered peanuts (Sharon won't buy them for me anymore)!