Chapter 9
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, sometimes on tape, sometimes in the user's brain, as when a program 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 LDA #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 subprogram. 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 definitions, messages, pointers, buffers, flags, and registers. LADS couldn't operate without them, but they're not active programming instructions-they're for reference.

Three Parallel Tables
Tables starts out, appropriately enough, with three parallel tables: MNEMONICS, TYPES, and OPS. Each table contains 56 pieces of information. MNEMONICS holds the names of all the 6502 mnemonics like LDA and INY. TYPES identifies the category of each mnemonic (we'll get to this in a minute). And OPS provides an opcode for each category. To see how these three tables work together, let's look at the first item in the first table, the mnemonic LDA.
     In your machine language programming, you might want to load the Accumulator with the number 1. You would write: 100 LDA #1
     The computer wouldn't grasp the meaning of the ASCII characters L-D-A-#-1 at all. They're for our convenience, not its.
     We think alphabetically or alphanumerically. It thinks binarily. It wants pure numbers. The CPU, the "thinking" part of the 6502 chip, takes action according to a code of its own, but this code isn't the ASCII code. It's an opcode, an operations code. The CPU will place a number into the Accumulator, the A Register, if it comes across any of the following numbers: 161, 165, 169, 173, 177, 181, 185, or 189. Each of these numbers is an opcode for LDA. But each one loads from a different place. The different numbers represent the opcodes for the eight different addressing modes available to LDA. They are:

Addressing
Mode's Name

Example

Opcode
Immediate
Zero Page
Zero Page,X
Zero Page,X (indirect)
Zero Page,Y (indirect)
Absolute
Absolute,Y
Absolute,X
LDA # 15
LDA 15
LDA 15,X
LDA (15,X)
LDA (15),Y
LDA 1500
LDA 1500,Y
LDA 1500,X
169
165
181
161
177
173
185
189

     Most of the mnemonics can use a variety of addressing modes. LDA can be addressed these eight ways, LDY can be addressed five ways, and so on. That's where TYPES comes in. There are ten TYPES, and each opcode falls into one of the ten categories. Mnemonics are grouped according to their addressing mode's similarities. The mnemonics cluster into TYPES according to the way that they can be addressed:

Type 0:
RTS, INY, DEY, DEX, INX, SEC,
CLC, TAX, TAY, TXA, TYA, PHA,
PLA, BRK, CLD, CLI, PHP, PLP,
RTI, SED, SEI, TSX, TXS, CLV
NOP

(Each of these mnemonics takes up only one byte in memory; each is only capable of Implied addressing-they have no argument, no address.)

Type 1:
LDA, CMP, STA, SBC, ADC, AND,
ORA, EOR

(Type 1 mnemonics have the largest number of possible addressing modes, eight. See the list for LDA above.)

Type 2:
STY, STX, DEC, INC

(These are fairly restricted in their addressing options. STY has only three possibilities: Absolute, Zero Page, and Zero Page,X. STX can perform only Absolute, Zero Page, and Zero Page,Y [it's the only one which can use this Zero Y mode]. DEC and INC can do Absolute; Zero Page; Zero Page,X; and Absolute,X.)

Type 3:
ROL, ROR, LSR, ASL

(These are the bit-shifting, "logical" instructions. They can be addressed in the following modes: Absolute; Zero Page; Zero Page,X; Absolute,X; and one which is reserved for them alone, Accumulator mode. In that mode, the number held in the Accumulator is acted upon.)

Type 4:
CPY, CPX

(The compare X or Y can use Immediate, Absolute, or Zero Page modes.)

Type 5:
LDY, LDX

(These loads are more restricted in their addressing possibilities than LDA. LDX can use Immediate; Absolute; Zero Page; Absolute,Y; and Zero Page,Y. LDY can use Immediate; Absolute; Zero Page; Zero Page,X; and Absolute,X. Notice that they cannot index themselves; X modes are possible only with LDY and vice versa.)

Type 6:
JMP

(This is a special case; it stands alone. It has two ways of addressing: the extremely common Absolute mode and the extremely rare Indirect mode, JMP (via this). Because most programming contains many JMPs, it should have its own category. Also, the only other mnemonic which is essentially limited to Absolute addressing is JSR, and it gets a category all to itself as well.)

Type 7:
BIT

(This one is also an oddity. It too needs a category all its own. BIT can use only Absolute or Zero Page addressing.)

Type 8:
BCS, BEQ, BCC, BNE, BMI, BPL,
BVC, BVS

(All the branch instructions collect together as type 8. They have only one addressing mode, Relative, and they are the only instructions which can use this mode.)

Type 9:
JSR

(It can only Absolute address.)
Each of these groups derives from the arrangement of the opcodes. The patterns are more easily visualized if you look at the opcodes laid out in a table according to their numeric values.

Table 9-1. Table of Opcodes

LSD

MSD

0

1

2

3

4

5

6

7

8

9

A

B

C

D

E

F
LSD

MSD
0
BRK
ORA IND,X



ORA Z Page
ASL Z Page

PHP
ORA IMM
ASL A


ORA ABS
ASL ABS

0
1
BPL
ORA IND,Y



ORA Z Page, X
ASL Z Page,X

CLC
ORA ABS,Y



ORA ABS,X
ASL ABS,X

1
2
JSR
AND IND,X


Bit Z Page
AND Z Page
ROL Z Page

PLP
AND IMM
ROL A

BIT ABS
AND ABS
ROL ABS

2
3
BMI
AND IND,Y



AND Z Page,X
ROL Z Page,X

SEC
AND ABS,Y



AND ABS,X
ROL ABS,X

3
4
RTI
EOR IND,X



EOR Z Page
LSR Z Page

PHA
EOR IMM
LSR A

JMP ABS
EOR ABS
LSR ABS

4
5
BVC
EOR IND,Y



EOR Z Page,X
LSR Z Page,X

CLI
EOR ABS,Y



EOR ABS,X
LSR ABS,X

5
6
RTS
ADC IND,X



ADC Z Page
ROR Z Page

PLA
ADC IMM
ROR A

JMP IND
ADC ABS
ROR ABS

6
7
BVS
ADC IND,Y



ADC Z Page,X
ROR Z Page,X

SEI
ADC ABS,Y



ADC ABS,X
ROR ABS,X

7
8

STA IND,X


STY Z Page
STA Z Page
STX Z Page

DEY

TXA

STY ABS
STA ABS
STX ABS

8
9
BCC
STA IND,Y


STY Z Page,X
STA Z Page,X
STX Z Page,Y

TYA
STA ABS,Y
TXS


STA ABS,X


9
A
LDY IMM
LDA IND,X
LDX IMM

LDY Z Page
LDA Z Page
LDX Z Page

TAY
LDA IMM
TAX

LDY ABS
LDA ABS
LDX ABS

A
B
BCS
LDA IND,Y


LDY Z Page,X
LDA Z Page,X
LDX Z Page,Y

CLV
LDA ABS,Y
TSX

LDY ABS,X
LDA ABS,X
LDX ABS,Y

B
C
CPY IMM
CMP IND,X


CPY Z Page
CMP Z Page
DEC Z Page

INY
CMP IMM
DEX

CPY ABS
CMP ABS
DEC ABS

C
D
BNE
CMP IND,Y



CMP Z Page,X
DEC Z Page,X

CLD
CMP ABS,Y



CMP ABS,X
DEC ABS,X

D
E
CPX IMM
SBC IND,X


CPX Z Page
SBC Z  Page
INC Z Page

INX
SBC IMM
NOP

CPX ABS
SBC ABS
INC ABS

E
F
BEG
SBC IND,Y



SBC Z Page,X
INC Z Page,X

SED
SBC ABS,Y



SBC ABS,X
INC ABS,X

F
     Notice the relationship between LDA (15,X) and LDA #15. The former has an opcode of 161; the latter, 169. As the Eval subprogram goes through the source code line, it is looking for clues to the addressing mode: Is there a #, a comma, a parenthesis, an X, or a Y?
     Each of these things, combined with the TYPE, tells Eval when to raise the value of the original opcode (let's call it the base opcode) assigned to the mnemonic from the OPS table. If Eval finds a # symbol, it adds 8 to the base opcode and goes right to the TWOS exit. It knows then that this opcode should be 169 (161 + 8) and that there will be two bytes to assemble: Immediate mode addressing uses two bytes. (All the other mnemonics grouped with LDA as type 1 will also add 8 to their base opcodes to signify their Immediate addressing modes.)
     The base opcodes are in that third table called OPS (190). The Eval subprogram looks up each mnemonic in the MNEMONICS table, and then the numbers extracted from the TYPES and OPS tables are stored in the variables TYPE and OP for future reference. Finally, Eval starts looking for those # and ) clues within the source code line. These clues cause Eval to add 4 or 8 or 16 or sometimes even 24 to the base opcode. This adjusts the base opcode upward so it will eventually become the correct opcode for the addressing mode being used.
     CMP is grouped with LDA as a type 1 mnemonic. That's because a # will add 8 to either of their base opcodes and result in the correct, final opcode for Immediate addressing. The base opcode for CMP is 193, which, unadjusted, would stand for CMP (15,X). If we come upon a # following the CMP, however, 8 is added to the 193, giving 201, the correct opcode for CMP #15. Then Eval would JMP to TWOS and conclude assembly of that line of source code.
     In each case, the base opcode in the OPS table is the lowest possible opcode number from among the addressing mode options available to each mnemonic. As the evaluation process proceeds throughout the Eval subprogram, the discovery of the various addressing modes triggers additions to the base opcode. In the end, when Eval finally releases a source code line, the right opcode has been achieved.
     Returning to the data within the Tables subprogram, we next come upon the little HEXA table (270). It lists all the digits found in hexadecimal numbers. It's used as a lookup table when LADS translates an internal two-byte integer into a printable, readable ASCII hexadecimal number like F-F-D-2.

The Six Bufferettes
Here are the buffers (290-340). They are constantly being filled with a source code line, evaluated, and then cleaned off by being filled with zeros. They are separated into six different bufferettes primarily for the programmer's benefit. It's easier to visualize different actions if the buffers have different names.
     LABEL is the main buffer-every source code line comes into it. BUFFER is where arguments are sent for further study. The rest of them are used for special-purpose analysis. Things like hex numbers are moved up to HEXBUF, for example, so they will be isolated from other characters and can be translated.
     One other buffer, distant from the rest, is needed. LADS stores comments (remarks following semicolons in the source code) into a buffer normally used by BASIC to hold program lines. The location of this buffer depends on each computer's memory organization and so it is defined in the Defs subprogram.
     The computer's Accumulator and Y and X are called registers. They're like hypervariables inside the 6502 chip-they are constantly changing. Calling them registers serves to distinguish them from program-created variables or other special locations within the computer. The three variables RADD, VREND, and TSTORE are called registers in LADS. That's largely the result of whimsy. There are as yet no established conventions concerning how to describe storage areas in ML programming. In this book we're variously referring to these set-aside bytes as flags, variables, registers, pointers, vectors, etc. (See Chapter 1).
     In reality, they're all pretty much the same thing: Just some RAM memory space we've allocated with the BYTE pseudo-op (or identified in zero page by definition using the = pseudo-op like STATUS = $FD). But it's nice to use various terms. It helps to remember things and, sometimes, it even helps to describe the purpose or function of a particular variable. Pointers, for example, are always associated with the Indirect Y addressing mode-LDA (POINTER),Y. They point to some address in RAM.

Registers Used by Valdec
Anyway, these three variables are described (350) as registers. RADD holds numbers being added to other numbers. VREND holds the length of the ASCII version of a number while it's being turned into an integer. TSTORE holds the interim results of multiplication. All three "registers" are used by the Valdec subprogram.
     Lines 400-460 contain the various error messages. Note that each one ends with BYTE 0 to stick a delimiting 0 in after the message itself. This 0 tells PRNTMESS (the subroutine in the Printops subprogram which prints messages) where to stop.
     The rest of Tables contains variables, pointers, and registers. Notice that there are no zero page variables here. Zero page variables, pointers especially, are most useful for Indirect Y addressing, but you won't need too many of them. In fact, you won't be allowed to use much of zero page because it is so popular with your computer's operating systems and languages. But the most important thing to remember about any zero page space that you do use is: Zero page variables must be defined at the start of your assembler source code. They are unique in this. Any other equates can be defined anywhere in the source code. And, of course, the address-type PC variables or labels can be defined anywhere.
     OP and TYPE are variables which hold information about the mnemonic currently under investigation during assembly. After a mnemonic is located in the MNEMONIC table, the matching TYPE and base opcode are pulled out of their tables and stored into the variables OP and TP for later reference (480-490). TA is the permanent storage area for the start address of assembly, the original *=.

Source Code Line Numbers
LINEN holds the source code line number of whatever physical line is currently being assembled. ENDFLAG tells Eval when to shut down assembly. It is incremented by the END pseudo-op. WORK is used by several routines within LADS as a convenient place to temporarily leave two-byte values.
     RESULT is an important variable. It holds the argument of each opcode. When an argument (expression-type) label like STA HERE is encountered, the label HERE is looked up by the subprogram Array and the integer value of the word HERE is placed into RESULT. When a hex argument like STA $1500 comes in from the source code, the subprogram Indisk translates the characters $1500 into an integer value and stores that value in RESULT. Likewise, a decimal argument like STA 5376 is sent to RESULT after it's evaluated in the Eval subprogram. For every addressing mode which has an argument, the argument is stored in RESULT after it's been evaluated.
     ARGSIZE holds the length of each argument, how many characters long it is. For example, ARGSIZE would hold a 7 for the argument in LDA (155),Y since (155),Y is seven characters long. It is used in the Eval subprogram in lines 1670, 2250, 2750, and 3020.
     EXPRESSF is a flag which shows whether or not there is a label being used as an argument. LDA 15 would leave EXPRESSF down. LDA NAME would set it up. It is used in the Eval subprogram at lines 740, 1470, 1510, 1590, and 1700.
     HEXFLAG tells the Eval subprogram whether or not it must calculate a decimal argument. Hex arguments are calculated (and left in RESULT) by the Indisk subprogram. Decimal arguments, however, need to be worked out by Eval. HEXFLAG is used in lines 550 and 1680 in Eval.
     HEXLEN holds the length of a hex number. It is used in Indisk in lines 2170, 2240, and 2490.
     KEYNUM holds the position of a keyword (a BASIC command) in the table of keywords in ROM BASIC. It is used in Indisk in 1060, 1080, 4260, and 4280.
     LABSIZE is used in the Equate subprogram to hold the number of characters in an equate-type label (such as NAME _ 22). It is used in lines 120, 160, and 410.
     LABPTR is also used by Equate. It points to the position in the label array where the integer value of a label should be stored. It is found in lines 600 and 750.
     ARRAYTOP points to the highest byte in the label array. It is where we start any search through the labels. Identical to TA, ARRAYTOP also represents the start of the LADS assembler in memory, minus one. It is used in Equate in lines 110 and 150 and in Array in lines 30 and 50.

A List of Flags and Variables
BUFLAG goes up when a line of source code contains # or (. These symbols are important when determining addressing mode, but must be ignored in evaluating arguments (the numeric value of the expression). This flag is used in lines 470 and 1020 in Array and in lines 750 and 1400 in Eval.
     PASS is used frequently throughout the entire LADS program-it shows which pass we're currently on during assembly. A 0 in PASS signifies pass 1; a 1 represents pass 2.
     The three variables A, X, and Y are often called upon to temporarily hold the values in the 6502 registers after which they were named. They are temporary storage areas.
     PT is a temporary storage area to hold the PARRAY dynamic pointer in the Array subprogram.
     BNUMFLAG and BFLAG are used in the evaluation of the .BYTE pseudo-op in the Indisk subprogram.
     ADDNUM holds the value of the number following the + pseudo-op. For example, it would hold 78 if this were the source code: LDA LABEL+78.
     The PLUSFLAG shows that there is something in the ADDNUM variable which must be added to the label in an argument. It shows that the + pseudo-op appears in the current source code line.
     BYTEFLAG shows that the < or > pseudo-op appears in the current source code line. It is an odd flag in that it has more than two states. It can be 0 indicating no < or >. And it can be 1 or 2 to distinguish between < and >.
     DISKFLAG means the D NAME pseudo-op was activated and so object code should be sent to a disk object file to create a runnable ML program.
     PRINTFLAG means the P pseudo-op was activated and a listing should go to the printer for a hard copy record of assembly.
     POKEFLAG means the .O pseudo-op was activated and all object code generated by assembly should be POKEd into RAM memory.
     COLFLAG is used in the Indisk subprogram to show that the previously assembled line of source code ended with a colon rather than a 0 (end of physical line). It tells Indisk not to look for a new source code line number.
     FOUNDFLAG goes up when the same word is found more than once within the label array, proving that a label has been redefined. That's illegal and results in an error message. This flag is used in the Array subprogram.
     SFLAG means the S pseudo-op is being used and a visible listing of source and object code should appear on the screen during assembly.
     HXFLAG responds to the H pseudo-op. If set (that's the default, the normal start-up condition in LADS), all opcodes and arguments are printed (to screen or printer) in hexadecimal. HXFLAG is turned off by the NH (no hex) pseudo-op and causes opcodes and arguments to be printed as decimal numbers.
     LOCFLAG, when set, tells the printout routines within the Eval subprogram that they need to print a PC address-type label. For example, a line like:

100 START LDA #GREEN

requires special handling so that the address-type label START will be printed on screen or printer in the correct format (or that it will be printed at all). LOCFLAG is used in Eval in lines 790, 1210, and 3510.
     BABFLAG shows that there is a semicolon on a line of source code. It signifies that a REMark, a comment, appears on this line. It tells the printout routines that there is a comment which must also be printed on the screen or the printer following the printout of the business part of a line.

Program 9-1. Tables

10 ; "TABLES"
15 ;
20 ; TABLE OF MNEMONICS AND PARALLEL TABLE OF OPCODE/ADDRESS TYPE DATA
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
90 .BYTE "BRKBMIBPLANDORAEORBITBVC
100 .BYTE "BVSROLRORLSRCLDCLIASLPHP
110 .BYTE "PLPRTISEDSEITSXTXSCLVNOP
120 TYPES .BYTE 1 5 9 0 8 8 8 1
130 .BYTE 8 5 6 1 2 2 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
450 MDUPLAB .BYTE "    -- DUPLICATED LABEL -- ":.BYTE 0
460 MERROR .BYTE "    -- SYNTAX ERROR -- ":.BYTE 0
470 ;----------- FLAGS, POINTERS, REGISTERS ---------------------
480 OP .BYTE 0;        OPCODE
490 TP .BYTE 0;        TYPE
500 TA .BYTE 0 0;        START ADDRESS
510 LINEN .BYTE 0 0;     CURRENT LINE #
520 ENDFLAG .BYTE 0;   END-OF-PROG FLAG
530 WORK .BYTE 0 0;      TEMP WORK AREA
540 RESULT .BYTE 0 0;    TEMP ANSWER AREA
550 ARGN .BYTE 0 0;      VALUE OF ARGUMENT
560 ARGSIZE .BYTE 0;   LENGTH OF ARGUMENT
570 EXPRESSF .BYTE 0;  IS IT AN EXPRESS LABEL
580 HEXFLAG .BYTE 0;   HEX NUMBER FLAG
590 HEXLEN .BYTE 0;    LENGTH OF HEX NUMBER
600 NUMSIZE .BYTE 0;    LENGTH OF ASCII NUMBER IN BUFFER (FOR VALDEC)
610 KEYNUM .BYTE 0;     POSITION OF KEYWORD IN BASIC'S TABLE
620 LABSIZE .BYTE 0;    SIZE OF LABEL (EQUATE TYPE)
630 LABPTR .BYTE 0 0;     POINTS TO ARRAY POSITION FOR ARG STORAGE
640 ARRAYTOP .BYTE 0 0;   TOP OF ARRAYS--SAME AS MEMTOP BEFORE LABELS.
650 BUFLAG .BYTE 0;     AVOID # OR ( DURING ARRAYS ANALYSIS
660 PASS .BYTE 0;       WHICH PASS WE'RE ON.
670 A .BYTE 0:X .BYTE 0:Y .BYTE 0; TO HOLD REGISTERS DURING P SUBR. CHECKER
680 PT .BYTE 0 0;         TEMPORARILY HOLDS PARRAY (IN "ARRAY") 2-BYTE
690 BNUMFLAG .BYTE 0;   FOR BYTE IN "INDISK"
700 BFLAG .BYTE 0 0;      FOR NUMWERK IN "INDISK"
710 ADDNUM .BYTE 0 0;     NUMBER TO ADD FOR + PSEUDO
720 PLUSFLAG .BYTE 0;   FLAG SHOWS THAT + PSEUDO HAPPENED.
730 BYTFLAG .BYTE 0;    SHOWS THAT < OR > HAPPENED.
740 DISKFLAG .BYTE 0;   SHOWS TO SEND BYTES TO DISK OBJECT FILE
750 PRINTFLAG .BYTE 0;  SHOWS TO SEND BYTES TO PRINTER
760 POKEFLAG .BYTE 0;   SHOWS TO SEND BYTES TO MEMORY (OBJECT CODE)
770 COLFLAG .BYTE 0;    ENCOUNTERED A COLON (USED BY INDISK)
780 FOUNDFLAG .BYTE 0;  DUPLICATED LABEL NAME (USED BY ARRAY)
790 SFLAG .BYTE 0;      SHOWS TO SEND SOURCECODE TO SCREEN
800 HXFLAG .BYTE 0;     SHOWS TO PRINT SA AND OPCODES IN HEX
810 LOCFLAG .BYTE 0;    SHOWS TO PRINT A PC ADDRESS LABEL
820 BABFLAG .BYTE 0;    SHOWS TO PRINT A REM AFTER PRNTINPUT IN EVAL
830 ;-----------------------
840 ; NOW LINK UP WITH 1ST FILE ("DEFS") TO PERMIT 2ND PASS.
850 ;
860 .END DEFS

Program 9-2. Tables, Apple Modifications

To create the Apple version of Tables, make the following changes and additions to Program 9-1:

295 .BYTE 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
     0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
305 .BYTE 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
     0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
315 .BYTE 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
     0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
      0 0 0 0 0 0 0,
830 LENPTR .BYTE 0 0;   HOLDS LENGTH OF BINARY PROGRAM
840 FOPEN1 .BYTE 0;     HOLDS THE CURRENT INPUT FILE
850 FOPEN2 .BYTE 0;     HOLDS THE CURRENT OUTPUT FILE
855 ;------------ DOS-MANAGER CONTROL BYTES -------------------
860 OPNREAD .BYTE 1 0 1 0 0 1 6 2
870 .BYTE 45 147 0 0 0 147 0 146 0 0
880 OPNWRIT .BYTE 1 0 1 0 0 1 6 4
890 .BYTE 128 149 0 0 83 149 83 148 0 0
900 RD1B .BYTE 3 1 0 0 0 0 0 0 0 0 0 0
910 .BYTE 0 147 0 146 0 145
920 WR1B .BYTE 4 1 0 0 0 0 0 0
930 WRDATA .BYTE 0 0 0 0 83 149 83 148 83 147
940 CLOSER .BYTE 2 0 0 0 0 0 0 0 0 0 0 0 0 147 0 146 0 145
950 CLOSEW .BYTE 2 0 0 0 0 0 0 0 0 0 0 0 83 149 83 148 83 147
960 OPNI .BYTE 0;       HOLDS THE FILE # OF THE CURRENT INPUT DEVICE
970 OPNO .BYTE 0;       HOLDS THE FILE # OF THE CURRENT OUTPUT DEVICE
980 Al .BYTE 0;         TEMP STORAGE OF ACC
990 Y1 .BYTE 0;         TEMP STORAGE OF Y-REG
1000 ;---------------------
1010 .END DEFS


Program 9-3. Tables, Atari Modifications

To create the Atari version of Tables, make the following changes and additions to Program 9-1:

10 :ATARI MODIFICATIONS--TABLES
825 LLSA .BYTE 0 0
860 .END D:DEFS.SRC


Return to Table of Contents | Previous Chapter | Next Chapter