Classic Computer Magazine Archive A.N.A.L.O.G. ISSUE 78 / NOVEMBER 1989 / PAGE 15

THE BASIC
  UTILITIES
 PACKAGE

by Barry Kolbe

    With the BASIC Utilities Package, you can program in BASIC and still access the disk functions like: directory, locking files, deleting files. Normally, to do these functions you would have to save your program, type DOS and wait until DUP.SYS loaded in. Then it was back to BASIC, reload your program, etc. With BUP.SYS you merely type "DIR" for a disk directory. That's all there is to it. Your program remains intact. And that's not all. You also get automatic line numbering and renumbering, not to mention decimal and hex conversions at your fingertips. And there's more! List the variables in your program and their line numbers, and trace your program while it is running.

Typing it in
    BUP.SYS is a machine-language program and must be typed in using the M/L Editor, found elsewhere in this issue. Listing 1 is the data that will create your copy of the BASIC Utilities Package. You should type it using the M/L Editor, found elsewhere in this issue, and name the resulting file AUTORUN.SYS.

Loading BUP.SYS
    The BASIC Utilities Package will load automatically when you boot your computer with a disk containing DOS and the AUTORUN.SYS file you created from Listing 1. The message "BASIC Utilities Package" will appear, followed by the BASIC prompt "READY." BUP.SYS remains in memory until you type DOS or turn the computer off.

BUP.SYS Commands
    BUP.SYS supports 13 commands, shown in format form below:

DIR
PRO "D::filespec.ext
UNP "D::filespec.ext
NAM "D::filespecl.ext,filespec2.ext
ERA "D::fiiespec.ext
REN [nnnn,nnnn]
NUM [nnnn,nnnn]
TRA
OFF
DEC nnnn
HEX [$]nnnn
LVA
DOS

    All commands are three letters in length, with no spaces allowed in the first three letters. After the first three letters, spaces are removed. For example, HEX $ A0 00 is crunched down to HEX$A0000.
    DIR gives a listing of the disk directory.
    PRO, UNP, NAM and ERA are filemanagement commands. They lock (protect), unlock (unprotect), rename and erase files on disk. Think carefully before using ERA-you are not asked if you are sure! Once you hit Return, your file is erased.
    REN is the renumber command. The first number following REN is the new starting line number and the second is the increment between lines. For example, REN 100,10 makes the first program Line 100, the next 110, the next 120 and so on. More on REN later. Typing REN [Return] gives default values of 10 and 10.
    NUM is the auto line-numbering command. As in REN, the first number is the first line number and the second is the increment between lines. The default values are 10 and 10 if you type NUM [Return]. If a program is in memory, NUM [Return] will start numbering at the last line (plus the increment, of course). To stop auto linenumbering, hit the break key. Do not press Reset! Disastrous things may happen if you do.
    NUM will not allow you to type over an already existing line. For example, if Line 100 exists and you type NUM 100,10, no auto line-numbering will be done. No message appears, just the READY prompt. Even while NUM is in operation, it will quit if you are about to type over an existing line.
    TRA allows you to trace a BASIC program. When you type TRA [Return] an extra display line is set up above the normal screen. The message "EXECUTING LINE: 032768" is displayed on this line. When you run a BASIC program, this message is updated 60 times a second during the vertical blank. Consequently, it may be a blur at times. Infinite loops are easy to spot. Trace works in any graphics mode. It will stay in effect until you remove it by typing OFF [Return]. Trace uses the immediate vertical blank interrupt, so don't use Trace if your program also uses that interrupt vector.
    OFF turns off the Trace function and removes the extra display line. I would recommend turning it off before performing disk commands. Whenever BUP.SYS uses the disk drive, it automatically turns TRACE off.
    DEC converts any decimal number from 0 to 65535 to its hex equivalent. If you type in anything other than a whole number in this range, the result should not be trusted.
    HEX converts any four-digit hex number to its decimal equivalent. A "$" is optional. For example: HEXA000 and HEX$A000 are both acceptable.
    LVA lists the variables in your BASIC program and the line numbers in which they appear.
    Now that we've covered the basic commands, we must turn our attention back to renumber.
    REN, in addition to renumbering the program lines, renumbers internal line references. There are nine program statements that can use line numbers. They and their BASIC tokens are:


Statement Token

LIST
GOTO
GO TO
GOSUB
TRAP
RESTORE
IF(THEN)
ON(GOTO)
ON(GOSUB)
4
10
11
12
13
35
7(...27)
30( ... 23)
30(...24)

    De Re Atari has a nice explanation of tokenized BASIC. ANALOG issues 25 and 26 also have articles on this subject. Each statement can be followed by a line number(s), variable(s) or algebraic expression(s). For example:


1) GOTO 1050
2) LIST 1040,1100
3) GOSUB N4
4) REST0RE 240+0
5) TRAP 15*P
6) ON Z GOSUB 20,N,25,6*T,30
7) ON T GOTO 1000,1100,1200,1300

    The numbers or expressions following the statements are internal line references; REN cannot decipher all of these. REN will only renumber an internal line reference if it is an actual number. Only in examples 1, 2 and 7 would all internal lines be renumbered. The others would cause a message to be sent to the screen.
    The three conditions and their messages are shown in Table 1.

CONDITION    MESSAGE

1. A renumbered line would be > =32768. No renumbering done.    Line > = 32768.
2. An internal line number cannot be found. It is not renumbered.    NF-100
3. An internal line reference is a variable or contains a variable.    VR-540
Table 1


    To remedy the first condition, choose a smaller first line number and/or a smaller increment. The second condition means that you are missing a program line. For example, Line 100 might be "100 GOTO 2000" when Line 2000 doesn't exist.
    The last type is the most frustrating to deal with. Examples 3, 4, 5 and 6 from above would result in a VR-line number message. Whenever REN encounters one of those special nine tokens, it checks whether it is followed by a line number. If it is a line number, that line number is renumbered. If not, a VR message is given.
    If a list of line numbers, separated by commas, is possible (types 2, 6 and 7), these are renumbered until a variable is encountered. If a variable is found, all renumbering on that statement is halted and the next statement on the line or the next line is checked for one of the nine tokens. Again, the VR message would be sent to the screen. In example 6, the 20 would be renumbered, but no others, not even the 25 or 30.
    A TRAP statement with a line greater than 32767 would also give an NF message, but this type of TRAP is used to shut off a previous TRAP and so doesn't need to be renumbered.
    If LIST is not followed by a line number, it is listed as a VR. This doesn't represent a problem.
    Except for the exceptions just noted, all lines printed on the screen with either NF or VR need to be examined and any necessary changes made. Save a copy of the unrenumbered program in case you need to check line numbers.
    The message "Program renumbered" is displayed on the screen when the process is complete. It should not take more than a few seconds.

Anomalies
    Some unusual things have happened to me while using BUP.SYS. An IF-THEN statement, such as "20 IF I$=`R' THEN POP:GOTO 240" resulted in a VR-20 message when I renumbered it. Even though Line 240 existed, the message VR ( NF) was sent to the screen. I'll try to explain why. In tokenized BASIC, following the token for THEN is a number (zero-255), which gives the offset to the next statement on the line. REN checks the token after the THEN token to see whether it is a line number. The token for a number is 14. Guess what the offset to the next statement is in Line 20. Yes, it is 14! The same as the token for a number. Since POP is not a number, the VR message was printed.
    Originally, I used UNL as the command to UNLOCK files. I changed it to UNP so it is more like DOS XL. One Saturday my son, Philip, was trying out BUP.SYS. Needless to say, he was impressed! Then Phil decided to work with Clayton Walnum's programs from "Adventurous Programming." He got to the point where he was to "UNLOCK DOOR." The screen looked like this:

WHAT NOW? UNLOCK DOOR
ERROR # 146
READY
WHAT NOW?

    Remember that BUP.SYS parses (scans) all inputs before passing them on to BASIC. BUP.SYS thought he was trying to UNLOCK a file! We changed the verb to KEY to make the program work with BUP.SYS. It was also interesting to watch the program work with the TRACE function.

Technical Notes
    BUP.SYS is a BASIC Utilities Package, so the BASIC cartridge must be present to use it. BUP.SYS loads at $2000 and moves LOMEM to $2AFB, using 2,811 bytes of memory. After loading, BUP.SYS clears the stack and jumps to the BASIC cartridge. If BASIC is not there, there will certainly be a lockup. In the initialization process, it wedges itself into the editor's Get-Byte routine. By doing this, an immediate-mode command is scanned by BUP.SYS before sending it to BASIC. In this way, BUP.SYS can take control if the command is one it recognizes. The Put-Byte routine is used to print messages on the screen.
    BUP.SYS works fine with DOS 2.0 and 2.5, but has serious problems with DOS XL and perhaps others. Two vertical blanks are used. One is for the TRACE command. The other is used by auto line-numbering. BUP. SYS is "protected" from Reset to prevent its erasure. But if I were you, I would not press Reset while using auto numbering, renumber or TRACE. I shudder to think of a program that is partially renumbered. Any other time, pressing Reset should present no difficulty. If you do get stuck, typing X=USR(8192) will probably fix things by reinitializing BUP.SYS.

Conclusion
    I think you'll agree that a program like BUP.SYS has been needed for some time. I hope it will make your programming easier.

Barry Kolbe


    Barry Kolbe is part of the BBKprogramming team, which is responsible for such ANALOG programs as The BBK Artist, The BBK Monitor and The ANALOG Database. He is a teacher in Wisconsin.


LISTING 1:

