A.N.A.L.O.G. ISSUE 72 / MAY 1989 / PAGE 36
Do you use DOS 2.0 or 2.5? If so, this article is for you. If you tire of waiting for DUP.SYS to load, and hate MEM.SAV, you will enjoy this memory-resident DUP.SYS file. The BBK Command Processor.
The idea of a command processor is not new; they have been around for quite some time. Have you ever used UNIX, OSS A+ or SpartaDOS? All these operating systems use a system of input called Command Processing. Put simply, you type in commands, followed by a string of arguments which are then interpreted by the computer. This is what the BBK Command Processor does and what is better is that it gives you most of the functions of DUP.SYS (and some DUP never thought of) in less than 2,000 bytes!
Listing 1 is the data used to create the AUTORUN.SYS file of BBKCP. Please refer to the M/L Editor, found elsewhere in this issue, for typing instructions.
Listing 2 is the MAC/65 source code which need not be typed in to use the program, but is provided so you can see how the program works and so we can refer to it in later discussions.
BBKCP has ten internal commands and can have an extensive library of external commands. The built-in commands are given, with syntax, below:
In the table above, fname stands for any legal DOS filename in the format of [Dx:]filename.ext, where x is any legal drive number. Anything in brackets is considered optional. For optional arguments, certain default conditions will be used. For example, just giving a filename following a command will tell BBKCP that this command is issued to the default device. (The default device is used as the prompt.) So if you typed PROTECT MYFILE.BAS, BBKCP would expand this to PROTECT D1:MYFILE.BAS—assuming D1: is the default device.
To change the default device, just enter it on the command line. For example, if the prompt is D1: , and you type D2:, you are now prompted with D2:.
Any legal Atari device may be used for the default device, such as P:, E:, S: and C:. You should remember, though, that most of the commands are used for disk operation and will give errors with another device.
BBKCP uses the Space (ATASCII 32) as a delimiter to separate commands and arguments on the command line. You may put as many spaces between arguments as you like, however there may be no spaces before a command.
To enter the BBKCP from BASIC or MAC/65 (or any other language cartridge), simply use the DOS command. Any program currently in memory will remain safe unless you use the COPY command or use an external command. (We’ll discuss external commands in a little while.)
You are only required to enter the first three letters of any internal command, but in all examples the entire command name will be used.
ERASE. This command accepts a filename as the argument (wildcards are allowed) and will delete the matching file(s) from your disk. You are not asked for verification, so be careful with this command.
PROTECT. Again only specify the file to be used, and voila, it’s locked. Use UNPROTECT to reverse the locking process. Wildcards are allowed.
RENAME. This requires two arguments, namely the current name of the file and its new name. Separate the names by at least one space to ensure the rename will function correctly. Wildcards are allowed—but be careful not to rename two files with the same name.
Do not supply a device prefix for the new filename with a rename command, as it will cause unpredictable results. It will not destroy your disk, but it will cause some headaches. It is, however, perfectly legal to put a device prefix on the old filename.
DIR. This command takes an optional argument, the directory specifier. The default specifier is [*].[*], but you may use D2:[*].BAS or anything else you may think of. To get the directory from anything but the default device, just type the device name after the DIR command.
COPY. This command will copy one file to another disk drive or file. Wildcards will produce strange results—Don’t use them. COPY will make as many passes as needed to duplicate the file. COPY is mainly for a two-drive system; if used with a one-drive system, it can only duplicate the file to the same disk under a separate name. (Note: If you are using one drive with COPY, make certain that you use unique filenames for the source and destination files. Otherwise you could loose the source file forever!) Another great use for COPY is to copy a text file to the screen or printer. To do this your commands would look like this:
COPY MYFILE.TXT E: (screen) COPY MYFILE.TXT P: (printer)
Using the COPY command will destroy any program in memory, so save your work before performing a COPY.
RUN. This command takes an optional hexadecimal address as its parameter and is used to execute a machine-language program in memory. If an address is supplied, RUN will execute at the supplied address. If no address is given, the last run address will be used. At the end of your machine-language routine, execute an RTS instruction to return to BBKCP.
RUN (with no argument) may also be used to re-run the last external command, assuming it still resides in memory.
The RUN command checks to see if the address given as an argument contains only legal hexadecimal digits and that the number contains no more than four digits. If these conditions are not met, an ERROR 180 is given, and control passes back to BBKCP.
CAR. This command will attempt to pass control to the left cartridge, if it is present. (In the case of an XL or XE, the “left” cartridge is either the built-in BASIC or whatever cartridge is plugged into the computer.) If no cartridge exists, the message “No Cart” will appear, and you are returned to BBKCP; otherwise, the cartridge will be entered.
TYPE. This command will print the contents of a text file (the name of which you supply) to the screen, assuming each line of the text has a maximum of 64 characters per line. Mainly this is used to show the contents of a BATCH file. (More on BATCH files later.)
KILL. Use of this command will (1) remove BBKCP from memory, (2) wipe out any program in memory and (3) pass control to either a cartridge (if present) or go to DOS.
If you enter something that BBKCP does not understand, it assumes that it is an external command, and BBKCP attempts to binary load the file. If what you typed has no filename extension, BBKCP adds on a .COM extension. Executing an external command is destructive to memory, in most cases. External commands must be binary, load-and-go machine-language files. If the file doesn’t begin with a $FF $FF header, an ERROR 181 is given and control passes back to BBKCP.
Next month, a library of external commands will be published.
Batch files are a wonderful way of automating certain processes. A batch file is simply a text file full of commands that either BBKCP understands or commands that the left cartridge understands. You may use a batch file to perform simple operations like copying a few files or running other external commands.
Use any text editor to make a batch file or simply use the COPY command like this:
COPY E1: D1:MYBATCH.BAT
When using this command, type your text one line at a time (maximum length is 64 characters), and press Return after each line. When you are finished press Control-3 to terminate the COPY.
To execute a batch file, type a “[*]” before the filename at the prompt. You are also allowed to chain batch files if the last line in the batch file looks like “[*] batfile”. If no file extension is supplied on the filename a .BAT extension is used. Here is a sample batch file:
;BATCH FILE TO GIVE DIRECTORY AND ;RUN THE CART. ;ANY LINE STARTING MITH A ';' ;IS IGNORED BY BBKCP! DIR CAR
Upon power-up, after it has loaded, BBKCP will attempt to run the batch file called AUTORUN.BAT from Drive 1. If the file does not exist you are left in BBKCP, or control is passed to a cartridge (if present).
The AUTORUN.BAT file is extremely powerful. You could use it to copy files to a RAMdisk or go to the cartridge and run a program or simply print a “hello” message whenever you boot up your system. You can think of this file as giving you an infinite number of AUTORUN.SYS files.
Next time around, we will provide some library functions and tell you how to interface into BBKCP so you can write your own commands!
By the time you read this, Bryan and Carol will have been happily married for a while. Their new (read: same) apartment contains a new Mega ST2, which shares the computer room with the 800XL. The compu-kids get along very well—if you overlook the constant battle for the printer.
1000 DATA 255,255,124,29,198,35,160,0,132,226,140,224,2,140,225,2,7642 1010 DATA 32,212,31,160,0,32,237,33,16 9,121,160,35,32,163,32,32,2915 1020 DATA 221,30,32,195,34,32,149,31,1 69,4,157,74,3,32,86,228,3431 1030 DATA 16,7,76,165,31,160,181,208,2 49,32,81,30,166,220,232,208,1852 1040 DATA 244,166,221,232,208,239,32,1 58,32,169,118,141,226,2,169,30,8118 1050 DATA 141,227,2,32,81,30,166,220,2 32,208,8,166,221,232,208,3,823 1060 DATA 32,81,30,165,220,133,216,165 ,221,133,217,166,226,208,10,230,4112 1070 DATA 226,141,182,35,165,216,141,1 81,35,32,81,30,165,220,56,229,8435 1080 DATA 216,133,218,165,221,229,217, 133,219,230,218,208,2,230,219,32,4146 1090 DATA 43,30,48,9,32,16,30,76,191,2 9,108,226,2,32,221,30,2625 1100 DATA 173,224,2,170,13,225,2,240,9 ,142,181,35,173,225,2,141,7353 1110 DATA 182,35,108,181,35,165,216,13 3,214,165,217,133,215,162,16,169,1717 1120 DATA 7,157,66,3,165,214,157,68,3, 165,215,157,69,3,165,218,8231 1130 DATA 157,72,3,165,219,157,73,3,76 ,86,228,169,220,133,214,169,1388 1140 DATA 0,133,215,133,219,169,2,133, 218,208,210,133,212,132,213,160,4077 1150 DATA 0,177,212,240,11,32,119,30,2 30,212,208,243,230,213,208,239,6730 1160 DATA 96,168,173,7,228,72,173,6,22 8,72,152,96,162,0,169,64,6231 1170 DATA 141,190,2,169,0,133,214,133, 219,169,64,133,218,169,5,133,9097 1180 DATA 215,76,55,30,169,0,133,226,1 33,212,133,213,185,0,5,201,8448 1190 DATA 155,208,8,165,226,240,2,24,9 6,56,96,162,15,221,105,35,5069 1200 DATA 240,5,202,16,248,48,242,6,21 2,38,213,6,212,38,213,6,6672 1210 DATA 212,38,213,6,212,38,213,138, 5,212,133,212,230,226,200,165,4010 1220 DATA 226,201,5,176,212,144,197,16 2,16,208,2,162,32,138,72,169,7488 1230 DATA 12,157,66,3,32,86,228,104,17 0,96,169,81,160,35,32,97,4793 1240 DATA 30,32,130,30,16,6,32,165,31, 76,240,30,173,0,5,201,3083 1250 DATA 155,240,231,96,165,6,208,7,1 69,72,160,35,76,97,30,108,4280 1260 DATA 250,191,32,35,31,133,8,32,10 ,31,108,10,0,169,255,133,3420 1270 DATA 10,169,255,133,11,173,194,32 ,133,12,173,195,32,133,13,172,6407 1280 DATA 216,35,169,0,153,26,3,169,22 8,153,27,3,169,255,141,231,9860 1290 DATA 2,169,255,141,232,2,169,0,14 1,217,35,96,169,33,208,40,6709 1300 DATA 169,35,208,36,169,36,208,32, 32,212,31,164,223,32,237,33,7227 1310 DATA 166,222,169,44,157,186,35,18 5,0,5,157,187,35,232,200,201,169 1320 DATA 155,208,244,169,32,72,208,4, 72,32,212,31,32,221,30,104,4675 1330 DATA 157,66,3,32,149,31,157,74,3, 32,86,228,48,17,96,169,3413 1340 DATA 183,157,68,3,169,35,157,69,3 ,169,0,157,75,3,96,132,2929 1350 DATA 212,169,0,133,213,32,221,30, 32,170,217,32,230,216,160,255,2729 1360 DATA 200,177,243,153,100,35,16,24 8,41,127,153,100,35,169,155,153,8177 1370 DATA 101,35,169,0,153,102,35,169, 93,160,35,76,97,30,173,82,4344 1380 DATA 35,141,183,35,173,83,35,141, 184,35,162,0,185,1,5,201,4620 1390 DATA 58,240,24,185,2,5,201,58,208 ,25,185,1,5,141,184,35,4179 1400 DATA 185,0,5,141,183,35,200,200,2 00,208,8,185,0,5,141,183,7590 1410 DATA 35,200,200,185,0,5,157,186,3 5,201,155,240,10,201,32,240,9976 1420 DATA 6,200,232,224,13,208,236,169 ,155,157,186,35,169,0,157,187,710 1430 DATA 35,134,222,96,185,0,5,201,15 5,240,15,32,154,30,176,13,4965 1440 DATA 165,212,141,181,35,165,213,1 41,182,35,108,181,35,160,180,76,8919 1450 DATA 165,31,169,6,208,2,169,4,141 ,112,32,32,212,31,173,186,6361 1460 DATA 35,201,155,208,11,162,3,189, 86,35,157,186,35,202,16,247,8312 1470 DATA 32,221,30,32,195,34,32,149,3 1,169,6,157,74,3,32,86,1536 1480 DATA 228,48,204,162,16,32,137,30, 48,27,160,0,185,0,5,201,2693 1490 DATA 155,240,3,200,208,246,169,0, 153,1,5,169,0,160,5,32,2930 1500 DATA 97,30,76,121,32,76,221,30,16 9,0,133,8,96,133,212,132,6254 1510 DATA 213,162,255,160,4,232,189,18 6,35,201,46,240,13,201,155,208,2022 1520 DATA 244,177,212,157,186,35,232,1 36,16,247,96,32,255,255,32,35,9213 1530 DATA 31,162,0,32,227,30,32,195,34 ,169,90,141,68,3,169,35,3811 1540 DATA 141,69,3,142,75,3,169,12,141 ,74,3,32,86,228,216,172,6796 1550 DATA 4,228,174,5,228,200,208,1,23 2,140,82,34,142,83,34,160,7232 1560 DATA 0,185,26,3,201,69,240,7,200, 200,200,192,33,144,242,200,2754 1570 DATA 140,216,35,169,234,153,26,3, 169,35,153,27,3,162,80,32,3114 1580 DATA 227,30,160,15,185,0,228,153, 234,35,185,144,3,153,250,35,8862 1590 DATA 136,16,241,169,71,141,238,35 ,169,34,141,239,35,173,217,35,9276 1600 DATA 208,61,238,217,35,165,12,141 ,194,32,165,13,141,195,32,169,7673 1610 DATA 193,133,12,169,32,133,13,165 ,10,141,36,31,165,11,141,40,2472 1620 DATA 31,169,118,133,10,169,33,133 ,11,173,231,2,141,67,31,173,5632 1630 DATA 232,2,141,72,31,169,10,141,2 31,2,169,36,141,232,2,96,5981 1640 DATA 32,228,32,169,255,133,8,216, 32,240,30,173,0,5,201,42,5608 1650 DATA 208,3,76,8,34,201,59,240,238 ,160,0,32,212,31,173,186,8720 1660 DATA 35,201,155,208,15,173,183,35 ,141,82,35,173,184,35,141,83,6943 1670 DATA 35,76,125,33,169,131,133,212 ,169,35,133,213,162,0,160,0,7018 1680 DATA 185,0,5,209,212,208,26,200,1 92,3,208,244,189,161,35,141,1272 1690 DATA 210,33,189,171,35,141,211,33 ,32,237,33,32,255,255,76,125,9409 1700 DATA 33,165,212,24,105,3,133,212, 144,2,230,213,232,224,10,208,1997 1710 DATA 205,32,124,29,76,125,33,185, 0,5,201,32,240,7,201,155,6666 1720 DATA 240,3,200,208,242,185,0,5,20 1,32,208,3,200,208,246,132,1525 1730 DATA 223,96,160,0,169,32,141,0,5, 32,237,33,32,212,31,169,4570 1740 DATA 126,160,35,32,163,32,169,12, 32,112,34,169,183,141,254,35,7238 1750 DATA 169,35,141,255,35,169,4,141, 4,36,169,3,32,112,34,16,818 1760 DATA 10,169,12,132,212,32,112,34, 32,167,31,76,125,33,169,155,5293 1770 DATA 208,35,173,250,35,16,7,162,0 ,160,1,76,255,255,169,0,7126 1780 DATA 141,2,36,141,3,36,169,7,32,1 12,34,48,234,173,233,35,5944 1790 DATA 72,32,119,30,104,162,0,160,1 ,96,141,252,35,32,137,34,4221 1800 DATA 162,80,32,86,228,141,233,35, 16,9,152,72,162,80,32,227,6567 1810 DATA 30,104,168,152,72,160,15,185 ,32,0,72,185,218,35,153,32,5496 1820 DATA 0,104,153,218,35,185,144,3,7 2,185,250,35,153,144,3,104,7058 1830 DATA 153,250,35,136,16,225,104,16 8,96,157,66,3,169,0,157,72,5534 1840 DATA 3,157,68,3,169,48,157,73,3,1 57,69,3,96,169,3,157,3752 1850 DATA 66,3,96,32,165,31,76,225,30, 32,212,31,32,221,30,32,3447 1860 DATA 149,31,32,195,34,169,4,157,7 4,3,32,86,228,48,228,169,7255 1870 DATA 183,160,35,32,97,30,164,223, 32,237,33,32,212,31,32,225,6878 1880 DATA 30,32,149,31,32,195,34,169,8 ,157,74,3,32,86,228,48,3765 1890 DATA 194,32,158,32,162,16,169,7,3 2,175,34,32,86,228,48,6,2817 1900 DATA 169,1,133,226,208,4,169,0,13 3,226,189,72,3,133,224,189,306 1910 DATA 73,3,133,225,162,32,169,11,3 2,175,34,165,224,157,72,3,6191 1920 DATA 165,225,157,73,3,32,86,228,1 65,226,208,200,32,221,30,76,9540 1930 DATA 225,30,78,111,32,67,97,114,1 16,155,0,155,68,49,58,0,1940 1940 DATA 42,46,42,155,69,58,155,69,11 4,114,111,114,45,32,32,32,1930 1950 DATA 32,155,0,48,49,50,51,52,53,5 4,55,56,57,65,66,67,9809 1960 DATA 68,69,70,155,77,79,67,46,155 ,84,65,66,46,69,82,65,2268 1970 DATA 80,82,79,85,78,80,82,69,78,6 8,73,82,67,79,80,82,2445 1980 DATA 85,78,67,65,82,84,89,80,75,7 3,76,82,86,90,94,72,3024 1990 DATA 207,42,10,76,24,31,31,31,31, 32,34,32,31,32,31,118,7947 2000 DATA 30,68,49,58,65,85,84,79,82,8 5,78,46,66,65,84,155,3106 2010 DATA 0,10,36,139,36,162,0,142,217 ,35,134,8,232,134,9,32,4394 2020 DATA 199,32,169,83,160,36,32,97,3 0,32,225,30,32,195,34,32,2731 2030 DATA 149,31,169,4,157,74,3,32,86, 228,8,32,225,30,40,16,1997 2040 DATA 10,165,6,208,3,108,10,0,108, 250,191,169,81,160,35,32,5894 2050 DATA 97,30,169,186,160,35,32,97,3 0,104,104,76,28,34,125,155,4029 2060 DATA 66,66,75,32,67,80,32,45,32,4 0,67,41,32,49,57,56,8780 2070 DATA 55,32,65,78,65,76,79,71,32,6 7,111,109,112,117,116,105,4599 2080 DATA 110,103,155,98,121,58,32,66, 114,121,97,110,32,83,99,104,4308 2090 DATA 97,112,112,101,108,155,0,226 ,2,227,2,10,36,0,0,0,9327
.OPT NOLIST ;------------------------------- ; ;Super Command Processor ; ;by: Bryan Schappel ; ;If the typed line does not ;contain a command, then the ;filename entered will be loaded ;as a binary file. ; ;------------------------------- ; ;*** Commands *** ; ;ERA [fname] = delete file ;REN [f1,f2] = rename f1 to f2 ;PRO [fname] = lock file ;UNP [fname] = unlock file ;DIR [Dn:] = directory of D#: ;RUN [adr] = run at address ;COPY = copy a File ;CAR = enter Cart ;TYPE = read BATCH file ;KILL = KILL BBK CP ; NUMCOM = 10 ;# OF COMMANDS IOCB5 = $0390 ;Adr of IOCB5 MYBUF = $0500 ;I/O Buffer ZIOCB = $20 ;Zpage IOCB ; ;Zero Page Variables ; *= $D6 SL .DS 1 ;Load adr lo SH .DS 1 ;Load adr hi STL .DS 1 ;start adr lo STH .DS 1 ;start adr hi BLL .DS 1 ;length lo BLH .DS 1 ;length hi BAL .DS 1 ;buffer byte 1 BAH .DS 1 ;buffer byte 2 XSAV .DS 1 ;save loc LNPOS .DS 1 ;CP line pos LENSAV .DS 2 ;COPY length COUNT .DS 1 ;counter ; ;OS Equates ; CIOV = $E456 ;CIO Vector ICCOM = $0342 ;CIO Command ICBAL = $0344 ;CIO buffer lo ICBAH = $0345 ;CIO buffer hi ICBLL = $0348 ;CIO length lo ICBLH = $0349 ;CIO length hi AUX1 = $034A ;CIO aux 1 AUX2 = $034B ;CIO aux 2 RUNAD = $02E0 ;run address EOL = $9B ;end of line FR0 = $D4 ;FP number TRAMSZ = $06 ;cart in? BOOT? = $09 ;boot flag DOSVEC = $0A ;DOS Vector DOSINI = $0C ;init vec WARMST = $08 ;warm st flag MEMLO = $02E7 ;lo mem pntr INITAD = $02E2 ;init addr HATABS = $031A ;Handler Table SHFLOK = $02BE ;Caps toggle IFP = $D9AA ;Int to FP FASC = $D8E6 ;FP to ASC INBUFF = $F3 ;FP pntr EDITRV = $E400 ;E: Handler Tab ; ;BUMP Macro ; .MACRO BUMP INC %1 BNE @BUMP INC %1+1 @BUMP .ENDM ; ;PRINT Macro ; .MACRO PRINT LDA #<%1 LDY #>%1 JSR EPRINT .ENDM ; ORIGIN = $1D7C *= ORIGIN ; ;This routine attempts to ;Binary Load a file. ;If the file is not Binary an ;Error #181 is given. ; ;ENTER: ;MYBUF=Filename to load minus ; a .COM extension. ; Load is on IOCB #1 ; LOADIT LDY #0 STY COUNT STY RUNAD STY RUNAD+1 JSR FINDFILE LDY #0 JSR FINDARG LDA #<COM LDY #>COM JSR ADD_EXT JSR CLOSE1 ; JSR SET_OPN JSR SET_DEV JSR SET_4 BPL LOAD_MAIN GO_ERR JMP IOERROR NO_BIN LDY #181 BNE GO_ERR ; ;Main load Loop ; LOAD_MAIN JSR READ2 LDX BAL INX BNE NO_BIN LDX BAH INX BNE NO_BIN JSR SET_DEST ; GET_FIL LDA #<EPRDN STA INITAD LDA #>EPRDN STA INITAD+1 JSR READ2 LDX BAL INX BNE NOT_FF LDX BAH INX BNE NOT_FF JSR READ2 NOT_FF LDA BAL STA STL LDA BAH STA STH LDX COUNT BNE PASS2 INC COUNT STA ADDRESS+1 LDA STL STA ADDRESS PASS2 JSR READ2 LDA BAL SEC SBC STL STA BLL LDA BAH SBC STH STA BLH BUMP BLL JSR GET_DATA BMI JSTART JSR JINIT JMP GET_FIL ; JINIT JMP (INITAD) JSTART JSR CLOSE1 LDA RUNAD TAX ORA RUNAD+1 BEQ LOAD_GO STX ADDRESS LDA RUNAD+1 STA ADDRESS+1 LOAD_GO JMP (ADDRESS) ; ;Get DATA from file ; GET_DATA LDA STL STA SL LDA STH STA SH ; GET_REC LDX #$10 LDA #7 CALL_CIO STA ICCOM,X LDA SL STA ICBAL,X LDA SH STA ICBAH,X LDA BLL STA ICBLL,X LDA BLH STA ICBLH,X JMP CIOV ; ;Read 2 bytes from file ; READ2 LDA #<BAL STA SL LDA #0 STA SH STA BLH LDA #2 STA BLL BNE GET_REC ; ;Set AUX1 to 4 ; SET_4 LDA #4 STA AUX1,X JMP CIOV ; ;E: Print Routine ; ;ENTER: ;A=LSB of string ;Y=MSB of string ; ;EXIT: ;A=zero ; EPRINT STA FR0 STY FR0+1 EPL LDY #0 LDA (FR0),Y BEQ EPRDN JSR EPUT INC FR0 BNE EPL INC FR0+1 BNE EPL EPRDN RTS ; ;E: Put Byte Routine ; ;ENTER: ;A=character to print ; EPUT TAY LDA EDITRV+7 PHA LDA EDITRV+6 PHA TYA RTS ; ;E: Input Routine ; EINPUT LDX #$00 LDA #$40 STA SHFLOK ; ;Get a 64 byte line in MYBUF ; ;ENTER: ;X=IOCB Index ($10,$20,...) ; INP_MYB LDA #0 STA SL STA BLH LDA #64 STA BLL LDA #5 STA SH JMP CALL_CIO ; ;Get a Hex # from MYBUF ; ;ENTER: ;Y=offset into MYBUF where ; the Hex # starts ; ;EXIT: ;FR0,FR0+1 = binary number ; ; GRAB_HEX LDA #0 STA COUNT STA FR0 STA FR0+1 G4LOOP LDA MYBUF,Y CMP #EOL BEQ HEX_OUT CMP #$20 BNE TESTIT HEX_OUT LDA COUNT BEQ HEX_BAD HEX_GOOD CLC RTS HEX_BAD SEC RTS ; TESTIT LDX #$0F G4SCAN CMP HEXDIG,X BEQ GOTG4D DEX BPL G4SCAN BMI HEX_BAD ; GOTG4D ASL FR0 ROL FR0+1 ASL FR0 ROL FR0+1 ASL FR0 ROL FR0+1 ASL FR0 ROL FR0+1 TXA ORA FR0 STA FR0 INC COUNT INY LDA COUNT CMP #5 BCS HEX_BAD BCC G4LOOP ; ;Close IOCB #1 ; CLOSE1 LDX #$10 BNE CLOSEIT ; ;Close IOCB #2 ; CLOSE2 LDX #$20 ; ;Close Any IOCB ; ;ENTER: ;X=IOCB Index ($10,$20,...) ; ;EXIT: ;X=IOCB Index ; CLOSEIT TXA PHA LDA #$0C STA ICCOM,X JSR CIOV PLA TAX RTS ; ;CP's PROMPT + INPUT Routine ; INPUT PRINT PROMPT JSR EINPUT BPL INPUTLV JSR IOERROR JMP INPUT INPUTLV LDA MYBUF CMP #EOL BEQ INPUT RTS ; ;######################## ; ;Start of Commands ; ;######################## ; ;Enter Cart ; GOCART LDA TRAMSZ BNE TRY_CART LDA #<NOCART LDY #>NOCART JMP EPRINT TRY_CART JMP ($BFFA) ; ;Kill CP ; KILL JSR UNHOOK STA WARMST JSR GOCART JMP (DOSVEC) ; ;Un-Hook OS Patches ; UNHOOK LDA #$FF STA DOSVEC CP_HI LDA #$FF STA DOSVEC+1 LDA RESET+1 STA DOSINI LDA RESET+2 STA DOSINI+1 LDY INDEX LDA #<EDITRV STA HATABS,Y LDA #>EDITRV STA HATABS+1,Y OLD_ML LDA #$FF STA MEMLO OLD_MH LDA #$FF STA MEMLO+1 LDA #0 STA SETFLAG RTS ; ;Erase a File ; ERASE LDA #33 BNE DOXIO ; ;Lock a File ; PROTECT LDA #35 BNE DOXIO ; ;Unlock a File ; UNPROTECT LDA #36 BNE DOXIO ; ;Rename a File ; RENAME JSR FINDFILE LDY LNPOS JSR FINDARG LDX XSAV LDA #', STA FNAME,X REN_LP LDA MYBUF,Y STA FNAME+1,X INX INY CMP #EOL BNE REN_LP LDA #32 PHA BNE XIO_ENT ; ;Perform an XIO ; ;ENTER: ;A=XIO Number ;Y=Offset to Filename in MYBUF ; DOXIO PHA JSR FINDFILE XIO_ENT JSR CLOSE1 PLA STA ICCOM,X JSR SET_DEV STA AUX1,X JSR CIOV BMI IOERROR RTS ; ;Set ICBAL/H to DEVICE ; ;ENTER: ;X=IOCB Index ; SET_DEV LDA #<DEVICE STA ICBAL,X LDA #>DEVICE STA ICBAH,X LDA #0 STA AUX2,X RTS ; ;Handle I/O error ; ;ENTER: ;Y=I/O Error # ; ;EXIT: ;Channel #1 is closed ; IOERROR STY FR0 IO_ERR LDA #0 STA FR0+1 JSR CLOSE1 JSR IFP JSR FASC LDY #$FF IOERR INY LDA (INBUFF),Y STA ERBUF,Y BPL IOERR AND #$7F STA ERBUF,Y LDA #EOL STA ERBUF+1,Y LDA #0 STA ERBUF+2,Y LDA #<ERTXT LDY #>ERTXT JMP EPRINT ; ;This will grab a filename from ;MYBUF and put it in the ;device buffer. ; ;ENTER: ;Y=Offset to Filename in MYBUF ; FINDFILE LDA DEFDEV STA DEVICE LDA DEFDEV+1 STA DEVICE+1 ; FIND1 LDX #0 LDA MYBUF+1,Y CMP #': BEQ X2 LDA MYBUF+2,Y CMP #': BNE FIND2 LDA MYBUF+1,Y STA DEVICE+1 LDA MYBUF,Y STA DEVICE INY INY INY BNE FIND2 ; X2 LDA MYBUF,Y STA DEVICE INY INY ; FIND2 LDA MYBUF,Y STA FNAME,X CMP #EOL BEQ FIND3 CMP #$20 BEQ FIND3 INY INX CPX #13 BNE FIND2 FIND3 LDA #EOL STA FNAME,X LDA #0 STA FNAME+1,X STX XSAV RTS ; ;This handles the 'RUN' command ; MEMRUN LDA MYBUF,Y CMP #EOL BEQ RUN_IT ; PULL_IT JSR GRAB_HEX BCS BAD_RUN LDA FR0 STA ADDRESS LDA FR0+1 STA ADDRESS+1 RUN_IT JMP (ADDRESS) BAD_RUN LDY #180 MEM_ERR JMP IOERROR ; ;Get disk Directory ; DIRECT LDA #6 BNE DIR_GO ; ;Get a TYPE of a File ; TYPE LDA #4 DIR_GO STA DIR_COM+1 JSR FINDFILE LDA DEVICE+3 CMP #EOL BNE OPEN_DIR LDX #3 CP_DIR LDA DIRNAM,X STA DEVICE+3,X DEX BPL CP_DIR ; OPEN_DIR JSR CLOSE1 JSR SET_OPN JSR SET_DEV DIR_COM LDA #6 STA AUX1,X JSR CIOV BMI MEM_ERR ; DIROK LDX #$10 JSR INP_MYB BMI DIRDONE LDY #0 DIRCK1 LDA MYBUF,Y CMP #EOL BEQ DIRCK2 INY BNE DIRCK1 DIRCK2 LDA #0 STA MYBUF+1,Y PRINT MYBUF JMP DIROK DIRDONE JMP CLOSE1 ; ;Set Destroy Flag ; SET_DEST LDA #0 STA WARMST RTS ; ;Add File Extension ; ;ENTER: ;A=LSB of extension ;Y=MSB of extension ; ADD_EXT STA FR0 STY FR0+1 LDX #$FF LDY #4 ; EXT_SCAN INX LDA FNAME,X CMP #'. BEQ EXT_RTS CMP #EOL BNE EXT_SCAN EXT_ADD LDA (FR0),Y STA FNAME,X INX DEY BPL EXT_ADD EXT_RTS RTS ; ;This is where RESET comes ; RESET JSR $FFFF JSR UNHOOK ; HOOKUP LDX #$00 JSR CLOSEIT JSR SET_OPN LDA #<EDEV STA ICBAL LDA #>EDEV STA ICBAH STX AUX2 LDA #12 STA AUX1 JSR CIOV ; HOOK1 CLD LDY EDITRV+4 LDX EDITRV+5 INY BNE NO_UPX INX NO_UPX STY EGET+1 STX EGET+2 LDY #0 ; FIND_E LDA HATABS,Y CMP #'E BEQ GOT_E INY INY INY CPY #33 BCC FIND_E ; GOT_E INY STY INDEX LDA #<NEW_E.HAN STA HATABS,Y LDA #>NEW_E.HAN STA HATABS+1,Y ; LDX #$50 JSR CLOSEIT LDY #$0F COPY_E LDA EDITRV,Y STA NEW_E.HAN,Y LDA IOCB5,Y STA BAT_IOCB,Y DEY BPL COPY_E ; LDA #<[BAT_GET-1] STA NEW_E.HAN+4 LDA #>[BAT_GET-1] STA NEW_E.HAN+5 ; SKIP_BAT LDA SETFLAG BNE INIT_RTS INC SETFLAG LDA DOSINI STA RESET+1 LDA DOSINI+1 STA RESET+2 LDA #<RESET STA DOSINI LDA #>RESET STA DOSINI+1 ; LDA DOSVEC STA UNHOOK+1 LDA DOSVEC+1 STA CP_HI+1 LDA #<GO_CP STA DOSVEC LDA #>GO_CP STA DOSVEC+1 ; LDA MEMLO STA OLD_ML+1 LDA MEMLO+1 STA OLD_MH+1 LDA #<PROGEND STA MEMLO LDA #>PROGEND STA MEMLO+1 INIT_RTS RTS ; ;COMMAND PROCESSOR ENTRY ; GO_CP JSR HOOK1 LDA #$FF STA WARMST ; MAIN CLD JSR INPUT ;get line LDA MYBUF CMP #'* ;Batch? BNE NO_BAT JMP BATCH ; NO_BAT CMP #'; BEQ MAIN LDY #0 JSR FINDFILE LDA DEVICE+3 CMP #EOL BNE NO_REM LDA DEVICE STA DEFDEV LDA DEVICE+1 STA DEFDEV+1 JMP MAIN ; NO_REM LDA #<COMTAB STA FR0 LDA #>COMTAB STA FR0+1 LDX #0 COMLP LDY #0 COMCK LDA MYBUF,Y CMP (FR0),Y BNE TRYNEXT INY CPY #3 BNE COMCK ; LDA COMADRL,X STA COMJSR+1 LDA COMADRH,X STA COMJSR+2 JSR FINDARG COMJSR JSR $FFFF JMP MAIN ; TRYNEXT LDA FR0 CLC ADC #3 STA FR0 BCC TRY_NH INC FR0+1 TRY_NH INX CPX #NUMCOM BNE COMLP JSR LOADIT JMP MAIN ; ;Find an Argument on Line ; ;ENTER: ;Y=Offset to start search ; ;EXIT: ;Y=1st char of argument ; FINDARG LDA MYBUF,Y CMP #$20 BEQ NEXTARG CMP #EOL BEQ NEXTARG INY BNE FINDARG NEXTARG LDA MYBUF,Y CMP #$20 BNE FOUNDARG INY BNE NEXTARG FOUNDARG STY LNPOS RTS ; ;Handle a BATCH File ; BATCH LDY #0 LDA #$20 STA MYBUF JSR FINDARG JSR FINDFILE LDA #<BAT LDY #>BAT JSR ADD_EXT BAT_GO LDA #12 JSR BAT_CIO ; LDA #<DEVICE STA ICBALB LDA #>DEVICE STA ICBAHB LDA #4 STA AUX1B LDA #3 JSR BAT_CIO BPL BAT_MAIN LDA #12 STY FR0 JSR BAT_CIO JSR IO_ERR BAT_MAIN JMP MAIN BAT_9B LDA #EOL BNE BAT_XIT ; BAT_GET LDA BAT_IOCB BPL BAT_PROC BAT_NORM LDX #$00 LDY #1 EGET JMP $FFFF ; BAT_PROC LDA #0 STA ICBLLB STA ICBLHB LDA #7 JSR BAT_CIO BMI BAT_NORM LDA BAT_ZIO+15 PHA JSR EPUT PLA BAT_XIT LDX #$00 LDY #1 RTS ; ;Perform BATCH CIO ; BAT_CIO STA ICCOMB JSR BAT_SWAP LDX #$50 JSR CIOV STA BAT_ZIO+15 BPL BAT_SWAP TYA PHA LDX #$50 JSR CLOSEIT PLA TAY ; ;Swap IOCB Blocks ; BAT_SWAP TYA PHA LDY #$0F BAT_SLP LDA ZIOCB,Y PHA LDA BAT_ZIO,Y STA ZIOCB,Y PLA STA BAT_ZIO,Y LDA IOCB5,Y PHA LDA BAT_IOCB,Y STA IOCB5,Y PLA STA BAT_IOCB,Y DEY BPL BAT_SLP PLA TAY RTS ; ;Set COPY IOCB ; ;ENTER: ;X=IOCB Index ;A=CIO Command ; ;EXIT: ;CIO set for I/O of 12K block ;at $3000 ; SET_CPY STA ICCOM,X LDA #0 STA ICBLL,X STA ICBAL,X LDA #$30 STA ICBLH,X STA ICBAH,X RTS ; ;Set ICCOM for Open ; ;ENTER: ;X=IOCB Index ; SET_OPN LDA #3 STA ICCOM,X RTS ; ;Copy I/O Error ; ;ENTER: ;Y=CIO Error # ; ;EXIT: ;Channels #1 and #2 are closed ; CPY_IOR JSR IOERROR JMP CLOSE2 ; ;Handle COPY Verb ; COPY JSR FINDFILE JSR CLOSE1 JSR SET_DEV JSR SET_OPN JSR SET_4 BMI CPY_IOR PRINT DEVICE LDY LNPOS JSR FINDARG JSR FINDFILE JSR CLOSE2 JSR SET_DEV JSR SET_OPN LDA #8 STA AUX1,X JSR CIOV BMI CPY_IOR ; JSR SET_DEST COPY.2 LDX #$10 LDA #7 JSR SET_CPY JSR CIOV BMI EOF LDA #1 STA COUNT BNE SAVLEN ; EOF LDA #0 STA COUNT ; SAVLEN LDA ICBLL,X STA LENSAV LDA ICBLH,X STA LENSAV+1 LDX #$20 LDA #11 JSR SET_CPY LDA LENSAV STA ICBLL,X LDA LENSAV+1 STA ICBLH,X JSR CIOV LDA COUNT BNE COPY.2 JSR CLOSE1 JMP CLOSE2 ; ;Program Text/Buffers ; NOCART .BYTE "No Cart",EOL,0 PROMPT .BYTE EOL DEFDEV .BYTE "D1:",0 DIRNAM .BYTE "*.*",EOL EDEV .BYTE "E:",EOL ERTXT .BYTE "Error- " ERBUF .BYTE " ",EOL,0 HEXDIG .BYTE "0123456789" .BYTE "ABCDEF" COM .BYTE EOL,"MOC." BAT .BYTE EOL,"TAB." ; ;Command Tables ; COMTAB .BYTE "ERAPROUNPREN" .BYTE "DIRCOPRUN" .BYTE "CARTYPKIL" ; COMADRL .BYTE <ERASE .BYTE <PROTECT .BYTE <UNPROTECT .BYTE <RENAME .BYTE <DIRECT .BYTE <COPY .BYTE <MEMRUN .BYTE <GOCART .BYTE <TYPE .BYTE <KILL ; COMADRH .BYTE >ERASE .BYTE >PROTECT .BYTE >UNPROTECT .BYTE >RENAME .BYTE >DIRECT .BYTE >COPY .BYTE >MEMRUN .BYTE >GOCART .BYTE >TYPE .BYTE >KILL ; ADDRESS .WORD EPRDN ;RUN Addr DEVICE .BYTE "D1:" ; ;Buffers ; FNAME .BYTE "AUTORUN.BAT" .BYTE EOL,0 .DS 17 INDEX .DS 1 ;HATABS Index SETFLAG .DS 1 ;set up? ; ;Wedge/Handler Space ; ;For Batch Processing ; BAT_ZIO .DS 16 ;Zpage IOCB NEW_E.HAN .DS 16 ;E: Handler BAT_IOCB .DS 16 ;IOCB #5 Copy ICCOMB = BAT_IOCB+2 ICBALB = BAT_IOCB+4 ICBAHB = BAT_IOCB+5 ICBLLB = BAT_IOCB+8 ICBLHB = BAT_IOCB+9 AUX1B = BAT_IOCB+10 ; PROGEND = * T_LENGTH = PROGEND-ORIGIN ; ;Entry Point to Start CP ; ENTRY LDX #0 STX SETFLAG STX WARMST INX STX BOOT? JSR HOOKUP PRINT CREDITS JSR CLOSE2 JSR SET_OPN JSR SET_DEV JSR SET_4 PHP JSR CLOSE2 PLP BPL HAV_BAT LDA TRAMSZ BNE G_CART JMP (DOSVEC) G_CART JMP ($BFFA) HAV_BAT PRINT PROMPT PRINT FNAME PLA PLA JMP BAT_GO ; CREDITS .BYTE $7D,EOL .BYTE "BBK CP - (C) 1987 " .BYTE "ANALOG Computing",EOL .BYTE "by: Bryan Schappel" .BYTE EOL,0 ; ;Set Run Address ; *= RUNAD .WORD ENTRY .OPT LIST .END
A.N.A.L.O.G. ISSUE 74 / JUNE 1989 / PAGE 46
Welcome back! This month we will discuss external commands, how external commands interface with BBKCP, and how to write your own external commands. There are also four external commands supplied with this installment. Let’s get to it.
Last month we said an external command is something that the internal or memory resident portion of BBKCP does not understand. Such a command is loaded from disk each time it is called. Almost all external commands are destructive to memory, meaning that when an external command is executed any program in memory will be lost!
External commands interface directly by calling routines built into BBKCP. By doing this, filenames, addresses and numbers may be sent to an external command. Table 1 gives the name, address and description of special routines in BBKCP. These routines are called by a 6502 JSR instruction. Any parameters or initial conditions for the routines will be given also.
By using the routines in the table, we may write any number of external commands, performing almost any operation. Here are some samples.
Listings 1 through 4 are the data needed to create your copies of the four external commands described below. You should type in this data using the M/L Editor on page 61. Listings 5 through 8 are the assembly language source codes for the four external commands. You need not type these listings; they are provided only for those who are interested in assembly language programming.
COMMAND #1: DISBAT**
This command will toggle the batch-file processing feature of BBKCP on or off. After the file executes, a message will be displayed telling you about the status of batch processing.
This command is not destructive to memory. It was included because certain programs and games published in ANALOG will fail to run if batch processing is left on.
COMMAND #2; DUMP [addr]
This is a memory dump utility that loads and runs at $2480. It will begin dumping the contents of memory on the screen from the address you specify. Press Start or Break to return to BBKCP.
COMMAND #3: SAVE fname start end [init run]
This allows you to perform a binary save of memory. You must provide a legal filename, a start address, an end address and optional initialize and run addresses.
NAME | HEX ADDRESS | DESCRIPTION |
---|---|---|
ADDRESS | 23B7 | Contains the last RUN address of an external command. Contains address for the RUN command. |
CLOSE1 | 1EE4 | Closes IOCB #1 Returns with X=$10. |
CLOSE2 | 1EE8 | Closes IOCB #2. Returns with X=$20. |
CLOSEIT | 1EEA | Closes ANY IOCB. enter with X=IOCB offset. ($00, $10, $20, …) |
DEFDEV | 2354 | This is the default device and device number in the format D1. |
DEVICE | 23B9 | Contains a correct DOS filename in the format of D1:filename.ext. |
EPRINT | 1E64 | Will print a NULL terminated string to the screen. Enter with A,Y being the LO,HI of your text. (NULL=0). |
FINDARG | 21F4 | Will find the start of the next argument on the command line. Enter with Y = search offset. (i.e. Y = 3 says start search on Character 4.) Exits with Y and LNPOS = start of argument. |
FINDFILE | 1FDB | Enter with Y = start of name and DEVICE will return the filename in the D1:filename.ext format. |
FNAME | 23BC | Start of formatted filename. Same as DEVICE + 3. |
FR0 | 00D4 | Contains the result of a GRAB_HEX. $D4 is LO byte and $D5 is HI byte. |
GOCART | 1F11 | Tries to RUN a cartridge. Calling this is the same as issuing a CAR command. |
GRAB_HEX | 1E9D | Pulls a hex address from the command line. Enter with Y = offset. Exit: Carry Clear means good number Carry Set means bad number. |
HEXDIG | 236B | Contains the ATASCII hexadecimal digits. 0-9 and A-F. |
INPUT | 1EF7 | Prints the current prompt and accepts one 64-byte line from the screen editor. |
IOERROR | 1FAC | Closes IOCB #1 and prints the I/O error number on the screen in decimal. Enter with Y = error number. |
LNPOS | 00DF | Contains the current offset to the argument on the command line. |
MYBUF | 0500 | 64-byte command line buffer. |
WARMST | 0008 | Warm start flag. If the value here is $FF, memory contents are OK. If value is $00, memory will be wiped out. |
COMMAND #4: FORMAT**
This is a diskette initialization program. The menu contains five options: Format, Write DOS, Format and Write DOS, Change Drive and Exit. Just press the number next to the description to select your option. If you choose an option between 1 and 3, you are asked to insert a disk and press Return. Pressing Return begins the process; pressing any other key aborts the option, returning you to the menu.
When you choose to write DOS, FORMAT not only writes the DOS.SYS file, but it also writes the AUTORUN.SYS version of BBKCP to the disk.
Option 4 allows you to alter the drive number that the commands are being executed on. Just type the new drive number, and you are returned to the menu.
Option 5 returns you to BBKCP.
All external commands must be written in machine language, therefore you must be familiar with 6502 assembly language. Here are a couple of rules to follow.
Rule #1: Assemble all your commands with an origin not less than $2410, otherwise part of BBKCP would be overwritten, causing a system crash.
Rule #2: While a batch file is being processed never use IOCB #5. Doing so will most likely cause a system crash. This is the IOCB that the input is being redirected from—take care.
If you write a small external command that is less than 448 bytes long, you may load it at $0540 and set WARMST back to a $FF, thus preserving the contents of memory.
Study the source code for the external commands given in this issue. They will guide you in the method of writing your own commands. Some extra commands you may consider writing would be a multifile copy program, a disk copier or a simple assembler/disassembler. The possibilities are quite endless.
By the time you read this, Bryan and Carol will have been happily married for a while. Tlteir new apartment contains a new Mega ST2, which shares the computer room with the 800XL. The compu-kids get along very well—if you overlook the constant battle for the printer.
1000 DATA 255,255,0,5,84,5,104,104,173,8,34,201,160,240,32,169,6842 1010 DATA 160,141,8,34,169,0,141,9,34, 169,169,141,10,34,169,185,5164 1020 DATA 141,247,32,169,26,141,248,32 ,169,3,141,249,32,208,41,169,8132 1030 DATA 76,141,247,32,141,8,34,169,5 1,141,248,32,169,33,141,249,8339 1040 DATA 32,169,125,141,9,34,169,33,1 41,10,34,172,216,35,169,0,3685 1050 DATA 153,26,3,169,228,153,27,3,76 ,116,228,0,0,0,0,0,8563
1000 DATA 255,255,128,36,78,37,164,223,185,0,5,201,155,208,13,173,7859 1010 DATA 181,35,133,212,173,182,35,13 3,213,76,156,36,32,154,30,144,5925 1020 DATA 1,96,165,212,133,203,165,213 ,133,204,165,204,160,0,32,8,7486 1030 DATA 37,165,203,160,2,32,8,37,160 ,0,132,224,177,203,72,201,8219 1040 DATA 155,208,2,169,27,153,62,37,1 66,224,189,71,37,168,104,32,5646 1050 DATA 8,37,164,224,200,192,8,208,2 25,152,24,101,203,133,203,144,1263 1060 DATA 2,230,204,162,0,169,9,141,66 ,3,169,33,141,68,3,169,3400 1070 DATA 37,141,69,3,169,1,141,73,3,1 41,254,2,32,86,228,48,4093 1080 DATA 7,173,31,208,201,7,240,162,1 69,0,141,254,2,96,72,41,5607 1090 DATA 15,170,189,105,35,153,34,37, 104,41,240,74,74,74,74,170,4761 1100 DATA 189,105,35,153,33,37,96,48,4 8,48,48,32,48,48,32,48,8027 1110 DATA 48,32,48,48,32,48,48,32,48,4 8,32,48,48,32,48,48,6998 1120 DATA 32,48,48,32,32,32,32,32,32,3 2,32,32,155,5,8,11,6077 1130 DATA 14,17,20,23,26,0,0,0,0,0,0,0 ,0,0,0,0,1460
1000 DATA 255,255,16,36,16,37,164,223,32,212,31,164,223,32,237,33,7338 1010 DATA 32,154,30,176,47,165,212,133 ,204,165,213,133,205,164,223,32,2160 1020 DATA 237,33,132,203,32,154,30,176 ,27,165,212,133,206,165,213,133,1365 1030 DATA 207,32,221,30,32,195,34,32,1 49,31,169,8,157,74,3,32,1148 1040 DATA 86,228,16,3,76,221,30,32,205 ,36,48,248,32,205,36,48,4117 1050 DATA 243,32,252,36,48,238,165,204 ,133,214,165,205,133,215,165,206,4834 1060 DATA 56,229,214,133,218,165,207,2 29,215,133,219,230,218,208,2,230,5999 1070 DATA 219,32,10,37,48,206,164,203, 32,237,33,132,203,32,154,30,6261 1080 DATA 176,194,32,241,36,169,226,13 3,204,169,228,133,206,169,2,133,1376 1090 DATA 205,133,207,32,252,36,48,172 ,32,227,36,48,167,164,203,32,7052 1100 DATA 237,33,32,154,30,176,157,32, 241,36,169,224,133,204,169,226,2488 1110 DATA 133,206,169,2,133,205,133,20 7,32,252,36,48,135,32,227,36,6616 1120 DATA 76,221,30,169,255,72,162,16, 169,0,157,72,3,157,73,3,2865 1130 DATA 169,11,157,66,3,104,76,86,22 8,173,17,37,32,207,36,48,2950 1140 DATA 16,173,18,37,76,207,36,165,2 12,141,17,37,165,213,141,18,6377 1150 DATA 37,96,169,4,133,218,169,0,13 3,219,133,215,169,204,133,214,2960 1160 DATA 169,11,162,16,76,55,30,0,0,0 ,0,0,0,0,0,0,2821
1000 DATA 255,255,128,36,199,39,173,184,35,141,90,38,160,2,185,8,4387 1010 DATA 34,153,36,39,185,30,39,153,8 ,34,185,247,32,153,39,39,3394 1020 DATA 185,33,39,153,247,32,136,16, 229,169,65,160,38,32,97,30,3770 1030 DATA 173,90,38,141,36,38,141,55,3 8,141,40,38,32,13,38,48,8480 1040 DATA 251,141,20,39,56,233,49,48,2 43,201,5,176,239,72,169,20,7528 1050 DATA 160,39,32,97,30,133,203,104, 170,240,11,202,240,14,202,240,1634 1060 DATA 17,202,240,27,208,43,32,29,3 7,76,163,36,32,102,37,76,996 1070 DATA 163,36,32,29,37,165,203,208, 3,32,107,37,76,163,36,169,4259 1080 DATA 7,160,39,32,97,30,32,13,38,4 1,127,141,90,38,76,163,1936 1090 DATA 36,160,2,185,36,39,153,8,34, 185,39,39,153,247,32,136,4897 1100 DATA 16,241,96,32,22,38,240,3,230 ,203,96,169,211,160,38,32,7305 1110 DATA 97,30,32,221,30,169,35,157,6 8,3,169,38,157,69,3,169,3625 1120 DATA 0,157,75,3,157,74,3,169,254, 157,66,3,32,86,228,16,4187 1130 DATA 26,152,72,169,21,160,39,32,9 7,30,104,168,32,165,31,230,5150 1140 DATA 203,169,198,160,38,32,97,30, 76,29,38,96,32,22,38,208,1382 1150 DATA 250,169,227,160,38,32,97,30, 32,252,37,169,54,157,68,3,3571 1160 DATA 169,38,157,69,3,32,86,228,48 ,199,32,252,37,169,39,157,6527 1170 DATA 68,3,169,38,157,69,3,32,86,2 28,48,181,162,16,169,24,4382 1180 DATA 157,68,3,169,39,157,69,3,169 ,6,157,72,3,169,0,157,2891 1190 DATA 73,3,169,11,157,66,3,32,86,2 28,48,149,162,16,169,124,5497 1200 DATA 157,68,3,169,29,157,69,3,169 ,57,157,72,3,169,6,157,3461 1210 DATA 73,3,169,11,157,66,3,32,86,2 28,48,32,162,16,169,11,2305 1220 DATA 157,66,3,169,42,157,68,3,169 ,39,157,69,3,169,158,157,5599 1230 DATA 72,3,169,0,157,73,3,32,86,22 8,16,3,76,75,37,76,390 1240 DATA 221,30,32,221,30,32,195,34,1 69,8,157,74,3,169,0,157,3613 1250 DATA 75,3,96,173,37,228,72,173,36 ,228,72,96,169,185,160,38,8095 1260 DATA 32,97,30,32,13,38,201,155,96 ,68,32,58,155,68,32,58,1611 1270 DATA 65,85,84,79,82,85,78,46,83,8 9,83,155,68,32,58,68,1607 1280 DATA 79,83,46,83,89,83,155,125,70 ,79,82,77,65,84,32,85,2130 1290 DATA 84,73,76,73,84,89,155,155,68 ,101,118,105,99,101,32,68,3768 1300 DATA 32,58,155,155,160,205,197,20 6,213,160,155,49,46,32,70,111,7272 1310 DATA 114,109,97,116,155,50,46,32, 87,114,105,116,101,32,68,79,2565 1320 DATA 83,155,51,46,32,70,111,114,1 09,97,116,32,97,110,100,32,2743 1330 DATA 87,114,105,116,101,32,68,79, 83,155,52,46,32,67,104,97,2116 1340 DATA 110,103,101,32,68,114,105,11 8,101,32,35,155,53,46,32,69,1181 1350 DATA 120,105,116,155,155,79,112,1 16,105,111,110,32,62,32,0,73,1680 1360 DATA 110,115,101,114,116,32,68,73 ,83,75,44,32,80,114,101,115,2647 1370 DATA 115,32,82,69,84,85,82,78,0,1 55,155,70,111,114,109,97,4520 1380 DATA 116,116,105,110,103,46,46,46 ,0,155,155,87,114,105,116,105,4635 1390 DATA 110,103,32,68,79,83,46,46,46 ,0,155,155,87,114,105,116,3794 1400 DATA 105,110,103,32,66,66,75,67,8 0,46,46,46,0,78,101,119,698 1410 DATA 32,68,114,105,118,101,32,35, 32,0,32,155,155,0,255,255,6460 1420 DATA 124,29,198,35,160,0,169,185, 26,3,0,0,0,0,0,0,6063 1430 DATA 118,30,68,49,58,65,85,84,79, 82,85,78,46,66,65,84,1198 1440 DATA 155,0,10,36,139,36,162,0,142 ,217,35,134,8,232,134,9,4761 1450 DATA 32,199,32,169,83,160,36,32,9 7,30,32,225,30,32,195,34,3067 1460 DATA 32,149,31,169,4,157,74,3,32, 86,228,8,32,225,30,40,2471 1470 DATA 16,10,165,6,208,3,108,10,0,1 08,250,191,169,81,160,35,6332 1480 DATA 32,97,30,169,186,160,35,32,9 7,30,104,104,76,28,34,125,2318 1490 DATA 155,66,66,75,32,67,80,32,45, 32,40,67,41,32,49,57,8250 1500 DATA 56,55,32,65,78,65,76,79,71,3 2,67,111,109,112,117,116,3590 1510 DATA 105,110,103,155,98,121,58,32 ,66,114,121,97,110,32,83,99,3578 1520 DATA 104,97,112,112,101,108,155,0 ,224,2,2,0,10,36,0,0,7532
.OPT NOLIST ;----------------------------- ;BATCH File Processing Disable ;Utility. ; ;External Command #1 ; ;by: Bryan Schappel ; ;CP Call: ;DISBAT ;----------------------------- ; ;Equates ; FIND_E = $20F7 BATCH = $2208 MAIN = $217D SKIP_BAT = $2133 HATABS = $031A INDEX = $23D8 RESET = $20C1 ; *= $0500 ; START PLA PLA LDA BATCH CMP #$A0 ;LDY # BEQ DIS_BAT ; ;Re-enable Batch Processing ; LDA #$A0 ;LDY # STA BATCH LDA #0 STA BATCH+1 LDA #$A9 ;LDA # STA BATCH+2 LDA #$B9 ;LDA HATABS,Y STA FIND_E LDA #<HATABS STA FIND_E+1 LDA #>HATABS STA FIND_E+2 BNE LEAVE ; ;Disable BATCH Processing ; DIS_BAT LDA #$4C ;JMP STA FIND_E STA BATCH LDA #<SKIP_BAT STA FIND_E+1 LDA #>SKIP_BAT STA FIND_E+2 LDA #<MAIN STA BATCH+1 LDA #>MAIN STA BATCH+2 LDY INDEX LDA #$00 STA HATABS,Y LDA #$E4 STA HATABS+1,Y LEAVE JMP $E474
.OPT NOLIST ;------------------- ;MEMORY DUMPER ;External Command #2 ; ;By: Bryan Schappel ; ;CP Call: ;DUMP [addr] ;------------------- ; ;Equates ; HEXDIG = $2369 GRAB_HEX = $1E9A CONSOL = $D01F LNPOS = $DF SAVEY = $E0 EOL = $9B FR0 = $D4 DSPFLG = $02FE MYBUF = $0500 ADDRESS = $23B5 INDR = $CB ICCOM = $0342 ICBAL = $0344 ICBAH = $0345 ICBLL = $0348 ICBLH = $0349 CIOV = $E456 ; *= $2480 ; START LDY LNPOS LDA MYBUF,Y CMP #EOL BNE GET_HEX LDA ADDRESS STA FR0 LDA ADDRESS+1 STA FR0+1 JMP HEX1 ; GET_HEX JSR GRAB_HEX BCC HEX1 RTS ; ;Memory Dump is Here ; HEX1 LDA FR0 STA INDR LDA FR0+1 STA INDR+1 NEXT LDA INDR+1 LDY #0 JSR MAKE_HEX LDA INDR LDY #2 JSR MAKE_HEX LDY #0 LOOP STY SAVEY LDA (INDR),Y PHA CMP #EOL BNE NOT_EOL LDA #27 NOT_EOL STA HEX_BUF+29,Y LDX SAVEY LDA POSIT,X TAY PLA JSR MAKE_HEX LDY SAVEY INY CPY #8 BNE LOOP TYA CLC ADC INDR STA INDR BCC NO_HI INC INDR+1 NO_HI LDX #$00 LDA #9 STA ICCOM LDA #<HEX_BUF STA ICBAL LDA #>HEX_BUF STA ICBAH LDA #1 STA ICBLH STA DSPFLG JSR CIOV BMI XIT LDA CONSOL CMP #7 BEQ NEXT XIT LDA #0 STA DSPFLG RTS ; ;Make a Number Hexadeximal ; MAKE_HEX PHA AND #$0F TAX LDA HEXDIG,X STA HEX_BUF+1,Y PLA AND #$F0 LSR A LSR A LSR A LSR A TAX LDA HEXDIG,X STA HEX_BUF,Y RTS ; ;Buffers ; HEX_BUF .BYTE "0000 00 00 00 " .BYTE "00 00 00 00 00 " .BYTE " ",EOL POSIT .BYTE 5,8,11,14,17,20 .BYTE 23,26
.OPT NOLIST ;------------------------------- ;BINARY SAVE ;External Command #3 ; ;by: Bryan Schappel ; ;CP Call: ;SAVE fname start end [init run] ;------------------------------- ; ;Equates ; LNPOS = $DF GRAB_HEX = $1E9A FINDFILE = $1FD4 FINDARG = $21ED CALL_CIO = $1E37 CLOSE1 = $1EDD SET_DEV = $1F95 SET_OPN = $22C3 RUNAD = $02E0 INITAD = $02E2 FR0 = $D4 ICCOM = $0342 ICBAL = $0344 ICBAH = $0345 ICBLL = $0348 ICBLH = $0349 AUX1 = $034A CIOV = $E456 LPOS = $CB S_SAVE = $CC E_SAVE = $CE SL = $D6 SH = $D7 BLL = $DA BLH = $DB ; *= $2410 ; START LDY LNPOS JSR FINDFILE ;filename LDY LNPOS JSR FINDARG JSR GRAB_HEX ;start adr BCS NO_SAVE LDA FR0 STA S_SAVE LDA FR0+1 STA S_SAVE+1 LDY LNPOS JSR FINDARG STY LPOS JSR GRAB_HEX ;end adr BCS NO_SAVE LDA FR0 STA E_SAVE LDA FR0+1 STA E_SAVE+1 ; ;Start Save ; JSR CLOSE1 ;open file JSR SET_OPN JSR SET_DEV LDA #8 STA AUX1,X JSR CIOV BPL DO_SAVE ; NO_SAVE JMP CLOSE1 ; DO_SAVE JSR PUT_FF ;send $FF BMI NO_SAVE ;header JSR PUT_FF BMI NO_SAVE JSR PUT_HEADER ;send load BMI NO_SAVE ;adr's ; LDA S_SAVE ;get len STA SL ;to save LDA S_SAVE+1 STA SH LDA E_SAVE SEC SBC SL STA BLL LDA E_SAVE+1 SBC SH STA BLH INC BLL BNE N_HI INC BLH N_HI JSR S_SEG ;send seg BMI NO_SAVE LDY LPOS JSR FINDARG STY LPOS JSR GRAB_HEX ;init adr BCS NO_SAVE JSR MOVE_2 LDA #<INITAD STA S_SAVE LDA #<[INITAD+2] STA E_SAVE LDA #>INITAD STA S_SAVE+1 STA E_SAVE+1 JSR PUT_HEADER ;put addr's BMI NO_SAVE JSR PUT_TEMP ;init adr BMI NO_SAVE LDY LPOS JSR FINDARG JSR GRAB_HEX ;run adr BCS NO_SAVE JSR MOVE_2 ;save it LDA #<RUNAD ;headers STA S_SAVE LDA #<[RUNAD+2] STA E_SAVE LDA #>RUNAD STA S_SAVE+1 STA E_SAVE+1 JSR PUT_HEADER ;send 'em BMI NO_SAVE JSR PUT_TEMP ;send run adr JMP CLOSE1 ;all done ; ;Send a $FF ; PUT_FF LDA #$FF ; ;Put 1 byte to file ; PUT_BYTE PHA LDX #$10 LDA #0 STA ICBLL,X STA ICBLH,X LDA #11 STA ICCOM,X PLA JMP CIOV ; ;Put the TEMP location ; PUT_TEMP LDA TEMP JSR PUT_BYTE BMI P_RTS LDA TEMP+1 JMP PUT_BYTE ; ;Move FR0 to TEMP ; MOVE_2 LDA FR0 STA TEMP LDA FR0+1 STA TEMP+1 P_RTS RTS ; ;Put the Header Out ; PUT_HEADER LDA #4 STA BLL LDA #0 STA BLH STA SH LDA #S_SAVE STA SL S_SEG LDA #11 LDX #$10 JMP CALL_CIO ; TEMP .DS 2
.OPT NOLIST ;------------------- ;DISK FORMATTER ;External Command #4 ; ;by: Bryan Schappel ; ;CP Call: ;FORMAT ;------------------- ; ;Equates ; CLOSE1 = $1EDD CLOSE2 = $1EE1 SET_DEV = $1F95 SET_OPN = $22C3 EPRINT = $1E61 ICCOM = $0342 ICBAL = $0344 ICBAH = $0345 ICBLL = $0348 ICBLH = $0349 AUX1 = $034A AUX2 = $034B CIOV = $E456 EOL = $9B DEVICE = $23B7 IOERROR = $1FA5 ORIGIN = $1D7C EPRDN = $1E76 ERROR = $CB BATCH = $2208 FIND_E = $20F7 ; ;PRINT macro ; .MACRO PRINT LDA #<%1 LDY #>%1 JSR EPRINT .ENDM ; *= $2480 ; START LDA DEVICE+1 STA MY_DEV LDY #2 SV LDA BATCH,Y STA HOLD,Y LDA NORM,Y STA BATCH,Y LDA FIND_E,Y STA HOLD+3,Y LDA NORM+3,Y STA FIND_E,Y DEY BPL SV BEGIN PRINT TITLE LDA MY_DEV STA FMAT+1 STA DOSNAME+1 STA AUTO+1 ; M_LOOP JSR GET_KEY BMI M_LOOP STA OPTION SEC SBC #'1 BMI M_LOOP CMP #5 BCS M_LOOP PHA PRINT OPTION STA ERROR PLA TAX BEQ OPT1 DEX BEQ OPT2 DEX BEQ OPT3 DEX BEQ OPT4 BNE OPT5 ; ;Just Format Disk ; OPT1 JSR FORMAT JMP BEGIN ; ;Just Write DOS+BBKCP ; OPT2 JSR WRITE_DOS JMP BEGIN ; ;Format and Write DOS ; OPT3 JSR FORMAT LDA ERROR BNE G_B JSR WRITE_IT G_B JMP BEGIN ; ;Get new device number ; OPT4 PRINT NEW_DEV JSR GET_KEY AND #$7F STA MY_DEV JMP BEGIN ; ;Return to BBKCP ; OPT5 LDY #2 LD LDA HOLD,Y STA BATCH,Y LDA HOLD+3,Y STA FIND_E,Y DEY BPL LD RTS ; ;Format the Disk ; FORMAT JSR PROMPT BEQ GO_F INC ERROR RTS GO_F PRINT F_MAT JSR CLOSE1 LDA #<FMAT STA ICBAL,X LDA #>FMAT STA ICBAH,X LDA #0 STA AUX2,X STA AUX1,X LDA #254 STA ICCOM,X JSR CIOV BPL G_BEGIN ; OOPS TYA PHA PRINT EOL2 PLA TAY JSR IOERROR INC ERROR PRINT H_KEY JMP KEY_RET G_BEGIN RTS ; ;Write DOS and BBKCP ; WRITE_DOS JSR PROMPT BNE G_BEGIN WRITE_IT PRINT W_DOS JSR SET_80 LDA #<DOSNAME STA ICBAL,X LDA #>DOSNAME STA ICBAH,X JSR CIOV BMI OOPS ; JSR SET_80 LDA #<AUTO STA ICBAL,X LDA #>AUTO STA ICBAH,X JSR CIOV BMI OOPS LDX #$10 LDA #<HEADER STA ICBAL,X LDA #>HEADER STA ICBAH,X LDA #6 STA ICBLL,X LDA #0 STA ICBLH,X LDA #11 STA ICCOM,X JSR CIOV BMI OOPS LDX #$10 LDA #<ORIGIN STA ICBAL,X LDA #>ORIGIN STA ICBAH,X LDA #$39 STA ICBLL,X LDA #$06 STA ICBLH,X LDA #11 STA ICCOM,X JSR CIOV BMI J_ERR LDX #$10 LDA #11 STA ICCOM,X LDA #<END_DATA STA ICBAL,X LDA #>END_DATA STA ICBAH,X LDA #<DATLEN STA ICBLL,X LDA #>DATLEN STA ICBLH,X JSR CIOV BPL J_CL J_ERR JMP OOPS J_CL JMP CLOSE1 ; ;Set up IOCB #1 ; SET_80 JSR CLOSE1 JSR SET_OPN LDA #8 STA AUX1,X LDA #0 STA AUX2,X RTS ; ;Get a Key ; GET_KEY LDA $E425 PHA LDA $E424 PHA RTS ; ;Prompt for a Disk ; PROMPT PRINT P_TXT KEY_RET JSR GET_KEY CMP #EOL RTS ; ;Program Data ; FMAT .BYTE "D :",EOL AUTO .BYTE "D :AUTORUN.SYS",EOL DOSNAME .BYTE "D :DOS.SYS",EOL TITLE .BYTE $7D,"FORMAT " .BYTE "UTILITY",EOL .BYTE EOL,"Device D" MY_DEV .BYTE " :",EOL,EOL .BYTE " MENU ",EOL .BYTE "1. Format",EOL .BYTE "2. Write DOS",EOL .BYTE "3. Format and " .BYTE "Write DOS",EOL .BYTE "4. Change Drive #" .BYTE EOL .BYTE "5. Exit",EOL,EOL .BYTE "Option > ",0 ; P_TXT .BYTE "Insert DISK, " H_KEY .BYTE "Press RETURN",0 F_MAT .BYTE EOL,EOL .BYTE "Formatting...",0 W_DOS .BYTE EOL,EOL .BYTE "Writing DOS...",0 W_CP .BYTE EOL,EOL .BYTE "Writing BBKCP...",0 NEW_DEV .BYTE "New Drive # ",0 OPTION .BYTE " " EOL2 .BYTE EOL,EOL,0 HEADER .WORD $FFFF,$1D7C,$23C6 NORM .BYTE $A0,$00,$A9 .BYTE $B9,$1A,$03 HOLD .WORD $00,$00,$00 ; ;CP Run Stuff ; END_DATA .WORD EPRDN .BYTE "D1:AUTORUN.BAT" .BYTE EOL,0 .WORD $240A .WORD $248B LDX #0 STX $23D9 STX $08 INX STX $09 JSR $20C7 LDA #$53 ;credits LDY #$24 JSR EPRINT JSR CLOSE2 JSR SET_OPN JSR SET_DEV LDA #4 STA AUX1,X JSR CIOV PHP JSR CLOSE2 PLP BPL HAV_BAT LDA $06 BNE G_CART JMP ($0A) G_CART JMP ($BFFA) HAV_BAT LDA #$51 ;prompt LDY #$23 JSR EPRINT LDA #$BA ;fname LDY #$23 JSR EPRINT PLA PLA JMP $221C ; .BYTE $7D,EOL .BYTE "BBK CP - (C) 1987 " .BYTE "ANALOG Computing",EOL .BYTE "by: Bryan Schappel" .BYTE EOL,0 .WORD $02E0 .WORD $02 .WORD $240A DATLEN = *-END_DATA