10 REM > AFSFiler
   20 os%=FNfx(0,1)AND&FF:VDU10,8:A%=POS:VDU13:IFA%<50:MODE&87:IFHIMEM>&7C00:MODE&83:IFHIMEM>&4000:MODE&80
   30 IFHIMEM<&FFFF:HIMEM=FNfx(132,0)
   40 PROCinit:PROChdr:PRINT:ONERRORIFFNerr:END
   50 curr%=-1:inmem%=0:REPEAT:fs%=FNfs:X%=ctrl%:Y%=X%DIV256:IFPOS:PRINT
   60   VDU8:wdt%=POS+1:PRINT
   70   IFdrv$="":PRINTCHR$(D%+48)">";ELSEPRINT"["drv$"]";
   80   csd%=home%:INPUTLINE" "A$:PROCdo(FNs(A$))
   90 UNTIL0
  100 DEFPROCinit:ver$="1.32c"
  110 DIMctrl% 127,name% 255,data% 255,thisdir% &19FF,alloc% 511:diskrec%=0:IFos%=6:DIMdiskrec% 255
  120 D%=0:drv$="":path$="":title$="":csd%=0:home%=0:valid%=&30534641:map$="JesMap"
  130 fsv%=0:opt%=0:fullinf%=TRUE:d$=".":s$="/":IFos%AND-24:d$="/":s$=".":IFos%AND-32:d$="\"
  140 cmd$=":MOUNT:DIR:CAT:EX:INFO:TYPE:DUMP:COPY:BLOCK:INF:HELP:QUIT:"
  150 hlp$=":<drive>|<image>:<dir>|&<blocknum>:::(<file>):<file> [CTRLS]:<file> [7BIT]:<source> <dest> (<opts>):<blocknum>:FULL|SHORT:::<opts>:"
  160 ENDPROC
  170 DEFPROChdr:PRINT"AFSFiler v"ver$" by J.G.Harston":ENDPROC
  180 DEFFNerr:OSCLI"FX229":IFPOS:PRINT
  190 REPORT:IFFNfs<>fs%:OSCLI"FX143,18,"+STR$fs%
  200 PROCCloseAll:A%=ERR<>17ANDERR<>28:PRINTLEFT$(" at line "+STR$ERL,ERR<128ANDA%):=INKEY-1ANDA%
  210 DEFPROCCloseAll
  220 out%=out%:IFout%:A%=out%:out%=0:CLOSE#A%
  230 dsk%=dsk%:IFdsk%:A%=dsk%:dsk%=0:CLOSE#A%
  240 ENDPROC
  250 DEFPROCdo(A$):IFA$="?":A$="HELP"
  260 IFLEFT$(A$,1)=";"ORA$="":ENDPROC
  270 IFLEFT$(A$,1)="*":OSCLIMID$(A$,2):ENDPROC
  280 IFLEFT$(A$,1)=".":A$="CAT "+MID$(A$,2)
  290 A%=INSTR(A$+" "," "):B$=FNuc(LEFT$(A$,A%-1)):A$=FNs(MID$(A$,A%+1))
  300 IFLENB$=1ANDINSTR("01234567",B$):drv$="":D%=VALB$AND(((os%<6)OR3)AND7):home%=0:ENDPROC
  310 A%=INSTR(cmd$,":"+B$+":"):IFA%=0:PRINT"Bad command":ENDPROC
  320 A%=EVAL("FN_"+B$+"(A$)"):ENDPROC
  330 DEFFNsyn(S$):IFA$="":PRINT"Syntax: "B$" "S$:=TRUEELSE=FALSE
  340 DEFFN_QUIT(A$):PRINT"Quit"
  350 ONERROREND
  360 IFos%>5:*QUIT
  370 END
  380 DEFFN_HELP(A$):PROChdr:p%=2:q%=2:REPEAT
  390   A%=INSTR(cmd$,":",p%):PRINTSPC2MID$(cmd$,p%,A%-p%);:p%=A%+1
  400   A%=INSTR(hlp$,":",q%):PRINTTAB(8)MID$(hlp$,q%,A%-q%):q%=A%+1
  410 UNTILp%>LENcmd$:=0
  420 DEFFN_OPT(A$)
  430 fsv%=VAL(A$):=0
  440 DEFFN_INF(A$):IFA$="":PRINT"Output "LEFT$("FULL",fullinf%);LEFT$("SHORT",NOTfullinf%)" .inf info":=0
  450 fullinf%=FNuc(A$)="S":=0
  460 DEFFN_MOUNT(A$):home%=0:IFLENA$<2:PROCdo(A$):=0ELSEdrv$=FNs(A$):D%=-1:=0
  470 DEFFN_CAT(A$):PROCLstDir(0):=0
  480 DEFFN_EX(A$):PROCLstDir(1):=0
  490 DEFFN_DIR(A$):curr%=-1:IFFNsyn("<dir>|&<blocknum>"):=TRUE
  500 IFLEFT$(A$,1)="&":A%=FNMount:home%=EVAL(FNuc(A$)):path$="&"+FNh0(home%,6):=0
  510 IFA$="$":A%=FNMount:home%=root%:path$="$":=0
  520 IFFNlook:=TRUE
  530 IF(fptr%?&14AND&20)=0:PRINT"'"src$"' not a directory":=TRUE
  540 A%=fptr%?&C:fptr%?&C=13:path$=path$+"."+FNs($(fptr%+2)):fptr%?&C=A%
  550 IFRIGHT$(path$,2)=".^":A%=LENpath$-1:REPEATA%=A%-1:UNTILMID$(path$,A%,1)="."ORA%<2:path$=LEFT$(path$,A%+(A%>1))
  560 home%=fptr%!&17AND&FFFFFF
  570 =0
  580 DEFFN_BLOCK(A$):IFFNsyn("<blocknum>"):=TRUE
  590 blk%=EVAL("&"+FNuc(A$))AND&FFFFFF:PROCRdBlocks(data%,blk%,D%,1):S%=blk%*256:O%=data%:ln%=256:PROCdump
  600 =0
  610 DEFFN_DUMP(A$):IFFNsyn("<fsp>"):=TRUE
  620 IFFNlook:=TRUE
  630 PROCFileInfo(fptr%,1):S%=0:REPEAT:PROCReadData:PROCdump:UNTILeof%
  640 =0
  650 DEFPROCdump:cols%=16:IFwdt%<80:cols%=8
  660 FORP%=0TOln%-1STEPcols%:B$=""
  670   PRINTFNh0(P%+S%,8)" ";:FORQ%=P%TOP%+cols%-1
  680     IFQ%<ln%:PRINTFNh0(?O%,2)" ";ELSE?O%=32:PRINTSPC3;
  690     A$=CHR$(?O%AND&7F):IFA$>=" "ANDA$<="~" B$=B$+A$ELSEB$=B$+"."
  700 O%=O%+1:NEXT:PRINTB$:NEXT:S%=S%+ln%:ENDPROC
  710 DEFFN_TYPE(A$):IFFNsyn("<fsp>"):=TRUE
  720 msk%=INSTR(A$," [")<>0:msk%=(msk%AND&80)OR&7F:A$=LEFT$(A$,INSTR(A$+" "," ")-1)
  730 IFFNlook:=TRUE
  740 PROCFileInfo(fptr%,1):S%=0:last%=0:REPEAT:PROCReadData
  750   FORP%=0TOln%-1:Q%=?O%ANDmsk%:IFmsk%=255:VDUQ%ELSEIFQ%=10ORQ%=13ORQ%>31VDUQ%
  760     IF(Q%=10ORQ%=13)ANDQ%<>last%:VDU23-Q%
  770     IFQ%=9:PRINTSPC(8-(POSMOD8));
  780   last%=?O%:O%=O%+1:NEXT:S%=S%+ln%
  790 UNTILeof%:IFPOS:PRINT
  800 =0
  810 DEFFN_INFO(A$)
  820 IFA$<>"":IFFNlook:=TRUE
  830 IFA$<>"":x%=0:PROCListFile(1):=0
  840 IFFNMount:=TRUE
  850 PROCHdr:PRINTSPC(18-LENtitle$);MID$("SEQINTMUX",(fsv%AND3)*3+1,3)" DEN=";fsv%DIV4+1
  860 PRINT"Root: &"FNh0(root%,6)"  CrDate: "FNdate(idate%)
  870 PRINT"MapA: &"FNh0(mapa%,6);MID$("* ",(mapa%=map%)+2,1)" ";
  880 PRINT"MapB: &"FNh0(mapb%,6);MID$("* ",(mapb%=map%)+2,1)" ";
  890 PRINT"MapSz: ";mapsz%'"Size: &"FNh0(dsize%,6)"  ";dsize%DIV4;"K  ";(dsize%AND-512)/4096;"M"
  900 =0
  910 DEFFN_COPY(A$):IFFNsyn("<afs0 source> (inf:)<host dest> (<C>onfirm)"):=TRUE
  920 A%=INSTR(A$+" "," "):src$=LEFT$(A$,A%-1):dst$=FNs(MID$(A$,A%+1))
  930 cnf%=FNuc(RIGHT$(dst$,2))=" C":IFcnf%:dst$=FNs(LEFT$(dst$,LENdst$-2))
  940 inf%=FNuc(LEFT$(dst$,4))="INF:":IFinf%:dst$=MID$(dst$,5)
  950 IFdst$="":PRINT"<dest> missing":=TRUE
  960 IFos%<6:IFINSTR(dst$,"::")ORLEFT$(dst$,1)="-":PRINT"FS prefix unsupported":=TRUE
  970 A$=src$:IFA$<>"$":IFFNlook:=TRUE
  980 IFsrc$="$":A%=FNMount:fptr%=data%:fptr%?&14=&20:fptr%!&17=root%:curr%=-1:IFA%<0:=TRUE
  990 IF((fptr%?&14)AND&20)=0:leaf$=src$:PROCCopyOneFile(src$,dst$):=0
 1000 A%=FNfile(dst$,8):dst$=dst$+d$
 1010 oldcsd%=csd%:oldfptr%=fptr%:curr%=-1:csd%=fptr%!&17AND&FFFFFF:PROCCopyDirectory(dst$)
 1020 A%=LENdst$:REPEATA%=A%-1:UNTILMID$(dst$,A%,1)=d$ORA%<1:leaf$=MID$(dst$,A%+1,LENdst$-A%-1):dst$=LEFT$(dst$,A%)
 1030 IFsrc$="$":load%=0:exec%=0:length%=&200:attr%=8:mdate%=idate%:PROCSetInfo(dst$+leaf$):=0
 1040 PROCSetDir:=0
 1050 DEFPROCCopyDirectory(dst$):LOCALentry%,leaf$
 1060 PROCRdDir:fptr%=thisdir%:IFthisdir%?15=0:ENDPROC
 1070 entry%=1:REPEAT:fptr%=thisdir%+(!fptr%AND&FFFF):PROCCopyObject
 1080 entry%=entry%+1:UNTILentry%>thisdir%?15
 1090 ENDPROC
 1100 DEFPROCCopyObject:LOCALoldcsd%,oldfptr%
 1110 PROCFileInfo(fptr%,1):IFfname$="":ENDPROC
 1120 IFcnf%:PRINT"Copy "fname$;:cnf%=FNyna(cnf%):IFcnf%>0:PRINT:ENDPROCELSEVDU13
 1130 leaf$=fname$:fname$=FNfn_todos(fname$)
 1140 IF((fptr%?&14)AND&20)=0:PROCCopyOneFile(fname$,dst$+fname$):ENDPROC
 1150 PRINT"Copying "fname$;SPC(10-LENfname$)" to "dst$+fname$
 1160 oldcsd%=csd%:oldfptr%=fptr%
 1170 curr%=-1:csd%=fptr%!&17AND&FFFFFF
 1180 A%=FNfile(dst$+fname$,8)
 1190 PROCCopyDirectory(dst$+fname$+d$)
 1200 PROCSetDir:ENDPROC
 1210 DEFPROCSetDir
 1220 curr%=-1:csd%=oldcsd%:PROCRdDir:fptr%=oldfptr%
 1230 PROCFileInfo(fptr%,1):PROCSetInfo(dst$+fname$)
 1240 ENDPROC
 1250 DEFPROCCopyOneFile(src$,dst$)
 1260 PRINT"Copying "src$;SPC(10-LENsrc$)" to "dst$;SPC4;
 1270 PROCFileInfo(fptr%,1):IFFNfile(dst$,5):X%!14=&33:A%=FNfile(dst$,4)
 1280 X%!2=load%:X%!6=exec%:X%!10=0:X%!14=&4000:A%=FNfile(dst$,7)
 1290 IFlength%:PROCCopyData
 1300 PROCSetInfo(dst$):PRINTSTRING$(3,CHR$127)
 1310 ENDPROC
 1320 DEFPROCCopyData
 1330 out%=FNf_openout(dst$):S%=0:REPEAT:PROCReadData:IFPOS=0:PRINTSPC4;
 1340   IF(S%AND1023)=0:PRINTSTRING$(3,CHR$8)FNd0(100*S%DIVlength%,2)"%";
 1350   IFln%:PROCgbpb(2,out%,data%,ln%,0):S%=S%+ln%
 1360 UNTILeof%:CLOSE#out%:out%=0:length%=S%
 1370 ENDPROC
 1380 DEFPROCSetInfo(dst$):X%!2=load%:X%!6=exec%:X%!10=length%:X%!14=attr%:A%=FNfile(dst$,1)
 1390 A$=leaf$+STRING$(11-LENleaf$," ")+FNh0(load%,8)+" "+FNh0(exec%,8)+" "+FNh0(length%,8)
 1400 IFfullinf%:A$=A$+" "+FNh0(attr%AND255,2)+" "+FNh0(mdate%,4)
 1410 A$=A$+CHR$13+CHR$10
 1420 IFinf%:out%=OPENOUT(dst$+s$+"inf"):FORp%=1TOLENA$:BPUT#out%,ASCMID$(A$,p%,1):NEXT:CLOSE#out%:out%=0
 1430 IFfs%<>5:ENDPROC
 1440 A%=FNNetFS_Op(19,CHR$4+CHR$access%+dst$)
 1450 X%!8=mdate%:A%=FNNetFS_OpN(19,5,10,dst$)
 1460 IFFNNetFS_Op(18,CHR$64+dst$):ENDPROC
 1470 X%!8=mdate%:X%!10=0:X%!13=mdate%:X%!15=0
 1480 A%=FNNetFS_OpN(19,64,18,dst$)
 1490 ENDPROC
 1500 DEFPROCHdr:PRINT"Disk: L";fsv%DIV4+2;"FS::"title$;:ENDPROC
 1510 DEFPROCLstDir(cflg%):x%=0:IFFNMount:PRINT"Not an AFS0 disk":ENDPROC
 1520 PROCHdr:PRINT"."path$'
 1530 PROCRdDir:fptr%=thisdir%:IFthisdir%?15=0:ENDPROC
 1540 FORentry%=1TOthisdir%?15
 1550   fptr%=thisdir%+(!fptr%AND&FFFF):PROCListFile(cflg%)
 1560 NEXTentry%:IFPOS:PRINT
 1570 ENDPROC
 1580 DEFPROCListFile(cflg%)
 1590 PROCFileInfo(fptr%,cflg%):PRINTfname$;SPC(11-LENfname$);
 1600 IF(cflg%AND1):PRINTFNh0(load%,8)" "FNh0(exec%,8)" "FNh0(length%,6)" ";
 1610 PRINTFNattr(access%);
 1620 IF(cflg%AND1):PRINTFNdate(mdate%)" "FNh0(sin%,6):ENDPROC
 1630 x%=x%+1:IFx%<(wdt%+1)DIV20:PRINT" ";ELSEx%=0:PRINT
 1640 ENDPROC
 1650 DEFFNattr(A%):A$=""
 1660 IF(A%AND1):A$="r"+A$
 1670 IF(A%AND2):A$="w"+A$
 1680 A$="/"+A$
 1690 IF(A%AND4):A$="R"+A$
 1700 IF(A%AND8):A$="W"+A$
 1710 IF(A%AND16):A$="L"+A$
 1720 IF(A%AND32):A$="D"+A$
 1730 IF(A%AND64):A$="P"+A$
 1740 IF(A%AND128):A$="M"+A$
 1750 =A$+STRING$(8-LENA$," ")
 1760 DEFFNdate(A%)=FNd0(A%AND31,2)+"/"+FNd0((A%DIV256)AND15,2)+"/"+FNd0(1981+(A%DIV4096)+((A%AND&E0)/2),4)
 1770 DEFFNlook:src$=A$:fptr%=FNfind(src$):IFfptr%:=FALSE
 1780 PRINT"'"src$"' not found":=TRUE
 1790 DEFFNfind(A$):match$=FNuc(LEFT$(A$,10)):match%=0:IFFNMount:=0
 1800 PROCRdDir:IFmatch$="^":IFthisdir%!17=&FFFF:thisdir%!19=&D5E:thisdir%?37=32:=thisdir%+17
 1810 fptr%=thisdir%:entry%=1:IFthisdir%?15=0:=0
 1820 REPEAT:fptr%=thisdir%+(!fptr%AND&FFFF)
 1830   A%=fptr%?&C:fptr%?&C=13:fname$=FNs($(fptr%+2)):fptr%?&C=A%
 1840   match%=(FNuc(fname$)=match$):entry%=entry%+1
 1850 UNTILentry%>thisdir%?15ORmatch%
 1860 IFmatch%:=fptr%ELSE=0
 1870 DEFPROCFileInfo(f%,i%)
 1880 A%=f%?&C:f%?&C=13:fname$=FNs($(f%+2)):f%?&C=A%
 1890 FORA%=1TOLENfname$:IFMID$(fname$,A%,1)<"!"ORMID$(fname$,A%,1)>"~":fname$=""
 1900 NEXTA%
 1910 load%=f%!&0C:exec%=f%!&10:access%=f%?&14:mdate%=f%!&15AND&FFFF:sin%=f%!&17AND&FFFFFF
 1920 length%=0:attr%=(access%AND3)*16+(access%AND&C)/4+(access%AND16)/2+mdate%*256
 1930 IF(i%AND1)=0ORsin%=0:ENDPROC
 1940 IFfsv%<4:PROCFileLen1:ENDPROCELSEPROCFileLen2:ENDPROC
 1950 DEFPROCFileLen1
 1960 offset%=sin%:REPEAT
 1970   offset%=(offset%AND&FFF)*2+5
 1980   PROCRdAlloc(map%+offset%DIV256,2)
 1990   offset%=alloc%!(offset%AND255)AND&FFFF
 2000 length%=length%+256:UNTILoffset%AND&4000
 2010 A%=offset%AND255:IFA%:length%=length%+A%-256
 2020 ENDPROC
 2030 DEFPROCFileLen2
 2040 PROCRdAlloc(sin%,1):IFFNChkMap(alloc%):PRINT"Bad map":ENDPROC
 2050 B%=alloc%?8:IFB%:length%=B%-256
 2060 REPEAT
 2070   A%=12:REPEAT:B%=alloc%!A%AND&FFFF00:length%=length%+B%:A%=A%+5:UNTILB%=0ORA%>&F9
 2080   IFA%>&F9:B%=alloc%!250AND&FFFFFF:IFB%:PROCRdAlloc(B%,1)
 2090 UNTILB%=0
 2100 ENDPROC
 2110 DEFPROCRdDir:IFcurr%=csd%:ENDPROC
 2120 IFfsv%<4:PROCRdDir1ELSEPROCRdDir2
 2130 curr%=csd%:ENDPROC
 2140 DEFPROCRdDir1
 2150 addr%=thisdir%:fptr%=csd%:REPEAT
 2160   PROCRdBlocks(addr%,fptr%AND&FFF,D%,1)
 2170   offset%=(fptr%AND&FFF)*2+5
 2180   PROCRdAlloc(map%+offset%DIV256,2)
 2190   fptr%=alloc%!(offset%AND255)AND&FFFF
 2200 addr%=addr%+256:UNTIL(fptr%AND&4000)
 2210 ENDPROC
 2220 DEFPROCRdDir2
 2230 PROCRdAlloc(csd%,1):IFFNChkMap(alloc%):PRINT"Bad map":thisdir%?15=0:ENDPROC
 2240 addr%=thisdir%:fptr%=alloc%+10:REPEAT
 2250   PROCRdBlocks(addr%,!fptr%AND&FFFFFF,D%,fptr%!3AND&FFFF)
 2260   addr%=addr%+256*(fptr%!3AND&FFFF):fptr%=fptr%+5
 2270 UNTIL(!fptr%AND&FFFFFF)=0
 2280 ENDPROC
 2290 DEFFNMount:IFcsd%:=0
 2300 curr%=-1:home%=0:inmem%=0:bps%=256:fsv%=8:REPEAT:fsv%=fsv%+((fsv%AND3)=0)-1:IFfsv%<4:spt%=10ELSEspt%=16
 2310   PROCfdcInit(diskrec%,8,spt%,2,fsv%DIV4+1,80,0):!data%=0:PROCRdBlocks(data%,0,D%,1)
 2320   IFfsv%<4:root%=data%!22AND&FFFFFF:IF!data%=valid%:dib%=0:PROCRdBlocks(data%,root%,D%,1):IFroot%<spt%:fsv%=0
 2330   IFfsv%>3:!data%=-1:dib%=data%!&F6AND&FFFFFF:PROCRdBlocks(data%,dib%,D%,1)
 2340   IFfsv%>3:!data%=-1:root%=data%!&1FAND&FFFFFF:PROCRdBlocks(data%,root%,D%,1)
 2350   IFfsv%>3:!data%=-1:PROCRdBlocks(data%,data%!&0AAND&FFFFFF,D%,1)
 2360   ?data%=-1:IFdata%!3=&20202024:!data%=valid%
 2370 UNTILfsv%=0OR!data%=valid%
 2380 IF!data%=0:IFdrv$<>"":err%=-2
 2390 IFerr%=-2:PRINT"Disk error: image file not found":=-2
 2400 IF!data%<>valid%:=-5
 2410 PROCRdBlocks(data%,dib%,D%,1):path$="$"
 2420 A%=data%?20:data%?20=13:title$=FNs($(data%+4)):data%?20=A%
 2430 freec%=data%!36AND&FFFF:idate%=data%!34AND&FFFF:root%=data%!31AND&FFFFFF:dnxt%=data%?29
 2440 mapsz%=data%?28:nsec%=data%!26AND&FFFF:ndsks%=data%?25:dsize%=data%!22AND&FFFFFF
 2450 ntrk%=data%!20AND&FFFF:mapb%=0:mapa%=0:map%=0:home%=root%:csd%=home%
 2460 IFfsv%>3:=0
 2470 mapsz%=data%?33:mapb%=data%!30AND&FFFFFF:mapa%=data%!27AND&FFFFFF
 2480 idate%=data%!25AND&FFFF:root%=data%!22AND&FFFFFF:dsize%=(data%!20AND&FFFF)*2
 2490 map%=mapa%:home%=root%:csd%=home%
 2500 PROCRdBlocks(data%,mapa%,D%,1):f%=?data%
 2510 PROCRdBlocks(data%,mapb%,D%,1):IF((f%-?data%)AND255)=255:map%=mapb%
 2520 =0
 2530 DEFPROCReadData
 2540 IFsin%=0:ln%=0:eof%=TRUE:ENDPROC
 2550 IFfsv%<4:PROCReadData1ELSEPROCReadData2
 2560 O%=data%:ENDPROC
 2570 DEFPROCReadData1
 2580 PROCRdBlocks(data%,sin%AND&FFF,D%,1)
 2590 offset%=(sin%AND&FFF)*2+5
 2600 PROCRdAlloc(map%+offset%DIV256,2)
 2610 sin%=alloc%!(offset%AND255)AND&FFFF
 2620 eof%=sin%AND&4000:ln%=256
 2630 IFeof%:ln%=sin%AND255:IFln%=0:ln%=256
 2640 ENDPROC
 2650 DEFPROCReadData2
 2660 eof%=0:IFS%=0:aptr%=0
 2670 IFaptr%=0:PROCRdAlloc(sin%,1):IFFNChkMap(alloc%):PRINT"Bad map":eof%=TRUE:ln%=0:ENDPROC
 2680 ln%=alloc%?8:REPEAT:IFaptr%<10:aptr%=10
 2690   sec%=alloc%!aptr%AND&FFFFFF
 2700   num%=alloc%!(aptr%+3)AND&FFFF
 2710   IFaptr%=250:PROCRdAlloc(sec%,1):alloc%?8=ln%:aptr%=0
 2720 UNTILaptr%:PROCRdBlocks(data%,sec%,D%,1)
 2730 sec%=sec%+1:num%=num%-1:alloc%!aptr%=sec%
 2740 alloc%?(aptr%+3)=num%:alloc%?(aptr%+4)=num%DIV256
 2750 ln%=256:IFnum%=0:aptr%=aptr%+5:IFalloc%!aptr%=0:eof%=TRUE:ln%=alloc%?8:IFln%=0:ln%=256
 2760 ENDPROC
 2770 DEFPROCRdAlloc(sin%,num%):IFsin%=inmem%:ENDPROC
 2780 PROCRdBlocks(alloc%,sin%,D%,num%):inmemX%=sin%:ENDPROC
 2790 DEFFNChkMap(B%):A%=B%?6:B%?6=13:IF$B%=map$:B%?6=A%:=B%?6<>B%?255ELSEB%?6=A%:=TRUE
 2800 DEFPROCRdBlocks(ad%,bl%,dv%,nm%):LOCALp%
 2810 err%=0:FORp%=0TOnm%-1:PROCfdcRd(ad%+p%*256,bl%+p%,dv%,1,fsv%DIV4+1)
 2820 NEXT:ENDPROC
 2830 DEFPROCfdcInit(dskrec%,bps%,spt%,hds%,den%,trks%,sec0%)
 2840 LOCALi%:IFos%<>6:ENDPROC
 2850 dskrec%?0=bps%:dskrec%?1=spt%:dskrec%?2=hds%:dskrec%?3=den%:IFden%=1:dskrec%?2=1
 2860 FORi%=4TO59STEP4:dskrec%!i%=0:NEXT:dskrec%!60=&20000000:dskrec%!64=&20000000
 2870 dskrec%?8=sec0%:dskrec%!16=trks%*spt%*(2^bps%)*hds%
 2880 ENDPROC
 2890 DEFPROCfdcRd(addr%,sec%,drv%,num%,den%)
 2900 FORA%=0TO255STEP4:addr%!A%=0:NEXT:IFdrv%>7:err%=-1:ENDPROC
 2910 A%=sec%DIVspt%
 2920 IFfsv%AND1:sec%=((A%MOD80)*2+(A%DIV80))*spt%+(sec%MODspt%)
 2930 IFfsv%AND2:sec%=((A%MOD2)*80+(A%DIV2))*spt%+(sec%MODspt%)
 2940 IFdrv$="":REPEAT:PROCfdcOp(1):addr%=addr%+256:sec%=sec%+1:num%=num%-1:UNTILnum%<1:ENDPROC
 2950 dsk%=FNf_openin(drv$):IFdsk%=0:err%=-2:ENDPROC
 2960 IFsec%*256>EXT#dsk%:CLOSE#dsk%:dsk%=0:err%=-3:PRINTLEFT$("Disk error: past end of image"+CHR$10+CHR$13,curr%<>-1);:ENDPROC
 2970 PROCgbpb(3,dsk%,addr%,num%*256,sec%*256):CLOSE#dsk%:dsk%=0
 2980 ENDPROC
 2990 DEFPROCfdcOp(op%)
 3000 IFos%=6:SYS"XADFS_DiscOp",0,op%+64+(diskrec%<<6),sec%*bps%+((drv%AND3)<<29),addr%,bps%TOerr%
 3010 IFos%<6:IFden%=1:IFop%=1:err%=FNdisk(addr%,&53,(drv%AND3)+2*(sec%DIV800),(sec%DIV10)MOD80,sec%MOD10,1,den%)
 3020 IFos%<6:IFden%>1:IFop%=1:err%=FNscsi(addr%,&08,drv%,sec%,1)
 3030 IFcsd%=0:ENDPROC
 3040 IFerr%:IFPOS:PRINT
 3050 IFerr%=-1:PRINT"Unsupported":ENDPROC
 3060 IFerr%:PRINT"Disk error &"FNh0(err%,2)" at ";drv%":"FNh0(sec%,6)
 3070 ENDPROC
 3080 DEFFNfn_todos(A$):LOCALB%:IF(os%AND-32)=0:=A$
 3090 FORA%=1TOLENA$:B%=INSTR("/?<>+=;\",MID$(A$,A%,1)):IFB%:A$=LEFT$(A$,A%-1)+MID$(".#$^&@%~",B%,1)+MID$(A$,A%+1)
 3100 NEXT:=A$
 3110 DEFFNyna(A%):IFA%=0:=0
 3120 PRINT"? (Y/N/A)";:REPEAT:A%=INSTR("YAN",CHR$(GETAND&DF)):UNTILA%
 3130 PRINTSTRING$(7,CHR$127);MID$("YesAllNo ",A%*3-2,3);:=A%-2
 3140 DEFFNdisk(addr%,cmd%,drv%,trk%,sec%,num%,den%):LOCALfs%
 3150 fs%=FNfs:IFfs%<>4:*FX143,18,4
 3160 REPEATX%?0=drv%+den%*24+8:X%!1=addr%:X%?5=3-7*(cmd%>127)
 3170   X%?6=cmd%:X%?7=trk%:X%?8=sec%:X%?9=num%OR&20:A%=127:CALL&FFF1
 3180 A%=X%?(7+X%?5):UNTILA%<>&10:IFfs%<>4:OSCLI"FX143,18,"+STR$fs%
 3190 =A%
 3200 DEFFNscsi(addr%,cmd%,drv%,sect%,num%):LOCALfs%
 3210 fs%=FNfs:IFfs%<>8:*FX143,18,8
 3220 X%?0=0:X%!1=addr%:X%?5=cmd%:X%?6=drv%*32+((sect%AND&1F0000)DIV65536)
 3230 X%?7=((sect%AND&FF00)DIV256):X%?8=sect%:X%!9=num%:X%!11=0
 3240 A%=&72:CALL&FFF1:A%=?X%:IFfs%<>8:OSCLI"FX143,18,"+STR$fs%
 3250 =A%
 3260 DEFFNfx(A%,X%):LOCALY%:Y%=X%DIV256:=((USR&FFF4)AND&FFFF00)DIV256
 3270 DEFFNh0(A%,N%):=RIGHT$("0000000"+STR$~A%,N%)
 3280 DEFFNd0(A%,N%):=RIGHT$("00000000"+STR$A%,N%)
 3290 DEFFNs(A$):IFLEFT$(A$,1)=" ":REPEATA$=MID$(A$,2):UNTILLEFT$(A$,1)<>" "
 3300 IFRIGHT$(A$,1)=" ":REPEATA$=LEFT$(A$,LENA$-1):UNTILRIGHT$(A$,1)<>" "
 3310 =A$
 3320 DEFFNuc(A$):LOCALB$:IFA$="":=""
 3330 REPEATB$=B$+CHR$(ASCA$AND((A$<"@")OR&DF)):A$=MID$(A$,2):UNTILA$="":=B$
 3340 DEFFNfile(A$,A%):IFA%-8:IFPAGE<&FFFFF:$name%=A$:?X%=name%:X%?1=name%DIV256:=(USR&FFDD)AND&FF
 3350 A$=FNf_name(A$):IFA%=255ORA%=5:X%!14=OPENIN(A$):IFX%!14:X%!10=EXT#X%!14:CLOSE#X%!14:X%!14=&33
 3360 IFA%=255:IFX%?6=0:OSCLI"LOAD """+A$+""" "+STR$~X%!2:=1
 3370 IFA%=5:IFX%!14:=1ELSEIFA%=5:=0
 3380 IFA%=0:OSCLI"SAVE """+A$+""" "+STR$~X%!10+" "+STR$~X%!14:X%!10=X%!14-X%!10:=1
 3390 IFA%=7:OSCLI"SAVE """+A$+""" "+STR$~PAGE+"+"+STR$~X%!10:X%!10=X%!14-X%!10:=1
 3400 IFA%-8:=0
 3410 IF(os%AND-24):A$="mkdir "+A$ELSEA$="cdir "+A$
 3420 IFHIMEM>&FFFF:LOCALERROR:ONERRORLOCAL:=0
 3430 OSCLIA$:=2
 3440 DEFPROCgbpb(A%,chn%,addr%,num%,ptr%)
 3450 ?X%=chn%:X%!1=addr%:X%!5=num%:X%!9=ptr%:IFPAGE<&FFFFF:CALL&FFD1:ENDPROC
 3460 IFA%=1ORA%=3:PTR#?X%=X%!9
 3470 REPEAT:IFA%=1ORA%=2:BPUT#?X%,?X%!1ELSEIFA%=3ORA%=4:?X%!1=BGET#?X%
 3480 X%!1=X%!1+1:X%!5=X%!5-1:UNTIL(EOF#?X%ANDA%>2)ORX%!5<1:ENDPROC
 3490 DEFFNfs:IF(os%AND-32)=0:LOCALA%,Y%,E%:=(USR&FFDA)AND&FF
 3500 =29
 3510 DEFFNf_openin(A$)=OPENIN(FNf_name(A$))
 3520 DEFFNf_openout(A$)=OPENOUT(FNf_name(A$))
 3530 DEFFNf_name(A$):IFos%AND-32:LOCALA%,B%:REPEATB%=A%:A%=INSTR(A$,"\",A%+1):UNTILA%=0:IFINSTR(A$,".",B%)=0:A$=A$+"."
 3540 =A$
 3550 DEFFNNetFS_Op(A%,A$)=FNNetFS_OpN(A%,0,7,A$)
 3560 DEFFNNetFS_OpN(A%,T%,O%,A$):LOCALN%:!X%=0:X%?1=O%+1+LENA$:X%!3=A%:X%?7=T%:$(X%+O%)=A$
 3570 IFHIMEM>&FFFF:FORN%=4TOX%?1:X%?N%=X%?(N%+3):NEXT:SYS&60048,A%,X%+4,O%+LENA$,120TOA%:IFA%=0:X%?3=0:=0
 3580 IFHIMEM>&FFFF:IFA%>&FFFF:X%?3=?A%:SYS&2002B,A%+4TO$(X%+4):=X%?3
 3590 A%=&14:CALL&FFF1:=X%?3