10 REM > UxFiler
   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 REPEAT: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 UNTILFALSE
  100 DEFPROCinit:ver$="1.32":bsz%=1024:fsv%=6
  110 DIMctrl% 127,name% 255,zp% 7,data% bsz%-1,data2% bsz%-1,ientry% 63,dir% bsz%+4,object% 63,thisdir% 63,diskrec% 255AND(os%=6)
  120 X%=ctrl%:Y%=X%DIV256:res%=0:D%=0:dmk%=&FFFF:drv$="":path$="/":title$="":home%=-1:csd%=-1
  130 fs%=FNfs:d$=".":s$="/":IFos%AND-24:d$="/":s$=".":IFos%AND-32:d$="\"
  140 cmd$=":MOUNT:DIR:CD:CAT:EX:LS:INFO:TYPE:DUMP:IMPORT:EXPORT:FREE:BLOCK:HELP:QUIT:"
  150 hlp$=":<drive>|<image>:<dir>|&<inode>:<dir>|&<inode>::::(<file>):<file> [CTRLS]:<file> [7BIT]:<host source> <unix dest> (<opts>):<unix source> <host dest> (<opts>)::<blocknum>:::"
  160 ENDPROC
  170 DEFPROChdr:PRINT"UxFiler 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:in%=in%:IFin%:A%=in%:in%=0:CLOSE#A%
  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 IFB$="COPY":PRINT"Use EXPORT or IMPORT":ENDPROC
  310 IFLENB$=1ANDINSTR("0123",B$):drv$="":D%=VALB$:home%=-1:ENDPROC
  320 A%=INSTR(cmd$,":"+B$+":"):IFA%=0:PRINT"Bad command":ENDPROC
  330 A%=EVAL("FN_"+B$+"(A$)"):ENDPROC
  340 DEFFNsyn(S$):IFA$="":PRINT"Syntax: "B$" "S$:=TRUEELSE=FALSE
  350 DEFFN_QUIT(A$):PRINT"Quit"
  360 ONERROREND
  370 IFos%>5:*QUIT
  380 END
  390 DEFFN_HELP(A$):PROChdr:p%=2:q%=2:REPEAT
  400   A%=INSTR(cmd$,":",p%):PRINTSPC2MID$(cmd$,p%,A%-p%);:p%=A%+1
  410   A%=INSTR(hlp$,":",q%):PRINTTAB(9)MID$(hlp$,q%,A%-q%):q%=A%+1
  420 UNTILp%>LENcmd$:=0
  430 DEFFN_MOUNT(A$):home%=-1:IFLENA$<2:PROCdo(A$):=0ELSEdrv$=A$:D%=-1:=0
  440 DEFFN_CAT(A$):PROCLstDir(0):=0
  450 DEFFN_EX(A$):PROCLstDir(1):=0
  460 DEFFN_LS(A$)=FN_EX(A$)
  470 DEFFN_CD(A$)=FN_DIR(A$)
  480 DEFFN_DIR(A$):curr%=-1:IFFNsyn("<dir>|&<inode>"):=TRUE
  490 IFLEFT$(A$,1)="&":A%=FNMount:home%=EVAL(FNuc(A$)):path$="&"+FNh0(home%,6):=0
  500 IFA$="/":A%=FNMount:home%=root%:path$="/":=0
  510 IFFNlook:=TRUE
  520 IF(mode%AND16384)=0:PRINT"'"src$"' not a directory":=TRUE
  530 path$=path$+fname$+"/":home%=ptr%
  540 IFRIGHT$(path$,3)="../":path$=LEFT$(path$,LENpath$-4):REPEAT:path$=LEFT$(path$,LENpath$-1):UNTILRIGHT$(path$,1)="/"ORpath$=""
  550 IFRIGHT$(path$,2)="./":path$=LEFT$(path$,LENpath$-2)
  560 =0
  570 DEFFN_BLOCK(A$):IFFNsyn("<blocknum>"):=TRUE
  580 A%=FNMount:blk%=EVAL("&"+FNuc(A$)):PROCRdBlocks(data%,blk%,D%,1):O%=data%:ln%=512:PROCdump(FALSE)
  590 =0
  600 DEFFN_DUMP(A$):IFFNsyn("<fsp>"):=TRUE
  610 IFFNlook:=TRUE
  620 PROCdump(TRUE)
  630 =0
  640 DEFPROCdump(F%):cols%=16:IFwdt%<80:cols%=8
  650 FORP%=0TOln%-1STEPcols%:B$=""
  660   PRINTFNh0(P%,6)" ";:IFF%:IF(P%AND(bsz%-1))=0:PROCReadData(P%):O%=data%
  670   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: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 last%=0:FORP%=0TOln%-1:IF(P%AND(bsz%-1))=0:PROCReadData(P%):O%=data%
  750   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:IFPOS:PRINT
  790 =0
  800 DEFFN_FREE(A$):A%=FNMount
  810 PROCRdInode(0):PROCRdBlocks(dir%,1,D%,1):isize%=dir%!0AND&FFFF
  820 IFfsv%=6:fsize%=dir%!2AND&FFFF:nfree%=dir%!4AND&FFFF:ptr%=dir%!6AND&FFFF
  830 IFfsv%>6:fsize%=FNswap32(dir%!2):nfree%=dir%!6AND&FFFF:ptr%=FNswap32(dir%!8)
  840 free%=nfree%:REPEAT
  850   IFptr%:PROCRdBlocks(data%,ptr%,D%,1):IFdata%?1=0:free%=free%+data%?0-1
  860   IFptr%:IFfsv%=6:ptr%=data%!2AND&FFFF
  870   IFptr%:IFfsv%>6:ptr%=FNswap32(data%!2)
  880 UNTILptr%<2ORptr%>=fsize%:used%=fsize%-free%
  890 PRINT"Disk free: &"FNh0(free%,8)" blocks, &"FNh0(free%*bsz%,8)" bytes, ";free%DIV(1024/bsz%);"K"
  900 PRINT"Disk used: &"FNh0(used%,8)" blocks, &"FNh0(used%*bsz%,8)" bytes, ";used%DIV(1024/bsz%);"K"
  910 PRINT"Disk size: &"FNh0(fsize%,8)" blocks, &"FNh0(fsize%*bsz%,8)" bytes, ";fsize%DIV(1024/bsz%);"K"
  920 =0
  930 DEFFN_INFO(A$)
  940 IFA$=""ORA$="$":PROCPrSBlock:=0
  950 IFFNlook:=TRUE
  960 inode%=ptr%:x%=0:PROCListFile(1)
  970 FORp%=all0%TOalmx%-1STEPalsz%:PRINTFNh0(FNblk(ientry%!p%),alsz%*2);" ";:NEXT:PRINT
  980 =0
  990 DEFFN_EXPORT(A$):IFFNsyn("<unix source> (inf:)<host dest> (<C>onfirm)"):=TRUE
 1000 A%=INSTR(A$+" "," "):src$=LEFT$(A$,A%-1):dst$=FNs(MID$(A$,A%+1))
 1010 cnf%=FNuc(RIGHT$(dst$,2))=" C":IFcnf%:dst$=FNs(LEFT$(dst$,LENdst$-2))
 1020 inf%=FNuc(LEFT$(dst$,4))="INF:":IFinf%:dst$=MID$(dst$,5)
 1030 IFdst$="":PRINT"<dest> missing":=TRUE
 1040 IFos%<6:IFINSTR(dst$,"::")ORLEFT$(dst$,1)="-":PRINT"FS prefix unsupported":=TRUE
 1050 A$=src$:IFA$<>"/":A%=FNlook:cblk%=ptr%:IFA%:=TRUE
 1060 IFA$="/":A%=FNMount:cblk%=root%:IFA%<0:=TRUE
 1070 PROCFileInfo(cblk%)
 1080 IF(mode%AND24576)<>16384:fptr%=ientry%:leaf$=src$:PROCCopyOneFile(src$,dst$):=0
 1090 A%=FNfile(dst$,8):dst$=dst$+d$:PROCCopyDirectory(dst$)
 1100 PROCMetaInfo(thisdir%):PROCAcornInfo
 1110 PROCSetInfo(LEFT$(dst$,LENdst$-1))
 1120 =0
 1130 DEFFN_IMPORT(A$):IFFNsyn("<host source> <unix dest>"):=TRUE
 1140 A%=INSTR(A$," "):src$=LEFT$(A$,A%-1):A$=MID$(A$,A%+1)
 1150 A%=INSTR(A$," "):dst$=LEFT$(A$,A%-1):A$=MID$(A$,A%+1)
 1160 ptr%=FNfind(dst$):IFptr%=0:PRINT"'"dst$"' not found":=TRUE
 1170 PROCFileInfo(ptr%)
 1180 in%=FNf_openin(src$):IFin%=0:PRINT"'"src$"' not found":=TRUE
 1190 ln%=EXT#in%:IFln%>length%:CLOSE#in%:in%=0:PRINT"Source file longer than dest":=TRUE
 1200 IFln%>1024*1024-1:CLOSE#in%:in%=0:PRINT"Can't 1M+ files yet":=TRUE
 1210 PRINT"Copying "src$;" to "dst$;SPC4;
 1220 FORP%=0TOln%-1:B%=0
 1230   IF(P%AND(bsz%-1))=0:PROCf_gbpb(3,in%,data%,bsz%,P%):PROCWriteData(P%):PRINTSTRING$(3,CHR$8)FNd(100*P%DIVlength%,2)"%";
 1240 NEXT:CLOSE#in%:in%=0:PRINTSTRING$(3,CHR$127)
 1250 =0
 1260 DEFPROCCopyDirectory(dst$):LOCALentry%,bit%,inode%,fptr%,fname$,blk%,dptr%,alloc%
 1270 FORA%=0TO63STEP4:thisdir%!A%=ientry%!A%:NEXT
 1280 alloc%=all0%
 1290 REPEAT
 1300   blk%=FNblk(thisdir%!alloc%):IFblk%:PROCCopyBlock
 1310   alloc%=alloc%+alsz%
 1320 UNTILblk%=0ORalloc%>almx%-1
 1330 ENDPROC
 1340 DEFPROCCopyBlock
 1350 PROCRdBlocks(dir%,blk%,D%,1):dptr%=dir%
 1360 REPEAT
 1370   inode%=!dptr%AND&FFFF
 1380   A%=dptr%?16:dptr%?16=13:fname$=$(dptr%+2)+CHR$0:dptr%?16=A%
 1390   fname$=LEFT$(fname$,INSTR(fname$,CHR$0)-1)
 1400   IFinode%THENPROCCopyObject
 1410   dptr%=dptr%+16
 1420 UNTILdptr%>=dir%+bsz%
 1430 ENDPROC
 1440 DEFPROCCopyObject:LOCALptr%,bit%,old_cblk%,thisdir$,bitmap$,object$
 1450 IFfname$="."ORfname$="..":ENDPROC
 1460 IFcnf%:PRINT"Copy "fname$;:cnf%=FNyna(cnf%):IFcnf%>0:PRINT:ENDPROCELSEVDU13
 1470 PROCFileInfo(inode%):leaf$=fname$:fname$=LEFT$(FNfn_undos(fname$),10):fptr%=ientry%
 1480 IF(mode%AND24576)<>16384:PROCCopyOneFile(leaf$,dst$+fname$):ENDPROC
 1490 old_cblk%=cblk%
 1500 FORA%=0TO63:thisdir$=thisdir$+CHR$thisdir%?A%:NEXT
 1510 FORA%=0TO63:object$ =object$ +CHR$fptr%?A%:NEXT
 1520 cblk%=inode%
 1530 A%=FNfile(dst$+fname$,8)
 1540 PROCCopyDirectory(dst$+fname$+d$)
 1550 FORA%=0TO63:object%?A%=ASCMID$(object$,A%+1):NEXT
 1560 PROCMetaInfo(object%)
 1570 PROCAcornInfo:PROCSetInfo(dst$+fname$)
 1580 FORA%=0TO63:thisdir%?A%=ASCMID$(thisdir$,A%+1):NEXT
 1590 cblk%=old_cblk%:PROCRdBlocks(dir%,blk%,D%,1)
 1600 ENDPROC
 1610 DEFPROCCopyOneFile(src$,dst$):LOCALcblk%
 1620 PRINT"Copying "src$;SPC(15-LENsrc$)"to "dst$SPC4;
 1630 FORA%=0TO63STEP4:object%!A%=fptr%!A%:NEXT
 1640 PROCMetaInfo(object%):IFFNfile(dst$,5):X%?14=&33:A%=FNfile(dst$,4)
 1650 PROCAcornInfo:X%!2=load%:X%!6=exec%:X%!10=0:X%!14=length%:A%=FNfile(dst$,7)
 1660 IFlength%:PROCCopyData
 1670 PROCSetInfo(dst$):PRINTSTRING$(3,CHR$127):ENDPROC
 1680 DEFPROCCopyData
 1690 out%=FNf_openout(dst$):P%=0:REPEAT:PROCReadData(P%):IFPOS=0:PRINTSPC4;
 1700   IF(P%AND1023)=0:PRINTSTRING$(3,CHR$8)FNd(100*P%DIVlength%,2)"%";
 1710   num%=bsz%:IFP%+num%>length%:num%=length%-P%
 1720 PROCf_gbpb(2,out%,data%,num%,0):P%=P%+num%:UNTILP%>=length%
 1730 CLOSE#out%:out%=0:ENDPROC
 1740 DEFPROCSetInfo(dst$):X%!2=load%:X%!6=exec%:X%!10=length%:X%!14=attr%:A%=FNfile(dst$,1)
 1750 A$=leaf$+STRING$(15-LENleaf$," ")+FNh0(load%,8)+" "+FNh0(exec%,8)+" "+FNh0(length%,8)+CHR$13+CHR$10
 1760 IFinf%:out%=OPENOUT(dst$+s$+"inf"):FORp%=1TOLENA$:BPUT#out%,ASCMID$(A$,p%,1):NEXT:CLOSE#out%:out%=0
 1770 IFfs%<>5:ENDPROC
 1780 X%!8=cdate%:A%=FNNetFS_OpN(19,5,10,dst$)
 1790 IFFNNetFS_Op(18,CHR$64+dst$):ENDPROC
 1800 X%!8=cdate%:X%!10=ctime%:X%!13=mdate%:X%!15=mtime%
 1810 A%=FNNetFS_OpN(19,64,18,dst$)
 1820 A%=FNNetFS_Op(0,"ACCOUNT "+dst$+" "+STR$~acc%+" ("+STR$~aux%+")")
 1830 ENDPROC
 1840 DEFPROCLstDir(cflg%):x%=0:IFFNMount:PRINT"Not a UNIX disk":ENDPROC
 1850 PROCRdInode(csd%)
 1860 IF(ientry%?1AND(64+32))<>64THENPRINT"inode "FNh0(csd%,4)" is not a directory":ENDPROC
 1870 PRINT"Path: "path$
 1880 IF(cflg%AND1):PRINT"inode filename"SPC12"mode"SPC6"nd uid gid len   ctime"SPC4"mtime"SPC4"atime"
 1890 alloc%=all0%
 1900 REPEAT
 1910   blk%=FNblk(ientry%!alloc%):IFblk%:PROCListBlock
 1920   alloc%=alloc%+alsz%
 1930   IFalloc%<almx%:PROCRdInode(csd%)
 1940 UNTILblk%=0ORalloc%>almx%-1
 1950 IF(cflg%AND1)=0:IF(x%AND3):PRINT
 1960 ENDPROC
 1970 DEFPROCListBlock
 1980 PROCRdBlocks(dir%,blk%,D%,1):dptr%=dir%
 1990 REPEAT
 2000   inode%=!dptr%AND&FFFF
 2010   A%=dptr%?16:dptr%?16=13:fname$=$(dptr%+2)+CHR$0:dptr%?16=A%
 2020   fname$=LEFT$(fname$,INSTR(fname$,CHR$0)-1)
 2030   IFinode%:PROCListFile(cflg%)
 2040   dptr%=dptr%+16
 2050 UNTILdptr%>=dir%+bsz%
 2060 ENDPROC
 2070 DEFPROCListFile(cflg%)
 2080 IF(cflg%AND1):PRINTFNh0(inode%,4)" ";
 2090 PROCFileInfo(inode%):PRINTfname$;SPC(15-LENfname$);
 2100 IF(cflg%AND1)=0:x%=x%+1:IFx%<wdt%DIV15:PRINT" ";ELSEIF(cflg%AND1)=0:x%=0:PRINTCHR$8
 2110 IF(cflg%AND1)=0:ENDPROC
 2120 PRINTFNattr(mode%)" ";
 2130 PRINTFNh0(nlink%,2)" ";
 2140 PRINTFNh0(uid%,2)" ";
 2150 PRINTFNh0(gid%,2)" ";
 2160 PRINTFNd(length%,6);" ";
 2170 PRINTFNdate(cdate%);" "FNdate(mdate%);" "FNdate(adate%)
 2180 ENDPROC
 2190 DEFPROCPrSBlock
 2200 A%=FN_FREE("")
 2210 PRINT"UnixFS version:";SPC14;fsv%;" (";4*LEN(STR$~dmk%);"-bit) bsz=";bsz%;" naddr=";naddr%
 2220 PRINT"isize: inode table size:"SPC5"&"FNh0(isize%,4)" blocks, max inode: &";~isize%*bsz%/isz%
 2230 PRINT"in-core free blocks: &"FNh0(nfree%,4)
 2240 IFfsv%=6:fbk%=6:stp%=2:ino%=&CE:in1%=&197
 2250 IFfsv%>6:fbk%=8:stp%=4:ino%=&D0:in1%=&199
 2260 FORn%=fbk%TOino%-1STEPstp%:IFfsv%=6:PRINTFNh0(dir%!n%,4);ELSEIFfsv%>6:PRINTFNh0(FNswap32(dir%!n%),8);
 2270   IF(n%AND31)=4:PRINTCHR$8ELSEPRINT" ";
 2280 NEXT:PRINT
 2290 PRINT"in-core free inodes: &"FNh0(dir%!ino%,4)
 2300 FORn%=ino%+2TOin1%STEP2:PRINTFNh0(dir%!n%,4);:IF((n%-ino%-2)AND31)=30:PRINTCHR$8ELSEPRINT" ";
 2310 NEXT:PRINT
 2320 PRINT"flock: free list lock:"SPC7FNh0(dir%?(in1%+1),2);SPC8;
 2330 PRINT"ilock: inode table lock: "FNh0(dir%?(in1%+2),2)
 2340 PRINT"fmod:  superblock modified:  "FNh0(dir%?(in1%+3),2);SPC8;
 2350 PRINT"dlock: disk read only:"SPC3FNh0(dir%?(in1%+4),2)
 2360 PRINT"time:  disk last update:"SPC5FNdate(FNswap32(dir%!(in1%+5)))
 2370 FORn%=in1%+9TO&1FFSTEP2:PRINTFNh0(dir%!n%,4);:IF((n%-in1%-9)AND31)=30:PRINTCHR$8ELSEPRINT" ";
 2380 NEXT:IFPOS:PRINT
 2390 ENDPROC
 2400 DEFFNattr(A%):A$=""
 2410 IF(A%AND1)THENA$="x"ELSEA$="-"
 2420 IF(A%AND2)THENA$="w"+A$ELSEA$="-"+A$
 2430 IF(A%AND4)THENA$="r"+A$ELSEA$="-"+A$
 2440 IF(A%AND8)THENA$="x"+A$ELSEA$="-"+A$
 2450 IF(A%AND16)THENA$="w"+A$ELSEA$="-"+A$
 2460 IF(A%AND32)THENA$="r"+A$ELSEA$="-"+A$
 2470 IF(A%AND64)THENA$="x"+A$ELSEA$="-"+A$
 2480 IF(A%AND128)THENA$="w"+A$ELSEA$="-"+A$
 2490 IF(A%AND256)THENA$="r"+A$ELSEA$="-"+A$
 2500 IF(A%AND512)THENA$="s"+A$ELSEA$="-"+A$
 2510 IF(A%AND1024)THENA$="g"+A$ELSEA$="-"+A$
 2520 IF(A%AND2048)THENA$="u"+A$ELSEA$="-"+A$
 2530 IF(A%AND4096)THENA$="l"+A$ELSEA$="-"+A$
 2540 IF(A%AND8192)THENA$="c"+A$ELSEA$="-"+A$
 2550 IF(A%AND16384)THENA$="d"+A$ELSEA$="-"+A$
 2560 IF(A%AND32768)THENA$="a"+A$ELSEA$="-"+A$
 2570 =A$
 2580 DEFFNdate(A%)
 2590 LOCALday%,month%,year%,hour%,minute%,second%
 2600 X%!1=A%/2.56:X%!1=X%!1+&336E996A:PROCDate_ToOrd(X%)
 2610 =FNd0(day%,2)+"/"+FNd0(month%,2)+"/"+FNd0(year%,2)
 2620 DEFPROCUnixDateToAcorn(A%)
 2630 X%!1=A%/2.56:X%!1=X%!1+&336E996A:PROCDate_ToOrd(X%)
 2640 date%=&101:IFyear%>1980:date%=FNf_date(day%,month%,year%)
 2650 time%=FNf_time(hour%,minute%,second%)
 2660 ENDPROC
 2670 DEFPROCAcornInfo
 2680 attr%=(mode%AND256)DIV256+(mode%AND128)DIV64+(mode%AND64)DIV16
 2690 attr%=attr%+(((mode%AND32)/2)OR((mode%AND4)*4))+(((mode%AND16)*2)OR((mode%AND2)*16))+(((mode%AND8)*8)OR((mode%AND1)*64))
 2700 IFcdate%>mdate%:cdate%=mdate%
 2710 PROCUnixDateToAcorn(cdate%):cdate%=date%:ctime%=time%
 2720 PROCUnixDateToAcorn(mdate%):mdate%=date%:mtime%=time%
 2730 PROCDate_FromOrd(X%,day%,month%,year%,hour%,minute%,second%,0)
 2740 X%!5=&FFFFFF:IF(mode%AND&49):X%!5=&FFFFE6
 2750 load%=X%!4:exec%=!X%:attr%=attr%+256*mdate%:acc%=uid%:aux%=gid%
 2760 ENDPROC
 2770 DEFFNlook:src$=A$:ptr%=FNfind(src$):IFptr%:PROCFileInfo(ptr%):ln%=length%:=FALSE
 2780 PRINT"'"src$"' not found":=TRUE
 2790 DEFFNfind(A$):match$=LEFT$(A$,14):match%=0:IFFNMount:=0
 2800 PROCRdInode(csd%):IFcsd%=-1:csd%=root%
 2810 alloc%=all0%:match%=0
 2820 REPEAT
 2830   blk%=FNblk(ientry%!alloc%):IFblk%:PROCFileBlock
 2840   alloc%=alloc%+alsz%
 2850   IFNOTmatch%:IFalloc%<almx%:PROCRdInode(csd%)
 2860 UNTILblk%=0ORalloc%>almx%-1ORmatch%
 2870 IFmatch%:=inode%ELSE=0
 2880 DEFPROCFileBlock
 2890 PROCRdBlocks(dir%,blk%,D%,1):dptr%=dir%
 2900 REPEAT
 2910   inode%=!dptr%AND&FFFF
 2920   A%=dptr%?16:dptr%?16=13:fname$=$(dptr%+2)+CHR$0:dptr%?16=A%
 2930   fname$=LEFT$(fname$,INSTR(fname$,CHR$0)-1)
 2940   match%=fname$=match$
 2950   dptr%=dptr%+16
 2960 UNTILdptr%>=dir%+bsz%ORmatch%
 2970 ENDPROC
 2980 DEFPROCFileInfo(f%):PROCRdInode(f%):PROCMetaInfo(ientry%):ENDPROC
 2990 DEFPROCMetaInfo(i%)
 3000 mode%  =i%!0AND&FFFF
 3010 nlink% =i%!2ANDimk%
 3020 uid%   =i%!(2+usz%/2)ANDimk%
 3030 gid%   =i%!(2+2*(usz%/2))ANDimk%
 3040 IFisz%=32:length%=FNswap24(i%!5)
 3050 IFisz%>32:length%=FNswap32(i%!8)
 3060 IFisz%=32:adate%=FNswap32(i%!tm%):mdate%=FNswap32(i%!(tm%+4)):cdate%=mdate%
 3070 IFisz%>32:adate%=FNswap32(i%!(tm%+8)):mdate%=FNswap32(i%!(tm%+4)):cdate%=FNswap32(i%!tm%)
 3080 ENDPROC
 3090 DEFPROCRdInode(i%)
 3100 PROCRdBlocks(data%,(bsz%*2+i%*isz%-isz%)DIV(bsz%),D%,1)
 3110 i%=(bsz%*2+i%*isz%-isz%)AND(bsz%-1)
 3120 FORA%=0TOisz%-1STEP4:ientry%!A%=data%!(A%+i%):NEXT
 3130 ENDPROC
 3140 DEFFNMount:IFcsd%<>-1:=0
 3150 bsz%=512:PROCfdcInit(diskrec%,9,9,2,2,80,1):PROCRdBlocks(data%,2,D%,1)
 3160 IFerr%=-2:PRINT"Disk error: Image file not found":=-2
 3170 fsv%=6:isz%=32:root%=1:all0%=08:alsz%=2:naddr%=08:tm%=&18:usz%=2:bsz%=0512
 3180 IFdata%!8=0:fsv%=7:isz%=64:root%=2:all0%=12:alsz%=3:naddr%=13:tm%=&34:usz%=4:bsz%=0512
 3190 IFdata%?1<&80:fsv%=9:isz%=64:root%=2:all0%=12:alsz%=3:naddr%=07:tm%=&34:usz%=4:bsz%=1024
 3200 almx%=all0%+alsz%*naddr%:dmk%=EVAL("&"+STRING$(alsz%,"FF")):imk%=EVAL("&"+STRING$(usz%,"FF"))
 3210 csd%=root%:home%=csd%:path$="/"
 3220 =0
 3230 DEFFNblk(b%)
 3240 IFalsz%=2:=b%AND&FFFF
 3250 IFalsz%=3:=FNswap24(b%)
 3260 =FNswap32(b%)
 3270 DEFPROCReadData(ptr%):PROCTxData(FALSE):ENDPROC
 3280 DEFPROCWriteData(ptr%):PROCTxData(TRUE):ENDPROC
 3290 DEFPROCTxData(write%):LOCALp%
 3300 IFalsz%=2:PROCTx16ELSEPROCTx24
 3310 IFp%=0:IFNOTwrite%:FORA%=0TObsz%-1STEP4:data%!A%=0:NEXT:ENDPROC
 3320 IFp%:PROCTxBlocks(data%,p%,D%,1,write%)
 3330 ENDPROC
 3340 DEFPROCTx24
 3350 p%=ptr%DIVbsz%:IFp%<naddr%-3:p%=all0%+p%*alsz%:p%=FNblk(ientry%!p%):ENDPROC
 3360 ptr%=(p%-naddr%+3)
 3370 p%=ptr%DIV(bsz%/4)
 3380 PROCRdBlocks(data2%,FNblk(ientry%!(almx%+(p%-3)*alsz%)),D%,1)
 3390 IFp%>1:p%=0:ENDPROC
 3400 IFp%=1:PROCRdBlocks(data2%,data2%!((ptr%DIV(bsz%/4))*4),D%,1):ptr%=ptr%MOD(bsz%/4)
 3410 p%=FNswap32(data2%!(ptr%*4))
 3420 ENDPROC
 3430 DEFPROCTx16
 3440 IF(mode%AND4096)=0:p%=all0%+2*(ptr%DIVbsz%):p%=ientry%!p%:ENDPROC
 3450 p%=all0%+2*(ptr%DIV(128*1024))
 3460 PROCRdBlocks(data2%,ientry%!p%,D%,1)
 3470 p%=(ptr%DIVbsz%)AND&FF:p%=data2%!(p%*2)
 3480 ENDPROC
 3490 DEFPROCRdBlocks(a%,b%,d%,n%):PROCTxBlocks(a%,b%,d%,n%,FALSE):ENDPROC
 3500 DEFPROCTxBlocks(addr%,block%,drive%,number%,write%):LOCALq%
 3510 err%=0:block%=block%ANDdmk%
 3520 FORq%=0TOnumber%-1:PROCfdcAct(2+(write%=0),addr%+q%*bsz%,block%+res%+q%,drive%,1,0):NEXT
 3530 ENDPROC
 3540 DEFPROCfdcInit(dskrec%,bps%,spt%,hds%,den%,trks%,sec0%)
 3550 LOCALi%:IFos%<>6:ENDPROC
 3560 dskrec%?0=bps%:dskrec%?1=spt%:dskrec%?2=hds%:dskrec%?3=den%:IFden%=1:dskrec%?2=1
 3570 FORi%=4TO59STEP4:dskrec%!i%=0:NEXT:dskrec%!60=&20000000:dskrec%!64=&20000000
 3580 dskrec%?8=sec0%:dskrec%!16=trks%*spt%*(2^bps%)*hds%
 3590 ENDPROC
 3600 DEFPROCfdcAct(op%,ad%,sc%,dv%,nm%,dn%)
 3610 IFop%=1:FORA%=0TObsz%-1STEP4:ad%!A%=0:NEXT:drv%=drv%AND-5:IFdrv%>7:err%=-1:ENDPROC
 3620 IFdrv$="":REPEAT:PROCfdcOp(op%):ad%=ad%+bsz%:sc%=sc%+1:nm%=nm%-1:UNTILnm%<1:ENDPROC
 3630 IFop%=2:dsk%=FNf_openup(drv$):IFdsk%=0:err%=-2:ENDPROC
 3640 IFop%=1:dsk%=FNf_openin(drv$):IFdsk%=0:err%=-2:ENDPROC
 3650 IFop%=1:IFsc%*bsz%>EXT#dsk%:CLOSE#dsk%:dsk%=0:err%=-3:PRINT"Disk error: Past end of image":ENDPROC
 3660 PROCf_gbpb(5-op%*2,dsk%,ad%,nm%*bsz%,sc%*bsz%):CLOSE#dsk%:dsk%=0
 3670 ENDPROC
 3680 DEFPROCfdcOp(op%)
 3690 IFos%>6:err%=-1
 3700 IFos%=6:SYS"XADFS_DiscOp",,op%+(diskrec%<<6),sc%*bsz%+((dv%AND3)<<29),ad%,bsz%TOerr%
 3710 IFos%<6:trk%=sc%DIV9:trk%=trk%DIV2+80*(trk%AND1):err%=FNscsi(ad%,6+op%*2,dv%OR4,trk%*16+sc%MOD9+1,1)
 3720 IFcsd%=0:ENDPROC
 3730 IFerr%:IFPOS:PRINT
 3740 IFerr%=-1:PRINT"Unsupported":ENDPROC
 3750 IFerr%:PRINT"Disk error &"FNh0(err%,2)" at ";dv%":"FNh0(sc%,6)
 3760 ENDPROC
 3770 DEFFNswap24(A%):zp%!0=A%:zp%!3=A%:=zp%!1AND&FFFFFF
 3780 DEFFNswap32(A%):zp%!0=A%:zp%!4=A%:=zp%!2
 3790 DEFFNs(A$):IFLEFT$(A$,1)=" ":REPEATA$=MID$(A$,2):UNTILLEFT$(A$,1)<>" "
 3800 IFRIGHT$(A$,1)=" ":REPEATA$=LEFT$(A$,LENA$-1):UNTILRIGHT$(A$,1)<>" "
 3810 =A$
 3820 DEFFNuc(A$):IFA$="":=""
 3830 FORA%=1TOLENA$:IFMID$(A$,A%,1)>"_":A$=LEFT$(A$,A%-1)+CHR$(ASCMID$(A$,A%,1)AND&5F)+MID$(A$,A%+1)
 3840 NEXT:=A$
 3850 DEFFNfx(A%,X%):LOCALY%:Y%=X%DIV256:=(USR&FFF4AND&FFFF00)DIV256
 3860 DEFFNfn_undos(A$):LOCALB%:IF(os%AND-32):=A$
 3870 FORA%=1TOLENA$:B%=INSTR(".#$^&@%~",MID$(A$,A%,1)):IFB%:A$=LEFT$(A$,A%-1)+MID$("/?<>+=;\",B%,1)+MID$(A$,A%+1)
 3880 NEXT:=A$
 3890 DEFFNyna(A%):IFA%=0:=0
 3900 PRINT"? (Y/N/A)";:REPEAT:A%=INSTR("YAN",CHR$(GETAND&DF)):UNTILA%
 3910 PRINTSTRING$(7,CHR$127);MID$("YesAllNo ",A%*3-2,3);:=A%-2
 3920 DEFFNh0(A%,N%):=RIGHT$("00000000"+STR$~A%,N%)
 3930 DEFFNd0(A%,N%):=RIGHT$("00000000"+STR$A%,N%)
 3940 DEFFNd(A%,N%):=RIGHT$("         "+STR$A%,N%)
 3950 DEFFNscsi(addr%,cmd%,drv%,sect%,num%):LOCALfs%
 3960 fs%=FNfs:IFfs%<>8:*FADFS
 3970 X%?0=0:X%!1=addr%:X%?5=cmd%:X%?6=drv%*32+((sect%AND&1F0000)DIV65536)
 3980 X%?7=((sect%AND&FF00)DIV256):X%?8=sect%:X%!9=num%:X%!11=0
 3990 A%=&72:CALL&FFF1:A%=?X%:IFfs%<>8:OSCLI"FX143,18,"+STR$fs%
 4000 =A%
 4010 DEFFNfs:IF(os%AND-32)=0:LOCALA%,Y%,E%:=(USR&FFDA)AND&FF
 4020 =29
 4030 DEFPROCf_gbpb(A%,chn%,addr%,num%,ptr%)
 4040 ?X%=chn%:X%!1=addr%:X%!5=num%:X%!9=ptr%:IFPAGE<&FFFFF:CALL&FFD1:ENDPROC
 4050 IFA%=1ORA%=3:PTR#?X%=X%!9
 4060 REPEAT:IFA%=1ORA%=2:BPUT#?X%,?X%!1ELSEIFA%=3ORA%=4:?X%!1=BGET#?X%
 4070 X%!1=X%!1+1:X%!5=X%!5-1:UNTIL(EOF#?X%ANDA%>2)ORX%!5<1:ENDPROC
 4080 DEFFNfile(A$,A%):IFA%-8:IFPAGE<&FFFFF:$name%=A$:?X%=name%:X%?1=name%DIV256:=(USR&FFDD)AND&FF
 4090 A$=FNf_name(A$):IFA%=255ORA%=5:X%!14=OPENIN(A$):IFX%!14:X%!10=EXT#X%!14:CLOSE#X%!14:X%!14=&33
 4100 IFA%=255:IFX%?6=0:OSCLI"LOAD """+A$+""" "+STR$~X%!2:=1
 4110 IFA%=5:IFX%!14:=1ELSEIFA%=5:=0
 4120 IFA%=0:OSCLI"SAVE """+A$+""" "+STR$~X%!10+" "+STR$~X%!14:X%!10=X%!14-X%!10:=1
 4130 IFA%=7:OSCLI"SAVE """+A$+""" "+STR$~PAGE+"+"+STR$~X%!10:X%!10=X%!14-X%!10:=1
 4140 IFA%-8:=0
 4150 IF(os%AND-24):A$="mkdir "+A$ELSEA$="cdir "+A$
 4160 IFHIMEM>&FFFF:LOCALERROR:ONERRORLOCAL:=0
 4170 OSCLIA$:=2
 4180 DEFFNf_openin(A$)=OPENIN(FNf_name(A$))
 4190 DEFFNf_openout(A$)=OPENOUT(FNf_name(A$))
 4200 DEFFNf_openup(A$)=OPENUP(FNf_name(A$))
 4210 DEFFNf_name(A$):IFos%AND-32:LOCALA%,B%:REPEATB%=A%:A%=INSTR(A$,"\",A%+1):UNTILA%=0:IFINSTR(A$,".",B%)=0:A$=A$+"."
 4220 =A$
 4230 DEFFNNetFS_Op(A%,A$)=FNNetFS_OpN(A%,0,7,A$)
 4240 DEFFNNetFS_OpN(A%,T%,O%,A$):LOCALN%:!X%=0:X%?1=O%+1+LENA$:X%!3=A%:X%?7=T%:$(X%+O%)=A$
 4250 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
 4260 IFHIMEM>&FFFF:IFA%>&FFFF:X%?3=?A%:SYS&2002B,A%+4TO$(X%+4):=X%?3
 4270 A%=&14:CALL&FFF1:=X%?3
 4280 DEFPROCDate_FromOrd(mem%,d%,m%,y%,hr%,mn%,sc%,cs%):y%=y%MOD400
 4290 d%=y%*365.25+m%*30+d%+VALMID$("120112234455",m%,1)+((y%MOD4)=0)-((y%-1)DIV100)-(m%>2AND((y%MOD4)=0AND(y%MOD100)<>0ORy%=0))+36493
 4300 IFd%>146066:d%=d%-146097
 4310 d%=d%*&41EB:mem%!1=d%+d%:d%=((hr%*60+mn%)*60+sc%)*100+cs%
 4320 ?mem%=d%:mem%!1=mem%!1+d%DIV256:ENDPROC
 4330 DEFPROCDate_ToOrd(mem%):LOCALA%,B%,C%,D%
 4340 year%=0:month%=0:day%=0:hour%=0:minute%=0:second%=0:centi%=0
 4350 IFmem%!1<0:ENDPROC
 4360 D%=mem%!1DIV&83D6+2447065:C%=mem%?0+256*(mem%!1MOD&83D6):centi%=C%MOD100
 4370 C%=C%DIV100:second%=C%MOD60:C%=C%DIV60:minute%=C%MOD60:hour%=C%DIV60
 4380 B%=((D%*4+3)MOD146097AND-4)+3:C%=B%MOD1461DIV4*5+2:D%=D%*4+3
 4390 A%=C%DIV153+2:day%=C%MOD153DIV5+1:month%=A%MOD12+1
 4400 year%=D%DIV146097*100+B%DIV1461+A%DIV12-4800
 4410 ENDPROC
 4420 DEFFNf_date(d%,m%,y%):y%=y%-1981:=d%+m%*256+(y%AND15)*4096+(y%DIV16)*32
 4430 DEFFNf_time(h%,m%,s%):=h%+m%*256+s%*65536