10 ! DISK CHECKER - DAVE SMALL 13 ! Creative Computing - 15 ! May 1982, pp.186-190 20 ! 30 GOTO 290 40 ' SUBROUTINES PLACED IN FRONT 50 ' FOR SPEED, NO COMMENTING. 60 ! 70 ' DISK READ SUBROUTINE 80 POKE DCB+1,DFROM 90 POKE DCB+2,82 100 BHI=INT(BUFF/256):BLO=BUFF-(BHI*256) 110 POKE DCB+4,BLO 120 POKE DCB+5,BHI 130 SHI=INT(RSECTOR/256):SLO=RSECTOR-(SHI*256) 140 POKE DCB+10,SLO:POKE DCB+11,SHI 150 X=USR(CALL) 160 DSTATS=PEEK(DCB+3) 170 RETURN 180 ' DISK WRITE SUBROUTINE - (SAMPLE) 190 POKE DCB+1,DTO 200 POKE DCB+2,87 210 BHI=INT(BUFF/256):BLO=BUFF-(BHI*256) 220 POKE DCB+4,BLO 230 POKE DCB+5,BHI 240 SHI=INT(RSECTOR/256):SLO=RSECTOR-(SHI*256) 250 POKE DCB+10,SLO:POKE DCB+11,SHI 260 PRINT "ERROR":GRAPHICS 0 270 DSTATS=PEEK(DCB+3) 280 RETURN 290 REM DISK CHECKER 300 ' DOES SECTOR TRACE OF ALL 310 ' FILES IN THE DIRECTORY. 320 ' PRODUCES LISTING WITH OK/BAD. 330 ! 340 ' ASSUMES 48K, MICROSOFT. 350 ! 360 ' GET DISK NUMBER, WELCOME.--- 370 GRAPHICS 0:SETCOLOR 8,9,4:POKE 82,0:POKE 83,39 380 CLEAR 390 PRINT " DISK CHECKER " 400 PRINT:PRINT "INPUT DRIVE NUMBER"; 410 INPUT DF$ 420 IF DF$="" THEN DFROM=1:GOTO 440 430 DFROM=VAL(DF$) 440 DTO=DFROM 450 CALL=&E453 !DSKINV ADDRESS 460 ! NOTE: MICROSOFT CAN CALL 470 ! DSKINV$ DIRECTLY, NO PLA 480 ! NEEDED 490 DCB=&300 500 OPTION RESERVE 20*128 510 B=VARPTR(RESERVE) 520 IF B<0 THEN B=B+65536 530 ! FIRST, READ IN DIRECTORY---- 540 PRINT "GETTING DIRECTORY." 550 INCR=0 560 FOR RSECTOR=360 TO 368 570 BUFF=B+(128*INCR) !INPUT AREA 580 GOSUB 70 !GET SECTOR 590 IF DSTATS=1 THEN 630 600 PRINT "***DISK RETRY,DIRECTORY SECTOR ";RSECTOR 610 PRINT "***STATUS =";DSTATS 620 GOTO 570 630 INCR=INCR+1 640 PRINT INCR 650 NEXT RSECTOR 660 PRINT 670 PRINT "WAIT -- BUILDING TABLES." 680 ! OK, NOW EXAMINE DIRECTORY. 690 ! PRODUCE LISTING FIRST OFF. 700 !NOTE 360=VTOC, NOT DIR. 710 DIM INFO(64,6) ! FILE INFO 720 DIM NIME$(64) ! NAME INFO 730 DIM DEAD(64) ! FILE BOMBED? 740 FOR Z%=1 TO 64:DEAD(Z%)=0:NEXT Z% 750 ' 760 Z=B+128 ! START OF DIR ENTRY 770 ! BUILD FLAG AND INFO TABLE 780 FNUM=1 790 FOR LOC=Z TO Z+(64*16) STEP 16 800 ! LOC=ENTRIES' STARTING ADDR 810 FLAG%=PEEK(LOC) 820 IF(FLAG% AND &80)=&80 THEN INFO(FNUM,3)=1 830 IF(FLAG% AND &40)=&40 THEN INFO(FNUM,4)=1 840 IF(FLAG% AND &20)=&20 THEN INFO(FNUM,5)=1 850 IF (FLAG% AND 1)=1 THEN INFO(NUM,6)=1 860 ! SECTOR INFO----------------------- 870 INFO(FNUM,1)=PEEK(LOC+1)+256*PEEK(LOC+2) 880 INFO(FNUM,2)=PEEK(LOC+3)+256*PEEK(LOC+4) 890 ! NOW GET NAME DATA..--------------- 900 NIME$(FNUM)="" 910 FOR Z%=5 TO 15 920 NIME$(FNUM)=NIME$(FNUM)+CHR$(PEEK(LOC+Z%)) 930 NEXT Z% 940 ! CHECK FOR END OF ENTRIES 950 IF PEEK(LOC+5)=0 THEN 1020 960 ! 970 FNUM=FNUM+1 980 IF FNUM/5=INT(FNUM/5) THEN PRINT FNUM; 990 NEXT LOC 1000 PRINT "DIR TOTALLY FULL." 1010 GOTO 1030 1020 PRINT "DIR PARTLY FULL." 1030 FNUM=FNUM-1 1040 PRINT 1050 PRINT "NUMBER OF ENTRIES =";FNUM 1060 ! OUTPUT DIRECTORY 1070 ! ENTRY POINT FROM BELOW 1080 IF FNUM=0 THEN 1320 ! EMPTY DISK 1090 PRINT 1100 PRINT " D=DELETED / U=USED / L=LOCKED / O=OPEN" 1110 PRINT " SC=SECTOR COUNT(LEN)" 1120 PRINT " SS=STARTING SECTOR" 1130 PRINT " +=GOOD FILE-=BAD FILE ?=UNKNOWN" 1140 PRINT 1150 FOR F=1 TO FNUM 1160 PRINT USING "##";F; 1170 IF DEAD(F)=-1 THEN PRINT "+"; 1180 IF DEAD(F)=1 THEN PRINT "-"; 1190 IF DEAD(F)=0 THEN PRINT "?"; 1200 PRINT "!";NIME$(F);"!"; 1210 IF INFO(F,3)=1 THEN PRINT "D"; ELSE PRINT " "; 1220 IF INFO(F,4)=1 THEN PRINT "U"; ELSE PRINT " "; 1230 IF INFO(F,5)=1 THEN PRINT "L"; ELSE PRINT " "; 1240 IF INFO(F,6)=1 THEN PRINT "O"; ELSE PRINT " "; 1250 PRINT "!SC:"; 1260 PRINT USING "###";INFO(F,1); 1270 PRINT "!SS:"; 1280 PRINT USING "###";INFO(F,2) 1290 IF F/20=INT(F/20) THEN INPUT RET$ 1300 NEXT F 1310 GOTO 1390 1320 PRINT "EMPTY DISK -- NO ENTRIES" 1330 STOP 1340 PRINT 1350 ! ENTRY POINT (BELOW) 1360 PRINT "PRESS RETURN." 1370 INPUT RET$:CLS:GOTO 1420 1380 GOTO 1400 1390 PRINT "PRESS RETURN." 1400 INPUT RET$ 1410 ! NEXT IS ENTRY POINT 1420 PRINT "}SELECT : 1430 PRINT "1. 'n' A FILE NUMBER TO CHECK." 1440 PRINT "2. 'A' TO CHECK ALL FILES." 1450 PRINT "3. 'D' TO SEE DIRECTORY LIST AGAIN." 1460 PRINT "NOTE: ERRORS SHOW UP ON DIR LISTING" 1470 PRINT " AFTER THEY OCCUR IN SEARCH." 1480 INPUT N$ 1490 IF N$="A" THEN FILE=128:GOTO 1690 1500 IF N$="D" THEN GRAPHICS 0:GOTO 1070 1510 ON ERROR 1540 1520 FILE=VAL(N$) 1530 GOTO 1560 1540 PRINT "ERROR. RE-ENTER." 1550 RESUME 1420 1560 ! --- PROCESS. CHECK. 1570 IF FILE>FNUM OR FILE<0 OR FILE<>INT(FILE) THEN PRINT "ERROR.":GOTO 1420 1580 ! SINGLE ENTRY HANDLER 1590 PRINT "TRACING--'SELECT' TO ABORT." 1600 SS=INFO(FILE,2) ! STARTING SECT 1610 SC=INFO(FILE,1) ! SECTOR COUNT 1620 RSECTOR =SS 1630 ! GO TRACE IT...ARROR=RETURN 1640 GOSUB 1850 1650 IF ARROR=1 THEN PRINT "***BAD FILE***" 1660 IF ARROR=1 THEN DEAD(FILE)=1 ELSE DEAD(FILE)=-1 1670 GOSUB 2110 ! MARK FILE NAME 1680 GOTO 1350 1690 ! ALL ENTRIES HANDLER 1700 FOR FILE=1 TO FNUM 1710 CLS 1720 PRINT "TRACING FILE #";FILE 1730 IF LP=1 THEN PRINT #3,"TRACING FILE #";FILE 1740 PRINT "PRESS 'SELECT' TO ABORT." 1750 SS=INFO(FILE,2) ! STARTING SECT 1760 SC=INFO(FILE,1) ! SECTOR COUNT 1770 RSECTOR=SS 1780 GOSUB 1850 1790 IF ARROR=1 THEN PRINT "***BAD FILE***" **" 1800 IF ARROR=1 THEN DEAD(FILE)=1 ELSE DEAD(FILE)=-1 1810 GOSUB 2110 1820 NEXT FILE 1830 PRINT "COMPLETED." 1840 GOTO 1350 1850 ! TRACING SUBROUTINE 1860 ARROR=0 1870 PRINT 1880 PRINT "---SEC CNT=";SC;" READING SEC ";RSECTOR 1890 POKE &D01F,0 ' CLEAR BUTTONS 1900 GOSUB 70 'READ 1910 ! CHECK BUTTONS 1920 IF PEEK(&D01F)<>7 THEN RETURN 1930 IF DSTATS=1 THEN 1960 1940 PRINT "+++ERROR. DSTATS=";DSTATS;" ON SECTOR ";RSECTOR 1950 GOTO 1900 'RETRY 1960 IF SC=0 THEN RETURN 1970 SC=SC-1 ! DECR S COUNT 1980 ! GET FORWARD POINTER + FNUM 1990 FWD=(PEEK(BUFF+125) AND 3)*256 2000 FWD=FWD+PEEK(BUFF+126) 2010 FN=INT((PEEK(BUFF+125) AND &FC)/4) ! HENCE, SHIFTED 2 BITS RIGHT 2020 FN=FN+1 ! (DISK STARTS AT 0) 2030 PRINT "---DATA: FILE NUM=";FN;" FWD SEC =";FWD 2040 IF FN<>FILE THEN PRINT "FILE NUMBER ERROR.":ARROR=1 2050 IF FWD>720 OR FWD<0 THEN PRINT "FORWARD PTR OUT OF RANGE, ABORT.:ARROR=1:RETURN 2060 IF FWD=0 THEN 2090 2070 RSECTOR=FWD 2080 GOTO 1870 2090 PRINT "COMPLETED." 2100 RETURN 2110 ! MARK A FILE AS BAD IN NAME. 2120 ! SET HIGH BIT SO IT SHOWS 2130 ! UP IN INVERSE VODEO.. 2140 IF ARROR=0 THEN RETURN 2150 Z$=NIME$(FILE) 2160 NIME$(FILE)="" 2170 FOR Z=1 TO LEN(Z$) 2180 NIME$(FILE)=NIME$(FILE)+CHR$((ASC(MID$(Z$,Z,1)) OR &80)) ! SET HIGH BIT 2190 NEXT Z 2200 RETURN