PASS2
Pass 2: constants, variable routines, backpatching, header and report. Each section's comment stands above it, each line's comments beside it; point at a name for its meaning; line numbers after GOTO, GOSUB and THEN are links.
Sections (38)
- 10 DECLARATIONS: INTEGER VARIABLES, ARRAYS AND THE COMMON BLOCK
- 200 PASS 2 OF THE COMPILER
- 320 COLLECT A PAIR (LATEST REFERENCE, TARGET) FOR THE DATA CHAIN AND EVERY LINE SYMBOL
- 450 SORT THE LINE PAIRS BY LINE NUMBER (A SHELL SORT WITH AN ODD GAP IN PAIRS); THE DATA PAIR
- 570 LOOK UP EACH LINE IN THE LINE NUMBER FILE (NUMBER AND ADDRESS OF EVERY LINE, IN ORDER), SO
- 740 FUNCTIONS
- 900 REPORT WHERE THE REFERENCE AT R4 IS (A FATAL ERROR); PAUSE IF ASKED
- 1060 ANY FATAL ERROR ENDS THE COMPILATION HERE
- 1090 THE CONSTANT POOL, WRITTEN AFTER THE CODE
- 1280 COMMON ALLOCATION IN DECLARATION ORDER FROM THE START OF THE COMMON BLOCK
- 1500 SIZE OF THE ROUTINE AREA
- 1720 LOCAL VARIABLES START AFTER THE ROUTINES, OR AT THE VARIABLES ADDRESS ASKED FOR
- 1780 THE DISPATCHERS THE ROUTINES JUMP TO
- 1850 THE ROUTINES AND THE LOCAL VARIABLES, IN THREE PASSES OVER THE SYMBOL TABLE
- 2060 A NUMERIC VARIABLE'S ROUTINE
- 2370 A STRING VARIABLE'S ROUTINE
- 2500 ENTRY: A PAIR (LATEST REFERENCE, ROUTINE ADDRESS) AND SEC, LDA #$18
- 2700 ENTRY: LDY #HIGH BYTE, LDA #LOW BYTE OF UF
- 2780 AN ARRAY'S ROUTINE
- 3000 THE END OF EACH PASS
- 3080 BACKPATCHING
- 3660 THE HEADER, WRITTEN OVER THE 24 BYTES RESERVED AT THE START OF THE FILE
- 3960 THE COMPILATION INFORMATION AND LINE NUMBER REFERENCE TABLE, IF ASKED FOR
- 4440 THE END: PUT BACK THE SIX BYTES OF DOS THAT PASS 0 CHANGED
- 4600 ADD R9 TO RL()
- 4700 ENTRY
- 4800 WRITING
- 5000 FIND THE LINE THAT HOLDS ADDRESS R4
- 5100 AT A VARIABLE REFERENCE IN THE FILE
- 5200 AT A CHAINED WORD IN THE FILE
- 5300 READ A WORD (LOW BYTE FIRST) INTO R3; 5300 RETURNS IT AS A STORED VALUE (-32767)
- 5500 POSITION THE OBJECT FILE FOR READING AT FO
- 5600 READ A BYTE INTO OW
- 5640 TOO LONG: THE PROGRAM, ITS VARIABLES OR THE REFERENCE LIST DO NOT FIT
- 5660 COMPILATION TERMINATED: DELETE THE OBJECT FILE
- 5800 REPORT A FATAL ERROR: END THE DIRECT FILE INPUT OR OUTPUT FIRST
- 5900 THE MOTOR SWITCHES OF THE SLOT DOS USED LAST
- 6000 STOP THE MOTOR AND CLOSE ALL FILES
10DECLARATIONS: INTEGER VARIABLES, ARRAYS AND THE COMMON BLOCK
INTEGER VARIABLES
EL IS LIBRARY ROUTINE ($0947) THAT RESETS THE STACK, DROPPING EVERY PENDING GOSUB AND FOR, AND RESETS THE DATA POINTER; CALLED AFTER AN ERROR
MN IS DRIVE MOTOR-OFF SWITCH FOR THE BOOT SLOT
SC IS 1 IF THE SOURCE AND OBJECT FILES ARE ON THE BOOT DRIVE (MOTOR KEPT ON), ELSE 0
SC() IS SYMBOL TABLE: CHAIN HEADS, THEN ENTRIES LINKED THROUGH THEIR FIRST WORD
INTEGER VARIABLES
N1 IS RESUME/DEBUG CODE OPTION (1 = YES)
O4 IS COMPILATION LISTING OPTION (1 = YES)
OO IS PAUSE ON ERRORS OPTION (1 = YES)
P8 IS INTEGER ARITHMETIC OPTION (1 = YES)
INTEGER VARIABLES
C3 IS COMMON KIND: -1 NONE, 0 DEFINE, 255 USE
FC IS 1 ONCE A FATAL ERROR HAS BEEN REPORTED (NO MORE CODE IS WRITTEN)
KV IS ADDRESS OF THE FIVE PACKED BYTES LEFT BY THE USR ROUTINE ($0371)
QB IS ADDRESS OF THE ROUTINE THAT READS ONE BYTE FROM THE OPEN FILE INTO IX ($037E)
WS IS ADDRESS OF THE ROUTINE THAT WRITES THE BYTE IN IX TO THE OPEN FILE ($0387)
INTEGER VARIABLES
AK IS ADDRESS BEING COUNTED (COMMON ALLOCATION), SIZE OF THE ROUTINE AREA, START OF THE PAGE BEING PATCHED
CD IS START OF THE COMMON BLOCK (THE PROGRAM START BEFORE COMMON MOVED IT)
CY IS COMMON PASS (0 NUMBERS, 1 STRINGS); ALSO AN OPERATION OR DIMENSION INDEX
L1 IS SCRATCH: A LINE NUMBER, AN ELEMENT SIZE, AN OPERATION MASK
LB IS LIBRARY ADDRESS, STORED AS ADDRESS-32767
LH IS NUMBER OF SOURCE LINES READ
VC IS VARIABLES ADDRESS ASKED FOR, AS ADDRESS-32767, OR -32767 FOR END OF PROGRAM
INTEGER VARIABLES
DW IS DOS STATE BYTE AT $AA52: POKED BEFORE EACH DIRECT FILE READ OR WRITE
GD IS GAP OF THE SORT; ALSO A POWER OF TWO
K8 IS LOOP INDEX; ALSO THE INDEX IN RL()
NR IS NUMBER OF VALUES IN RL()
R4 IS ADDRESS OF A REFERENCE TO REPORT
INTEGER VARIABLES
EU IS SYMBOL TABLE ENTRY BEING WORKED ON
HD IS HIGHEST OPERATION OF A VARIABLE ROUTINE (-1 FOR NONE); ALSO AN INDEX IN THE SORT
HW IS LAST CHAIN HEAD IN SC(); ENTRIES ARE ALLOCATED ABOVE IT
L8 IS CHAIN INDEX; ALSO A TYPE CODE
LQ IS ADDRESS OF THE ROUTINE THAT LISTS THE TOKENIZED LINE IN THE INPUT BUFFER ($038D)
MX IS DRIVE MOTOR-ON SWITCH FOR THE BOOT SLOT ($C089+SLOT*16), TOUCHED TO KEEP THE DRIVE SPINNING
NG IS NUMBER OF CONSTANT HASH CHAINS (32)
NK IS NUMBER OF LINE NUMBER HASH CHAINS (32)
NU IS NUMBER OF VARIABLE HASH CHAINS IN THE SYMBOL TABLE (32)
OH IS INTEGER CONSTANTS OPTION (1 = YES)
R9 IS VALUE TO ADD TO RL()
UV IS ADDRESS OF THE USR ROUTINE THAT PACKS A NUMBER INTO FIVE BYTES ($0377)
INTEGER VARIABLES
LM IS LENGTH OF THE RUNTIME LIBRARY IN BYTES (4013)
T3 IS TYPE CODE: -3 REAL, -2 STRING, -1 INTEGER, 19-21 ARRAYS
VO IS FIRST VARIABLE CHAIN HEAD IN SC() (9; 1-4 HOLD FN AND LINE SYMBOLS, 5-8 TEMPORARIES)
VZ IS TYPE CODE AS STORED (50 HIGHER FOR COMMON, 47/49 FOR A REAL/INTEGER CONSTANT)
INTEGER VARIABLES
CP IS ADDRESS OF THE LAST BYTE OF CODE
DG IS WHICH DISPATCHER: 0 REAL, 1 STRING, 2 INTEGER, 3-5 REAL, STRING AND INTEGER ARRAYS, 6-10 LOOP STARTS AND NEXT
IX IS ADDRESS OF THE ONE-BYTE TRANSFER CELL FOR QB AND WS ($0376)
OU IS OPERATION NUMBER READ AT A REFERENCE
OW IS BYTE TO WRITE TO THE OBJECT FILE (OR JUST READ)
INTEGER VARIABLES
CC IS ADDRESS OF THE LINK WORD OF THE LAST DATA BLOCK (DATA BLOCKS ARE CHAINED)
ED IS OBJECT FILE BASE: FILE POSITION = PC - ED (THE FILE STARTS WITH THE BSAVE HEADER)
NI IS SCRATCH: COUNT OF LINE NUMBER RECORDS READ, THE PASS OVER THE SYMBOLS (1 NUMBERS, 2 ARRAYS, 3 STRINGS), A KEY
PC IS ADDRESS OF THE NEXT OBJECT CODE BYTE, AS ADDRESS-32767
Q9 IS SIZE OF RL() (5900 VALUES)
UR IS PROGRAM START, STORED AS ADDRESS-32767; MOVED UP BY COMMON DECLARATIONS
INTEGER VARIABLES
DN() IS DISPATCHER ADDRESSES: DN(I,0) LOW BYTE, DN(I,1) HIGH BYTE
DP() IS DOS PATCH TABLE: DP(I,0) ADDRESS (AS A SIGNED WORD, ADDRESS-65536), DP(I,1) ORIGINAL BYTE
GG() IS GG(0) = LAST INDEX OF THE LINE AND FUNCTION PAIRS IN RL(), GG(1) = LAST INDEX OF THE NUMERIC ROUTINE GROUPS
KX IS FIRST CONSTANT CHAIN HEAD IN SC()
L IS FIRST LINE NUMBER CHAIN HEAD IN SC()
QF IS PREVIOUS ENTRY (FOR UNLINKING); ALSO THE END OF THE CODE
RL() IS REFERENCE LIST: FOR EACH LINE, FUNCTION AND DATA CHAIN A PAIR (LATEST REFERENCE, TARGET); FOR EACH NUMERIC VARIABLE OR CONSTANT ITS LATEST REFERENCE, STORAGE ADDRESS, ENTRY COUNT (NEGATIVE FOR AN INTEGER) AND ROUTINE ENTRIES; FOR EACH STRING VARIABLE OR ARRAY ITS LATEST REFERENCE AND ROUTINE ADDRESS
COMMON BLOCK, IN THE ORDER IT IS LAID OUT: NUMBERS FIRST, THEN STRINGS. THE PASSES SHARE IT, SO EVERY PASS DECLARES IT THE SAME WAY
BP$ IS TWO BELLS, SOUNDED BEFORE EACH ERROR MESSAGE
CO$ IS DOS CLOSE COMMAND
DI$ IS CONTROL-D, THE DOS COMMAND PREFIX
DN$ IS SLOT AND DRIVE OF THE BOOT DRIVE (",S6,D1")
LN$ IS NAME OF THE LINE NUMBER FILE ("CLINENUM")
OD$ IS OBJECT FILE NAME
OO$ IS SLOT AND DRIVE OF THE OBJECT FILE
OP$ IS DOS OPEN COMMAND
RV$ IS DOS READ COMMAND
SB$ IS SLOT AND DRIVE OF THE SOURCE FILE
SI$ IS SOURCE FILE NAME
WO$ IS DOS WRITE COMMAND
ARRAYS
MM() IS MEMORY LAYOUT FOR THE HEADER: MM(0) LOCALS START-1, (1) END OF NUMERIC LOCALS, (2) END OF STRING LOCALS, (3) COMMON START-1, (4) END OF NUMERIC COMMON, (5) END OF STRING COMMON
200PASS 2 OF THE COMPILER: CHECKS THAT EVERY LINE AND FUNCTION REFERRED TO EXISTS, WRITES THE CONSTANTS AND THE VARIABLE ROUTINES AFTER THE CODE, ALLOCATES COMMON AND LOCAL VARIABLES, REPLACES EVERY CHAINED REFERENCE IN THE OBJECT FILE BY ITS ADDRESS, WRITES THE HEADER AND REPORTS. PASS 1 LEFT EACH REFERENCE AS A LINK TO THE PREVIOUS ONE TO THE SAME SYMBOL, THE SYMBOL HOLDING THE LATEST
THE COPYRIGHT NOTICE; Y$ IS THEN THE ANSWER STRING
Y$ IS THE ANSWER TO THE REPORT QUESTION
FN HB(X): HIGH BYTE OF X
FN LO(X): LOW BYTE OF X
FN UB(X): THE ADDRESS STORED AS X (X+32767)
FN BI(X): ADDRESS X AS IT IS STORED (X-32767)
FN TY(X): TYPE CODE X WITHOUT THE COMMON MARK (X-50 ABOVE 21)
FN LG(X): THE NUMBER OF THE HIGHEST BIT SET IN X (FLOOR OF LOG2)
320COLLECT A PAIR (LATEST REFERENCE, TARGET) FOR THE DATA CHAIN AND EVERY LINE SYMBOL
THE LIST IS EMPTY
THE DATA CHAIN FIRST: ITS LATEST LINK AND -32767 (0 AT THE END OF THE CHAIN)
OPEN THE LINE NUMBER FILE AND READ IT FROM THE START
KEEP THE DRIVE RUNNING
EVERY LINE NUMBER CHAIN
EACH LINE SYMBOL: ITS LATEST REFERENCE AND ITS NUMBER (-32767)
450SORT THE LINE PAIRS BY LINE NUMBER (A SHELL SORT WITH AN ODD GAP IN PAIRS); THE DATA PAIR STAYS FIRST
ONLY THE DATA PAIR: NOTHING TO SORT OR LOOK UP
ONE LINE: NO SORT
THE GAP STARTS AT HALF THE PAIRS ...
... ROUNDED TO WHOLE PAIRS ...
... AND AN ODD NUMBER OF PAIRS
COMPARE EACH PAIR WITH THE ONE A GAP FURTHER, MOVING THE SMALLER BACK AS FAR AS IT GOES
A SMALLER GAP, DOWN TO ONE PAIR
570LOOK UP EACH LINE IN THE LINE NUMBER FILE (NUMBER AND ADDRESS OF EVERY LINE, IN ORDER), SO THE PAIR'S TARGET BECOMES THE LINE'S ADDRESS
NO RECORDS READ YET
EACH LINE REFERRED TO, IN ORDER
THE WHOLE FILE READ WITHOUT FINDING IT
THE NEXT RECORD: THE LINE NUMBER ...
(KEPT)
... AND THE ADDRESS
FOUND: THE PAIR'S TARGET IS THE LINE'S ADDRESS
NOT YET REACHED: READ ON
PASSED: NO SUCH LINE
THE LATEST REFERENCE TO IT
READ THE LINE NUMBER FILE FROM THE START AGAIN
740FUNCTIONS: A PAIR (LATEST REFERENCE, ADDRESS OF THE BODY); A FUNCTION NEVER DEFINED IS AN ERROR
THE FOUR FUNCTION CHAINS
EACH FUNCTION: ITS LATEST REFERENCE ...
... AND THE ADDRESS OF ITS BODY
THE NAME FROM ITS HASH, 99*FIRST CHARACTER+SECOND
900REPORT WHERE THE REFERENCE AT R4 IS (A FATAL ERROR); PAUSE IF ASKED
THE LINE OF THE LATEST REFERENCE
A FATAL ERROR
WITHOUT THE PAUSE OPTION, GO ON AT ONCE
STOP THE DRIVE MOTOR WHILE WAITING
WAIT FOR A KEY; CONTROL-C ENDS THE COMPILATION
1060ANY FATAL ERROR ENDS THE COMPILATION HERE
CLOSE THE LINE NUMBER FILE
1090THE CONSTANT POOL, WRITTEN AFTER THE CODE: REAL CONSTANTS AS 5 BYTES, INTEGER CONSTANTS AS 2 (HIGH BYTE FIRST); AN INTEGER CONSTANT NEVER REFERRED TO IS DROPPED
THE CODE ENDS HERE
OPEN THE OBJECT FILE ...
T9 IS SCRATCH: A SIZE, A PRODUCT, THE FILE BASE
... AND POSITION IT AT ITS END
EVERY CONSTANT CHAIN
QF = THE PREVIOUS ENTRY
A REAL CONSTANT (ITS FIRST BYTE, THE EXPONENT, IS NOT NEGATIVE): WRITE ITS 5 BYTES AND REPLACE THEM BY ITS ADDRESS AND THE MARK 47 (A REAL CONSTANT)
AN INTEGER CONSTANT NEVER REFERRED TO: UNLINK IT
ITS ADDRESS
THE VALUE, HIGH BYTE FIRST
THE MARK 49: AN INTEGER CONSTANT
1280COMMON ALLOCATION IN DECLARATION ORDER FROM THE START OF THE COMMON BLOCK: NUMBERS FIRST, THEN STRINGS
THE FIRST COMMON ADDRESS
NUMBERS FIRST
FOR THE HEADER: THE ADDRESS BEFORE THE COMMON BLOCK
THE LIST OF COMMON DECLARATIONS AT SC(0)
THE NEXT DECLARATION: ITS SYMBOL AND TYPE
IN THE STRING PASS ONLY STRINGS ...
... IN THE NUMERIC PASS ONLY NUMBERS
THE NAME HASH IS REPLACED BY THE STORAGE ADDRESS ...
... AND THE TYPE IS MARKED COMMON (+50)
2 BYTES AN ELEMENT FOR AN INTEGER OR A STRING, 5 FOR A REAL
A SIMPLE VARIABLE
AN ARRAY: THE PRODUCT OF (DIMENSION+1)
THE END OF THE NUMERIC COMMON; NOW THE STRINGS
THE END OF THE STRING COMMON
1500SIZE OF THE ROUTINE AREA: A NUMERIC ROUTINE 3 BYTES PER OPERATION USED PLUS 6, A STRING ROUTINE 10, AN ARRAY ROUTINE 9 + 2 PER DIMENSION
TEMPORARIES, VARIABLES AND CONSTANTS
VARIABLES AND CONSTANTS
A TEMPORARY: A STRING ONE (FREE OR IN USE) HAS A STRING ROUTINE
10 BYTES
A VARIABLE OR CONSTANT: ITS TYPE
AN ARRAY: 9 + 2 PER DIMENSION
A NUMERIC ONE: NO OPERATION USED, NO ROUTINE
3 BYTES FOR EACH OPERATION BIT SET IN THE MASK ...
... AND 6 FOR LDY, LDA, JMP
1720LOCAL VARIABLES START AFTER THE ROUTINES, OR AT THE VARIABLES ADDRESS ASKED FOR
THE LINE AND FUNCTION PAIRS END HERE
THE LOCALS START AFTER THE ROUTINES ...
K1 IS NEXT FREE ADDRESS FOR LOCAL VARIABLES
... WHICH END THE PROGRAM
PB IS LAST ADDRESS OF THE PROGRAM (CODE, CONSTANTS AND ROUTINES)
OR AT THE ADDRESS ASKED FOR
FOR THE HEADER
1780THE DISPATCHERS THE ROUTINES JUMP TO: LIBRARY OFFSETS OF THE REAL, STRING AND INTEGER DISPATCHERS, THE THREE ARRAY DISPATCHERS, THE FOUR LOOP START ENTRIES AND NEXT
$1764 REAL, $0C7F STRING, $0D06 INTEGER, $0B11 $0B14 $0B17 ARRAYS, $09E1 $09E5 $09DE $09E8 LOOP STARTS, $0A31 NEXT (FOR THE LIBRARY AT $0803)
THE LIBRARY ADDRESS
EACH OFFSET PLUS THE LIBRARY ADDRESS
UF IS STORAGE ADDRESS OF THE VARIABLE; ALSO A VALUE READ FROM THE DATA TABLE
1850THE ROUTINES AND THE LOCAL VARIABLES, IN THREE PASSES OVER THE SYMBOL TABLE: 1 NUMERIC VARIABLES, TEMPORARIES AND CONSTANTS, 2 NUMERIC ARRAYS, 3 STRING VARIABLES, TEMPORARIES AND ARRAYS. STORAGE IS ALLOCATED IN THE SAME ORDER
THE CHAINS FROM 5: TEMPORARIES, VARIABLES, CONSTANTS
NO TEMPORARIES IN THE ARRAY PASS
CONSTANTS ONLY IN THE FIRST PASS
CONTROL-C ENDS THE COMPILATION
A VARIABLE OR CONSTANT: ITS TYPE IS IN ITS FOURTH WORD
A TEMPORARY: IN ITS THIRD WORD
A TEMPORARY STILL MARKED IN USE (TYPE-3)
THE TYPE WITHOUT THE COMMON MARK
A LOCAL VARIABLE GOES AT THE NEXT FREE ADDRESS ...
... A CONSTANT OR COMMON VARIABLE HAS ITS ADDRESS ALREADY
ARRAYS
STRINGS IN THE THIRD PASS
NUMBERS IN THE FIRST
STRING ARRAYS IN THE THIRD PASS, NUMERIC ARRAYS IN THE SECOND
2060A NUMERIC VARIABLE'S ROUTINE: FOR EACH OPERATION USED, HIGHEST FIRST, LDX #OPERATION, EACH BUT THE FIRST PRECEDED BY $AD (THE LDA ABSOLUTE OPCODE SWALLOWS THE NEXT LDX, SO EACH ENTRY FALLS THROUGH); THEN LDY #HIGH, LDA #LOW OF THE STORAGE ADDRESS AND JMP TO THE DISPATCHER. NO OPERATION USED: NO ROUTINE
THE GROUP IN RL(): THE LATEST REFERENCE ...
... THE STORAGE ADDRESS ...
THE OPERATION MASK; HD = ITS HIGHEST BIT
... THE NUMBER OF ENTRIES+1 (NEGATIVE FOR AN INTEGER) ...
... AND FOR EACH OPERATION, HIGHEST FIRST, THE ADDRESS OF ITS ENTRY (-32767 IF NOT USED)
$AD BEFORE EACH ENTRY BUT THE FIRST
LDX #OPERATION
LDY #HIGH, LDA #LOW
THE REAL DISPATCHER, OR THE INTEGER ONE
THE INTEGER DISPATCHER FOR AN INTEGER
JMP
A REAL TAKES 5 BYTES, AN INTEGER 2
2370A STRING VARIABLE'S ROUTINE: SEC, LDA #$18 (WHOSE $18 IS THE CLC OF THE SECOND ENTRY, 2 BYTES IN), LDY #HIGH, LDA #LOW, JMP TO THE STRING DISPATCHER: +0 LOADS, +2 STORES
SEC, LDA #$18
LDY #HIGH, LDA #LOW
JMP TO THE STRING DISPATCHER
A STRING VARIABLE IS A 2-BYTE POINTER
2500ENTRY: A PAIR (LATEST REFERENCE, ROUTINE ADDRESS) AND SEC, LDA #$18
SEC
LDA #
$18, THE CLC
2700ENTRY: LDY #HIGH BYTE, LDA #LOW BYTE OF UF
LDY #
HIGH BYTE
LDA #
LOW BYTE
2780AN ARRAY'S ROUTINE: SEC, LDA #$18, JSR TO THE ARRAY DISPATCHER, THEN THE ARRAY'S ADDRESS, ITS NUMBER OF DIMENSIONS AND EACH DIMENSION (10 IF IT WAS NEVER DIMENSIONED): +0 LOADS AN ELEMENT, +2 GIVES ITS ADDRESS
JSR TO THE ARRAY DISPATCHER: 3 REAL, 4 STRING, 5 INTEGER
THE ARRAY'S ADDRESS
W IS WORD TO WRITE
THE NUMBER OF DIMENSIONS
EACH DIMENSION, OR 10
THE NUMBER OF ELEMENTS
TIMES 2, OR 5 FOR A REAL ARRAY
CONSTANTS AND COMMON VARIABLES TAKE NO LOCAL STORAGE
THE NEXT FREE ADDRESS
THE VARIABLES MUST END BELOW $C000
3000THE END OF EACH PASS
AFTER THE FIRST PASS: THE NUMERIC ROUTINE GROUPS END HERE
AFTER THE SECOND: THE NUMERIC LOCALS END HERE
THE STRING LOCALS END HERE
THE HIGHEST ADDRESS: THE END OF THE LOCALS, OF THE PROGRAM OR OF THE LIBRARY
H4 IS HIGHEST MEMORY ADDRESS USED
3080BACKPATCHING: WORK THROUGH THE OBJECT FILE 256 BYTES AT A TIME FROM THE END; IN EACH PAGE FOLLOW EVERY CHAIN WHOSE LATEST REFERENCE LIES IN IT, REPLACING EACH LINK BY THE TARGET. BECAUSE LINKS ALWAYS POINT BACK, EVERY REFERENCE IS REACHED IN ITS PAGE
KEEP THE END OF THE PROGRAM FOR THE HEADER
PC COUNTS FROM 0 NOW, SO THE PATCHES DO NOT LOOK TOO LONG
THE OBJECT FILE IS WRITTEN AGAIN
THE FILE POSITION OF THE LAST BYTE OF CODE ...
... ROUNDED DOWN TO A 256-BYTE PAGE OF THE FILE: AK = THE ADDRESS AT THE PAGE'S START
END THE DIRECT OUTPUT
A DOT FOR EACH PAGE
THE DATA CHAIN: WHILE ITS LATEST LINK IS IN THIS PAGE ...
... READ THE LINK AND POSITION THE FILE OVER IT
FO IS FILE POSITION OF A REFERENCE
THE LAST LINK GETS 0; EACH EARLIER ONE THE ADDRESS RIGHT AFTER THE LATER LINK: SO EACH DATA JMP GOES PAST ITS BLOCK AND EACH BLOCK'S LAST WORD POINTS AT THE NEXT BLOCK'S FIRST ITEM
(WRITE IT)
THIS LINK IS THE TARGET OF THE NEXT ONE BACK
FOLLOW THE CHAIN
NO LINE OR FUNCTION PAIRS
EACH LINE AND FUNCTION PAIR: WHILE ITS LATEST REFERENCE IS IN THIS PAGE, READ THE LINK AND WRITE THE TARGET'S ADDRESS OVER IT (THE JMP OR JSR BEFORE IT IS ALREADY THERE)
NO NUMERIC ROUTINES
EACH NUMERIC VARIABLE OR CONSTANT
ITS LATEST REFERENCE IS BELOW THIS PAGE: THE NEXT GROUP
READ THE OPERATION AND THE LINK
FOLLOW THE CHAIN
OPERATIONS 0-13: JSR TO THE ROUTINE'S ENTRY FOR THE OPERATION
21-25: JSR TO THE LOOP START OR NEXT ENTRY, THEN THE VARIABLE'S ADDRESS IN THE TWO BYTES AFTER
20, AN AND / OR TEST: LDA OF THE VARIABLE ...
... AND FOR AN INTEGER ORA OF ITS SECOND BYTE (THE THREE BYTES PASS 1 LEFT AFTER IT)
THE NEXT GROUP
NO STRING OR ARRAY ROUTINES
EACH STRING VARIABLE OR ARRAY: JSR TO ITS ROUTINE, +2 FOR OPERATION 1 (STORE, OR AN ELEMENT'S ADDRESS)
CONTROL-C ENDS THE COMPILATION
THE PAGE BEFORE, UNTIL THE START OF THE FILE
END THE DIRECT OUTPUT
WRITE AT THE START OF THE FILE
3660THE HEADER, WRITTEN OVER THE 24 BYTES RESERVED AT THE START OF THE FILE: THE BINARY FILE'S ADDRESS AND LENGTH, JSR TO THE LIBRARY, THE FIRST DATA ITEM, THE HIGHEST ADDRESS, THE COMMON AND LOCAL BOUNDS, THE COMMON FLAG
THE BINARY FILE'S ADDRESS ...
... AND LENGTH
JSR TO THE LIBRARY, WHICH COPIES THE HEADER TO PAGE ZERO
THE FIRST DATA ITEM (0 IF THERE IS NO DATA)
THE HIGHEST ADDRESS USED
THE COMMON BOUNDS
THE LOCAL BOUNDS
THE COMMON FLAG: 0 NONE OR DEFINE, 255 USE
CLOSE THE OBJECT FILE
3960THE COMPILATION INFORMATION AND LINE NUMBER REFERENCE TABLE, IF ASKED FOR
A LINE STARTING WITH CONTROL-D IS A DOS COMMAND: IT IS RUN, AND THE QUESTION IS ASKED AGAIN
NO: SKIP THE REPORT
THE PROGRAM START WAS NOT MOVED: NO COMMON
THREE COLUMNS OF LINE NUMBER AND ADDRESS
READ THE LINE NUMBER FILE FROM THE START
EACH RECORD: THE LINE NUMBER AND THE ADDRESS, THREE TO A ROW
(THE NEXT COLUMN, OR A NEW ROW)
4440THE END: PUT BACK THE SIX BYTES OF DOS THAT PASS 0 CHANGED
THE ADDRESSES AND ORIGINAL BYTES PASS 0 SAVED IN DP()
OPEN AND CLOSE THE LINE NUMBER FILE
4600ADD R9 TO RL()
ONLY 5900 VALUES FIT: TOO LONG
4700ENTRY: JMP TO DISPATCHER DG; ENTRY AT 4720: THE OPCODE IN OW, THEN THE DISPATCHER'S ADDRESS
4800WRITING: 4800 THE BYTE OW AND THE WORD W (A STORED ADDRESS); 4820 THE WORD W (A STORED ADDRESS); 4840 THE WORD W AS IT IS; 4880 THE BYTE OW
DOS'S OUTPUT STATE 4: EVERY CHARACTER GOES TO THE FILE; THE ROUTINE AT $0387 WRITES THE BYTE IN $0376
COUNT THE BYTE
THE OBJECT MAY NOT PASS $BFFF
5000FIND THE LINE THAT HOLDS ADDRESS R4: THE LAST LINE IN THE LINE NUMBER FILE THAT STARTS BELOW IT
READ THE LINE NUMBER FILE FROM THE START
EACH RECORD UNTIL ONE STARTS AT OR ABOVE THE ADDRESS
LN IS NUMBER OF THE LINE THAT HOLDS IT
U6 IS A LINE NUMBER READ FROM THE LINE NUMBER FILE
5100AT A VARIABLE REFERENCE IN THE FILE: READ ITS OPERATION BYTE INTO OU AND ITS LINK INTO R3, THEN POSITION THE FILE FOR WRITING THE CALL OVER THEM
THE FILE POSITION OF THE REFERENCE
OU = THE OPERATION
5200AT A CHAINED WORD IN THE FILE: READ THE LINK INTO R3, THEN POSITION THE FILE FOR WRITING OVER IT
THE FILE POSITION
DOS WRITE WITH A BYTE POSITION, RELATIVE TO THE FILE'S START
5300READ A WORD (LOW BYTE FIRST) INTO R3; 5300 RETURNS IT AS A STORED VALUE (-32767)
R3 IS WORD JUST READ
LOW BYTE ...
... AND HIGH BYTE
5500POSITION THE OBJECT FILE FOR READING AT FO
DOS READ WITH A BYTE POSITION
5600READ A BYTE INTO OW
THE ROUTINE AT $037E READS A BYTE OF THE OPEN FILE INTO $0376
5640TOO LONG: THE PROGRAM, ITS VARIABLES OR THE REFERENCE LIST DO NOT FIT
5660COMPILATION TERMINATED: DELETE THE OBJECT FILE
CLOSE AND DELETE THE UNFINISHED OBJECT FILE
5800REPORT A FATAL ERROR: END THE DIRECT FILE INPUT OR OUTPUT FIRST
DOS'S OUTPUT STATE 5, AND A CONTROL-D ENDS THE DIRECT FILE INPUT OR OUTPUT
TWO BELLS
5900THE MOTOR SWITCHES OF THE SLOT DOS USED LAST
$C089 + SLOT*16 ($AA6A IS THE SLOT DOS USED LAST)
KEEP THE DRIVE RUNNING
6000STOP THE MOTOR AND CLOSE ALL FILES
STOP THE MOTOR
Variables
| NAME | TYPE | DEFINED | COMMON | MEANING |
|---|---|---|---|---|
| AK | INTEGER | 40 | ADDRESS BEING COUNTED (COMMON ALLOCATION), SIZE OF THE ROUTINE AREA, START OF THE PAGE BEING PATCHED | |
| BP$ | STRING | 110 | 37 | TWO BELLS, SOUNDED BEFORE EACH ERROR MESSAGE |
| C3 | INTEGER | 30 | 34 | COMMON KIND: -1 NONE, 0 DEFINE, 255 USE |
| CC | INTEGER | 90 | 25 | ADDRESS OF THE LINK WORD OF THE LAST DATA BLOCK (DATA BLOCKS ARE CHAINED) |
| CD | INTEGER | 40 | 24 | START OF THE COMMON BLOCK (THE PROGRAM START BEFORE COMMON MOVED IT) |
| CO$ | STRING | 110 | 40 | DOS CLOSE COMMAND |
| CP | INTEGER | 80 | ADDRESS OF THE LAST BYTE OF CODE | |
| CY | INTEGER | 40 | COMMON PASS (0 NUMBERS, 1 STRINGS); ALSO AN OPERATION OR DIMENSION INDEX | |
| DG | INTEGER | 80 | WHICH DISPATCHER: 0 REAL, 1 STRING, 2 INTEGER, 3-5 REAL, STRING AND INTEGER ARRAYS, 6-10 LOOP STARTS AND NEXT | |
| DI$ | STRING | 110 | 38 | CONTROL-D, THE DOS COMMAND PREFIX |
| DN(10,1) | INTEGER() | 100 | DISPATCHER ADDRESSES: DN(I,0) LOW BYTE, DN(I,1) HIGH BYTE | |
| DN$ | STRING | 110 | 46 | SLOT AND DRIVE OF THE BOOT DRIVE (",S6,D1") |
| DP(5,1) | INTEGER() | 100 | 35 | DOS PATCH TABLE: DP(I,0) ADDRESS (AS A SIGNED WORD, ADDRESS-65536), DP(I,1) ORIGINAL BYTE |
| DW | INTEGER | 50 | 10 | DOS STATE BYTE AT $AA52: POKED BEFORE EACH DIRECT FILE READ OR WRITE |
| ED | INTEGER | 90 | 26 | OBJECT FILE BASE: FILE POSITION = PC - ED (THE FILE STARTS WITH THE BSAVE HEADER) |
| EL | INTEGER | 10 | 11 | LIBRARY ROUTINE ($0947) THAT RESETS THE STACK, DROPPING EVERY PENDING GOSUB AND FOR, AND RESETS THE DATA POINTER; CALLED AFTER AN ERROR |
| EU | INTEGER | 60 | SYMBOL TABLE ENTRY BEING WORKED ON | |
| FC | INTEGER | 30 | 33 | 1 ONCE A FATAL ERROR HAS BEEN REPORTED (NO MORE CODE IS WRITTEN) |
| FO | REAL | 3190 | FILE POSITION OF A REFERENCE | |
| GD | INTEGER | 50 | GAP OF THE SORT; ALSO A POWER OF TWO | |
| GG(1) | INTEGER() | 100 | GG(0) = LAST INDEX OF THE LINE AND FUNCTION PAIRS IN RL(), GG(1) = LAST INDEX OF THE NUMERIC ROUTINE GROUPS | |
| H4 | REAL | 3050 | HIGHEST MEMORY ADDRESS USED | |
| HD | INTEGER | 60 | HIGHEST OPERATION OF A VARIABLE ROUTINE (-1 FOR NONE); ALSO AN INDEX IN THE SORT | |
| HW | INTEGER | 60 | 7 | LAST CHAIN HEAD IN SC(); ENTRIES ARE ALLOCATED ABOVE IT |
| IX | INTEGER | 80 | 17 | ADDRESS OF THE ONE-BYTE TRANSFER CELL FOR QB AND WS ($0376) |
| K1 | REAL | 1740 | NEXT FREE ADDRESS FOR LOCAL VARIABLES | |
| K8 | INTEGER | 50 | LOOP INDEX; ALSO THE INDEX IN RL() | |
| KV | INTEGER | 30 | 14 | ADDRESS OF THE FIVE PACKED BYTES LEFT BY THE USR ROUTINE ($0371) |
| KX | INTEGER | 100 | 5 | FIRST CONSTANT CHAIN HEAD IN SC() |
| L | INTEGER | 100 | 6 | FIRST LINE NUMBER CHAIN HEAD IN SC() |
| L1 | INTEGER | 40 | SCRATCH: A LINE NUMBER, AN ELEMENT SIZE, AN OPERATION MASK | |
| L8 | INTEGER | 60 | CHAIN INDEX; ALSO A TYPE CODE | |
| LB | INTEGER | 40 | 19 | LIBRARY ADDRESS, STORED AS ADDRESS-32767 |
| LH | INTEGER | 40 | 23 | NUMBER OF SOURCE LINES READ |
| LM | INTEGER | 70 | 12 | LENGTH OF THE RUNTIME LIBRARY IN BYTES (4013) |
| LN | REAL | 5030 | NUMBER OF THE LINE THAT HOLDS IT | |
| LN$ | STRING | 110 | 45 | NAME OF THE LINE NUMBER FILE ("CLINENUM") |
| LQ | INTEGER | 60 | 18 | ADDRESS OF THE ROUTINE THAT LISTS THE TOKENIZED LINE IN THE INPUT BUFFER ($038D) |
| MM(5) | REAL() | 120 | MEMORY LAYOUT FOR THE HEADER: MM(0) LOCALS START-1, (1) END OF NUMERIC LOCALS, (2) END OF STRING LOCALS, (3) COMMON START-1, (4) END OF NUMERIC COMMON, (5) END OF STRING COMMON | |
| MN | INTEGER | 10 | 9 | DRIVE MOTOR-OFF SWITCH FOR THE BOOT SLOT |
| MX | INTEGER | 60 | 8 | DRIVE MOTOR-ON SWITCH FOR THE BOOT SLOT ($C089+SLOT*16), TOUCHED TO KEEP THE DRIVE SPINNING |
| N1 | INTEGER | 20 | 30 | RESUME/DEBUG CODE OPTION (1 = YES) |
| NG | INTEGER | 60 | 2 | NUMBER OF CONSTANT HASH CHAINS (32) |
| NI | INTEGER | 90 | SCRATCH: COUNT OF LINE NUMBER RECORDS READ, THE PASS OVER THE SYMBOLS (1 NUMBERS, 2 ARRAYS, 3 STRINGS), A KEY | |
| NK | INTEGER | 60 | 3 | NUMBER OF LINE NUMBER HASH CHAINS (32) |
| NR | INTEGER | 50 | NUMBER OF VALUES IN RL() | |
| NU | INTEGER | 60 | 1 | NUMBER OF VARIABLE HASH CHAINS IN THE SYMBOL TABLE (32) |
| O4 | INTEGER | 20 | 28 | COMPILATION LISTING OPTION (1 = YES) |
| OD$ | STRING | 110 | 44 | OBJECT FILE NAME |
| OH | INTEGER | 60 | 32 | INTEGER CONSTANTS OPTION (1 = YES) |
| OO | INTEGER | 20 | 29 | PAUSE ON ERRORS OPTION (1 = YES) |
| OO$ | STRING | 110 | 48 | SLOT AND DRIVE OF THE OBJECT FILE |
| OP$ | STRING | 110 | 39 | DOS OPEN COMMAND |
| OU | INTEGER | 80 | OPERATION NUMBER READ AT A REFERENCE | |
| OW | INTEGER | 80 | BYTE TO WRITE TO THE OBJECT FILE (OR JUST READ) | |
| P8 | INTEGER | 20 | 31 | INTEGER ARITHMETIC OPTION (1 = YES) |
| PB | REAL | 1750 | LAST ADDRESS OF THE PROGRAM (CODE, CONSTANTS AND ROUTINES) | |
| PC | INTEGER | 90 | 22 | ADDRESS OF THE NEXT OBJECT CODE BYTE, AS ADDRESS-32767 |
| Q9 | INTEGER | 90 | SIZE OF RL() (5900 VALUES) | |
| QB | INTEGER | 30 | 15 | ADDRESS OF THE ROUTINE THAT READS ONE BYTE FROM THE OPEN FILE INTO IX ($037E) |
| QF | INTEGER | 100 | PREVIOUS ENTRY (FOR UNLINKING); ALSO THE END OF THE CODE | |
| R3 | REAL | 5310 | WORD JUST READ | |
| R4 | INTEGER | 50 | ADDRESS OF A REFERENCE TO REPORT | |
| R9 | INTEGER | 60 | VALUE TO ADD TO RL() | |
| RL(5900) | INTEGER() | 100 | REFERENCE LIST: FOR EACH LINE, FUNCTION AND DATA CHAIN A PAIR (LATEST REFERENCE, TARGET); FOR EACH NUMERIC VARIABLE OR CONSTANT ITS LATEST REFERENCE, STORAGE ADDRESS, ENTRY COUNT (NEGATIVE FOR AN INTEGER) AND ROUTINE ENTRIES; FOR EACH STRING VARIABLE OR ARRAY ITS LATEST REFERENCE AND ROUTINE ADDRESS | |
| RV$ | STRING | 110 | 41 | DOS READ COMMAND |
| SB$ | STRING | 110 | 47 | SLOT AND DRIVE OF THE SOURCE FILE |
| SC | INTEGER | 10 | 27 | 1 IF THE SOURCE AND OBJECT FILES ARE ON THE BOOT DRIVE (MOTOR KEPT ON), ELSE 0 |
| SC(5350) | INTEGER() | 10 | 36 | SYMBOL TABLE: CHAIN HEADS, THEN ENTRIES LINKED THROUGH THEIR FIRST WORD |
| SI$ | STRING | 110 | 43 | SOURCE FILE NAME |
| T3 | INTEGER | 70 | TYPE CODE: -3 REAL, -2 STRING, -1 INTEGER, 19-21 ARRAYS | |
| T9 | REAL | 1120 | SCRATCH: A SIZE, A PRODUCT, THE FILE BASE | |
| U6 | REAL | 5030 | A LINE NUMBER READ FROM THE LINE NUMBER FILE | |
| UF | REAL | 1810 | STORAGE ADDRESS OF THE VARIABLE; ALSO A VALUE READ FROM THE DATA TABLE | |
| UR | INTEGER | 90 | 20 | PROGRAM START, STORED AS ADDRESS-32767; MOVED UP BY COMMON DECLARATIONS |
| UV | INTEGER | 60 | 13 | ADDRESS OF THE USR ROUTINE THAT PACKS A NUMBER INTO FIVE BYTES ($0377) |
| VC | INTEGER | 40 | 21 | VARIABLES ADDRESS ASKED FOR, AS ADDRESS-32767, OR -32767 FOR END OF PROGRAM |
| VO | INTEGER | 70 | 4 | FIRST VARIABLE CHAIN HEAD IN SC() (9; 1-4 HOLD FN AND LINE SYMBOLS, 5-8 TEMPORARIES) |
| VZ | INTEGER | 70 | TYPE CODE AS STORED (50 HIGHER FOR COMMON, 47/49 FOR A REAL/INTEGER CONSTANT) | |
| W | REAL | 2830 | WORD TO WRITE | |
| WO$ | STRING | 110 | 42 | DOS WRITE COMMAND |
| WS | INTEGER | 30 | 16 | ADDRESS OF THE ROUTINE THAT WRITES THE BYTE IN IX TO THE OPEN FILE ($0387) |
| Y$ | STRING | 200 | THE ANSWER TO THE REPORT QUESTION | |
| FN HB | REAL | HIGH BYTE OF X | ||
| FN LO | REAL | LOW BYTE OF X | ||
| FN UB | REAL | THE ADDRESS STORED AS X (X+32767) | ||
| FN BI | REAL | ADDRESS X AS IT IS STORED (X-32767) | ||
| FN TY | REAL | TYPE CODE X WITHOUT THE COMMON MARK (X-50 ABOVE 21) | ||
| FN LG | REAL | THE NUMBER OF THE HIGHEST BIT SET IN X (FLOOR OF LOG2) | ||
| X | REAL | PARAMETER OF THE DEF FN FUNCTIONS (EACH FUNCTION HAS ITS OWN) |