Classic Computer Magazine Archive A.N.A.L.O.G. ISSUE 62 / JULY 1988 / PAGE 34

Boot
Directory

by Bill Bodenstein

It finally happened! Sooner or later, I knew it would. It was inevitable that my 1030 disk drive would break down. Naturally, it quits on me between terms of my summer course (I'm taking COBOL-why, I'm not sure), when I'm a little short of money. And of course it conks out in the middle of various programming projects-most, I might add, involve disk I/O. Well, I remained undaunted in the heinous face of disaster, and thanks to the help of a friend (I'd name my friend here, but he'd no doubt sue me for libel or something), I completed one of these projects.

48k disk

    The program is called Boot-Directory. You'll find the BASIC code in Listing 1 and the MAC/65 source code in Listing 2. It works on any single-density Atari DOS 2.0 or 2.5 disk, and takes up no space at all-it's stored in the currently unused third boot sector. Just type in and run Listing 1, insert the disk you want modified, hit RETURN, and voila! The BootDirectory machine-language routine will load and run automatically every time you boot that disk. Re-run the BASIC program to modify other disks. To remove Boot-Directory, just go to DOS and use the Write DOS Files option.

What's
Going On?

    Oh, maybe I ought to explain exactly what Boot-Directory is and how to use it. When you boot a DOS 2.0/2.5 disk, the three boot sectors (1-3) are loaded into memory by the operating system. Then control is turned over to the boot routine beginning at the seventh byte from the first sector. From here, a short machine-language program loads the File Manager System contained in the DOS.SYS file into memory, and control is reverted back to the operating system. What we'll do is cleverly insert a jump instruction to the code beginning at the third sector (BootDirectory) at the seventh byte in the first sector, then exit to $0714, the start of the DOS boot-load routine. For more info, read Inside Atardos by Bill Wilkinson.

How
It Works.

    Okay, now we know how BootDirectory gets control, but what does it do? Simple. It lists all the files from the directory; it starts at sector 361 and prints the names of all undeleted, existing files.
    If you hold down the SELECT key, Boot-Directory will, upon completion, loop until you hit RESET. Thus, if you're just looking for a file, insert a disk while holding down SELECT and wait until the directory is completely listed. If you do not see the file you want, insert another disk and press RESET. You could, of course, reboot by powering-down, but you never know when the computer might not want to power-up! (Remind one to tell you about the time my computer went on the blink .... ) The entire Boot-Directory routine is limited to one sector, just 128 bytes. Not much space for super-neato features, I'm afraid. But, nevertheless, as you can see from examining Listing 2, I did manage just barely-to squeeze the entire code into sector 3. If you modify the MAC/65 source code, don't forget the 128-byte maximum size! As for me, I won't be modifying anything for a while. Anyone know a place that repairs disk drives cheap?

Listing 1.:
Basic


JO 10 REM ** BOOT-DIRECTORY Maker **
GX 11 REM by Bill Bodenstein
JA 12 REM COPYRIGHT 1988 BY ANALOG COMPUT
   ING
BQ 20 DIM X$(25),A$(1):FOR X=1 TO 25:READ
    A:X$(X,X)=CHR$(A):NEXT X
