10 REM > MkMap 1.01 - 06-Apr-2013 J.G.Harston 20 REM Create a free space map from examining directory structure 30 : 40 MODE7:PRINT"Build a free space map from directory"'"structure" 50 DIM ctrl% 31,name% 31,map% 511,fsm% 511:X%=ctrl%:Y%=X%DIV256:fs%=FNfs 60 IFfs%=8:aD%=&7C0B:aL%=&7C28:aS%=&7C32:IFHIMEM<>&7C00:PRINT"Needs to run in I/O memory":END 70 OSCLI"DIR $":*INFO $ 80 IFfs%=8 :drive%=VALFNgbpb(6):name%?(1+?name%)=13:drive%=VAL$(name%+1) 90 IFfs%=16:drive%=FNargs(&FE,0,0) 100 IFfs%=8 :PROCerr(FNscsi(fsm%,8,drive%,0,2)):secmax%=fsm%!&FC 110 IFfs%=16:PROCerr(FNhadfs(fsm%,&80,drive%,&46,1)):secmax%=fsm%!28:IFfsm%?31<128:secmax%=secmax%AND&FFFF 120 secmax%=(secmax%AND&FFFFFF)-1 130 PRINT"Total disk sectors (&";~secmax%+1;"): &";:INPUT""A$:IFA$<>"":secmax%=EVAL("&"+A$)-1 140 FOR A%=0 TO 255 STEP4:map%!A%=0:NEXT 150 sec%=2:num%=secmax%-num%-1:PROCmapadd:REM Add whole disk to FSM 160 IFfs%=8 :sec%=2 :num%=5:PROCmaprem :REM Remove root directory 170 IFfs%=16:sec%=70:num%=4:PROCmaprem :REM Remove FSM and root directory 180 CLS:PROCscan:IFPOS:PRINT 190 PRINT"(W)rite new free space map to disk"'"(S)ave free space map as a file"'"(Q)uit" 200 PRINT":";:REPEATA$=CHR$(GETAND&DF):UNTILINSTR("WSQ",A$):VDU127 210 IFA$="W":IFfs%=8 :PROCmapwriteA 220 IFA$="W":IFfs%=16:PROCmapwriteH 230 IFA$="S":PROCmapsave 240 END 250 : 260 DEFPROCscan 270 LOCAL idx%,ret%:REPEATf$=FNgbpb8(idx%):idx%=X%!9:ret%=LENf$:IFret%:PROCfile 280 UNTILret%=0:ENDPROC 290 : 300 DEFPROCfile 310 VDU30:OSCLI"INFO "+f$:IFVPOS<2:PRINTSPC39 320 REM HADFS has 'read sector start' command: 330 IFfs%=16:dir%=FNfile(f$,&FD)=2:sec%=X%!14 AND &FFFFFF:num%=X%!11 AND &7FFFFF 340 REM ADFS, need to peek output of *INFO command: 350 IFfs%=8 :dir%=(aD%?0=ASC"D" OR aD%?1=ASC"D") 360 IFfs%=8 :aL%?8=13:A$=$aL%:aL%?8=32:num%=-1:IF?aL%<>32:num%=EVAL("&"+A$):num%=(num%+255)DIV256 370 IFfs%=8 :aS%?6=13:A$=$aS%:aS%?6=32:sec%=-1:IF?aS%<>32:sec%=EVAL("&"+A$) 380 IFfs%=8 :IFsec%=-1:aD%?15=13:A$=$(aD%+9):aD%?15=32:sec%=EVAL("&"+A$):num%=5 390 PRINT:PROCmaprem:PROCmaplist 400 IFdir%:IFfs%=16:PROClinks 410 IFdir%:OSCLI"Dir "+f$:PROCscan:OSCLI"Dir ^" 420 ENDPROC 430 : 440 DEFPROClinks 450 link%=sec%:REPEAT 460 PROCerr(FNhadfs(fsm%,&80,drive%,link%,1)) 470 link%=fsm%!14 AND &FFFF:IFfsm%?12>127:link%=fsm%!24 AND &FFFFFF 480 IFlink%:sec%=link%:num%=3:PROCmaprem 490 UNTILlink%=0 500 ENDPROC 510 : 520 DEFPROCmaprem:IFnum%=0:ENDPROC 530 ptr%=-8:REPEATptr%=ptr%+8 540 UNTILmap%!ptr%=0 OR map%!ptr%>=sec% 550 IFptr%>512-9:PRINT"FSM too full":END 560 IFmap%!ptr%=sec%:map%!ptr%=map%!ptr%+num%:map%!(ptr%+4)=map%!(ptr%+4)-num%:PROCmaprem2:ENDPROC 570 IFmap%!ptr%+map%!(ptr%+4)=sec%+num%:map%!(ptr%+4)=map%!(ptr%+4)-num%:PROCmaprem2:ENDPROC 580 FOR A%=512-4 TO ptr% STEP -4:map%!A%=map%!(A%-8):NEXT 590 map%!(ptr%-4)=sec%-map%!(ptr%-8) 600 map%!(ptr%+4)=map%!ptr%+map%!(ptr%+4)-(sec%+num%) 610 map%!(ptr%+0)=sec%+num% 620 PROCmaprem2 630 ENDPROC 640 : 650 DEFPROCmaprem2 660 IFmap%!(ptr%+4)=0:FOR A%=ptr% TO 511 STEP 4:map%!A%=map%!(A%+8):NEXT 670 ENDPROC 680 : 690 DEFPROCmapadd:IFnum%=0:ENDPROC 700 ptr%=-8:REPEATptr%=ptr%+8 710 UNTILmap%!ptr%=0 OR map%!ptr%>=sec% OR map%!ptr%+map%!(ptr%+4)=sec% 720 IFptr%>512-9:PRINT"FSM too full":END 730 IFmap%!ptr%=0:map%!ptr%=sec%:map%!(ptr%+4)=num%:PROCmapadd2:ENDPROC 740 IFsec%+num%=map%!ptr%:map%!ptr%=map%!ptr%-num%:PROCmapadd2:ENDPROC 750 IFmap%!ptr%+map%!(ptr%+4)=sec%:map%!(ptr%+4)=map%!(ptr%+4)+num%:PROCmapadd2:ENDPROC 760 FOR A%=512-4 TO ptr% STEP -4:map%!A%=map%!(A%-8):NEXT 770 map%!ptr%=sec%:map%!(ptr%+4)=num% 780 ENDPROC 790 : 800 DEFPROCmapadd2 810 IFmap%!ptr%+map%!(ptr%+4)=map%!(ptr%+8):ptr%=ptr%+8 820 IFptr%<>0:IFmap%!(ptr%-8)+map%!(ptr%-4)=map%!ptr%:map%!(ptr%-4)=map%!(ptr%-4)+map%!(ptr%+4):FOR A%=ptr% TO 511 STEP 4:map%!A%=map%!(A%+8):NEXT:ENDPROC 830 ENDPROC 840 : 850 DEFPROCmaplist 860 LOCAL ptr% 870 ptr%=-8:REPEATptr%=ptr%+8 880 PRINTFNh0(map%!ptr%,5);"+";FNh0(map%!(ptr%+4),5);SPC(2-(POS>35)); 890 IFmap%!ptr%>secmax%:PRINT"Sector too big":END 900 UNTILmap%!ptr%=0 OR VPOS=24:PRINTSPC11; 910 ENDPROC 920 : 930 DEFPROCmapsave 940 INPUTLINE"File to save: "A$:OSCLI"SAVE "+A$+" "+STR$~map%+"+200 0 FFFFFD0" 950 A$="":ENDPROC 960 : 970 DEFFNadfs_sum(mem%):LOCAL sum%:sum%=255 980 FOR A%=254 TO 0 STEP -1 990 IF sum%>255:sum%=(sum%+1)AND255 1000 sum%=sum%+mem%?A%:NEXT:=sum%AND255 1010 : 1020 DEFPROCmapwriteA 1030 IFptr%DIV8>82:PRINT"FSM too big":ENDPROC 1040 PROCerr(FNscsi(fsm%,8,drive%,0,2)) 1050 src%=0:dst%=0:REPEAT 1060 fsm%!dst%=map%!src% 1070 fsm%!(dst%+256)=map%!(src%+4) 1080 src%=src%+8:dst%=dst%+3 1090 UNTILmap%!(src%-8)=0 1100 fsm%?&1FE=dst%-3 1110 REPEATfsm%!dst%=0:fsm%!(dst%+256)=0:dst%=dst%+3:UNTILdst%>&FB 1120 fsm%!&0FC=secmax%+1 1130 fsm%?&0FF=FNadfs_sum(fsm%) 1140 fsm%?&1FF=FNadfs_sum(fsm%+&100) 1150 PROCerr(FNscsi(fsm%,10,drive%,0,2)) 1160 OSCLI"MOUNT "+STR$drive% 1170 ENDPROC 1180 : 1190 DEFPROCmapwriteH 1200 IFptr%DIV8>35:PRINT"FSM too big":ENDPROC 1210 PROCerr(FNhadfs(fsm%,&80,drive%,&47,1)) 1220 dskid%=fsm%!16 AND &FFFF 1230 PROCerr(FNhadfs(fsm%,&80,drive%,&46,1)) 1240 fsm%?24=dskid%:fsm%?25=dskid%DIV256 1250 fsm%!28=secmax%+1:size%=2:IFfsm%?30:fsm%?31=&80:size%=3 1260 src%=0:dst%=&20:REPEAT 1270 fsm%!dst%=map%!src% 1280 fsm%!(dst%+size%)=map%!(src%+4) 1290 src%=src%+8:dst%=dst%+size%*2 1300 UNTILmap%!(src%-8)=0 1310 PROCerr(FNhadfs(fsm%,&81,drive%,&46,1)) 1320 OSCLI"MOUNT "+CHR$(48+drive%-7*(drive%>9)) 1330 ENDPROC 1340 : 1350 DEFFNscsi(addr%,cmd%,drv%,sect%,num%):LOCALfs% 1360 fs%=FNfs:IFfs%<>8:*FADFS 1370 X%?0=0:X%!1=addr%:X%?5=cmd%:X%?6=drv%*32+((sect%AND&1F0000)DIV65536) 1380 X%?7=((sect%AND&FF00)DIV256):X%?8=sect%:X%!9=num%:X%!11=0 1390 A%=&72:CALL&FFF1:A%=?X%:IFfs%<>8:OSCLI"FX143,18,"+STR$fs% 1400 =A% 1410 : 1420 DEFFNhadfs(addr%,cmd%,drv%,sect%,num%):LOCALfs%:REM cmd%=&80 read, &81 write 1430 X%!0=&600:X%!2=addr%:X%!6=sect%:X%?9=drv%:X%?10=num%:X%?11=cmd%:A%=90:CALL&FFF1:=X%?11 1440 : 1450 DEFPROCerr(A%):IFA%=0:ENDPROC 1460 PRINT"Disk error &"FNh0(A%,2);" at "FNh0(sect%,8):END 1470 ENDPROC 1480 : 1490 DEFFNfs:LOCALA%,Y%,E%:=(USR&FFDA)AND&FF 1500 DEFFNfile(A$,A%):$name%=A$:?X%=name%:X%?1=name%DIV256:=(USR&FFDD)AND&FF 1510 DEFFNgbpb(A%):X%!1=name%:CALL&FFD1:A%=name%+((1+?name%)AND((A%AND-2)=6)):A%?(1+?A%)=13:=$(A%+1) 1520 DEFFNgbpb8(ptr%):X%!1=name%:X%!5=1:X%!9=ptr%:A%=8:CALL&FFD1:IFX%!5=1:="" 1530 A%=name%+1:A%!(A%?-1)=&D20:A%?(INSTR($A%," ")-1)=13:=$A% 1540 DEFFNh0(A%,N%)=RIGHT$("0000000"+STR$~A%,N%) 1550 DEFFNargs(A%,Y%,ptr%):LOCALX%,E%:IF?(TOP-3)=0:E%=Y%:Y%=0 1560 IFHIMEM<&10000:LOCAL!&70:X%=&70:!X%=ptr%:CALL&FFDA:=!X% 1570 LOADATN"OS_Args",A%,Y%,ptr%TO,,ptr%:=ptr% 1580 :