MicroDOS
Dennis Keathley
Webster, TX
This extraordinarily useful Atari Disk technique lets you eliminate DUP.SYS and MEM. SAV from most of your disks and to call a function menu directly from BASIC.
It's late at night and you've been working on major revisions to a huge BASIC program for four hours. You finally finish and want to save it back on disk as ULTIMATE.003 (versions 001 and 002 are already on the disk). Upon SAVEing it, you get ERROR 162 (disk full). You think to yourself, "I'll save it as version 001 since that version is out of date anyway." You get another error, ERROR 167 (file locked). "Well I'll just type DOS and unlock the file. After all, MEM.SAV will preserve my program." So you type "DOS" and sit back to twiddle your thumbs for a minute or so. Wait! There's something wrong. There was no MEM.SAV file on the disk. You deleted it because you needed more free sectors. Four hours of work are lost forever.
Save Yourself 88 Sectors And 75 Seconds
Would you like to eliminate the need for DUP.SYS and MEM.SAV on most of your disks?
The Disk Operating System, version 2.0, is a powerful and well-designed piece of software. It also allows you more free RAM for programming use than DOS 1 by moving many of the utility functions into a separate file called DUP.SYS. The Disk Utility Programs are loaded into memory only when requested by typing DOS. The trade-off is that the file DUP.SYS (42 sectors) must be on your disk in drive #1, and it requires 15 to 20 seconds to load into RAM.
Another trade-off is that the BASIC program in RAM will be lost unless you have a MEM.SAV file (45 sectors) on your disk in drive #1, and using MEM.SAV requires almost a minute longer. Eliminating the need for DUP.SYS and MEM.SAV saves you 88 sectors and 75 seconds.
When DOS is booted into RAM at power-on, the portion that remains memory-resident at all times is called the File Management System. The FMS allows you to perform some file manipulation and directory modifications. The most common way to do this is to type DOS which gives you the DOS 2.0 Menu contained in DUP.SYS. Some schemes have been developed to access the RMS functions from BASIC, but they require you to either remember the exact XIO command or to have numerous short programs on your disk that remember them for you (more time and sectors wasted).
Wouldn't it be nice to be able to call a function menu from BASIC without using additional memory, losing your BASIC program, or performing disk I/O?
MicroDOS is a machine language program that is loaded into page six of RAM (Decimal 1536 to 1791), an area conveniently left to the user by the wizards that designed the Atari Operating System. When executed, MicroDOS gives you a menu of FMS functions, which allows you to select the function and desired filename. You may perform as many functions as you wish, and then return to BASIC. And your BASIC program is still there, intact.
Program 1 is the assembly listing. For those of you who do not have an assembler, Program 2 provides a BASIC program to accomplish the same result. If using an assembler, you may designate "D:AUTORUN.SYS" as the binary output file. This will perform automatic loading of MicroDOS when DOS is booted into RAM. If you are presently using an AUTORUN.SYS file, you may append it onto this one using the /A (append) feature of the copy (C) option of the DOS 2.0 menu. The comments in the listings make them self-explanatory.
For ease of use, we "steal" the DOS jump vector, DOSVEC ($0A or decimal 10) and point it to MicroDOS. Perform POKE 10,0 and POKE 11,6. When you type "DOS", BASIC jumps to the address specified in DOSVEC and DOSVEC + 1 (low byte, high byte). Now it will jump to MicroDOS instead. One more detail: when SYSTEM RESET is pressed, DOS restores DOSVEC to the original value. To prevent this, POKE 5446,0 and POKE 5450,6. DOS will now reload DOSVEC with $0600 (the start of MicroDOS) when SYSTEM RESET is pressed.
Note that the last six lines of the assembler listing before the .END statement will cause this to be done automatically when the file is loaded. In the BASIC listing, the last 16 numbers perform this. Omit them if you desire and subtract 16 from the 342 in line two. If you should desire to reset DOSVEC so that DUP.SYS may be loaded, POKE 10,159 and POKE 11,23. Now, typing "DOS" will load DUP.SYS, but SYSTEM RESET will cause DOSVEC to point to MicroDOS.
Upon typing "DOS", MicroDOS will display the menu:
LOCK UNLOCK DELETE RENAMEFORMAT MENU ADOS BASIC
Note: Underlined letters are inverse video.
Enter the command you desire (only the first letter is necessary). You will then see:
FN?
Enter your filename and press RETURN. You must enter the "D:" or "D2:" at the beginning of your filename so that FMS will know which drive to access (do not use quotes, as in BASIC). The function will be performed and the menu will reappear. Note: if you selected RENAME, the correct filename input is "D1:fn1,fn2". Only one "Dn:" is needed and the comma is required.
If you selected FORMAT, instead of FN? you will see:
FD #
to warn you that the information on the disk will be destroyed. Type "D1",RETURN (or D2,D3, etc.) to format, or anything else to abort formatting.
If you selected MENU, you will see:
D #?
as a prompt. Enter the drive number (single digit) from which you wish to see a disk directory, and it will scroll across the screen. Use CTRL 1 to momentarily halt the scrolling, and CTRL 1 to resume. The directory will stay on the screen until you press RETURN once more.
Making Use Of The 6502 Stack
Selecting ADOS will allow you to load DUP.SYS in the normal way if you have a need to do that (and you shouldn't often!). As a safety feature, to select this function you must type the first two letters. If you enter an invalid filename or if FMS is unable to perform the function, MicroDOS will just return to the ">" prompt. To return to BASIC, type "B" (or any other letter that is not a selection letter).
The most difficult part about writing MicroDOS was fitting it into just one page (256 bytes) of RAM. Due to this constraint, a Disk Directory option could not be included in page six. In order to add this feature, the MicroDOS selection menu and input buffer had to be moved to the beginning of page one. What? You thought page one of RAM was used by the 6502 microprocessor as a stack area? Well, it is, but the 6502 will never need more than the top one-third. So we will use the bottom one-third.
If you spend a portion of your time programming in BASIC, you will probably find MicroDOS well worth the time spent typing it in. It has saved me much time and frustration.
Program 1. Source Listing
0100 .TITLE "MICRO-DOS" 0110 REM COPYRIGHT 1982 0120 REM ALL COMMERCIAL RIGHTS 0130 REM RESERVED BY DENNIS KEATHLEY 0140 .OPT NOEJECT 0150 ; 0160 ; DEFINE EQUATES 0170 ; 0180 * = $0342 0190 ICCMD * = * + 2 0200 ICCMD1 = ICCMD + 16 0210 ICBAL * = * + 1 0220 ICBAL 1 = ICBAL + 16 0230 ICBAH * = * + 3 0240 ICBAH1 = ICBAH + 16 0250 ICBLL * = * + 1 0260 ICBLL1 = ICBLL + 16 0270 ICBLH * = * + 1 0280 ICBLH1 = ICBLH + 16 0290 ICAX1 * = * + 1 0300 ICAX11 = ICAX1 + 16 0310 ICAX2 * = * + 1 0320 CIOV = $E456 0330 OPEN = 3 0340 CLOSE = 12 0350 GET C = 7 0360 PUT C = 11 0370 GET R = 5 0380 PUT R = 9 0390 EOL = 155 0400 CLR = 125 0410 TAB = 127 0420 ; ******** MICRODOS SOURCE CODE ******** 0430 * = $0600 0440 ; 0450 ; DISPLAY MENU ON SCREEN 0460 ; 0470 INIT 0480 LDY #MBUF & 255 0490 LDX #EOM-MBUF 0500 LDA #PUTC 0510 JSR IOE2 0520 ; 0530 ; ACCEPT COMMAND 0540 ; 0550 GRAB 0560 JSR INPUT 0570 ; 0580 ; EXECUTE COMMAND 0590 ; 0600 JSR IOP 0610 BPL INIT 0620 BMI GRAB If CIOV error, Y > 1270630 ; 0640 ; INPUT CONTROL ROUTINE 0650 ; 0660 INPUT 0670 ; PUT PROMPT ON SCREEN 0680 LDY #QBUF & 255 0690 LDX #2 0700 JSR Q 0710 ; GET COMMAND CHOICE 0720 JSR IN 0730 LDY #6 0740 STY ICAX11 To "open directory" later 0750 LOOP 0760 DEY 0770 BEQ EXIT 0780 LDA ASCII-1, Y 0790 CMP KBUF 0800 BNE LOOP 0810 LDA CMD-1, Y 0820 PHA Save command # 0830 CMP #$FE 0840 BNE CONT 0850 ; VERIFY FORMAT COMMAND 0860 LDY #QBUF + 5&255 0870 LDX #3 0880 JSR Q 0890 JSR IN 0900 LDA KBUF 0910 CMP #68 Is first letter a "D"? 0920 BNE EXIT No, then leave MICRO-DOS 0930 BEQ RT 0940 CONT 0950 ; PUT PROMPT ON SCREEN 0960 LDY #QBUF + 2 & 255 0970 LDX #3 0980 JSR Q 0990 ; GET FILENAME 1000 JSR IN 1010 RT 1020 PLA Retrieve FMS command 1030 RTS 1040 ; 1050 ; PROMPT ON SCREEN ROUTINE 1060 ; 1070 Q 1080 LDA #PUTC 1090 JSR IOE 1100 RTS 1110 ; 1120 ; EDITOR LINE IN ROUTINE 1130 ; 1140 IN 1150 LDY #KBUF & 255 1160 LDX #40 1170 LDA #GETR 1180 JSR IOE2 1190 RTS 1200 ; 1210 ; EXIT AND I/O ROUTINES 1220 ; 1230 EXIT 1240 LDA KBUF 1250 CMP #77 Directory Request? 1260 BNE DOS No, 90 to DOS 1270 LDY #QBUF + 6 & 255 1280 LDX #3 1290 JSR Q Put D#? prompt on screen 1300 LDY #SBUF + 1 & 255 1310 LDX #1 1320 LDA #GETR 1330 JSR IOE2 Get drive # 1340 LDY #58 1350 STY SBUF + 2 Restore colon 1360 LDY #SBUF & 255 1370 LDA #OPEN 1380 JSR IOP2 Open directory 1390 AGAIN 1400 LDA #19 1410 STA ICBLL1 1420 LDA #GETR 1430 JSR IOP Get directory entry 1440 BMI THRU Last entry? Go to THRU 1450 LDY #KBUF-1 &255 Tab is first character 1460 LDX #20 1470 LDA #PUTR 1480 JSR IOE2 Put directory entry on screen 1490 BPL AGAIN Go get another entry 1500 THRU 1510 LDA #CLOSE 1520 JSR IOP Close directory 1530 JSR IN Wait for RETURN pressed 1540 JMP INIT Go to selection menu 1550 ; 1560 DOS 1570 CMP #65 Is DOS desired? 1580 BNE BASIC No, exit MICRODOS 1590 LDA #68 1600 CMP KBUF + 1 Additional check for safety 1610 BNE BASIC 1620 JMP 6047 Load DUP.SYS 1630 ; 1640 BASIC 1650 JMP $A04D Warm start entry 1660 ; 1670 IOE 1680 PHA 1690 LDA #QBUF/256 1700 STA ICBAH1710 PLA 1720 ENT 1730 STY ICBAL 1740 STX ICBLL 1750 LDK #0 1760 STX ICBLH 1770 STX ICBLH1 1780 BEQ 10 1790 IOE2 1800 PHA 1810 LDA #KBUF/256 1820 STA ICBAH 1830 STA ICBAH1 1840 PLA 1850 BNE ENT 1860 ; 1870 IOP 1880 LDY #KBUF&255 1890 IOP2 1900 STY ICBAL 1 1910 LDX #$10 1920 I0 1930 STA ICCMD, X 1940 JSR CIOU 1950 RTS 1960 ; 1970 ; DEFINE MENU AND BUFFERS 1980 ; 1990 ASCII 2000 .BYTE 76,85,68,82,70 2010 CMD 2020 .BYTE $23, $24, $21, $20, $FE 2030 QBUF 2040 .BYTE 29,">FN?",198,"D#?" 2050 ; PUT THE REST IN PAGE 1 2060 * = $100 2070 SBUF 2080 .BYTE "Dl :*.*",EOL,TAB 2090 KBUF 2100 *= * + 29 2110 MBUF 2120 .BYTE CLR,204,"OCK", EOL 2130 .BYTE 213, "NLOCK", EOL 2140 .BYTE 196, "ELETE", EOL 2150 .BYTE 210, "ENAME", EOL 2160 .BYTE 198, "ORMAT", EOL 2170 .BYTE 205, "ENU", EOL 2180 .BYTE 193,196, "OS", EOL 2190 .BYTE 194, "ASIC", EOL 2200 EOM 2210 * = 10 2220 .BYTE 0,6 2230 *=5446 2240 .BYTE 0 2250 * = 5450 2260 .BYTE 6 2270 END
Program 2. BASIC Loader
1 OPEN #1, 8, 0, "D:MICRODOS.OBJ" 2 FOR I = 1 TO 342 3 READ A 4 PUT #1, A 5 NEXT I 6 END 10 DATA 255, 255, 0, 6, 253, 6, 160, 37, 162, 50, 169, 11, 32, 209, 6, 32, 19, 6, 32, 221, 6, 16, 239, 48, 246, 160, 245, 162, 2, 32, 84, 6, 32, 90 20 DATA 6, 160, 6, 140, 90, 3, 136, 240, 63, 185, 234, 6, 205, 8, 1, 208, 245, 185, 239, 6, 72, 201, 254, 208, 19, 160, 250, 162, 3, 32, 84, 6, 32 30 DATA 90, 6, 173, 8, 1, 201, 68, 208, 30, 240, 10, 160, 247, 162, 3, 32, 84, 6, 32, 90, 6, 104, 96, 169, 11, 32, 186, 6, 96, 160, 8, 162, 40 40 DATA 169, 5, 32, 209, 6, 96, 173, 8, 1, 201, 77, 208, 62, 160, 251, 162, 3, 32, 84, 6, 160, 1, 162, 1, 169, 5, 32, 209, 6, 160, 58, 140, 2 50 DATA 1, 160, 0, 169, 3, 32, 223, 6, 169, 19, 141, 88, 3, 169, 5, 32, 221, 6, 48, 11, 160, 7, 162, 20, 169, 9, 32, 209, 6, 16, 233, 169, 12 60 DATA 32, 221, 6, 32, 90, 6, 76, 0, 6, 201, 65, 208, 10, 169, 68, 205, 9, 1, 208, 3, 76, 159, 23, 76, 77, 160, 72, 169, 6, 141, 69, 3, 104 70 DATA 140, 68, 3, 142, 72, 3, 162, 0, 142, 73, 3, 142, 89, 3, 240, 19, 72, 169, 1, 141, 69, 3, 141, 85, 3, 104, 208, 228, 160, 8, 140, 84, 3 80 DATA 162, 16, 157, 66, 3, 32, 86, 228, 96, 76, 85, 68, 82, 70, 35, 36, 33, 32, 254, 29, 62, 70, 78, 63, 198, 68, 35, 63, 0, 1, 7, 1, 68 90 DATA 49, 58, 42, 46, 42, 155, 127, 37, 1, 86, 1, 125, 204, 79, 67, 75, 155, 213, 78, 76, 79, 67, 75, 155, 196, 69, 76, 69, 84, 69, 155, 210, 69 100 DATA 78, 65, 77, 69, 155, 198, 79, 82, 77, 65, 84, 155, 205, 69, 78, 85, 155, 193, 196, 79, 83, 155, 194, 65, 83, 73, 67, 155, 10, 0, 11, 0, 0 110 DATA 6, 70, 21, 70, 21, 0, 74, 21, 74, 21, 6