1000 DATA 255,255,0,32,64,42,216,173,4
8,2,141,66,42,173,49,2,1891
1010 DATA 141,67,42,165,12,141,188,32,
165,13,141,189,32,173,36,2,3393
1020 DATA 141,137,42,173,37,2,141,138,
42,169,32,133,13,169,187,133,6025
1030 DATA 12,169,0,141,136,42,141,82,4
2,141,65,42,160,0,185,26,2797
1040 DATA 3,201,69,240,8,200,200,200,1
92,33,208,242,96,200,169,168,3373
1050 DATA 153,26,3,200,169,42,153,26,3
,160,0,185,0,228,153,168,6462
1060 DATA 42,200,192,16,208,245,169,20
8,141,172,42,169,32,141,173,42,8635
1070 DATA 24,173,4,228,105,1,141,210,3
2,173,5,228,105,0,141,211,7227
1080 DATA 32,173,6,228,24,105,1,141,20
0,32,173,7,228,105,0,141,5070
1090 DATA 201,32,169,42,141,232,2,169,
248,141,231,2,169,144,141,198,1196
1100 DATA 2,162,28,189,247,41,32,193,3
2,32,178,32,32,178,32,202,5085
1110 DATA 16,241,162,255,154,76,0,160,
169,0,133,20,165,20,240,252,8901
1120 DATA 96,32,255,255,76,35,32,142,7
5,42,140,76,42,32,255,255,7461
1130 DATA 174,75,42,172,76,42,96,32,25
5,255,8,192,128,240,31,201,9770
1140 DATA 155,240,60,142,94,42,174,92,
42,224,255,208,8,162,0,142,7762
1150 DATA 136,42,142,92,42,174,94,42,2
38,136,42,76,23,33,169,0,2584
1160 DATA 141,64,42,141,82,42,141,136,
42,141,135,42,169,7,172,137,5700
1170 DATA 42,174,138,42,32,92,228,32,8
1,210,76,134,33,40,96,173,5256
1180 DATA 82,42,208,218,173,64,42,240,
21,169,5,141,134,42,169,1,4812
1190 DATA 141,135,42,169,0,133,194,141
,136,42,169,155,40,96,140,77,6246
1200 DATA 42,142,78,42,162,255,142,92,
42,160,0,140,81,42,172,81,5173
1210 DATA 42,162,0,189,128,5,217,240,3
3,208,77,200,232,189,128,5,9727
1220 DATA 217,240,33,208,67,200,232,18
9,128,5,217,240,33,208,57,200,1384
1230 DATA 185,240,33,141,132,33,200,18
5,240,33,141,133,33,172,136,42,7482
1240 DATA 169,155,153,128,5,216,32,185
,33,76,255,255,160,0,132,195,9817
1250 DATA 140,136,42,169,46,153,128,5,
200,169,155,153,128,5,174,78,7171
1260 DATA 42,172,77,42,169,155,40,96,1
73,81,42,24,105,5,141,81,2831
1270 DATA 42,201,65,208,153,172,136,42
,169,155,153,128,5,208,223,162,1030
1280 DATA 0,189,128,5,201,155,240,3,23
2,16,246,142,167,42,162,0,7548
1290 DATA 189,128,5,201,155,240,30,201
,32,208,20,138,168,185,129,5,7620
1300 DATA 153,128,5,200,204,167,42,208
,244,206,167,42,76,202,33,232,1124
1310 DATA 236,167,42,208,219,96,68,73,
82,49,34,69,82,65,203,34,3564
1320 DATA 80,82,79,207,34,85,78,80,211
,34,78,65,77,215,34,68,3981
1330 DATA 79,83,219,34,84,82,65,235,34
,79,70,70,32,35,78,85,1757
1340 DATA 77,3,41,82,69,78,197,37,68,6
9,67,11,36,72,69,88,452
1350 DATA 117,36,76,86,65,242,36,32,38
,35,32,152,34,162,80,169,3878
1360 DATA 3,157,66,3,169,6,157,74,3,16
9,42,157,69,3,169,204,5260
1370 DATA 157,68,3,32,86,228,16,2,48,6
2,162,80,169,20,157,72,3504
1380 DATA 3,169,0,157,73,3,169,42,157,
69,3,169,184,157,68,3,4073
1390 DATA 169,5,157,66,3,32,86,228,48,
30,162,0,169,9,141,66,2945
1400 DATA 3,169,20,141,72,3,142,73,3,1
69,42,141,69,3,169,184,4610
1410 DATA 141,68,3,32,86,228,16,194,32
,152,34,76,134,33,162,80,4294
1420 DATA 169,12,157,66,3,32,86,228,96
,72,32,152,34,32,38,35,761
1430 DATA 104,162,80,157,66,3,169,0,15
7,73,3,157,72,3,169,132,3942
1440 DATA 157,68,3,169,5,157,69,3,32,8
6,228,152,16,202,76,67,4620
1450 DATA 35,169,33,208,212,169,35,208
,208,169,36,208,204,169,32,208,2017
1460 DATA 200,173,188,32,133,12,173,18
9,32,133,13,32,38,35,76,116,2283
1470 DATA 228,173,65,42,208,45,238,65,
42,173,48,2,141,66,42,24,2334
1480 DATA 105,3,141,22,42,173,49,2,141
,67,42,105,8,141,23,42,361
1490 DATA 169,42,141,49,2,169,16,141,4
8,2,169,6,160,116,162,35,3703
1500 DATA 32,92,228,76,134,33,32,38,35
,76,134,33,173,67,42,141,3118
1510 DATA 49,2,173,66,42,141,48,2,169,
0,141,65,42,174,97,228,5691
1520 DATA 172,96,228,169,6,32,92,228,9
6,72,162,7,189,239,41,32,6314
1530 DATA 193,32,202,16,247,104,133,21
2,169,0,133,213,32,170,217,32,9046
1540 DATA 230,216,32,244,39,32,71,36,3
2,104,35,76,146,34,162,5,1955
1550 DATA 189,128,42,32,193,32,202,16,
247,96,165,66,240,3,76,95,6560
1560 DATA 228,173,48,2,201,16,208,7,17
3,49,2,201,42,240,33,173,6549
1570 DATA 48,2,141,66,42,24,105,3,141,
22,42,173,49,2,141,67,1301
1580 DATA 42,105,8,141,23,42,169,16,14
1,48,2,169,42,141,49,2,1160
1590 DATA 165,138,133,4,165,139,133,5,
160,0,177,4,141,72,42,200,5182
1600 DATA 177,4,141,73,42,169,0,141,68
,42,141,69,42,141,70,42,2505
1610 DATA 141,71,42,248,160,16,14,72,4
2,46,73,42,162,3,189,68,2797
1620 DATA 42,125,68,42,157,68,42,202,2
08,244,136,208,233,216,162,25,2574
1630 DATA 160,0,185,69,42,72,74,74,74,
74,9,16,157,24,42,232,2789
1640 DATA 104,41,15,9,16,157,24,42,232
,200,192,3,208,228,76,95,8225
1650 DATA 228,169,3,133,242,169,5,133,
244,169,128,133,243,32,0,216,33
1660 DATA 144,3,76,210,40,32,210,217,3
2,77,36,169,61,32,193,32,4606
1670 DATA 169,36,32,193,32,162,3,189,2
18,42,32,193,32,202,16,247,7930
1680 DATA 32,71,36,32,01,218,169,0,133
,242,76,134,33,169,155,32,6679
1690 DATA 193,32,96,160,3,162,1,142,94
,42,181,212,72,74,74,74,5072
1700 DATA 74,170,189,151,42,153,218,42
,136,104,41,15,170,189,151,42,6963
1710 DATA 153,218,42,136,174,94,42,202
,16,221,96,166,3,185,128,5,6272
1720 DATA 201,36,208,1,200,162,0,134,2
12,134,213,142,80,42,185,128,9411
1730 DATA 5,162,15,221,151,42,240,5,20
2,16,248,48,48,142,78,42,5451
1740 DATA 6,212,38,213,6,212,38,213,6,
212,38,213,6,212,38,213,8580
1750 DATA 216,24,165,212,109,78,42,133
,212,165,213,105,0,133,213,200,1146
1760 DATA 238,80,42,173,80,42,201,4,24
0,3,76,136,36,173,80,42,4487
1770 DATA 208,3,76,210,40,32,170,217,3
2,230,216,169,61,32,193,32,8010
1780 DATA 162,0,189,128,5,72,41,127,32
,193,32,232,104,16,243,32,5868
1790 DATA 71,36,32,81,218,76,134,33,16
5,130,133,2,165,131,133,3,5395
1800 DATA 169,127,141,93,42,165,3,197,
133,208,9,165,2,197,132,208,9263
1810 DATA 3,76,134,33,160,0,177,2,72,4
1,127,32,193,32,230,2,3832
1820 DATA 208,2,230,3,104,16,237,32,71
,36,165,136,133,0,165,137,6107
1830 DATA 133,1,169,0,141,91,42,238,93
,42,32,186,37,133,232,32,6097
1840 DATA 186,37,133,233,201,128,144,6
,32,71,36,76,255,36,32,186,5841
1850 DATA 37,32,186,37,32,186,37,201,2
,176,9,32,186,37,201,155,6492
1860 DATA 208,249,240,214,32,186,37,20
1,20,248,230,201,27,240,226,201,5124
1870 DATA 22,240,199,201,14,208,10,162
,6,32,186,37,202,208,250,240,2449
1880 DATA 227,201,15,208,6,32,186,37,1
70,208,238,205,93,42,208,212,2203
1890 DATA 165,232,133,212,165,233,133,
213,32,170,217,32,230,216,238,91,4423
1900 DATA 42,173,91,42,281,6,208,8,169
,0,141,91,42,32,71,36,2089
1910 DATA 32,244,39,169,32,32,193,32,2
00,192,6,208,246,76,94,37,7728
1920 DATA 168,0,177,0,230,0,208,2,230,
1,96,32,3,40,32,71,968
1930 DATA 36,162,3,142,91,42,32,14,38,
216,160,1,177,203,201,128,8390
1940 DATA 176,70,165,206,201,128,176,3
0,165,205,24,101,207,133,205,165,2099
1950 DATA 206,101,208,133,206,200,177,
203,24,101,203,133,203,165,204,105,335
1
1960 DATA 0,133,204,76,212,37,162,13,1
89,114,42,32,193,32,202,16,5592
1970 DATA 247,76,134,33,165,136,133,20
3,165,137,133,204,96,173,254,6,1441
1980 DATA 133,205,173,255,6,133,206,96
,32,14,38,32,23,38,160,0,1561
1990 DATA 177,203,133,232,200,177,203,
133,233,201,128,144,3,76,147,38,9606
2000 DATA 200,177,203,141,89,42,200,17
7,203,141,90,42,200,177,203,162,2686
2010 DATA 5,221,83,42,208,3,76,221,38,
202,16,245,201,7,208,3,7589
2020 DATA 76,159,39,281,30,208,3,76,14
3,39,173,90,42,205,89,42,5445
2030 DATA 240,9,168,177,203,141,90,42,
76,70,38,24,173,89,42,101,4158
2040 DATA 203,133,203,165,204,105,0,13
3,204,24,165,205,101,207,133,205,2329
2050 DATA 165,206,101,208,133,206,76,4
0,38,32,14,38,32,23,38,160,1655
2060 DATA 1,177,203,201,128,208,14,162
,18,189,95,42,32,193,32,202,7541
2070 DATA 16,247,76,134,33,136,173,254
,6,145,203,173,255,6,200,145,2100
2080 DATA 203,24,173,254,6,101,207,141
,254,6,173,255,6,101,208,141,1256
2090 DATA 255,6,200,177,203,24,101,203
,133,203,165,204,105,0,133,204,1269
2100 DATA 76,153,38,200,177,203,201,14
,240,3,76,90,39,140,74,42,5373
2110 DATA 152,24,105,7,168,177,203,201
,18,240,8,201,20,240,4,201,9542
2120 DATA 22,208,231,172,74,42,32,181,
39,165,136,133,228,165,137,133,783
2130 DATA 229,173,254,6,133,212,173,25
5,6,133,213,160,1,177,228,201,3453
2140 DATA 128,240,96,197,227,208,26,13
6,177,228,197,226,208,19,32,170,2399
2150 DATA 217,32,205,39,200,177,203,20
1,18,208,3,76,221,38,76,100,7625
2160 DATA 38,160,2,177,228,24,l01,228,
133,228,165,229,105,0,133,229,2111
2170 DATA 24,165,212,101,207,133,212,1
65,213,101,208,133,213,76,21,39,9784
2180 DATA 169,86,32,193,32,169,82,32,1
93,32,169,45,32,193,32,165,6087
2190 DATA 205,133,212,165,206,133,213,
32,170,217,32,230,216,32,221,39,1539
2200 DATA 76,100,38,169,78,32,193,32,1
69,70,32,193,32,169,45,32,4313
2210 DATA 193,32,76,105,39,200,177,203
,201,23,208,3,76,221,38,201,9684
2220 DATA 24,240,249,208,240,200,177,2
03,201,27,208,249,200,177,203,201,8260
2230 DATA 14,208,4,136,76,221,38,136,7
6,70,38,162,8,200,177,203,8725
2240 DATA 149,212,232,224,6,208,246,32
,210,217,165,212,133,226,165,213,6856
2250 DATA 133,227,96,172,74,42,162,0,2
00,181,212,145,203,232,224,6,2594
2260 DATA 208,246,96,32,244,39,169,32,
32,193,32,174,91,42,202,16,5984
2270 DATA 5,32,71,36,162,3,142,91,42,9
6,160,255,200,177,243,72,1279
2280 DATA 41,127,32,193,32,104,16,244,
96,32,16,48,160,3,185,128,5076
2290 DATA 5,201,155,208,88,96,169,10,1
41,254,6,133,205,133,207,169,2080
2300 DATA 0,141,255,6,133,208,133,206,
96,32,16,40,32,14,38,160,3445
2310 DATA 1,177,203,16,1,96,133,1,136,
177,203,133,0,32,92,41,4165
2320 DATA 160,1,177,203,16,240,165,0,2
4,101,207,141,254,6,133,205,356
2330 DATA 165,1,105,0,141,255,6,133,20
6,96,216,173,254,6,56,229,1309
2340 DATA 207,141,254,6,173,255,6,229,
208,141,255,6,96,162,0,185,519
2350 DATA 128,5,201,44,240,16,201,155,
240,12,157,210,42,232,224,6,987
2360 DATA 240,84,200,76,105,40,157,210
,42,140,79,42,169,0,133,242,8431
2370 DATA 133,205,32,199,40,32,0,216,3
2,210,217,176,57,165,213,48,9826
2380 DATA 53,141,255,6,133,206,165,212
,141,254,6,133,205,172,79,42,657
2390 DATA 185,128,5,201,155,208,1,96,1
62,8,200,185,128,5,201,155,9555
2400 DATA 240,39,157,210,42,232,224,6,
240,12,76,180,40,169,210,133,687
2410 DATA 243,169,42,133,244,96,104,10
4,162,11,189,139,42,32,193,32,6721
2420 DATA 202,16,247,32,81,218,76,134,
33,157,210,42,169,0,133,242,9585
2430 DATA 32,199,40,32,0,216,32,210,21
7,176,219,165,212,133,207,165,4773
2440 DATA 213,133,208,48,209,32,81,218
,96,32,35,40,169,0,141,64,4668
2450 DATA 42,32,14,38,168,0,177,203,13
3,226,200,177,203,133,227,48,2868
2460 DATA 27,205,255,6,240,8,176,20,32
,92,41,76,14,41,165,226,5744
2470 DATA 205,254,6,240,4,176,5,144,23
9,76,134,33,32,84,40,169,6101
2480 DATA 7,160,132,162,41,32,92,228,3
2,81,218,169,10,141,134,42,7026
2490 DATA 169,0,133,194,141,136,42,169
,1,141,135,42,141,64,42,76,4984
2500 DATA 134,33,132,230,160,2,177,203
,216,24,101,203,133,203,165,204,3732
2510 DATA 105,0,133,204,164,230,96,32,
92,41,132,230,160,0,177,203,391
2520 DATA 133,226,200,177,203,133,227,
164,230,96,173,135,42,240,99,165,3711
2530 DATA 194,240,95,173,134,42,240,6,
206,134,42,76,236,41,169,0,7576
2540 DATA 141,135,42,173,254,6,24,101,
207,141,254,6,133,212,173,255,3562
2550 DATA 6,101,208,141,255,6,133,213,
165,213,48,26,197,227,240,8,1814
2560 DATA 144,31,32,113,41,76,178,41,1
65,212,197,226,240,8,144,17,9697
2570 DATA 32,113,41,76,178,41,238,82,4
2,169,12,141,252,2,76,236,8825
2580 DATA 41,32,170,217,32,230,216,32,
244,39,169,32,32,193,32,32,6310
2590 DATA 81,218,76,98,228,32,35,32,82
,79,82,82,69,155,101,103,5204
2600 DATA 97,107,99,97,80,32,115,101,1
05,116,105,108,105,116,85,32,5133
2610 DATA 67,73,83,65,66,125,112,112,6
6,24,42,1,0,0,0,0,7400
2620 DATA 0,0,0,0,0,0,0,37,56,37,35,53
,52,41,41,46,7412
2630 DATA 39,0,44,41,46,37,26,0,0,0,0,
0,0,0,0,0,3599
2640 DATA 0,0,0,0,0,0,0,83,42,88,42,10
,11,12,13,35,6210
2650 DATA 4,95,42,133,42,155,100,101,1
14,101,98,ie9,117,110,101,ii4,6972
2660 DATA 32,109,97,114,103,111,114,80
,155,56,54,55,50,51,32,61,2305
2670 DATA 62,32,101,110,105,76,155,89,
68,65,69,82,139,42,166,42,4879
2680 DATA 155,114,111,114,114,101,32,1
81,117,108,97,86,48,49,50,51,3168
2690 DATA 52,53,54,55,56,57,65,66,67,6
8,69,70,204,42,209,42,4764
2700 DATA 68,58,42,46,42,155,247,42,24
7,42,0,226,2,227,2,0,4988
2710 DATA 32,0,0,0,0,0,0,0,0,0,0,0,0,0
,0,0,2742