YI 24 IF PEEK(1799)=20 AND PEEK(1860=7 T
   HEN 30
HS 26 ? "Atari File manager system not in
   ":? "memory. Reboot with DOS 2.0 or 2.
   5.":STOP
UD 30 ? "    *** BOOT-DIRECTORY Maker ***
   ":? :? "This program will write a shor
   t m/l"
GS 40 ? "routine (BOOT-DIRECTORY) to sect
   or 3":? "which will list all files nam
   es in":? "the directory at boot-up."
DP 50 ? :? "If just searching for a file,
    hold":? :down <SELECT> until BOOT-DIR
   ECTORY is"
UX 60 ? "executed, insert a new disk, and
   ":? "press <SYSTEM RESET> to reboot di
   sk."
EU 70 RESTORE 500:SUM=0:FOR X=1536 TO 153
   6+124:READ N:SUM=SUM+N:POKE X,N:NEXT X
IC 80 READ CHCKSUM:IF CHCKSUM<>SUM THEN ?
    "BAD DATA!":STOP
LN 100 ? :? "Insert a diskette to modify.
   ":? "HIT <RETURN>":INPUT AS
YK 110 CMD=82:BUFF=(PEEK(15)+1)*256:SECT=
   1:X=USR(ADR(X$),CMD,BUFF,SECT)
BM 120 IF PEEK(BUFF+7)=0 AND PEEK(BUFF+8)
   =8 THEN ? "DISK ALREADY MODIFIED!":GOT
   0 100
RB 130 IF PEEK(BUFF+7)<>20 OR PEEK(BUFF+8
   )<>7 THEN ? "NOT A DOS 2.x DISK!":GOTO
    100
FD 140 POKE 1799,0:POKE 1800,8:? "Re-writ
   ing DOS.SYS to disk...":OPEN #1,8,0,"D
   :DOS.SYS":CLOSE #1
SE 150 ? "Writing new sector 3...":CMD=87
   :BUFF=1536:SECT=3:X=USR(ADR(X$),CMD,BU
   FF,SECT)
EC 160 ? "Disk now contains BOOT-DIRECTOR
   Y.":POKE 1799,20:POKE 1800,7:GOTO 180
BG 400 DATA 104,104,104,141,2,3,104,141,5
   ,3,104,141,4,3,104,141,11,3,104,141,10
   ,3,76,83,228
CT 500 DATA 169,104,141,10,3,169,1,141,11
   ,3,169,0,141,4,3,133,206
QL 510 DATA 169,6,141,5,3,133,207,133,84,
   238,10,3,173,10,3,201,113
MG 520 DATA 176,65,169,82,141,2,3,32,83,2
   28,162,0,161,206,240,51,48,36
BZ 530 DATA 160,5,169,11,157,72,3,196,85,
   176,4,160,23,169,9,132,85
QE 540 DATA 157,66,3,165,206,24,105,5,157
   ,68,3,165,207,157,69,3,32,86,228
UR 550 DATA 165,206,24,105,16,41,127,133,
   206,240,183,208,199
IX 560 DATA 173,31,208,201,5,240,254,169,
   0,133,84,169,20,141,7,7
OR 570 DATA 169,7,141,8,7,76,20,7
ME 580 DATA 12577

Listing 2.
Assemb1y

 
10 ***********************************
20 **       BOOT-DIRECTORY          **
30 **       by Bill Bodenstein      **
40 **       COPYRIGHT 1988          **
45 **       BY ANALOG COMPUTING     **
50 ***********************************
60 ;
70 ;This program creates a directory
80 ;lister which is executed when
90 ;disk is booted.
0100 ;
0110 ;
0120 ; EQUATES
0130 ;
8140 CURSORROW = $54
0150 CURSORCOL = $55
0160 CONSOLEPRESS = $D01F
0170 SELECTKEY = 5
0180 ;
0190 DIRSECT = $0169
0200 DIRBUFF = $0600
0210 FENTRYPTR = $CE
0220 ENTRYLENGTH = 16
0230 ;
0240 FNPLACE = 5
0250 PUTRECORD = 9
0260 PUTCHARS = 11
0270 ICCOM = $0342
0280 ICBADR = $0344
0290 ICBLEN = $0348
0300 CIO =    $E456
0318 ;
0320 READ = 82
0330 DCBCMD = $0382
0340 DCBBUF = $0304
0350 DCBSEC = $030A
0360 SIO =   $E453
0370 ;
0380 CONTBOOT = $0714 ;start of boot
0390 ;  record routine which loads
0400 ;  DOS.SYS into memory.
0410 ;
0420     *=  $0800
0430 ;
0440 ;The following code is stored in
0450 ;the 3rd boot sector and booted
0460 ;into memory from $800 to $87F.
0470 ;
0480 ;
8490 ;Set data control block to read
0500 ;sectors into directory buffer
0510 ;and set file entry pointer to
8520 ;point to the first file entry
0530 ;in directory.
0540 ;
0550 SETUPDCB
0560     LDA # <DIRSECT-1
0570     STA DCBSEC
0580     LDA # >DIRSECT
0590     STA DCBSEC+1
0600     LDA # <DIRBUFF
0610     STA DCBBUF
0620     STA FENTRYPTR
0630     LDA # >DIRBUFF
6640     STA DCBBUF+1
0650     STA FENTRYPTR+1
0660 SETRON STA CURSORROW ;start at
0670 ;  row 6, avoiding silly stuff
0680 ;  LOAD*IT puts on the screen.
8690 ;
0700 ;
0710 ;Skip to next sector and check
0720 ;if last sector in directory.
0730 ;
0740 READINSECTOR
0750     INC DCBSEC
0760     LDA DCBSEC
0770     CMP # <DIRSECT+8
0780     BCS EXITBOOTDIR
0790     LDA #READ
0800     STA DCBCMD
0810     JSR SIO
0820 ;
0830 ;
0840 ;Check status flag of entry:
0850 ;  =0 if no more files
0860 ;  >=128 if deleted file
0870 ;
0880 CHECKENTRY
0890    LDX #0
0960    LDA (FENTRYPTR,X)
0918    BEQ EKITBOOTDIR
0920    BMI NEXENTRY
0930 ;
0940 ;
0950 ;Indent file name and put two on
0960 ;each line.
0970 ;
0980 WHERECURSOR?
0990     LDY #5
1000     LDA #PUTCHARS
1010     STA ICBLEN,X ;fname=11 chars
1020     CPY CURSORCOL
1030     BCS SETPOSITION
1040     LDY #23
1050     LDA #PUTRECORD ;causes a
1060 ;  carriage return after name.
1070 SETPOSITION STY CURSORCOL
1080 ;
1090 ;
1100 ;Tell the screen editor to print
1110 ;the 11-character file name from
1120 ;the file entry.
1130 ;
1140 PRINTFN
1150     STA ICCOM,X ;xreg=0
1160     LDA FENTRYPTR
1170     CLC
1180     ADC #FNPLACE
1190     STA ICBADR,X
1200     LDA FENTRYPTR+1
1210     STA ICBADR+1,X
1220     JSR CIO
1230 ;
1240 ;
1250 ;Skip to next 16-byte entry.
1260 ;
1270 NEXTENTRY
1280     LDA FENTRYPTR
1290     CLC
1300     ADC #ENTRYLENGTH
1310     AND #127
1320     STA FENTRYPTR
1330     BEQ READINSECTOR
1340     BNE CHECKENTRY
1350 ;
1360 ;
1370 EKITBOOTDIR
1380 ;
1390 ;If <SELECT> pressed, loop until
1400 ;<SYSTEM RESET> pressed.
1410 ;
1420 SELECTPRESSED?
1430     LDA CONSOLEPRESS
1440     CMP #SELECTKEY
1450 LOOPFOREVER BEG LOOPFOREVER
1460 ;
1470 ;
1480 ;Fix patch made to sector 1:
1490 ;  JMP $800=>JMP $714
1500 ;and move cursor to top line
1510 ;(so LOAD*IT will be happy).
1520 ;
1530 RESETCURSOR
1540     LDA #0
1550     STA CURSORROW
1560 ;
1570 RESETJMP
1580     LDA # <CONTBOOT
1590     STA $0707
1680     LDA # >CONTBOOT
1610     STA $0708
1620 ;
1630 ;Return and let FMS take over.
1640 ;
1650 GOBOOTER JMP CONTBOOT