10
20
30 :
40 mapsz%=1024
50 MODE7:PRINT"Build a free space map from directory"'"structure"
60 DIM ctrl% 31,name% 31,map% mapsz%-1,fsm% 511:X%=ctrl%:Y%=X%DIV256:fs%=FNfs
70 OSCLI"DIR $":*INFO $
80 IFfs%=8 :drive%=VALFNgbpb(6):name%?(1+?name%)=13:drive%=VAL$(name%+1)
90 IFfs%=8 :PROCerr(FNscsi(fsm%,8,drive%,0,2),0):secmax%=fsm%!&FC
100 IFfs%=16:drive%=FNargs(&FE,0,0)
110 IFfs%=16:PROCerr(FNhadfs(fsm%,&80,drive%,&46,1),&46):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 mapsz%-1 STEP 4:map%!A%=0:NEXT:disp%=TRUE:VDU23,1;0;0;0;0
150 sec%=2:num%=secmax%-sec%+1:PROCmapadd:
160 IFfs%=8 :sec%=2 :num%=5:PROCmaprem :
170 IFfs%=16:sec%=70:num%=4:PROCmaprem :
180 CLS:PROCscan:PRINTTAB(0,2)SPC20:PROCmaplist:VDU23,1,1;0;0;0;:IFPOS:PRINT
190 PRINT"(W)rite new free space map to disk"'"(S)ave free space map as a file"'"(Q)uit"
200 REPEATVDU58: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 UNTILA$="Q":END
250 :
260 DEFPROCscan
270 LOCALidx%,ret%:REPEATf$=FNgbpb8(idx%):idx%=X%!9:ret%=LENf$:IFret%:PROCfile
280 UNTILret%=0:ENDPROC
290 :
300 DEFPROCfile
310 IFADVAL(-1):IFGET=32:disp%=NOTdisp%
320 IFfs%=8 OR disp%:VDU30:OSCLI"INFO @."+f$:vpos%=VPOS:IFvpos%<2:PRINTSPC39
330
340 IFfs%=16:dir%=FNfile("@."+f$,&FD)=2:sec%=X%!14 AND &FFFFFF:num%=X%!11 AND &7FFFFF
350
360 IFfs%=8:PRINTTAB(11,0);:dir%=FNbyte(135,0,0)=68
370 IFfs%=8:PRINTTAB(10-10*(vpos%=1),vpos%-1);:A$="":FORnum%=1TO6:A$=A$+CHR$FNbyte(135,0,0):VDU9:NEXT:sec%=EVAL("&"+A$)
380 IFfs%=8:num%=5:IFNOTdir%:PRINTTAB(0,1);:A$="":FORnum%=1TO8:A$=A$+CHR$FNbyte(135,0,0):VDU9:NEXT:num%=EVAL("&"+A$):num%=(num%+255)DIV256
390 PRINTTAB(0,3);:PROCmaprem:IFdisp%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),link%)
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%>mapsz%-9:PRINTTAB(0,2);"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%=mapsz%-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 mapsz%-1 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%>mapsz%-9:PRINTTAB(0,2);"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%=mapsz%-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 mapsz%-1 STEP 4:map%!A%=map%!(A%+8):NEXT:ENDPROC
830 ENDPROC
840 :
850 DEFPROCmaplist
860 ptr%=-8:REPEATptr%=ptr%+8
870 PRINTFNh0(map%!ptr%,6);"+";FNh0(map%!(ptr%+4),5);SPC(1-(POS>35));
880 IFmap%!ptr%>secmax%:PRINT"Sector too big":END
890 UNTILmap%!ptr%=0 OR VPOS=24:PRINTSPC12;
900 ENDPROC:=ptr%
910 :
920 DEFPROCmapsave
930 INPUTLINE"File to save: "A$:IFA$<>"":OSCLI"SAVE "+A$+" "+STR$~map%+"+200 0 FFFFFD0"
940 A$="":ENDPROC
950 :
960 DEFFNadfs_sum(mem%):LOCALsum%:sum%=255
970 FOR A%=254 TO 0 STEP -1
980 IFsum%>255:sum%=(sum%+1)AND255
990 sum%=sum%+mem%?A%:NEXT:=sum%AND255
1000 :
1010 DEFPROCmapwriteA
1020 IFptr%DIV8>82:PRINT"FSM too big":ENDPROC
1030 PROCerr(FNscsi(fsm%,8,drive%,0,2),0)
1040 src%=0:dst%=0:REPEAT
1050 fsm%!dst%=map%!src%
1060 fsm%!(dst%+256)=map%!(src%+4)
1070 src%=src%+8:dst%=dst%+3
1080 UNTILmap%!(src%-8)=0
1090 fsm%?&1FE=dst%-3
1100 REPEATfsm%!dst%=0:fsm%!(dst%+256)=0:dst%=dst%+3:UNTILdst%>&FB
1110 fsm%!&0FC=secmax%+1
1120 fsm%?&0FF=FNadfs_sum(fsm%)
1130 fsm%?&1FF=FNadfs_sum(fsm%+&100)
1140 PROCerr(FNscsi(fsm%,10,drive%,0,2),0)
1150 OSCLI"MOUNT "+STR$drive%
1160 ENDPROC
1170 :
1180 DEFPROCmapwriteH
1190 IFptr%DIV8>35:PRINT"FSM too big":ENDPROC
1200 PROCerr(FNhadfs(fsm%,&80,drive%,&47,1),&47)
1210 dskid%=fsm%!16 AND &FFFF
1220 PROCerr(FNhadfs(fsm%,&80,drive%,&46,1),&46)
1230 fsm%?24=dskid%:fsm%?25=dskid%DIV256
1240 IFsecmax%<&10000:fsm%!28=(secmax%+1)OR(fsm%!28 AND &7FFF0000):size%=2
1250 IFsecmax%>&FFFF :fsm%!28=(secmax%+1)OR(fsm%!28 AND &7F000000)OR&80000000: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),&46)
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%:
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%,S%):IFA%=0:ENDPROC
1460 PRINT"Disk error &"FNh0(A%,2)" at "FNh0(S%,8):END
1470 ENDPROC
1480 :
1490 DEFFNbyte(A%,X%,Y%)=((USR&FFF4)AND&FF00)DIV256
1500 DEFFNfs:LOCALA%,Y%,E%:=(USR&FFDA)AND&FF
1510 DEFFNfile(A$,A%):$name%=A$:?X%=name%:X%?1=name%DIV256:=(USR&FFDD)AND&FF
1520 DEFFNgbpb(A%):X%!1=name%:CALL&FFD1:A%=name%+((1+?name%)AND((A%AND-2)=6)):A%?(1+?A%)=13:=$(A%+1)
1530 DEFFNgbpb8(ptr%):X%!1=name%:X%!5=1:X%!9=ptr%:A%=8:CALL&FFD1:IFX%!5=1:=""
1540 A%=name%+1:A%!(A%?-1)=&D20:A%?(INSTR($A%," ")-1)=13:=$A%
1550 DEFFNh0(A%,N%)=RIGHT$("0000000"+STR$~A%,N%)
1560 DEFFNargs(A%,Y%,ptr%):LOCALX%,E%:IF?(TOP-3)=0:E%=Y%:Y%=0
1570 IFHIMEM<&FFFF:LOCAL!&70:X%=&70:!X%=ptr%:CALL&FFDA:=!X%
1580 SYS"OS_Args",A%,Y%,ptr%TO,,ptr%:=ptr%