Second Book of Machine Language Personal Computer Machine Language Programming For The Commodre 64, VIC-20, Atari, Apple, and PET CBM Computers - PDF Room
Second Book of Machine Language Personal Computer Machine Language Programming For The Commodre 64, VIC-20, Atari, Apple, and PET CBM Computers - PDF Room
Second Book of Machine Language Personal Computer Machine Language Programming For The Commodre 64, VIC-20, Atari, Apple, and PET CBM Computers - PDF Room
Second
Book
01
Machine
Language
By Richard Mansfield
221Yc1~~!~~Eublications,lnc,.
Greensboro, North Carolina
Copyright 1984, COMPUTE! Publications, Inc. All rights reserved.
ISBN 0-942386-53-1
10 9 8 7 6 5 4 3 2 1
COMPUTE! Publications, Inc., Post Office Box 5406, Greensboro, NC 27403, (919)
275-9809, is one of the ABC Publishing Companies, and is not associated with any
manufacturer of personal computers. PET, CBM, VIC-20, and Commodore 64 are all
trademarks of Commodore Electronics Limited and/or Commodore Business Ma-
chines, Inc. Apple is a trademark of Apple Computer Company. Atari is a trademark
of Atari, Inc.
Contents
Preface. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. v
1: How to Use This Book .. . ..... .. ...... . .. . ...... 1
2: Defs:
Equates and Definitions . ...... . .. . . . ... .. . .. . .. . 13
3: Eval:
The Main Loop .. . ... . . . ...... . ...... . .. . . ... . . 27
4: Equate and Array:
Data Base Management .. ........ . . . .. . .. . . .. . .. 77
5: Openl, Findmn, Getsa, and Valdec:
I/O Management and Number Conversions . .... . . 103
6: Indisk:
The Main Input Routine .... .. ... . .............. 137
7: Math and Printops:
Range Checking and Formatted Output . .. .... . ... 177
8: Pseudo:
I/O and Linked Files . .. . ............. . ....... . 197
9: Tables:
Data, Messages, Variables . . . . . . . . . . . . . . . . . . . . . . . 219
10: 6502 Instruction Set ... . .. . .... . ... ... .. . ...... 237
11: Modifying LADS
Adding Error Traps, RAM-Based Assembly, and a
Disassembler ............... .. .............. .. 275
Appendices .............. ... . . ....... . . .. . .... .. 353
A: How to Use LADS ... .. . . . .... .. . ..... .... . . .. 355
B: LADS Object Code .. . . .. .. . ........ .. .... ... . 357
C: Machine Language Editor for Atari and Commodore 415
D: A Library of Subroutines ... . ........ ... .... . .. 433
E: How to Type In Basic Programs ... . . ... ... .... . 440
Index ... . . .... .... .. ... ........ ...... .. .. .... . . 443
Preface
This book shows how to put together a large machine lan-
guage program. All of the fundamentals were covered in my
first book, Machine Language for Beginners. What remains is to
put the rules to use by constructing a working program, to
take the theory into the field and show how machine language
is done.
Showing how to construct an assembler-written entirely
in machine language-would serve two useful purposes. It
would illustrate advanced programming technique and also
provide the reader with a powerful assembler to use in other
ML programming.
This book, then, offers the reader both a detailed descrip-
tion of a sophisticated machine language program (the LADS
assembler) and an efficient tool, a complete language with
which to write other machine language programs. Every line
in the LADS assembler program is described. All the sub-
routines are picked apart and explained. Each major routine is
examined in depth.
LADS, the Label Assembler Development System, is a
fast, feature-laden assembler-it compares favorably with the
best assemblers available commercially. And not the least of
its virtues is the fact that few programs you will ever use will
be as thoroughly documented and therefore as accessible to
your understanding, modification, and customization.
LADS is a learning device too. By exploring the assem-
bler, you will learn how to go about writing your own large
machine language (ML) programs. You will see how a data
base is created and maintained, how to communicate with
peripherals, and how to accomplish many other ML tasks.
Also, because you can study the creation of a computer lan-
guage, the LADS assembler, you will gain an in-depth knowl-
edge of the intimate details of direct communication with your
computer.
Most programming involves a tradeoff between three pos-
sible objectives: speed, brevity, or clarity. You can program
with the goal of creating the fastest running program possible.
Or you can try to write a program which uses up as little
memory as possible. Or you can try to make the program as
understandable as possible, maximizing the readability of the
program listing with REMarks.
v
LADS emphasizes clarity so that its source code will serve
as a learning tool and as the focus of this book. It's designed
so that important events in the program can be easily ex-
plained and understood . Virtually every ML instruction, every
tiny step, is commented within the source code listings follow-
ing each chapter.
This doesn't mean that LADS is flabby or slow. Assem-
bling roughly 1000 bytes a minute and taking up SK in mem-
ory, LADS is considerably faster and more compact than most
commercial assemblers. That's because, in ML, you can have
the best of both worlds: You can comment as heavily as you
want, but the assembler will strip off the comments when it
creates the object code. In this way, clarity does not sacrifice
memory or speed.
The frequent comments contribute considerably to the
educational value of this assembler. Exploring LADS is a way
to learn how to achieve many common programming goals
and how to construct a large, significant program entirely in
ML. An additional advantage of this comprehensibility is that
you'll be able to modify LADS to suit yourself: Add your own
pseudo-ops, define defaults, format output. All this is referred
to as a language's extensibility. We'll get to this in a minute.
What BASIC is to BASIC programming, an assembler is to
ML programming. LADS is a complete language. You write
programs (source code) which LADS translates into the fin-
ished, executable ML (object code). Unlike less advanced
assemblers, however, symbolic assemblers such as LADS can
be as easy to use as higher level languages like BASIC. The
source code is very simple to modify. Variables and sub-
routines have names . The program can be internally com-
mented with REM-like explanations. Strings are automatic via
the .BYTE command. There are a variety of other built-in fea-
tures, the pseudo-ops, which make it easy to save object pro-
grams, control the screen and printer listings, choose hex or
decimal disassembly, and service other common programming
needs.
Perhaps the best feature of LADS, though, is its extensibil-
ity. Because you have the entire source code along with de-
tailed explanations of all the routines, you can customize
vi
LADS to suit yourself. Add as many pseudo-ops as you want.
Redesign your ML programming language anytime and for
any reason. Using an extensible programming language gives
you control not only over the programs you design, but also
over the way that they are created. You can adjust your tools
to fit your own work style.
Do you often need to subtract hex numbers during assem-
bly? It's easy to stick in a - command. Would you rather that
LADS read source programs from RAM memory instead of
disk files? (This makes it possible to assemble using a tape
drive. It can also be a bit faster.) In Chapter 11 we'll go
through the steps necessary to make this and other modifica-
tions. You'll be surprised at how easy it is.
Finally, studying the language (the LADS assembler)
which produces machine language will significantly deepen
your understanding of ML programming.
I would like to thank Charles Brannon for his translation
and work with the Atari version of LADS, Kevin Martin for his
translation and work with the Apple version, and Todd
Heimarck for his many helpful discoveries about the assembler.
vii
Ho\V to Use This Book
The dual nature of this book-it's both a text and a pro-
gram-offers you a choice. You can follow the ideas: reading
through the chapters, studying the program listings, and deep-
ening your understanding of machine language programming.
Alternatively, you can type in the LADS assembler and
experiment with it: learning its features, trying out modifica-
tions, and using it to write your own machine language pro-
grams. Appendix A describes how to use the assembler and
Appendix B provides instructions on typing it in. If you choose
this second approach, the rest of the book can serve as a ref-
erence and a map for modifying the assembler. The tutorials
can also help to clarify the structure and purpose of the vari-
ous subroutines and subprograms.
LADS is nearly 5K long, and for those who prefer not to
type it in, it can be purchased on a disk by calling COMPUTE!
Publications toll free at 1-800-334-0868. Be sure to state
whether you want the Commodore, Atari, or Apple disk. The
disk contains both the LADS source and object code (these
terms are defined below) . To create customized versions of the
assembler, you will need the source code. It, too, can be typed
in (it is printed in sections at the end of Chapters 2-9). If you
don't type in any of the comments, it is roughly 10K long. The
Commodore disk contains the various PET ICBM (Upgrade
and 4.0 BASIC), VIC, and Commodore 64 versions.
Definitions
There are several concepts and terms which will be important
to your understanding of the rest of the book.
ML programming, and programming in general for that
matter, is a new discipline, a new art. There are few rules yet
and few definitions. Words take on new meanings and are
sometimes used haphazardly. For example, the word monitor
means two entirely different things in current computerese: (1)
a debugging program for machine language work or (2) a spe-
cial TV designed to receive video signals from a direct video
source like a com pu ter.
Since there is no established vocabulary, some program-
ming ideas are described by an imprecise cluster of words.
When applied to machine language programming, the terms
pointer, variable, register, vector, flag, and constant can all refer
3
How to Use This Book
Loose Lingo
Purists will argue that each of these words has a distinct, de-
finable meaning. But then purists will always argue. The fact
is that computing is still a young discipline and its lingo is still
loose.
Some professors of BASIC like to distinguish between vari-
ables and constants, the latter meaning unchanging definitions
like SCREEN = 1024. The address of the start of screen RAM
is not going to vary; it's a constant.
In BASIC, something like SCORE = 10 would be a vari-
able. The score might change and become 20 or whatever. At
any rate, the word SCORE will probably vary during the execu-
tion of the program. In ML, such a variable would be set up as
a two-byte reserved space within the source code:
100 SCORE .BYTE 0 0
Then, anytime you AOC SCORE or AOC SCORE + 1, you
will add to the SCORE. That's a variable. The word pointer re-
fers to those two-byte spaces in zero page which are used by
Indirect Y addressing-like LOA (155),Y-and which serve to
point to some other address in memory.
Register usually means the X or Y or Accumulator bytes
within the 6502 chip itself. As generally used, the word reg-
ister refers to something hard wired within the computer: a
circuit which, like memory, can hold information. It can also
refer to a programmer-defined, heavily used, single-byte vari-
able within an ML program:
100 TEMP .BYTE 0
A vector is very much like a pointer. It stores a two-byte
address but can also include the JMP instruction, forming a
three-byte unit. If you have a series of vectors, it would be
called a "jump table," and the Kernal in Commodore comput-
ers is such a table:
4
How to Use This Book
5
How to Use This Book
6
How to Use This Book
7
How to Use This Book
rately, but linking them with the .FILE and .END pseudo-ops
into one big chain of source programs. This chain will be
assembled by LADS into a single, large, runnable ML object
program.
Each of the source programs, each link in this chain, is
called a subprogram. In the source code which makes up LADS
there are 13 such subprograms-from Defs to Tables-compris-
ing the whole of LADS when assembled together. This book is
largely a description of these subprograms, and some chapters
are devoted to the explication of a single subprogram. To distin-
guish subprograms from subroutines and label names, the sub-
program names (like Tables) have only their first letter
capitalized. Subroutines and labels are all-caps (like
PRINTFLAG).
The word integer means a number with no fraction at-
tached. In the number 10.557, the integer is the 10 since inte-
gers have no decimal point. They are whole numbers. ML
programs rarely work with anything other than integers. In fact,
the integers are usually between 0 and 65535 because that's a
convenient range within which the 6502 chip can operate-two
bytes can represent this range of numbers. Of course, decimal
fractions are not allowed. But virtually anything can be accom-
plished with this limitation. And if you need to work with big
or fractional numbers, there are ways.
In any case, when we refer to integer in this book, we
mean a number that LADS can manipulate, in a form that
LADS can understand, a number which is a number and not,
for example, a graphics code. For example, when you write
LDA $15 as a part of your source code, the computer holds the
number 15 in ASCII code form. In this printable form, 15 is
held in the computer as the numbers $31 $35 which, when
printed on the screen, provide the characters 1 and 5 (but not
the true number 15). For the assembler to work with this 15 as
the number 15, it must be transformed into a two-byte integer,
an actual number. When translated, and put into two bytes, the
characters 1 5 become: $OF 00. We'll see what this means, and
how the translation is accomplished, in Chapter 5 where we
examine the subprogram Valdec. It's Valdec's job to turn ASCII
characters into true numbers.
8
How to Use This Book
9
How to Use This Book
Springboard
In the 6502 chip instruction set, there aren't any instructions for
giant branches. Some chips allow you to branch thousands of
bytes away, but our chip limits us to 127 bytes in either direc-
tion from the location of the branch. Normally, this isn't much
of a problem. You ,JSR or IMP when you want to go far away.
But as you assemble, you'll be making tests with BNE and
BEQ and their cousins in the B group. Then, later, you'll add
some more pieces of programming between the branch instruc-
tion and its target. Without realizing it, you'll have moved the
target too far away from the branch instruction. It will be a
branch out of range.
This is pretty harmless. When you assemble it, LADS will
let you know. It will print a bold error message, print the
offending line so you can see where it happened, and even ring
a bell in case you're not paying attention. What can you do,
10
How to Use This Book
11
Defs:
Equates and Definitions
Let's get started. Recall that the boldface numbers within the
text refer to line numbers within the program listings at the
end of each chapter. The first section of LADS defines many
of the variables which are used throughout the program. It's
called " Defs. "
Defsfor Relocatability
One of the advantages of advanced assemblers, LADS in-
cluded, is that they create object code (runnable ML programs)
which are both relocatable anywhere within a computer's RAM
memory as well as transportable between computer brands and
models.
If you want to put LADS at $5000 instead of $2AFS, you
can relocate it quite simply: Just change line 10 in the Defs
source code file, the first file in the chain of LADS source code
files. As written, line 10 reads *= 11000 (equivalent to *=
$2AFS) and that causes the entire object program to start at
that address. Changing line 10 to '" = $5000 relocates LADS
when you next assemble it. If you include the pseudo-op .D,
the object program will be saved to disk under the filename
you specify.
In the source code of LADS itself, at the end of this
chapter, the ".D LADS64 " in line 30 will create a version of
LADS on disk by the name of LADS64 and if you later LOAD
"LADS64",S,1 it will come into your computer ready to run
with a SYS 11000. If you change the start address in line 10,
however, to $5000, and then reassemble the source code, your
LADS will start with a SYS 204S0 (decimal for $5000).
The numbers generated by the assembly (the object code)
will be sent to a disk file if you specify that with .D. They will
be sent into RAM memory if you use the .0 pseudo-op. If you
do turn on storage of object code to memory, LADS will send
the results of the assembly right into memory during the
assembly process. This can cause mysterious difficulties unless
you are careful not to assemble over LADS itself. If you have
created a version of LADS which starts at $4COO and you then
start assembly of some object program at $5000, you'll eat into
LADS itself. LADS is about 5K long. This, of course, would
15
Defs: Equates and Definitions
16
Defs: Equates and Definitions
17
Defs: Equates and Definitions
base. It will always know where the last symbol in our label
table was stored. All through pass 1 it will be lowering itself,
making room for new symbols and labels. (This data base will
later be referenced as we fill in the blanks on pass 2.)
PARRAY makes that search through the symbol table on pass
2 easy and fast. It points us through the array. PMEM is used
as a pointer during assembly from RAM, if you decide to use
the RAM-based version of LADS described in Chapter 11. The
uses of all these variables will become clear when we exam-
ine, throughout the book, the techniques which utilize them.
18
Defs: Equates and Definitions
19
N tj
o Program 211. Defs: Commodore 64 ~
~
HI *= 11000
20 .NO trJ
30 .D LADS64
-g
40 : IDEFS64" EQUATES AND DEFINITIONS FOR COMMODORE 64 ~
~
rIl
50 :--------------------- MACHINE SPECIFIC ZERO PAGE EQUATES -----------
~
60 RAMSTART = $2B: BASIC'S START OF RAM MEMORY POINTER ::I
70 BMEMTOP = $37: BASIC'S TOP OF RAM MEMORY POINTER 0..
80 ST = 144: STATUS WORD FOR DISK / TAPE I / O d
~
90 LOADFLAG = $93: FLAG WHICH DECIDES LOAD OR VERIFY (0 LOAD) ~
100 FNAMELEN = $B7: LENGTH OF FILENAME FOR OPEN A FILE ::I
....
110 FNAMEPTR = $BB: POINTER TO FILENAME LOCATION IN RAM.
..,.
120 FNUM = $B8: CURRENT FILE NUMBER FOR OPEN, GET & PUT CHARS TO DEVICE c5"
::I
rIl
130 FSECOND = $B9: CURRENT SECONDARY ADDRESS FOR OPEN
140 FDEV = $BA: DEVICE NUMBER (8 FOR COMMODORE DISK)
150 CURPOS = 211: POSITION OF CURSOR ON A GIVEN SCREEN LINE.
160 :--------------------- LADS INTERNAL ZERO PAGE EQUATES -----------
170 TEMP = $FB:SA = $FD:MEMTOP = $B0:PARRAY = $B2:PMEM = $A7
180 :------------------ MACHINE SPECIFIC ROM EQUATES -----------
190 BABUF = $0200: BASIC'S INPUT BUFFER
200 TOBASIC = $A474: GO BACK TO BASIC
210 KEYWDS = $A09E: START OF KEYWORD TABLE IN BASIC
220 OUTNUM = $BDCD: PRINTS OUT A (MSB), x (LSB) NUMBER
230 OPEN = $E1C1i OPENS A FILE (3 BYTES PAST NORMAL OPEN IN ROM).
240 CHKIN = $FFC6: OPENS A CHANNEL FOR READ (FILEt IN x)
250 CHKOUT = $FFC9: OPENS CHANNEL FOR WRITE (FILEt IN x)
260 CHARIN = $FFE4: PULLS IN ONE BYTE
270 PRINT = $FFD2: SENDS OUT ONE BYTE
280 LOAD = $E175: LOAD A BASIC PROGRAM FILE (SOURCE CODE FILE) INTO RAM.
281 : (F322 FOR UPGRADE/E172 FOR VIC)
290 CLRCHN = $FFCC; RESTORES DEFAULT I/O
300 CLOSE = $FFC3; CLOSE FILE (FILE# IN A)
310 STOPKEY = $FFE1; TESTS STOP KEY, RETURNS TO BASIC IF PRESSED.
320 SCREEN = $0400; ADDRESS OF 1ST BYTE OF SCREEN RAM
330 ,-------------------
340 .FILE EVAL
200 OPEN = $EIBE: OPENS A FILE (3 BYTES PAST NORMAL OPEN IN ROM) '"
210 CHKIN = $FFC6: OPENS A CHANNEL FOR READ (FILE# IN X) trJ
220 CHKOUT = $FFC9: OPENS CHANNEL FOR WRITE (FILE# IN X) .g
230 CHARIN = $FFE4: PULLS IN ONE BYTE ~
(1)
240 PRINT = $FFD2; SENDS OUT ONE BYTE '"
250 CLRCHN = $FFCC: RESTORES DEFAULT I/O ~
260 CLOSE = $FFC3: CLOSE FILE (FILE# IN A) Q..
270 STOPKEY = $FFEl: TESTS STOP KEY, RETURNS TO BASIC IF PRESSED. tj
(1)
280 SCREEN = $1000: ADDRESS OF 1ST BYTE OF SCREEN RAM (W/EXPANDED MEMORY) ::n
640 .FILE EVAL
....o2.
Program 2~3. Defs: PETjCBM 4.0 BASIC ::l
l0 *= 11000
'"
20 .NO
30 .D LADS
40 ; "DEFS" EQUATES AND DEFINITIONS FOR PET/CBM 4.0 BASIC
50 ;--------------------- MACHINE SPECIFIC ZERO PAGE EQUATES -----------
60 RAMSTART = $28; BASIC'S START OF RAM MEMORY POINTER
70 BMEMTOP = $34; BASIC'S TOP OF RAM MEMORY POINTER
80 ST = 150; STATUS WORD FOR DISK / TAPE I /O
90 LOAD FLAG = $9D; FLAG WHICH DECIDES LOAD OR VERIFY (0 LOAD)
100 FNAMELEN = $Dl; LENGTH OF FILENAME FOR OPEN A FILE
110 FNAMEPTR = $DA; POINTER TO FILENAME LOCATION IN RAM.
120 FNUM = $D2; CURRENT FILE NUMBER FOR OPEN, GET & PUT CHARS TO DEVICE
130 FSECOND = $D3; CURRENT SECONDARY ADDRESS FOR OPEN
14 0 FDEV = $D4; DEVICE NUMBER (8 FOR COMMODORE DISK)
150 CURPOS = 198; POSITION OF CURSOR ON A GIVEN SCREEN LINE.
160 ;--------------------- LADS INTERNAL ZERO PAGE EQUATES -----------
170 TEMP = $FB:SA = $FD:MEMTOP = $BB:PARRAY = $BD:PMEM = $BF
180 ;------------------ MACHINE SPECIFIC ROM EQUATES -----------
190 BABUF = $0200; BASIC'S INPUT BUFFER
200 TOBASIC = $B3FF; GO BACK TO BASIC
210 KEYWDS = $B0B2; START OF KEYWORD TABLE IN BASIC
220 OUTNUM = $CF83; PRINTS OUT A (MSB), X (LSB) NUMBER
230 OPEN = $F563; OPENS A FILE (3 BYTES PAST NORMAL OPEN IN ROM).
240 CHKIN = $FFC6; OPENS A CHANNEL FOR READ (FILE# IN X)
250 CHKOUT = $FFC9; OPENS CHANNEL FOR WRITE (FILE# IN X)
260 CHARIN = $FFE4; PULLS IN ONE BYTE
270 PRINT = $FFD2; SENDS OUT ONE BYTE
280 LOAD = $F356; LOAD A BASIC PROGRAM FILE (SOURCE CODE FILE) INTO RAM.
281 ; (F322 FOR UPGRADE/E172 FOR VIC/E175 FOR 64)
290 CLRCHN = $FFCC; RESTORES DEFAULT I /O
300 CLOSE = $F2E2; CLOSE FILE (FILE# IN A)
310 STOPKEY = $FFE1; TESTS STOP KEY, RETURNS TO BASIC IF PRESSED.
320 SCREEN = $8000; ADDRESS OF 1ST BYTE OF SCREEN RAM I:j
(\)
330 ,-------------------
~
340 .FILE EVAL
t'T1
.c
Program 2,4. Defs: Apple ~
~
...,.
(\)
10 *= $79FD
20 .0 LADS '"~
~
30 .NO 0-
40 ;APPLE VERSION tj
50 ; .. DEFS" EQUATES AND DEF I NIT IONS (\)
25
Eval:
The Main Loop
Eval is the heart of LADS. It is the main loop. It starts assem-
bly at START (line 30) and ends assembly at FINI (line 4250).
Throughout Eval, JSRs take us away from the main loop to
perform various other tasks, but like mailmen, all the other
routines in the assembler start out from Eval, the post office,
and they all RTS back to it when their work is done.
For convenience, references to lines within the source
code listing at the end of the chapter are boldface inside
parentheses. Also, to distinguish label names like FIN I from
the names of one of the 13 sections of LADS (a subprogram
like Eval), we'll put label names in all caps, but just capitalize
the first letter of the subprograms of the assembler.
Preliminaries, Preparations
Most programs have a brief initialization phase, a series of
steps which have to be taken to fix things up before the real
action of the program can commence. Variables have to be set
to zero, files sometimes have to be opened on a disk, defaults
have to be announced to the program. (Defaults are those
things a program will do unless you specifically tell it not to.
A game might default to single-player mode unless you do
something which tells it that there are two of you playing.
LADS defaults to hexadecimal numbers for printer or screen
listings and turns off all its other options.)
At its START, LADS loads the Accumulator with zero and
runs down through 48 bytes of registers, flags, and pointers,
stuffing a zero into each one. These flags are all needed by
LADS to keep track of such things as which pass it's on,
whether or not you want a printer listing, or want the results
of an assembly to POKE into memory, or whatever. This
initialization fills them all with zero. The label OP is the high-
est of these registers in memory, so we LOY with 48 and DEY
down through them (see line 30).
Let's take a minute to briefly review our terminology:
Register usually refers to the Accumulator (A), or the X or
Y Register in the 6502 chip. It can also mean a single byte set
aside to temporarily hold something. It's like a tiny buffer.
A buffer is a group of continuous bytes used to hold infor-
29
Eva1: The Main Loop
30
Eval: The Main Loop
31
Eval: The Main Loop
32
Eval: The Main Loop
33
Eval: The Main Loop
34
Eval: The Main Loop
35
Eval: The Main Loop
ing LOA 15. Nevertheless, any LOA will first get a 161, the
base opcode. It's the lowest possible opcode for an LOA; the
other LOA addressing modes can be calculated by adding to
161. LOA 15 is Zero Page addressing and its opcode is 165.
Eval's main job is to start off with the lowest, the base opcode
for a particular mnemonic like LOA, and then make adjust-
ments to it when the correct addressing mode is detected. Eval
establishes the addressing mode when it examines the line
and looks for things like the # symbol and so forth. As we'll
see, this examination will modify the OP number until the
correct opcode is calculated.
For now, though, it's enough that we return from Findmn
with a base opcode number, something reliable to work from,
stored in the variable OP. By the way, Findmn gets these
numbers, TP and OP, from a table in the subprogram Tables.
We'll look at it at the very end of our exploration of LADS in
Chapter 9. Tables is where all the constants are stored.
36
Eval: The Main Loop
It, too, is stored during the first pass and looked up dur-
ing the second pass. But the equals sign shows that we should
remember the value on the other side of the = symbol, not
the address of the location of the label. In this example, when-
ever we want to store something onscreen, we don' t need to
calculate the correct address. $0400 is the first byte in screen
memory (on the Commodore 64 in this example). So we can
just STA SCREEN to put whatever is in A into the upper left-
hand corner of the screen. Or STA SCREEN + 200, or STA
SCREEN +400, or whatever. (Adding numbers to SCREEN
will, in this case, position our A lower on the screen.)
It's here that we decide whether we're dealing with one of
the labels or with an ordinary mnemonic. If we JMP back from
Findmn to EVAR (920), the first thing on the source code line
was a mnemonic. If we JMP back from Findmn to EQLABEL,
it wasn't a mnemonic (hence it's a label). EVAR evaluates the
argument, the 15 in LDA 15. EQLABEL evaluates the other
kind of argument, the label SPRITE in LDA SPRITE.
37
Eval: The Main Loop
38
Eval: The Main Loop
at the end of the loop. But some loops require that we INY at
the start or at least early within the loop. In such cases, we
must LDY #255 before entering the loop. The first event
within the loop is an INY, so in effect, Y becomes 0 right off
the bat. When you increment 255, you get a zero.
EQLABEL is where we determine what kind of label
we're dealing with. On the first pass, we don't care. All labels
must be stored in our label table array for later reference on
pass 2. On pass 2, though, we must go through the test in
EVX1 (1090). And it's one of those fat Y loops that start off
with a bloated Y Register. We put 255 into Y at the start.
We load the first character in the LABEL buffer. If it's zero
(end of the line), there wasn't any argument. There should
have been. This is a mistake. By this time, there has to be an
argument. We've already eliminated the only addressing types
that have no argument: Implied (type 0) and Accumulator (a
variant of type 3). If there's no argument, the source code is
defective. There should be an argument. We've got to print an
error message.
NOAR is tucked away at line 520 of the Equate sub-
program. We'll get to it later. It just prints a "no argument"
error message. But we should clear up the little mystery
surrounding the bounce we just took. We BEQ GONOAR
(1110) only to JSR NOAR (1320). Why? This is one of those
springboards we discussed in Chapter 1.
The B instructions, the branchers like BEQ, can move us
only 127 bytes in either direction, forward or backward, from
their location. This is sometimes not far enough. LADS will
alert you to this if you should try to branch further than you
can. It will print BRANCH OUT OF RANGE and ring the bell.
The easiest solution to this problem is to simply have the
branch go to a nearby JMP or JSR. They can fly off to any ad-
dress in the computer. Have them act as springboards, bounc-
ing you to your actual target.
The alternative is to move yo ur target closer to the
branch. The target is probably a subroutine. But moving a sub-
routine is often a lot more trouble than simply creating a
springboard.
Back to the evaluation (1120). If there is an argument, we
move it up to another buffer called FILEN. Then we check for
the blank character, 32, before leaving this loop. The label
39
Eval: The Main Loop
40
Eva1: The Main Loop
work with LOA #15 and ignore the OA #150000, etc., the
remnants of the old line. All is now ready for the assembler to
take a look at a mnemonic and its argument, so we JMP to
MOE4 (1310). If this had been pass I, we would have by-
passed all this and leapt from 1070 right down to 1330, where
we go to the subprogram Equate, which stores labels and their
values in the label table array. But both pass 1 and pass 2
must continue to work out the addressing modes by going to
MOE4 . Why should we need to worry about addressing
modes on pass 1 since LADS doesn't POKE anything into
memory or save anything to disk during pass I?
LADS must keep an accurate PC (Program Counter) dur-
ing pass 1 to know what value to assign to address type la-
bels. Otherwise, the address labels would be inaccurate:
10 START INC 15
20 LOA 15
30 BEQ FINISH
40 JMP START
50 FINISH R TS
Notice that both INC 15 and LOA 15 are Zero Page
addressing. They occupy two bytes in memory. But they could
have been Absolute (LOA 1500) addressing, or other modes
which use up three bytes. LADS has no way of knowing, by
reading LOA or INC alone, whether to raise the program
counter by two or by three. All this wouldn't matter much ex-
cept for that label FINISH in line 50. It has to be assigned its
proper address during pass 1 and stored in the array. That
means LADS needs to know exactly how many bytes it is
from START to FINISH.
Consequently, LADS has to check out the arguments of
INC and LOA to see whether they're addressing modes using
up two or three bytes. This Program Counter is kept in a vari-
able in LADS called SA. It's constantly changing during both
passes of the assembly, but it is used during pass 1 to assign
numbers to address labels like START and FINISH.
We'll deal with the next routine, EVEXLAB (1360), shortly.
Let's go first to MOE4 and see how LADS analyzes
arguments.
41
Eval: The Main Loop
42
Eval: The Main Loop
How Is It Addressed?
This is the final job the assembler must perform- distinguish-
ing between Immediate (LOA #15 ), Absolute (LOA 1500),
Zero Page (LOA 15), Indirect Y (LOA (15),Y), and the other
addressing modes. Recall that we 've already eliminated nearly
half the possibilities by previously handling type 0, the self-
contained, implied ones like CLC and INY. What's left is to
check for # and ( symbols and to see how big the argument is.
That tells us if our argument (the expression) calls for Zero
Page addressing or not.
First off, LADS checks for the # character (2130) and,
finding one, goes to the IMMEO routine to handle Immediate
addressing. Next it looks for the ( character. Finding one of
those, it goes off to the INOIR routine to deal with Indirect
addressing.
Failing to find either of these symbols, it loads in the type
variable, TP, and looks to see if it's an 8. All the B instruc-
tions, the branches like BNE and BCe, are grouped together as
type 8. Finding a type 8, LADS goes to the REL subroutine to
handle Relative addressing.
From here (line 2220) to the end of Eval, there will, from
time to time, be adjustments made to the OP variable which
43
Eva1: The Main Loop
44
Eval: The Main Loop
45
Eval: The Main Loop
set, the "minus sign" in signed arithmetic was found. The sign
in signed arithmetic is held in the seventh bit. lXXXXXXX
would signify a negative number, OXXXXXXX a positive num-
ber. (There's a connection here with the fact that forward
branch arguments can range from $00 to $7F, and backward
branches from $FF down to $80.)
Now some people will point out that there are eight bits in
a byte, and we keep referring to the seventh bit when we're
talking about the eighth. Recall that, in computing, much
counting begins with the zeroth bit. A byte can hold only the
numbers 0-255. The lowest number it can hold is a zero. But
that still means that there are 256 possibilities, 256 possible
states for a byte: 1-255 plus O.
Signed Arithmetic Branching
If all this seems an unnecessary detour into messy detail, con-
sider how Relative addressing uses signed arithmetic to cal-
culate where it should branch. When the 6502 chip comes
upon one of the B branch instructions like BNE, it looks at the
argument in a unique way. If the number is higher than 127, it
knows it must go backward. If lower or equal, it must go for-
ward. That's why you cannot branch further than 128 back-
ward or 127 forward. The argument can't use the entire byte
to hold a number-the seventh bit must be reserved to hold
the plus or minus sign. Remember, if the s~'venth bit is set, it
means minus. If clear, it means plus. BPL (Branch if PLus) is
triggered when the seventh bit is clear. BMI responds to a set
(1) seventh bit.
Take a look at the assembly in the example above. Line
120 shows that BEQ END became the opcode FO and the argu-
ment is 03 . 03 will take us to END because all branches are cal-
culated from the address of the mnemonic following the branch
instruction . Count three from address 1005. You hit END.
A branch backward, too, counts backward from the address
of the mnemonic following the B instruction. All branches count
from their own PC location plus 2. Look at a branch backward:
40 1000 AO 00 START LDY #0
50 1002 C8 LOOP INY
60 1003 DO FD BNE LOOP
70 1005 60 END RTS
Here line 60 is branch backward, but the argument, $FD, is
pretty strange. $FD looks like this in binary: 11111101. So the
46
Eval: The Main Loop
Further Evaluation
We've seen how LADS calculates the branch addresses. At this
point in the source code, we come upon a continuation of
evaluations of other addressing modes. EVM05 (2740) gets the
47
Eva1: The Main Loop
48
Eva1: The Main Loop
justs the base opcode (in the OP variable) if necessary, and be-
haves like any other two-byte addressing mode, jumping to
TWOS.
TAB
The first thing INLINE does is to check if we're on the first
pass. Nothing gets printed out on pass 1, so we jump over the
entire INLINE routine. If it's pass 2, we look to see if the screen
flag, SFLAG, is up (3470). If it isn't, we again jump past
INLINE.
Then the LOCFLAG is checked. It is up when there is a PC
address label (like the label START in the example above). If it's
up, we use something from BASIC: the cursor position byte.
We've been using BASIC's PRINT routine all along. One of the
advantages of this is that PRINT keeps a record in zero page of
the current screen position; we could just LDA #20:STA
CURPOS, and the next printout would be at position 20 .
49
Eval: The Main Loop
Tab to Printer
Things are more complicated, though, since LADS has an op-
tion to print listings to a printer as well as to the screen. We
cannot use the same technique with a printer.
To find out how many blanks to print to the printer, it's
necessary to subtract the CURPOS value from 20. Assume that
we've printed 14 characters so far: 20 - 14 = 6. We use this
result in a loop to print blanks to the printer (3660) to cause a
simulated TAB.
Following the TAB, we're set to print an address label
which is still waiting for us up in the buffer FILEN. As usual,
we set TEMP to point to the message we want printed, and JSR
PRNTMESS, thereby printing whatever is in FILEN, delimited
by O.
50
Eval: The Main Loop
51
Eval: The Main Loop
ting the disk's PC to point to the first byte in the disk file. Now
we're ready to read in the source code all over again. We're
ready to start the second pass.
We jump back up, just below START, to SMORE and read
in, once again, the first line of the entire source code.
If we've already completed pass 2, however, we don't want
to restart source code examination-every thing's already
accomplished, POKEd and PRINTed and SAVEd to disk as the
case may be. We want to gracefully exit the assembler. FIN
(4390) does this. It closes down any read or write files on disk,
closes down communication to a printer, and jumps to BASIC
mode. Now would be the time to try the object code program,
to make some adjustments to your source code if you want, and
then SYS back into LADS for another assembly.
Each computer has a "side entrance," a warm start into its
BASIC. This entrance doesn't wipe out what's in RAM memory,
doesn't blank out the screen. It's here that the LADS goes to
move gently back into BASIC mode. The address of TOBASIC
for each computer is defined in the subprogam Defs.
Evaluating ,X and ,Y
Although FIN I is the logical end of the evaluation process, it's
not the physical end of the Eval subprogram. Just below FINI is
XYTYPE where such addressing modes as LDA $5000,Y are
analyzed.
They too require some opcode adjustments before going to
TWOS or THREES for printing and POKEing. We JMP to
XYTYPE after having found a comma in a source code line like:
LOA SCREEN,X
and so the Y Register is pointing to the character just beyond
the comma when we arrive at XYTYPE. All we need to do is
load BUFFER, Y to check if the character following the comma is
an X or a Y. If it's an X, we jump down to L720 which handles
X type modes.
Otherwise, we're dealing with something involving a Y
addressing mode. It might be this:
LOA (15),Y
so we have to check for the right parenthesis. We DEY DEY to
move over to just in front of the comma and see if there's a )
symbol. If not, we've got a Zero Page Y addressing mode like
LDX IO,Y or STX IO,Y. LDX and STX are the only two
52
Eval: The Main Loop
How P Works
P prints the current PC on screen, but doesn't destroy what's in
the A, Y, or X Registers. Saving A, Y, and X is straightforward
enough (5520), but where is the PC?
Whenever you JSR, the return address is pushed onto the
stack. We can pull it off the stack with PLA, transferring its two
bytes (one to the X Register and one to the Accumulator), and
then push it back on with PHA. That leaves the stack ready to
RTS correctly, but a copy of this RTS address is now in the reg-
isters as well, OUTNUM is a BASIC routine which normally
prints line numbers during BASIC's LIST. But it will print any
integer number if the low byte is in X and the high byte is in A.
(See Atari notes for Atari's OUTNUM.)
Character $BA on Commodore machines is a check graph-
ics symbol (v) , and it's a convenient way to show that what
53
Eval: The Main Loop
54
Program 3-1. Eval
HI ~ II EVAL" MAIN EVALUATION ROUTINE (SIMPLE ASSEMBLER)
20 ~---------------------------------------------------------------
30 START LDA #0
40 LDY #48
50 STRTLP STA OP,Y~ LOOP TO CLEAR FLAGS --
60 DEY
70 BNE STRTLP~ --------
80 LDA #<START~ STORE BOTTOM OF LADS INTO TOP OF ARRAY/ MEMORY. PROTECT IT.
90 STA MEMTOP
100 STA BMEMTOP
110 STA ARRAYTOP
120 LDA #>START
130 STA MEMTOP+1
140 STA BMEMTOP+1
150 STA ARRAYTOP+1~--------
160 LDA #l~ -- SET DEFAULTS --
170 ~ HERE YOU CAN SET ANY ADDITIONAL DEFAULTS YOU WISH
180 STA HXFLAG~ TURN ON HEX LISTING FLAG
190 STM0 LDA SCREEN,Y~ -- GET SOURCE FILE NAME
200 CMP #32 ~
III
210 BEQ STM1~ CHECK FOR ANOTHER BLANK
220 BCS STM3
230 CLC
-;2
~
240 ADC #64~ ADJUST FOR LOW ASCII CHARACTERS
250 STM3 STA FILEN,Y~ STORE CHARACTER IN FILENAME BUFFER ~
III
260 INY 5'
270 JMP STM0~ GET ANOTHER CHARACTER
280 STM1 STA FILEN,Y~ CHECK FOR 2ND BLANK b
~ 290 INY o
"0
c.n 300 LDA SCREEN,Y
0' ~
310 CMP #32; IF NO 2ND BLANK SPACE ;.
320 BNE STM0; THEN GO BACK FOR MORE NAME (MIGHT BE 2 WORDS) ...,
330 DEY
340 STY FNAMELEN; STORE FILENAME LENGTH
::r
~
350 JSR OPEN1; OPEN READ FILE (SOURCE CODE FILE ON DISK)
~
360 ;------------------ RE-ENTRY POINT FOR PASS 2 ------- ~
370 SMORE JSR GETSA; POINT DISKFILE TO 1ST CHARACTER IN SOURCE CODE S·
380 LDA #0
390 STA ENDFLAG; SET LADS-IS-OVER FLAG TO DOWN b
o
400 JSR INDISK; GET A SINGLE LINE OF SOURCE CODE 'tl
410 LDA PASS; IF 2ND PASS
420 BNE STARTLINE; THEN JUMP OVER PRINTING OF LADS NAME
430 JSR PRNTCR; PRINT CARRIAGE RETURN
440 LDA #230; PRINT BLOCK GRAPHICS SYMBOL
450 JSR PRINT
460 LDA #76; L
470 JSR PRINT
480 LDA #65; A
490 JSR PRINT
500 LDA #68; D
510 JSR PRINT
520 LDA #83; S
530 JSR PRINT
540 JSR PRNTCR; ANOTHER CARRIAGE RETURN
550 CKHEX LDA HEXFLAG; IF START ADDRESS NUMBER IS HEX, IT'S ALREADY TRANSLATED
560 BNE STAR1
570 LDA #<LABEL; IN THE LABEL BUFFER IS SOMETHING LIKE: *= 864
580 STA TEMP; PUT THE ADDRESS OF THE BUFFER INTO THE POINTER CALLED TEMP
590 LDA #>LABEL
600 STA TEMP+1
610 JSR VALDEC: TURN ASCII NUMBER INTO A TWO-BYTE INTEGER IN "RESULT"
620 STARI LDA RESULT: -- STORE OBJECT CODE'S STARTING ADDRESS IN SA,TA
630 STA SA
640 STA TA
650 LDA RESULT+l
660 STA SA+l
670 STA TA+l
680 ;---------------- ENTRY POINT FOR EACH NEW LINE OF SOURCE CODE
690 STARTLINE JSR STOPKEY:LDA ENDFLAG:BEQ EVIND:JMP FINI: END LADS ASSEMBLY IF
700 : EITHER THE STOP (BREAK) KEY IS PRESSED OR IF THE ENDFLAG IS UP.
710
720 EVIND JSR INDISK: OTHERWISE GO TO PULL IN A LINE FROM SOURCE CODE
730 LDA #0
740 STA EXPRESSF: SET DOWN THE FLAG THAT SIGNALS A LABEL ARGUMENT LIKE LDA P
750 STA BUFLAG: SET DOWN THE FLAG THAT SIGNALS # OR ( DURING ARRAY CHECK.
760 LDY PASS:ON PASS 1, WE DON'T PRINT LINE NUMBERS, ADDR. OR ANYTHING ELSE
770 BNE MOREEV
780 JMP MOE4
790 MOREEV STY LOCFLAG: ZERO ADDRESS-TYPE LABEL FLAG (LIKE: LABEL INY)
800 THIS IS FOR THE INLINE SUBROUTINE BELOW.
810 LOA SFLAG; SHOULD WE PRINT TO THE SCREEN
820 BEQ MX; IF NOT, SKIP THIS PART ~
830 JSR PRNTLINE; PRINT LINE NUMBER ~
840 JSR PRNTSPACE; PRINT SPACE
850 JSR PRNTSA; PRINT PC (PROGRAM COUNTER)."SA" IS THE VARIABLE. ~
860 JSR PRNTSPACE
870 MX LOA PLUSFLAG; DO WE HAVE A + PSEUDO OP ~
III
880 BEQ MOE4; IF NOT SKIP Er
890 JSR MATH; IF SO, HANDLE IT IN SUBPROGRAM "MATH"
CJ1
900 MOE4 JMP FINDMN; LOOK UP MNEMONIC (OR, NOT FINDING ONE, IT'S A LABEL) b
o
'.J 910 -------- EVALUATE ARGUMENT '0
U1
00 920 EVAR LDA TP
930 BEQ TPIJMP~ CHECK TYPE, IF 0, NO ARGUMENT ~
940 CMP #3~ IF NOT TYPE 3, THEN CONTINUE EVALUATION ~
950 BNE EVGO ;i
960 LDA #1~ OTHERWISE, REPLACE 3 WITH 1 IN TP (TYPE) (I)
970 STA TP
980 LDA LABEL+3~ IS THERE SOMETHING (NOT A ZERO) IN 4TH POSITION ~
990 BNE EVGO~ EVGO = ARGUMENT {IF NOT, THERE ' S NO ARGUMENT,IT'S IMPLIED ~r
1000 LDA #8; OTHERWISE, RAISE OP (OPCODE) BY 8
1010 CLC b
o
1020 ADC OP 'e
1030 STA OP
1040 TPIJMP JMP TPl~ AND JUMP TO TYPE 1 (SINGLE BYTE TYPES)
1050 ~------------------
1060 EQLABEL LDA PASS~ MOE4 FOUND IT TO BE A LABEL, NOT A MNEMONIC
1070 BEQ EQLABl~ ON PASS 1 WE DON'T CARE WHICH KIND OF LABEL IT IS SO WE
1080 LOY #255~ GO DOWN AND STORE IT IN THE ARRAY (VIA EQLABl)
1090 EVXl INY~ BUT ON PASS 2, WE NEED TO DECIDE IF IT'S A PC ADDRESS TYPE
1100 LOA LABEL,Y~ LABEL (LIKE: LABEL INY) OR AN EQUATE TYPE (LABEL = 15)
1110 BEQ GONOAR~ SO IN THIS LOOP WE LOOK FOR A BLANK WHILE STORING THE
1120 STA FILEN,Y~ LABEL NAME IN THE "FILEN" BUFFER. IF WE FIND A 0, IT'S
1130 CMP #32~ A NAKED LABEL (NO ARGUMENT TO IT) WHICH CAUSES US TO PRINT
1140 BNE EVXl~OUT THAT ERROR MESSAGE {AT NOAR, IN EQUATE).OTHERWISE, WE FIND A
1150 INY~ BLANK AND FALL THROUGH TO THIS LINE.
1160 LOA LABEL,Y~ WE RAISE Y BY 1 AND CHECK FOR AN = SIGN.
1170 CMP #$3D
1180 BNE NOTEQ~ IF NOT, IT'S A PC ADDRESS TYPE (SO SET LOCFLAG)
1190 JMP INLINE~ IF SO,WAS = TYPE SO IGNORE IT (ON PASS 2) ----------
1200 NOTEQ LOX #0
1210 STX LOCFLAG~(SHOWS PRINTOUT TO DO THIS TYPE OF LABEL ON SCREEN/PRINTER)
1220 TXA~ PUT A ZERO IN AT THE END OF THE LABEL NAME (AS A DELIMITER)
1230 STA FILEN,Y; NOW WE HAVE TO MOVE THE ARGUMENT PORTION OF THIS LINE
1240 EVX5 LDA LABEL,Y; OVER TO THE START OF THE "LABEL" BUFFER FOR FURTHER
1250 BEQ EVX4; ANALYSIS (0 DELIMITER HERE)
1260 STA LABEL,X; WE CAN IGNORE THE PC LABEL (THIS IS PASS 2), BUT WE
1270 INX; NEED TO EVALUATE THE REST OF THE LINE FOLLOWING THAT LABEL.
1280 INY
1290 JMP EVX5;-------------------
1300 EVX4 STA LABEL,X
1310 JMP MOE4; JUMP TO CONTINUE EVALUATION
1320 GONOAR JSR NOAR; PRINT NO ARGUMENT MESSAGE (A SPRINGBOARD);----------
1330 EQLABI JSR EQUATE; PUT LABEL AND IT'S VALUE INTO THE ARRAY (PASS 1)
1340 JMP MOE4; CONTINUE EVALUATION
1350 ;------------------ TRANSLATE ARGUMENT LABELS INTO NUMBERS
1360 EVE XLAB LDA BUFFER; IS THIS 1ST CHARACTER ALPHABETIC (>64)
1370 CMP #64
1380 BCS EVEl; IF SO, GO DOWN TO FIND ITS VALUE .
1390 LDA BUFFER+l; IF NOT, IT MUST HAVE BEEN A ( OR # SYMBOL
1400 INC BUFLAG; TO TELL ARRAY THAT ( OR # WAS FOUND (AND TO IGNORE THEM)
1410 EVEI EOR #$80; SET 7TH BIT IN 1ST CHAR. (TO MATCH ARRAY STORAGE METHOD)
1420 STA WORK; SAVE IT HERE TEMPORARILY TO COMPARE WITH ARRAY WORDS
1430 JSR ARRAY; EVAL. EXPRESSION LABEL, SHIFTED 1ST CHAR.
1440 JMP L340; THEN CONTINUE ON WITH EVALUATION (AFTER VALUE IS IN "RESULT") ~
III
1450 ;--------------- IS ARGUMENT NUMERIC OR A LABEL -
1460 EVGO LDY #0 ;i
1470 STY EXPRESSF; TURN OFF THE "IT'S A LABEL" FLAG (b
5270 ; ---------- SEE CHAPTER 11 FOR EXPLANATION OF THIS ERROR TRAP ------ ~
5271 L760 LOA BUFFER+2,Y:CMP #89:BNE ML760; --- ERROR TRAP FOR LOA (15,y) III
5272 LOA OP:CMP #182:BEQ ML760; IS THE MNEMONIC LOX (IF SO, MODE IS CORRECT) :r
5273 JMP L680; IF NOT, JUMP TO MAKE IT (LDA $0015,y) ABSOLUTE Y
5274 ML760 JMP TWOS
ro
'1j
5275 ,-----------------------------------
5280 L780 LOA TP
5290 CMP #2
5300 BNE L790
5310 LOA #24
5320 CLC
5330 ADC OP
5340 STA OP
5350 JMP THREES
5360 L 790 CMP #l
5370 BEQ L809
5380 CMP #3
5390 BEQ L809
5400 CMP #5
5410 BEQ L809
5420 L800 LOA #$33
5430 JSR P
5440 JMP L700
5450 L809 LOA #28
5460 CLC
5470 ADC OP
5480 STA OP
5490 JMP THREES; END OF ADDR. MODE EVALUATIONS AND ADJUSTMENTS
5500
5510 ;-------------------- ERROR REPORTING FOR DEBUGGING (PRINTS PC)
5520 P STA A; WHEN YOU INSERT A "JSR pOI INTO YOUR SOURCE CODE, THIS ROUTINE
5530 STY Y; WILL PRINT THE PC FROM WHICH YOU JSR'ED.
5540 STX X: AFTER AN RTS, THIS WILL REVEAL THE JSR ADDR.
5550 LDA #$BA; PRINT A GRAPHICS SYMBOL TO SIGNAL THAT THE PC IS TO FOLLOW
5560 JSR PRINT
5570 PLA; SAVE THE RTS ADDRESS (TO KEEP THE STACK INTACT)
5580 TAX
5590 PLA
5600 TAY
5610 TYA
5620 PHA
5630 TXA
5640 PHA
5650 TYA
5660 JSR OUTNUM; PRINT THE PC ADDRESS.
5670 LDA A; RESTORE THE REGISTERS.
5680 LDY Y
5690 LDX X ~
III
5700 RTS :-:-
5710 ,---------------------------
5720 CLEANLAB LDY #0; FILLS MAIN INPUT BUFFER ("LABEL") WITH ZERO. CLEANS IT. ~
rn
5730 TYA
5740 CLEMORE STA LABEL,Y ~
5750 INY S·
5760 CPY #80
'1
5770 BNE CLEMORE b
o
W 5780 RTS '1j
'-l
.,.. 5790 : ---------PRINT BRANCH OUT OF RANGE ERROR MESSAGE--------------
5800 DOBERR JSR PRNTCR: PRINT "BRANCH OUT OF RANGE" ERROR MESSAGE ~
5810 JSR ERRING ~
5820 JSR PRNTLINE: PRINT THE LINE NUMBER
5830 LDA #<MBOR: POINT "TEMP" TO THE ERROR MESSAGE "MBOR" ;l
('I)
5840 STA TEMP: (MESSAGE BRANCH OUT OF RANGE, MBOR)
5850 LDA #>MBOR ~
5860 STA TEMP+l !!:.
5870 JSR PRNTMESS: PRINT THE MESSAGE ='
5880 JSR PRNTCR: PRINT A CARRIAGE RETURN AND b
5890 o
JMP TWOS: BUNGLE AS AN ORDINARY 2-BYTE EVENT (TO KEEP PC CORRECT) '0
5900 ,-----------------------------
5910 .FILE EQUATE
79
Equate and Array: Data Base Management
80
Equate and Array: Data Base Management
Equate
The Equate subprogram starts off with one of those LDY #255
initializations. Remember that we don't always want to LDY #0
before a loop. There are times when the first event is the zeroth
event. This is one of those times .
Line 40 sets Y to 255 so the INY in line 50 will make Y =
O. This allows us to LDA LABEL,Y and receive the first charac-
ter in the buffer called LABEL. If we had set Y=O, the INY
would have forced us to look at the second character in the
buffer. Why not put the INY lower in the loop somewhere?
That way, we would load in the first character the first time
through the loop.
Obviously we can't INY just before the BNE in line 90.
That would branch depending on the condition of Y itself, not
on the item in A (which is our intention). For the same reason,
we can't put it just before the BEQ in line 70. The only other
safe place for it would be in a line between 70 and 80. That
wouldn't do any damage to the branches because the eMP will
reset the flags and the following BNE will act correctly.
This loop isn't moving characters from one buffer to an-
other or anything. Its sole purpose is to count the number of
characters in a label name, to find the length of the label. Y is
the counter.
While locating Y in a line 75 would work correctly, it
would be less clear what the loop is accomplishing. In cases
like this, you have to decide where your personal priorities lie:
Do you want to emphasize the function of a routine in a way
that's more easily understood, or do you want to emphasize a
uniform style of coding loops? If you prefer to always start such
loops with LDY #0, by all means, go ahead. But that LDY #255
serves to alert you that this loop is a special kind of loop . If you
come back later to modify a program, such signals can be
helpful.
81
Equate and Array: Data Base Management
82
Equate and Array: Data Base Management
Address or Equate?
Now we load the second character and check if it's a space
(260-280). We might be dealing with a one-character-Iong label,
like P. We've got to check for this eventuality. Finding such a
short label, we would jump down to see if there's an = sign.
But if the label is more than one character long, we store the
second letter in the array (290) and jump back up to fetch and
store the third and any additional letters in the label name.
The essential thing to notice here is that a space is our
delimiter in the buffer-letting us know when we've reached
the end of the label word. And after finding a space, we are
then prepared to distinguish between the two types of labels:
PC and equate.
We compare the character following the space to $3D (this
is the = sign). If it is an = sign, we branch to the routine
83
Equate and Array: Data Base Management
Equate Labels
If we're not dealing with a PC-type label, though, we come
here to store an equate label like LABEL = $22 (590) into the
84
Equate and Array: Data Base Management
Array
The Array subprogram is essentially a search routine. It looks
up a label's name in the array that was built by the Equate sub-
program. When it finds a match, it puts the integer value of the
array word into the variable RESULT. In effect, Array replaces a
85
Equate an d Array: Data Base Management
86
Equate and Array: Data Base Management
87
Equate and Array: Data Base Management
Double Decrement
Let's pause a minute to look at how a double decrement works
(280-310). If, upon loading the low byte of PARRAY, the zero
flag is set, we would be forced to lower the high byte of
PARRAY (PARRAY + 1 in line 300). If the low byte isn't yet
lowered to zero, however, we can just lower the low byte and
ignore the high byte (310). Note that a zero in the low byte re-
quires lowering both the high and low bytes. Correctly
decrementing $8500 would result in $84FF, lowering both
bytes, while a correct decrement of $8501 would just lower the
low byte: $8500.
Once we have located a set seventh bit, thus locating the
start of a label name, we come to the FOUNDONE subroutine
(350). Here we must first store PARRAY into the temporary
holding variable PT so we can remember exactly where the la-
bel name begins. Then we reload A with the first character of
the label (390) and compare it against the first character of the
label we're looking for. That first character was previously in
the variable WORK just before we came to Array from Eval.
If these first characters match, we go to LKMORE to check
the rest of the word for a full match . If not, we go to
STARTOVER.
In LKMORE, we first raise X to be the correct length of the
current array label under examination. Then we save it in the
variable WORK + 1. We've got to save it at this point because
now X will serve as the counter of the source label length. The
88
Equate and Array: Data Base Management
source label is the word we're looking for, the label from the
source code we're trying to find a match to.
The fact that some labels will be like (LABEL),Y or #LABEL
(having a ( or # as their first character) is a potential source of
confusion to the Array search routine. To eliminate this confu-
sion, whenever a ( or # is encountered during the Eval sub-
program, a special flag, BUFLAG, is raised. That makes it easy
for us to skip over them here by raising the Y offset (490) if
necessary.,
Paradoxically, we simply INY again, right after this. That's
because we want to point to the second character in the label
(we got this far because the first characters matched). Neverthe-
less, the combination of INY and DECPAR (490-500) effectively
takes care of the ( or # situation and makes this INY point to
the second letter of the label proper.
The LKM1 loop compares the entire rest of the source label
against the array label (520-600) . There are three ways, and
only three ways, for us to get out of this loop. We can come
upon a zero, which would surely be the end of the label in the
buffer (the source label). A zero always means the end of a line
of source code. Or we can come upon a character which is
lower than 48. That includes things like left parentheses and
commas in the ASCII code. Something like the comma in LDA
LABEL,X would signal the end of the source label. (Checking
for characters lower than 48, however, doesn't exclude num-
bers. We can still check for such legal labels as: LDA LABEL12.)
89
Equate and Array: Data Base Management
Pseudo-op Adjustments
Here's where we make the adjustments for two of our pseudo-
ops: > < and +. If BYTFLAG is set, it means that < or> was
used to request the low or high byte of a label. LDA #<LABEL
requests the low byte (and Eval will only deal with low bytes
in the # Immediate addressing mode). The label's low byte is
already in the low byte of RESULT, so we need do nothing. But
BYTFLAG is a special kind of flag. It has three states rather
90
Equate and Array: Data Base Management
91
Equate and Array: Data Base Management
that means that it's still holding the $FF we put there at the
very start of Array. We never found the match . We check the
PASS, and if it's pass 2, we print the line number and the
NOLAB error message "undefined label."
Then, no matter which pass it is, we still want to keep the
program counter straight, or all the rest of the assembly will be
off. The problem is that an undefined label doesn't give us the
answer to the question: Is this a three-byte ordinary address or
a two-byte zero page address? Is it LDA 15 or LDA 1500?
Should we raise the PC by two or by three? If we raise it the
wrong amount, any future reference to address-type labels will
be skewed. Here's why:
100 *= 800
110 LOA LABEL; this label is undefined
120 ADDRESS INY; what is the location of ADDRESS here?
If LABEL is in zero page, ADDRESS = 802. If LABEL is
not zero page, ADDRESS = 803 . We should try to get this
right on pass 1. Pass 2 depends on pass 1 for correct label val-
ues, including address-type labels. Even if a label is not yet de-
fined, we should still try to raise the program counter by the
correct amount.
In Eval there are routines called TWOS and THREES.
TWOS raises the PC by two bytes for Zero Page and other two-
byte-long addressing modes like LDA #15. THREES handles
three-byte-Iong modes like Absolute addresses, etc. It's here in
the Array subprogram, however, that we have to decide which
of these routines to jump back to in Eval.
Branches like BNE and BEQ will often be undefined during
pass 1 because the program is branching forward. We'll want to
go to TWOS if there's an undefined label following a branch
instruction. All branches are type 8, and we can easily check for
them by LDA TP:CMP #8 (860) . The other possible TWOS can-
didate is one of the > or < pseudo-ops. BYTFLAG signals one
of them.
92
Equate and Array: Data Base Mana gemen t
93
':f2 Program 4-1. Equate tTl
.g
III
10 "EQUATE" EVALUATE LABELS ....
rP
20 : COULD BE EITHER PC (ADDRESS) TYPE OR EQUATE TYPE. STORE IN ARRAY. III
25 : FORMAT--NAME/2-BYTE INTEGER VALUE/NAME/2-BYTE VALUE/ETC ... ::l
p...
30 :-------------
40 EQUATE LDY #255: PREPARE Y TO ZERO AT START OF LOOP ~
50 EQl INY: Y GOES TO ZERO 1ST TIME THROUGH LOOP "1
60 LDA LABEL,Y: LOOK AT THE WORD, THE LABEL ~
70 BEQ NOAR: END OF LINE (SO THERE'S A NAKED LABEL, NOTHING FOLLOWS IT)
80 CMP #32: FOUND A SPACE, SO RAISE Y BY 2 AND SET LABEL SIZE (LABSIZE) d
III
90 BNE EQ1: OTHERWISE, KEEP LOOKING FOR A SPACE.
....
III
100 INY b:1
110 INY III
rP
'"
120 STY LABSIZE
130 :-------------------- LOWER MEMTOP POINTER WITHIN ARRAY (BY LABEL SIZE) ~
III
140 SUBMEM SEC: SUBTRACT LABEL SIZE FROM ARRAY POINTER TO MAKE ROOM FOR LABEL ::l
150 LDA MEMTOP III
(JQ
160 SBC LABSIZE rP
170 STA MEMTOP S
rP
180 LDA MEMTOP+l ::l
....
190 SBC #0
200 STA MEMTOP+l:--------------
205 :SHIFT 7TH BIT OF 1ST CHAR. TO SIGNIFY START OF LABEL'S NAME
210 LDY #0
220 LDA LABEL,Y
230 EOR #$80
240 STA (MEMTOP),Y: STORE SHIFTED 1ST LETTER
250 EQ3 INY
260 LDA LABEL,Y: IF SPACE, STOP STORING LABEL NAME IN ARRAY.
270 CMP #32
280 BEQ EQ2
290 STA (MEMTOP),Yi OTHERWISE, PUT NEXT LETTER INTO ARRAY &
300 JMP EQ3i CONTINUE.
310 EQ2 INYi NOW CHECK FOR = (SIGNIFYING EQUATE TYPE) (LABEL 15)
320 LDA LABEL,Y
330 CMP #$3Di IF EQUATE TYPE, GO TO FIND ITS VALUE.
340 BEQ EQUAL
350 DEYi OTHERWISE, IT'S PC TYPE (LABEL LDA 15)
360 LDA SAi SO THE PC VARIABLE (SA) CONTAINS THE VALUE OF THIS LABEL
370 STA (MEMTOP),Yi STORE IT RIGHT AFTER LABEL NAME WITHIN ARRAY.
380 INY tTJ
..0
390 LDA SA+1 !:
III
400 STA (MEMTOP),Y ....
~
410 LDX LABSIZEi NOW, USING LABELSIZE AS INDEX, ERASE THE PC-TYPE LABEL III
420 DEXi FROM THE BUFFER. FOR EXAMPLE, (LABEL LDA 15) NOW ::l
0-
430 LDY #0i BECOMES (LDA 15). THE LABEL NAME IS COVERED OVER
440 EQ5 LDA LABEL,Xi TO PREPARE THE REST OF THE LINE TO BE ANALYZED
450 BEQ EQ4i NORMALLY BY EVAL. ...~
460 STA LABEL,Y ~
470 INX d
480 INY III
....
III
490 JMP EQ5
500 EQ4 STA LABEL,Y tP
III
510 RTSi RETURN TO EVAL ------------------------- 'Il
~
520 NOAR JSR PRNTCR:JSR PRNTLINE;NAKED LABEL FOUND (NO ARGUMENT) SO
525 JSR ERRING ~
III
530 LDA #<NOARGi RING BELL AND PRINT NAKED LABEL ERROR MESSAGE. ::l
540 STA TEMP III
(JQ
~
550 LDA #>NOARG
560 STA TEMP+1 :3
~
~ 570 JSR PRNTMESS:JSR PRNTCR ::l
....
\D 580 JMP EQRET~ RETURN TO EVAL----------------------- tTl
Q'\
584 '§
585 Pol
.....
~--------------- HANDLE EQUATE TYPES HERE (LABEL = 15)
(1)
590 EQUAL DEY Pol
600 STY LABPTR~ TELLS US HOW FAR FROM MEMTOP WE SHOULD STORE ARGUMENT VALUE ~
610 LDA HEXFLAG~ HEX NUMBERS ALREADY HANDLED BY INDISK ROUTINE, SO SKIP OVER. 0-
620 BNE FINEQ~ HEX FLAG UP, SO GO TO EQUATE EXIT ROUTINE BELOW.
630 INY~ OTHERWISE, WE NEED TO FIGURE OUT THE ARGUMENT (LABEL = 15) ~
"1
640 INY~ THERE ARE THREE CHARS. ( = ) BETWEEN LABEL & ARGUMENT, SO
~
650 INY~ INY THRICE.
660 STY WORK+l~ POINT TO LOCATION OF ASCII NUMBER (IN LABEL BUFFER) tj
Pol
.....
670 LDA #<LABEL~ SET UP TEMP POINTER TO POINT TO ASCII NUMBER Pol
680 CLC tp
690 ADC WORK+l Pol
(1)
'"
700 STA TEMP
710 LDA #>LABEL ~
720 ADC #0 Pol
~
730 STA TEMP+l
740 JSR VALDEC~ CALCULATE ASCII NUMBER VALUE AND STORE IN RESULT
£
(1)
750 FINEQ LDY LABPTR~ STORE INTEGER VALUE JUST AFTER LABEL NAME IN ARRAY 8
(1)
760 LDA RESULT ~
770 STA (MEMTOP),Y .....
780 LDA RESULT+l
790 INY
800 STA (MEMTOP),Y
810 EQRET PLA~PULL OFF THE RTS (FROM EVAL) AND JUMP DIRECTLY TO INLINE
820 PLA~ IGNORING ANY FURTHER EVALUATION OF THIS LINE SINCE EQUATE TYPE
830 JMP INLINE~ LABELS ARE FOLLOWED BY NOTHING TO EVALUATE
840 .FILE ARRAY
For the Atari version of Equate, change line 840 to: 840 .FILE D:ARRAY.SRC
Program 4,2. Array
10 ; "ARRAY" LOOKS THROUGH LABEL TABLE AND PUTS VALUE IN RESULT.
20 (USED IN BOTH PASS 1 AND PASS 2)
30 ARRAY LDA ARRAYTOP;PUT TOP-OF-ARRAY VALUE INTO THE DYNAM IC POINTER (PARRAY)
40 STA PARRAY; IN OTHER WORDS, MAKE PARRAY POINT TO THE HIGHEST WORD IN THE
50 LDA ARRAYTOP+1; LABEL ARRAY
60 STA PARRAY+l
70 JSR DEC PAR
80 LDA #$FF; SET UP FOR BMI TEST IF NO MATCH FOUND
90 STA FOUNDFLAG tIi
..c
100 STARTLK SEC; START LOOKING FOR LABEL NAME t:
~
110 LDA MEMTOP; CHECK TO SEE IF WE'RE AT THE BOTTOM OF THE ARRAY .....
(b
120 SBC PARRAY ~
130 LDA MEMTOP+l ::l
0-
140 SBC PARRAY+l
150 BCS ADONE; IF SO, CHECK IF WE FOUND THE LABEL (OR FOUND IT TWICE) ~"'I
160 LDX #0; SET LABEL NAME SIZE COUNTER TO ZERO
170 SEC; GO DOWN 2 BYTES IN MEMORY (PAST THE INTEGER VALUE OF A LABEL) ~
180 LDA PARRAY tj
190 SBC #2 ~
~
200 STA PARRAY
210 LDA PARRAY+l OJ
~
220 SBC #0 (b
'"
230 STA PARRAY+ 1
240 LDY #0 ~
~
250 ;-------------------------- ::l
~
260 LPAR LDA (PARRAY),Y; LOOK FOR A 7TH BIT SET (START OF LABEL NAME) IJQ
(b
270 BMI FOUNDONE; IF YES, WE'VE GOT TO THE START OF A NAME.
280 LDA PARRAY; OTHERWISE GO DOWN 1 BYTE IN ARRAY S
(b
\.D
"'I 290 BNE MDECX ::l
.....
300 DEC PARRAY+1 t'T1
00
'" 310 MDECX DEC PARRAY .g
320 INX; INCREASE LABEL NAME SIZE COUNTER ~
~
330 JMP LPAR
III
340 ,------------------------ ::l
350 FOUNDONE LDA PARRAY; WE'VE LOCATED A LABEL NAME IN THE ARRAY p..
360 STA PT; REMEMBER IT'S STARTING LOCATION
370 LDA PARRAY+1 ~
'1
III
380 STA PT+1 ~
390 LDA (PARRAY), Y
400 CMP WORK; COMPARE THE 1ST LETTER WITH THE 1ST LETTER OF THE TARGET HORD d
III
~
410 BEQ LKMORE; LOOK MORE CLOSELY AT THE WORD, IF 1ST LETTER MATCHED III
420 JMP STARTOVER; IF IT DIDN'T MATCH, GO DOWN IN THE TABLE & FIND NEXT WORD. ttl
430 ,---------------------------- III
LKMORE INX; RAISE LENGTH COUNTER BY 1 ~
'"
440
450 STX WORK+1; REMEMBER IT ~
460 LDX #1 III
::l
470 LDA BUFLAG; THIS MEANS THAT # OR ( COME BEFORE THE NM1E IN THE BUFFER III
at<
480 BEQ LKM1; IF THEY DON'T WE DON'T NEED TO RAISE Y IN ORDER TO IGNORE THEM (l>
490 INY 3
(l>
500 JSR DECPAR; LOWER THE INDEX TO COMPENSATE FOR THE INY ::l
~
510
520 LKM1 INY
530 LDA BUFFER,Y; CHECK BUFFER-HELD LABEL
540 BEQ FOUNDIT; IF WE'RE AT THE END OF THE WORD (0), THEN WE'VE FOUND A MATCH
550 CMP #48; OR THERE'S A MATCH IF IT'S A CHARACTER LOWER THAN ASCII 0 (,OR+)
560 BCC FOUNDIT
570 ; NOT YET THE END OF THE "BUFFER" HELD LABEL
580 INX
590 CMP (PARRAY),Y; IF ARRAY HORD STILL AGREES iVITH BUFFER WORD, THEN
600 BEQ LKM1; CONTINUE LOOKING AT THESE WORDS
610 ;--------------------------- NO MATCH , SO LOOK AT NEXT WORD DOWN
620 STARTOVER LDA PT; PUT PREVIOUS WORD'S START ADDR. INTO POINTER
630 STA PARRAY
640 LDA PT+l
650 STA PARRAY+l
660 JSR DECPAR; LOWER POINTER BY 1 (STARTLK WILL LOWER IT ALSO, BELOW VALUE)
670 JMP STARTLK; TRY ANOTHER WORD IN THE ARRAY
680 I
._----------------------
690 ADONE LDA FOUNDFLAG
700 BMI ADl; DIDN'T FIND THE LABEL
710 RTS; ALL IS WELL. RETURN TO EVAL. tT1
.0
720 ADI LOA PASS :::
III
730 ~
BNE AOIX; 2ND PASS-- GO AHEAD A~D PRINT ERROR MESSAGE
740 BEQ ADONEl; ON 1ST PASS, MIGHT NOT YET BE DEFINED (RAISE I~CSA/2S OR 3S) I~
750 ADIX JSR ERRING; LABEL NOT IN TABU:. (TREAT IT AS A 2-BYTE ADDRESS) ::l
0-
760 JSR PRNTLINE
770 JSR PRNTSPACE
780 LOA #<NOLAB
..,~
III
790 STA TEMP -<
800 LDA #>NOLAB U
810 STA TEMP+l III
~
820 JSR PRNTMF.SS; RING BELL AND PRINT NOT FOUND MESSAGE III
830 JSR PRNTCR to
III
840 ADONEI PLA rtl
850 PLAi
'"
860 LDA OP ~
III
870 AND #31 ::l
III
880 CMP #16 (JQ
rtl
890 BEQ AD02; CHECK IF BRANCH INSTRUCT.
900 LOA BYTFLAG :3
rtl
\0
\0 910 BNE AD02; < OR > PSEUDO ::l
~
>-' t'Ii
o 920 JMP THREES
o 930 AD02 JMP TWOS .g
940 ; ~
~
950 FOUNDIT CPX WORK+l;CHECK LABEL LENGTH AGAINST TARGET WORD LENGTH
960 BEQ FOUNDF; THEY MUST EQUAL TO SIGNIFY A MATCH. (PRINT / PRIN WOULD FAIL) ~
970 JMP STARTOVER; FAILED MATCH P-
980 FOUNDF INC FOUNDFLAG; RAISE FLAG TO ZERO (FIRST MATCH)
990 BEQ FOFX; IF HIGHER THAN 0, PRINT DUPLICATION LABEL ERROR MESSAGE ~
'1
1000 JSR DUPLAB ~
1010 FOFX LDY WORK+l
tj
1020 LDA BUFLAG; COMPENSATE FOR # AND
1030 BEQ FOF ~
~
1040 INY OJ
1050 FOF LDA (PARRAY),Y; PUT TABLE LABEL'S VALUE IN RESULT ~
00
~
1060 STA RESULT
1070 INY ~
~
1080 LDA (PARRAY),y ::3
1090 STA RESULT+l ~
Il'Q
111313 LDA BYTFLAG ~
tJ:j
~
'Il
~
....... 3
o ~
....... ::l
.....
-
Open 1, Findm.n, Getsa,
and Valdec:
I/ O Management and
N umber Conversions
I/0 (Input/Output), a computer's method of communicating
with its peripherals, is one of the most machine-specific and
potentially complex aspects of machine language programming.
Sending or receiving bytes to or from disk or tape drives
and sending bytes to a printer are the most common I/0 activ-
ities. A large part of a computer's ROM memory is usually de-
voted to managing I/ O.
I/O is machine-specific because each manufacturer invents
his own way of managing data, his own variations on the
ASCII code, and his own disk or tape operating systems.
And I/O is complex because printers and disk and tape
drives differ greatly in such things as how fast they can store
bytes, how many bytes they can accept, and esoteric matters
like timing, error checking, and special control signals.
ML programmers are frequently advised to perform I/O
operations in BASIC and then SYS, CALL, or USR into the ML
after the hard part has been accomplished by the computer's
operating system. This works well enough with small ML
projects. But it can become awkward in a large ML program.
LADS itself must open and close disk files pretty often. It
would be inefficient to require LADS to fly down into an at-
tached BASIC program for this. Also, large ML programs are
easiest to save, load, and use if they are written entirely in ML.
Fortunately, we can access BASIC's ROM routines from
within an ML program. Certain registers and pointers in zero
page need to be set up, then we can JSR to open a file to a
peripheral. After that, we can send or receive bytes from that
file .
Since these routines are so machine-specific, we'll look at
the Commodore techniques in this chapter. See Appendix C for
an explanation of the Atari and Apple I/O techniques.
105
Open!, Findmn, Getsa, and Valdec: I/O Management
Commodore I/O
Some peripherals are intelligent and some are dumb. Com-
modore disk drives are highly intelligent-they've got large
amounts of RAM and ROM memory. One consequence of this is
that relatively little I/O computing needs to be done within the
computer proper. A Commodore disk drive is a little computer
itself. You can just send it a command, and it takes over from
there.
The tape drives, though, are dumb. ROM intelligence within
the computer must manage I/O to tape. Some printers aren't so
dumb, but since you can choose from so many different models
and brands, the computer just sends out a sequence of raw bytes
when you print to a printer. Your BASIC or operating system
makes no effort to control fonts, formatting, or any other special
printer functions. You are expected to send any necessary printer
control codes via your software. If the printer is equipped to TAB
or justify text, that's up to the printer's ROM.
Open!
In the subprogram Open1, there are four Commodore-specific
subroutines. In many respects, they are identical subroutines.
Each opens a file to an external device in much the same way.
Only the specifics differ. The first subroutine, OPEN1, starts
communication with a disk file which will be read. That is, the
source code will come streaming in from this file so that LADS
can assemble it. This file will be referred to as file 1.
The second subroutine, OPEN2, opens file 2 as a write file.
If the user includes the .D NAME pseudo-op within his source
code, the results of a LADS assembly, the object code, will be
stored on disk in a file called NAME. OPEN2 makes the disk
create this file.
The third subroutine, OPEN4, creates a simple write file to
the printer. It, too, is similar to the others except that there is, of
course, no filename.
Looking at OPEN1 , the first event is a call to the CLRCHN
subroutine within BASIC. All I/ O (including that to the screen
and from the keyboard) is governed by this opened-files concept
in Commodore computers. The normal I/ O condition is output
to the screen and input from the keyboard. CLRCHN sets the
computer to this condition. It is a necessary preliminary before
any other opening or closing of files .
106
Open!, Findmn, Getsa, and Valdec: I/O Management
107
Openl, Findmn, G etsa, and Valdec: I/ O Management
A Special Order
First of all, in what order did we put these mnemonics? They're
not in alphabetical order. In that case, ADC would be first.
They're not in the numeric order of their opcodes either. Using
that scheme, BRK would be first, having an opcode of O. Instead,
they're in order of their frequency of use in ML programming.
The order wasn't derived from a scientific study-I just looked at
them and decided that I used LOA more often than anything
else. So I put it first.
The reason for putting them in order of popularity is that
every line of source code contains a mnemonic. Every time a
mnemonic is detected, it must be looked up. Since this lookup
starts with the first three-letter word in the table (all mnemonics
are three letters long) and works its way up the table, it makes
sense to have the most common ones lowest in the table. They'll
be found sooner, and LADS can continue with other things. It
turns out that rearranging the order of the mnemonics in the ta-
ble resulted in an increase in speed of considerably less than 1
percent, but everything helps. The principle is valid, even if it
doesn't accomplish much in this case.
The second quality of a lookup table-parallelism-is rather
significant to the speed of LADS. Right below the MNEMONICS
table in the Tables subprogram are two parallel tables: TYPES
and OPS. (See the Tables subprogram at the end of Chapter 9.)
TYPES can be numbers from 0 to 9. It is handy to group
mnemonics into these ten categories according to the addressing
modes they are capable of using. Some mnemonics, like RTS,
INY, and DEY, have only one possible addressing mode (they
take no argument and have Implied addressing). They are all la-
beled type O. The branching instructions, BNE, BEQ, etc., are ob-
109
Openl, Findmn, G etsa , and Valdec: I/O M a nagement
110
Openl, Findmn, Getsa, and Valdec: I/O Management
111
Openl, Findmn, Getsa, and Valdec: I/O Management
Getsa pulls off the first six bytes (in a Commodore disk
program file) so that it can check to see if the seventh byte is
the'" character (120). If so, Getsa returns to the calling routine
in Eval (200). If not, it prints the NO START ADDRESS error
message and goes to FIN (190), the shutdown (return to BASIC)
routine.
Conditional Assembly
There are two fundam entally different versions of LADS. The
version presented as object code (to be typed in) in this book
assembles from disk-based source code. You create BASIC-like
"programs" on disk, and then LADS reads them and assembles
them without bringing any source code into RAM memory.
An easy modification to LADS, however, will allow it to
assemble directly from source code within RAM memory. A
few trivial changes to LADS' own source code and you can as-
semble a new, memory-based LADS . These changes are de-
scribed between lines 430 and 640 of the Getsa source code
printed at the end of this chapter. The changes are described in
greater detail in Chapter II , " Modifying LADS ."
But this Getsa source code illustrates one way that your
source code program can conditionally assemble. Notice line 210.
The MEMSA and CHARIN routines below it will never be
assembled. When LADS sees the .FILE pseudo-op, it will im-
mediately turn its attention to the Valdec source code . .FILE
shuts down the current file and switches to the named source
file, ignoring any additional source code in the current file.
Thus, to assemble the "conditional" part of this source
code, all you have to do is move .FILE below the new source
code. See the instruction in line 580 of this Getsa subprogram.
That's how you do it to create a memory-based version of
LADS.
Another way to conditionally assemble is to insert the .NO
pseudo-op, thus turning off object-code-to-memory-storage until
the .0 pseudo-op turns it back on. You could write your own
.ND (no storage to disk) pseudo-op if you want to control
assembly which is sending its object program to a disk drive.
Another pseudo-op you could write would be something like
.NA for No Assembly which would cause LADS to simply
search down through source code (taking no actions other than
building the label array) until it located a .A pseudo-op, turning
all assembly back on. These .ND, .NA, and .A pseudo-ops aren't
112
Openl, Findmn, Getsa, and Valdec: I/O Management
built into LADS, but would be easy to add if you felt you'd have
a use for them.
Determining Length
After Valdec finishes, it leaves the results in the two-byte register
called RESULT.
First Valdec finds the length of the ASCII number (50-90).
Our example number, IS, would be two bytes long. Its length is
stored in the variable VREND, and we then clean out the RE-
SULT register by storing 0 into it (130-150). Then X (not the reg-
113
Openl, Findmn, Getsa, and Valdec: I/O Management
114
Openl, Findmn, Getsa, and Vald ec : I/O Man agemen t
115
Openl, Findmn, Getsa, and Valdec: I/O Management
116
Program 5-1. Open 1 , Commodore
10 ~ "OPEN1" OPEN 1,8,3, "WHATEVER NAME FROM SCREEN"
20 ~ OPEN A FILE ON DISK (THIS TYPE OF FILE IS READ FROM)
30 ~------------------ o
40 OPEN1 JSR CLRCHN~RESTORE NORMAL I / O (OUTPUT TO SCREEN, INPUT FROM KEYBOARD) (I)
130 NAME AD LDA #<FILEN~ SET POINTER TO FILE NAME BUFFER (FILEN) IN LADS. ...
frl
~
140 STA FNAMEPTR ~POINTER TO FILENAME ADD R.
~
150 LDA #>FILEN ::l
160 STA FNAMEPTR+1 0..
170 JSR OPEN~ ROUTINE WITHIN BASIC THAT OPENS UP A NEW FILE
180 RTS ~
190 ,------------------------- 0:
(I)
200 OPEN 2,8,2, "NAME" (OPENS DISK PROGRAM FILE FOR WRITING OBJECT CODE) r.
,.....
210 j------------------------ '-..
220 OPEN2 LDA #2~ SEE DEFINITIONS ABOVE (SAME SETUP) o
230 STA FNUM
240 LDA #8 ~
~
250 STA FDEV ::l
~
260 LDA #2 (JQ
(I)
270 STA FSECOND S
..... 280 LDA #<FILEN (I)
.....
'-l 290 STA FNAMEPTR~ POINTER TO FILENAME ADDR. ...::l
,......
,...... 300 LDA #>FILEN o
co 310 STA FNAMEPTR+1 "0
(t>
320 JSR OPEN ~
I-'
330 JSR CLRCHN
340 RTS '"Tj
350 ,-------------------------- 5·
360 OPEN 4,4 (OPENS FILE TO PRINTER) 0..
370 ,------------------------- a
::l
380 OPEN4 LDA #4; SAME FORMAT, EXCEPT FNAMELEN
390 STA FNUM C1
(t>
400 LDA #4 .....
00
~
410 STA FDEV
420 LDA #0; THERE IS NO FILE NAME SO SET FILENAME LENGTH TO ZERO. ~
~
430 STA FNAMELEN 0..
440 JSR OPEN
450 JSR CLRCHN ~
460 RTS 0:
(t>
470 ,-------------------------- r.
480 LOAD "NAME" (LOADS A PROGRA~l FILE, A SOURCE CODE FILE INTO RAM) ......
490 ,------------------------- "-
500 LOAD1 JSR CLRCHN;RESTORE NORMAL I / O
o
510 LDA #0 ~
~
520 STA LOADFLAG; LOAD/VERIFY FLAG ::l
~
530 STA ST; THE STATUS BYTE IJQ
(t>
540 LDA #8
550 STA FDEV; DEVICE NUMBER. a
(t>
560 LDA #<FILEN; SET POINTER TO FILENAME BUFFER (FILEN) IN LADS. ::l
.....
570 STA FNAMEPTR ;POINTER TO FILENAME ADDR.
580 LDA #>FILEN
590 STA FNAMEPTR+1
600 JSR LOAD; ROUTINE WITHIN BASIC THAT LOADS IN A PROGRAM
, -\
uSR CLRCHN
615 LDA RAMSTART:STA PMEM:LDA RAMSTART+1:STA PMEM+1
\ 620 RTS
630 .FILE FINDMN
o
"Cl
Program 5-2. Open!, Apple ro
::l
~
5 ;OPEN INPUT FILE
10 OPENI JSR CLRCHN 'Tj
20 LDA #1; CLOSE FILE IF ALREADY OPEN S·
30 JSR CLOSE 0..
40 LDA # <OPNREAD 3
::l
50 STA FMOP
60 LOA # }OPNREAD C1
ro
,....
70 STA FMOP+l CIl
80 JSR FMDRIJRO ~
270 INY Jl
280 BNE LOOP~ OTHERWISE TRY NE XT MNEMONIC III
::l
290 BEQ NOMATCH 0..
300 FOUND LDA LABEL+3~ THE 4TH CHAR. MUST BE A BLANK FOR THIS TO BE A MNEMONIC
310 CMP #32 ~
320 BEQ F01~ IF SO, STORE DATA ABOUT THIS MNEMONIC & RETURN TO EVAL. 5:
I'D
330 CMP #0~ OR IF END OF LINE , IT WOULD BE AN IMPLIED ADDR. MNEMONIC LIKE INY r.
340 BNE NOMATCH ~ OTHERWISE, NO MATCH FOUND (IT'S NOT A MNEMONIC) . 0-<
'-...
350 FOI LDA TYPES,X~ STORE ADDR. TYPE . o
360 STA TP
370 LDY OPS,X~ STORE OPCODE ~
III
380 STY OP ::l
III
390 END JMP EVAR~ MATCH FOUND SO JUMP TO EVAR ROUTINE IN EVAL Q'Q
I'D
400 .FILE GETSA
8
I'D
::l
.....
For the Atari version of Findmn, change line 400 to:
400 .FILE D:GETSA.SRC
Program 5-5. Getsa
10 "GETSA" GET STARTING ADDRESS FROM DISK (LEAVES DISK POINTING AT-
20 *= THIS SPACE (START ADDRESS)
30 (EXPECTS FILE #1 TO BE ALREADY OPENED). o
"0
40 ; ------------------------- ro
50 GETSA LDX #1; SET UP INPUT CHANNEL FOR A DEVICE (TO GET BYTES) ::l
.....
60 JSR CHKIN; BASIC'S ROUTINE
70 LDX #6; WE NEED TO THROW AWAY THE 1ST 6 BYTES ON A DISK FILE (LINE LINK, 'TJ
80 LSA JSR CHARIN; LINE #, AND 2 BYTES) (CHARIN IS "GET BYTE") S·
p...
90 DEX; COUNT DOWN UNTIL WE'VE PULLED OFF THE
100 BNE LSA; 1ST 6 BYTES ••. THEN------------------ §
110 JSR CHARIN; PULL IN NEXT BYTE
120 CMP #172; IS IT THE * SYMBOL CJ
ro
....,.
130 BEQ MSA; IF SO , GO BACK TO CALLER (EVAL SUBPROGRAM CALLS GETSA) '"
,?l
140 LDA #<MNOSTART; OTHERWISE, PRINT ERROR MESSAGE WHICH
~
150 STA TEMP; SAYS "NO START ADDRESS". POINT TO THIS ERROR MESSAGE IN ::l
160 LDA #>MNOSTART; THE POINTER, "TEMP," AND PRINT THE MESSAGE (PRNTMESS) p...
170 STA TEMP+l; (NOTE: THIS NO-START-ADDRESS CONDITION OCCURS 2 WAYS: EITHER
180 JSR PRNTMESS; YOU FORGOT TO WRITE ONE OR YOU GAVE THE WRONG FILE NAME) ~
190 JMP FIN; GO BACK TO BASIC VIA THE SHUTDOWN ROUTINE WITHIN EVAL;-------
5:
ro
200 MSA RTS r.
210 .FILE VALDEC >-'
215 o
-----
217
220 "MEMSA" GET STARTING ADDRESS FROM MEMORY. LEAVES DISK POINTING AT- ~
230 *= THIS SPACE (START ADDRESS) ~
~
240 II INITIALIZES PMEM TO START OF MEMORY (JQ
(b
250 REPLACES "GETSA" SOURCE CODE FILE TO CREATE RAM-BASED ASSEMBLER. :3
...... 260 (b
w ::;
....,.
...... 270 MEMSA LDA RAMSTART:STA PMEM:LDA RAMSTART+l:STA PMEM+l
...... 280 LDX #3:MEM1 JSR CHARIN:DEX:BNE MEM1: ADD 4 TO PMEM TO POINT TO *=
V.l o
N 300 JSR CHARIN:CMP #172:BEQ MMSA "0
~
310 LDA #<MNOSTART:STA TEMP:LDA #>MNOSTART:STA TEMP+1:JSR PRNTMESS ~
320 JMP FIN: GO BACK TO BASIC VIA ROUTINE WITHIN EVAL I-'
540 2. REPLACE "JSR GETSA" IN LINE 370 OF THE EVAL FILE WITH 3
~
550 "JSR MEMSA" AND REMOVE THE "JSR OPENl" IN LINE 350 AND ::I
.....
560 LINE 4350 IN EVAL.
570
580 3. PUT A : IN FRONT OF ".FILE VALDEC" IN LINE 210 IN THIS FILE.
590 (IN OTHER WORDS, ALLOW THE NEW VERSIONS OF CHARIN ETC.
600 TO ASSEMBLE INTO THE FINISHED VERSION OF LADS.)
610
620 4. PUT SEMICOLONS AS 1ST CHARACTER IN LINES 760,770,780, & 800
630 IN THE PSEUDO SUBPROGRAM. ALSO, CHANGE LINE 750 TO
640 READ "JSR LOAD1" (INSTEAD OF "JSR OPEN1"). o
'1j
650 rtl
660 ,FILE VALDEC ::s
.....
"Tj
Program 5-6. Getsa, Apple Modifications So
~
To create the Apple version of Getsa, make the following 3
changes and additions to Program 5-5: ::s
75 LSA STX X C1
rtl
,..,.
80 JSR CHARIN; RAM START ADDRESS, AND LINE LINK) (CHARINIS "GET BYTE")
85 LOX X ?'"
~
120 CMP #$2A; IS IT THE * SYMBOL ;:l
~
~
Program 5-7. Getsa, Atari Modifications 0:
rtl
DEY~ MOVE INDEX OVER BY 1 (TO POINT TO NEXT ASCII CHAR. TO THE LEFT)
....
rr>
360
370 DEC VREND~ LOWER LENGTH POINTER. IF IT'S NOT YET ZERO, THEN ~
Pol
380 BNE VALLOOP~ CONTINUE PROCESSING THIS ASCII NUMBER ::l
390 RTS; OTHERWISE RETURN TO CALLER. 0-
400 ~--------------- MULTIPLY BY 10
410 TEN CLC ~
420 ASL RADDi MULTIPLY RADD X 4 0::
~
139
Indisk: The Main Input Routine
140
Indisk: The Main Input Routine
But let's assume for now that we're trying to get the next
character in a line. If it's zero, that means the end of a phys-
ical line (230), so we go to the routine which checks to see if
we're at the end of the entire program, not just the end of a
single line.
If there was no zero, we check for a colon and jump to
the routine which handles that (260). Then we check for a
semicolon. The next section (290-750) handles semicolons.
There are two types of semicolon situations, requiring two dif-
ferent responses.
One type of semicolon defines an entire line as a com-
ment. The semicolon, announcing that a remark follows, ap-
pears in this case as the first character in a physical line:
100; THIS ENTIRE LINE IS A REMARK.
This type is relatively simple since there is no source code for
Eval to evaluate.
The other type of remark, though, appears at the end of a
logical line, and there is something for Eval to assemble on
such lines:
100 LOA 75; ONLY PART OF THIS LINE IS A REMARK.
When we first detect a semicolon (270), we store the Y
Register in variable A (290). The Y Register is very important
in Indisk. It is set to zero at the start of each physical line (60)
and will still be zero in line 290 if the semicolon is the first
character in a physical line . This is how we can tell which
type of comment we're dealing with (at the start of a line or
within a line).
If, however, the programmer has not requested a screen
printout, there is no point to storing a comment. Comments
have no meaning to the assembler; they're just a convenience
to the programmer. Line 300 checks to see if PRINTFLAG is
set and, if not, skips over the store-the-comment routine.
141
Indisk: The Main Input Routine
Storage to BABUF
The PULLREST routine (520-600) is similar to the PUX routine
above it, but it stores a comment into the BABUF buffer.
PULLREST cannot use the LABEL buffer because this is one of
those lines where the comment comes after some legitimate
source code. And Eval assembles all legitimate source code from
the LABEL buffer. After Indisk turns the following line over to
Eval:
100 LOX 22; HERE IS A COMMENT.
the two buffers hold their respective pieces of this line:
LABEL LOX 22
BABUF HERE IS A COMMENT.
142
Indisk: The Main Input Routine
KEYWAD
Then PULLREST pulls the rest of the line into BABUF (560-650)
with a little detour to KEYWAD if the seventh bit is set on one
of the characters being pulled in. That signals a tokenized
keyword like? for PRINT. KEYWAD is the same routine as
KEYWORD (called above when Indisk is pulling in source code
characters). The only difference between them is that KEYWORD
extends ? to the word PRINT in LABEL, the source code buffer.
KEYWAD extends tokens into BABUF, the comment buffer.
PULLRX (660-680) is quite similar to PULLREST. However,
PULLRX is a pure suction routine. It pulls in the rest of a com-
ment line, but doesn't store any of the characters. It is called
upon when the PRINTFLAG is down and nothing needs to be
printed to screen or printer. All PULLRX does is get us past the
comment to the next physical line.
MPULL (690-750) is the exit from Indisk back to Eval after a
commented line has been handled. Recall that there are two
kinds of comments-those which take up an entire physical line
and those which take up only the latter part of a line, those
which come after some real source code. MPULL distinguishes
between them after first checking to see if we're at the end of
the entire program (ENDPRO) . It loads in the A variable. If A is
holding a zero, that would mean that the semicolon was the first
character in the physical line, and consequently, the entire line
was a comment and can be ignored. There's nothing to as-
semble. So we PLA PLA to get rid of the RTS address and JMP
directly to STARTLINE in Eval to get a new physical line.
143
Indisk: The Main Input Routine
Y Is the Pointer
Alternatively, if the semicolon was not at the start of the line,
the value in the A variable will be higher than zero. (The Y
Register was stored in A when a semicolon was first detected
[290].) Y keeps track of which position we are currently look-
ing at within each physical line. In cases where there is some
source code on a line for Eval to assemble, we just RTS (750)
back to Eval where the evaluation routine begins.
The end of the main Indisk loop is between lines 760 and
950. This section is all. extension of the character-testing se-
quence found between lines 220 and 270. What's happening is
that a single character is being drawn in from the source code
(on a disk file or within RAM memory, depending on which ver-
sion of LADS you are using). Each character is tested for a vari-
ety of conditions: pseudo-ops, keyword tokenization, hex
numbers, end-of-line (220), colon (240), and semicolon (270). If it
was a semicolon, we dealt with it before making any further
tests. The semicolon (comments) handler is the large section of
code we just discussed (between lines 290 and 750). If the
character isn't a semicolon, however, there are several other spe-
cial cases which we should test for before storing the character
into LABEL, the source code buffer.
Special Cases
Is it a > pseudo-op? If so, we go to the routine which handles
that (770) called HI. Is it the < pseudo-op? Then go to the LO
routine. Is it the plus sign, signaling the + pseudo-op? If not,
jump over line 820. The + pseudo-op is handled elsewhere in
LADS; all we do for now is set up the PLUSFLAG (820). Is it the
*=, the Program Counter changing pseudo-op? If so, go to the
subroutine which fixes that (850). Is it one of the pseudo-ops
which start with a period, like .BYTE or .FILE? If so, go to the
springboard to the subroutines which deal with these various
pseudo-ops (870). Is the character a $, meaning that the source
code number which follows the $ should be translated as a hex
number? If so, go to the hex number routine springboard (890).
The final test is for tokenized keywords (? for PRINT). To-
kens all have a value higher than 127, so their seventh bit will
be set. If the character is lower (BCC) than 127, we can finally
add the character to the source code line we're building in the
LABEL buffer (930) . Then we raise the Y Register to point to the
next available space in the LABEL buffer, and return to fetch the
144
Indisk: The Main Input Routine
next available space in the LABEL buffer, and return to fetch the
next character of source code from disk or RAM memory (950).
This ends the main loop of the Indisk routine. As you see,
there are many tests before a character can be placed into the
LABEL buffer. We only want to give Eval source code that it can
assemble. We can't give it characters like. or + or $ which it
cannot evaluate properly. Those, and other special conditions,
are worked out and fixed up by Indisk before LADS turns con-
trol back to the Eval subprogram.
145
Indisk: The Main Input Routine
the number 153, which can fit into a single byte. The word
PRINT takes up five bytes.
But BASIC itself must detokenize when it lists a program. It
must tum that 153 back into the characters P-R-I-N-T. To do
that, it keeps a table of the keywords in ROM. We'll take advan-
tage of that table to do our own detokenization.
The specifics of the example we'll examine here are for
Commodore computers. The principle, however, applies to Ap-
ple and Atari as well. Only the particular numbers differ. We ar-
rive here at KEYWORD because we picked up a character with a
value higher than 127. The first thing we do is subtract 127.
That will give us the position of this keyword in the table of
keywords. To see how this works, look at how these words are
stored in ROM memory:
enDfoRnexTdatA
Notice that BASIC stores words in this table with their last
letter shifted, similar to the way LADS stores labels with their
first letter shifted. That's how the start of each word can be de-
tected. The code for these words is set up so that END = 128,
FOR = 129, NEXT = 130, and so on.
Imagine that we picked up a 129 and came here to the
KEYWORD subroutine to get the ASCII form of the word, the
readable form. We would subtract: 129 - 127 = 2. Then we
would look for the second word in the table. We store the results
of our subtraction in the variable KEYNUM (1060) and keep
DECing KEYNUM until it's zero and we've thus located the
word. We look at the first character in the table of keywords. It
will be an e. If it's not a shifted character, we've not yet come to
the end of a word, and we keep looking (1120). Otherwise, we
go back and DEC KEYNUM. All of this is just a way of counting
through the keyword table until we get to the word we're after.
146
Indisk: The Main Input Routine
147
~ Listing 6-1 5""
C/J
Listing 6-3
10 320 *= 800
100 320 AS 0F LDA 15
110 322 4C 58 03 JMP CONTINUE: (AT THIS POINT WE'RE AT ADDRESS 805)
120 325 *= 855 (THIS RESETS THE PC TO 855)
130 357 C8 CONTINUE INY: (THIS WILL ASSEMBLE AT ADDRESS 855,
140; LEAVING A 50-BYTE-LONG BUFFER OR
150: STORAGE ZONE FOR VARIABLES. )
Indisk: The Main Input Routine
149
Indisk: The Main In put Routine
Stabilizing Buffers
This makes for very unstable addresses . You would never know
where to PEEK at a particular buffer or variable.
There are two ways to solve this . You could put the data
buffers, etc., at the start of your program. That way, they
wouldn't shift when you changed the source code beyond them.
But that's somewhat clumsy. That means that your program
doesn't start with the first byte. The entry to your program is up
higher, and you can't just SYS or CALL or USR to the first byte.
An alternative, and likely the best, idea is to put tables at
the very end. That way the SYS to the object code start address
is also the first byte of the ML program. But how does this solve
the shifting tables problem? That's where the *= comes in.
When I first started to write LADS, I decided to start it at
$3AOO. That left plenty of room below for BASIC-type source
files and plenty of room above for "Micromon," an extended
debugging monitor program which sits in memory between
$5BOO and $7000. (I do all my programming on the venerable,
but serviceable, Commodore PET 8032.) LADS was expected to
end up using about 4K of memory, so I forced Tables, the final
source file, to detach itself from the rest of the program and to
assemble at $5000. The Tables subprogram started off like this:
10; TABLES
20 *= $5000
30 MNEMONICS etc.
This kept everything in the Tables unaffected by any
changes in the program code below it. The entire source code
could be massaged and manipulated without moving the data ta-
150
Indisk: The Main Input Routine
151
Indisk: The Main Input Routine
Hex Conversions
HEX is an interesting routine. It is called w hen Indisk detects the
$ character. HEX looks at the ASCII form of a number like $OF
and turns it into the equivalent two-byte integer 00 OF in RE-
SULT. It's similar to the subprogram Valdec which translates an
ASCII decimal number into an integer.
HEX operates like a little Indisk. It pulls in characters from
the source code, storing them in its ow n special buffer, HEXBUF,
until it finds either a zero, a colon, a blank, a semicolon, a
comma, or a close parenthesis character. Each of these symbols
means that we've reached the end of the hex number. Some of
them signal the end of a line, some of them don't. Whichever
152
Indisk: The Main Input Routine
Busy X and Y
If we're not yet at the end of the hex number, however, the
character is stored in HEXBUF (1970) for later translation and
also stored in LABEL for printout. Notice that both the X and the
Y Registers are kept busy here, indexing their respective buffers.
Y cannot do double duty because it is farther into the LABEL
buffer than X; the LABEL buffer is holding the entire logical line,
HEXBUF is holding only the ASCII number. The two buffers will
look like this when the source line HERE LDA $45 is completely
stored:
LABEL HERE LDA $45
HEXBUF 45
LABEL will be analyzed and assembled by Eval. It needs to
store the entire logical line. HEXBUF will be analyzed only to ex-
tract the integer value of the hex number. Storing anything else
in HEXBUF would be confusing.
A hex number which is not at the end of a line goes to
DE CIT (2020) and, the length of the hex number is stored into
the variable HEXLEN (2020) so we'll know how many ASCII
characters there are to translate into an integer. Then the final
character (a comma or whatever) is put into the LABEL buffer.
Then the JSR to STARTHEX (2050) translates the ASCII into an
integer in RESULT. A JMP (rather than a JSR) to STINDISK pulls
in the rest of the logical line and takes us away from this area of
the code. The assembler will not return to this area. It will treat
the rest of the line as if it were an ordinary line.
By contrast, a hex number which is at the end of a line goes
to DECI (2070), and we store the type of end-of-line condition
(colon, semicolon, 0) in the variable A. We put the length of the
hex number into the variable HEXLEN (2090), so we'll know
how many ASCII characters there are to translate into an integer.
And we put a 0 delimiter at the end of the information in the
LABEL buffer. Then the JSR to STARTHEX (2110) translates the
ASCII into an integer in RESULT. We restore the colon or semi-
colon or whatever (2120) and jump to the routine which pro-
vides a graceful exit (2130).
ASL/ROL Massage
STARTHEX turns a hex number from its ASCII form into a two-
153
Indisk: The Main Input Routine
byte integer. It does this by rolling the bits to the left, pulling the
number into RESULT's two bytes, and adjusting for alphabetic
hex digits (A-F) as necessary.
The variable HEXLEN knows how many characters are in
the hex number. It will tell us how many times to go through
this loop. Before entering the loop, we clean the RESULT vari-
able by storing zeros into it (2140-2160) and set the X Register to
zero.
The loop proper is between lines 2180 and 2350, and is
largely an ASL/ROL massage. Each bit in a two-byte number is
marched to the left. ASL does the low byte, ROL the high byte.
ASL moves the seventh bit of RESULT into the carry. ROL puts
the carry into the zeroth bit of RESULT + 1, the high byte.
As an example of how this ASCII-to-integer machinery
works, let's assume that the number $2F is sitting in the
HEXBUF. As ASCII, it would be 2F. But recall that the ASCII
code simplifies our job somewhat since the number 2 is coded as
$32. To tum an ASCII hex digit into a correct integer, we can get
rid of the unneeded 3 by using AND #$OF.
Alphabetic Numbers
What complicates matters, however, is those alphabetic digits in
hex numbers: A through F. For them, we'll need to subtract 7 to
adjust them to the proper integer value. They, too, will have the
high four bits stripped off by AND #$OF.
Let's now follow $2F as it rolls into RESULT. $2F, as two
ASCII digits in HEXBUF, is: $32 $46 or, in binary form,
00110010 01000110.
HXLOOP starts off by moving all the zeros in RESULT four
places to the left. There are four ASL/ROL pairs. The first time
through this loop, just zeros move and there's no effect. Then
we load in the leftmost byte from the HEXBUF (2260) and see if
it's an alphabetic digit. This time we're loading in the $32 (the
ASCII 2), so it isn't alphabetic and we branch (to 2300) for the
AND which strips off the four high bits:
00110010 ($32, as ASCII code digit)
AND 00001111 ($OF)
00000010 (now a true integer 2)
The ORA command sets a bit in the result if either of the
tested bits is set. That's one way of stuffing a new value into
RESULT:
154
Indisk: The Main Input Routine
Alphabetic Adjustment
Now it's time to pick up the F from HEXBUF (2260), and since it
has a decimal value of 70, it is higher than 65, so we adjust it by
subtracting 7. That leaves us with 63 ($3F). We strip off the 3
with AND $OF:
00111111 ($3F, the adjusted ASCII code digit)
AND 00001111 ($OF)
00001111 (now a true integer F)
and then incorporate this F with the $20 we've already got in
RESULT from the earlier trip through the loop:
00100000 (RESULT is holding a $20)
ORA 00001111 (we stuff the F into it)
00101111 (leaving the integer 2F in RESULT)
Again, X is raised and tested to see if we're finished with
our ASCII hex number (2340) . This time, we are finished . There's
nothing more to roll into RESULT so we set up the HEXFLAG.
155
Indisk: The Main Input Routine
This alerts all interested parties in LADS that they do not need
to evaluate this argument. The value is already determined and
has been placed into RESULT, ready to be printed out or POKEd
as the need arises. Then we return to whatever routine called on
STARTHEX for its services.
Pseudo-op Preliminaries
The important pseudo-op .BYTE is also handled within the
Indisk subprogram. Any pseudo-op beginning with. comes here
to PSEUDO] (2410) first. All of these . type pseudo-ops require
certain preliminary actions, and the first section of PSEUDO]
accomplishes those things . Then they split up and go to their
own specific subroutines. Most of them end up going to the sub-
program Pseudo.
PSEUDO] first tests to see if there is a PC address-type label
such as the word OPCODES in:
100 OPCODES .BYTE 161 160 32 96.
The Y Register will still hold a zero if the . character is de- "
tected at the very start of a logical line of source code. That "
would mean that there is no PC-type label and we don't need to
bother storing it into the label array for later reference. Likewise,
if this isn't pass 1, we can also skip storing such a label in the la-
bel array.
But if it is pass 1 and there is one of those labels at the start
of the line, we need to save the A and Y Registers (2450-2470)
and ]SR EQUATE to store the PC label (and its address) into
LADS' label array. Then we restore the values of A and Y (2490-
2510) and store the . character in the main input buffer LABEL.
If It's Not B
The character following the" will tell us which pseudo-op we're
dealing with, so CHARIN pulls it in and stores it into the buffer
(2550). If it's not a B, we branch to the springboard PSEUDI
which sends us to the Pseudo subprogram for further tests
(3010).
Now we know it's a .BYTE type, but is it the ASCII alpha-
betic type or the ASCII numeric type? It is .BYTE "ABCDE or
.BYTE 25 72 1 6?
There is a flag which distinguishes between alphabetic and
numeric .BYTEs: the BNUMFLAG. It is first reset (2600), and we
check both the pass and the SFLAG to decide whether we .
156
Indisk : The Main Input Routine
should print out this line or not. If it's pass 2 and SFLAG is set,
we print the line number and the PC address. Then we pull in
more of this source code line until we hit a space character. If
the character following the space isn't a quote, we know that
we're dealing with the numeric type of .BYTE, so we branch
down to handle that at BNUMWERK (2810).
Otherwise, we take care of the alphabetic type. This type is
easy. We can just pull them in and POKE them. There's nothing
to figure out or translate . These bytes are held in the source code
as ASCII characters and will be POKEd into the object code as
ASCII characters. The main use for this pseudo-op is to store
messages which will later be printed to the screen or printer.
End-of-Line Alternatives
The active parts of this loop are the CHARIN (2820) and the JSR
INCSA (2990) or JSR POKEIT (3050). The decision whether to
simply raise the PC with INCSA or actually POKE the object
code is based on the test of PASS (2970). The rest of the loop
(2830-2960) is similar to other tests for end-of-line conditions
found throughout LADS. We look for a 0 (2830), a colon (2850),
a semicolon (2880), and a concluding quote (2940). Any of these
characters signal the end of our alphabetic message. And each
condition exits in a way appropriate to it. Semicolons, for exam-
ple, require that the comment be stored in BABUF for possible
printout. To do this, we JSR PULLREST (2900) .
PSLOOP stores each character into LABEL, the main input
buffer. It also JSRs to the POKEIT routine (in the Printops sub-
program) which both stores the character in any object code on
disk or memory and raises the PC by 1. Then it jumps back up
to the start of the loop to fetch another alphabetic character
(3080).
Numeric .BYTE
BNUMWERK is more complicated than BY1 , the alphabetic
.BYTE pseudo-op we just examined. BNUMWERK must not only
check for all of those possible end-of-line conditions; it must also
translate the numbers following .BYTE from ASCII into one-byte
integers before they can be POKEd. It's that same problem we've
dealt with before: 253 is stored in the source code as three bytes:
$32 $35 $33. We need to turn it into a single value: $FD. (One
thing simplifies the numeric type .BYTE pseudo-op. The pro-
grammer can use only decimal numbers in the source code for
157
I n disk: The Main Input Routine
158
Indisk: The Main Input Routine
Graceful Exits
There are so many options in LADS that graceful exits from
routines like BNUMWERK are rather difficult. We cannot just
simply RTS somewhere. We've got to take into account several
sometimes conflicting conditions.
LADS can get its source code from two places: disk or RAM
memory. The source code can be entirely within a single pro-
gram file or spread across a chain of linked files. LADS can as-
semble hex or decimal numbers from source code (except within
the .BYTE pseudo-op). The assembler can send its object code to
four places: disk, screen, RAM memory, or printer. All or any of
these targets can be operative at any given time. And output can
be turned on or off at will. No wonder there have to be different
exits and some testing before we can leave a pseudo-op. We've
got to figure out what's expected, where the object code is going.
Finally, the fact that logical lines of source code can end in sev-
eral ways adds one additional complication to the exit.
BBEND is the start of exit testing for BNUMWERK. On pass
1 we have to raise the PC one final number (3650). If the line
ends with a colon, we cannot go to ENDPRO and look for a
new line number, since colons end logical, not physical, lines of
source code (3680). In either case, we set the COLFLAG up or
down, depending on whether or not we've got a colon-type end-
ing to this logical line (3700) . We then raise the LOCFLAG to tell
Eval to print a PC-type address label and PLA PLA, pulling the
RTS off the stack in preparation for a JMP back to Eva!. If it's
pass 1 or if the printer printout flags are down, we don't need to
print anything, and we JMP into Eval at START LINE to fetch a
new line of source code (3790).
Alternatively, if it's pass 2 or if the PRINTFLAG is up, we
go back into Eval at PRMMFIN where comments following
semicolons are printed (3780).
FILLDISK (3810) takes care of a problem created by using
the * = pseudo-op with disk object code files . Recall that if you
wrote source code like:
10 *= 900
100 START INY
159
Indisk: The Main Input Routine
160
Program 6-1. Indisk
10 i "INDISK" MAIN GET-INPUT-FROM-DISK ROUTINE
20 iSETUP/EXPECTS DISK TO POINT TO 1ST CHAR IN A NEW LINE (OR BEYOND COLON)
30 iRESULTS/EITHER FLAGS END OF PROG. OR FILLS LABEL+ WITH LINE OF CODE
40 i------------------
50 INDISK JSR CLEANLABi FILL LABEL WITH ZEROS (ROUTINE IN EVAL)
60 LDY #0
70 STY HEXFLAGi PUT HEXFLAG DOWN
80 STY BABFLAGi PUT COMMENTS FLAG DOWN
90 STY BYTFLAGi PUT FLAG SHOWING < OR > DOvm
100 STY PLUSFLAGi PUT ARITHMETIC PSEUDO OP (+) FLAG DOWN
110 LDA COLFLAGi IF THERE WAS A COLON JUST PRIOR TO THIS, REMOVE ANY BLANKS
120 BNE NOBLANKSi (THIS TAKES CARE OF: INY: LDA 15: LDX 17 TYPE ERRORS)
130 JSR CHARINi OTHERWISE, PULL IN THE 1ST CHARACTER (FROM DISK OR RAM)
140 STA LINENi STORE LOW BYTE OF LINE NUMBER .....
150 JSR CHARIN ::l
160 STA LINEN+li STORE HIGH BYTE OF LINE NUMBER ~
rn
i';'"
170 NOBLANKS JSR CHARINi ROUTINE TO ELIMINATE BLANKS FOLLOWING A COLON
175 BNE COOLOOK ~
176 JSR ENDPROi THIS HANDLES COLONS PLACED ACCIDENTALLY AT END OF LINE ::r
(!)
177 PLA:PLA:JMP STARTLINE
180 COOLOOK CMP #32i (OR FOLLOWING A LINE NUMBER) ~
190 BEQ NOBLANKSi-------------------------- S·
'"
200 JMP MOlli SKIP TO CHECK FOR COLON (IT'S EQUIVALENT TO AN END OF LINE 0) .....
::l
210 STINDISK JSR CHARINi ENTRY POINT WITHIN LINE (NOT AT START OF LINE) "0
220 MOINDI BNE MOlli IF NOT ZERO, LOOK FOR COLON ....C
230 JMP ENDPROi FOUND A 0 END OF LINE. CHECK FOR END OF PROGRAM (3 ZEROS)
240 MOIl CMP #58i IS IT A COLON ~
C
...... 250 BNE XMOli IF NOT, CHECK FOR SEMICOLON ....
Q'\ S·
...... 260 JMP COLONi FOUND A COLON (!)
....... ......
(J'\ 270 XM01 CMP #59; IS IT A SEMICOLON ~
tv 280 BNE COMOA; IF NOT CONTINUE ON p..
290
. ..
<Il
STY A; FOUND A SEMICOLON (REM)
300 LDA PRINTFLAG; IF PRINTOUT NOT REQUESTED, THEN DON'T STORE THE REMARKS !'r
310 BEQ PULLRX ;!
320 STA BABFLAG; SET UP PRINT COMMENTS FLAG (A MUST BE > 0 AT THIS POINT) ~
360 ......
JMP MPULL; AND THEN RETURN TO EVAL --------------------------- ~
370 PUX JSR CHARIN; PUT NON-COMMENT DATA INTO LABEL BUFFER '0
~
380 BEQ PUX1; END OF LINE, SO EXIT .....
390 CMP #127; 7TH BIT NOT SET (SO IT'S NOT A KEYWORD IN BASIC) ::0
400 BCC PUX2 o
~
410 JSR KEYWORD; IT IS A KEYWORD, SO EXTEND IT OUT AS AN ASCII WORD .....
420 PUX2 STA LABEL,Y; PUT THE CHAR. INTO THE MAIN BUFFER
s·
~
430 INY
440 JMP PUX; RETURN TO LOOP FOR MORE CHARACTERS---------------------
450 PUX1 JSR PRNTLINE; PRINT THE LINE NUMBER
460 JSR PRNTSPACE; PRINT A SPACE
470 JSR PRNTINPUT; PRINT THE CHARACTERS IN THE LABEL BUFFER (MAIN BUFFER)
480 JSR PRNTCR; PRINT A CARRIAGE RETURN
490 LDA #0; SET A VARIABLE TO ZERO TO SIGNIFY NOTHING FOR EVAL TO EVALUATE
500 STA A
510 JMP MPULL; GO TO EXIT ROUTINE--------------------------------
520 PULLREST STA BABFLAG; PUT REMARKS INTO BABUF (BUFFER FOR COMMENTS)
530 THIS ROUTINE REMOVES (AND SAVES) COMMENTS
540 STA A; SET A VARIABLE TO SIGNIFY NOTHING FOR EVAL TO EVALUATE
550 LDY #0; SET OFFSET TO BABUF BUFFER FOR FILLING WITH COMMENTS
560 PAX1 JSR CHARIN; GET CHARACTER
570 BNE PAX; IF NOT ZERO, CONTINUE
580 STA BABUF,Y; OTHERWISE, WE'RE AT THE END OF THE COMMENT
590 LDY A
600 RTS; Y MUST HOLD OFFSET FOR ZERO FILL (ENDPRO)-----------------
610 PAX BPL PAXA; NOT A KEYWORD (7TH BIT NOT SET)
620 JSR KEYWAD; OTHERWISE, EXTEND KEYWORD INTO AN ASCII STRING
630 PAXA STA BABUF,Y; STORE CHAR. IN REMARK BUFFER
640 INY
650 JMP PAX1; RETURN TO LOOP TO GET ANOTHER CHARACTER--------------
660 PULLRX JSR CHARIN; JUST PULL IN REMARK CHARACTERS, IGNORING THEM
670 BEQ MPULL; LOOKING FOR THE END OF LINE ZERO
680 JMP PULLRX;--------------------------
690 MPULL JSR ENDPRO; CHECK FOR END OF PROGRAM AND THEN
700 LDA A; SEE IF Y = 0. IF SO, THE SEMICOLON WAS AT THE START OF A LINE
710 BNE MPULLl
720 PLA; Y = 0 SO JUMP BACK TO EVAL TO PREPARE TO GET NEXT LINE
730 PLA .....
=:l
740 JMP STARTLINE; SEMI @ START SO RETURN TO EVAL TO GET NEXT LINE--------- ....p..
750 MPULLl RTS; SEMICOLON, BUT NOT AT START OF LINE (RETURN TO CALLER) '"~
760 COMOA CMP #177;------------------ CHECK FOR OTHER ODD CHARACTERS
770 BEQ HI; FOUND> ~
::r'
780 CMP #179 rt>
790 BEQ LO; FOUND < ~
800 CMP #170 ~
15513 STARR LDA PASS; ON PASS 1, LEAVE DISK OBJECT FILE ALONE. ~
1560 BEQ STARRX ~
1570 LDA DISKFLAG; ON PASS 2, WE'VE GOT TO STUFF THE DISK OBJECT FILE S·
1580 BEQ STARRX; IF THE DISKFLAG IS UP (HE ARE CREATING AN OBJECT CODE FILE) I,.....
::l
1590 JSR FILLDISK; FILLDISK DOES THIS FOR US . "0
1600 STARRX LDA RESULT; PUT THE ARGUMENT OF *= INTO THE PC (SA) :::....
1610 STA SA ::0
16213 LDA RESULT+1 0
:::....
1630 STA SA+l ....
1640 PLA; PULL OFF THE RTS AND ::l
(t>
16513 PLA
16613 JMP STARTLINE; RETURN TO EVAL FOR THE NEXT LINE OF CODE
1670 ;------------------ IS THIS THE END OF THE ENTIRE SOURCE CODE
1680 ENDPRO STA LABEL,Y; PUT THE ZERO (THAT SENT US HERE) INTO THE MAIN BUFFER
16913 INY
1700 CPY #813
17113 BNE ENDPRO; FILL REST OF BUFFER WITH 00S
1720 STA LABEL,Y
1730 JSR CHARIN; PULL IN THE NEXT 2 BYTES. IF THEY ARE BOTH ZEROS, THEN
1740 JSR CHARIN: WE HAVE, IN FACT, FOUND THE END OF OUR SOURCE CODE FILE
1750 BEQ INEND; AND WE BEQ TO INEND
1760 LDA #13; OTHERWISE WE PUT THE COL FLAG (COLON) DOWN, BECAUSE THIS IS
17713 STA COLFLAG; AN END OF LINE CONDITION, NOT A COLON
1780 RTS; AND RETURN TO CALLER
1790 INEND LDA #1;-------- SET END OF SOURCE CODE FILE FLAG TO UP CONDITION
1800 STA ENDFLAG
1810 RTSi AND RETURN TO CALLER
1820 i------------------------ CHANGE A HEX NUMBER TO A 2-BYTE INTEGER
1830 ; PULL IN NEXT FEW BYTES, TURNING THEM INTO AN INTEGER IN RESULT
1840 HEX LDX #0i PUTS INTEGER EQUIVALENT OF INCOMING HEX INTO RESULT
1850 HI JSR CHARIN
1860 BEQ DECIi END OF LINE (SO STOP LOOKING)
1870 CMP #58
1880 BEQ DECI; COLON (SO STOP LOOKING)
1890 CMP #32
1900 BEQ HI; BLANK CHARACTER SO KEE P LOO KING FOR END OF LINE
1910 CMP #59
1920 BEQ DECI; SEMICOLON (SO STOP LOOKING)
1930 CMP #44
1940 BEQ DECITi COMMA (SO STOP LOOKING, BUT GO TO A DIFFERENT PLACE)
1950 CMP #41i (THIS "DIFFERENT PLACE" HANDLES A NOT-END-OF-LINE CONDITION). .....
BEQ DECITi CLOSE PARENTHESIS) (SO STOP LOOKING)
='0-
1960 00'
1970 STA HEXBUF,Xi OTHERWISE, PUT THE ASCII-STYLE-HEX CHAR. IN BUFFER AND 1'r
1980 INXi RAISE THE INDEX AND
1990 STA LABEL,Y; ALSO STORE IT INTO MAIN BUFFER FOR PRINTOUT AND ;J
2000 INY; RAISE THIS INDEX TOO ro
2010 JMP Hli THEN KEEP ON PUTTING HEX NUMBER I NTO HEXBUFFER----------- ~
~
2020 DECIT STX HEXLEN; SAVE LENGTH OF ASCII-HEX NUMBER S·
2030 STA LABEL,Y; FINISH STORI NG CHARS. INTO MAIN BUFFER (, OR ) IN THIS CASE) .....
2040 INY ='
2050 JSR STARTHEX; TRANSLATE ASCII -HEX NUMBER I NTO I NTEGER IN RESULT VARIABLE '0
c::
..,.
2060 JMP STINDISKi RETURN TO PULL IN REST OF THE LINEi-----------
2070 DECI STA Ai SAVE THE END OF LINE, COLON, OR SEMICOLON CHAR. FOR LATER :::0
o
2080 LDA #0 c::
..,.
>-' 2090 STX HEXLENi SAVE LENGTH OF ASCII-HEX NUMBER S·
~
"1 2100 STA LABEL,Yi FINISH STORING CHARS. INTO MAIN BUFFER (0 IN THIS CASE) ro
...... 2110 JSR STARTHEX; TRANSLATE ASCII-HEX NUMBER INTO INTEGER IN RESULT VARIABLE ....
0- ;:l
00 2120 LDA A; RETRIEVE 0 OR COLON OR SEMICOLON AND GO BACK UP TO MOINDI WHICH
2130 JMP MOINDI;----------------- BEHAVES ACCORDING TO WHICH SYMBOL A HOLDS.
....0-
2140 STARTHEX LDA #0;----------------- HEX-ASCII TO INTEGER TRANSLATOR------ f."
2150 STA RESULT; SET RESULT TO ZERO ~
2160 STA RESULT+1 ('t)
4090 KEYWAD SEC; SEE KEYWORD ABOVE (SAME KEWORD TO ASCII STRING ROUTINE)
...
~
4100 SBC #$ 7F; THIS IS A VERSION OF KEYWORD, BUT FOR COMMENTS(PUTS IT IN BABUF o
~
4110 STA KEYNUM; INSTEAD OF LABEL BUFFER). ...
4 120 LDX #255 5"
rt>
4130 SKEX DEC KEYNUM
4140 BEQ FKEX
4150 KSXX INX
4160 LDA KEYWDS,X
4170 BPL KSXX
4180 BMI SKEX
4190 FKEX INX
4200 LDA KEYWDS,X
4210 BMI KSEX
4220 STA BABUF,Y
4230 INY
4240 JMP FKEX
4250 KSEX AND #$7F
4260 RTS
4270 i------------------
4280 .FILE MATH
ing lines: ~
39Q! ~
4!l1!!I III
41e!
S·
6H! PAX NOP ......
::l
'1j
621~!
t:::
.....
76 Q! COMOA C I'1F' #62
780 CMP #6 Qi ~
80Q! CMP #4 3
o
t:::
.....
....... 83 Q! COMO e MF' #42 S·
'1 (I)
U1 9!lI Q!
Indisk: The Main Input Routine
W
L:z:
to
J:
I-
<I
t"~1 Cl 1:
In t<1 ··n Z:': I.
t"~1 IS, t.') W 0
is!~....-iZ
lff :# :# .-dU
...J
<I il. il. I;) ....
Q!:}:WlJ..
" , ..J U U III •
Wl '$: '$: rl C, ~
'$: C"l t"~1 <t Wl Wl
IS"~ co
rl C, t.'~1 ~'" i ' i ' i ' N
o-, o-rl .... rl ... rl~
176
Math and Printops:
Range Checking and
Formatted Output
Math, a short subprogram, has a rather limited job. It is de-
signed to turn the ASCII number following the + pseudo-op
into a two-byte integer and to save it in the variable
AOONUM. Later, when the final RESULT is calculated by the
Valdec subprogram, anything in AOONUM will be added to
RESULT. Math responds to a source code line like:
100 SCREEN = $0400
120 LOA SCREEN + 256; this would assemble as $0500
As with the .BYTE pseudo-op, the + pseudo-op allows
only decimal numbers as an argument following the + .
The first loop in the Math subprogram simply looks along
the LABEL buffer to locate the +. Thus, it doesn't matter if
the + is right next to its label. You could write
SCREEN + 256 as well as SCREEN + 256. However, find-
ing the +, the subroutine expects to find no spaces between
the + and the number to be added. + 256 is correct. + 256
would be incorrect. This allows us to test for a variety of end-
of-number conditions. That means that you can use the +
pseudo-op within such addressing modes as LOA
(SCREEN+256),Y or LOA 1500+25,Y.
Each character following the + is stored in HEXBUF for
later translation by Valdec. Each is also tested to see if it is a
nonnumber-if it is outside the range from 47 to 58, the
ASCII code for the digits 0-9. Anything outside that range
ends our storage of the number to be added, and we go down
to put the number into AODNUM.
Range checking is simple enough. Just remember to test
against a number which is one lower than the low end and
one higher than the high end of the range. For example, to see
if a number is lower than $30, you must test against $2F.
That's because BCC tests for lower than. $30 wouldn't be
lower than $30. The same thing works on the high end. To
test for numbers higher than $39, you CMP #$3A.
After the number is set up in HEXBUF, we point TEMP to
it, JSR to Valdec, and move the result from RESULT into the
179
Math and Printops: Range Checking and Formatted Output
181
1vlath and Printops: Range Checking and Formatted Output
raises the PC by 1 for each opcode byte and for each argu-
ment byte. Much depends on the fact that INCSA keeps the
Program Counter accurate during assembly. A single ignored
byte would throw off all address-type labels which followed.
(The HERE in 100 HERE LOA 15 is an address-type label.) In
consequence, the entire assembled object program would be
useless. INCSA just adds 1 to SA (the variable which holds
the LADS internal Program Counter). Notice lines 690-710.
They add 0 to the high byte of SA. What's the point of that?
182
Math and Printops: Range Checking and Formatted Outpu t
Hex Default
LADS' default, and probably the most common way to print out
numbers during an assembly, is hex. LADS itself handles hex
printing. If the HXFLAG is up (870), we JSR to HEXPRINT, a
subroutine at the end of the Printops subprogram. We'll get to it
in a minute. It's the opposite of the HEX subroutine within the
Indisk subprogram which changes hex numbers in ASCII format
into integers. The HEXPRINT routine will take an integer and
tum it into hex ASCII characters for printout.
After the number has been printed to the screen, we JSR to
the sister routine PTPNU (910) to also print it to the printer if
necessary. Then the number is restored to the X Register from
the X variable (920) before returning to the caller.
PRNTSA (990) is similar to PRNTNUM. The main dif-
ference is that PRNTNUM always prints the single byte sent to it
in the X Register. By contrast, PRNTSA prints the two bytes in
SA, the Program Counter variable. The same four possibilities
are tested: printer, screen, hex, or decimal. PRNTSA's sister rou-
tine, PTPSA, is called upon from both the hex (1050) and the
decimal (1100) versions of this routine.
PRNTCR (1120) prints a carriage return; the 13 is the ASCII
code for carriage return on both the screen and a printer.
PRNTLINE (1160) prints out a line number from the source code.
As each physical line is drawn into view by LADS, its line num-
ber is stored in the LINEN variable. This routine also uses that
OUTNUM routine from BASIC ROM which prints BASICs line
numbers during a LIST. Line numbers, in BASIC or LADS, are
always decimal. PTPLI (1190) is the sister routine for printer
printouts.
PRNTINPUT (1210) prints the contents of the main buffer.
Those contents will be the most recent logical line of source code
as it appeared in the source code. It uses the PRNTMESS routine
183
Math and Printops: Range Checking and Formatted Output
Error Alert
ERRING (1280) performs the preliminaries to an error message
printout. Such messages as SYNTAX ERROR or NAKED LABEL
are triggered at various places within LADS. But most of them
JSR to ERRING before printing out their particular messages.
ERRING rings the bell first. The number 7 is the ASCII code
which rings any bells attached to computers or printers. (This
works on Apple and PET ICBM computers; the 7 is changed to
253 in the Atari version to produce the same result. The VIC
and Commodore 64 have no "bell," so the character 7 will
have no effect on those computers.) The purpose of the bell is
to alert the programmer that an error has been detected. True,
the error message will appear on screen, but during an assem-
bly of a large program, the programmer might well miss silent
error messages sliding up the screen.
On Commodore computers, the character 18 reverses the
field of all subsequent characters on a line. This, too, highlights
errors. Next (1320), the logical line of source code where the er-
ror appears is printed, followed by a carriage return.
It would be simple to make error reports more dramatic.
You could stop assembly at that point with a key-testing loop
that required the programmer to hit any key to continue. You
could JSR FIN and exit to BASIC mode, aborting all further
assembly. You could JSR PRNTLINE to emphasize the line num-
ber in the source code where the error happened. You could ring
the bell ten times. As with all other aspects of LADS, you can
make it do what's efficient for you, what's responsive to your
own style of programming. Add some special effects here if you
wish. Then reassemble your customized version of LADS.
184
Math and Printops: Range Checking and Formatted Output
185
~ Program 7,1. Math ~
~
10 : "PRINTOPS" PRINTS & POKES VALUES (BOTH OPCODES & ARGUMENTS) (')
0'"
20 FORMAT LDA PASS: ON PASS 2, IGNORE INCSA (RAISES PC) SINCE (1)
910 JSR PTPNU: CHECK IF NUMBER SHOULD BE PRINTED TO PRINTER AS WELL (")
920 LDX X: RESTORE NUMBER IN X BEFORE ::r
~
930 RTS: RETURNING TO CALLER------------------------- ~
940 PRNTNUMD LDA #0: PRINT A DECIMAL NUMBER S·
950 JSR OUTNUM: BASIC ' S LINE NUMBER PRINTOUT ROUTINE (JQ
2300 LSR
2310 TAY7 AGAIN, PUT POSITION OF THIS VALUE INTO THE Y INDEX
2320 LOA HEXA,Y7 PULL OUT THE RIGHT ASCII CHARACTER FROM "HEXA" STRING
2330 JSR PRINT7 PRINT HIGH VALUE (FIRST) (A HOLDS HIGH VALUE AFTER LINE 2280) I~
.....
2340 TXA7 (X HELD LOW VALUE AFTER LINE 2210) ::r-
2350 JSR PRINT7 PRINT LOW VALUE III
2360 RTS7 RETURN TO CALLER ::I
0-
2370 .FILE PSEUDO
"1
....::I~
.....
Program 7-3. Printops, Atari Modifications 0
'0
~
To create the Atari version of Printops, change the following
lines in Program 7-2: :::0
III
::I
6 1 ~:! J S R D 8 J P F: r N T (JQ
(1)
128;2! EF:F:ING ! _DA # :-:5 :.
()
2370 .FILE D :P S EU DO. SRC ::r-
(1)
n
~
....::I
(JQ
III
::I
0-
'"Ii
0
"1
3
III
.....
.....
(1)
0-
0
C
.....
...... '0
\0 C
CJ1 .....
Pseudo:
I/O and Linked Files
All pseudo-ops except .BYTE (and in-line ones like #< or +)
are handled by the Pseudo subprogram. Eight pseudo-ops are
tested for at the start of Pseudo (50-300). They are: .FILE,
.END, .0, .P, .N, .0, .S, and .H. These tests and the asso-
ciated JMPs are identical to an ON-GOTO multiple branch
structure in a BASIC program. The rest of the Pseudo sub-
program is a collection of subroutines which service these
various pseudo-ops.
If an unrecognized pseudo-op appears within the source
code, an error message is printed out (340-460). If something
like .X or .MAP appears, the line number, the start address,
and the source code line are printed (350-390). The variable
TEMP is set to point to the SYNTAX ERROR message in the
Tables subprogram, and that message is sent to screen, and
possibly printer, via the PRNTMESS subroutine (440). A car-
riage return is printed (450), and we return to the Eval sub-
program after pulling all the characters of the current source
code line. The subroutine PULLINE does this (460).
Assuming, however, that LADS came upon the legitimate
pseudo-op .FILE during an assembly, lines 480-830 take the
necessary action . .FILE appears at the end of a subprogram. It
tells LADS that another subprogram is linked to the one just
assembled and that the source code within this next sub-
program is to be assembled next, as an extension of the cur-
rent sub!Jrogram. The current source code file will need to be
shut down, and the next linked file will need to be opened for
business. The next linked file is the one called NAME, for
example, in .FILE NAME .
199
Pseudo: I/O and Linked Files
200
Pseudo: I/O and Linked Files
201
Pseudo: 1/0 and Linked Files
202
Pseudo: I/O and Linked Files
An Abnormal Program
The routine OPEN2 in the Openl subprogram will now open
the write file on disk (1390), and the channel to that file is made
the main output channel at this point (1400-1410). Whatever is
PRINTed will now go to the disk write file . And the first two
bytes of a program file tell the computer where in RAM mem-
ory to load a program file. Normally, for a BASIC program, this
load address would be the start of RAM, the start of BASIC's
storage area for programs. But this is an abnormal program. It's
machine language; it could go anywhere in RAM. We therefore
need to tell the computer what the starting address of this
particular program is.
At the very beginning of LADS, the start address is pulled
from just beyond the source code's * = symbol. That symbol
must be the first item in any source code. The start address is
then put into several variables. SA, the Program Counter, gets
it, but will keep raising it as each logical line is assembled. SA
is a dynamic, changing variable. TA also gets the start address.
TA is a "variable," but never changes. Its job is to remember
the starting address all through the assembly process. Perhaps
TA should be called a constant rather than a variable, but the
term variable is generally used in computing to refer to both
types of " remember this" storage places.
TA Remembers
In any event, TA will always know where we started assem-
bling. So TA is sent to the disk object file as the first two bytes
(1420-1450) and then normal I/ O (input from disk source file,
output to screen) is restored (1460-1470) . Now a disk error is
checked for, and we prepare to look at the next logical line via
JSR END PRO (1500). The RTS is pulled off the stack (it would
want to send us back to INDISK), we set the END FLAG down
203
Pseudo: I/O and Linked Files
and JMP back to Eval to analyze the next line of source code
(1550).
The PRINTER subroutine responds to a .P pseudo-op. It is
ignored on pass I, but on pass 2 the file to the printer is
opened (1590), and the PRINTFLAG is raised. Normal I/O is
restored, and we "fall through" to PULLINE, the subroutine
which keeps sucking bytes off the current logical line until the
end of that line is reached . These bytes are ignored. That's why
pseudo-ops should be the only thing on any physical line. Any-
thing following a pseudo-op is sucked in and ignored.
The PULLINE routine finishes when a colon or a 0 is de-
tected. The exit back to STARTLINE in Eval is prepared for by
the PLA PLA which throws away the RTS (caused by JSRing to
Pseudo from within Indisk). The only difference between a 0
(end-of-physical-line) and a colon (end-of-Iogical-line) condition
is that a 0 requires that we skip over some link bytes in the
source code. 0 requires that we first clean off these link bytes
by a JSR to ENDPRO (1700). ENDPRO is also necessary in the
event that the end of a physical line is also the end of the
source code file itself. ENDPRO would detect that.
The .0 pseudo-op notifies LADS that you want object code
stored into RAM memory during assembly beginning at the
start address *=. This is relatively simple: We just print out the
.0 (1770-1800) and set up the POKEFLAG. (Elsewhere in
LADS, the POKEFLAG is queried to determine if object code
should be sent to RAM.) Then we exit via PULLINE.
204
Pseudo: I/O and Linked Files
205
Pseudo: I/O and Linked Files
206
Program 8-1. Pseudo
10 "PSEUDO" HANDLE ALL PSEUDOPS EXCEPT .BYTE
15
20 JMP HERE FROM INDISK
30 (INDISK WAS JSR'ED TO FROM EVAL). / Y HOLDS POINTER TO LABEL
40 ; -------------------------
50 PSEUDO CMP #70; IS IT "F" FOR .FILE
60 BNE PSEI
70 JSR FILE; F MEANS GO TO NEXT LINKED FILE -----------------
80 GOBACK PLA; RETURN TO EVAL TO GET NEXT LINE
90 PLA
100 JMP STARTLINE;------------------------
110 PSEI CMP #128; IS IT .END
120 BNE PSEE
130 JSR PEND; 128 IS TOKEN FOR END (END OF CHAIN PSEUDO)
140 JMP GOBACK; RETURN TO EVAL
150 PSEE CMP #68; IS IT "D" FOR .DISK (CREATE OBJECT CODE FILE ON DISK) ""0
rr>
(!)
160 BNE PSEEI t::
170 JMP PDISK; OPEN FILE ON DISK FOR OBJECT CODE STORAGE 0..
o
180 PSEEI CMP #80; IS IT "p" FOR .P (PRINTER OUTPUT)
190 BNE PSEE2 ......
'-..
200 JMP PPRINTER; TURN ON PRINTER LISTING o
210 PSEE2 CMP #78; IS IT "N" FOR . NH OR .NS OR SOME OTHER "TURN IT OFF" ~
~
p..
'Tj
IV
..... ( l)
CIl
"l
-....
Tables:
Data, Messages, Variables
Computers are information processors. Data is another word
for information. This points up the difference between the two
distinct sections of any computer program: code and data. The
code, or program proper, is a list of actions for the computer
to take. The data is the information upon which those actions
are based.
Data is usually separated from the code; it might even be
outside the computer. Sometimes data is on a disk file, some-
times on tape, sometimes in the user's brain, as when a pro-
gram halts and asks for input from a keyboard. In all of these
cases, though, the code is segregated from the data which it
processes.
An Odd Duck
LADS processes source code, turning it into runnable object
code. It takes a list of actions like LOA #75:STA SCREEN and
turns them into computer-understandable machine language
object programs.
LADS gets its data from two sources, a disk source code
file (or source code in RAM) and also from the Tables sub-
program. Tables isn't really a subprogram, of course. We're
forced to call it that because there isn't a better word. It's
really an odd duck. There are no commands to the computer
within Tables. It's pure information. Essential information,
true, but there are no ML instructions in Tables. Just defi-
nitions, messages, pointers, buffers, flags, and registers. LADS
couldn't operate without them, but they're not active program-
ming instructions-they're for reference .
221
Tables: Data, Messages, Variables
222
Tables: Data, Messages, Variables
223
Tables: Data, Messages, Variables
224
Table 9,1. Table of Opcodes
I.SI) lSI)
A C 0
MSD \1 50
BRK ORA IN D.X O IU\ Z Page ASI. Z r.lgl· PHI' O RA IMM ;\ S L ,\ ORA ABS A5 1. ASS
BPl ORA IND.Y ORA Z Page. X AS L Z r.lgt" X CI.C O llA AUS .Y ORA ABS.X ASl ABS .X
)SR AND IN D .X nit Z r,l ~l' AND Z rJ~(, I~OL Z Pagl' 1'1.1' AND IMM ROLA BIT ABS ..\NO ..\BS ROL ASS
BMI AND IN D .Y AND Z P.l gC.X ROI.. Z [ \l ~l'.X SEC AND A BS.Y AND ASS. X IWL ABS .X
RT I EOR IND.X EOR Z ragl' 1.5" Z PJ~l' PH" lUI< [MM IS R A I MP AilS EO ll ABS IS H A US
UVC EOR IN D .Y EOR Z Page, X 1.SI{ Z Pi1).;l'. X CI.I EO R AilS Y EO ll AUS.X I.SR AI3S, X
Ins ADC IND.X J\DC Z PJ~l' ROR Z f'J).;l' I'I. A A IX IMM ROR ,\ )MI' IND AI)( AUS ROR AilS
UVS ADC IND.Y ADC Z PJgl' ,X RO I< Z P,l).;l', X SEI ADC AIlS.Y ,\DC AUS .X lOll ABS.X
STA. IND X STY Z Pagl' STA Z Page ST X Z Pagt' DEY TXA STY ABS STA AilS STX. ABS
UCC STA IND.Y STY Z Pa gl'.X STA Z Page.X ST X Z Pagl',Y TYA STA ABS. Y TXS STA AUS.X
A LDY IMM LD A IND.X LOX IMM lDY Z P.lgC LOA Z Page LOX Z Pagl' TAY I .DA IMM TAX LDY ABS I.DA ABS l OX AilS A
, T SX
rt>
BCS lDA IN D .Y LOY Z Pagl·.X LO A Z r.lg("X I.DX z ra g",Y CI.V LOA " OS,V WY ABS.X LOA ABS,X LOX AIlS.Y 'f>
Cry Z Pa ge CMP Z Page DEC Z Pagt' INY CMp IMM DEX CPY ABS CMp ABS
-~
C CPY IMM CMp IN D.X DEC ABS C
D BNE CM p IND.Y CM p Z Page.X DEC Z Pagc.X Cl D CMp ABS.Y e MP ABS,X DEC ABS .X D
o
~
CPX IMM SBC IND.X CPX Z Page SBC Z Page INC Z Page INX SBC IM M NOP CPX ABS SIlC ABS INC ABS .?'
BEG SBC IND .Y SBC Z Page.X INC Z Page.X SED _ SSC ABS.Y SBC ABS .X INC ABS .X F !
- ~
rt>
(I>
(I>
~
IJQ
rt>
(I>
~
'1
N
~
N
(b
(I>
U1
Tables: Data, Messages, Variables
226
Tables: Data, Messages, Variables
227
Tables: Data, Messages, Variables
228
Tables: Data, Messages, Variables
229
Tables: Data, Messages, Variables
230
Tables: Data, Messages , Variables
231
~ Program 9,1. Tables
tv
10 "TABLES" ~
15 -'"~
20 TABLE OF MNEMONICS AND PARALLEL TABLE OF OPCODE/ADDRESS TYPE DATA tj
30 BUFFERS AND MESSAGES, FLAGS, POINTERS, REGISTERS ~
40 ;------------------------- MNEMONICS, TYPES, ADDRESS MODE OPCODES ?
50 MNEMONICS .BYTE "LDALDYJSRRTSBCSBEQBCCCMP
60 .BYTE "BNELDXJMPSTASTYSTXINYDEY ~
~
70 .BYTE "DEXDECINXINCCPYCPXSBCSEC ~
'"'"
80 .BYTE "ADCCLCTAXTAYTXATYAPHAPLA (JQ
~
90 .BYTE " BRKBMIBPLANDORAEORBITBVC '"
100 .BYTE "BVSROLRORLSRCLDCLIASLPHP
110 .BYTE "PLPRTISEDSEITSXTXSCLVNOP ~
'1
120 TYPES . BYTE 1 5 9 0 8 8 8 1 ....
~
130 .BYTE 8 5 6 1 2 2 0 0 0'"
~
140 .BYTE 0 2 0 2 4 4 1 0 -'"
150 .BYTE 1 0 0 0 0 0 0 0
160 .BYTE 0 8 8 1 1 1 7 8
170 .BYTE 8 3 3 3 0 0 3 0
180 .BYTE 0 0 0 0 0 0 0 0
190 OPS .BYTE 161 160 32 96 176 240 144 193
200 . BYTE 208 162 76 129 132 134 200 136
210 .BYTE 202 198 232 230 192 224 225 56
220 .BYTE 97 24 170 168 138 152 72 104
230 .BYTE 0 48 16 33 1 65 36 80
240 .BYTE 112 34 98 66 216 88 2 8
250 .BYTE 40 64 248 120 186 154 184 234
260 ;--------------------- HEX ROUTINE TABLE ------------------
270 HEXA .BYTE "0123456789ABCDEF"
280 ;--------------------- BUFFERS -----------------------------
290 LABEL .BYTE 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
300 BUFFER .BYTE 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
310 BUFM .BYTE 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
320 HEXBUF .BYTE 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
330 FILEN .BYTE 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
340 NUBUF .BYTE 0 0 0 0 0 0 0
350 ;----- REGISTERS USED BY VALDEC -------
360 RADD .BYTE 0 0;TEMPORARY REGISTER FOR DOUBLE ADDITION
370 VREND .BYTE 0; TEMP REG TO HOLD END OF PROGRAM COUNTER
380 TSTORE .BYTE 0 0; TEMPORARY REGISTER FOR MULTIPLY
390 ;---- MESSAGES TO PRINT TO SCREEN ---------------------------
400 MNOSTART .BYTE "NO START ADDRESS":.BYTE 0
410 MBOR .BYTE ,,-------------------- BRANCH OUT OF RANGE":.BYTE 0
420 NOLAB .BYTE "UNDEFINED LABEL":.BYTE 0
430 NOARG .BYTE " NAKED LABEL":.BYTE 0
440 MDISER .BYTE " «««« DISK ERROR »»»» ":.BYTE 0 ~
0'"
450 MDUPLAB . BYTE " -- DUPLICATED LABEL -- ":. BYTE 0 ;"
460 MERROR . BYTE " -- SYNTAX ERROR -- ":. BYTE 0 '"
470 ;----------- FLAGS, POINTERS, REGISTERS --------------------- tj
~
480 OP .BYTE 0; OPCODE ...
490 TP .BYTE 0; TYPE Jl
500 TA .BYTE 0 0; START ADDRESS ~
510 LINEN .BYTE 0 0; CURRENT LINE # rt>
520 ENDFLAG .BYTE 0; END-OF-PROG FLAG '"
530 vlORK • BYTE 0 0; TEMP WORK AREA JJ'"rt>
540 RESULT .BYTE 0 0; TEMP ANSWER AREA '"
550 ARGN .BYTE 0 0; VALUE OF ARGUMENT
560 ARGSIZE .BYTE 0; LENGTH OF ARGUMENT
~
"1
~
'"'"
()'Q
(D
'"
~
....,.,
~
0'"
(D
'"
6502 Instruction Set
Here are the 56 mnemonics, the 56 instructions you can give
the 6502 (or 6510) chip. Each of them is described in several
ways: what it does, what major uses it has in ML program-
ming, what addressing modes it can use, what flags it affects,
its opcode (hex/decimal), and the number of bytes it uses up.
ADC
What it does: Adds byte in memory to the byte in the
Accumulator, plus the carry flag if set. Sets the carry flag if re-
sult exceeds 255. The result is left in the Accumulator.
Major uses: Adds two numbers together. If the carry flag
is set prior to an ADC the resulting number will be one
greater than the total of the two numbers being added (the
carry is added to the result). Thus, one always clears the carry
(CLC) before beginning any addition operation. Following an
ADC a set (up) carry flag indicates that the result exceeded
one byte'S capacity (was greater than 255), so you can chain-
add bytes by subsequent ADCs without any further CLCs (see
"Multi-Byte Addition " in Appendix D).
Other flags affected by addition include the V (overflow)
flag. This flag is rarely of any interest to the programmer. It
merely indicates that a result became larger than could be held
within bits 0-6. In other words, the result" overflowed" into
bit 7, the highest bit in a byte. Of greater importance is the
fact that the Z is set if the result of an addition is zero. Also
the N flag is set if bit 7 is set. This N flag is called the "neg-
ative" flag because you can manipulate bytes thinking of the
seventh bit as a sign (+ or -) to accomplish "signed
arithmetic" if you want to. In this mode, each byte can hold a
maximum value of 127 (since the seventh bit is used to reveal
the number's sign). The B branching instruction's Relative
addressing mode uses this kind of arithmetic.
ADC can be used following an SED which puts the 6502
into "decimal mode. " Here's an example. Note that the num-
ber 75 is decimal after you SED:
239
6502 Instruction Set
SED
CLC
LDA #75
ADC #$05 (this will result in 80)
CLD (always get rid of decimal mode as soon as you've
finished)
Attractive as it sounds, the decimal mode isn't of much real
value to the programmer. LADS will let you work in decimal
if you want to without requiring that you enter the 6502's
mode. Just leave off the $ and LADS will handle the decimal
numbers for you.
Addressing Modes:
Number of
Name Format Opcode Bytes Used
Immediate ADC #15 $69/105 2
Zero Page ADC 15 $65/101 2
Zero Page, X ADC 15,X $75/117 2
Absolute ADC 1500 $6D/109 3
Absolute,X ADC 1500,X $7D/125 3
Absolute,Y ADC 1500,Y $79/121 3
Indirect,X ADC (15 ,X) $61/97 2
Indirect,Y ADC (15),Y $71/113 2
Affected flags: N ZCV
AND
What it does: Logical ANDs the byte in memory with the
byte in the Accumulator. The result is left in the Accumulator.
All bits in both bytes are compared, and if both bits are 1, the
result is 1. If either or both bits are 0, the result is O.
Major uses: Most of the time, AND is used to turn bits
off. Let's say that you are pulling in numbers higher than 128
(10000000 and higher) and you want to "unshift" them and
print them as lowercase letters. You can then put a zero into
the seventh bit of your " mask" and then AND the mask with
the number being unshifted :
LDA ? (test number)
AND #$7F (01111111)
240
6502 Instruction Set
(If either bit is 0, the result will be O. So the seventh bit of the
test number is turned off here and all the other bits in the test
number are unaffected .)
Addressing Modes:
Number of
Name Format Opcode Bytes Used
Immediate AND #15 $29/41 2
Zero Page AND 15 $25/37 2
Zero Page,X AND 15 / X $35/53 2
Absolute AND 1500 $2D/45 3
Absolute,X AND 1500,X $3D / 61 3
Absolute,Y AND 1500,Y $39/57 3
Indirect,X AND (15 ,X) $21/33 2
Indirect,Y AND (15),Y $31/49 2
Affected flags: N Z
ASL
What it does: Shifts the bits in a byte to the left by 1.
This byte can be in the Accumulator or in memory, depending
on the addressing mode . The shift moves the seventh bit into
the carry flag and shoves a 0 into the zeroth bit.
241
6502 Instruction Set
Addressing Modes:
Number of
Name Format Opcode Bytes Used
Accumulator ASL $OA/ I0 1
Zero Page ASL 15 $06 / 6 2
Zero Page,X ASL 15,X $16/22 2
Absolute ASL 1500 $OE/ 14 3
Absolute,X ASL 1500,X $IE/ 30 3
Affected flags: N Ze
BCC
What it does: Branches up to 127 bytes forward or 128
bytes backward from its own address if the carry flag is clear.
In effect, it branches if the second item is lower than the first,
as in: LDA #150: eMP #149 or LDA #22: SBe #15. These ac-
tions would clear the carry and, triggering BCC, a branch
would take place.
Major uses: For testing the results of CMP or ADC or
other operations which affect the carry flag. IF-THEN or ON-
GOTO type structures in ML can involve the BCC test. It is
similar to BASIC's> instruction.
Addressing Modes:
Number of
Name Format Opcode Bytes Used
Relative Bee addr. $90 / 144 2
Affected flags: none of them .
BCS
What it does: Branches up to 127 bytes forward or 128
bytes backward from its own address if the carry flag is set. In
effect, it branches if the second item is higher than the first, as
in: LDA #150: eMP #249 or LDA #22: SBe #85 . These ac-
tions would set the carry and, triggering BCS, a branch would
take place.
Major uses: For testing the results of LDA or ADC or
other operations which affect the carry flag. IF-THEN or ON-
242
6502 Instruction Set
BIT
What it does: Tests the bits in the byte in memory against
the bits in the byte held in the Accumulator. The bytes (mem-
ory and Accumulator) are unaffected. BIT merely sets flags.
The Z flag is set as if an Accumulator AND memory had been
performed. The V flag and the N flag receive copies of the
sixth and seventh bits of the tested number.
Major uses: Although BIT has the advantage of not hav-
ing any effect on the tested numbers, it is infrequently used
because you cannot employ the Immediate addressing mode
with it. Other tests (CMP and AND, for example) can be used
instead.
243
6502 Instruction Set
Addressing Modes:
Number of
Name Format Opcode Bytes Used
Zero Page BIT 15 $24/36 2
Absolute BIT 1500 $2C/ 44 3
Affected flags: N Z V
BMI
What it does: Branches up to 127 bytes forward or 128
bytes backward from its own address if the negative (N) flag is
set. In effect, it branches if the seventh bit has been set by the
most recent event: LDA #150 or LDA #128 would set the sev-
enth bit. These actions would set the N flag, signifying that a
minus number is present if you are using signed arithmetic or
that there is a shifted character (or a BASIC keyword) if you
are thinking of a byte in terms of the ASCII code.
Major uses: Testing for BASIC keywords, shifted ASCII,
or graphics symbols. Testing for + or - in signed arithmetic.
Addressing Modes:
Number of
Name Format Opcode Bytes Used
Relative BMI addr. $30/48 2
Affected flags: none of them.
BNE
What it does: Branches up to 127 bytes forward or 128
bytes backward from its own address if the zero flag is clear.
In other words, it branches if the result of the most recent
event is not zero, as in: LDA #150: SBC #120 or LDA #128:
CMP #125. These actions would clear the Z flag, signifying
that a result was not O.
Major uses: The reverse of BEQ. BNE means Branch if
Not Equal. Since a CMP subtracts one number from another
to perform its comparison, a 0 result means that they are
equal. Any other result will trigger a BNE (not equal). Like the
other B branch instructions, it has uses in IF-THEN, ON-
GOTO type structures and is used as a way to exit loops (for
244
6502 Instruction Set
BPL
What it does: Branches up to 127 bytes forward or 128
bytes backward from its own address if the N flag is clear. In
effect, it branches if the seventh bit is clear in the most recent
event, as in: LDA #12 or LDA #127. These actions would
clear the N flag, signifying that a plus number (or zero) is
present in signed arithmetic mode.
Major uses: For testing the results of LDA or ADC or
other operations which affect the negative (N) flag. IF-THEN
or ON-GOTO type structures in ML can involve the BCC test.
It is the opposite of the BMI instruction. BPL can be used for
tests of "unshifted" ASCII characters and other bytes which
have the seventh bit off and so are lower than 128
(OXXXXXXX).
Addressing Modes:
Number of
Name Format Opcode Bytes Used
Relative BPL addr. $10 / 16 2
Affected flags: none of them.
BRK
What it does: Causes a forced interrupt. This interrupt
cannot be masked (prevented) by setting the I (interrupt) flag
within the Status Register. If there is a Break Interrupt Vector
(a vector is like a pointer) in the computer, it may point to a
resident monitor if the computer has one. The PC and the Sta-
245
6502 Instruction Set
tus Register are saved on the stack. The PC points to the loca-
tion of the BRK + 2.
Major uses: Debugging an ML program can often start
with a sprinkling of BRKs into suspicious locations within the
code. The ML is executed, a BRK stops execution and drops
you into the monitor, you examine registers or tables or vari-
ables to see if they are as they should be at this point in the
execution, and then you restart execution from the breakpoint.
This instruction is essentially identical to the actions and uses
of the STOP command in BASIC.
Addressing Modes:
Number of
Name Format Opcode Bytes Used
Implied BRK $00/0 1
Affected flags: Break (B) flag is set.
BVC
What it does: Branches up to 127 bytes forward or 128
bytes backward from its own address if the V (overflow) flag
is clear.
Major uses: None . In practice, few programmers use
"signed" arithmetic where the seventh bit is devoted to in-
dicating a positive or negative number (a set seventh bit
means a negative number) . The V flag has the job of notifying
you when you've added, say 120 + 3D, and have therefore set
the seventh bit via an " overflow" (a result greater than 127).
The result of your addition of two positive numbers should
not be seen as a negative number, but the seventh bit is set.
The V flag can be tested and will then reveal that your answer
is still positive, but an overflow took place.
Addressing Modes:
Number of
Name Format Opcode Bytes Used
Relative BVe addr. $50/ 80 2
Affected flags: none of them.
246
6502 Instruction Set
BVS
What it does: Branches up to 127 bytes forward or 128
bytes backward from its own address if the V (overflow) flag
is set).
Major uses: None. See BVC above.
Addressing Modes:
Number of
Name Format Opcode Bytes Used
Relative BVS addr. $70/112 2
Affected flags: none of them.
CLC
What it does: Clears the carry flag. (Puts a 0 into it.)
Major uses: Always used before any addition (ADC). If
there are to be a series of additions (multiple-byte addition),
only the first ADC is preceded by CLC since the carry feature
is necessary. There might be a carry, and the result will be in-
correct if it is not taken into account.
The 6502 does not offer an addition instruction without
the carry feature. Thus, you must always clear it before the
first ADC so a carry won't be accidentally added.
Addressing Modes:
Number of
Name Format Opcode Bytes Used
Implied CLC $18/24 1
Affected flags: Carry (C) flag is set to zero.
CLD
What it does: Clears the decimal mode flag. (Puts a 0 into
it.)
Major uses: Commodore computers execute a CLD when
first turned on as well as upon entry to monitor modes
(PET/CBM models) and when the SYS command occurs. Ap-
ple and Atari, however, can arrive in an ML environment with
the D flag in an indeterminant state. An attempt to execute
247 -
6502 Instruction Set
CLI
What it does: Clears the interrupt-disable flag . All inter-
rupts will therefore be serviced (including maskable ones).
Major uses: To restore normal interrupt routine process-
ing following a temporary suspension of interrupts for the
purpose of redirecting the interrupt vector. For more detail, see
SEI below.
Addressing Modes:
Number of
Name Format Opcode Bytes Used
Implied CLI $58/88 1
Affected flags: Interrupt (I) flag is set to zero.
CLV
What it does: Clears the overflow flag. (Puts a 0 into it.)
Major uses: None . (See BYC above.)
248
6502 Instruction Set
Addressing Modes:
Number of
Name Format Opcode Bytes Used
Implied eLY $B8/ 184 1
Affected flags: Overflow (Y) flag is set to zero.
CMP
What it does: Compares the byte in memory to the byte
in the Accumulator. Three flags are affected, but the bytes in
memory and in the Accumulator are undisturbed. A CMP is
actually a subtraction of the byte in memory from the byte in
the Accumulator. Therefore, if you LOA #15:CMP #15-the
result (of the subtraction) will be zero, and BEQ would be trig-
gered since the CMP would have set the Z flag .
Major uses: This is an important instruction in ML. It is
central to IF-THEN and ON-GOTO type structures. In
combination with the B branching instructions like BEQ, CMP
allows the 6502 chip to make decisions, to take alternative
pathways depending on comparisons. CMP throws the N, Z,
or C flags up or down. Then a B instruction can branch,
depending on the condition of a flag .
Often, an action will affect flags by itself, and a CMP will
not be necessary. For example, LOA #15 will put a 0 into the
N flag (seventh bit not set) and will put a 0 into the Z flag
(the result was not 0). LOA does not affect the C flag. In any
event, you could LOA #15 : BPL TARGET, and the branch
would take effect. However, if you LOA $20 and need to
know if the byte loaded is precisely $00, you must CMP
#$OO:BEQ TARGET. So, while CMP is sometimes not ab-
solutely necessary, it will never hurt to include it prior to
branching.
Another important branch decision is based on > or <
situations. In this case, you use BCC and BC5 to test the C
(carry) flag . And you've got to keep in mind the order of the
numbers being compared. The memory byte is compared to
the byte sitting in the Accumulator. The structure is: memory
is less than or equal to the Accumulator (BCC is triggered be-
cause the carry flag was cleared). Or memory is more than
Accumulator (BC5 is triggered because the carry flag was set).
Here's an example. If you want to find out if the number in
the Accumulator is less than $40, just CMP #$41:BCC
249
6502 Instruction Set
CPX
What it does: Compares the byte in memory to the byte
in the X Register. Three flags are affected, but the bytes in
memory and in the X Register are undisturbed. A CPX is ac-
tually a subtraction of the byte in memory from the byte in
250
6502 Instruction Set
Cpy
What it does: Compares the byte in memory to the byte
in the Y Register. Three flags are affected, but the bytes in
memory and in the Y Register are undisturbed. A CPX is ac-
tually a subtraction of the byte in memory from the byte in
the Y Register. Therefore, if you LDA #15: CPY #15-the re-
sult (of the subtraction) w ill be zero, and BEQ would be trig-
gered since the CPY would have set the Z flag.
Major uses: Y is the most popular index, the most heavily
used counter within loops since it can serve two purposes: It
permits the very useful Indirect Y addressing mode (LDA
(15),Y) and can simultaneously maintain a count of loop
events.
See CMP above for a detailed discussion of the various
branch comparisons which CPY can implement.
251
650 2 Instruction Set
INC
What it does: Increases the value of a byte in memory by
1.
Major uses: Used exactly as DEC (see DEC above), except
it counts up instead of down. For raising address pointers or
supplementing the X and Y Registers as loop indexes.
Addressing Modes:
Number of
Name Format Opcode Bytes Used
Zero Page INC 15 $E6/230 2
Zero Page,X INC 15,X $F6/246 2
Absolute INC 1500 $EE/ 238 3
Absolute,X INC 1500,X $FE / 254 3
Affected flags: N Z
INX
What it does: Increases the X Register by 1.
254
6502 Instruction Set
Cpy
What it does: Compares the byte in memory to the byte
in the Y Register. Three flags are affected, but the bytes in
memory and in the Y Register are undisturbed. A CPX is ac-
tuall y a subtraction of the byte in memory from the byte in
the Y Register. Therefore, if you LDA #15: CPY #15-the re-
sult (of the subtraction) will be zero, and BEQ would be trig-
gered since the CPY would have set the Z flag .
Major uses: Y is the most popular index, the most heavily
used counter within loops since it can serve two purposes: It
permits the very useful Indirect Y addressing mode (LDA
(15),Y) and can simultaneously maintain a count of loop
events.
See CMP above for a detailed discussion of the various
branch comparisons w hich CPY can implement.
251
650 2 Instruction Set
INC
What it does: Increases the value of a byte in memory by
1.
Major uses: Used exactly as DEC (see DEC above), except
it counts up instead of down. For raising address pointers or
supplementing the X and Y Registers as loop indexes.
Addressing Modes:
Number of
Name Format Opcode Bytes Used
Zero Page INC 15 $E6/ 230 2
Zero Page,X INC 15,X $F6 / 246 2
Absolute INC 1500 $EE /238 3
Absolute,X INC 1500,X $FE/ 254 3
Affected flags: N Z
INX
What it does: Increases the X Register by 1.
254
6502 Instruction Set
INY
What it does: Increases the Y Register by 1.
Major uses: Used exactly as DEY (see DEY above), except
it counts up instead of down. For loop indexing and working
with the Indirect Y addressing mode (LOA (lS),Y).
Addressing Modes:
Number of
Name Format Opcode Bytes Used
Implied INY $C8/200 1
Affected flags: N Z
JMP
What it does: Jumps to any location in memory.
Major uses: Branching long range. It is the equivalent of
BASIC's GOTO instruction. The bytes in the Program Counter
are replaced with the address (the argument) following the
JMP instruction and, therefore, program execution continues
from this new address.
Indirect jumping-JMP (lS00)-is not recommended, al-
though some programmers find it useful. It allows you to set
up a table of jump targets and bounce off them indirectly. For
example, if you had placed the numbers $00 $04 in addresses
$88 and $89, a JMP ($0088) instruction would send the pro-
gram to whatever ML routine was located in address $0400.
Unfortunately, if you should locate one of your pointers on
the edge of a page (for example, $OOFF or $17FF), this Indirect
JMP addressing mode reveals its great weakness . There is a
bug which causes the jump to travel to the wrong place-JMP
255
6502 Instruction Set
($OOFF) picks up the first byte of the pointer from $OOFF, but
the second byte of the pointer will be incorrectly taken from
$0000. With JMP ($17FF), the second byte of the pointer
would come from what's in address $1700.
Since there is this bug, and since there are no compelling
reasons to set up JMP tables, you might want to forget you
ever heard of Indirect jumping.
Addressing Modes:
Number of
Name Format Opcode Bytes Used
Absolute }MP 1500 $4C/76 3
Indirect }MP (1500) $6C/108 3
Affected flags: none of them.
JSR
What it does: Jumps to a subroutine anywhere in mem-
ory. Saves the PC (Program Counter) address, plus three, of
the JSR instruction by pushing it onto the stack. The next RTS
in the program will then pull that address off the stack and re-
turn to the instruction following the JSR.
Major uses: As the direct equivalent of BASIC's CaSUB
command, JSR is heavily used in ML programming to send
control to a subroutine and then (via RTS) to return and pick
up where you left off. The larger and more sophisticated a
program becomes, the more often JSR will be invoked. In
LADS, whenever something is printed to screen or printer,
you'll often see a chain of JSRs performing necessary tasks:
JSR PRNTCR: JSR PRNTSA:JSR PRNTSPACE:JSR
PRNTNUM:JSR PRNTSPACE. This JSR chain prints a carriage
return, the current assembly address, a space, a number, and
another space.
Another thing you might notice in LADS and other ML
programs is a PLA:PLA pair. Since JSR stuffs the correct return
address onto the stack before leaving for a subroutine, you
need to do something about that return address if you later
decide not to RTS back to the position of the JSR in the pro-
gram. This might be the case if you usually want to RTS, but
in some particular cases, you don't. For those cases, you can
take control of program flow by removing the return address
256
6502 Instruction Set
from the stack (PLA:PLA will clean off the two-byte address)
and then performing a direct JMP to wherever you want to go.
lf you JMP out of a subroutine without PLA:PLA, you
could easily overflow the stack and crash the program.
Addressing Modes:
Number of
Name Format Opcode Bytes Used
Absolute J5R 1500 $20/32 3
Affected flags: none of them .
LDA
What it does: Loads the Accumulator with a byte from
memory. Copy might be a better word than load, since the byte
in memory is unaffected by the transfer.
Major uses: The busiest place in the computer. Bytes
coming in from disk, tape, or keyboard all flow through the
Accumulator, as do bytes on their way to screen or
peripherals. Also, because the Accumulator differs in some im-
portant ways from the X and Y Registers, the Accumulator is
used by ML programmers in a different way from the other
registers.
Since INY /DEY and INX/ DEX make those registers useful
as counters for loops (the Accumulator couldn't be conve-
niently employed as an index; there is no INA instruction), the
Accumulator is the main temporary storage register for bytes
during their manipulation in an ML program. ML program-
ming, in fact, can be defined as essentially the rapid, or-
ganized maneuvering of single bytes in memory. And it is the
Accumulator where these bytes often briefly rest before being
sent elsewhere.
257
6502 Instruction Set
Addressing Modes:
Number of
Name Format Opcode Bytes Used
Immediate LDA #15 $A9/169 2
Zero Page LDA 15 $A5 / 165 2
Zero Page,X LDA 15,X $B5 / 181 2
Absolute LDA 1500 $AD/173 3
Absolute,X LDA 1500,X $BD/189 3
Absolute,Y LDA 1500,Y $B9/185 3
Indirect,X LDA (15 ,X) $Al/161 2
Indirect,Y LDA (15),Y $B1/177 2
Affected flags: N Z
LDX
What it does: Loads the X Register with a byte from
memory.
Major uses: The X Register can perform many of the tasks
that the Accumulator performs, but it is generally used as an
index for loops. In preparation for its role as an index, LDX
puts a value into the register.
Addressing Modes:
Number of
Name Format Opcode Bytes Used
Immediate LDX #15 $A2/162 2
Zero Page LDX 15 $A6 / 166 2
Zero Page,Y LDX 15,Y $B6/182 2
Absolute LDX 1500 $AE/174 3
Absolute,Y LDX 1500,Y $BE/ 190 3
Affected flags: N Z
LDY
What it does: Loads the Y Register with a byte from
memory.
Major uses: The Y Register can perform many of the
tasks that the Accumulator performs, but it is generally used
as an index for loops. In preparation for its role as an index,
LDY puts a value into the register.
258
6502 Instruction Set
Addressing Modes:
Number of
Name Format Opcode Bytes Used
Immediate LDY #15 $AO/160 2
Zero Page LDY 15 $A4/164 2
Zero Page,X LDY 15,X $B4/180 2
Absolute LDY 1500 $AC/l72 3
Absolute,X LDY 1500,X $BC/188 3
Affected flags: N Z
LSR
What it does: Shifts the bits in the Accumulator or in a
byte in memory to the right, by one bit. A zero is stuffed into
bit 7, and bit 0 is put into the carry flag.
Carry
Bit Bit Bit Bit Bit Bit Bit Bit Flag
76543 2 1 0
259
6502 Instruction Set
NOP
What it does: Nothing. No operation.
Major uses: Debugging. When setting breakpoints with
BRK, you will often discover that a breakpoint, when exam-
ined, passes the test. That is, there is nothing wrong at that
place in the program. So, to allow the program to execute to
the next breakpoint, you cover the BRK with a Nap. Then,
when you run the program, the computer will slide over the
NOP with no effect on the program. Three Naps could cover
a JSR XXXX, and you could see the effect on the program
when that particular JSR is eliminated.
Addressing Modes:
Number of
Name Format Opcode Bytes Used
Implied NOP $EA/234 1
Affected flags: none of them.
ORA
What it does: Logically ORs a byte in memory with the
byte in the Accumulator. The result is in the Accumulator. An
OR results in a 1 if either the bit in memory or the bit in the
Accumulator is 1.
Major uses: Like an AND mask which turns bits off, ORA
masks can be used to turn bits on. For example, if you wanted
to "shift" an ASCII character by setting the seventh bit, you
could LDA CHARACTER:ORA #$80 . The number $80 in bi-
nary is 10000000, so all the bits in CHARACTER which are
ORed with zeros here will be left unchanged. (If a bit in
CHARACTER is a 1, it stays a 1. If it is a zero, it stays 0.) But
the 1 in the seventh bit of $80 will cause a 0 in the CHARAC-
TER to turn into a 1. (If CHARACTER already has a 1 in its
seventh bit, it will remain a 1.)
260
6502 Instruction Set
Addressing Modes:
Number of
Name Format Opcode Bytes Used
Immediate ORA #15 $09/9 2
Zero Page ORA 15 $05/5 2
Zero Page,X ORA 15,X $15/21 2
Absolute ORA 1500 $OD/13 3
Absolute,X ORA 1500,X $ID/29 3
Absolute,Y ORA 1500,Y $19/25 3
Indirect,X ORA (15,X) $01/1 2
Indirect,Y ORA (15),Y $11/17 2
Affected flags: N Z
PHA
What it does: Pushes the Accumulator onto the stack.
Major uses: To temporarily (very temporarily) save the
byte in the Accumulator. If you are within a particular sub-
routine and you need to save a value for a brief time, you can
PHA it. But beware that you must PLA it back into the Accu-
mulator before any RTS so that it won't misdirect the computer
to the wrong RTS address. All RTS addresses are saved on the
stack. Probably a safer way to temporarily save a value (a
number) would be to STA TEMP or put it in some other tem-
porary variable that you've set aside to hold things. Also, the
values of A, X, and Y need to be temporarily saved, and the
programmer will combine TYA and TXA with several PHAs to
stuff all three registers onto the stack. But, again, matching
PLAs must restore the stack as soon as possible and certainly
prior to any RTS.
Addressing Modes:
Number of
Name Format Opcode Bytes Used
Implied PHA $48/72 1
Affected flags: none of them .
261
6502 Instruction Set
PHP
What it does: Pushes the "processor status" onto the top
of the stack. This byte is the Status Register, the byte which
holds all the flags: N Z C I D V.
Major uses: To temporarily (very temporarily) save the
state of the flags. If you need to preserve the all current con-
ditions for a minute (see description of PHA above), you may
also want to preserve the Status Register as well. You must,
however, restore the Status Register byte and clean up the
stack by using a PLP before the next RTS.
Addressing Modes:
Number of
Name Format Opcode Bytes Used
Implied PHP $08/8 1
Affected flags: none of them.
PLA
What it does: Pulls the top byte off the stack and puts it
into the Accumulator.
Major uses: To restore a number which was temporarily
stored on top of the stack (with the PHA instruction). It is the
opposite action of PHA (see above) . Note that PLA does affect
the Nand Z flags. Each PHA must be matched by a
corresponding PLA if the stack is to correctly maintain RTS
addresses, which is the main purpose of the stack.
Addressing Modes:
Number of
Name Format Opcode Bytes Used
Implied PLA $68/104 1
Affected flags: N Z
PLP
What it does: Pulls the top byte off the stack and puts it
into the Status Register (where the flags are). PLP is a mne-
monic for Pull Processor status.
262
6502 Instruction Set
ROL
What it does: Rotates the bits in the Accumulator or in a
byte in memory to the left, by one bit. A rotate left (as op-
posed to an ASL, Arithmetic Shift Left) moves bit 7 to the
carry, moves the carry into bit 0, and every other bit moves one
position to its left. (ASL operates quite similarly, except it al-
ways puts a 0 into bit 0.)
carry---i
Flag
Tl' Tl' l' 1'~ I
Bit Bit Bit Bit Bit Bit Bit Bit
76543 2 1 0
Major uses: To multiply a byte by 2. ROL can be used
with ASL to multiply multiple-byte numbers since ROL puUs
any carry into bit O. If an ASL resulted in a carry, it would be
thus taken into account in the next higher byte in a multiple-
byte number. (See Appendix D.)
Notice how the act of moving columns of binary numbers
to the left has the effect of multiplying by 2:
0010 (the number 2 in binary)
0100 (the number 4)
263
6502 Instruction Set
Addressing Modes:
Number of
Name Format Opcode Bytes Used
Accumulator ROL $2A/42 1
Zero Page ROL 15 $26/38 2
Zero Page,X ROL 15,X $36/54 2
Absolute ROL 1500 $2E/46 3
Absolute,X ROL 1500,X $3E/62 3
Affected flags: N Z C
ROR
What it does: Rotates the bits in the Accumulator or in a
byte in memory to the right, by one bit. A rotate right (as op-
posed to a LSR, Logical Shift Right) moves bit 0 into the carry,
moves the carry into bit 7, and every other bit moves one po-
sition to its right. (LSR operates quite similarly, except it al-
ways puts a 0 into bit 7.)
264
6502 Instruction Set
Addressing Modes:
Number of
Name Format Opcode Bytes Used
Accumulator ROR $6A/ 106 1
Zero Page ROR 15 $66/102 2
Zero Page,X ROR 15 ,X $76/118 2
Absolute ROR 1500 $6E/110 3
Absolute,X ROR 1500,X $7E/126 3
Affected flags: N Z C
RTI
What it does: Returns from an interrupt.
Major uses: None. You might want to add your own
routines to your machine's normal interrupt routines (see SEI
below), but you won't be generating actual interrupts of your
own. Consequently, you cannot ReTurn from Interrupts you
never create.
Addressing Modes:
Number of
Name Format Opcode Bytes Used
Implied RTI $40/64 1
Affected flags: all of them (Status Register is retrieved from the
stack).
RTS
What it does: Returns from a subroutine jump (caused by
JSR).
Major uses: Automatically picks off the two top bytes on
the stack and places them into the Program Counter. This re-
verses the actions taken by JSR (which put the Program
Counter bytes onto the stack just before leaving for a sub-
routine) . When RTS puts the return bytes into the Program
265
6502 Instruction Set
SBC
What it does: Subtracts a byte in memory from the byte
in the Accumulator, and " borrows" if necessary. If a "borrow"
takes place, the carry flag is cleared (set to 0). Thus, you al-
ways SEC (set the carry flag) before an SBC operation so you
can tell if you need a "borrow." In other words, when an SBC
operation clears the carry flag, it means that the byte in mem-
ory was larger than the byte in the Accumulator. And since
memory is subtracted from the Accumulator in an SBC opera-
tion, if memory is the larger number, we must "borrow."
Major uses: Subtracts one number from another.
Addressing Modes:
Number of
Name Format Opcode Bytes Used
Immediate SBe #15 $E9/ 233 2
Zero Page SBe 15 $E5/ 229 2
Zero Page, X SBe 15,X $F5 / 245 2
Absolute SBe 1500 $ED/ 237 3
Absolute,X SBe 1500,X $FD/ 253 3
Absolute,Y SBe 1500,Y $F9/ 249 3
Indirect,X SBe (15 ,X) $El / 225 2
Indirect,Y SBe (15),Y $Fl / 241 2
Affected flags: N Z e V
SEC
What it does: Sets the carry (C) flag (in the processor Sta-
tus Register byte).
266
6502 Instruction Set
SED
What it does: Sets the decimal (D) flag (in the processor
Status Register byte).
Major uses: Setting this flag puts the 6502 into decimal
arithmetic mode. This mode can be easier to use when you are
inputting or outputting decimal numbers (from the user of a
program or to the screen). Simple addition and subtraction can
be performed in decimal mode, but most programmers ignore
this feature since more complicated math requires that you re-
main in the normal binary state of the 6502.
Note: Commodore computers automatically clear this mode
when entering ML via SYS. However, Apple and Atari computers
can enter ML in an indeterminant state. Since there is a possibil-
ity that the D flag might be set (causing havoc) on entry to an ML
routine, it is sometimes suggested that owners of these two
computers use the CLD instruction at the start of any ML program
they write. Any ML programmer must CLD following any delib-
erate use of the decimal mode.
Addressing Modes:
Number of
Name Format Opcode Bytes Used
Implied SED $F8/248 1
Affected flags: D
267
6502 Instruction Set
SEI
What it does: Sets the interrupt disable flag (the I flag) in
the processor status byte. When this flag is up, the 6502 will
not acknowledge or act upon interrupt attempts (except a few
nonmaskable interrupts which can take control in spite of this
flag, like a reset of the entire computer). The operating sys-
tems of most computers will regularly interrupt the activities
of the chip for necessary, high-priority tasks such as updating
an internal clock, displaying things on the TV, receiving sig-
nals from the keyboard, etc. These interruptions of whatever
the chip is doing normally occur 60 times every second. To
find out what housekeeping routines your computer interrupts
the chip to accomplish, look at the pointer in $FFFE/FFFF. It
gives the starting address of the maskable interrupt routines.
Major uses: You can alter a RAM pointer so that it sends
these interrupts to your own ML routine, and your routine then
would conclude by pointing to the normal interrupt routines.
In this way, you can add something you want (a click sound
for each keystroke? the time of day on the screen?) to the nor-
mal actions of your operating system. The advantage of this
method over normal SYSing is that your interrupt-driven rou-
tine is essentially transparent to whatever else you are doing
(in whatever language). Your customization appears to have
become part of the computer's ordinary habits.
However, if you try to alter the RAM pointer while the
other interrupts are active, you will point away from the nor-
mal housekeeping routines in ROM, crashing the computer.
This is where SEI comes in. You disable the interrupts while
you LDA STA LDA STA the new pointer. Then eLI turns the
interrupt back on and nothing is disturbed.
Interrupt processing is a whole subcategory of ML
programming and has been widely discussed in magazine arti-
cles. Look there if you need more detail.
Addressing Modes:
Number of
Name Format Opcode Bytes Used
Implied SEI $78/120 1
Affected flags: I
268
6502 Instruction Set
STA
What it does: Stores the byte in the Accumulator into
memory.
Major uses: Can serve many purposes and is among the
most used instructions. Many other instructions leave their re-
sults in the Accumulator (ADCjSBC and logical operations
like ORA), after which they are stored in memory with STA.
Addressing Modes:
Number of
Name Format Opcode Bytes Used
Zero Page STA 15 $85/133 2
Zero Page,X STA 15,X $95/149 2
Absolute STA 1500 $8D/141 3
Absolute,X STA 1500,X $9D/157 3
Absolute,Y STA 1500,Y $99/153 3
Indirect,X STA (15,X) $81/129 2
Indirect,Y STA (15),Y $91/145 2
Affected flags: none of them.
STX
What it does: Stores the byte in the X Register into
memory.
Major uses: Copies the byte in X into a byte in memory.
Addressing Modes:
Number of
Name Format Opcode Bytes Used
Zero Page STX 15 $86/134 2
Zero Page,Y STX 15,Y $96/150 2
Absolute STX 1500 $8E/142 3
Affected flags: none of them .
STY
What it does: Stores the byte in the Y Register into
memory.
Major uses: Copies the byte in Y into a byte in memory.
269
6502 Instruction Set
Addressing Modes:
Number of
Name Format Opcode Bytes Used
Zero Page STY 15 $84/132 2
Zero Page,X STY 15,X $94/148 2
Absolute STY 1500 $8C/ 140 3
Affected flags: none of them.
TAX
What it does: Transfers the byte in the Accumulator to
the X Register.
Major uses: Sometimes you can copy the byte in the
Accumulator into the X Register as a way of briefly storing the
byte until it's needed again by the Accumulator. If X is cur-
rently unused, TAX is a convenient alternative to PHA (an-
other temporary storage method).
However, since X is often employed as a loop counter,
TAX is a relatively rarely used instruction.
Addressing Modes:
Number of
Name Format Opcode Bytes Used
Implied TAX $AA/170 1
Affected flags: N Z
TAY
What it does: Transfers the byte in the Accumulator to
the Y Register.
Major uses: Sometimes you can copy the byte in the
Accumulator into the Y Register as a way of briefly storing the
byte until it's needed again by the Accumulator. If Y is cur-
rently unused, TAY is a convenient alternative to PHA (an-
other temporary storage method) .
However, since Y is quite often employed as a loop
counter, TAY is a relatively rarely used instruction.
270
6502 Instruction Set
Addressing Modes:
Number of
Name Format Opcode Bytes Used
Implied TAY $A8/168 1
Affected flags: N Z
TSX
What it does: Transfers the Stack Pointer to the X
Register.
Major uses: The Stack Pointer is a byte in the 6502 chip
which points to where a new value (number) can be added to
the stack. The Stack Pointer would be "raised" by two, for
example, when you JSR and the two bytes of the Program
Counter are pushed onto the stack. The next available space
on the stack thus becomes two higher than it was previously.
By contrast, an RTS will pull a two-byte return address off the
stack, freeing up some space, and the Stack Pointer would
then be "lowered" by two.
The Stack Pointer is always added to $0100 since the
stack is located between addresses $0100 and $OlFF.
Addressing Modes:
Number of
Name Format Opcode Bytes Used
Implied TSX $BA/186 1
Affected flags: N Z
TXA
What it does: Transfers the byte in the X Register to the
Accumulator.
Major uses: There are times, after X has been used as a
counter, when you'll want to compute something using the
value of the counter. And you'll therefore need to transfer the
byte in X to the Accumulator. For example, if you search the
screen for character $75:
271
6502 Instruction Set
CHARACTER = $75:SCREEN =
$0400
LOX #0
LOOP LOA SCREEN,X:CMP
#CHARACTER:BEQ MORE:INX
BEQ NOTFOUNO ; (this prevents an endless loop
MORE TXA ; (you now know the charac-
ter's location)
NOTFOUNO BRK
In this example, we want to perform some action based
on the location of the character. Perhaps we want to remem-
ber the location in a variable for later reference. This will re-
quire that we transfer the value of X to the Accumulator so it
can be added to the SCREEN start address.
Addressing Modes:
Number of
Name Format Opcode Bytes Used
Implied TXA $8A/138 1
Affected flags: N Z
TXS
What it does: Transfers the byte in X Register into the
Stack Pointer.
Major uses: Alters where, in the stack, the current "here's
storage space" is pointed to . There are no common uses for
this instruction.
Addressing Modes:
Number of
Name Format Opcode Bytes Used
Implied TXS $9A/154 1
Affected flags: none of them.
272
6502 Instruction Set
TYA
What it does: Transfers the byte in the Y Register to the
Accumulator.
Major uses: See TXA.
Addressing Modes:
Number of
Name Format Opcode Bytes Used
Implied TYA $98/152 1
Affected flags: N Z
273
-
Modifying LADS:
Adding Error Traps,
RAM, Based Assembly, and
a Disassembler
Special Notes on the Construction of
Atari and Apple LADS
277
Modifying LADS: Special Notes on Atari and Apple LA D S
278
M odifying LADS: Special Notes on Atari and Apple LADS
279
Modifying LADS: Special Notes on Atari and Apple LADS
280
Listing 11.1
1472 ;------------------- SEE CHAPTER 11 FOR DESCRIPTION OF THIS ERROR TRAP ~
1473 ; (TRAP FOR NAKED MNEMONICS ERROR) o
0...
1474 LDA LABEL+3:CMP #32:BEQ GVEG:JMP L700; (TEST FOR "INC:" TYPE ERROR)
-t.
;:l
(JQ
Listing 11.2 r'
5270 ; ---------- SEE CHAPTER 11 FOR EXPLANATION OF THIS ERROR TRAP ------ ~
(JJ
5271 L760 LDA BUFFER+2,Y:CMP #89:BNE ML76k:l; --- ERROR TRAP FOR LDA (15,Y)
5272 LDA OP:CMP #182:BEQ ML760; IS THE MNEMONIC LDX (IF SO, MODE IS CORRECT) (JJ
5273 JMP L680; IF NOT, JUMP TO MAKE IT (LDA $0015,Y) ABSOLUTE Y "0
(1)
,..,.
>
....el
~
;:l
0...
?
"0
(1)
-
N
00
(JJ
..... ~
Modifying LADS: Special Notes on Atari and Apple LADS
282
Modifying LADS: Special Notes on Atari and Apple LADS
ANew CHARIN
Next, we need to change the CHARIN subroutine itself. As
LADS normally runs, it goes to BASIC's get-a-byte subroutine
whenever CHARIN is invoked. This won't work for memory-
based source code. BASIC RAM cannot, alas, be OPENed as if
it were a file . So, since LADS is peppered with references to
CHARIN, we can just undefine CHARIN in the Defs sub-
program by putting a semicolon in front of it (Listing 11.3).
Similarly, CHKIN is scattered throughout LADS to reopen
file #1, the read-code-from-disk file. We're not using file #1 in
this version of LADS, so we add a semicolon to its definition
too (Listing 11.4).
But throughout LADS there are references to these two
subroutines. We need to write a new CHARIN and CHKIN to
replace the ones we just obliterated. LADS will then have
somewhere to go, something to do, as it comes upon
CHAR INs or CHKINs throughout the code. We do this by
adding to the Getsa subprogram (Listing 11.5).
283
N
00 Listing 11.3 ~
oj:>.
o
260 ;CHARIN $FFE4; PULLS IN ONE BYTE 0-
-?
::l
(JQ
Listing 11.4
t'""
240 ;CHKIN = $FFC6; OPENS A CHANNEL FOR READ (FILE# IN x)
~
en
Listing 11.5 en
"0
(T)
340 n
350 "NEW CHARIN" ASSEMBLE SOURCECODE FROM MEMORY RATHER THAN DISK. Si'
360 (IMITATES CHARIN FOR DISK) -z
370 RETURNS WITH NEXT BYTE FROM MEMORY, IN A o
380 ....
(T)
390 CHARIN INC PMEM:BNE INCP1:INC PMEM+1; REPLACES CONVENTIONAL CHARIN/DISK
400 INCP1 STY Y:LDY #0:LDA (PMEM),Y:PHP:LDY Y:PLP:RTS; SAVE STATUS REGISTER o'"
::l
410 CHKIN RTS; REPLACES DISK ROUTINE IN DEFS
:>
....
~
..,....
~
::l
0-
:>
"0
"0
(b
~
en
Modifying LADS: Special Notes on Atari and Apple LADS
285
Modifying LADS: Special Notes on Atari and Apple LADS
286
Listing 11.6
350 :JSR OPEN1: OPEN READ FILE (SOURCE CODE FILE ON DISK) ~
4350 ;JSR OPEN1: OPEN INPUT FILE (POINT IT TO THE 1ST BYTE IN THE FILE) o
0-
$
Listing 11.7 S·
IJQ
220 "MEMSA" GET STARTING ADDRESS FROM MEMORY. LEAVES DISK POINTING AT- t""'
230 *= THIS SPACE (START ADDRESS)
240 !1 INITIALIZES PMEM TO START OF MEMORY ~
250 REPLACES "GETSA" SOURCE CODE FILE TO CREATE RAM-BASED ASSEMBLER. r.fJ
260 -- - ---------------------- r.fJ
"0
270 MEMSA LDA RAMSTART:STA PMEM :LDA RAMSTART+1:STA PMEM+1 (t)
280 LDX #3 :MEM1 JSR CHARIN:DEX:BNE MEM1: ADD 4 TO PMEM TO POINT TO *= ....n
III
300 JSR CHARIN:CMP # 172: BEQ MMSA -
310 LDA #<MNOSTART:STA TEMP:LDA #>MNOSTART:STA TEMP+1:JSR PRNTMESS z
320 JMP FIN; GO BACK TO BASIC VIA ROUTINE WITHIN EVAL o
,...
(t)
330 MMSA RTS or>
o
::I
~
....~
III
::I
0-
?
"0
( t)
-
t'"'"
N
00 ~
'-l r.fJ
Modifying LADS: Special Notes on Atari and Apple LADS
A Disassembler
In a perfectly symmetrical universe, with a right hand for ev-
ery left, and a north pole for every sou th, you could transform
an assembler into a disassembler by just making it run
backwards.
Unfortunately, ours is not such a universe. Since LADS
turns source code into object code, it would seem possible to
tinker with it and adjust it a bit and make it turn object code
back into source code, to disassemble . Not so. We have to link
two new files onto LADS to add a disassembler function: Dis
and Dtables.
printed, it will ask for the start address location in RAM of the
object code you want to see listed. Notice that the object code
must be residing in RAM to be disassembled. (It would be
simple, though, to make a disassembler which operated on
disk or tape code.) Then it will disassemble until you hit the
STOP or BREAK key. You might want to adjust it- you could
have it assemble 20 instructions and then halt until a key was
pressed. Or you might want to make it print disassemblies to
the printer. Or it could ask for both starting and ending ad-
dresses before it begins. To have the disassembler you prefer,
just modify the code.
The disassembler is included in this book because it dem-
onstrates compressed LADS source code and it also shows
how LADS itself can be expanded while borrowing from exist-
ing LADS subroutines like STOPKEY and PRNTNUM.
The source code in other parts of the book is somewhat
artificial: Each line contains only one mnemonic followed by a
description, a comment about the purpose of that line. Nor-
mally, such extensive commentary will not be necessary, and
many lines can contain multiple statements separated by co-
lons. Dis is an example of LADS source code as many pro-
grammers will probably write it.
To add the disassembler to LADS, change the .END DEFS
at the end of the Tables subprogram in LADS to .FILE DIS.
This will cause the file for Dis to be assembled along with
LADS. Dis will link to Dtables, which ends with .END DEFS
to permit the second pass through the combined LADS lOis
code.
Keyboard Input
Let's briefly outline the structure and functions of the
disassembler. It starts off by printing its prompt message
called DISMESS (30). The actual message is located in line
710. PRNTMESS is a subroutine within LADS which prints
any message pointed to by the variable TEMP.
Then $3F, the? symbol, is printed and STARTDIS (50)
sets the hexflag up so that number printouts will be in hexa-
decimal. If you prefer decimal, LOA #0 and store it in
HXFLAG .
Now there's an input loop to let the user input a decimal
start address, character by character. If a carriage return is de-
tected (90), we leave the loop to process the number. The
289
Modifying LADS: Special Notes on Atari and Apple LADS
Battling Insects
This is a good place to observe that programming is never a
smooth trip from the original concept to the final product. No
programmer is so well-prepared or knowledgeable that he or
she simply sits down and calmly creates a workable program.
If you find yourself scratching your head, circling around a
bug and not trapping it, spending hours or days trying to see
what could possibly be wrong-you're in good company. I've
worked with some very experienced, very talented people and
have yet to see someone fashion a program without snags.
And the more significant and sophisticated the program, the
more snags it has.
All that can be done, when you hit a snag, is to single-
step through the offending area of your program, or set BRK
traps, or puzzle over the source code, or try making some ten-
tative reassemblies (not knowing for sure if your changes will
have any salutary effect), or sometimes even toss out an entire
subroutine and start over. For example, I wrote the rough
draft, the first draft of this disassembler, in about two hours. I
didn't have the final version working until I'd spent two full
290
Modifying LADS: Special Notes on Atari and Apple LADS
days battling bugs. Some were easy to fix, some were mon-
sters. It took about ten minutes to cure that problem with the
start address being one too high. But it took hours to locate an
error in the disassembler tables, Dtables.
After the user has input the start address, TEMP is made
to point to the LABEL buffer and VALDEC is invoked.
VALDEC leaves the result of an ASCII-to-integer conversion in
the RESULT variable . That number is stored in PMEM and SA
(140-150) . One final adjustment restores SA to the original
number input by the user. SA will only print addresses
onscreen; PMEM is the real pointer to the current address dur-
ing disassembly. The decrementing of PMEM, made necessary
by that JSR GB early in the main loop, is not necessary for SA.
(SA is not incremented by the GB subroutine.)
291
Modifying LADS: Special Notes on Atari and Apple LADS
Addressing Type
We had previously saved our original byte (the number 1 in
our example) in FILEN (190). We now retrieve it, pull out the
position value from MTABLE (getting the number 2), and load
in the addressing mode type from TYPETABLE (see lines
360-410 in the Dtables subroutine listing at the end of this
chapter). It turns out that the number 2 we're using in our
example will pull out a number 4 from TYPETABLE. The
number 4 identifies this as an Indirect X addressing mode.
Between lines 380 and 410 we have a simple decision
structure, much like BASIC's ON-GOTO structure. In our
example, the CMP #4 in line 390 will now send us to a rou-
tine called DINDX which handles Indirect X addressing.
DINDX (460) takes advantage of several routines which
print symbols to the screen for us: LEPAR prints a left paren-
thesis; DOONE fetches and prints the next number in RAM
memory (the argument for the current mnemonic); COMX
prints a comma and an X; and RIPAR finishes things off with
a right parenthesis. Now we have something like this
onscreen:
292
Modifying LADS : Special Notes on Atari and Apple LADS
293
N
\.0 Program 11-1. Dis-The Disassembler
>i'> ~p..
10 ; DIS -- DISASSEMBLER
20 *= 17000 ~
30 LOA #<DISMESS:STA TEMP:LDA #>DISMESS:STA TEHP+1:JSR PRNTMESS S·
(JQ
40 JSR PRNTCR:LDA #$3F:JSR PRINT
50 STARTDIS LOA #1:STA HXFLAG:LDY #0:STY Y t""'
60 DTM0 JSR CHARINi -- GET START ADDRESS (DECIMAL) -- ~
70 BEQ DTM0 (f)
0
~
~
~
~
~.
~
~
~
~
~
~
.--
~
~
en
Modifying LADS: Special Notes on Atari and Apple LADS
Atari LADS has a special file called Kernal (see program list-
ings below), which transparently supports all these routines,
making the conversion between the Atari's I/O system and
the Commodore's transparent. Explanations of Commodore
I/ O given in Chapter 5, then, are valid as well for the Atari
LADS system. In other words, when the original Commodore
version of LADS was translated to the Atari, the Kernal sub-
program was added to mimic the operations of the Com-
modore operating system I/O. This emulation allows the
descriptions of LADS to remain essentially identical for non-
Commodore machines.
300
Modifying LADS: Special Notes on Atari and Apple LADS
301
Modifying LADS: Special Notes on Atari and Apple LADS
302
Modifying LADS: Special N otes on Atari and Apple LADS
numbers into integers. The ASCII line number does not end
with a zero, though. The first part of Valdec finds the length
of the number by checking for a zero. It has been changed in
the Atari version to exit on any nonnumeric digit (one with an
ASCII value less than 48 or greater than/equal to 58). The
change does not affect any other use of Valdec.
Indisk. It is in Indisk where we see many modifications to
the Commodore version. Since the editor does not tokenize
anything, KEYWORD and KEYWAD are not needed, and ref-
erences to them in this source code, as well as the KEYWORD
and KEYWAD routines themselves, have been deleted. Again,
since nothing is tokenized, checks for +, "', <, >, etc., look for
the ASCII values instead of the tokenized ones. Since line
numbers are stored as a string of digits instead of a two-byte
integer, we must call LINENUMBER in the SYSTEM module
in order to set LINEN. ENDPRO, instead of looking for three
zeros to signify the end of a program, must check the disk sta-
tus variable for end of file . End of file returns 136 after the last
character has been read, and $03 if you try to read past the
end of file, so we check for both to be safe. We check the sta-
tus for file #1 (the input file) directly ($0353), instead of ST,
since ST may have been changed by another I/O operation.
Nonetheless, large parts of Indisk are unchanged from the
Commodore version.
Printops. Because of the Kernal simulator, even though
Printops has plenty of Commodore I/O calls, few changes
were needed to make Printops work on the Atari.
Pseudo. There are some minor changes here . KEYWORD
does not need to be used by .END or .FILE. FILE finds the end
of the pseudo-op by looking for a space delimiter. The
filename is then copied into FILEN, and the file opened. If the
current operation is a RAM-based assembly, Open1 takes care
of loading in the next file. PEND, which supports .END, first
calls FILE to open the file, then copies SA, which holds the
current address, into LLSA for use with OPEN2.
Speaking of OPEN2, some code was deleted from PDISK
and instead implemented in OPEN2. There were no more
changes after PDISK to the Pseudo module. In Commodore
LADS, Pseudo links to Tables, the last module. Here we link
to Kernal, inserting Kernal, System, and Edit into the chain.
Kernal. This is the most important module in the Atari
translation . It implements all the Commodore I/O functions
303
Modifying LADS: Special Notes on Atari and Apple LADS
304
Modifying LADS: Special Notes on Atari and Apple LADS
305
Modifying LADS: Special Notes on Atari and Apple LADS
306
Modifying LADS: Special Notes on Atari and Apple LADS
307
Modifying LADS: Special Notes on Atari and Apple LADS
309
Modifying LADS: Special Notes on Atari and Apple LADS
310
Modifying LADS: Special Notes on Atari and Apple LADS
311
Modifying LADS: Special Notes on Atari and A p ple LADS
play the address where the BRK was found, clears the inter-
rupt flag, cleans the stack, then jumps to the Edit entry point.
Edit then links to Tables.
312
Modifying LADS: Special Notes on Atari and Apple LADS
313
Modifying LADS: Special Notes on Atari and A pple LADS
314
Modifying LADS: Special Notes on A tari and Apple LADS
315
Modifying LADS: Special Notes on Atari and Apple LADS
e a command
214121 CMP #48;"0"
215!ZS BCS LINE;greater than 119" ~ but greater
than/== "0 f1
?
2160 JMP COMMAND;no, so command
2170 ;Must be a line, so get line number
2180 LINE LDA #255;no offset
2190 JSR GETLNUM
2200 LDA INDEX;INDEX points to first non-num
eric digit
2210 STA TEXTPTR;so sa v e i t
2220 LDA FOUNDFLAG:if i t exists
2230 BNE NODELETE;it not, don't delete i t
224111 JSR DELETE
2250 NODELETE LDY TEXTPTR;is there any text
on the line?
226121 CPY INLEN;compare to line length
2270 BED OVERINS;no te x t. just delete
228 111 JSR INSERT;otherwise insert line
229 121 OVERINS JMP ENTER;and get another line
23 12HZI
316
Modifying LADS: Special Notes on Atari and Apple LADS
317
Modifying LADS: Special Notes on A tari and A pple LADS
271111 SBC #0
272111 PHA
273111 LDA TMP
274!l1 PHA
275!l1 RTS
2760 ;Command table. Format:
277111 ;.BYTE "command" lll,"command" (11,255 (255
to end table>
278111 COMTABLE . BYTE "L I ST"
279111 .BYTE !ll
280111 .BYTE "DOS"
281111 .BYTE (11
282111 .BYTE "NEW"
283111 .BYTE 0
2840 .BYTE "SAVE "
2850 .BYTE 0
2860 .BYTE "LOAD "
2870 .BYTE III
288111 .BYTE "MERGE "
2890 .BYTE 0
29(110 .BYTE "LADS"
291111 .BYTE III
2920 .BYTE "SYS"
2930 .BYTE 0
2940 .BYTE 255
2950 ;table will hold address of each comman
d routine in low,high format
2960 COMVECT .BYTE 0 0 0 0 0 0 0 0 0 0 0 0 0
o 0 III
297111
2980 MLIST LDA # ( TEXTBAS;Point to beginning
of program
2990 STA PTR
3000 SEC;get length of program to l i s t
3(1110 LDA TEXEND
3020 SBC PTR
3030 STA LLEN;into LLEN
3040 LDA #)TEXTBAS
31!150 STA PTR+ 1
3060 LDA TEXEND+1
31Z17!ll SBC PTR+ 1
3080 STA HLEN;and HLEN
3090 INLIST LDA HLEN
3100 TAX
3110 ORA LLEN;both zero ?
312111 BNE DOLIST
3130 RTS;if so, e x i t LIST
3131 DOLIST LDA #l:STA 766
3140 CPX #0;high byte zero?
318
Modifying LADS: Special Notes on Atari and Apple LADS
319
Modifying LADS: Special Notes on Atari and Apple LADS
320
Modifying LADS: Special Notes on Atari and Apple LADS
321
Modifying LADS: Special Notes on Atari and Apple LADS
-322
M odifying LADS: Special Notes on Atari and Apple LADS
51'/11'/11'/1 INY
51'/111'/1 CPY INLEN
51'/121'/1 BCC INSLOOP
5030 BEQ INSLOOP
5040 RTS;insert done~
5050 CLOSEIT LDA FNUM
5 1<1160 BEQ NOCLOSE
5 1217121 JSR CLOSE
5080 NOCLOSE JSR CLRCHN
5 1219121 RTS
510121 ERRPRINT LDA ST
511121 STA TMP
512121 JSR CLALL
513121 LDA #(ERRMSG
514f.!1 LDY #>ERRMSG
515121 JSR PRMSG
516121 LDX TMP
517121 LDA #121
518111 JSR OUTNUM
519111 JSR PRNTCR
52121 121 RTS
5210 PMSG .B YTE 155
522 111 . BYTE "LADS Ready."
523121 . BYTE 155 121
5240 SYNMSG .BYTE 253
525121 .BYTE "S y nta >: Error"
5260 .BYTE 155 0
5270 ERRMSG .BYTE 253
5280 .BYTE "Error -
529 111 . BYTE 1<11
53!111<11 BRI<MSG . BYTE " BRI< from "
531 111 . BYTE 121
532f!J
5330 GETNUM STA SF2
534 !!1 INC SF2
5350 LDA # < BABUF;point to line buffer
536 !11 STA SF3
537111 LDA # > BABUF
5380 STA SF4 ; offset should be in Sf2
5390 JSR SD800;convert ASCII to floating poi
nt
54!!1 !!1 BeS NUMERR
5410 JSR SD9D2;floating point to integer
5420 LDA $F2;store pointer to f i r s t non-nume
r al
543!!1 STA INDE X
544 i11 RTS
5450 NUMERR LDA #0;clear result
546 !!1 STA SD4
323
Modifying LADS: Special Notes on Atari and Apple LADS
324
Modifying LADS: Special Notes on Atari and Apple LADS
325
Modifying LADS: Special Notes on Atari and Apple LADS
326
Modifying LADS: Special Notes on Atari and Apple LADS
68QIQI JSR X 16
6810 CLC:add buffer length to get ending add
327
Modifying LADS: Special Notes on Atari and Apple LADS
OPEN 1
1 2
. .
3/4 5
. . .
6 7
..8 ..
9/10 11
. 13/14 15/16 17/18
.
CLOSE 2 . . . .
DELETE 5 . .. .. . .. .. . . .
CATALOG 6 . . .. ..
LOCK 7 . .. .. .. .. .. . .
UNLOCK 8 . . . .. .. . . .
RENAME 9 .. .. .. . .. .. . . .
INIT 11 157 . . . . ..
VERIFY 12 . . .. . . .. .. . ..
328
Modifying LADS: Special Notes on Atari and Apple LADS
Parameter
1 2 3/4 5/6 7/8 9/10 11 12/14 15/16 17/18
READ 1 Byte 3 1 * * * * *
READ Range 3 2 * * * * * •
POSITION and
READ 1 Byte
3 3 * * * * * * *
POSITION and
READ Range
3 4 • * * * • • • •
WRITE 1 Byte 4 1 * * * * *
WRITE Range 4 2 • • • • • *
POSITION and
WRITE 1 Byte
4 3 * * * * * * *
POSITION and
WRITE Range
4 4 * • • • • * • *
POSITION 10 * * * *
Note : The numbers in the leftmost column represent the
opcode; the numbers across the top of this chart represent
byte positions relative to the start of the parameter list. As-
terisks signify that a byte is required for the operation listed.
A blank space means that this parameter can be ignored.
Nevertheless, the byte positions must be maintained. For
example, to DELETE, you do not need to worry about the
second, third, or fourth bytes-anything can be in them-
but they must exist. The first byte must contain a five, and
the fifth through the eighteenth bytes must be set up as de-
scribed below.
The parameters are expained in sections. The first section
tells you about all the opcodes except for the read, write, and
positions opcodes, because they are slightly different from the
rest. The second section tells you about the read, write, and
position opcodes; the third, about the last set of parameters
that is common to all opcodes.
The first byte of the parameter field is the opcode type.
This parameter can be in the range of 1 to 12.
The second parameter is used only with the INIT
opcodes. If you are using a 48K Apple, the correct value for
this parameter is 15 7.
The third and fourth parameters are used with the OPEN
and RENAME opcodes. Together they hold the record length
of a random access file. If you are not using a random access
file, you should ha ve a zero in both of these locations . With
the RENAME opcode, these bytes hold the address of the new
name.
329
Modifying LADS: Special Notes on Atari and Apple LADS
The fifth byte holds the volume number. The sixth byte
holds the drive number. The seventh byte holds the slot num-
ber. The eighth byte holds the file type.
The ninth and tenth bytes hold the address of the
filename . The filename must be stored in the address pointed
to by these bytes. It must be padded with spaces.
This section explains the read, write, and position
opcodes.
The first byte holds the opcode. The second byte holds
the subcode.
The next four bytes are used only when you require a po-
sition command. The third and fourth bytes hold the record
number. The fifth and sixth bytes hold the byte offset. To re-
position the pointer in an open file, you can use these bytes to
calculate a new position. The new position is equal to the
length of the file specified in the open opcode times the record
number plus the byte offset.
The seventh and eighth bytes hold the length of the range
of bytes. This is used only when reading or writing a range.
When reading or writing a range of bytes, the ninth and
tenth bytes hold the start address of the range. If you are read-
ing or writing only one byte, then the ninth byte holds the
byte you read or the byte you are going to write.
The following are parameters for all the opcodes.
The eleventh byte is the error byte. It should be checked
each time after you access the file manager. The errors are as
follows:
0: NO ERROR
2: INVALID OPCODE
3: INVALID SUBCODE
4: WRITE PROTECTED
5: END OF DATA
6: FILE NOT FOUND
7: VOLUME MISMATCH
8: I/O ERROR
9: DISK FULL
10: FILE LOCKED
330
Modifying LADS: Special Notes on Atari and Apple LADS
331
Modifying LADS: Special Notes on Atari and Apple LA D S
its work by putting the filename at the top of the screen and
jumping to the start of LADS.
The insert line routine gets the line number, then jumps
to the Apple tokenize routine, which loads the Y Register with
the length of the line plus six and then jumps to the normal
line insert and tokenize routine .
The last subroutine in Open 1 is the first thing that is
called when you BRUN LADS. It initializes the wedge and sets
HIMEM to the start of LADS .
332
Ho-w to Use LADS
335
Appendix A: How to Use LADS
336
Appendix A: How to U se LADS
Features
There are a number of pseudo-ops (direct instructions to the
assembler) available in LADS. The .S in line 15 is such an
instruction. It tells LADS to print the results of an assembly to
the screen. If you add the following lines to our test program,
you will cause the listing to be in decimal instead of hex and
cause LADS to save the object code (the runnable ML pro-
gram) to a disk file called T.OBJ.
10 *= $0360
1l.NH
12.D T.OBJ
20 LDA #22:LDY #0
30 STA $1500,Y
40 .END TEST
The pseudo-op .NH means no hex (causing the listing to
change from hex to decimal), and .D means create a disk file
containing the ML program which results from the assembly
process.
You can add REM-like comments by using a semicolon.
And you can turn the screen listing off with .NS, anytime.
Turn it on or off as much as you want:
10 *= $0360
1l.NH
12 .D T.OBJECTPROGRAM
15.NS
20 LDA #22:LDY #0; load A with 22, load Y with zero
30 STA $1500,Y
40 .END TEST
You turn on printer listings with .P and turn them off
with .NP. However, for the .P pseudo-op to work, the .S
337
Appendix A: How to Use LADS
338
Appendix A: How to Use LADS
A Stable Buffer
The pseudo-op * = is mainly useful when you want to
create data tables. The subprogram Tables in LADS source
code is an example. (A subprogram is one of the source code
files which, when linked together, form an entire ML pro-
gram.) You might want to create an ML program and locate its
tables, equates, buffers, and messages at the high end of the
ML program the way LADS does with its Tables subprogram.
Since you don't know what the highest RAM address will be
while you're writing the program, you can set * = to some ad-
dress perhaps 4K above the starting address . This gives you
space to write the program below the tables. The advantage of
stable tables is that you can easily PEEK them and this greatly
assists debugging . You'll always know exactly where buffers
and variables are going to end up in memory after an assem-
bly-regardless of the changes you make in the program.
Here's an example. Suppose you write:
10 *= $5000
20 STA BUFFER
30 *= $6000
40 BUFFER .BYTE 0 0 0 0 0 0 0 0 0 0 0 0 0 0
50 .END BUFFEREXAMPLE
This creates an ML instruction (STA buffer) at address $5000
(the starting address of this particular ML program), but places
the buffer itself at $6000. When you add additional instruc-
tions after STA buffer, the location of the buffer itself will re-
main at address $6000. This means that you can write an
entire program w ithout having to worry that the location of
the buffer is changing each time you add new instructions,
339
Appendix A: How to Use LADS
Labels
With LADS, or with other assemblers that permit labels, you
need not refer to locations in memory or numeric values by
using numbers. You can use labels.
In the example above, line 10 starts off with the word
340
Appendix A: How to Use LADS
LOOP. This means that you can use the word LOOP later on
to refer to that location (see line 50) . That's quite a conve-
nience: The assembler remembers where the word LOOP is
used and you need not refer to an actual memory address; you
can refer to the label instead. Throughout this book, this kind
of label is called a PC-type (for Program Counter) or address-
type label.
The other type of label is defined is with an assembly
convention called an equate (an equals sign). This is quite simi-
lar to the way that BASIC allows you to assign value to
words-it's called "assigning variables" when you do it in
BASIC. In ML, the = pseudo-op works pretty much the way
the = sign does in BASIC. Here's an example:
5 *= $0360
10 SCREEN = $0400; the location of the 1st byte in RAM of the
64 screen
20 HEARTSYMBOL = 83; the heart figure
30; ------------------------
40 START LOA HEARTSYMBOL; notice "START" (an address-
type label)
50 STA SCREEN
60 RTS
Line 10 assigns the number $0400 (1024 decimal) to the
word SCREEN. Anytime thereafter that you use the word
SCREEN, LADS will substitute $0400 when it assembles your
ML program. Line 20 " equates" the word HEARTSYMBOL to
the number 83. So, when you LDA HEARTSYMBOL in line
40, the assembler will put an 83 into your program. (Notice
that, like BASIC, LADS requires that equate labels be a single
word. You couldn't use HEART SYMBOL, since that's two
words.)
Line 30 is just a REMark. The semicolon tells the assem-
bler that what follows on that line is to be ignored. Neverthe-
less, blank lines or graphic dividers like line 30 can help to
visually separate subroutines, tables, and equates from your
actual ML program. In this case, we've used line 30 to sepa-
rate the section of the program which defines labels (lines 10-
20) from the program proper (lines 40-60). All this makes it
easier to read and understand your source code later.
341
Appendix A: How to U se LADS
Automatic Math
There are times when you will want to have LADS do addi-
tion for you. That's where the + pseudo-op comes in. If you
write "label + 1" you will add 1 to the value of the label.
Here's how it works:
10 *= 864
20 MEMTOP = $34; top-of-memory pointer for 8032 PET.
30; -----------------------------
40 LOA #O:STA MEMTOP:LOA #$50:STA MEMTOP+l
Here we are putting a new location into the top-of-
memory pointer which the computer uses to decide where it
can store things. (Doing that could protect an ML program
which resides above the address stored in this pointer.) Like
all pointers, it uses two bytes. If we want to store $5000 into
this pointer, we store the lower half (the least significant byte)
into MEMTOP. We'll want to put the number $50 into the
most significant byte of the pointer-but we don't want to
waste time making a new label. It's just one higher in memory
than MEMTOP. Hence, MEMTOP + 1.
You'll also want to use the + pseudo-op command in
constructions like this :
10 *= 864
15 SCREEN = $0400
17; -----------------------------
20 LOA #32; the blank character
30 LOA #0
40 START STA SCREEN,Y
50 STA SCREEN+256,Y
60 STA SCREEN+512,Y
70 STA SCREEN+768,Y
80INY
90 BNr: START
This is the fastest way to fill memory with a given byte.
In this case we're clearing out the screen RAM by filling it
with blanks. But it's easy to indicate multiples of 256 by just
adding them to the label SCREEN.
A similar pseudo-op command is the # <. This refers to
the least significant byte of a lab el. For example:
10 *= $0360
20 SCREEN = $8011
25 SCREENPOINTER = $FB
30 ;--------------------
342
Appendix A: H ow to U se LADS
Chained Files
It is sometimes convenient to create several source code sub-
programs, to break the ML program source code into several
pieces. LADS source code is divided into a number of program
files: Array, Equate, Math, Pseudo, etc. This way, you don't
need to load the entire source code in the computer's memory
when you just want to work on a particular part of it. It also
allows you to assemble source code far larger than could fit
into available RAM.
In the last line of each subprogram you want to link, you
put the linking pseudo-op .FILE NAME (use no quotes) to tell
the assembler which subprogram to assemble next. Sub-
programs, chained together in this fashion, will be treated as if
they were one large program. The final subprogram in the
chain ends with the special pseudo-op .END NAME, and this
time the name is the filename of the first of the subprograms,
the subprogram which begins the chain. It's like stringing
pearls and then, at the end, tying thread so that the last pearl
is next to the first, to form a necklace .
Remember that you always need to include the .END
pseudo-op, even if you are assembling from a single, unlinked
source code file. In such a case (where you're working with a
solo file), you don 't need the linking .FILE pseudo-op. Instead,
343
Appendix A: How to Use LADS
refer the file to itself with .END NAME where you list the solo
file's name. Here's an illustration of how three subprograms
would be linked to form a complete program:
5 *= 864
10; "FIRST"--first program in chain
20;its first line must contain the start address
30;----------
40 LOA #20
50 STA $0400
60 .FILE SECOND
Then you save this subprogram to disk (it's handy to let
the first remark line in each subprogram identify the sub-
program's filename):
SAVE "FIRST",8
Next you create SECOND, the next link in the chain. But
here, you use no starting address; you enter no *= since only
one start address is needed for any program:
10 ; "SECOND"
20 INY:INX:DEY:DEX
30 .FILE THIRD
SAVE"SECOND",8
Now write the final subprogram, ending it with the clasp
pseudo-op .END NAME which links this last subprogram to
the first:
10 ; "THIRD"
20 LOA #65:STA $0400
30 .END FIRST
SAVE "THIRD",8
When you want to assemble this chain, just type FIRST in
the upper left-hand corner of the screen, SYS to LADS, and it
will assemble the entire chain.
If you want the object code (the finished ML program)
stored in the computer's memory during the LADS assembly,
add this line to FIRST above:
35.0
If you want to save the object code as an ML program on
disk that can be later loaded into the computer and run, add
this line to FIRST:
344
Appendix A: How to Use LADS
36.0 PROGRAMNAME
When LADS is finished assembling, there will be an ML
program on disk called PROGRAMNAME. You can load it
and SYS 864 (that was the start address we gave this pro-
gram), and the newly assembled ML program will execute.
One additional pseudo-op is the # " . It is sometimes useful
when you want to load the Accumulator with a particular
ASCII character and don't offhand recall the numerical value.
The letter A is 65 in the ASCII code. If you LOA #65:STA
SCREEN, you would store the letter A to the screen. But, for
convenience, you can LOA #"A:STA SCREEN. You can, in
other words, use the # " followed by the character itself rather
than by its ASCII code number.
346
Appendix A: How to Use LADS
LOOPLDA MESSAGE
and
LOOP LDAMESSAGE
are wrong.
It's fine to have leading spaces following a colon, how-
ever. LADS will ignore those (see line 60 above) . Also, spaces
within remarks are ignored. In fact, LADS ignores anything
following a semicolon (see line 70). However, the semicolon
should come after anything you want assembled. You couldn't
rearrange line 50 above by putting the BEQ END after the re-
mark message . It would be ignored because it followed the
semicolon.
When using the text form of .BYTE, it's up to you
whether you use a close quote:
50 MESSAGE .BYTE "PRINT THIS" (right)
60 MESSAGE .BYTE "PRINT THIS (also right)
3. The first character of any label must be a letter, not a
number. LADS knows when it comes upon a label because a
number starts with a number; a label starts with a letter of the
alphabet:
10 *= 864
20 LABEL = 255
30 LDA LABEL
40 LDA 255
Lines 30 and 40 accomplish the same thing and are cor-
rectly written. It would confuse LADS, however, if you wrote:
20 5LABEL = 255 (wrong)
since the number 5 at the start of the word label would signal
the assembler that it had come upon a number, not a label.
You can use numbers anywhere else in a label name-just
don't put a number at the start of the name. Also avoid using
symbols like # < > * and other punctuation, shifted letters, or
graphics symbols within labels. Stick with ordinary
alphanumerics:
10 5LABEL (wrong)
20 LABEL15 (right)
30 *LABEL * (wrong)
4. Move the Program Counter forward, never backward. The
* = pseudo-op should be used to make space in memory. If
347
Appendix A: How to Use LADS
you set the PC below its current address, you would be writ-
ing over previously assembled code:
10 *= 864
20 LOA #15
30 * = 900 (right)
10 *= 864
20 LOA #15
30 * = 864 (wrong, you'll assemble right over the LDA #15)
edit your source code, the Atari version has a special editor
integrated into LADS itself. This is necessary because with
Atari BASIC, you can only enter BASIC instructions. The line
10 *= $0600
is just as illegal as
10 PRIMT IJNAME":INPPUT A#
Both are coolly received with an error message. This syntax
checking is fine when working with BASIC, but prevents the
standard BASIC editor from accepting and storing LADS
source code. Once the decision was made to create an entirely
new source code editor, LADS became a self-contained pack-
age. The BASIC cartridge is neither needed nor especially de-
sired. Since LADS takes over the Atari, DOS is the only other
program in memory, freeing up all the RAM ordinarily used
by BASIC.
One note : If you'd rather use a word processor or other
text editor to enter and edit your source code, you can, as long
as your editor will send out numbered statements, in ASCII,
ending with 155's (ATASCII carriage returns). Most Atari
word processors conform to this; it you're not sure, experiment
with a short source code program. Be sure to end each source
line with a carriage return. You can then load the file into the
LADS editor or assemble directly from disk with the LADS
D:filename command.
Entering LADS
The object code for Atari LADS is typed in with the Atari ver-
sion of MLX, a machine language entry editor. See Appendix
C for details. After you've typed it in, you can save LADS to
disk under the filename AUTORUN.5YS. This will cause
LADS to load and automatically run when you turn on (boot)
your computer and disk drive . LADS as assembled requires at
least 40K of memory. If you have access to a 40K Atari, you
can reassemble the source code to almost any memory loca-
tion you want (see " Programming Atari LADS" in Chapter
11).
If you didn't save LADS as AUTORUN .5YS, you need to
load it from the DOS menu, then use menu selection M and
run it at address 8000 . If you bought the LADS source/object
code disk, LADS will automatically load and run when you in-
sert the disk and turn on your system. LADS will then print
349
A ppendix A: How to Use LADS
351
Appendix A : How to U se LADS
Error Handling
Within the editor, any error will be displayed with Error - and
the error number. This may be Error - 170 for file not found
when you try to load a nonexistent file from the editor, or it
may be an error returned from the assembler. Use your DOS
or BASIC manual for a list of error numbers and error mes-
sages. Any illegal command or a command the editor can't
understand will result in a Syntax Error.
Pseudo-ops
All the pseudo-ops described above for the Commodore and
Apple versions are full y operative in Atari LADS. A few usage
notes follow:
.0 This causes the assembler to POKE the object code into
memory. Its converse is .NO. You must not overwrite the
352
Appendix A: How to Use LADS
Programming Aids
Following are two utility programs, written in BASIC. Program
A-I will renumber an Atari LADS source program. Just run it
and follow the prompts. Program A-2 partially converts a file
from the Assembler Editor, EASMD, or MAC/65 assembler to
the LADS syntax. It removes leading spaces after a line num-
ber, trailing spaces at the end of a line, and tucks comments
right next to the operand fields. Into the DATA statements
starting at 500, insert the filenames of the files you want con-
verted. Be sure to make END the last item in the DATA state-
ments. To use LADS to assemble code written for one of these
other assemblers, you must complete the conversion yourself
by adjusting the pseudo-ops. See the descriptions of the LADS
pseudo-ops at the start of this appendix.
354
Appendix A: How to Use LADS
357
Appendix B: LADS Object Code
11144 :254,141,116,062,032,225,198
11150 :255,173,119,062,240,003,226
11156 :076,168,046,032,104,051,113
11162 :169,000,141,127,062,141,026
11168 :137,062,172,138,062,208,171
11174 :003,076,198,043,140,158,016
11180 :062,173,156,062,240,012,109
11186 :032,142,056,032,063,056,047
11192 :032,103,056,032,063,056,014
11198 :173,149,062,240,003,032,081
11204 :059,055,076,106,05 0 ,173,203
11210 :114,062,240,023,201,003,077
11216 :208,114,169,001,141,114,187
11222 :062,173,071,061,208,104,125
11228 :169,008,024,109,113,062,193
11234 :141,113,062,076,185,045,080
11240 :173,138,062,240,057,160,038
11246 :255,200,185,068,061,240,223
11252 :046,153,150,061,201,032,119
11258 :208,243,200,185,068,061,191
11264 :201,061,208,003,076,233,014
11270 :045,162,000,142,158,062,063
11276 :138,153,150,061,185,068,255
11282 :061,240,008,157,068,061,101
11288 :232,200,076,016,044,157,237
11294 :068,061,076,198,043,032,252
11300 :130,048,032,036,048,076,150
11306 :198,043,173,089,061,201,039
11312 :064,176,006,173,090,061,106
11318 : 238,137,062,073,128,141,065
11324 :120,062,032,207,048,076,093
11330 :197,044,160,000 , 140,127,222
11336 :062,173,071,061,201,032,160
11342 :240,003,076,071,047,185,188
11348 :072,061,201,065,144,003,118
11354 :238,127,062,153,089,061,052
11360 :200,185,072,061,240,022,108
11366 :153,089,061,201,065,144,047
11372 :003,238,127,062,200,185,155
11378 :072,061,240,006,153,089,223
11384 :061,076,112,044,136,140,177
11390 :126,062,173,128,062,208,117
11396 :064,173,127,062,208 , 162,160
11402 :169,089,133,251,169,061,242
11408 :133,252,160,000,173,089,183
11414 :061,201,0 48,176,007,024,155
11420 :230,251,144,002,230,252,241
11426 :177,251,240,016,201,041,064
11432 :240,012,201,044,240,008,145
358
Ij
11438 :201,032,240,004,200,076,159
11444 :162,044,072,152,072,169,083
11450 :000,145,251.032.219.050.115
11456 :104,168,104,145,251,173,113
11462 :089,061,201,035,240,063,119
11468 :201,040,240,023,173 ,1 14,227
11474 :062,201,008,240,055,201,209
11480 :003,208,113,169,008,024,229
11486 :109,113,062,141,113,062,054
11492 :076,185,045,172 ,126,062,126
11498 :185,089,061,201,041,240,027
11504 :016,173,114,062,201,001,039
11510 :208,009,169,016,024,109,013
11516 :113,062,141,113,062,173,148
11522 :114,062,201,006,240,083,196
11528 :076,126,045,076,153,045,017
11534 :173,138,062,208,003,076,162
11540 :126,045,056,173,122,062,092
11546 :229,253,072,173,123,062,170
11552 :229,254,176,014,2 01,255, 137
11558 :240,004,104,076,010,048,008
11564 :104,016,012,07 6,062,045, 103
11570 :240,004,104,076,010,048,020
11576 :104,016,003,076, 0 10 ,048,0 57
11582 :056,233,002,141 ,122,062, 166
11588 :169,000,141,123,062,076,127
11594 :126,045,172,12 6,062, 136,229
11600 :185,089, 061,20 1,044,208,100
11606 :004,200,076,242,046,173,059
11612 :113,062,201,076,208,003,243
11618 :076,135,045,173,123,062,200
11624 :208,085,173,114,0 62 ,2 0 1,179
11630 :006,176,013,201,0 02,240,2 36
11636 :009,169, 004 ,02 4,109,113,032
11642 :062,141,113,062,032,130,150
11648 :055,032,168,055,076,233,235
11654 :045,172,126,062,1 85,089,045
11660 :061,201,041,208,005,169,0 57
11666 :108,141,113,062,076,227,105
11672 :045,173,090,061, 20 1,034,244
11678 :208,006,173,091,061,141,070
11684 :122,062,173,114,062,201,130
11690 :001,208,209,169,008,024,021
11696 :109,113,062,141,113,062,008
11702 :076,126,045,032,130, 055, 134
11708 :076,233, 045 ,173,114,062, 123
11714 :201,002,240,004,201,007,081
11720 :208,012,173,113, 062,024,024
11726 :105,008,141,113,062,076,199
359
Appendix B : LADS Object Code
11732 :227,045,201,006,176,009,108
11738 :173,113,062,024,105,012,195
11744 :141,113,062,032,130,055,245
11750 :032,194,055,173,138,062,116
11756 :208,003,076,165,046,173,139
11762 :156,062,208,003,076,165,144
11768 :046,173,158,062,208,062,189
11774 :173,152,062,240,042,169,068
11780 :020,056,229,211,141,139,032
11786 :062,032,204,255,162,004,217
11792 :032,201,255,172,139,062,109
11798 :016,005,160,002,076,031,056
11804 :046,169,032,032,210,255,004
11810 :136,208,250,032,204,255,095
11816 :162,001,032,198,255,169,089
11822 :020,133,211,169,150,133,094
11828 :251 i 169,061,133,252,032,182
11834 :046,056,169,030,056,229,132
11840 :211,141,140,062,169,030,049
11846 :133,211,173,152,062,240,017
11852 :031,032,204,255,162,004,252
11858 :032,201,255,172,140,062,176
11864 :240,010,048,008,169,032,083
11870 :032,210,255,136,208,250,161
11876 :032,204,255,162,001,032,018
11882 :198,255,032,155,056,173,207
11888 :150,062,240,017,201,001,015
11894 :208,005,169,060,076,127,251
11900 :046,169,062,032,210,255,130
11906 :032,192,056,173,159,062,036
11912 :240,019,032,063,056,169,203
11918 :059,032,210,255,169,000,099
11924 :133,251,169,002,133,252,064
11930 :032,046,056,032,133,056,253
11936 :173,119,062,208,003,076,033
11942 :140,043,173,138,062,208,162
11948 :027,238,138,062,173,115,157
11954 :062,133,253,173,116,062,209
11960 :133,254,032,204,255,169,207
11966 :001,032,195,255,032,248,185
11972 :049,076,061,043,032,204,149
11978 :255,169,001,032,195,255,085
11984 :169,002,032,195,255,173,010
11990 :152,062,240,021,032,204,157
11996 :255,162,004,032,201,255,105
12002 :169,013,032,210,255,032,169
12008 :204,255,169,004,032,195,067
12014 :255,076,116,164,185,089,099
12020 :061,201,088,240,101,136,047
360
Appendix B: LADS Object Code
12026 :136,185,089,061,201,041,195
12032 :208,003,076,231,044,173,223
12038 :123,062,208,015,173,114,189
12044 :062,201,002,240,082,201,032
12050 :005,240,078,201,001,240,015
12056 :122,173,114,062,201,001,185
12062 :208,012,173,113,062,024,110
12068 :105,024,141,113,062,076,045
12074 :227,045,173,114,062,201,096
12080 :005,240,008,169,049,032,039
12086 :218,047,076,071,047,173,174
12092 :113,062,024,105,028,141,021
12098 :113,062,076,227,045,032,109
12104 :167,056,032,142,056,169,182
12110 :087,133,251,169,062,133,145
12116 :252~032~046,056,032,133,123
12122 :056,076,233,045,173,123,028
12128 :062,208,068,173,114,062,015
12134 :201,002,208,012,169,016,198
12140 :024,109,113,062,141,113,158
12146 :062,076,126,045,201,001,113
12152 :240,016,201,003,240,012,064
12158 :201,005,240,008,169,050,031
12164 :032,218,047,076,071,047,111
12170 :169,020,024,109,113,062,123
12176 :141,113,062,185,091,061,029
12182 :201,089,208,010,173,113,176
12188 :062,201,182,240,003,076,152
12194 :025,047,076,126,045,173,142
12200 :114,062,201,002,208,012,255
12206 :169,024,024,109,113,062,163
12212 :141,113,062,076,227,045,076
12218 :201,001,240,016,201,003,080
12224 :240,012,201,005,240,008,130
12230 :169,051,032,218,047,076,023
12236 :071,047,169,028,024,109,140
12242 :113,062,141,113,062,076,009
12248 :227,045,141,139,062,140,202
12254 :141,062,142,140,062,169,170
12260 :186,032,210,255,104,170,161
12266 :104,168,152,072,138,072,172
12272 :152,032,205,189,173,139,106
12278 :062,172,141,062,174,140,229
12284 :062,096,160,000,152,153,107
12290 :068,061,200,192,080,208,043
12296 :248,096,032,133,056,032,093
12302 :167,056,032,142,056,169,124
12308 :198,133,251,169,061,133,197
12314 :252,032,046,056,032,133,065
361
Appendix B: LADS Object Code
12320 :056,076,126,045,160,255,238
12326 :200,185,068,061,240,086,110
12332 :201,032,208,246,200,200,107
12338 :140,132,062,056,165,176,013
12344 :237,132,062,133,176,165,193
12350 :177,233,000,133,177,160,174
12356 :000,185,068,061,073,128,071
12362 :145,176,200,185,068,061,141
12368 :201,032,240,005,145,176,111
12374 :076,076,048,200,185,068,227
12380 :061,201,061,240,059,136,082
12386 :165,253,145,176,200,165,178
12392 :254,145,176,174,132,062,023
12398 :202,160,000,189,068,061,022
12404 :240,008,153,068,061,232,110
12410 :200,076,113,048,153,068,012
12416 :061,096,032,133,056,032,026
12422 :142,056,032,167,056,169,244
12428 :255,133,251,169,061,133,118
12434 :252,032,046,056,032,133,185
12440 :056,076,202,048,136,140,042
12446 :133,062,173,128,062,208,156
12452 :023,200,200,200,140,121,024
12458 :062,169,068,024,109,121,211
12464 :062,133,251,169,061,105,189
12470 :000,133,252,032,219,050,100
12476 :172,133,062,173,122,062,144
12482 :145,176,173,123,062,200,049
12488 :145,176,104,104,076,233,014
12494 :045,173,135,062,133,178,164
12500 :173,136,062,133,179,032,159
12506 %221,049,169,255,141,155,184
12512 :062,056,165,176,229,178,066
12518 :165,177,229,179,176,099,231
12524 :162,000,056,165,178,233,006
12530 :002,133,178,165,179,233,108
12536 :000,133,179,160,000,177,129
12542 :178,048,012,165,178,208,019
12548 :002,198,179,198,178,232,223
12554 :076,253,048,165,178,141,103
12560 :142,062,165,179,141,143,080
12566 :062,177,178,205,120,062,058
12572 :240,003,076,063,049,232,179
12578 :142,121,062,162,001,173,183
12584 :137,062,240,004,200,032,203
12590 :221,049,200,185,089,061,083
12596 :240,083,201,048,144,079,079
12602 :232,209,178,240,241,173,051
12608 :142,062,133,178,173,143,127
362
Appendix B: LADS Object Code
12614 :062,133,179,032,221,049,234
12620 :076,225,048,173,155,062,047
12626 :048,001,096,173,138,062~088
12632 :208,002,240,023,032,167,248
12638 :056,032,142,056,032 , 063,219
12644 :056,169,239,133,251,169,093
12650 :061,133,252,032,046,056,174
12656 :032,133,056,104,104,173,202
12662 :113,062,041,031,201,~16,070
12668 :240,008,173,150,062,208,197
12674 :003,076,227,045,076,126,171
12680 :045,236,121,062,240,003,075
12686 :076,063,049,238,155,062,017
12692 :240,003,032,230,049,172,106
12698 :121,062,173,137,062,240,181
12704 :001,200,177,178,141,122,211
12710 :062,200,177,178,141,123,023
12716 :062,173,150,062,240,010,101
12722 :201,002,208,030,173,123,147
12728 :062,141,122,062,173,149,125
12734 :062,240,019,024,173,147,087
12740 :062,109,122,062,141,122,046
12746 :062,173,148,062,109,123,111
12752 :062,141,123,062,173,138,139
12758 :062,208,001,096,076,063,208
12764 :049,165,178,208,002,198,252
12770 :179,198,178,096,032,167,052
12776 :056,169,057,133,251,169,043
12782 :062,133,252,032,046,056,051
12788 :032,133,056,096,032,204,029
12794 :255,169,001,032,195,255,133
12800 : 169,001,133,184,169,008,152
12806 :133,186,169,003,133,185,047
12812 :169,150,133,187,169,061,113
12818 :133,188,032,193,225,096,117
12824 :169,002,133,184,169,008,177
12830 :133,186,169,002,133,185,070
12836 :169,150 , 133,187,169,061,137
12842 :133,188,032,193,225,032,077
12848 :204,255,096,169,004,133,141
12854 :184,169,004,133,186,169,131
12860 :OOO,133 , 183,032,193,225,058
12866 :032,204,255,096,032,204,121
12872 :255,169,OOO,133,147,133,141
12878 :144,169,008,133,186 , 169,119
12884 :150,133,187,169 , 061,133,149
12890 :188,032,117,225,032,204,120
12896 :255,165,043,133,167,165,OOO
12902 :044,133,168,096,160,OOO,191
363
Appendix B: LADS Object Code
12908 :162;255,232;185,028;060,006
12914 :205,068,061,240,010,200,130
12920 :200,200,224,057,208,240,225
12926 :076,232,043,200,185,028,122
12932 :060,205,069,061,240,006,005
12938 :200,200,208,224,240,238,168
12944 :200,185,028,060,205,070,124
12950 :061,240,005,200,208,210,050
12956 :240,224,173,071,061,201,102
12962 :032,240,004,201,000,208,079
12968 :213,189,196,060,141,114,057
12974 :062,188,252,060,140,113,221
12980 :062,076,201,043,162,001,213
12986 :032,198,255,162,006,032,103
12992 :228,255,202,208,250,032,087
12998 :228,255,201,172,240,014,028
13004 :169,181,133,251,169,061,144
13010 :133,252,032,046,056,076,037
13016 :200,046,096,160,000,177,127
13022 :251,240,004,200,076,221,190
13028 :050,140,178,061,136,169,194
13034 :000,141,122,062,141,123,055
13040 :062,162,001,142,140,062,041
13046 :177,251,041,015,141,176,023
13052 :061,141,179,061,169,000,095
13058 :141,177,061,141,180,061,251
13064 :202,240,018,032,045,051,084
13070 :173,176,061,141,179,061,037
13076 :173,177,061,141,180,061,045
13082 :076,008,051,238,140,062,089
13088 :174,140,062,032,084,051,063
13094 :136,206,178,061,208,202,005
13100 :096,024,014,176,061,046,205
13106 :177,061,014,176,061,046,073
13112 :177~061,024,173,179,061,219
13118 :109,176,061,141,176,061,018
13124 :173,180,061,109,177,061,061
13130 :141,177,061,014,176,061,192
13136 :046,177,061,096,024,173,145
13142 :176,061,109,122,062,141,245
13148 :122,062,173,177,061,109,028
13154 :123,062,141,123,062,096,193
13160 :032,254,047,160,000,140,225
13166 :128,062,140,159,062,140,033
13172 :150,062,140,149,062,173,084
13178 :154,062,208,012,032,228,050
13184 :255,141,117,062,032,228,195
13190 :255,141,118,062,032,228,202
13196 :255,208,008,032,231,052,158
364
Appendix B : LADS Object Code
13202 :104,104,076,140,043,201,046
13208 :032,240,239,076,166,051,188
13214 :032,228,255,208,003,076,192
13220 :231,052,201,058,208,003,149
13226 :076,080,052,201,059,208,078
13232 :115,140,139,062,173 , 152,189
13238 :062,240,085,141,159,062,163
13244 :173,139,062,240,006,032,072
13250 :238,051,076,022,052,032,153
13256 :228,255,240,014,201,127 , 241
13262 :144,003,032,094,052,153,172
13268 :068,061,200,076,199,051,099
13274 :032,142,056,032,063,056,087
13280 :032,155,056,032,133,056,176
13286 :169,000,141,139,062,076,049
13292 :022,052,141,159,062,141,045
13298 :139,062,160,000,032,228,095
13304 :255,208,007,153,000,002,105
13310 :172,139,062,096,016,003,230
13316 :032,022,055,153,000,002,012
13322 :200,076,246,051,032,228,075
13328 :255,240,003,076,014,052,144
13334 :032,231,052,173,139,062 , 199
13340 :208,005,104,104,076,140,153
13346 :043,096,201,177,240,091,114
13352 :201,179,240,095,201,170,102
13358 :208,003,238,149,062,201,139
13364 :172,208,003,076,147,052,198
13370 :201,046,240,022,201,036,036
13376 :240,021,201,127,144,003,032
13382 :032,094,052,153,068,061,018
13388 :200,076,158,051,141,154,088
13394 :062,096,076,139,053,153,149
13400 :068,061,200,076,006,053 , 040
13406 :056,233,127,141,131,062,076
13412 :162,255,206,131,062,240,132
13418 :008,232,189,158,160,016,101
13424 :250,048,243,232,189,158,208
13430 :160,048,007,153,068,061,103
13436 :200,076,115,052,041,127,223
13442 :096,169,002,141,150,062,238
13448 :076,158,051,169,001,141,220
13454 :150,062,076,158,051,032,159
13460 :158,051,173,138,062 , 240,202
13466 :011,169,042,032,210,255,105
13472 :032,155,056,032,133,056,112
13478 :173,128,062,208,032,160,161
13484 :000,185,068,061,201,032,207
13490 :240,004,200,076,173,052,155
365
Appendix B: LADS Object Code
13496 :200,132,251,169,068,024,004
13502 :101,251,133,251,169,061,132
13508 :105,000,133,252,032,219,169
13514 :050,173,138,062,240,008,105
13520 :173,151,062,240,003,032,101
13526 :213,054,173,122,062,133,203
13532 :253,173,123,062,133,254,194
13538 :104,104,076,140,043,153,078
13544 :068,061,200,192,080,208,017
13550 :248,153,068,061,032,228,004
13556 :255,032,228,255,240,006,236
13562 :169,000,141,154,062,096,104
13568 :169,001,141,119,062,096,076
13574 :162,000,032,228,255,240,155
13580 :044,201,058,240,040,201,028
13586 :032,240,243,201,059,240,009
13592 :032,201,044,240,015,201,245
13598 :041,240,011,157,129,061,157
13604 :232,153,068,061,200,076,058
13610 :008,053,142,129,062,153,077
13616 :068,061,200,032,077,053,027
13622 :076,158,051,141,139,062,169
13628 :169,000,142,129,062,153,203
13634 :068,061,032,077,053,173,018
13640 :139,062,076,161,051,169,218
13646 :000,141,122,062,141,123,155
13652 :062,170,014,122,062,046,048
13658 :123,062,014,122,062,046,007
13664 :123,062,014,122,062,046,013
13670 :123,062,014,122,062,046,019
13676 :123,062,189,129,061,201,105
13682 :065,144,002,233,007,041,094
13688 :015,013,122,062,141,122,083
13694 :062,232,236,129,062,208,031
13700 :209,238,128,062,169,001,171
13706 :096,192,000,240,014,174,086
13712 :138,062,208,009,072,152,017
13718 :072,032,036,048,104,168,098
13724 :104,153,068,061,200,032,006
13730 :228,255,153,068,061,200,103
13736 :201,066,208,104,169,000,148
13742 :141,144,062,173,138,062,126
13748 :240,023,140,141,062,173,191
13754 :156,062,240,015,032,142,065
13760 :056,032,063,056,032,103,022
13766 :056,032,063,056,172,141,206
13772 :062,032,228,255,153,068,234
13778 :061,200,201,032,208,245,133
13784 :032,228,255,153,068,061,245
366
Appendix B: LADS Object Code
13790 :200,201,034,208,069,032,198
13796 :228,255,208,003,076,186,160
13802 :054,201,058,208,003,076,066
13808 :189,054,201,059,208,012,195
13814 :032,238,051,174,152,062,187
13820 :142,159,062,076,186,054,163
13826 :201,034,208,003,076,227,239
13832 :053,174,138,062,208,009,140
13838 :032,032,056,076,227,053,234
13844 :076,139,057,153,068,061,062
13850 :170,140,141,062,032,248,051
13856 :055,172,141,062,200,076,226
13862 :227,053,162,000,142,145,255
13868 :062,157,169,061,232,173,130
13874 :145,062,208,117,032,228,074
13880 :255,240,067,201,058,240,093
13886 :063,201,059,208,012,032,125
13892 :238,051,174,152,062,142,119
13898 :159,062,076,126,054,141,180
13904 :109,061,173,138,062,208,063
13910 :013,173,109,061,201,032,163
13916 :208,211,032,032,056,076,195
13922 :049,054,173,109,061,153,185
13928 :068,061,200,201,032,240,138
13934 :024,201,000,240,020,201,028
13940 :058,240,016,157,169,061,049
13946 :232,076,049,054,238,145,148
13952 :062,141,110,061,076,079,145
13958 :054,169,169,133,251,169,055
13964 :061,133,252,140,141,062,161
13970 :032,219,050,174,122,062,037
13976 :032,248,055,172,141,062,094
13982 :169,000,162,005,157,169,052
13988 :061,202,208,250,076,049,242
13994 :054,173,138,062,208,003,040
14000 :032,032,056,173,110,061,128
14006 :201,058,240,003,032,231,179
14012 :052,141,154,062,238,158,225
14018 :062,104,104,173,138,062,069
14024 :240,008,173,156,062,240,055
14030 :003,076,108,046,076,140,143
14036 :043,173,138,062,201,002,063
14042 :208,001,096,032,204,255,246
14048 :162,002,032,201,255,056,164
14054 :173,122,062,229,253,141,186
14060 :120,062,173,123,062,229,237
14066 :254,141,121,062,169,000,221
14072 :032,210,255,173,120,062,076
14078 :208,003,206,121,062,206,036
367
Appendix B : LADS Object Code
14084 :120,062,208,238,173,121,158
14090 :062,208,233,032,204,255,236
14096 :162,001;032,198,255,096,248
14102 :056,233,127,141,131,062,004
14108 :162,255,206,131,062,240,060
14114 :008,232,189,158,160,016,029
14120 :250,048,243,232,189,158,136
14126 :160,048,007,153,000,002,160
14132 :200,076,043,055,041,127,082
14138 :096,160,OOO,162,OOO,185,149
14144 :068,061,201,043,240,004,169
14150 :200,076,063,055,200,185,081
14156 :068,061,032,090,055,176,046
14162 :018,157,129,061,232,076,243
14168 :074,055,201,058,176,006,146
14174 :056,233,048,056,233,208,160
14180 :096,169,000,157,129,061,200
14186 :169,129,133,251,169,061,250
14192 :133,252,032,219,050,173,203
14198 :122,062,141,147,062,173,057
14204 :123,062,141,148,062,096,244
14210 :173,138,062,208,004,032,235
14216 :032,056,096,173,156,062,199
14222 :240,017,032,204,255,162,028
14228 :001,032,198,255,174,113,153
14234 :062,032,072,056,032,063,215
14240 :056,174,113,062,032,248,077
14246 :055,096,173,138,062,208,130
14252 :004,032,032,056,096,173,053
14258 :156,062,240,006,174,122,170
14264 :062,032,072,056,174,122,190
14270 :062,076,248,055,173,138,174
14276 :062,208,007,032,032,056,081
14282 :032,032,056,096,173,156,235
14288 :062,240,006,174,122,062,106
14294 :032,072,056,174,122,062,220
14300 :032,248,055,173,156,062,178
14306 :240,014,173,157,062,240,088
14312 :003,032,063,056,174,123,171
14318 :062,032,072,056,174,123,245
14324 :062,076,248,055,142,121,180
14330 :062,173,153,062,240,005,177
14336 :160,000,138,145,253,173,101
14342 :151,062,240,022,032,204,205
14348 :255,162,002,032,201,255,151
14354 :173,121,062,032,210,255,103
14360 :032,204,255,162,001,032,198
14366 :198,255,024,169,001,101,010
14372 :253,133,253,169,OOO,101,177
368
Appendix B: LADS Object Code
14378 :254,133,254,096,160,OOO,171
14384 :177,251,240,010,032,210,200
14390 :255,032,186,056,200,076,091
14396 :048,056,096,169,032,032,237
14402 :210,255,032,186,056,096,133
14408 :142,140,062,173,157,062,040
14414 :240,011,138,032,114,057 , 158
14420 :032,227,056,174,140,062,007
14426 :096,169,000,032,205,189,013
14432 :032,227,056,174 , 140,062,019
14438 :096,173,157,062,240,014,076
14444 :165,254,032,114,057,165 , 127
14450 :253,032,114,057,032,022,112
14456 :057,096,166,253,165,254,087
14462 :032,205,189,032,022,057,151
14468 :096,169,013,032,210,255,139
14474 :032,186,056,096,174,117,031
14480 :062,173,118,062,032,205,028
14486 :189,032,076,057,096,169,001
14492 :068;133;251;169;061;133;203
14498 :252,032,046,056,096,169,045
14504 :007,032,210,255,169,018,091
14510 :032,210,255,032,155,056,146
14516 :169,013,032,210,255 , 096,187
14522 :174,138,062,208,001,096,097
14528 :174,152,062,208,001,096,117
14534 :141,139,062,032,204,255,007
14540 :162,004,032,201,255,173,007
14546 :139,062,032,210,255,032,172
14552 :204,255,162,001,032,198,044
14558 :255,173,139,062,096,174,097
14564 :138,062,208,001,096,174,139
14570 :152,062,208,001,096,032,017
14576 :204,255,162,004,032,201,074
14582 :255,173,157,062,240,009,118
14588 :173,140,062,032,114,057,062
14594 :076,013,057,169,000,174,235
14600 :140,062,032,205,189,032,156
14606 :204,255,162,001,032,198,098
14612 :255,096,174,138,062,208,185
14618 :001,096,174,152,062,208,207
14624 :001,096,032,204,255 , 162,014
14630 :004,032,201,255,174,157,093
14636 :062,240,013,165,254,032,042
14642 :114,057,165,253,032,114,017
14648 :057,076,067,057,165,254,220
14654 :166,253,032,205,189,032,171
14660 :204,255,162,001 , 032,198,152
14666 :255,096,174,138,062,208,239
369
Appendix B : LADS Object Code
14672 :001,096,174,152,062,208,005
14678 :001,096,032,204,255,162,068
14684 :004,032,201,255,173,118,107
14690 :062,174,117,062,032,205,238
14696 :189,032,204,255,162,001,179
14702 :032,198,255,096,072,041,036
14708 :015,168,185,052,061,170,255
14714 :104,074,074,074,074,168,178
14720 :185,052,061,032,210,255,155
14726 :138,032,210,255,096,201,042
14732 :070,208,008,032,238,057,241
14738 :104,104,076,140,043,201,046
14744 :128,208,006,032,071,058,143
14750 :076,146,057,201,068,208,146
14756 :003,076,127,058,201,080,197
14762 :208,003,076,244,058,201,192
14768 :078,208,003,076,053,059,141
14774 :201,079,208,003,076,032,013
14780 :059,201,083,208,003,076,050
14786 :237,059,201,072,208,003,206
14792 :076,007,060,153,068,061,113
14798 :032,142,056,032,063,056,075
14804 :032,103,056,032,167,056,146
14810 :032,155,056,169,087,133,082
14816 :251,169,062,133,252,032,099
14822 :046,056,032,133,056,076,117
14828 :007,059,032,228,255,201,250
14834 :032,240,003,076,238,057,120
14840 :160,000,032,228 , 255,201,100
14846 :000,240,014,201,127,144,212
14852 :003,032,094,052,153,068,150
14858 :061,200,076,250,057,132,018
14864 :183,160,000,185,068,061,161
14870 :240,007,153,150,061,200,065
14876 :076,019,058,173,138,062,042
14882 :208,006,032,103,056,032,215
14888 :063,056,032,155 , 056,032,178
14894 :133,056,032,248,049,162,214
14900 :001,032,198,255,032,228,030
14906 :255,032,228,255,032,231,067
14912 :052,162,000,142,119,062,089
14918 :096,169,046,032,210,255,110
14924 :169,069,032,210,255,169,212
14930 :078,032,210,255,169,068,126
14936 :032,210,255,169,032,032,050
14942 :210,255,032,228,255,032,082
14948 :248,057,173,138,062,240,250
14954 :003,238,119,062,238,138,136
14960 :062,173,115,062,133,253,142
370
Appendix B: LADS Object Code
14966 :173,116,062,133,254,032,120
14972 :104,051,096,173,138,062,236
14978 :240,030,032,228,255,153,044
14984 :068,061,160,000,032,228,173
14990 :255,240,020,201,127,144,105
14996 :003,032,094,052,153,068,038
15002 :061,153,150,061,200,076,087
15008 :140,058,076,007,059,169,157
15014 :044,153,150,061,200,169,175
15020 :080,153,150,061,200,169,217
15026 :044,153,150,061,200,169,187
15032 :087,153,150,061,200,132,199
15038 :183,032,155,056,032,133,013
15044 :056,238,151,062,032,024,247
15050 :050,162,002,032,201,255,136
15056 :173,115,062,032,210,255,031
15062 :173,116,062,032,210,255,038
15068 :032,204,255,162,001,032,138
15074 :198,255,032,205,059,032,239
15080 :231,052,104,104,162,000,117
15086 :142,119,062,076,140,043,052
15092 :173,138,062,240,014,032,135
15098 :051,050,238,152,062,032,067
15104 :204,255,162,001,032,198,084
15110 :255,032,228,255,240,007,255
15116 :201,058,240,006,076,007,088
15122 :059,032,231,052,104,104,088
15128 :162,000,142,119,062,076,073
15134 :140,043,169,046,032,210,158
15140 :255,169,079,032,210,255,012
15146 :032,133,056,169,001,141,062
15152 :153,062,076,007,059,173,066
15158 :138,062,240,205,032,228,191
15164 :255,201,080,240,012,201,025
15170 :079,240,058,201,083,240,199
15176 :106,201,072,240,076,169,168
15182 :046,032,210,255,169,078,100
15188 :032,210,255,169,080,032,094
15194 :210,255,032,133,056,206,214
15200 :152,062,032,204,255,162,195
15206 :004,032,201,255,169,013,008
15212 :032,210,255,169,004,032,042
15218 :195,255,032,204,255,162,193
15224 :001,032,198,255,076,007,177
15230 :059,169,046,032,210,255,129
15236 :169,078,032,210,255,169,021
15242 :079,032,210,255,032,133,111
15248 :056,169,000,141,153,062,213
15254 :076,007,059,169,046,032,027
371
Appendix B: LADS Object Code
15260 :210,255,169,078,032,210,086
15266 :255,169,072,032,210,255,131
15272 :032,133,056,169,000,141,187
15278 :157,062,076,007,059,169,192
15284 :046;032;210;255 ; 169 ; 078 ; 202
15290 :032,210,255,169,083,032,199
15296 :210,255,032,133,056,169,023
15302 :000,141,156,062,076,007,128
15308 :059,166,144,208,001,096,110
15314 :169,000,032,072,056,032,059
15320 :063,056,169,021,133,251,141
15326 :169,062,133,252,032,167,013
15332 :056,032,046,056,104,104,114
15338 :076,200,046,169,046,032,035
15344 :210,255,169,083,032,210,175
15350 :255,032,133,056,173,138,009
15356 :062,240,005,169,001,141,102
15362 :156,062,076,007,059,169,019
15368 :046,032,210,255,169,072,024
15374 :032,210,255,032,133,056,220
15380 :169,001,141,157,062,076,114
15386 :007,059,076,068,065,076,121
15392 :068,089,074,083,082,082,254
15398 :084,083,066,067,083,066,231
15404 :069,081,066,067 , 067,067,205
15410 :077,080,066,078,069,076,240
15416 :068,088,074,077 , 080,083,014
15422 :084,065,083,084,089,083,038
15428 :084,088,073,078,089,068,036
15434 :069,089,068,069,088,068,013
15440 :069,067,073,078,088,073,016
15446 :078,067,067,080,089,067,022
15452 :080,088,083,066,067,083,047
15458 :069,067,065,068,067,067,245
15464 :076,067,084,065,088,084,056
15470 :065,089,084 , 088,065,084,073
15476 :089,065,080,072,065,080,055
15482 :076,065,066,082,075,066,040
15488 :077,073,066,080 , 076,065,053
15494 :078,068,079,082,065,069,063
15500 :079,082,066,073,084,066,078
15506 :086,067,066,086,083,082,104
15512 :079,076,082,079,082,076,114
15518 :083,082,067,076,068,067,089
15524 :076,073,065,083,076,080,105
15530 :072,080,080,076,080,082,128
15536 :084,073,083,069,068,083,124
15542 :069,073,084,083,088,084,151
15548 :088,083,067,076,086,078,154
372
Appendix B : LADS O bject C ode
15554 :079,080,001,005,009,000,112
15560 :008,008,008,001,008,005,238
15566 :006,001,002,002,000,000,217
15572 :000,002,000,002,004,004,224
15578 :001,000,001,000,000,000,220
15584 :000,000,000,000,000,008,232
15590 :008,001,001,001,007,008,000
15596 :008,003,003,003,000,000,253
15602 :003,000,000,000,000,000,245
15608 :000,000,000,000,161,160,057
15614 :032,096,176,240,144,193,111
15620 :208,162,076,129,132,134,077
15626 :200,136,202,198,232,230,184
15632 :192,224,225,056,097 , 024,066
15638 :170,168,138,152,072,104,058
15644 :000,048,016,033 , 001,065,191
15650 :036,080,112,034,098,066,204
15656 :216,088,002,008,040,064,202
15662 :248,120,186,154,184,234,148
15668 :048,049,050,051,052,053 , 099
15674 :054,055,056,057,065,066 , 155
15680 :067;068;069,070,000 ; 000;082
15686 :000,000,000 , 000,000,000,070
15692 :000,000,000 , 000,000,000,076
15698 :000,000,000,000,000,000,082
15704 :000,000,000 , 000,000,000,088
15710 :000,000,000,000,000,000,094
15716 :000,000,000,000,000 , 000,100
15722 :000,000,000,000,000,000,106
15728 :000,000,000,000,000,000,112
15734 :000,000,000,000,000,000,118
15740 :000,000,000,000,000,000 , 124
15746 :000,000,000,000,000,000,130
15752 :000,000,000,000,000,000,136
15758 :000,000,000,000,000,000,142
15764 :000,000,000,000,000,000,148
15770 :000,000,000,000,000,000,154
15776 :000,000,000,000,000,000,160
15782 :000,000,000,000,000,000,166
15788 :000,000,000,000,000,000,172
15794 :000,000,000,078,079,032 , 111
15800 :083,084,065,082,084,032,102
15806 :065,068,068,082,069,083,113
15812 :083,000,045,045,045,045,203
15818 :045,045,045,045,045,045,216
15824 :045,045,045,045,045,045,222
15830 :045,045,045,045,032,066,236
15836 :082,065,078,067,072,032,104
15842 :079,085,084,032,079,070,143
373
Appendix B: LADS Object Code
15848 :032,082,065,078,071,069,117
15854 :000,085,078,068,069,070,096
15860 :073,078,069,068,032,076,128
15866 :065,066,069,076,000,029,043
15872 :029,029,029,029,029,029,174
15878 :029,029,032,078,065,075,058
15884 :069,068,032,076,065,066,132
15890 :069,076,000,029,029,029,250
15896 :029,029,032,060,060,060,038
15902 :060,060,060,060,060,032,106
15908 :068,073,083,075,032,069,180
15914 :082,082,079,082,032,062,205
15920 :062,062,062,062,062,062,164
15926 :062,032,000,029,029,029,235
15932 :029,029,032,045,045,032,016
15938 :068,085,080,076,073,067,003
15944 :065,084,069,068,032,076,210
15950 :065,066,069,076,032,045,175
15956 :045,032,000,029,029,029,248
15962 :029,029,032,045,045,032,046
15968 :083,089,078,084,065,088,071
15974 :032,069,082,082,079,082,016
15980 :032,045,045,032,000,000,006
374
Appendix B: LADS Object Code
376
Appendix B: LADS Object Code
377
Appendix B: LADS Object Code
,33212:072,152,072,169,000,145,030
33218:134,032,043,136,104,168,043
33224: 11114, 145, 134, 173, 165, 153,1115121
33230:201,035,240,063,201,040,218
33236: 24111, 12123,173,184,154,201,163
33242:008,240,055,201,003,208,165
33248: 113, 169,1211218,12124, 109, 183,12162
33254: 154, 141, 183, 154,12176, 191, 11215
33260: 13121 , 172, 196, 154, 185, 165,214
33266:153,201,041,240,016,173,042
33272:184,154,201,001,208,009,237
33278: 169,12116,12124, 11219,183,154,141
33284: 141, 183, 154, 173, 184, 154,225
33290:201,006,240,083,076,132,236
33296: 130,12176,159, 13!11, 173,208, 124
3331212: 154,21218,01213,12176, 132, 130,213
33308:056,173,192,154,229,136,200
33314:072,173,193,154,229,137,224
33320:176,014,201,255,240,004,162
33326:104,076,040,133,104,016,007
33332:012,076,068,130,240,004,070
33338: 11214,076,04121,133,11214,12116,12119
33344:003,076,040,133,056,233,093
33350:QIQI2, 141,192, 154, 169,00QI,216
33356: 141, 193,154,076,132, 13121, 134
33362: 172,196,154,136,185,165,12166
33368:153,201,044,208,004,200,130
33374:12176,12119, 132,173,183,154,QI 63
33380:201,076,208,003,076,141,037
33386:130,173,193,154,208,085,025
33392: 173, 184, 154,201,006,176,238
33398:013,201,002,240,009,169,240
3341214:01214,12124,109,183,154,141,227
3341121: 183, 154,12132,118,140,12132,12121
33416:156,140,076,239,130,172,025
33422: 196,154,185,165, 153,21211, 172
33428 : 1214 1 , 208 , 1211215, 1 69, 1 08, 1 4 1 , 052
33434:183,154,076,233,130,173,079
33440: 166, 153,21211, Q134, 21218, 1211216,16121
33446: 173, 167, 153, 141, 192, 154, 122
33452: 173, 184, 154,201,1211211,208,12169
33458:209,169,008,024,11219,183,112
33464: 154, 141, 183, 154,12176, 132,I2IQII1I
3347121: 13121,12132,118,140,076,239,157
33476: 13121, 173, 184, 154,2Qll,1211212,12116
33482:240,004,201,007,208,012,106
33488: 173, 183, 154,024,105,12108,087
33494: 141,183, 154,12176,233, 13121 ,107
33500:201,006,176,009,173,183,200
378
Appendix B: LADS Object Code
~~
S~51Z16: 1 54 , !!124 , 1 05 , 121 1 2, 1 4 1 , 1 83 , 12177
33512: 154,12132,118,14121 ,12132,182,122
33518: 14121,173,21218,154,21218,1211213, 10121
33524:12176,171,131,173,226,154,151
3353121: 21218, 1211213, !!176 , 171, 131,173,244
33536:228,154,208,062,173,222,023
33542:154,240,042,169,020,056,175
33548:229,085,141,209,154,032,094
33554:014,145,162,12104,032,12111,13!21
3356121: 145,172,209,154,12116,005,213
33566: 160,!'i11212,!'i176,12137, 131, 169,12193
33572:12132,12132,036,145,136,208,113
33578: 25121 ,12132,014, 145, 162,12101, 134
33584:032,008,145,169,020,133,043
3359121 :!2185,169,226, 133, 134,169,21212
33596: 153, 133,135,032,12134, 141,176
33602:169,030,056,229,085,141,008
3361218: 210, 154, 169,03121, 133,12185,12185
33614:173,222,154,240,031,032,162
3362121: 12114, 145, 162,01214,12132,12111, 196
33626: 145, 172, 21!21, 154,240,12110,253
33632:048,008,169,032,032,036,165
33638: 145,136,208,250,032,014,119
33644:145,162,001,032,008,145,089
3365121: 12132, 143, 141, 173,22121, 154,209
33656:240,017,201,001,208,005,024
33662: 169,12160,12176, 133,131, 169,12196
33668:062,032,036,145,032,175,102
33674: 141, 173,229,154,24121,019,1217121
3368121:12132,12151,141,169,12159,12132,116
33686:036,145,169,000,133,134,255
33692: 169,1211215,133, 135,032,12134, 152
33698: 141,QI32, 121,141, 173, 189,191
3371214: 154, 2Q18, 1211213, Q176, 146, 128, 115
3371 i!l: 173,21218, 154, 2Q18, 12141 , 238, 172
33716:21218,154,165,136,141,23121,19121
33722: 154, 165, 137, 141,231,154,144
33728: 173, 185, 154, 133, 136, 173, 122
33734: 186, 154, 133, 137,12132,12114,12186
3374121: 145,169, 12HZI1, 12132,12125,145, 21Z19
33746:165,162,208,003,032,013,025
33752:135,076,067,128,032,014,156
33758: 145, 169, IZI!Zll , 12132,025, 145,227
33764: 162,1211212,12132,12111,145,169,237
33770:000,032,036,145,032,014,237
33776:145,169,002,032,025,145,246
33782:173,222,154,240,021,032,064
33788: QI14, 145, 162, 1Z11214, 12132,011, l1Z18
33794:145,169,013,032,036,145,030
379
Appendix B: LADS Object Code
33800:032 , 014,145,169,004,032,148
33806:025,145 .0 76,182,145,185,004
33812:165,153,201,088,240,098,197
33818: 136, 136,185, 165,153,201,234
33824:041.208,003,076,237,129,214
3383!Z1: 173,193,154,208,015,173,186
33836:184,154,201,002,240,079,136
33842:201,005,240,075,201,001,005
33848:24QI, 119, 173, 184, 154,2!!11, 1!!13
33854: 0C!ll, 2C!18, 012,173,183,154, C!125
33860: iil24, li!15, 024,141,183,154,187
33866:076,233,1 30, 173,184,154,000
33872:201,005,240,008,169,049,240
33878:032,248,132,076,104,132,042
33884: 173, 183,154,024, 105,QI28,247
3389 C!1: 141, 183, 154,076,233, 13QI, 247
33896: Q132, 155, 141, C!132, 1 3!!1, 141,223
3391212: 169, 157, 1 33, 134, 169, 154,0C!12
339!.!18: 133, 135,032,i!134, 141,076, 155
33914:239,130,173,19 3, 154,208,195
3392QI:!!168, 173, 184, 154,201,0!!12, 142
33926: 21218, QI 12, 169, 016, QI2 4, 109, 16QI
33932: 183, 154, 141 , 183, 154, QI7 6, QI07
33938:132,130,201,001,240,016,098
33944:201,003,240,012,201,005,046
33950:240,008,169,050,032,248,137
33956:132,076,104,132,169,020,029
33962:iiI24, 1!!19, 183, 154,141,183,196
33968: 154, 185, 167, 153,201,QI 89, 101
33974:208,010,173,183,154,201,087
33980:182,240,003,076,104,132,157
33986:!!176, 132, 13QI, 173, 184, 154,019
33992:201,002,208,012,169,024,048
33998:024, lQ19, 183, 154, 141, 183,232
34004:154,076 ,233, 130,201,001,239
34010:240,016,201,003,240,012,162
34016:201,005,240,008,169,051,130
34022:032,248,132,076,104,132,186
34028: 169, Q128, 024,109,183,154,135
34Q134: 141,183,154,076,233,130,135
34fZ14fZl: 141,21Z19, 154, 14C!1,211, 154,233
34046:142,210,154,169,160,032,097
34fZI52:!Z136, 145 ,1(114,170, 1(114,168,219
34e158: 152,eI72, 138 ,1Z172,152,C!132, 116
34064:207,145,173,209,154,172,052
34eI7QI:211 , 154,174,21111, 154,(1196,253
34C!176: 16 QI, e1el!!I, 152, 153, 144, 153,022
34082:200,192,080,208,248,096,034
34eI88:QI32,121 141,QI32, 155,141, 15QI
380
Appendix B: LADS Object Code
381
Appendix B: LADS Object Code
382
Appendix B: LADS Object Code
383
Appendix B: LADS Object Code
384
Appendix B: LADS Object Code
35270:201,032,240,004,200,076,183
35276: 195, 137,2lZ10, 132, 134, 169, 147
35282: 144,12124, 101, 134, 133, 134, 112
35288: 169, 153, 105,lZllZI0, 133, 135, 143
35294:032,043,136,173,208,154,200
35300:240,008,173,221,154,240,240
35306:003,032,238,139,173,192,243
35312: 154, 133, 136, 173, 193,154,159
35318: 133.137, 1l214, 1l214,lZI76, 146,178
35324: 128, 153, 144, 153,2!!1l21, 192, 198
35330:080,208,248,153,144,153,220
35336:173,083,003,201,003,240,199
35342:010,201,136,240,006,169,008
35348: lZl 121 121 , 141,224, 154,11196, 169,12136
35354:!ZIl2I1,141, 189, 154,l2196, 162,1211211
35360:000,032.085,145,240,044,066
35366:201,058,240,040,201,032,042
35372:240,243,201,059,240,032,035
35378:201,044,240,015,201,041,024
35384:240,011,157,205,153,232,030
3539121: 153, 144, 153,21210,11176,12133,12153
35396: 138,142,199,154,153,144,23121
354l!12: 153, 2 iii QI ,12132,1 iZ12, 138,12176,1211217
354liI 8 : 235, 136, 141,2{119, 154, 169, l!1IQI
3 5 4 1 ·4 : 121 !11 121, 1 4 2, 1 9 9, 1 5 4, 1 5 3, 1 4 4, 1 1 iii
3542iil: 153.12132, 1!112, 138.173,2QI9, 131
35426: 154,1::176,238, 136, 169,12liil 12l , lQI3
35432: 141, 192, 154, 141, 193, 154,1::155
35438: 17121 ,i2114 , 192. 154,11146, 193, 111
35444: 154. ii I 14.192 : 154,i2146.193, 1!111
3545121: 154, !2114, 192, 154,12146,193, liZI7
35456: 154,12114, 192, 154,iiI46, 193, 113
35462: 154, 189, 2!115, 153, 2 iii 1 ,!2165, 12177
35468: 144,002,233,007,041,015,070
35474: 121 13,192,154,141,192,154,224
3548111: 232, 236, 199, 154,21218, 2ii19 , 11 i21
35486: 238,198,154,169, ii1l211, 12196, 246
35492: 192 , !2IlZ!!1I, 241::1, ii114, 174 , 2i118, 224
35 4 98: 154, 2Q18, iii iii 9 ,liI72, 152. i1172, ~:169
3 5 5 iii 4 : 1213 2 , ~:I 6 6, 1 3 3, 1 iii 4, 1 6 8, 1 1214 , 121 1 5
3551iil : 153, 144, 153, 2ii1!21, 12132,11185, 181
3 5 5 1 6: 1 4 5, 1 5 3, 1 4 4, 1 5 3 , 2 121 111 , 2 !21 1 , 1 6111
3 5 5 2 2 : 111 6 6 . 2 i21 8. 1 iii 4, 1 6 9 , 121ii1i21, 1 4 1 , 1 1 4
35528:214,154, 173,2iiI8, 154,24121,12163
35534:12123, 14 i:I,211, 154, 173,226, 11219
3554lil: 154, 24i1l, 11115, 12132, 13!11, 141,156
35546: 11132, QI51 , 141 . 11132, iil91 , 141, 194
35552:iiI 32,1Z151, 141, 172,211, 154,217
3 5558: 11132,12185,145,153,144,153,174
385
Appendix B: LADS Object Code
386
Appendix B: LADS Object Code
387
Appendix B: LADS Object Code
388
Appendix B: LADS Object Code
36446:008,145,096,072 , 041,015 , 21 5
36452: 168, 185 , 128, 153 , 17 111.1!214,24 121
36458:11174,11174,11174,11174,168,185,243
36464: 128, 153,12132,12136,145,138,232
36 470:032,036,145 ,0 96,201,070,186
36476:208,008,032,221,142,104,071
36482: 11114,11176,146,128,21211,12169 ,12186
36488:208,006,032,039,143,076,128
36494: 129 , 142, 2i211 ,12168, 21118, I1H:13, 125
365111111: 11176, 1 !~2, 14 3, 2!211, !218 121, 21218, 19 \<1
3651Z16: IZ11Z13, IZ176, 171,14 3, 2lZll, 12178, lZI58
36512:208.003, 076,23 6,14 3,20 1 ,003
36518:079,208, 003 ,076,215 , 143,122
36524: 201, lZ183, 2l218 , 1211Z13, IZI76 , 165, 14121
3653121: 144, 21211, lZ17 2, 21Z18 , IZIlZI3, 12176,114
36536: 191,144,153,144,153 , IZ132, 233
36542: 13121, 141 ,12132,12151, 141, 11132 ,20 5
365 48: QI91 , 141, 12132, 155 , 141,12132, 1212i21
36554: 143 , 141,169,157 , 133 , 134 ,11155
3656lZl: 169, 154 , 1 33, 1 3 5 , lZ132 , lZ134, 12197
3 6566: 141,lZI32,121,141, lZI76 , 19 121 ,147
36572:143,032,085,145,201,032,090
36 578: 24~L !!H213, lZ176, 221,142,16111 ,11144
36584:000 , 032 ,0 85 , 145 ,201,000, 183
36590:24!!I,1211Z17, 15 3, 144 , 153,2!21121, 111
36596:12176,233,142,132,128,16121 ,12191
36602:000 , 185.144,153,240,008,212
366lZ18: 153,226 , 153, 2121l21, 196, 128, 12132
36614:2QI 8,243,173,2lZI8, 154,21Z18, 176
3662~:1: lZ11Z16, 12132,12191 , 141 , Q132, IZI51 , 109
36626: 141,!!132, 143, 141 ,QI 32, 121, 116
36632: 141,11132 , IZ113 , 135, 162, QIQI1, 252
3 6638:032,008 ,1 45 ,162,000, 142,007
3 6644: 189, 154 , Q196 , 169, IZ146 , Q132, 21QI
36650:036,145,169,069,032,036,017
36656: 145. 169, 11178,1Z13 2,!2136, 145, 141
36662: 169, ~:168. IZI32 , 12136,145,169,161
3 6668:032,032,036 , 145,032,221,046
36674: 142, 173 ,21218, 154, 2 4 !2I, lil~)3, 2 18
3668121 :238,189, 154 ,238,21Z18, 154, 229
36686: 165, 136 , 141 ,23121,154,165, !!145
36692: 1 3 7 , 1 4 1 , 23 1 , 1 54, 1 73, 1 85 , iii 8 1
3 6698: 154, 133 , 136, 17 3, 186, 154,121!212
3671214: 133, 137,i2132, 19QI, 136 , 12196 ,1215 2
3671121: 173, 2('18,154, 24QI, i2123, 032,164
36716:lZ185, 145, 15 3, 144 , 15 3, 16111 , 18121
36722: !!llZl!!l, !!132,!2185, 145 ,24121,12113 , 117
3 6 7 2 8: 1 5 3 ~ 14 4 ~ 15 3 ~ 153 ~ 2 2 6!, 1 53!, ~i 7 8
36734:2!21!!I ,lZI76 , 115 , 14 3,12176, 19 !21 , 1 58
389
Appendix B: LADS Object Code
390
Appendix B: LADS Object Code
391
Appendix B: LADS Object Code
392
Appendix B: LADS Object Code
393
Appendix B: LADS Object Code
394
Appendix B: LADS Object Code
3821 iZl : i213 2. 128, 149. 2 !21Iii, 208. !21 !212 , !21 1 7
38216:230,204,076,245,148,206,157
38222:12155, 146,iiI32, 128, 149,!2124, 112H21
38228: 152, 1!2S1, 21213,141, iii 5:: , 146, 112
38234: 169, 121!il!2l, 11!S1, 2~~14, 141, !2154, 247
38240: 146,238,12155, 146, !2156, 173, 142
38246:(153, 146,237,iiI51, 146, 141, 1 iii 8
38252:iiI56, 146, 173,!2154, 146,237, 152
38258 : i!15 2, 1 46, 1 4 1 , iii 5 7 , 1 46 , 238, 1 26
38264:056,146,208,003,238,057,060
3827121: 146,(196, 172,12150, 146, 177, 145
38276:203,201,155,240,008,200,115
38282:208,247,230,204,076,131,210
38288:149,096,133,203,132,204,037
38294:160.000,177,203,240,006,168
38300:032,036,145,200,208,246,255
383iiI6:12196, 173,iiI53, 146,12124, lii15,247
38312: (ili2I1, 141,12135,146,173,12154, 2!!16
383 18: 1 46, 1 QI5 , 121 QI!2I, 14 1 , !2i 36, 1 46, 236
38324: 173,12151, 146, 141,!2137, 146, 11216
3833!!1: 173,12152,146,141, !!138, 146, 114
38336:iiI56, 173,iiI47, 146,237,iiI 53, 136
38342: 146, 141 , 12139, 146, 173,12148, 123
38348: 146,237,12154, 146, 176,12114,21219
38354:173,047,146,240,003,206,001
3836!!I:iiI48, 146,2!216,!2147, 146,iiI 76, 117
38366: 235,149,141, iil4iil, 146,12113,178
38372:039,146,240,022,032,067,006
38378: 146,12156, 173,12147, 146,237, iil15
38384:iiI56, 146, 141,12147, 146, 173, 181
38390:!!:148, 146,237,!2157, 146, 141,253
38396:iiI48, 146,iiI96, 173,12151, 146, 144
38402:133,203,141,035,146,056,204
3841218: 1 iii 9 , iii 4 2, 1 46, 1 4 1 , iii 3 7 , 1 46, 1 1 7
38414: 173, !2152, 146, 133,21214,141,12195
38420:036,146,105,000,141,038,230
38426:146,056,173,047,146,237,063
38432:12151,146, 141,iiI39, 146, 173,216
38438:12148, 146,237,!2152, 146, 141,ii14iil
38444:1214121,146, 176,!2114, 173,12147, 128
38450:146,208,003,206,048,146,039
38456:206,047,146,076,070,150,239
38462:013,039,146,240,003,032,023
38468: 134, 146,12156, 173,12147, 146,iil !212
38474: liiI9,i2142, 146, 141,047, 146, 193
38480: 173,iiI48, 146, 11215,121121121, 141, 181
38486: 12148, 146, 16iil, iZli2I!2I, 185, i2l!2H21, 113
38492:005.145.203,200,204,042,123
38498: 146, 144,245, 24~:1, 243, !!196, 188
395
Appendix B: LADS Object Code
396
Appendix B: LADS Object Code
~_ _
".c.
... R 7. 98'. 1 4 6, 1 4 ...'v," , (i.', 6 _
'/ , 1 4 6, 1 33, 1 28, 1 29
38804:169,007,133,131,032,025,133
3881121: 145, 169,~:H2I!2I, 133, 132,~:132,253
38816:218, 144, 166,~1H111,QI48, 01211, 226
38822: (2196, 11114. Il214, (2132, 1 15. 15121,255
38828:076,087,147,169,008,133,024
38834: 133.\2132. 1 1114. 151,166,131 ,127
3884i21: \2132. '2111, 145. ~:132, 246.15121.12132
38846:032,104,150,0 76,087,147,018
3 8 8 5 2: 1 6 9 , !2H~1 4, 1 3 3, 1 3 3 , (21 3 2, 1121 4 , QI QI 3
38858: 1 5 1 , 1 66, 1 3 1 , (2132 , Qllil 8, 1 4 5 , 12167
38864:~:!76,"!94, 147,173,(2162, 146, 138
38870:205,042,146,208,002,230,023
38876: 162,12176 , (2H213, 128, 173, Q!62, 1215 6
3 8 8 8 2: 1 4 6 , QI 3 2. 1 9 1 , 1 5!2!, 1 6 5 , 2 1 2 , 1219 8
38888: 141,241, 151 , 165,213, 141, !21!2!4
38894: 242~ 151 ~ y-J32 , 255~ 255~ ~~J76~ 225
389!2I !2I :12!87.147,i2132,252,151,!2!76,221
389i~16:!2187, 147, 169,i2HZ!4, 133, 133, 155
38912:!2!32, lQ!4, 151, 165, 131,!2!32, 1!~!3
38918: 212, 144, 169, 121 !2! ![l , 157, Q!68, 244
38924: "H1!3, 169. !2!32, 157,12169, !2HZ I 3, 189
3893ii'1: 169, ii'HZHZI, 157, i2172,liIQI3, 169, i2!76
38936:080,157,073,003,169,007,001
38942:157,066.003,032,002,145,179
38948: 165, 131 ,1Z!32,212, 144,!2!24,232
38954: 189, li172, QIQ!3, 1 i215, Qli2I!2!, 141, Q!4i2!
3896Q!: 1Z!4 7, 146, 189 ,12173,01213, Il~15, i2!99
38966: ii'132 , 141,12148, 146, 165, !2H211 ,i2!75
38972: 21211 , 136,24 121, !2!~:16, 12132, 115, i2!22
38978: 15!~!,12176,!2!87, 147,i2!32, 104, 15!2!
38984: 15i~l, li!96 , 12188, 169, 181, 16!21 , 148
3899ii'1: 15i21, "132,146,149,11214, li2!4, 251
38996: li~14, i2!56, 233, i2!i212, 17i~l, 1(2!4, 241
39002:233,000,032,207,145,162,101
39i2!!2!8:255, 154,i2!32, 121 , 141,Q!76, li2!7
39014:203,146,076,068,065,076,224
39020:068,089,074,083,082,082,074
39i2!26: Q!84, ii'183, ~:!-66, 12!6 7,12183, 12!66, kil51
39032:069,081.066,067,067,067,025
39038:077,080,066,078,069,076,060
39044:068,088,074,077,080,083,090
39050:084,065,083,084,089,083,114
39056:084,088,073,078,089,068,112
39062:069,089,068,069,088,068,089
39068:069,067,073,078,088,073,092
39074:078,067,067,080,089,067,098
39080:080,088,083,066,067,083,123
39086:069,067,065,068,067,067,065
397
Appendix B: LADS Object Code
39092:076,067,084,065,088,084,132
39098:065,089,084,088,065,084,149
39104:089,065,080,072,065,080,131
39110:076,065,066,082,075,066,116
39116:077,073,066,080,076,065,129
39122:078,068,079,082,065,069,139
39128:079,082,066,073,084,066,154
39134:086,067,066,086,083,082,180
39140:079,076,082,079,082,076 ,1 90
39146:083,082,067,076,068,067,165
39152:076,073,065,083,076,080,181
39158:072,080,080 ,076,0 80,082,204
39164:084,073,083,069,068,083,200
39170:069,073,084,083,088,084,227
39176:088,083,067,076,086 , 078,230
39182:079,080,001,005,009,000,188
39188:008,008,008,001,008,005,058
39194:006,001 ,002 ,002,000,000,037
39200:000,002,000,002,004,004,044
39206:001,000,001,000,000,000,040
39212:000,000,000,000,000, 008,0 52
39218:008,001,001,001,007,008,076
39224:008.003,003,003,000 ,000,073
39230:003.000,000,000,000 ,00 0 ,065
39236:000,000,000,000,161,160,133
39242:!2132,!2196, 176,24fl , 144, 193, 187
39248:208, 162,!2176 , 129, 132, 134, 153
39254:200,136,202,198,232 , 230,004
39260:192,224,225,056,09 7,024.1 42
39266: 17fl, 168, 138, 152 , f I 72, If14, 134
39272:000,048,016,033,001,065 ,0 11
39278:036,080,112,034,098,066,024
39284:216,088,002,008,040,064,022
3929!Z!: 248. 12!2!, 186. 154. 184,234 . 224
39296:048,049,050,051,052 ,0 53,175
39302:054,055,056,057.065,066,231
39308:067,068,069,070,000 ,0 00 ,1 58
39314:000,000,000,000,000 ,000,1 46
39320:000,000,000,000,000,000,152
39326:000,000,000.000,000 ,000.1 58
39332:000,000,000,000,000 ,000, 164
39338:000,000,000,000,000,000 ,170
39344:000.000,000,000.000,000,176
39350:000.000,000.000.000,000 , 182
39356:000,000 , 000,000,000,000,188
39362:000,000,000,000 ,000,000, 194
39368:000,000.000 ,000,0 00,000,200
39374:000,000 ,00 0,000 ,000,000,2 06
39380:000,000,000,000,000 ,000,2 12
398
Appendix B: LADS Object Code
39386:000,000,000,000,000,000,218
39392:000,000.000,000,000,000,224
39398:000,000,000,000,000,000,230
39404:000,000,000,000,000,000,236
394 1 0:000,000,000,000.000,000,242
39416:000,000,000,000,000,000,248
39422 : 000,000,000,206,239.160,091
39428:211,244,225,242,244,160,050
39434: 193 ,228,228,242,229,243,093
39440:243,000,045,045,045 ,0 45,183
39446:045,045,045,045,045,045,036
39452:045,045,045,045,045,032,029
39458 : 194~242~225~ 238~227 .. 232 ~ 112
39 464:160.2 07,245.244.160,239,015
39470:230,160,210, 22 5,2 38 ,231,060
39476 : 229.000,213,238,228,229,16 5
39482 :2 30,233,238,229,228,160,096
39488:204,225,226,229 , 236.000,160
39 494: 031,031,031,031,031,031,000
39500:031,031,031,032,206,225,120
395Q!6: 235.229,228, 16Q!, 236,225, 115
3 951 2:226,229,236,000,031,031,073
3 9518: !!!31, ~~!31, Q! 31, ~!32, 188, 188, ~!83
39524: 188,188, 188,188 , 188, 188,2!!!4
3953~!: 16l21 , 196 , 2l2!1, 211. 2!Z!3, 16~~!, 213
39536: 197 , 21 QI, 21 ii!, 2!!17 ,21 l21, 16Q!, l2!26
3 9 5 4 2: 1 9 Q!, 1 9 ~~! , 1 9 Q!, 1 9 l2!, 1 9!2!, 1 9 Q! , 2 3 4
39548:190.190,000,031,031.031,085
39554 : Q! 3 1 , iZI3 1 , 1 6 iZl, 1 73, 1 73, 1 6 '~l , ~! 9 Q!
39560:196,245,240,236,233,227,233
39566:225,244,229,160,160,204,084
39572: 225~ 226 :. 229 .. 236~ 16Q~~ 173, 117
39578 : 173, 16 !!!, iZi!!Ii!!, !!!3 1 ,!!131 , i2131 , QI68
39584:i!!3 1 .!!!31, 16 Q!. 173,173, 16l2!,12~!
39590:211,249 ,238.2 44.225.248,045
3 9596:160 , 197,242 ,242,239, 242,214
396!2!2: 16!Z!, 173 , 173 , 16!2!,!2Ii!! l2!,Ql!!!~~!,l2176
399
Appendix B: LADS Object Code
7A48- 20 OE 84 AD E7 8F DO 3F
7A50- 20 50 89 A9 E6 20 06 81
7A58- A9 4C 20 06 81 A9 41 20
7A60- 06 81 A9 44 20 06 81 A9
7A68- 53 20 06 81 20 50 89 AD
7A70- DO 8F DO OB A9 F1 85 FB
7A78- A9 80 85 FC 20 81 83 AD
7A80- 07 8F 85 FD 80 DO 8F AD
7A88- 08 8F 85 FE 80 01 8F 20
7A90- 2F 82 AD 04 8F FO 03 4C
7A98- A1 70 20 OE 84 A9 00 80
7AAO- DC 8F 80 E6 8F AC E7 8F
7AA8- DO 03 4C C9 7A 8C FB 8F
7ABO- AD F9 8F FO OC 20 59 89
7AB8- 20 OA 89 20 32 89 20 OA
7ACO- 89 AD F2 8F FO 03 20 06
7AC8- 88 4C OA 83 AD CF 8F FO
7ADO- 17 C9 03 DO 72 A9 01 80
7AD8- CF 8F AD F4 80 DO 68 A9
7AEO- 08 18 60 CE 8F 80 CE 8F
7AE8- 4C B2 7C AD E7 8F FO 39
7AFO- AO FF C8 B9 F1 80 FO 2E
7AF8- 99 F3 8E C9 20 DO F3 C8
7BOO- B9 F1 80 C9 3D DO 03 4C
7808- E2 7C A2 00 8E FB 8F 8A
7B10- 99 F3 8E B9 F1 8D FO 08
7B18- 9D F1 80 E8 C8 4C 13 7B
7B20- 90 F1 80 4C C9 7A 20 78
7B28- 7F 20 1A 7F 4C C9 7A AD
7B30- 38 8E C9 40 BO 06 AD 39
7B38- 8E EE E6 8F 49 80 80 05
7B40- 8F 20 BC 7F 4C BE 7B AO
7B48- 00 8C DC 8F B9 F5 80 C9
7B50- 41 90 03 EE DC 8F 99 38
7B58- 8E C8 B9 F5 80 FO 16 99
7B60- 38 8E C9 41 90 03 EE DC
7B68- 8F C8 B9 F5 80 Fn 06 99
7B70- 38 8E 4C 69 7B 88 8C DB
7B78- 8F AD DO 8F DO 40 AD DC
7B80- 8F DO AC A9 38 85 FB A9
7888- 8E 85 FC AO 00 AD 38 8E
7B90- C9 30 BO 07 18 E6 FB 90
7B98- 02 E6 FC B1 FB FO 10 C9
7BAO- 29 FO OC C9 2C FO 08 C9
7BA8- 20 FO 04 C8 4C 9B 7B 48
7BBO- 98 48 A9 00 91 FB 20 81
7BB8- 83 68 A8 68 91 FB AD 38
7BCO- 8E C9 23 FO 3F C9 28 FO
7BC8- 17 AD CF 8F C9 08 FO 37
400
Appendix B: LADS Object Code
7BDO- C9 03 DO 71 A9 OS IS 6D
7BOS- CE SF SD CE SF 4C B2 7C
7BEO- AC DB SF B9 3S SE C9 29
7BES- F0 10 AD CF 9F C9 01 D0
7BFO- 09 A9 10 IS 60 CE SF SO
7BFS- CE SF AD CF SF C9 06 FO
7COO- 53 4C 77 7C 4C 92 7C AD
7COS- E7 SF DO 03 4C 77 7C 3S
7CI0- AD 07 SF E5 FO 4S AD OS
7C1S- SF E5 FE BO OE C9 FF FO
7C20- 04 6S 4C 00 7F 6S 10 OC
7C2S- 4C 37 7C FO 04 6S 4C 00
7C30- 7F 6S 10 03 4C 00 7F 3S
7C3S- E9 02 SO 07 SF A9 00 SO
7C40- OS SF 4C 77 7C AC DB SF
7C4S- SS B9 3S SE C9 2C DO 04
7C50- CS 4C FC 70 AD CE SF C9
7C5S- 4C DO 03 4C SO 7C AD OS
7C60- SF DO 55 AD CF SF C9 06
7C6S- BO 00 C9 02 FO 09 A9 04
7C70- IS 60 CE SF SO CE SF 20
7C7S- 40 SS 20 73 SS 4C E2 7C
7CSO- AC DB SF B9 3S SE C9 29
7CSS- DO 05 A9 6C SO CE SF 4C
7C90- DC 7C AD 39 SE C9 22 DO
7C9S- 06 AD 3A SE SO 07 SF AD
7CAO- CF SF C9 01 DO 01 A9 OS
7CAS- IS 60 CE SF SO CE SF 4C
7CBO- 77 7C 20 40 SS 4C E2 7C
7CBS- AD CF SF C9 02 FO 04 C9
7CCO- 07 DO OC AD CE SF IS 69
7CCS- OS SO CE SF 4C DC 7C C9
7COO- 06 BO 09 AD CE SF IS 69
7COS- OC SO CE SF 20 40 SS 20
7CEO- SO SS AD E7 SF DO 03 4C
7CES- 9E 70 AD F9 SF DO 03 4C
7CFO- 9E 70 AD FB SF DO 3E AD
7CFS- F5 SF FO 2A A9 14 3S E5
7000- 24 SO ES SF 20 lC S2 A2
700S- 04 20 A6 SI AC ES SF 10
7010- 05 AO 02 4C IS 70 A9 20
7018- 20 06 81 S8 00 FA 20 lC
7020- 82 A2 01 20 A2 SI A9 14
702S- S5 24 A9 F3 85 FB A9 8E
7030- 85 FC 20 F9 88 A9 IE 3S
703S- E5 24 80 E9 SF A9 IE 85
7040- 24 AD F5 8F FO IF 20 lC
7048- 82 A2 04 20 A6 SI AC E9
7050- 8F FO OA 30 08 A9 20 20
401
Appendix B : LADS Object Code
7058- 06 81 88 00 FA 20 lC 82
7060- A2 01 20 A2 81 20 66 89
7068- AO F3 8F FO 11 C9 01 00
7070- 05 A9 3C 4C 78 70 A9 3E
7078- 20 06 81 20 8B 89 AO FC
7080- 8F FO 13 20 OA 89 A9 3B
7088- 20 06 81 A9 00 85 FB A9
7090- 02 85 FC 20 F9 88 20 50
7098- 89 AO 04 8F 00 03 4C 8F
70AO- 7A AO E7 8F 00 2C EE E7
70A8- 8F 38 A5 FO EO 00 8F 80
70BO- FO 8F A5 FE EO 01 8F 80
70B8- FE 8F AO 00 8F 85 FD AO
7DCO- 01 8F 85 FE 20 lC 82 A9
70C8- 01 20 35 82 20 E5 80 4C
7000- 40 7A 20 IC 82 A9 01 20
7008- 35 82 A9 02 20 35 82 AO
70EO- F5 8F FO 15 20 IC 82 A2
70E8- 04 20 A6 81 A9 00 20 06
7DFO- 81 20 lC 82 A9 04 20 35
7DF8- 82 4C DO 03 B9 38 BE C9
7EOO- 58 FO 62 88 88 B9 3S 8E
7E08- C9 29 DO 03 4C EO 7B AD
7EI0- 08 8F DO OF AD CF SF C9
7E18- 02 FO 4F C9 05 FO 4B C9
7E20- 01 FO 77 AD CF 8F C9 01
7E28- DO OC AD CE 8F 18 69 18
7E30- 80 CE 8F 4C DC 7C AD CF
7E38- 8F C9 05 FO 08 A9 31 20
7E40- DO 7E 4C 51 7E AD CE 8F
7E48- 18 69 lC SO CE SF 4C DC
7E50- 7C 20 72 89 20 59 89 A9
7E58- B4 85 FB A9 8F 85 FC 20
7E60- F9 88 4C E2 7C AD 08 8F
7E68- DO 33 AD CF 8F C9 02 DO
7E70- OC A9 10 18 60 CE 8F 80
7E78- CE BF 4C 77 7C C9 01 FO
7E80- 10 C9 03 FO OC C9 05 FO
7E88- 08 A9 32 20 DO 7E 4C 51
7E90- 7E A9 14 18 6D CE 8F 80
7E98- CE 8F 4C 77 7C AD CF 8F
7EAO- C9 02 DO OC A9 18 18 6D
7EA8- CE 8F SO CE 8F 4C DC 7C
7EBO- C9 01 FO 10 C9 03 FO OC
7EB8- C9 05 FO 08 A9 33 20 DO
7ECO- 7E 4C 51 7E A9 lC 18 60
7EC8- CE 8F 80 CE 8F 4C OC 7C
7EOO- 80 E8 8F 8C EA 8F 8E E9
7ED8- 8F A9 8A 20 06 81 68 AA
402
Appendix B: LADS Object Code
7EEO- 68 A8 98 48 8A 48 98 20
7EE8- 24 ED AD E8 8F AC EA 8F
7EFO- AE E9 8F 60 AO 00 98 99
7EF8- FI 8D C8 CO FF DO F8 60
7FOO- 20 50 89 20 72 89 20 59
7F08- 89 A9 23 85 FB A9 8F 85
7FIO- Fe 20 F9 88 20 50 89 4C
7F18- 77 7C AO FF C8 B9 Fl 8D
7F20- FO 56 C9 20 DO F6 C8 C8
7F28- 8C EI 8F 38 A5 EB ED El
7F30- 8F 85 EB A5 EC E9 00 85
7F38- EC AO 00 B9 FI 8D 49 80
7F40- 91 EB C8 B9 Fl 8D C9 20
7F48- FO 05 91 EB 4C 42 7F C8
7F50- B9 Fl 8D C9 3D FO 32 88
7F58- A5 FD 91 EB C8 A5 FE 91
7F60- EB AE EI 8F CA AO 00 BD
7F68- Fl 8D FO 08 99 Fl 8D E8
7F70- C8 4C 67 7F 99 Fl 8D 60
7F78- 20 72 89 A9 5C 85 FB A9
7F80- 8F 85 FC 20 F9 88 4C B7
7F88- 7F 88 8C E2 8F AD DD 8F
7F90- DO 17 C8 C8 C8 8C D6 8F
7F98- A9 Fl 18 6D D6 8F 85 FB
7FAO- A9 8D 69 00 85 FC 20 81
7FA8- 83 AC E2 8F AD D7 8F 91
7FBO- EB AD D8 8F C8 91 EB 68
7FB8- 68 4C E2 7C AD E4 8F 85
7FCO- ED AD E5 8F 85 EE 20 CA
7FC8- 80 A9 FF 8D F8 8F 38 A5
7FDO- EB E5 ED A5 EC E5 EE BO
7FD8- 63 A2 00 38 A5 ED E9 02
7FEO- 85 ED A5 EE E9 00 85 EE
7FE8- AO 00 Bl ED 30 OC A5 ED
7FFO- DO 02 C6 EE C6 ED E8 4C
7FF8- EA 7F A5 ED 8D EB 8F A5
8000- EE 8D EC 8F Bl ED CD D5
8008- 8F FO 03 4C 2C 80 E8 BE
8010- D6 8F A2 01 AD E6 8F FO
8018- 04 C8 20 CA 80 C8 B9 38
8020- 8E FO 53 C9 30 90 4F E8
8028- Dl ED FO Fl AD EB 8F 85
8030- ED AD EC 8F 85 EE 20 CA
8038- 80 4C CE 7F AD F8 8F 30
8040- 01 60 AD E7 8F DO 02 FO
8048- 17 20 72 89 20 59 89 20
8050- OA 89 A9 4C 85 FB A9 8F
8058- 85 FC 20 F9 88 20 50 89
8060- 68 68 AD CE 8F 29 IF C9
403
Appendix B: LADS Object Code
8068- 10 FO 08 AD F3 8F DO 03
8070- 4C DC 7C 4C 77 7C EC D6
8078- 8F FO 03 4C 2C 80 EE F8
8080- 8F FO 03 20 03 80 AC D6
8088- 8F AD E6 8F FO 01 C8 Bl
8090- ED 80 07 8F C8 Bl ED 80
8098- 08 8F AD F3 8F FO OA C9
80AO- 02 DO IE AD 08 8F 80 07
8QA8- 8F AD F2 8F FO 13 18 AD
80BO- FO 8F 60 07 8F 80 07 8F
80B8- AD Fl 8F 60 08 8F 80 D8
80CO- 8F AD E7 8F FO 01 60 4C
80C8- 2C 80 A5 ED DO 02 C6 EE
8000- C6 ED 60 20 72 89 A9 96
80D8- 85 FB A9 8F 85 FC 20 F9
80EO- 88 20 50 89 60 20 lC 82
80E8- A9 01 20 35 82 A9 01 85
80FO- 2C A9 90 85 20 20 5F 81
80F8- EE FF 8F 60 A9 13 85 2C
8100~ A9 90 85 20 20 5F 81 EE
8108- 00 90 60 60 A9 25 85 2C
8110- A9 90 85 20 20 8A 81 20
8118- DC 03 85 2B 84 2A AO 08
8120- Bl 2A 60 80 3F 90 A9 37
8128- 85 2C A9 90 85 20 20 8A
8130- 81 60 AD FF 8F FO 27 A9
8138- 49 85 2C A9 90 85 20 20
8140- 8A 81 A9 00 80 FF 8F 60
8148- AD 00 90 FO 11 A9 5B 85
8150- 2C A9 90 85 20 20 8A 81
8158- A9 00 80 00 90 60 60 AO
8160- 08 Bl 2C 85 2A C8 Bl 2C
8168- 85 2B A9 F3 85 FB A9 8E
8170- 85 FC AO 00 A9 AO 91 2A
8178- C8 CO IF 00 F9 AO 00 81
8180- FB 09 80 91 2A C8 C4 F9
8188- DO F5 20 DC 03 85 28 84
8190- 2A AO 00 Bl 2C 91 2A C8
8198- CO 12 00 F7 A2 00 20 06
81AO- 03 60 8E 60 90 60 8A 80
81A8- 6E 90 EO 04 00 OA A9 EC
81BO- 80 53 AA A9 81 80 54 AA
81B8- 60 8C 70 90 8E E9 8F AD
81CO- 60 90 C9 01 DO OC 20 OC
81C8- 81 08 AC 70 90 AE E9 SF
8100- 28 60 AC 70 90 60 8C 70
8108- 90 80 6F 90 AD 6E 90 C9
81EO- 02 DO IE AD 6F 90 20 23
81E8- 81 4C 02 81 80 6F 90 C9
404
Appendix B: LADS Object Code
81FO- 80 DO 02 A9 OA 80 90 CO
81F8- AD Cl Cl 30 F8 AD 6F 90
8200- 60 AD 6E 90 C9 04 DO 09
8208- AD 6F 90 20 EC 81 4C 02
8210- 81 AD 6F 90 09 80 20 FO
8218- FD 4C 02 81 A9 00 80 6E
8220- 90 80 60 90 A9 FO 80 53
8228- AA A9 FO 80 54 AA 60 AD
8230- 00 CO C9 83 60 C9 01 DO
8238- 03 4C 32 81 C9 02 DO 03
8240- 4C 48 81 4C 5E 81 80 6F
8248- 90 A9 00 C5 88 DO 18 A9
8250- 02 C5 89 DO 15 AO 00 81
8258- B8 C9 20 DO 05 E6 B8 4C
8260- 57 82 C9 2F 90 04 C9 3A
8268- 90 53 AD 00 02 C9 41 DO
8270- 37 AD 01 02 C9 53 DO 30
8278- AD 02 02 C9 40 DO 29 AD
8280- 03 02 C9 20 DO 22 AO 00
8288- 89 04 02 C9 00 FO 09 09
8290- 80 99 00 04 C8 4C 88 82
8298- A9 AO 99 00 04 99 01 04
82AO- 99 02 04 68 68 4C 00 7A
82A8- AD 6F 90 C9 3A BO 00 C9
82BO- 20 DO 03 4C Bl 00 38 E9
82B8- 30 38 E9 DO 60 A6 AF 86
82CO- 69 A6 80 86 6A 18 20 OC
82C8- OA 20 01 82 68 68 4C 6A
8200- 04 AO 00 84 94 A9 02 85
8208- 95 81 88 91 94 C8 C9 00
82EO- DO F7 88 88 81 94 C9 20
82E8- FO F9 C8 A9 00 91 94 C8
82FO- C8 C8 C8 C8 60 A9 46 85
82F8- BB A9 82 85 8C A9 4C 85
8300- 8A A9 FC 85 73 A9 79 85
8308- 74 60 AO 00 A2 FF E8 89
8310- C9 8C CO Fl 80 FO OA C8
8 318- C8 C8 EO 39 DO FO 4C EB
8320- 7A C8 89 C9 8C CD F2 8D
8328- FO 06 C8 C8 DO EO FO EE
8330- C8 B9 C9 8C CD F3 8D FO
8338- 05 C8 DO D2 FO EO AD F4
8340- 80 C9 20 FO 04 C9 00 DO
8348- 05 BO 71 80 80 CF 8F BC
8350- A9 80 8C CE 8F 4C CC 7A
8358- A2 01 20 A2 81 A2 06 8E
8360- E9 8F 20 B9 81 AE E9 8F
8368- CA DO F4 20 B9 81 C9 2A
8370- FO OE A9 12 85 FB A9 8F
405
Appendix B: LADS Object Code
8378- 85 FC 20 F9 88 4C 02 70
8380- 60 AO 00 Bl FB FO 04 C8
8388- 4C 83 83 8C OF 8F 88 A9
8390- 00 80 07 8F 80 08 8F A2
8398- 01 8E E9 8F Bl FB 29 OF
83AO- 80 00 8F 80 10 8F A9 00
83A8- 80 OE 8F 80 11 8F CA FO
83BO- 12 20 03 83 AD 00 8F 80
83B8- 10 BF AD OE 8F 80 11 BF
83CO- 4C AE B3 EE E9 BF AE E9
83C8- 8F 20 FA 83 88 CE OF 8F
8300- DO CA 60 18 OE 00 8F 2E
8308- OE 8F OE 00 8F 2E OE BF
B3EO- 18 AD 10 BF 60 00 BF BD
83E8- 00 8F AD 11 BF 60 OE 8F
83FO- BO OE BF OE 00 8F 2E OE
83FB- 8F 60 18 AD 00 8F 60 07
8400- BF BD 07 BF AD OE 8F 60
B408- 08 BF BO 08 8F 60 20 F4
B410- 7E AO 00 8C DO 8F 8C FC
B418- 8F BC F3 8F BC F2 BF AD
8420- F7 8F DO OC 20 B9 81 80
842B- 02 8F 20 89 81 80 D3 8F
8430- 20 B9 81 C9 20 DO 08 20
8438- B2 85 6B 6B 4C 8F 7A C9
B440- 20 4C 4C B4 20 B9 81 DO
B448- 03 4C B2 85 C9 3A DO 03
B450- 4C F6 B4 C9 3B DO 73 BC
8458- E8 8F AD F5 8F FO 55 80
B460- Fe BF AD EB BF FO 06 20
8468- 94 84 4C BC 84 20 B9 81
8470- FO OE C9 7F 90 03 20 04
847B- 85 99 Fl BD C8 4C 60 84
8480- 20 59 89 20 OA 89 20 66
B488- 89 20 50 89 A9 00 80 EB
8490- 8F 4C BC 84 80 FC 8F 80
8498- E8 8F AO 00 20 B9 81 DO
84AO- 07 99 00 02 AC E8 8F 60
84AB- 10 03 20 El 87 99 00 02
84BO- C8 4C 9C 84 20 B9 81 FO
8488- 03 4C B4 84 20 82 85 AD
84CO- E8 8F DO 05 68 68 4C 8F
84C8- 7A 60 C9 3E FO 58 C9 3C
8400- FO 5F C9 28 DO 03 EE F2
84D8- 8F C9 2A DO 03 4C 39 85
84EO- C9 2E FO 16 C9 24 FO 15
84E8- C9 7F 90 03 20 04 85 99
84FO- Fl 8D C8 4C 44 84 80 F7
84F8- 8F 60 4C 56 86 99 Fl 8D
406
Appendix B: LADS Object Code
8500- C8 4C 01 85 38 E9 7F 80
8508- EO 8F A2 FF CE EO 8F FO
8510- 08 E8 BO DO DO 10 FA 30
8518- F3 E8 BO DO DO 30 07 99
8520- Fl 80 C8 4C 19 85 29 7F
8528- 60 A9 02 80 F3 8F 4C 44
853 0- 84 A9 01 80 F3 8F 4C 44
8538- 84 AD F3 8F FO 20 A9 2A
8540 - 99 Fl 80 C8 EE DO 8F AD
8548- F3 8F C9 01 FO 08 A5 FE
8550- 80 07 8F 4C 44 84 A5 FO
8558- 80 07 8F 4C 44 84 20 44
8560- 84 AD E7 8F FO OB A9 2A
8568- 20 D6 81 20 66 89 20 50
8570 - 89 AD DO 8F DO 20 AO 00
85 7 8- 89 Fl 80 C9 20 FO 04 C8
8580- 4C 78 85 C8 84 F8 A9 Fl
8588- 18 65 F8 85 FB A9 80 69
8590- 00 85 FC 20 81 83 AD E7
859 8- 8F FO 08 AD F4 8F FO 03
85AO- 20 AO 87 AD 07 8F 85 FO
85A8- AD 08 8F 85 FE 68 68 4C
85BO- 8F 7A 99 Fl 80 C8 CO FF
8 5 88- DO F8 99 Fl 80 20 B9 81
85CO- 20 B9 81 FO 06 A9 00 80
85 C8- F7 8F 60 A9 01 80 04 8F
8500- 6n A2 00 20 89 81 FO 2C
8508- C9 3A Fn 28 C9 20 FO F3
85EO- C9 38 FO 20 C9 2C FO OF
85E8- C9 29 FO OB 90 DE 8E E8
85FO- 99 Fl 80 C8 4C 03 85 8E
85F8- DE 8F 99 Fl 80 C8 20 18
8600- 86 4C 44 84 80 E8 8F A9
8608- 00 8E DE 8F 99 Fl 80 20
8610 - 18 86 AD E8 8F 4C 47 84
8618- A9 00 80 D7 8F 80 08 8F
86 20 - AA OE 07 8F 2E 08 8F OE
8628- 07 8F 2E 08 8F OE 07 8F
863 0- 2E 08 8F OE 07 8F 2E 08
86 3 8- 8F BO DE 8E C9 41 90 02
8640- E9 07 29 OF 00 07 8F 80
8648- 07 8F E8 EC DE 8F DO 01
8650- EE DO 8F A9 01 60 CO 00
8658- FO OE AE E7 8F DO 09 48
8660- 98 48 20 lA 7F 68 A8 68
8668- 99 Fl 80 C8 20 89 81 99
8670- Fl 80 C8 C9 42 DO 68 A9
8678- 00 80 ED 8F AD E7 8F FO
8680- 17 8C EA 8F AD F9 8F FO
407
Appendix B: LADS Object Code
8688- OF 20 59 89 20 OA 89 20
8690- 32 89 20 OA 89 AC EA 8F
8698- 20 89 81 99 Fl 80 C8 C9
86AO- 20 DO F5 20 B9 81 99 Fl
86A8- 80 C8 C9 22 DO 45 20 80
86BO- 81 DO 03 4C 85 87 C9 3A
86B8- DO 03 4C 88 87 C9 38 DO
86CO- OC 20 94 84 AE F5 8F 8E
86C8- FC 8F 4C 85 87 C9 22 DO
8600- 03 4C AE 86 AE E7 8F DO
8608- 09 20 EB 88 4C AE 86 4C
86EO- 56 8A 99 Fl 80 AA 8C EA
86E8- 8F 20 C3 88 AC EA 8F C8
86FO- 4C AE 86 A2 00 8E EE 8F
86F8- 90 06 8F E8 AD EE 8F DO
8700- 75 20 B9 81 FO 43 C9 3A
8708- FO 3F C9 3B DO OC 20 94
8710- 84 AE F5 8F 8E FC 8F 4C
8718- 49 87 80 80 8E AD E7 8F
8720- DO 00 AD 80 8E C9 20 DO
8728- 03 20 E8 88 4C FC 86 AD
8730- 80 8E 99 Fl 80 C8 C9 20
8738- FO 18 C9 00 FO 14 C9 3A
8740- FO 10 90 06 8F E8 4C FC
8748- 86 EE EE 8F 80 81 8E 4C
8750- lA 87 A9 06 85 FB A9 8F
8758- 85 FC 8C EA 8F 20 81 83
8760- AE 07 8F 20 C3 88 AC EA
8768- 8F A9 00 A2 05 90 06 8F
8770- CA DO FA 4C FC 86 AD E7
8778- 8F DO 03 20 EB 88 AD 81
8780- 8E C9 3A FO 03 20 B2 85
8788- 80 F7 8F EE FB 8F 68 68
8790- AD E7 8F FO 08 AD F9 8F
8798- FO 03 4C 65 70 4C 8F 7A
87AO- AD E7 8F C9 02 DO 01 60
87A8- 20 lC 82 A2 02 20 A6 81
87BO- 38 AD 07 8F E5 FD 80 D5
87B8- 8F AD D8 8F E5 FE 8D D6
87CO- 8F A9 00 20 D6 81 AD D5
87C8- 8F DO 03 CE 06 8F CE 05
87DO- 8F DO EE AD 06 8F DO E9
8708- 20 lC 82 A? 01 20 A2 81
87EO- 60 38 E9 7F 80 EO 8F A2
87E8- FF CE EO 8F FO 08 E8 BD
87FO- DO DO 10 FA 30 F3 E8 BD
8 ~ F8- DO DO 30 07 99 00 02 C8
8800- 4C F6 87 29 7F 60 AO 00
8808- A2 00 B9 Fl 80 C9 2B FO
408
Appendix B: LADS Object Code
8810- 04 C8 4C OA 88 C8 B9 Fl
8818- 80 20 25 88 BO 12 90 DE
8820- 8E E8 4C 15 88 C9 3A BO
8828- 06 38 E9 30 38 E9 DO 60
8830- A9 00 9D DE 8E A9 DE 85
8838- FB A9 8E 85 FC 20 81 83
8840- AD D7 8F 8D FO 8F AD 08
8848- 8F 8D ~1 8F 60 AD E7 8F
8850- DO 04 20 EB 88 60 AD F9
8858- 8F FO 11 20 lC 82 A2 01
8860- 20 A2 81 AE CE 8F 20 13
8868- 89 20 OA 89 AE CE 8F 20
8870- C3 88 60 AD E7 8F DO 04
8878- 20 EB 88 60 AD F9 8F FO
8880- 06 AE D7 SF 20 13 89 AE
8888- 07 8F 4C C3 88 AD E7 8F
8890- DO 07 20 EB 88 20 EB 88
8898- 60 AD F9 8F FO 06 AE D7
88AO- 8F 20 13 89 AE D7 8F 20
88A8- C3 88 AD F9 8F FO OE AD
88BO- FA 8F FO 03 20 OA 89 AE
88B8- D8 8F 20 13 89 AE 08 8F
88CO- 4C C3 88 BE D6 8F AD F6
88C8- 8F ~O 05 AO 00 8A 91 FD
88DO- AD F4 8F FO 16 20 lC 82
88D8- A2 02 20 A6 81 AD D6 8F
88EO- 20 D6 81 20 Ie 82 A2 01
88E8- 20 A2 81 18 A9 01 65 FD
88FO- 85 FD A9 00 65 FE 85 FE
88F8- 60 AO 00 Bl FB ~O OA 20
8900- D6 81 20 85 89 C8 4C FB
8908- 88 60 A9 20 20 D6 81 20
8910- 85 89 60 8E E9 8F AD FA
8918- 8F FO OB 8A 20 3D 8A 20
8920- AE 89 AE E9 8F 60 A9 00
8928- 20 24 ED 20 AE 89 AE E9
8930- 8F 60 AD FA 8F FO OE A5
8938- FE 20 3D 8A A5 FD 20 3D
8940- 8A 20 El 89 60 A6 FD A5
8948- FE 20 24 ED 20 El 89 60
8950- A9 OD 20 D6 81 20 85 89
8958- 60 AE D2 8F AD 03 8F 20
8960- 24 ED 20 17 8A 60 A9 Fl
8968- 85 FB A9 8D 85 FC 20 F9
8970- 88 60 A9 07 20 D6 81 A9
8978- 12 20 06 81 20 66 89 A9
8980- OD 20 D6 81 60 AE E7 8F
8988- DO 01 60 AE F5 8F DO 01
8990- 60 80 E8 8F 20 Ie 82 A2
409
Appendix B: LADS Object Code
8998- 04 20 A6 81 AD E8 8F 20
89AO- D6 81 20 lC 82 A2 01 20
89A8- A2 81 AD E8 8F 60 AE E7
89BO- 8F DO 01 60 AE F5 8F DO
8988- 01 60 20 1C 82 A2 04 20
89CO- A6 81 AD FA 8F FO 09 AD
89C8- E9 8F 20 3D 8A 4C 08 89
89DO- A9 00 AE E9 8F 20 24 ED
8908- 20 lC 82 A2 01 20 A2 81
89EO- 60 AE E7 8F DO 01 60 AE
89E8- FS 8F DO 01 60 20 lC 82
89FO- A2 04 20 A6 81 AE FA 8F
89F8- FO OD A5 FE 20 3D 8A A5
8AOO- FD 20 3D 8A 4C OE 8A A5
8A08- FE A6 FD 20 24 ED 20 lC
8AI0- 82 A2 01 20 A2 81 60 AE
8A18- E7 8F DO 01 60 AE F5 8F
8A20- DO 01 60 20 lC 82 A2 04
8A28- 20 A6 81 AD D3 8F AE D2
8A30- 8F 20 24 ED 20 lC 82 A2
8A38- 01 20 A2 81 60 48 29 OF
8A40- A8 B9 El 80 AA 68 4A 4A
8A48- 4A 4A A8 B9 El 8D 20 D6
8A50- 81 8A 20 D6 81 60 C9 46
8A58- DO 08 20 B9 8A 68 68 4C
8A60- 8F 7A C9 45 DO 06 20 12
8A68- 88 4C 50 8A C9 44 DO 03
8A70- 4C 58 8B C9 50 DO 03 4C
8A78- Cl 8B C9 4E DO 03 4C 02
8A80- 8C C9 4F DO 03 4C ED 8B
8A88- C9 53 DO 03 4C 9A 8C C9
8A90- 48 DO 03 4C B4 8C 99 Fl
8A98- 80 20 59 89 20 OA 89 20
8AAO- 32 89 20 72 89 20 66 89
8AA8- A9 B4 85 FB A9 8F 85 FC
8ABO- 20 F9 88 20 50 89 4C D4
8AB8- 8B 20 89 81 C9 20 FO 03
8ACO- 4C B9 8A AO 00 20 B9 81
8AC8- C9 00 FO OE C9 7F 90 03
8ADO- 20 04 85 99 Fl 8D C8 4C
8AD8- C5 8A 84 F9 AO 00 B9 Fl
8AEO- 80 FO 07 99 F3 8E C8 4C
8AE8- DE 8A AD E7 8F DO 06 20
8AFO- 32 89 20 OA 89 20 66 89
8AF8- 20 50 89 20 E5 80 A2 01
8BOO- 20 A2 81 20 B9 81 20 B9
8B08- 81 20 B2 85 A2 00 8E D4
8810- 8F 60 A9 2E 20 06 81 A9
8B18- 45 20 06 81 A9 4E 20 D6
410
Appendix B: LADS Object Code
8820- 81 A9 44 20 D6 81 A9 20
8B28- 20 D6 81 20 89 81 20 89
8B30- 8A AD E7 8F FO 03 EE D4
8838- 8F EE E7 8F 38 A5 FD ED
8840- DO 8F 8D FD 8F A5 FE ED
8B48- Dl 8F 8D FE 8F AD DO 8F
8850- 85 FD AD Dl 8F 85 FE 20
8B58- OE 84 60 AD E7 8F FO IE
8860- 20 B9 81 99 Fl 8D AO 00
8868- 20 89 81 FO 14 C9 7F 90
8870- 03 20 04 85 99 Fl 8D 99
8878- F3 8E C8 4C 68 88 4C 04
8880- 88 84 F9 20 66 89 20 50
8B88- 89 EE F4 8F 20 FC 80 A2
8890- 02 20 A6 81 AO DO 8F 20
8898- D6 81 AD 01 8F 20 D6 81
88AO- AD FD 8F 20 D6 81 AD FE
88A8- 8F 20 D6 81 20 lC 82 A2
8880- 01 20 A2 81 20 82 85 68
8888- 68 A2 00 8E D4 8F 4C 8F
8BCO- 7A AD E7 8F FO OE 20 08
88C8- 81 EE F5 8F 20 lC 82 A2
88DO- 01 20 A2 81 20 89 81 FO
88D8- 07 C9 3A FO 06 4C D4 88
88EO- 20 82 85 68 68 A2 00 8E
88E8- D4 8F 4C SF 7A A9 2E 20
88FO- D6 81 A9 4F 20 D6 81 20
88F8- 50 89 A9 01 80 F6 8F 4C
8COO- 04 88 AD E7 8F FO CO 20
8C08- 89 81 C9 50 FO OC C9 4F
8CI0- FO 3A C9 53 FO 6A C9 48
8C18- FO 4C A9 2E 20 D6 81 A9
8C20- 4E 20 06 81 A9 50 20 06
8C28- 81 20 50 89 CE F~ 8F 20
8C30- lC 82 A2 04 20 A6 81 A9
8C38- OD 20 D6 81 A9 04 20 35
8C40- 82 20 lC 82 A2 01 20 A2
8C48- 81 4C 04 88 A9 2E 20 D6
8C50- 81 A9 4E 20 D6 81 A9 4F
8C58- 20 D6 81 20 50 89 A9 00
8C60- 8D F6 8F 4C 04 88 A9 2E
8C68- 20 D6 81 A9 4E 20 D6 81
8C 70- A9 48 20 D6 81 20 50 89
8C 78- A9 00 8D FA 8F 4C 04 88
8C80- A9 2E 20 D6 81 A9 4E 20
8C88- D6 81 A9 53 20 D6 81 20
8C90- 50 89 A9 00 8D F9 8F 4C
8C98- 04 88 A9 2E 20 06 81 A9
8CAO- 53 20 06 81 20 50 89 AD
411
Appendix B : LADS Object C ode
8CA8- E7 8F FO 05 A9 01 8D F9
8C80- 8F 4C 04 88 A9 2E 20 06
8CB8- 81 A9 48 20 06 81 20 50
8CCO- 89 A9 01 80 FA 8F 4C 04
8CC8- 8B 4C 44 41 4C 44 59 4A
8COO- 53 52 52 54 53 42 43 53
8C08- 42 45 51 42 43 43 43 40
8CEO- 50 42 4E 45 4C 44 58 4A
8CE8- 4D 50 53 54 41 53 54 59
8CFO- 53 54 58 49 4E 59 44 45
8CF8- 59 44 45 58 44 45 43 49
8000- 4E 58 49 4E 43 43 50 59
8D08- 43 50 58 53 42 43 53 45
8010- 43 41 44 43 43 4C 43 54
8D18- 41 58 54 41 59 54 58 41
8020- 54 59 41 50 48 41 50 4C
8028- 41 42 52 4B 42 4D 49 42
8030- 50 4C 41 4E 44 4F 52 41
8D38- 45 4F 52 42 49 54 42 56
8040- 43 42 56 53 52 4F 4C 52
8D48- 4F 52 4C 53 52 43 4C 44
8050- 43 4C 49 41 53 4C 50 48
8058- 50 50 4C 50 52 54 49 53
8060- 45 44 53 45 49 54 53 58
8068- 54 58 53 43 4C 56 4E 4F
8070- 50 01 05 09 00 08 08 08
8078- 01 08 05 06 01 02 02 00
8080- 00 00 02 00 02 04 04 01
8088- 00 01 00 00 00 00 00 00
8090- 00 00 08 08 01 01 01 07
8D98- 08 08 03 03 03 00 00 03
80AO- 00 00 00 00 00 00 00 00
80A8- 00 Al AO 20 60 BO FO 90
80BO- Cl DO A2 4C 81 84 86 C8
80B8- 88 CA C6 E8 E6 CO EO El
80CO- 38 61 18 AA A8 8A 98 48
8DC8- 68 00 30 10 21 01 41 24
80DO- 50 70 22 62 42 08 58 02
80D8- 08 28 40 F8 78 BA 9A B8
80EO- EA 30 31 32 33 34 35 36
8DE8- 37 38 39 41 42 43 44 45
80FO- 46 00 00 00 00 00 00 00
80F8- 00 00 00 00 00 00 00 00
8EOO- 00 00 00 00 00 00 00 00
8E08- 00 00 00 00 00 00 00 00
8EIO- 00 00 00 00 00 00 00 00
8E18- 00 00 00 00 00 00 00 00
8E20- 00 00 00 00 00 00 00 00
8E28- 00 00 00 00 00 00 00 00
412
Appendix B: LADS Object Code
8E30- 00 00 00 00 00 00 00 00
8E38- 00 00 00 00 00 00 00 00
8E40- 00 00 00 00 00 00 00 00
8E48- 00 00 00 00 00 00 00 00
8E50- 00 00 00 00 00 00 00 00
8E58- 00 00 00 00 00 00 00 00
8E60- 00 00 00 00 00 00 00 00
8E68- 00 00 00 00 00 00 00 00
8E70- 00 00 00 00 00 00 00 00
8E78- 00 00 00 00 00 00 00 00
8E80- 00 00 00 00 00 00 00 00
8E88- 00 00 00 00 00 00 00 00
8E90- 00 00 00 00 00 00 00 00
8E98- 00 00 00 00 00 00 00 00
8EAO- 00 00 00 00 00 00 00 00
8EA8- 00 00 00 00 00 00 00 00
8EBO- 00 00 00 00 00 00 00 00
8EB8- 00 00 00 00 00 00 00 00
8ECO- 00 00 00 00 00 00 00 00
8EC8- 00 00 00 00 00 00 00 00
8EOO- 00 00 00 00 00 00 00 00
8E08- 00 00 00 ~) 00 00 00 00
8EEO- 00 00 00 00 00 00 00 00
8EE8- 00 00 00 00 00 00 00 00
8EFO- 00 00 00 00 00 00 00 00
8EF8- 00 00 00 00 00 00 00 00
8FOO- 00 00 00 00 00 00 00 00
8F08- 00 00 00 00 00 00 00 00
8FI0- 00 00 4E 4F 20 53 54 41
8F18- 52 54 20 41 44 44 52 45
8F20- 53 53 00 20 20 20 20 20
8F28- 20 20 20 2D 20 20 20 20
8F30- 20 20 20 20 20 20 20 20
BF38- 42 52 41 4E 43 48 20 4F
8F40- 55 54 20 4F 46 20 52 41
8F48- 4E 47 45 00 55 4E 44 45
8F50- 46 49 4E 45 44 20 4C 41
8F58- 42 45 4C 00 10 10 10 10
8F60- 10 10 10 10 10 20 4E 41
8F68- 48 45 44 20 4C 41 42 45
8F70- 4C 00 10 10 10 10 10 20
8F78- 3C 3C 3C 3C 3C 3C 3C 3C
8F80- 20 44 49 53 4B 20 45 52
8F88- 52 4F 52 20 3E 3E 3E 3E
8F90- 3E 3E 3E 3E 20 00 10 10
8F98- 10 10 10 20 20 20 20 44
8FAO- 55 50 4C 49 43 41 54 45
8FA8- 44 20 4C 41 42 45 4C 20
8FBO- 20 20 20 00 10 10 10 10
413
Appendix B: LADS Object Code
8FB8- 10 20 20 20 20 53 59 4E
8FCO- 54 41 58 20 45 52 52 4F
8FC8- 52 20 20 20 20 00 00 00
8FOO- 00 00 00 00 00 00 00 00
8F08- 00 00 00 00 00 00 00 00
8FEO- 00 00 00 00 00 00 00 00
8FE8- 00 00 00 00 00 00 00 00
8FFO- 00 00 00 00 00 00 00 00
8FF8- 00 00 00 00 00 00 00 00
9000- 00 01 00 01 00 00 01 06
9008- 02 20 93 00 00 00 93 00
9010- 92 00 00 01 00 01 00 00
9018- 01 06 04 80 95 00 00 53
9020- 95 53 94 00 00 03 01 00
9028- 00 00 00 00 00 00 00 00
9030- 00 00 9 3 00 92 00 91 04
9038- 01 00 00 00 00 00 00 00
9040- 00 00 00 53 95 53 94 53
9048- 93 02 00 00 00 00 00 00
9050- 00 00 00 00 00 00 93 00
9058- 92 00 91 02 00 00 00 00
9060- 00 00 00 00 00 00 00 53
9068- 95 53 94 53 93 00 00 00
9070- 00 01
414
Machine Language
Editor for Atari and
COOltnodore
Charles Brannon
Have you ever typed in a long machine language program?
Chances are you typed in hundreds of DATA statements,
numbers, and commas. You're never sure if you've typed
them in right. So you go back, proofread, try to run the pro-
gram, crash, go back and proofread again, correct a few typing
errors, run again, crash, recheck your typing-frustrating, isn' t
it?
Until now, though, that has been the best way to enter
machine language into your computer. Unless you happen to
own an assembler and are willing to wrangle with machine
language on the assembly level, it is much easier to enter a
BASIC program that reads the DATA statements and POKEs
the numbers into memory.
Some of these BASIC loaders, as they are known, use a
checksum to see if you 've typed the numbers correctly. The
simplest checksum is just the sum of all the numbers in the
DATA statements. If you make an error, your checksum will
not match up . Some programmers make the task easier by
calculating checksums every ten lines or so, and you can
thereby locate your errors more easily.
Almost Foolproof
"MLX" lets you type in long machine language (ML) listings
with almost foolproof results . Using MLX, you enter the num-
bers from a special list that looks similar to BASIC DATA
statements. MLX checks your typing on a line-by-line basis. It
won't let you enter illegal characters when you should be
typing numbers, such as a lowercase L for a 1 or an 0 for a O.
It won't let you enter numbers greater than 255, which are not
permitted in ML DATA statements. It will prevent you from
entering the wrong numbers on the wro ng line. In short, MLX
should make proofreading obsolete!
In addition, MLX will generate a ready-to-use tape or disk
file. For the Commodore, you can then use the LOAD com-
415
Appendix C: Commodore and Atari Machine Language Ed~
Getting Started
To get started, type in and save MLX (VIC owners must have
at least 8K of extra memory attached). When you are ready to
enter LADS using MLX, Commodore 64 and VIC owners
should enter the line below before loading MLX:
POKE 55,0: POKE 56,42: CLR
Commodore PET JCBM owners should use:
POKE 52,0: POKE 53,42: CLR
When you're ready to type in LADS, the program will ask you
for several numbers: the starting address and the ending ad-
dress. In addition, the Atari MLX will request a "RunjInit
Address".
Below are the numbers you'll need.
PETjCBM, VIC and Commodore 64:
Starting address 11000
Ending address 15985
Atari:
Starting address 32768
Ending address 39607
RunjInit address 32768
The Atari version will then ask you to press either T for a
boot tape, or D for disk; press D. Next, you'll be asked if you
want to generate a boot disk or a binary file; press F.
Next you'll see a prompt. The prompt is the current line
you are entering from the listing. Each line is six numbers plus
a checksum. If you enter any of the six numbers wrong, or en-
416
Appendix C: Commodore and Atari Machine Language Editor
ter the checksum wrong, MLX will ring a buzzer and prompt
you to reenter the line. If you enter it correctly, a pleasant bell
tone will sound and you proceed to the next line.
A Special Editor
You are not using the normal screen editor with MLX. For
example, it will accept only numbers as input. If you need to
make a correction, press the DEL/ BACKS key (Atari) or the
INST /DEL key (Commodore). The entire number is deleted .
You can press it as many times as necessary back to the start
of the line. If you enter three-digit numbers as listed, the com-
puter will automatically print the comma and prepare to ac-
cept the next number. If you enter less than three digits (by
omitting leading zeros), you can press either the comma, space
bar, or RETURN key to advance to the next number. When
you get to the checksum value, the Atari MLX will emit a low
drone to remind you to be careful. The checksum will auto-
matically appear in inverse video; don't worry, it's highlighted
for emphasis.
When testing MLX, we've found that it makes entering
long listings extremely easy. We have tested MLX with people
lacking any computer background whatsoever. No one here
has managed to enter a listing wrong with it.
Done at Last!
When you finish typing (assuming you type the entire listing
in one session), you can then save the completed program on
tape or disk. Follow the screen instructions. (For Atari we sug-
gest that you use the filename AUTORUN.SYS when saving a
copy of LADS. This way LADS will automatically load and
run when you boot up your computer.) If you get any errors
while saving, you probably have a bad disk, or the disk is full,
or you made a typo when entering the actual MLX program.
(Remember, it can't check itself!)
Command Control
What if you don 't want to enter the whole program in one sit-
ting? MLX lets you enter as much as you want, save that por-
tion, and then reload the file from tape or disk when you
want to continue. MLX recognizes these few commands:
S: Save
L: Load
417
Appendix C: Commodore and Atari Machine Language Editor
N: New Address
D: Display
For the Atari, hold down the CTRL key while you type
the appropriate key. Hold down SHIFT on Commodore ma-
chines to enter a command key. You will jump out of the line
you've been typing, so it's best to perform these commands at
a new prompt. Use the Save command to save what you've
been working on. It will write the tape or disk file as if you've
finished, but the tape or disk won't work, of course, until you
finish the typing . Remember what address you stop on. The next
time you run MLX, answer all the prompts as you did before,
then insert the disk or tape . When you get to the entry
prompt, press CTRL-L (Atari) or SHIFT -L (Commodore) to re-
load the file into memory. You'll then use the New Address
command to resume typing.
Tricky Business
The special commands may seem a little confusing at first, but
as you work with MLX, they will become easy and valuable.
What if you forgot where you stopped typing, for instance?
Use the Display command to scan memory from the beginning
to the end of the program. You can stop a listing by hitting
any key.
Making Copies
You can use the MLX Save and Load commands to make
copies of the completed ML program. Use Load to reload the
tape or disk, then insert a new tape or disk and use the Save
command to make a new copy.
418
Appendix C: Commodore and Atari Machine Language Editor
310 A=l: PRINTRIGHT$ (" 0000" +MID$ (STR$ (AD) , 2) , 5) ; " : "
315 FORJ=AT06
320 GOSUB570:IFN=-lTHENJ=J+N:GOT0320
390 IFN=-211THEN 710
400 IFN=-204THEN 790
410 IFN=-206THENPRINT: INPUT" {DOWN}ENTER NE\</ ADDRES
S";ZZ
415 IFN=-206THENIFZZ<SORZZ>ETHENPRINT"{RVS}OUT OF
{SPACE}RANGE":GOSUB1000:GOT0410
417 IFN=-206THENAD=ZZ:PRINT:GOT0310
420 IF N<>-196 THEN 480
430 PRINT?: INPUT" DISPLAY: FROM" ; F: PRINT, "TO"; : INPUTT
440 IFF<SORF>EORT<SORT>ETHENPRINT"AT LEAST";S;"
{LEFT}, NOT MORE THAN";E:GOT0430
450 FORI=FTOTSTEP6: PRINT: PRINTRIGHT$ (" 0000" +MID$ (S,
TR$ ( I ) , 2 ) , 5 ) ; " : " ;
451 FORK=0T05:N=PEEK(I+K):PRINTRIGHT$("00"+MID$(ST
R$ ( N) , 2 ) , 3 ) ; " , " ;
460 GETA$:IFA$>""THENPRINT:PRINT:GOT031 0
470 NEXTK:PRINTCHR$(20); : NEXTI:PRINT:PRINT:GOT0310
480 IFN<0 THEN PRINT:GOT0310
490 A(J)=N:NEXTJ
500 CKSUM=AD-INT(AD / 256)*256:FORI=lT06:CKSUM=(CKSU
M+A(I))AND255:NEXT
510 PRINTCHR$(18); :GOSUB570:PRINTCHR$(146);
511 IFN=-lTHENA=6:GOT0315
515 PRINTCHR$(20):IFN=CKSUMTHEN530
520 PRINT:PRINT"LINE ENTERED WRONG RE-ENTER":PRI
NT:GOSUB1000:GOT0310
530 GOSUB2000
540 FORI=lT06:POKEAD+I-1,A(I):NEXT:POKE54272,0:POK
E54273,0
550 AD=AD+6:IF AD<E THEN 310
560 GOTO 710
570 N=0 :Z=0
580 PRINT"E£~";
581 GETA$:IFA$=""THEN581
585 PRINTCHR$(20); :A=ASC(A$):IFA=130RA=440RA=32THE
N670
590 IFA>128THENN=-A:RETURN
600 IFA<>20 THEN 630
610 GOSUB690:IFI=lANDT=44THENN=-1:PRINT"{OFF}
{LEFT} {LEFT}";:GOT0690
620 GOT0570
630 IFA<480RA>57THE N580
640 PRINTA$; :N=N*10+A-48
650 IFN>255 THEN A=20:GOSUB1000:G OT0600
660 Z=Z+1:IFZ<3THEN580
420
Appendix C: Commodore and Atari Machine Language Editor
740 GETA$:IFA$<>"T"ANDA$<>"D"THEN740
750 DV=I-7*(A$="D"):IFDV=8THENF$="0:"+F$:OPENI5,8,
15, "S"+F$:CLOSEI5
760 T$=F$:ZK=PEE K(53)+256*PEE K(54)-LEN(T$):POKE782
,ZK/256
762 POKE781,ZK-PEEK(782)*256:POKE780,LEN(T$):SYS65
469
763 POKE780,I:POKE781,DV:POKE782,I:SYS65466
765 K=S:POKE254,K / 256:POKE253,K-PEEK(254)*256:POKE
780,253
766 K=E+l:POKE782,K/ 256:POKE781,K-PEEK(782)*256:SY
S65496
770 IF(PEEK(783)AND1)OR(191ANDST)THEN780
77 5 PRINT {DOWN} DONE. {DOWN}" : GOT0310
II
RINT:GOT0310 -
8113 PRINT:PRI NT" {2 DOWN} {RVS}T{OFF}APE OR {RVS}D
(OFF}ISK: (T / D)" -
820 GETA$: IFA$ <>"T"ANDA$ <> "D"THEN820
830 DV=I-7* (A$="D") : IFDV=8THENF$="0: "+F$
840 T$=F$:ZK=PEEK(53)+256*PEEK(54)-LEN(T$):POKE782
,ZK / 256
841 POKE781,ZK-PEEK (782)*256:POKE780,LEN(T$):SYS65
469
845 POKE780,I:POKE781,DV : POKE782,I:SYS65466
850 POKE780,0:SYS65493
860 IF(PEEK(783)AND1)OR(191ANDST)THEN870
865 PRINT"{DOWN}DONE . ":GOT0 31 0
421
Appendix C: Commodore and Atari Machine Language Editor
422
Appendix C: C ommodore and Atari Machine Language Editor
417 IFN=-206THENAD=ZZ:PRINT:GOT0310
420 IF N<>-196 THEN 480
430 PRINT:INPUT"DISPLAY:FROM"~F:PRINT,"TO"~:INPUTT
440 IFF<SORF>EORT<SORT>ETHENPRINT"AT LEAST"~S~"
{LEFT}, NOT MORE THAN" ~ E, GOT0430
450 FORI=FTOTSTEP6:PRINT:PRINTRIGHT$("0000"+MID$(S
TR$(I),2),5)~":"~
455 FORK=0T05:N=PEEK(I+K):IFK=3THENPRINTSPC(10)~
457 PRINTRIGHT$("00"+MID$(STR$(N),2),3)~","~
460 GETA$:IFA$>""THENPRINT:PRINT:GOT0310
470 NEXTK:PRINTCHR$(20)~ :NE X TI:PRINT:PRIN~:GOT0310
480 IFN<0 THEN PRINT:GOT0310
490 A(J)=N:NEXTJ
500 CKSUM=AD-INT(AD / 256)*256:FORI=IT06:CKSUM=(CKSU
M+A(I))AND255:NEXT
510 PRINTCHR$(18)~:GOSUB570:PRINTCHR$(20)
515 IFN=CKSUMTHEN530
520 PRINT:PRINT"LINE ENTERED WRONG":PRINT"RE-ENTER
":PRINT:GOSUBI000-;-GOT0310-
530 GOSUB20ro0
5410 FORI=IT06:POKEAD+I-l,A(I):NEXT
5510 AD=AD+6:IF AD<E THEN 3110
5610 GOTO 7110
5710 N=ro:Z=ro
5810 PRINT" ~+~ " ~
581 GETA$:IFA$=""THEN581
585 PRINTCHR$(20)~:A=ASC( A $):IFA=130RA=440RA=32THE
N670
590 IFA>128THENN=-A:RETURN
6100 IFA<>2ro THEN 6310
6110 GOSUB69ro:IFI=IANDT=4 4 THENN=-I:PRINT"{LEFT}
(LEFT}"~ : GOT069ro
620 GOT0570
630 IFA<480RA>57THEN580
6410 PRINTA$~ :N=N*lro+A-48
650 IFN>255 THEN A=2ro:GOS UBlro00:GOT06ro0
660 Z=Z+I:IFZ<3THEN58ro
670 IFZ=0THENGOSUBI000:GOT0570
680 PRINT","~ : RETURN
6910 S%=PEEK(2ro9)+256*PEEK(210)+PEEK(211)
692 FORI=IT03:T=PEEK(S%-I)
695 IFT<>44ANDT<>58THENPOKES%-I,32:NEXT
700 PRINTLEFT$("{3 LEFT}",I-l)~ : RETURN
710 PRINT"{CLR}{RVS}* * * SAVE ***{3 Dovm}"
720 INPUT" {DO\m} FILENAME" ~F$
730 PRINT : PRINT"{"2 DOWN} {RVS}T{OFF}APE OR {RVS}D
{OFF}ISK: (:!,/ Q) " -
423
Appendix C : Comm od ore and Atari Machine Language Editor
740 GETA$:IFA$<>"T"ANDA$<>"D"THEN740
750 DV=I-7*(A$="D"):IFDV=8THENF$="0:"+F$
760 T$=F$:ZK=PEEK(53)+256*PEEK(54)-LEN(T$):POKE782
,ZK/256
762 POKE781,ZK-PEEK(782)*256:POKE780,LEN(T$):SYS65
469
763 POKE780,I:POKE781,DV:POKE782,I:SYS65466
765 POKE254,S/256:POKE253,S-PEEK(254)*256:POKE780,
253
766 POKE782,E/256:POKE781,E-PEEK(782)*256:SYS65496
770 IF(PEEK(783)ANDl)OR(ST ANDI91)THEN780
775 PRINT" {DOWN} DONE . " : END
780 PRINT"{DOWN}ERROR ON SAVE.{2 SPACES}TRY AGAIN.
" : IFDV=1 THEN720 - -
781 OPENI5,8,15:INPUT#15,El$,E2$:PRINTEl$;E2$:CLOS
EI5:GOT0720
782 GOT0720
790 PRINT"{CLR}{RVS}*** LOAD ***{2 DOWN}"
800 INPUT" {2 DOWN} FILENAME"; F$
810 PRINT: PRINT" {2 Dovm} {RVS} T {OFF} APE OR {RVS} D
{OFF} ISK: (T /D) " -
820 GETA$: IFA$ <>"T"ANDA$ <> "D"THEN820
830 DV=I-7 * (A$=" D" ) : IFDV=8THENF$= "0: "+F$
840 T$=F$:ZK=PEEK(53)+256*PEEK(54)-LEN(T$):POKE782
,ZK/256
841 POKE781,ZK-PEEK(782)*256:POKE780,LEN(T$):SYS65
469
845 POKE780,I:POKE781,DV:POKE782,I:SYS65466
850 POKE780,0:SYS65493
860 IF(PEEK(783)ANDl)OR(ST ANDI91)THEN870
865 PRINT"{DOWN}DONE.":GOT0310
870 PRINT"{DOWN}ERROR ON LOAD.{2 SPACES}TRY AGAIN.
{DOWN}": IFDV;;-1 THEN800- -
880 OPENI5,8,15:INPUT#15,El$,E2$:PRINTEl$;E2$:CLOS
EI5:GOT0800
1000 REM BUZZER
1001 POKE36878,15:POKE36874,190
1002 FORW=IT0300:NEXTW
1003 POKE36878,0:POKE36874,0:RETURN
2000 REM BELL SOUND
2001 FORW=15T00STEP-l:POKE36878,W:POKE36876,240:NE
XTW
2002 POKE36876,0:RETURN
3000 PRINTC$;"{RVS}NOT ZERO PAGE OR ROM":GOTOI000
424
Appendix C: Commodore and Atari Machine Language Editor
315 FORJ=AT06
320 GOSUB570:IFN=-lTHENJ=J+N:GOT0320
390 IFN=-211THEN 710
400 IFN=-204THEN 790
410 IFN=-206THENPRINT:INPUT"{DOWN}ENTER NEW ADDRES
S";ZZ
415 IFN=-206THENIFZZ<SORZZ>ETHENPRINT"{RVS}OUT OF
{SPACE)RANGE":GOSUB1000:GOT0410
417 IFN=-206THENAD=ZZ:PRINT:GOT0310
420 IF N<>-196 THEN 480
430 PRINT:INPUT"DISPLAY:FROM";F:PRINT,"TO"; :INPUTT
440 IFF<SORF>EORT<SORT>ETHENPRINT"AT LEAST";S;"
{LEFT}, NOT MORE THAN"; E : GOT0430
450 FORI=FTOTSTEP6:PRINT:PRINTRIGHT$("0000"+MID$(S
TR$ ( I ) , 2 ) , 5 ) ; " : " ;
451 FORK=0T05 :N=PEEK (I+K) : PRINTRIGHT$ ( "00 "+MID$ (ST
R$ ( N) , 2 ) , 3 ) ; " , " ;
460 GETA$:IFA$>""THENPRINT:PRINT:GOT0310
470 NEXTK:PRINTCHR$(20); :NEXTI:PRINT:PRINT:GOT0310
480 IFN<0 THEN PRINT:GOT0310
490 A(J)=N:NEXTJ
500 CKSUM=AD-INT(AD / 256)*256:FORI=lT06:CKSUM=(CKSU
M+A(I»AND255:NEXT
510 PRINTCHR$(18); :GOSU B570:PRINTCHR$(146);
511 IFN=-ITHENA=6:GOT0315
515 PRINTCHR$( 20 ):IFN=CKSUMTHEN530
425
Appendix C: Commodore and Atari Machine Language Editor
426
A ppendix C: Commodore and Atari Machine Language E d itor
427
Appendix C: Commodore and Atari Machine Language Editor
428
Appendix C : Commodore and Atari Machine Language E ditor
429
Appendix C: Commodore and Atari Machine Language Editor
430
Appendix C : C ommodore and Atari Machine Language Editor
431
A Library of
Subroutines
Here is a collection of techniques you'll need to use in many
of your ML programs. Those techniques which are not inher-
ently easy to understand are followed by an explanation.
433
Appendix D: A Library of Subroutines
Comparison
Comparing a single-byte against another single-byte is easily
achieved with CMP. Double-byte comparison can be handled
this way:
(Assume that the numbers you want to compare are located
in addresses $0605,0606 and $0700,0701. The ML program
segment performing the comparison is located at $5000.)
5000 SEC
5001 LOA $0605; low byte of first number
5004 SBC $0700; low byte of second number
5007 STA $0800; temporary holding place for this result
500A LOA $0606; high byte of first number
5000 SBC $0701; high byte of second number, leave result in A
5010 ORA $0800; results in zero if A and $0800 were both zero.
The flags in the Status Register are left in various states
after this routine-you can test them with the B instructions
and branch according to the results . The ORA sets the Z (zero)
flag if the results of the first subtraction (left in $0800) and the
second subtraction (in A, the Accumulator) were both zero.
This would only happen if the two numbers tested were
identical, and BEQ would test for this (Branch if EQual) .
If the first number is lower than the second, the carry flag
would have been cleared, so BCC (Branch if Carry Clear) will
test for that possibility. If the first number is higher than the
second, BCS (Branch if Carry Set) will be true. You can there-
fore branch with BEQ for =, BCC for < , and BCS for >. Just
keep in mind which number you are considering the first and
which the second in this test.
434
Appendix D : A Library of Subroutines
435
Appendix D : A Libr ar y of Subroutin es
436
Appendix D: A Library of Subroutines
2000 FIRST = $FB; define zero page pointers at $FB and $FO
2000 SECOND = $FO
2000 SETUP LOA #5; set up pointer to $0605
2002 STA FIRST
2004 LOA #6
2006 STA FIRST + 1
2008 LOA #0; set up pointer to $0700
200A STA SECOND
200C LOA #7
200E STA SECONO+1
Multiplication
X2
ASL (no argument used, " Accumulator addressing mode") will
multiply the number in the Accumulator by 2.
X3
(To multiply by 3, use a temporary variable byte we'll call
TEMP.)
5000 STA TEMP; put the number into the variable
5003 ASL; multiply it by 2
5004 AOC TEMP; (X * 2 + X = X * 3) the answer is in A.
X4
(To multiply by 4, just ASL twice.)
5000 ASL; * 2
5001 ASL; * 2 again
x 4 (two byte)
(To multiply a two-byte integer by 4, use a two-byte variable
we'll call TEMP and TEMP + 1.)
5000 ASL TEMP; multiply the low byte by 2
5003 ROL TEMP+1; moving any carry into the high byte
5006 ASL TEMP; multiply the low byte by 2 again
5009 ROL TEMP+1; again acknowledge any carry.
437
Appendix D: A Library of Subroutines
X 10
(To multiply a two-byte integer by 10, use an additional two-
byte variable we'll call STORE.)
5000i first put the number into STORE for safekeeping
5000 LOA TEMP:STA STORE:LOA TEMP+1:STA STORE+1
500Ci then multiply it by 4
500C ASL TEMPi multiply the low byte by 2
500F ROL TEMP+1i moving any carry into the high byte
5012 ASL TEMPi multiply the low byte by 2 again
5015 ROL TEMP+1i again acknowledge any carry.
5018i then add the original, resulting in X * 5
5018 LOA STORE
501B AOC TEMP
SOlE STA TEMP
5021 LOA STORE+1
5010 AOC TEMP+1
5024 STA TEMP+1
5027i then just multiply by 2 since (5 * 2 = 10)
5027 ASL TEMP
502A ROL TEMP + 1
X ?
(To multiply a two-byte integer by other odd values, just use
a similar combination of addition and multiplication which
results in the correct amount of multiplication.)
X 100
(To multiply a two-byte integer by 100, just go through the
above subroutine twice.)
X 256
(To multiply a one-byte integer by 256, just transform it into
a two-byte integer.)
5000 LOA TEMP
5003 STA TEMP+1
5006 LOA #0
5008 STA TEMP
438
Appendix D: A Library of Subroutines
Division
+2
LSR (no argument used, "Accumulator addressing mode") will
divide the number in the Accumulator by 2.
+4
(To divide by 4, just LSR twice.)
5000 LSR; / 2
5001 LSR; / 2 again
+ 4 (two byte)
(To divide a two-byte integer, called TEMP, by 2)
5000 LSR TEMP+1; shift high byte right
5001 ROR TEMP; pulling any carry into the low byte
439
Hovv to Type In
BASIC Progratns
Some of the programs listed in this book are written in BASIC
and contain special control characters (cursor control, color
keys, inverse video, etc.). To make it easy to tell exactly what
to type when entering one of these programs into your com-
puter, we have established the following listing conventions.
There is a separate key for each computer. Refer to the appro-
priate tables when you come across an unusual symbol in a
program listing. If you are unsure how to actually enter a con-
trol character, consult your computer's manuals.
Atari
Characters in inverse video will appear like: "';W":~"''''''''~];I(I:
Enter these characters with the Atari logo key, {AI .
When you see Tvpe See
{CLEAR} ESC SHIFT ... Clear Screen
{UP} ESC CTRL - ~ Cursor Up
{DOWN} ESC CTRL ... Cursor Oo .... n
(LEFT} ESC CTRL + <- Cursor Left
(RIGHT} ESC CTRL Cursor Right
(BACK S} ESC DELETE
* ->
Backspace
(DELETE} ESC CTRL DELETE (J Delete Character
(INSERT} ESC CTRL INSERT n Insert Character
{DEL LINE} E S C S HIFT DELETE ~l Delete Line
<INS LINE} ESC SHIFT INSERT e Insert Line
(TAB } ESC TAB TAB key
{CLR TAB} ESC CTRL TAB a Clear TAB
{SET TAB} ESC SHI F T TAB 0 Set TAB stop
(BELL} ESC CTRL 2 G1 Ring Buzzer
(ESC} ESC ESC ESCape key
'"
Graphics characters, such as CTRL-T, the ball character. will
appear as the " normal" letter enclosed in braces, e.g., {T} .
A series of identical control characters, such as 10 spaces,
3 cursor-lefts, or 20 CTRL-Rs, will appear as {10 SPACES},
{3 LEFT}, {20 R}, etc. If the character in braces is in inverse
video, that character or characters should be entered with the
Atari logo key. For example, {5 m } means to enter five inverse-
video CTRL-Us.
440
Appendix E: How to Type In BASIC Programs
441
Appendix E: How to Type In BASIC Programs
[DOWN}
[LEFT}
I SHiFf 11+ CRSR; I
I SHlFr I
1+ CRSR;
~ CRSR"' I
I
r:l
m
II
[YEL}
[Fl}
[F2 }
~Q iii
II
fl
I
!
-II•
[RIGHT}
[RVS}
~~
~ C RSR~ !I
m
(F3 )
[F4}
f3
f.
I
I
•II!-
[OFF}
[BLK}
~~
~CJ
•• [F5 }
(F6)
f5
f6
I
I
.1
II
[WHT } ~LJ ~ [ F7J f7
I II
[RED}
[CYN}
~[2J
~~
~
!IlL
[FB}
~
I f8
1. . . . 1
I
•
~
(PUR) ~c=J
• i I SHiFf I [JJ fi
·-
442
Index
• = (Program Counter =) pseudo-op 32, BAS IC
111 - 12, 149-51 , 203, 336, 339 borrowing from 18-19, 105-7, 182-83
# > pseud o-op 342-43 end of program mark 152
# < pseudo-op 34 2-43 keyword table 10, 18
+ pseudo-op 179, 342-43 See also tokenized keywords
Accumul ator. See 6502, Accumu lator BCC 242
Register BCS 242-43
Accumulator addressing 38 BEQ 243
ADC 239-40 B group instructions. See Relative
address (Progra m Counter) labe ls 7, addressin g
36-37 BIT 243-44
address ing modes . See 6502, instruction bit-moving instructions 38
types BMI 244
AND 240-41 and BPL 45-47, 83
with ASC II numbers 114, 154 BNE 244-45
Apple LADS 327-32, borrow 266
BASIC wedge 331-32 BPL 245
Disk Operating System file manager and BMI. See BMI and BPL
327-32 BRANCH OUT OF RANGE 11, 39
er ror byte 330 Brannon, Charl es 108,415
Openl 327- 32 BRK 245-46
Array (subprogram) 43 , 85-93 buffer 29-30, 140
program listings 97-101 BYC 246
ASC lI BYS 247
alpha betic numbers 154-55 carry 239, 242, 247, 266-67
characters 33 , 82-83 chain ed fil es. See pseudo-ops, .E; pseudo-
messages 182 ops, .F
number convers ion 113-16 character 8
ASL 241-42 CLC 247
with ROL 11 5- 16, 153-54 CLD 247-48
assembly 5-6, 34 CLl 248
Atari CLY 248-49
CIO 299 CMP 249- 50
IOCB 299 and turbo -charged programming 108
memory 300 cold sta rt 18
Atari LADS 299-327, 34 8-55 comments 141-44
Defs 30 1 Co mm odore
Editor 301, 308- 12, 350-55 Kerna l 4
program listing 312-27 ST (status byte) 205
Eval 301 , 304-5 constant 4
Getsa 302 CPX 250-51
Indisk 303 CPY 251 -5 2
Kerna l 300, 303 - 4 .0 (.D ISK) pseudo-op 181 , 202-5, 345
program listing 305-8 data base managem ent. See Array (sub-
modifying the Editor 311 progra m); Eq uate (subprogram)
Open 1 302 debugging 53-55, 149-5 1, 260, 339
Printops 303 DEC 252
Pseudo 303 decimal mode 239-40, 247-48, 261
System 305 defaults 29
program listing 308 changing 31
Va ldec 302 Defs (s ubprogra m) 15-25
.B (.BYTE) pseudo-op 156-58 program listings 20-25
base opcodes 36, 226 relocatability 15-16
transpo rtabil ity 16
443
delimiters 82-84 Indisk (s ubprogra m) 32, 34, 42, 139-76
DEX 252-53 program listings 161-76
DEY 253 initializa tion 29
Dis (optional subprogram) 288-96 Input/O utput (I / O)
program listings 294-96 Commodore 105-8
disk 16 See also Pseudo (subprogram)
assembly to disk. See pseudo-ops, .D instruction types. See 6502, instruction
errors 205 types
padding with spacer bytes 151, 159-60 integer 8
Program Counter 107 interrupt
division 259, 439 customizing 268
documentation. See comments disabling 268
double-byte ML routines forced 245
-addition 435 INX 254-55
comparison 434 INY 255
decrement 433 jMP 255-56
increment 433 jSR 256-57
subtraction 435 covering with NOP 260
Dtables (optional subprogram) 288-96 self-modifying indirect 311
program listings 296-98 Kernal. See Atari LADS, Kernal; Com-
DUPLICATED LABEL 86-88, 90 modore, Kernal
.E (.END) pseudo-op 201 , 202, 343 labels 40-42
EOR 253-54 storin g in data base 83-85
to shift an ASCII character 83 See also address (Program Counter) la-
equate labels 7, 16, 36-37 bels; DUPLICATED LABEL; equate la-
ze ro page 16 bels; expressio n labels; source labels;
Equate (subprogram) 81-84 UNDEFINED LABEL
program listings 94-96 LADS
error signals 184 Apple. See Apple LADS
error traps (additional) assembly 34
impossible instruction 279-80 Atari. See Atari LADS
keywords in fil enames buffers 227-28
naked mnemonic 278-79 'co mm and summary 338-39
Eval (subprogram) 29-76 development and philosophy 79-81,
calculating an opcode 226 108-11,150-5 1
determining addressing mode (instruc- disassembler. See Dis (optional
tion type) 43-53 subprogram)
program listings 55-76 fla gs 228-3 1
expression labels 86 how to use 335-55
extensibility 277 modifying 184, 200-201, 277-98
.F (.FILE) pseudo-op 112, 199-200, 343 object code listings 357-414
fa lse target 11 Program Counter 33, 86, 149-51
fields RAM-based assembl y 282-86
fixed length 79-81 , 108 registers 227-28
variable length 79-83 relocating 15
Findmn (subprogram) 32, 35-37, 109-11 rules for use 345
program listings 129-30 tape use 348
flags 5, 9, 30 zero page usage 17-18
Getsa (subprogram) 32, 111-13 LOA 257-5 8
program listings 131-34 LDX 258
.H (.HEX) pseudo-op 206 LOY 258-59
hexadecimal (hex) numbers 42-43, loopi ng 81-82
152-56, 183-85 lin ked fil es
Implied addressing 37-38 See pseud o-ops, .F; pseudo-ops, .E
INC 254 lookup tables 108-11
loop co unter 252-53
444
LSR 259 Pseudo (subprogram) 199-217
Machine Language Editor (MLX) 415 program listings 207-17
Macilille Lallguage for Bcgillllcrs 34 pseudo-ops
Machine Language (ML) routines . See *= (Program Counter = ) 32, 111-12,
double-byte ML routines; multi-byte 149-51,203,336,339
ML routines #> 342-43
Mappillg the Atari 327 #< 342-43
Math (subprogram) 179-80 + 179,34 2-43
program listings 186-87 .B (.BYTE) 156-58
" Micromon" 150 .0 (.DISK) 181, 202-5, 345
MLX. See Machine Language Editor .E (.END) 201 , 202, 343
program listings 419-31 .F (.FILE) 112, 199- 200,343
mnemonic instructions. See 6502, instruc- .H (.HEX) 206
tion set .N (.NO) 204-5
modifying LADS 184,200-201 , 277-98 .0 (.OBJECT code to RAM) 181 , 204,
monitor 3 344
multi-byte ML routines .r (.PRINTER) 204
addition 436 .s (.sCREEN) 206
subtraction 436 RAM-based assembly 282-86
multiplication 115-16, 437-38 range checking 179
.N (.NO) pseudo-op 204-5 redefined label 87
NAKED LABEL 84 register 4, 29
NOP 260 Relative addressing 44- 47
NO START ADDRESS 112 remarks. See comments
numbers 8 ROL 263-64
.0 (.OBJECT code to RAM) pseudo-op with ASL. See ASL, with ROL
181, 204, 344 ROR 264-65
object code 5, 181 with LSR 259
opcodes . See 6502, opcodes RTl265
Openl (subprogram) 106-8 RTS 265-66
program listings 117-29 .s (.sCREEN) pseudo-op 206
ORA 260-61 SBC 266
with alphabetic numbers 154-55 SEC 266-67
output. See Input/Output; Printops SED 267
(subprogram) SEI 268
OVERFLOW 47 semicolon 341
.P (.PRINTER) pseudo-op 204 seventh bit (bit 7) 9-10
parallel tables 108-11 , 221-27 shifted characters 82, 147, 244-45
PHA 261 signed arithmetic 10, 239, 244-45
and PLA 45-47, 53 branching 46-47
PHP 262 Simple Assemb ler 34
PLA 262 6502
and JSR 256 Accumulator Register 257
and PHA. See PHA and PLA add ressing modes. See 6502, instruction
PLP 262-63 types
pointer 4, 30 bug 255-56
printing instruction types 37-38, 43-45, 222-24
addresses 200 opcades 221-22, 225
hex numbers 185 Status Register 5, 9, 30, 246
routines 184-85 X Register 258
source code 49-51 Y Register 258
Printops (subprogram) 180-85 source code 5
program listings 187-95 printout. See printing, source cade
Program Counter. See LADS, Progra m source files 335
Counter source labels 88
445
springboards 10, 39, 145 tokenized keywords 139, 142, 144-46,
stack 261, 262, 265, 272 160, 199-200
start address 32-33. See also pseudo-ops, TSX 271
'= turbo-charged programming 108
STA 269 TXA 271-72
Status Register. See 6502, Status Register TXS 272
STX 269 TYA 273
STY 269-70 types. See 6502, instruction types
subprogram 7-8 UNDEFINED LABEL 91-92
suction routine 140 Valdec (subprogram) 32-33, 43, 113-16
SYNTAX ERROR 199 program listings 134-36
tables. See lookup tabl es registers 228
Tables (subprogram) 36, 108, 221 - 36 variable 4
program listings 232-36 vector 4
TAX 270 warm start 18
TAY 270-71 zero page address labels 93
toggle 253 Zero Page Y addreSSing 53
446
To order your copy of the LADS Disk call our toll-free US
order line : 1-800-334-0868 (in NC call 919-275-9809) or send
your prepaid order to:
LADS Disk
COMPUTE! Publications
P.O. Box 5406
Greensboro, NC 27403
Subtotal $_ _ _ __
D Payment enclosed
Charge D Visa D MasterCard D American Express
Name _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ __
Address