Listing 2:
Assembly


0100 ;SAVE#D:BUPP1.M65
0110 ;
0120 ;------------------;
0130 ; BUP.SYS part I   ;
0140 ;                  ;
0150 ;    (c) 1989      ;
0160 ; by Barry Kolbe   ;
0170 ;                  ;
0180 ;------------------;
0190     .OPT NO LIST
0200 ;
0210 ;equates
0220 ;
0230 LO  =   $00
0240 JO  =   $02
0250 EOL =   $9B     ;end of line
0260 LINENO = $E8    ;line number
0270 LINPTR = $CB    ;ptr to line #
0280 CLINE = SCD     ;current line
0290 ILINE = $CF     ;increment line
0300 FLINE = $06FE   ;first line
0310 RLINE = $E2     ;referenced line
0320 SPTR =  $E4     ;ptr. for seach
0330 SLINE = $E6     ;search line
0340 VNTP =  $82     ;var. name table
0350 STMTAB = $88    ;BASIC statmt.
0360 PROMPT = $C2    ;flag-BAIC done?
0370 CRITIC = $42    ;cirtical I/O
0380 ICCOM = $0342   ;command
0390 ICBAL = $0344   ;buff. address
0400 ICBAH = $0345
0410 ICBLL = $0348   ;buff. length
0420 ICBLH = $0349
0430 ICAUKI = $034A  ;aux. byte
0440 HATBAS = $031A  ;handler table
0450 LBUF =  $0586   ;input buffer
0460 MEMLO = $02E7   ;memlo
0470 DOSINI = $0C    ;disk init.
0480 DLISTL = $0230  ;display list
0490 DLISTH = $0231
0500 CIO =   $E456   ;cio vector
0510 F45C =  $DBE6   ;fp to ascii
0520 AFP =   $D800   ;ascii to fp
0530 IFP =   $D9AA   ;integer to fp
0540 FPI =   $D9D2   ;fp to integer
0550 FR0 =   $D4     ;fp register 0
0560 FR1 =   $D5
0570 SETLBF = $DA51  ;reset lbuf
0580 SETVBV = $E45C  ;set vert. blnk
0590 SY5VBV = $E45F  ;system vbi
0600 HITVBV = $E462  ;exit vbi
0610 INBUF = $F3     ;input buf. ptr
0620 CIX =   $F2     ;char, index
0630 WARMST = $E474  ;warnstart
0640 VVBLKD = $0224  ;deferred reg
0650 DOSVEC = $0A
0660 ;
0670     *=  $2000
0680 ;
0690 IN1 CLD
0700     LDA DLISTL  ;save orig
0710     STA DLS     ;display list
0720     LDA DLISTH  ;pointer
0730     STA DLH
0740     LDA DOSINI  ;save
0750     STA SYSRST+1 ;DOSINI
0760     LDA DOSINI+1
0770     STA SYSRST+2
0780 ;
0790 ;save immed.vbi vectors
0800 ;
0810     LDA VVBLKD
0820     STA VBLKDS
0830     LDA VVBLKD+1
0840     STA VBLKDS+1
0850 ;
0860 ;reset my SYSTEM RESET routine
0870 ;
0880 IN2 LDA # >SYSRST
0890     STA DOSINI+1
0900     LDA # <SYSRST
0910     STA DOSINI
0920 ;
0930 ;reset character counter
0940 ;
0950     LDA #0
0960     STA CHRCNT
0970     STA QTFLAG
0980     STA TFLG     ;trace flag
0990 ;
1000 ;find editor vectors
1010 ;search handler for E:
1020 ;
1030     LDY #0
1040 El  LDA HATBAS,Y
1050     CMP #'E
1060     BEQ E2      ;got.it
1070     INY
1080     INY
1090     INY
1100     CPY #33
1110     BNE E1
1120     RTS
1130 ;
1140 E2  INY         ;point to
1150     LDA # <MYEDIT ;my patch
1160     STA HATBAS,Y
1170     INY
1180     LDA # >MYEDIT
1190     STA HATBAS,Y
1200     LDY #0      ;copy system
1210 E3  LDA $E400,Y ;routines
1220     STA MYEDIT,Y ;to my
1230     INY         ;patch
1240     CPY #16
1250     BNE E3
1260 ;
1270 ;get byte vector
1280 ;
1290     LDA # <GETCOM-1 ;point it
1300     STA MYEDIT+4 ;to my
1310     LDA # >GETCOM-1 ;wedge
1320     STA MYEDIT+5
1330     CLC         ;put system
1340     LDA $E404   ;get byte
1350     ADC #1      ;at beginning
1360     STA GETCOM+1
1370     LDA $E405
1380     ADC #0
1390     STA GETCOM+2
1400 ;
1410 ;put byte vector
1420 ;
1430     LDA $E406   ;get vector
1440     CLC         ;vectors are
1450     ADC #1      ;always -1
1460     STA PUT1+1  ;add 1
1470     LDA $E407   ;install in
1480     ADC #0      ;my 'PUTC'
1490     STA PUT1+2  ;routine
1500     LDA # >ENDPRG ;set LOMEM
1510     STA MEMLO+l
1520     LDA # <ENDPRG
1530     STA MEMLO
1540 ;
1550     LDA #90     ;chang color
1560     STA 710
1570     LDX #28     ;say we are
1580 B1  LDA BB1,X   ;here!
1590     JSR PUTC
1600     JSR WAIT    ;wait a jiff
1610     JSR WAIT    ;maybe two
1620     DEX
1630     BPL B1
1640     LDH #$FF    ;clear stack
1650     TXS
1660     JMP $A000   ;jump to BASIC
1670 ;
1680 WAIT LDA #0     ;wait a jiffy
1690     STA 20
1700 WIT LDA 20
1710     BEQ WIT
1720     RTS
1730 ;
1740 ;handle SYSTEM RESET button
1750 ;
1760 SYSRST JSR $FFFF ;does DOSINI
1770     JMP IN2     ;reset
1780 ;
1790 ;print Accumulator via put byte
1800 ;
1810 PUTC STX XSAV   ;save X, Y
1820     STY PYSAV
1830 PUT1 JSR SFFFF  ;put byte
1840     LDX XSAV    ;restore X,Y
1850     LDY PYSAV
1860     RTS
1870 ;
1880 ;get bytes from editor
1890 ;
1900 GETCOM JSR $FFFF ;get a byte
1910     PHP         ;save status
1920     CPY #$80    ;break key
1930     BEQ BRK     ;yes
1940     CMP #EOL    ;RETURN?
1950     BEQ GOTRTI  ;yup
1960     STX X3      ;save X
1970     LDX LSTKEY  ;last key
1980     CPX #$FF    ;ret? =ff
1990     BNE KOK
2000     LDX #0      ;reset countr
2010     STX CHRCNT
2020     STX LSTKEY
2030 KOK LDX X3      ;get X
2040     INC CHRCNT
2050     JMP NOBRK   ;skip over
2060 ;
2070 BRK LDA #0      ;on break turn
2080     STA ONOFF   ;everything
2090     STA QTFLAG  ;OFF!
2100     STA CHRCNT
2110     STA ENDLIN
2120     LDA #7      ;restore vectors
2130     LDY VBLKDS  ;for VBI
2140     LDX VBLKDS+1
2150     JSR SETVBV
2160     JSR SETLBF  ;floating point
2170     JMP EXIT2   ;pointers
2180 ;
2190 NOBRK PLP       ;restore status
2200     RTS         ;done
2210 ;
2220 ;BASIC done with line
2230 ;
2240 ;PROMPT <> 0 when BASIC
2250 ;is done parsing a line
2260 ;endlin =0 means line
2270 ;not completely entered
2280 ;from BASIC
2290 ;
2300 GOTRTI LDA QTFLAG
2310     BNE BRK
2320     LDA ONOFF   ;autonum?
2330     BEQ NOTON   ;0= off
2340     LDA #5      ;VBI timer
2350     STA TIMER
2360     LDA #1
2370     STA ENDLIN
2380     LDA #0
2390     STA PROMPT  ;clear for
2400     STA CHRCNT  ;BASIC
2410     LDA #EOL
2420     PLP
2430     RTS
2440 ;
2456 ;autonum not on
2460 ;
2470 NOTON STY Y1    ;save regs
2480     STX X1
2490     LDX #SFF    ;last key
2500     STX LSTKEY
2510 ;
2520 ;Check command
2530 ;
2540     LDY #0
2550     STY CY1
2560 GTCM1 LDY CY1
2570     LDX #0
2580     LDA LBUF,X  ;first char
2590     CMP COMTAB,Y ;in table?
2600     BNE NOMAT
2610     INY
2620     INX
2630     LDA LBUF,X  ;try second
2640     CMP COMTAB,Y ;char
2650     BNE NOMAT
2660     INY
2670     INX
2680     LDA LBUF,X  ;try third
2690     CMP COMTAB,Y
2700     BNE NOMAT
2710 ;
2720 ;got match
2730 ;
2740     INY
2750     LDA COMTAB,Y
2760     STA TAKEOF+1 ;find addr
2770     INY         ;of my
2780     LDA COMTAB,Y ;routine
2790     STA TAKEOF+2
2800     LDY CHRCNT  ;stick in
2810     LDA #EOL    ;a RETURN
2820     STA LBUF,Y
2830     CLD
2840     JSR CRUNCH  ;smash spaces
2850 TAKEOF JMP SFFFF ;go to it
2860 ;
2870 ;exit routines
2880 ;
2890 EXIT2 LDY #0    ;show BASIC
2900     STY $C3     ;no error
2910     STY CHRCNT
2920     LDA #'.     ;REM
2930     STA LBUF,Y
2940     INY
2950     LDA #EOL    ;and EOL
2960     STA LBUF,Y
2970 EXIT1 LDX X1    ;restore X,Y
2980     LDY Y1      ;make a
2990     LDA #EOL    ;normal exit
3000     PLP
3010     RTS
3020 ;
3030 ;no match
3040 ;
3050 NOMAT LDA CY1   ;try next
3060     CLC         ;command
3070     ADC #5
3080     STA CY1
3090     CMP #$41    ;13 commands
3100     BNE GTCM1   ;@ 5 bytes
3110     LDY CHRCNT  ;each
3120     LDA #EOL    ;put in RETURN
3130     STA LBUF,Y
3140     BNE EXIT1   ;and exit
3150 ;
3160 ;crunch out spaces in input
3170 ;
3180 CRUNCH LDX #0   ;find the
3190 CR1 LDA LBUF,X  ;length
3200     CMP #EOL
3210     BEQ GOTEND  ;found it
3220     INX
3230     BPL CR1
3240 GOTEND STX ENDPTR ;save end
3250     LDX #0      ;now collapse
3260 SQUISH LDA LBUF,X ;it and
3270     CMP #EOL    ;remove spaces
3280     BEQ CR2
3290     CMP #$20    ;space?
3300     ONE NOSQSH  ;no squish
3310 DOSQSH TXA
3320     TAY         ;copy from
3330 SQSHLP LDA LBUF+1,Y ;back
3340     STA LBUF,Y  ;to front
3350     INY         ;next one
3360     CPY ENDPTR  ;done yet?
3370     BNE SQSHLP  ;no
3380     DEC ENDPTR  ;len=len-1
3390     JMP SQUISH  ;more
3400 N0505H INX      ;done yet
3410     CPX ENDPTR
3420     BNE SQUISH  ;no
3430 CR2 RTS         ;finished
3440 ;
3450 ;command table
3460 ;
3470 COMTAB .BYTE "DIR"
3480     .WORD DIR
3490     .BYTE "ERA"
3500     .WORD ERA
3510     .BYTE "PRO"
3520     .WORD LOCK
3530     .BYTE "UNP"
3540     .WORD UNLOCK
3550     .BYTE "NAM"
3560     .WORD RENAM
3570     .BYTE "DOS"
3580     .WORD DOS
3590     .BYTE "TRA"
3600     .WORD TRACE
3610     .BYTE "OFF"
3620     .WORD TOFF
3630     .BYTE "NUM"
3640     .WORD AUTNUM
3650     .BYTE "REM"
3660     .WORD RENAM
3670     .BYTE "DEC"
3680     .WORD DECHEX
3690     .BYTE "HEX"
3700     .WORD HEXDEC
3710     .BYTE "LVA"
3720     .WORD VARLST
3730 ;
3740 ;directory routine
3750 ;
3760 DIR JSR TURNOF  ;trace off
3770     JSR CLOSES  ;close iocb 5
3780     LDX #$50
3790     LDA #3      ;open Chan US
3800     STA ICCOM,X
3810     LDA #6      ;directory
3820     STA ICAUX1,X
3830     LDA # >DIRNAM ;D1:*.*
3840     STA ICBAH,X
3850     LDA # <DIRNAM
3860     STA ICBAL,X
3870     JSR CIO     ;openning
3880     BPL NOERR1  ;no error
3890     BMI ENDIR   ;opps
3900 ;
3910 NOERR1 LDX #$50 ;chan 5
3920     LDA #20     ;20 chars
3930     STA ICBLL,X
3940     LDA #0      ;for input
3950     STA ICBLH,X
3960     LDA # >DIRBUF ;my buffer
3970     STA ICBAH,X
3980     LDA # <DIRBUF
3990     STA ICBAL,X
4000     LDA #5      ;get bytes
4010     STA ICCOM,X
4020     JSR CIO     ;get 'em
4030     BMI ENDIR   ;error-quit
4040 ;
4050     LDX #$00
4060     LDA #9      ;put bytes
4070     STA ICCOM
4080     LDA #20     ;20 of 'em
4090     STA ICBLL
4100     STX ICBLH
4110     LDA # >DIRBUF ;my buffer
4120     STA ICBAH
4130     LDA # <DIRBUF
4140     STA ICBAL
4150     JSR CIO     ;print 'em
4160     BPL NOERR1  ;ok
4170 ENDIR JSR CLOSES ;close #5
4180     JMP EXIT2 ;to BASIC
4190 ;
4200 ;close iocb #5
4210 ;
4220 CLOSES LOX #$50
4230     LDA #$0C
4240     STA ICCOM,X
4250     JSR CIO
4260     RTS
4270 ;
4280 ;do XIOs using CIO
4290 ;
4300 DOXIO PHA       ;save command
4310     JSR CLOSES  ;Close chan
4320     JSR TURNOF  ;trace off
4330     PLA         ;get XIO
4340     LDX #$50    ;command
4350     STA ICCOM,X
4360     LDA #0      ;zero length
4370     STA ICBLH,X
4380     STA ICBLL,X
4390     LDA # <LBUF+4 ;D:filespec
4400     STA ICBAL,X
4410     LDA # >LBUF+4
4420     STA ICBAH,X
4430     JSR CIO     ;do XIO
4440     TYA
4450     BPL ENDIR
4460     JMP ERROR
4470 ;
4480 ;XIO jmp table
4490 ;
4500 ERA LDA #33     ;erase file
4510     BNE DOXIO
4520 LOCK LDA #35    ;lock a file
4530     BNE DOXIO
4540 UNLOCK LDA #36  ;unlock it
4550     BNE DOXIO
4560 RENAM LDA #32   ;rename it
4570     BNE DOXIO
4580 DOS LDA SYSRST+1 ;resstore
4590     STA DOSINI  ;DOSINI
4600     LDA SYSRST+2 ;vector
4610     STA DOSINI+1
4620     JSR TURNOF  ;trace off
4630     JMP WARMST  ;do warm start
4640 ;
4650 ;turn trace on
4660 ;special display list
4670 ;from ANALOG issue 31
4680 ;June 1985 page 74
4690 ;
4700 TRACE LDA TFLG  ;check flag
4710     BNE AON     ;1 = on now
4720     INC TFLG    ;set to 1
4730     LDA DLISTL  ;get display
4740     STA DLS     ;list and
4750     CLC         ;save it
4760     ADC #3
4770     STA BACK    ;put it into
4780     LDA DLISTH  ;my display
4790     STA DLH     ;list
4800     ADC #0
4810     STA BACK+1
4820     LDA # >NDLIST ;install
4830     STA DLISTH  ;the new
4840     LDA # <NDLIST ;special
4850     STA DLISTL  ;display
4860     LDA #6      ;list
4870     LDY # <VBI  ;turn on
4880     LDX # >VBI  ;VBI
4890     JSR SETVBV
4900 AON JMP EXIT2   ;out
4910 ;
4920 ;turn off VBI
4930 ;
4940 TOFF JSR TURNOF ;turn MUM off
4950     JMP EXIT2   ;goto BASIC
4960 ;
4970 TURNOF LDA DLH  ;restore
4980     STA DLISTH  ;original
4990     LDA DLS     ;display list
5000     STA DLISTL
5010     LDA #0      ;set flag
5020     STA TFLG
5030     LDX SYSVBV+2 ;reset VBI
5040     LDY SYSVBV+1 ;to system
5050     LDA #6      ;vectors
5060     JSR SETVBV
5070     RTS
5080 ;
5090 ;print error message
5100 ;
5110 ERROR PHA       ;save error #
5120     LDX #7
5130 Ell LDA ERMES,X ;get byte
5140     JSR PUTC    ;print it
5150     DEX
5160     BPL Ell
5170     PLA         ;get error
5180     STA FRO
5190     LDA #0
5200     STA FR1
5210     JSR IFP     ;convert to
5220     JSR FASC    ;ATASCII
5230     JSR MPRINT
5240     JSR DOCR
5250     JSR PRRDY
5260     JMP ENDIR
5270 ;
5280 ;print "READY"
5290 ;
5300 PRRDY LDX #5
5310 RDY LDA READ,X
5320     JSR PUTC
5330     DEX
5340     BPL RDY
5350     RTS
5360 ;
5370 ;vert blank code for trace
5380 ;
5390 VBI LDA CRITIC  ;critical
5400     BEQ V3      ;section? no
5410     JMP SYSVBV  ;out
5420 V3  LDA DLISTL  ;see if special
5430     CMP # <NDLIST ;display list
5440     BNE PUTDL   ;is present
5450     LDA DLISTH  ;if not - form
5460     CMP # >NDLIST ;it
5470     BEQ V9      ;yes
5480 PUTDL LDA DLISTL ;     save it
5490     STA DLS
5500     CLC
5510     ADC #3      ;install in
5520     STA BACK    ;new display
5530     LDA DLISTH  ;list
5540     STA DLH
5550     ADC #0
5560     STA BACK+1
5570     LDA # <NDLIST
5580     STA DLISTL
5590     LDA # >NDLIST
5600     STA DLISTH
5610 V9  LDA $8A     ;get executing
5620     STA $04     ;line pointer
5630     LDA $88
5640     STA $05
5650     LDY #0      ;get executing
5660     LDA ($04),Y ;line no.
5670     STA BFR0
5680     INY
5690     LDA ($04),Y
5700     STA BFR1
5710     LDA #0      ;clear out BCD
5720     STA BCD     ;work space
5730     STA BCD+1
5740     STA BCD+2
5750     STA BCD+3
5760     SED         ;decimal mode
5770     LDY #$10    ;16 bits
5780 V4  ASL BFR0    ;2 BCD digits
5790     ROL BFR1    ;per byte
5800     LDX #$03    ;6 BCD digits
5810 V5  LDA BCD,X   ;total
5820     ADC BCD,X
5830     STA BCD,X
5840     DEX
5850     BNE V5
5860     DEY
5870     BNE V4
5880     CLD         ;clear decimal
5890     LDX #25     ;put digits on
5900     LDY #0      ;top line
5910 V6  LDA BCD+1,Y
5920     PHA         ;high nibble
5930     LSR A
5940     LSR A
5950     LSR A
5960     LSR A
5970     ORA #$10    ;internal code
5980     STA TLINE,X
5990     INX
6000     PLA         ;get byte
6010     AND #$0F    ;low nibble
6020     ORA #$10    ;internal code
6030     STA TLINE,X
6040     INX
6050     INY
6060     CPY #3      ;done?
6070     BNE V6      ;no
6080     JMP SYSVBV  ;gone
6090 ;
6100 ;convert dec to hex
6110 ;
6120 DECHEX LDA #3   ;point to #
6130     STA CIX     ;in 'DECdddd'
6140     LDA # >LBUF
6150     STA INBUF+1 ;point FP
6160     LDA # <LBUF ;to it
6170     STA INBUF
6180     JSR AFP     ;to FP
6190     BCC DD2     ;ok
6200     JMP VALERR  ;error
6210 DD2 JSR FPI     ;to integer
6220     JSR BNTOHX  ;to hex digits
6230     LDA #'=
6240     JSR PUTC    ;'=$'
6250     LDA #'$
6260     JSR PUTC
6270     LDX #3      ;print the
6280 DD1 LDA N2BUF,X ;hex digits
6290     JSR PUTC
6300     DEX
6310     BPL DD1
6320     JSR DOCR
6330     JSR SETLBF  ;reset
6340     LDA #0      ;FP stuff
6350     STA CIX
6360     JMP EXIT2   ;to BASIC
6370 ;
6380 ;do a carriage return
6390 ;
6400 DOCR LDA #EOL
6410     JSR PUTC
6420     RTS
6430 ;
6440 ;binary to hex converter
6450 ;
6460 BNTOHX LDY #3   ;work backwards
6470     LDX #1      ;2 hex numbers
6480 HX1 STX X3
6490     LDA FR0,X   ;get high
6500     PHA         ;save it
6510     LSR A       ;move to
6520     LSR A       ;low nibble
6530     LSR A
6540     LSR A
6550 ;
6560     TAX
6570     LDA HEXTAB,X ;get hex digit
6580     STA N2BUF,Y ;store it
6590     DEY         ;move pointer
6600     PLA         ;down
6610     AND #$0F    ;now low nibble
6620     TAX
6630     LDA HEXTAB,X ;get hex
6640     STA N2BUF,Y ;save it
6650     DEY
6660     LDX X3      ;next hex numbr
6670     DEX
6680     BPL HX1
6690     RTS ;done
6700 ;
6710 ;hex to dec converter
6720 ;
6730 HEXDEC LDY #3  ;point to
6740     LDA LBUF,Y ;hex in
6750     CMP #'$    ;'HEX($]hhhh'
6760     BNE HD1    ;skip '$'
6770     INY
6780 HD1 LDX #0     ;clear work
6790     STX FR0    ;space
6800     STX FR0+1
6810     STX X2     ;digit countr
6820 PU1 LDA LBUF,Y ;get digit
6830     LDX #$0F   ;in table
6840 H2 CMP HEXTAB,X
6850     BEQ H3     ;X = 0-15
6860     DEX
6870     BPL H2
6880     BMI H6     ;oh! oh!
6890 H3  STX K1     ;= 0 <-> 15
6900 ;
6910 ;convert to binary
6920 ;
6930     ASL FR0    ;times 16
6940     ROL FR0+1
6950     ASL FR0
6960     ROL FR0+1
6970     ASL FR0
6980     ROL FR0+1
6990     ASL FR0
7000     ROL FR0+1
7010     CLD
7020     CLC
7030     LDA FR0     ;add in value
7040     ADC M1      ; 0<-> 15
7050     STA FR0
7060     LDA FR0+1
7070     ADC #0
7080     STA FR0+1
7090     INY         ;next dec digit
7100     INC X2      ;hex counter
7110     LDA X2
7120     CMP #4      ;got 4
7130     BEQ H6      ;yes
7140     JMP PU1     ;do more
7150 H6  LDA X2      ;# digits
7160     BNE H7
7170     JMP VALERR  ;error
7180 ;
7190 ;convert to ATASCII $ print
7200 ;
7210 H7  JSR IFP
7220     JSR FASC    ;to ATASCII
7230     LDA #'=
7240     JSR PUTC
7250     LDX #0
7260 H9  LDA LBUF,X
7270     PHA         ;save it
7280     AND #$7F    ;mask inverse
7290     JSR PUTC
7300     INX
7310     PLA         ;get it
7320     BPL H9      ;more
7330     JSR DOCR
7340     JSR SETLBF  ;reset LBUF
7350     JMP EXIT2   ;to BASIC
7360 ;
7370 ;do listing of variables
7380 ;
7390 VARLST LDA VNTP ;point to
7400     STA JO      ;variable
7410     LDA VNTP+1  ;table
7420     STA JO+1
7430     LDA #$7F    ;first var=$80
7440     STA MYTOKEN
7450 LSBEG LDA JO+1
7460     CMP $85     ;at end of
7470     BNE LPVAR   ;var table?
7480     LDA JO
7490     CMP $84
7500     BNE LPVAR
7510     JMP EXIT2   ;to BASIC
7520 ;
7530 LPVAR LDY #$00  ; print variable
7540     LDA (JO),Y
7550     PHA         ;save it
7560     AND #$7F    ;mask inverse
7570     JSR PUTC    ;to screen
7580     INC JO      ;move pntr up
7590     BNE LV1
7600     INC JO+1
7610 LV1 PLA         ;get byte
7620     BPL LPVAR   ;More if +
7630     JSR DOCR    ;do CR
7640     LDA STMTAB  ;get start of
7650     STA LO      ;BASIC
7660     LDA STMTAB+1 ;lines
7670     STA LO+1
7680     LDA #0      ;column cntr
7690     STA PRFLAG
7700     INC MYTOKEN ;next variable
7710 ;
7720 VV0 JSR GETTOKH ;get line
7730     STA LINENO  ;number
7740     JSR GETTOKN
7750     STA LINENO+1
7760     CMP #$80    ;at 32768?
7770     BCC VV1     ;no
7780     JSR DOCR    ;yes try
7790     JMP LSBEG   ;next variable
7800 ;
7810 VV1 JSR GETTOKN ;offset
7820 VN1 JSR GETTOKN ;offset
7830     JSR GETTOKN ;token
7840     CMP #$02    ;rem /data
7850     BCS VV2
7868 VV3 JSR GETTOKH ;get byte
7870     CMP #EOL    ;EOL yet
7880     BNE VV3     ;keep going
7890     BEQ VV0     ;next line
7900 ;look for end of statement
7910 ;or line
7920 VV2 JSR GETTOKN
7930     CMP #$14    ;statmt end?
7940     BEQ VN1     ;next stmt
7950     CMP #$1B    ;THEN?
7960     BEQ VN1
7970     CMP #$16    ;line end?
7980     BEQ VV0     ;next line
7990     CMP #$0E    ;nun constant?
8000     BNE VV4     ;try string
8010     LDX #$06    ;skip number
8020 VV7 JSR GETTOKN ;pull numbr
8030     DEX
8040     BNE VV7
8050     BEQ VV2
8060 VV4 CMP #$0F    ;a string?
8070     BNE VV6     ;no
8080     JSR GETTOKN ;length
8090     TAX         ;skip it
8100     BNE VV7
8110 VV6 CMP MYTOKEN ;a variable?
8120     BNE VV2     ;nope
8130     LDA LINENO  ;show line
8140     STA FR0     ;number
8150     LDA LINENO+1
8160     STA FR0+1
8170     JSR IFP     ;INT to FP
8180     JSR FASC    ;ATASCII
8190     INC PRFLAG  ;screen
8200     LDA PRFLAG  ;format
8210     CMP #6      ;5 per screen
8220     BNE VP2     ;line
8230     LDA #0
8240     STA PRFLAG  ;reset
8250     JSR DOCR
8260 VP2 JSR MPRINT  ;roll presses
8270 VP4 LDA #$20    ;space
8280     JSR PUTC
8290     INY         ;format with
8300     CPY #6      ;spaces so
8310     BNE VP4     ;in columns
8320     JMP VV2     ;try more lines
8330 ;
8340 ;get a token and increment
8350 ;the pointer in BASIC
8360 ;
8370 GETTOKN LDY #$00
8380     LDA (LO),Y
8390     INC LO
8400     BNE NINC
8410     INC LO+1
8426 NINC RTS
8430 ;
8440     .INCLUDE #D:BUPP2.M65
8450 ;
8460 ;data
8470 ;
8480 ERMES .BYTE " # RORRE"
8490 BBI .BYTE $9B,"egakcaP seiti"
8500     .BYTE "litU CISAB",$7D
8510 NDLIST .BYTE $70,$70,$42 ;new
8520     .WORD TLINE ;disply list
8530     .BYTE $01
8540 BACK .WORD $00  ;disp.lst flg
8550 TLINE .SBYTE "         EXECUTI"
8560     .SBYTE "ING LINE:         "
8570     .SBYTE "      "
8580 ONOFF .BYTE 0   ;auto num flg
8590 TFLG *= *+1     ;trace flg
8600 DLS *=  *+1     ;save old
8610 DLH *=  *+1     ;disp. list
8620 BCD *=  *+4     ;bcd wrk area
8630 BFRB *= *+1     ;psuedo FP
8640 BFR1 *= *+1     ;registers
8650 YSAV *= *+1     ;save y,x
8660 XSAV *= *+1
8670 PYSAV *= *+1    ;save y
8680 Y1  *=  *+1     ;more save
8690 X1  *=  *+1     ;x and y
8700 Y2  *=  *+1
8710 x2  *=  *+1
8720 CY1 *=  *+1     ;ysave in cord
8730 OTFLAG *= *+1   ;quit nun flg
8740 TOKTAB .BYTE 10,11,12,13,35,4
8750 OFFSET *= *+1   ;ren-stet offst
8760 NXTSTM *= *+1   ;next st. offst
8770 PRFLAG *= *+1   ;print flg
8780 LSTKEY *= *+1   ;last key"
8790 MYTOKEN *= *+1  ;save My taken
8800 X3  *=  *+1     ;save x
8810 DONMES .BYTE EOL,"derebmuner "
8820     .BYTE "margorP"
8830 OVRMES .BYTE $9B,"86723 => eniL"
8840 READ .BYTE EOL,"YDAER"
8850 TIMER *= *+1    ;vbi timer-num
8860 ENDLIN *= *+1   ;end line-num
8870 CHRCNT *= *+1   ;char. cnter
8880 VBLKDS *= *+2   ;save vvblkd
8890 FPMES .BYTE EOL,"rorre eulaV"
8900 HEXTAB .BYTE "0123456789ABCDEF"
8910 ENDPTR *= *+1   ;crunch
8920 MYEDIT *= *+16  ;ed. vector tab
8930 DIRBUF *= *+20  ;for directry
8940 DIRNAM .BYTE "D:*.*",EOL
8950 NBUF *= *+8     ;# buffers-num
8960 N2BUF *= *+29   ;& ren
8970     .BYTE 0     ;for unify
8980 ;
8990     .OPT LIST
9000 ENDPRG *= *+1
9010     .OPT NO LIST
9020     *= $02E2
9030     .WORD IN1
9040     .END



