10
20
30
40
50
60
70
80
90
100 :
110 DIMctrl%127,name%79,zp%9:A$=FNOS_GetEnv+" ":IFos%=32:PROCWin_TextIO
120 quit$=FNcl(" -qu",1):debug%=FNcl("-de",0):ON ERROR REPORT:PRINT:PROCexit(ERR)
130 IFFNcl("-help",0):PRINT"UnImg v1.12 (C)J.G.Harston 2017";:A$="-?":PRINT" Single disk only"
140 IFFNcl("-?",0):PRINT"Syntax: UnImg infile -d outdir -fs type -dsd -s -e -i -X -q -quit command":PROCexit(0)
150 dsd%=FNcl("-ds",0):dst$=FNcl("-d",1):type$=FNcl("-f",1):sub%=FNcl("-s",0):ext%=FNcl("-e",0)
160 vb%=NOTFNcl("-q",0):inf%=FNcl("-i",0):full%=FNcl("-X",0)
170 in$=FNcl("",0):drv$=FNcl("",0)
180 d$=".":s$="/":IFos%AND-24:d$="/":s$=".":IFos%AND-32:d$="\"
190 :
200 ON ERROR REPORT:PRINTLEFT$(" at line "+STR$ERL,ERR<128 AND ERR<>17):PROCClose_All:PROCexit(ERR)
210 X%=ctrl%:Y%=X%DIV256:fln%=11:fmx%=-1:IF(os%AND-24):fln%=256
220 DIMA%-1:max%=HIMEM-A%-2048+4096*(HIMEM>&FFFF):DIM mem% max%:wr%=2:rd%=4
230 IFin$="":INPUT"File to extract from: "in$:INPUT"Image type:"SPC11type$:IFdst$="":INPUT"Destination path:"SPC5dst$
240 in%=FNf_openin(in$):IFin%=0:PRINT"File '"in$"' not found":PROCexit(214)
250 IFtype$="":fstype%=FNchkdisk ELSE fstype%=INSTR("HADFS",FNuc(type$))
260 IFfstype%=0:CLOSE#in%:in%=0:PRINT"Unrecognised disk image":PROCexit(225)
270 IFfstype%<2:tsz%=10:dsz%=&300:root%=&47:
280 IFfstype%=2:tsz%=16:dsz%=&500:root%=&02:
290 IFfstype%>2:tsz%=10:dsz%=&200:root%=&00:
300 DIM dir% dsz%-1
310 :
320 IFdebug%:PRINT" run$='"run$"'"'"quit$='"quit$"'"'" in$='"in$"'"'" dst$='"dst$"'"'" drv$='"drv$"'"
330 IFdebug%:PRINT" dsd=";dsd%;" verbose=";vb%;" inf%=";inf%;" full%=";full%
340 IFdebug%:PRINT" fstype%=";fstype%
350 IFdebug%:PRINT" tsz=";tsz%;" dsz=";dsz%;" root=&";~root%
360 :
370 PROCsavedir(root%,dst$):CLOSE#in%:in%=0:PROCexit(0):END
380 :
390 DEFFNchkdisk
400 PROCf_gbpb(rd%-1,in%,mem%,4,&201):IF!mem%=&6F677548:=2:
410 PROCf_gbpb(rd%-1,in%,mem%,8,&4610):IF!mem%=&29432800:=1:
420 =3:
430 :
440 DEFPROCmkdir:IFdst$<>"":PROCf_cdir(dst$):dst$=dst$+d$
450 ENDPROC
460 :
470 DEFPROCsavedir(csd%,dst$)
480 LOCAL num%,r0%,f%:PROCmkdir:REPEAT:PROCRdDir(csd%)
490 IFnum%:f%=fn0%:REPEAT:num%=num%-FNsaveobject(f%):f%=f%+fsz%:UNTIL num%<1
500 csd%=0:IFfstype%<2:csd%=dir%!14 AND &FFFF:IF(dir%?12)>127:csd%=dir%!23 AND &FFFFFF
510 UNTIL csd%=0:ENDPROC
520 :
530 DEFFNsaveobject(fptr%)
540 LOCAL fn$,lf$,ld%,ex%,nm%
550 N%=0:REPEAT:A%=dir%?(fptr%+N%)AND127:IFA%>32:lf$=lf$+CHR$A%
560 N%=N%+1:UNTIL N%=10 OR A%<33
570 IFlf$="":IFfstype%<2:=0
580 IFlf$="":=num%
590 IFfstype%>2:lf$=CHR$(dir%?(fptr%+7)AND127)+"/"+LEFT$(lf$,7):IF(ASClf$AND-5)=32:lf$=MID$(lf$,3)
600 A%=(fstype%>2)AND(MID$(lf$,2,1)="/")
610 IFA%:IFsub%:lf$=LEFT$(lf$,1)+"."+MID$(lf$,3)
620 IFA%:IFext%:lf$=MID$(lf$,3)+"/"+LEFT$(lf$,1)
630 PROCgetattrs:fn$=FNf_name(FNfn_unbbc(lf$))
640 IFvb%:PRINTlf$SPC(11-LENlf$)FNh0(ld%,8)" "FNh0(ex%,8)" "FNh0(nm%,6):
650 IFattr%AND256:PROCsavedir(sec%,dst$+fn$):PROCRdDir(csd%) ELSE PROCsavefile
660 PROCsetattrs:=1
670 :
680 DEFPROCsavefile
690 A%=INSTR(fn$,d$):IFA%:PROCf_cdir(dst$+LEFT$(fn$,A%-1))
700 X%!2=ld%:X%!6=ex%:X%!10=0:X%!14=nm%:A%=FNfile(dst$+fn$,7):len%=nm%
710 out%=OPENOUT(dst$+fn$):REPEAT:cnt%=len%:IFlen%>max%:cnt%=max%AND-256
720 PROCRdData(mem%,sec%,(cnt%+255)DIV256):PROCf_gbpb(wr%,out%,mem%,cnt%,0)
730 sec%=sec%+(cnt%+255)DIV256:len%=len%-cnt%:UNTIL len%<1:CLOSE#out%:out%=0
740 ENDPROC
750 :
760 DEFPROCgetattrs
770 cdate%=0:mdate%=0:mtime%=0:usr%=0:IFfstype%>2:PROCdfsattrs:ENDPROC
780 ld%=dir%!(fptr%+10):ex%=dir%!(fptr%+14):nm%=dir%!(fptr%+18)
790 sec%=dir%!(fptr%+22)AND&FFFFFF:attr%=FNattr(fptr%)
800 IFfstype%=2:attr%=(attr%AND3)+(attr%AND4)*2+(attr%AND8)*32+(attr%AND&1E0)DIV2:ENDPROC
810 attr%=attr%EOR&33:usr%=dir%?19 OR (dir%?18DIV16) OR (dir%!20 AND &FFFF0000)
820 mdate%=dir%!(fptr%+26):mtime%=dir%!(fptr%+28):cdate%=dir%!(fptr%+30)
830 IFdir%?12>127:ENDPROC:
840 nm%=nm%AND&7FFFF :
850 sec%=sec%AND&FFFF :
860 mdate%=dir%!(fptr%+20)AND&FFF8
870 mdate%=mdate%OR((dir%?(fptr%+9)AND&80)DIV128)
880 mdate%=mdate%OR((dir%?(fptr%+13)AND&C0)DIV32)
890 cdate%=mdate%:ld%=(ld%AND&3FFFFFFF):IF(ld%AND&20000000):ld%=ld%OR&C0000000
900 ENDPROC
910 :
920 DEFPROCdfsattrs
930 ld%=dir%!(fptr%+256)AND&FFFF:ex%=dir%!(fptr%+258)AND&FFFF
940 nm%=dir%!(fptr%+260)AND&FFFF:sec%=dir%?(fptr%+263)
950 A%=dir%!(fptr%+261)AND&FF00
960 ld%=ld%OR((A%AND&0C00)*64):IFld%>&2FFFF:ld%=ld%OR&FFFF0000
970 ex%=ex%OR((A%AND&C000)*4):IFex%>&2FFFF:ex%=ex%OR&FFFF0000
980 nm%=nm%OR((A%AND&3000)*16):sec%=sec%OR(A%AND&0300)
990 attr%=&33:IFdir%?(fptr%+7)>127:attr%=&19
1000 ENDPROC
1010 :
1020 DEFPROCsetattrs
1030 X%!2=ld%:X%!6=ex%:X%!14=attr%AND&7F:X%!15=mdate%:A%=FNfile(dst$+fn$,1)
1040 IFinf%=0:IF(os%AND-24)=0:ENDPROC
1050 inf$=FNfn_unbbc(lf$)+s$+"inf":IF(os%AND-24)=0:inf$=LEFT$(LEFT$(lf$,8)+s$+"inf",10)
1060 inf$=dst$+inf$:IF(os%AND-24)=0:IFASCinf$=45:inf$="@."+inf$
1070 IFfstype%>2:IFASCMID$(lf$,2,1)=47:lf$=LEFT$(lf$,1)+"."+MID$(lf$,3)
1080 A$=lf$+" ":IFLENA$<11:A$=A$+STRING$(10-LENlf$," ")
1090 A$=A$+FNh0(ld%,8)+" "+FNh0(ex%,8)+" "+FNh0(nm%,6)+" "+FNh0(attr%,2)
1100 IF full%:IF fstype%<2:A$=A$+" "+FNh0(mdate%,4):IF dir%?12>127:A$=A$+" "+FNh0(mtime%,6)+" "+FNh0(cdate%,4)+" "+FNh0(cdate%,6)+" "+FNh0(acc%,4)+" "+FNh0(aux%,4)
1110 A$=A$+CHR$13+CHR$10:out%=FNf_openout(inf$):FOR A%=1 TO LEN A$:BPUT#out%,ASCMID$(A$,A%,1):NEXT:CLOSE#out%:out%=0
1120 A%=FNfile(inf$,5):X%!3=X%!3 OR &FFFFFF:A%=FNfile(inf$,2)
1130 ENDPROC
1140 :
1150 DEFFNattr(f%):LOCAL a%,n%:FOR n%=0 TO 7:a%=a%DIV2+(dir%?(f%+n%)AND&80):NEXT:=a%OR((dir%?(f%+8)*2)AND&100)
1160 :
1170 DEFPROCRdDir(sect%)
1180 PROCRdData(dir%,sect%,dsz%DIV256)
1190 IFfstype%>2:fn0%=8:fsz%=8:num%=(dir%?&105)DIV8:ENDPROC
1200 IFfstype%=2:fn0%=5:fsz%=26:num%=47:ENDPROC
1210 IFfstype%<2:fn0%=24:fsz%=24:num%=(dir%?12)AND31:IFdir%?12>127:fn0%=32:fsz%=32
1220 ENDPROC
1230 :
1240 DEFPROCRdData(ad%,sc%,nm%):LOCAL n%
1250 FOR n%=0 TO nm%-1:PROCrd(ad%+256*n%,sc%+n%):NEXT:ENDPROC
1260 :
1270 DEFPROCrd(ad%,sc%):LOCAL t%,s%,h%
1280 IFdsd%:t%=sc%DIVtsz%:s%=sc%MODtsz%:h%=t%DIV80:t%=t%MOD80:sc%=s%+h%*tsz%+t%*tsz%*2
1290 PROCf_gbpb(rd%-1,in%,ad%,256,sc%*256)
1300 ENDPROC
1310 :