Listing 3:
Assembly


0100 ;SAVE#D:BUPP2.M65
0110 ;
0120 ;------------------;
0130 ;                  ;
0140 ; BUP.SY5 part II  ;
0150 ;                  ;
0160 ;   (C) 1989       ;
0170 ; by Barry Kolbe   ;
0180 ;                  ;
0190 ;------------------;
0200 ;
0210 ;get line numbers
0220 ;
0230 RENUM JSR GETNBR
0240     JSR DOCR
0250 ;
0260     LDX #3      ;set prflag
0270     STH PRFLAG
0280 ;
0290 ;check if line>32768
0300 ;
0310     JSR GETPTR  ;point to
0320     CLD         ;first line
0330 NXTLN1 LDY #1   ;check hi byte
0340     LDA (LINPTR),Y ;of line #
0350     CMP #$80    ;>=32768?
0360     BCS LINOK   ;yes-AOK
0370     LDA CLINE+1 ;will new line
0380     CMP #$80    ;be >32768?
0390     BCS LINOVR  ;yes-quit
0400     LDA CLINE   ;add increment
0410     CLC         ;to current
0420     ADC ILINE   ;new line
0430     STA CLINE
0440     LDA CLINE+1
0450     ADC ILINE+1
0460     STA CLINE+1
0470     INY         ;add offset
0480     LDA (LINPTR),Y ;to BASIC
0490     CLC         ;current line
0500     ADC LINPTR
0510     STA LINPTR
0520     LDA LINPTR+1
0530     ADC #0
0540     STA LINPTR+1
0550     JMP NXTLN1  ;check more
0560 ;
0570 ; line >32768
0580 ;
0590 LINOVR LDX #13  ;show error
0600 L1  LDA OVRMES,X ;over the
0610     JSR PUTC    ;max
0620     DEX
0630     BPL L1
0640     JMP EXIT2   ;to BASIC
0650 ;
0660 GETPTR LDA STMTAB ;point to
0670     STA LINPTR  ;BASIC'S
0680     LDA STMTAB+1 ;first line
0690     STA LINPTR+1
0700     RTS
0710 ;
0720 FLNCLN LDA FLINE ;put new
0730     STA CLINE   ;first line
0740     LDA FLINE+1 ;into
0750     STA CLINE+1 ;test line
0760     RTS
0770 ;
0780 ;renumbered lines will all
0790 ;be less than 32768
0800 ;
0810 LINOK JSR GETPTR ;reset Pntrs
0820     JSR FLNCLN  ;get first line
0830 CKTOK LDY #0    ;get low byte
0840     LDA (LINPTR),Y ;of line no.
0850     STA LINENO  ;save it
0860     INY
0870     LDA (LINPTR),Y ;now high
0880     STA LINENO+1 ;byte
0890     CMP #$00    ;done?
0900     BCC L2      ;no
0910     JMP DOREN   ;do renumber!
0920 L2  INY
0930     LDA (LINPTR),Y ;offset to
0940     STA OFFSET  ;next line
0950     INY         ;offset to
0960     LDA (LINPTR),Y ;next stmt
0970     STA NKTSTM
0980 L4  INY
0990     LDA (LINPTR),Y ;get token
1000     LDX #5      ;is it a
1010 L3  CMP TOKTAB,X ;special?
1020     BNE L5
1030     JMP TOK1    ;yes-process
1040 L5  DEX         ;try next
1050     BPL L3
1060     CMP #7      ;IF token
1070     BNE L7
1080     JMP TOK3    ;handle it
1090 L7  CMP #30     ;ON token
1100     BNE GTNXST  ;do next stmt
1110     JMP TOK2    ;handle ON
1120 ;
1130 ;get next stmt or line
1140 ;
1150 GTNXST LDA NKTSTM ;is nxt stmt
1160     CMP OFFSET  ;= to next line?
1170     BEQ NXTLN3  ;yes
1180     TAY         ;no
1190     LDA (LINPTR),Y ;get offset
1200     STA NXTSTM
1210     JMP L4      ;look for token
1220 NXTLN3 CLC      ;move to next
1230     LDA OFFSET  ;line
1240     ADC LINPTR
1250     STA LINPTR
1260     LDA LINPTR+1
1270     ADC #0
1286     STA LINPTR+1
1290     CLC         ;move up
1300     LDA CLINE   ;new line
1310     ADC ILINE   ;counter
1320     STA CLINE
1330     LDA CLINE+1
1340     ADC ILINE+1
1350     STA CLINE+1
1360     JMP CKTOK   ;do next line
1370 ;
1380 ;do the renumbering
1390 ;
1400 DOREN JSR GETPTR ;pt to 1st line
1410     JSR FLNCLN  ;new nmbrs
1420 DOR2 LDY #1     ;high byte of
1430     LDA CLINPTRI,Y ;line no
1440     CMP #$80    ;at 32768?
1450     BNE DOR1    ;no
1460     LDX #18     ;yes-say 'done'
1470 DORT LDA DONMES,X
1480     JSR PUTC
1490     DEX
1500     BPL DORT
1510     JMP EXIT2   ;to BASIC
1520 ;
1530 DOR1 DEY        ;back up 1 byte
1540     LDA FLINE   ;get new line
1550     STA (LINPTR),Y ;numbr
1560     LDA FLINE+1 ;and insert
1570     INY         ;it into
1580     STA (LINPTR),Y ;Memory
1590     CLC
1600     LDA FLINE   ;next new line
1610     ADC ILINE
1620     STA FLINE
1630     LDA FLINE+1
1640     ADC ILINE+1
1650     STA FLINE+1
1660     INY         ;next BASIC
1670     LDA (LINPTR),Y ;line
1680     CLC
1690     ADC LINPTR
1700     STA LINPTR
1710     LDA LINPTR+1
1720     ADC #0
1730     STA LINPTR+1
1740     JMP DOR2    ;more!
1750 ;
1760 ;handle special tokens
1770 ;like GOTO, GO TO, GOSUB
1780 ;TRAP, RESTORE, LIST
1790 ;which preceed line numbers
1800 ;
1810 TOK1 INY        ;check for
1820     LDA (LINPTR),Y
1830     CMP #$14    ;a number
1840     BEQ GOTN    ;constant
1850 VAR JMP VARREF  ;variable refer
1860 GOTN STY YSAV   ;save position
1870 GOTN1 TYA       ;skip 7 bytes
1880     CLC         ;for constant
1890     ADC #7
1900     TAY
1910     LDA (LINPTR),Y ;get token
1920     CMP #$18    ;comma?
1930     BEQ DONUM
1940     CMP #$20    ;end stmt?
1950     BEQ DONUM
1960     CMP #$22    ;end line?
1970     BNE VAR     ;variable ref
1980 DONUM LDY YSAV
1990     JSR BCDINT  ;BCD to integer
2000 ;
2016 ;now see if the new line exits
2828 ;
2838     LDA STMTAB  ;point to
2040     STA SPTR    ;line table
2050     LDA STMTAB+1
2060     STA SPTR+1
2070     LDA FLINE   ;1st new line
2080     STA FR0
2090     LDA FLINE+1
2100     STA FR0+1
2110 SEARCH LDY #1   ;check if exits
2120     LDA (SPTR),Y ;high byte
2130     CMP #$80    ;at end?
2140     BEQ NOTFND  ;yes
2158     CMP RLINE+1 ;is it new line?
2160     BNE SNXTLN  ;no
2170     DEY         ;maybe-check
2180     LDA (SPTR),Y ;low byte
2190     CMP RLINE
2200     BNE SNXTLN  ;nope
2210 ;
2220 ;got match fr0 has new line #
2230 ;
2240     JSR IFP     ;INT to FP
2250     JSR INSERT  ;put it in
2260     INY         ;next token
2270     LDA (LINPTR),Y
2280     CMP #$18    ;comma?
2290     BNE NOCOM   ;no
2300     JMP TOK1    ;Check for #
2310 NOCOM JMP GTNXST ;next stmt
2320 ;
2330 SNXTLN LDY #2   ;offset to
2340     LDA (SPTR),Y ;next line
2350     CLC         ;move up to it
2360     ADC SPTR
2370     STA SPTR
2380     LDA SPTR+1
2390     ADC #$0
2400     STA SPTR+1
2410     CLC         ;move up
2420     LDA FR0     ;new line
2430     ADC ILINE   ;to next one
2440     STA FR0     ;in sequence
2450     LDA FR0+1
2460     ADC ILINE+1
2470     STA FR0+1
2480     JMP SEARCH  ;keep looking
2490 ;
2500 ;show variable reference msg
2510 ;
2520 VARREF LDA #'V  ;print 'VR-'
2530     JSR PUTC
2540     LDA #'R
2550     JSR PUTC
2560     LDA #'-
2570     JSR PUTC
2580 NF1 LDA CLINE   ;at current
2590     STA FR0     ;line nmbr
2600     LDA CLINE+1
2610     STA FR0+1
2620     JSR IFP     ;change to FP
2630     JSR FASC    ;to ATASCII
2640     JSR PRNO    ;print it
2650     JMP GTNXST  ;next stmt
2660 ;
2670 ;show not found msg
2680 ;
2690 NOTFND LDA #'N  ;print 'NF-
2700     JSR PUTC
2710     LDA #'F
2720     JSR PUTC
2730     LDA #'-
2740     JSR PUTC
2750     JMP NF1     ;print line #
2760 ;
2770 ;check for ON GOTO/GOSUB
2780 ;
2790 TOK2 INY
2800     LDA (LINPTR),Y
2810     CMP #23     ;ON GOTO
2820     BNE TK3     ;nope
2830 TK4 JMP TOK1    ;yup
2840 TK3 CMP #24     ;ON GOSUB
2850     BEQ TK4     ;yes
2860     BNE TOK2    ;try again
2870 ;
2880 ;check for IF-THEN
2890 ;
2900 TOK3 INY
2910     LDA (LINPTR),Y ;get token
2920     CMP #27     ;THEN?
2930     BNE TOK3    ;not yet
2940     INY         ;get next token
2950     LDA (LINPTR),Y
2960     CMP #14     ;a constant?
2970     BNE NTNUM
2980     DEY         ;yes
2990     JMP TOK1    ;process it
3000 NTNUM DEY       ;back up i byte
3010     JMP L4      ;find if other to
ken
3020 ;
3030 ;convert BCD to INTEGER
3040 ;
3050 BCDINT LDX #0   ;copy ATASCII
3060 BCD1 INY        ;to FRO
3070     LDA (LINPTR),Y
3080     STA FR0,X
3090     INX
3100     CPX #6      ;6 bytes
3110     BNE BCD1
3120     JSR FPI     ;FP to INT
3130     LDA FR0     ;save it
3140     STA RLINE
3150     LDA FR0+1
3160     STA RLINE+1
3170     RTS
3180 ;
3190 ;insert new line
3200 ;
3210 INSERT LDY YSAV ;get position
3220     LDX #0      ;move FP 33
3230 INS1 INY        ;to position
3240     LDA FR0,X   ;in memory
3250     STA (LINPTR),Y ;of line
3260     INX
3270     CPX #6
3280     BNE INS1
3290     RTS
3300 ;
3310 ;print line number
3320 ;
3330 PRNO JSR MPRINT ;print it
3340     LDA #20
3350     JSR PUTC
3360     LDX PRFLAG
3370     DEX
3380     BPL XR2
3390     JSR DOCR
3400     LDX #3
3410 XR2 STX PRFLAG
3420     RTS
3430 ;
3440 ;print LBUF
3450 ;
3460 MPRINT LDY #SFF
3470 MPT INY
3480     LDA (INBUF),Y ;get byte
3490     PHA         ;save it
3500     AND #$7F    ;mask inverse
3510     JSR PUTC    ;put it
3520     PLA         ;last byte
3530     BPL MPT     ;is inversed
3540     RTS
3550 ;
3560 ;ren & num input checker
3570 ;also gets first line and
3580 ;increment from input line
3590 ;
3600 GETNBR JSR DEFAULT
3610     LDY #3
3620     LDA LBUF,Y  ;no 3$ls?
3630     CMP #EOL
3640     BNE GETHMS
3650     RTS         ;no 3$s!
3660 ;
3670 ;default values are 10,10
3680 ;
3690 DEFAULT LDA #10
3700     STA FLINE   ;first line
3710     STA CLINE
3720     STA ILINE   ;and increment
3730     LDA #0
3740     STA FLINE+1
3750     STA ILINE+1
3760     STA CLINE+1
3770     RTS
3780 ;
3790 ;find the last program line
3800 ;
3810 GLAST JSR DEFAULT ;set defaults
3820     JSR GETPTR  ;point to
3830     LDY #1      ;first line
3840     LDA (LINPTR),Y ;get high
3850     BPL GLOK    ;< 32768?
3860     RTS         ;no!
3876 GLOK STA 1      ;save line #
3880     DEY         ;get low
3890     LDA (LINPTR),Y
3900     STA 0       ;save it
3910     JSR ADDLIN  ;next line
3920     LDY #1      ;get high of
3930     LDA (LINPTR),Y ;line
3940     BPL GLOK    ;< 32768
3950     LDA 0
3960     CLC
3978     ADC ILINE   ;move up
3980     STA FLINE   ;use last
3990     STA CLINE   ;number
4000     LDA 1
4010     ADC #0      ;high byte
4020     STA FLINE+1
4030     STA CLINE+1
4040     RTS
4050 ;
4060 ;set up for first time use
4070 ;
4080 SETNUM CLD
4090     LDA FLINE    ;back up
4100     SEC          ;one increment
4110     SBC ILINE    ;from first
4120     STA FLINE    ;line
4130     LDA FLINE+1
4140     SBC ILINE+1
4150     STA FLINE+1
4160     RTS
4170 ;
4180 ;get numbers from input
4190 ;
4200 GETNMS LDX #0
4210 FNDCOM LDA LBUF,Y
4220     CMP #',     ;comma?
4230     BEQ GOTFST
4240     CMP #EOL    ;done yet?
4250     BEQ GOTFST
4260     STA NBUF,X  ;copy number
4270     INX         ;out to NBUF
4280     CPX #6
4290     BEQ FPERR   ;error if
4300     INY         ;too many digits
4310     JMP FNDCOM  ;loop
4320 ;
4330 ;got first line #-convert it
4340 ;to integer form
4350 ;
4360 GOTFST STA NBUF,X ;, or EOL
4370     STY Y2      ;save position
4380     LDA #  0    ;set up FP
4390     STA CIX     ;stuff
4400     STA CLINE
4410     JSR DOINBF  ;point to NBUF
4420     JSR AFP     ;ATASCII to FP
4430     JSR FPI     ;FP to INT
4440     BCS FPERR
4450     LDA FR0+1   ;is number
4460     BMI FPERR   ;over 32768?
4470     STA FLINE+1
4480     STA CLINE+1
4490     LDA FR0
4500     STA FLINE
4510     STA CLINE
4520     LDY Y2      ;get position
4530     LDA LBUF,Y  ;check next
4540     CMP #EOL    ;char. done?
4550     BNE GETSCN  ; get second
4560     RTS
4570 ;
4580 ;got first line ,now get
4590 ;the increment
4600 ;
4610 GETSCN LDX #0
4620 GT1 INY
4630     LDA LBUF,Y  ;get byte
4640     CMP #EOL    ;done?
4650     BEQ NUMDON  ;yes
4660     STA NBUF,X  ;copy it
4670     INX         ;too
4680     CPX #6      ;many digits?
4690     BEQ FPERR   ;yes
4700     JMP GT1     ;more
4710 ;
4720 ;initialize INBUF
4730 ;
4740 DDINBF LDA # <NBUF ;point it
4750     STA INBUF   ;to NBUF
4760     LDA # >NBUF ;where the
4770     STA INBUF+1 ;number is
4780     RTS
4790 ;
4800 ;show floating point error
4810 ;
4820 FPERR PLA       ;remove return
4830     PLA
4840 VALERR LDX #11  ;'ERROR'
4850 FPER1 LDA FPMES,X ;msg
4860     JSR PUTC
4870     DEX
4880     BPL FPER1
4890     JSR SETLBF  ;reset FP
4900     JMP EXIT2   ;to BASIC
4910 ;
4920 ;got parameters so
4930 ;process second number
4940 ;
4950 NUMDON STA NBUF,X ;EOL
4960     LDA #0
4970     STA CIX     ;point to NBUF
4980     JSR DOINBF
4990     JSR AFP     ;to FP
5000     JSR FPI     ;to INT
5010     BCS FPERR   ;error!
5020     LDA FR0     ;put in
5030     STA ILINE   ;increment
5040     LDA FR0+1
5050     STA ILINE+1 ;error if
5060     BMI FPERR   ;>=32768
5070     JSR SETLBF  ;reset FP
5080     RTS
5090 ;
5100 ;this is the entry point
5110 ;for the auto numbering
5120 ;some ideas from ANALOG
5130 ;issue 29 April 1985
5140 ;
5150 AUTNUM JSR GLAST ;get params.
5160     LDA #0
5170     STA ONOFF
5180 ;
5190 ;check for line overwrite
5200 ;
5210     JSR GETPTR  ;point to
5220 NMI LDY #0      ;first line
5230     LDA (LINPTR),Y ;get lineno
5240     STA RLINE   ;low byte
5250     INY
5260     LDA (LINPTR),Y ;high byte
5270     STA RLINE+1 ;is line
5280     BMI NUMOK   ;>=32768
5290     CMP FLINE+1
5300     BEQ CKLOW   ;check low
5310     BCS NUMOK   ;AOK
5320 NN2 JSR ADDLIN  ;next line
5330     JMP NM1     ;loop
5340 ;
5350 CKLOW LDA RLINE ;check low
5360     CMP FLINE   ;byte
5370     BEQ NOAUTO  ;exits!
5380     BCS NUMOK   ;ok
5390     BCC NN2     ;check next
5400 NOAUTO JMP EXIT2
5410 ;
5420 ;parameters ok
5430 ;
5440 NUMOK JSR SETNUM ;back up
5450     LDA #7      ;set UBI
5460     LDY # <VBNUM
5470     LDX # >VBNUM
5480     JSR SETVBV
5490     JSR SETLBF  ;set FP pointrs
5500     LDA #10     ;VBI timer
5510     STA TIMER
5520     LDA #0
5530     STA PROMPT  ;for BASIC
5540     STA CHRCNT
5550     LDA #1
5560     STA ENDLIN
5570     STA ONOFF
5580     JMP EXIT2
5590 ;
5600 ;point to next BASIC line
5610 ;
5620 ADDLIN STY SLIME
5630     LDY #2
5640     LDA (LINPTR),Y ;get offset
5650     CLD
5660     CLC         ;move pointer
5670     ADC LINPTR
5680     STA LINPTR
5690     LDA LINPTR+1
5700     ADC #0
5710     STA LINPTR+1
5720     LDY SLIME
5730     RTS
5740 ;
5750 ;get next basic line for VBI
5760 ;
5770 INCLIN JSR ADDLIN
5780     STY SLIME
5790     LDY #0
5800     LDA (LINPTR),Y ;get low
5810     STA RLINE   ;store it
5820     INY
5830     LDA (LINPTR),Y ;high byte
5840     STA RLINE+1
5850     LDY SLIME
5860     RTS
5870 ;
5880 ;vertical blank interrupt
5890 ;
5900 VBNUM LDA ENDLIN ;BASIC done?
5910     BEQ XITVBI  ;no
5920     LDA PROMPT
5930     BEQ XITVBI  ;
5940     LDA TIMER   ;time yet?
5950     BEQ PRNUM
5960     DEC TIMER   ;count down
5970     JMP XITVBI
5980 PRNUM LDA #0
5990     STA ENDLIN
6000     LDA FLINE   ;get line to
6010     CLC         ;print
6020     ADC ILINE   ;add increment
6030     STA FLINE
6040     STA FR0
6050     LDA FLINE+1
6060     ADC ILINE+1
6070     STA FLINE+1
6080     STA FR0+1
6090 OVRCHK LDA FR0+1 ;is it
6100     BMI VBQT    ;over 32768?
6110     CMP RLINE+1 ;exist already?
6120     BEQ VCXLO   ;maybe
6130     BCC VBOK    ;ok
6140     JSR INCLIN  ;look again
6150     JMP OURCHK  ;check it
6160 VCKLO LDA FR0   ;low bytes
6170     CMP RLINE   ;match
6180     BEQ VBQT    ;yes-exit
6190     BCC VBOK    ;ok
6200     JSR INCLIN  ;try next line
6210     JMP OVRCHK  ;check it
6220 VBQT INC QTFLAG ;quit-exists
6230     LDA #12     ;force return
6240     STA 764
6250     JMP XITVBI  ;out
6260 ;
6270 ;line # ok print it
6280 ;
6290 VBOK JSR IFP    ;to ATASCII
6300     JSR FASC
6310     JSR MPRINT  ;print it
6320     LDA #$20    ;space
6330     JSR PUTC
6340     JSR SETLBF  ;reset FP ptrs
6350 XITVBI JMP XITVBV ;leave