> CPMFiler 1.27 > 27-Nov-1998 v1.20 Selects DFS before Osword to reset FDC 0 04-Dec-1998 v1.21 Displays file attributes (, 27-Nov-1999 v1.22 Accesses disk images 2$ 28-Nov-1999 v1.23 FREE and MAP < v1.24 AmsDOS, Einstein F! v1.25 Uppercase, long files PD v1.26 Try generalising, need to commands to specify disk shape ZU 28-Apr-2007 v1.27 Physical disk access on RISC OS, TYPE handles LF/CR/LFCR/CRLF d: nQos%=fx(0,1)&FF:arc%=os%=6 >&8000:8:A%=:9,11:A%<80:&80:>&4000:&80 xos%<32:arc%:=fx(132,0) :init:"CPMFiler v"ver$" by J.G.Harston"': err: :X%=ctrl%:Y%=X%256 8drv$="":(D%+65);pmt$,type%,1); "[";drv$;"] "; ""A$:do(A$) 0 : !init:pmt$=">)]":ver$="1.27" Zcom$="DIR CAT STAT INFO TYPE DUMP DISS COPY FREE MAP USER BLOCKHELP QUIT FILE EXAM" qhelp$=":::: [CTRLS]: [RAW]:: ::::::::::" A ctrl% 32,name% 20,store% 256,data% &1000:X%=ctrl%:Y%=X%256 1OSWORD=&FFF1:D%=D%15(D%>-1):drv$="":user%=0 /fs%=fs:d$=".":s$="/":os%=32:d$="\":s$="." >DFS%=4:HADFS%=3:CPN%=2:CPM%=1:BBC%=-1:type%=CPM%:AmsDOS%=0 : !stp%=0: Directory entry size 6res%=0: Reserved area - (offset to directory)/256 "0dir%=0: (Offset to directory from res%)/256 ,, : Directory is at (res%+dir%)*256 6fs%:"FX143,18,"+fs% 2CloseAll:" "+Þ,<128 <>17):=-1 <>17 -CloseAll:in%=in%:in%:A%=in%:in%=0:#A% 'out%=out%:out%:A%=out%:out%=0:#A%  : do(A$):A$="?":A$="HELP" ( A$,1)=" ":A$=A$,2):A$,1)<>" "  A$,1)=";" A$="":  A$,1)="*" A$: ! A$,1)="." A$="CAT "+A$,2) M A$=2 A$,1)=":" uc(A$)>"@" uc(A$)<"Q":D%=uc(A$)-65:drv$="": 8com%=0::B$=com$,com%*5+1,5):B$=B$,A$+" "," ")-1) 1com%=com%+1:uc(A$,B$))=B$ com%*5>=com$ &'uc(A$,B$))<>B$ "Bad command": 0)z%=("FN_"+B$+"(MID$(A$,2+LENB$))"): :: D: N Commands X ======== b: lݤ_QUIT(A$):"Quit" v  *QUIT  : ݤ_HELP(A$):ptr%=1:com%=0: T" "com$,com%*5+1,5);:A$=help$,ptr%):A$=A$,A$,":")-1):ptr%=ptr%+A$:" "A$; /:ptr%=ptr%+1:com%=com%+1:com%*5>=com$:=0 : 'ݤ_FILE(A$):drv$=A$:D%=-1:bsz%=0:=0 ݤ_USER(A$):user%=A$:=0 ݤ_CPM(A$):type%=CPM%:=0 ݤ_CPN(A$):type%=CPN%:=0 : ݤ_CAT(A$):LstDir(0):=0 ݤ_DIR(A$):LstDir(1):=0  ݤ_INFO(A$):LstDir(2):=0 ݤ_STAT(A$):LstDir(3):=0  : *,ݤ_DUMP(A$): ln%,p%,ptr%,cols%:cols%=16 4 DUMP [COLS] >N IF LEFT$(A$,1)="-" cols%=VAL(MID$(A$,2)):A$=MID$(A$,INSTR(A$+" "," ")+1) HA$="":"?":= R4src$=A$:ptr%=find(src$):ptr%=0:"Not found":= \!ln%=len(ptr%):open:dump:=0 f: p dump:extent%=0:M%=bsz%-1: z P%=0 ln%-1 cols%:B$="" (h0(P%,6);" ";: Q%=P% P%+cols%-1 /(Q%M%)=0:ReadData(Q%bsz%,ptr%):O%=data% Kh0(?O%,2);" ";:A$=(?O%&7F): A$>=" " A$<="~" B$=B$+A$ B$=B$+"." O%=O%+1:: B$: cCPM%:ln%=bsz%*16:extent%=extent%+1:ptr%=find(src$+";"+extent%):ptr%:ln%=len(ptr%) ln%=0  ln%=0: : 2ݤ_TYPE(A$): ln%,p%,ptr%,last%:A$="":"?":= )msk%=A$," [")<>0:msk%=(msk%&80)&7F 4src$=A$:ptr%=find(src$):ptr%=0:"Not found":= 4ln%=len(ptr%):open:extent%=0:M%=bsz%-1:last%=0 ;P%=0ln%-1:(P%M%)=0:ReadData(P%bsz%,ptr%):O%=data% #Q%=?O%msk%:?O%=26:P%=ln%:Q%=0 2msk%=&FF:Q% Q%>31 Q%<>127:Q%:last%=Q% =msk%=&7F: Q%=10 Q%=13: last%<>23-Q%: 10,13:last%=Q% ,msk%=&7F: Q%=9:(8-( 8));:last%=Q% $O%=O%+1::: .=0 8: B)ݤ_DISS(A$): p%,ptr%: A$="" "?":= L0 start%=("&"+A$,p%+1)) start%=&100 V9src$=A$:ptr%=find(src$):ptr%=0:src$" not found":= `len%=len(ptr%):open jMA%=190:!X%=&50200C:X%!4=0: OSWORD: X%!4=0 "No Z80 DisAssem routine":= taddr%=&100:p%=0: ~((p%2047)<4:ReadData(p%2048,ptr%) 8addr%CPM%:"Not yet done.":=0 !ptr%=data%:size%=bmx%:used%=2   L?ptr%<128:p%=ptr%+16: used%=used%-(?p%<>0):p%=p%+1:?p%=0 p%>ptr%+31 )ptr%=ptr%+stp%:ptr%>=data%+dsz%*stp% free%=size%-used% (:h0(free%,4)" Blocks = "d(free%*bsz%,9)" bytes free" 2:h0(used%,4)" Blocks = "d(used%*bsz%,9)" bytes used" <=0 F: P/ݤ_MAP(A$):"FREE SPACE MAP ON "(D%+65)":" Z RdDir: d$type%<>CPM%:"Not yet done.":=0 nD p%=0 31:data%!(p%*32+8)=0:data%!(p%*32+12)=0::data%!8=&FFFF xptr%=data%: `?ptr%<128:p%=ptr%+16::q%=?p%:data%?(8+(q% 7)+32*(q% 8))=-1:p%=p%+1:?p%=0 p%>ptr%+31 -ptr%=ptr%+stp%:ptr%>=data%+dsz%*stp%:11 . q%=0 bmx%-1: (q% 31)=0:'h0(q%,2); 332: data%?(8+(q% 7)+32*(q% 8)):35 46 : =0 : ݤ_EXAM(A$)  RdDir: "Disk Information:" M"res= "d(res%,3)" stp="d(stp%, 4)" dir="d(dir%,3)" dsz="d(dsz%,3) M"exm= "d(exm%,3)" bsz="h0(bsz%,4)" bmx="d(bmx%,3)" alz="d(alz%,3) "skew="d(skew%,3)  ."Directory starts at &";~(res%+dir%)*256 '"Directory size: ";dsz%*stp% "7"Directory entries: ";dsz%;" of ";stp%;" bytes" ,#"Block size: &";~bsz% 6T"Disk size: ";bmx%*bsz%+res%*256;" (";(bmx%*bsz%+res%*256)1024;"K)" @=0 J: T9ݤ_BLOCK(A$):cols%=16:sect%=0:A$<>"":sect%=("&"+A$) ^bsz%=0:RdDir: h1ptr%=store%:store%!16=sect%:ln%=bsz%:dump:=0 r: |$ݤ_COPY(A$):src%,dst%,src$,dst$ A$=uc(A$,4))+A$,5) A$,4)="BBC:":src%=BBC% A$,4)="CPM:":src%=CPM% A$,4)="CPN:":src%=CPN% Msrc%=0:"Bad syntax - use BBC:filename, CPM:filename or CPN:filename":= 5A$=A$,5):p%=A$," "):src$=A$,p%-1):A$=A$,p%+1) A$=uc(A$,4))+A$,5) A$,4)="BBC:":dst%=BBC% A$,4)="CPM:":dst%=CPM% A$,4)="CPN:":dst%=CPN% =src%=dst% (src%<>BBC% dst%<>BBC%):"Bad transfer":= -dst$=A$,5):src%<>BBC%:FromCPM ToCPM =0 : :  File copying code & ================= 0: : FromCPM D/ src$<>"*" src$<>"*.*":FromCPMOneFile: N RdDir: X from%=0 dsz%-1 b&ptr%=data%+from%*stp%:A$="":A%=1: l0ptr%?A%<>32:A$=A$+(ptr%?A%):A%=A%+1 A%=9 vA%>8:A$=A$+".": 1ptr%?A%<>32:A$=A$+(ptr%?A%):A%=A%+1 A%=12 A%>11:src$=A$:dst$=A$ " A%=1 dst$:A$=dst$,A%,1) Xos%<>32:p%="#$%^&*~\|:.",A$):p%:dst$=dst$,A%-1)+"=dpu+stb!c/",p%,1)+dst$,A%+1) *:?ptr%<128:FromCPMOneFile:A%=RdDir : : FromCPMOneFile )"Copying CPM:";src$;" to BBC:";dst$; .ptr%=find(src$):ptr%=0:" - Not found": 2ln%=len(ptr%):open:"Save "+dst$+" 0+"+~ln%  ln%=0: 0out%=(dst$):out%=0:" - Can't open dest": "extent%=0:M%=bsz%-1:" **%";:  P%=0ln%-1 O(P%M%)=0:ReadData(P%bsz%,ptr%):O%=data%:8;8;8;d(100*P%ln%,2);"%";  #out%,?O%:O%=O%+1: *cCPM%:ln%=bsz%*16:extent%=extent%+1:ptr%=find(src$+";"+extent%):ptr%:ln%=len(ptr%) ln%=0 4 ln%=0 >##out%:out%=0:127;127;127: H: R1ToCPM:"Copying BBC:";src$;" to CPM:";dst$; \" - Can't save yet": f: p: z Object display routines  ======================= : % DIR/CAT - short list, all files 8 STAT/INFO [filename] - long list, one or all files  cflg% -> xxxx-FULL-CPM : )LstDir(cflg%):x%=0:A$="":RdDir: "":ptr%=find(A$):ptr%=0:"Not found": &(cflg%3)=2:"Filename... etc..." ޚ(cflg%3)=3:"D:FILENAME.EXT U LENGTH ""EX ",type%=CPM%)"RSA ""<- -- -- -- -- -- ALLOCATION -- -- -- -- -- ->",type%=CPM%);"Sect",type%=CPN%);8 9"|FX229,1"::type%=CPM%:PrCPM type%=CPN%:PrCPN . IFADVAL(-1):IFGET=27:OSCLI"FX229":*FX125 7ptr%=ptr%+stp%:ptr%>=data%+dsz%*stp% A$<>"":: "FX229": : :PrN(ptr%):p%=ptr% ptr%+10:?p%&7F:p%=ptr%+7:46 $:x%=x%+1: .: 8IPrCPN:?ptr%+ptr%?1=0 ?ptr%+ptr%?1=510: (cflg%1)=0:PrCPNb: Bx%=0:(65+D%)":"; L8PrN(ptr%+5):x%>4::x%=0: (cflg%2)=0:" : ";: VI" "h0(ptr%?4,1)" "d(len(ptr%),6)" "attr(ptr%+5)" "h0(!ptr%,4); `x%<2:4;: x%=0:: j: t PrCPNb ~ : 1PrCPM:?ptr%>127: (cflg%1)=0:PrCPMb: cflg%=1:(ptr%?12)exm%: x%=0:(65+D%)":"; 8PrN(ptr%+1):x%>4::x%=0: (cflg%2)=0:" : ";: d(?ptr%,3);d(len(ptr%),7);" "h0(ptr%?12,2)" "attr(ptr%);:p%=ptr%+16:" ";h0(!p%,2*alz%);:p%=p%+alz%:?p%=0 ?(p%+alz%-1)=0 p%>ptr%+31:p%>ptr%+31:8 :x%=0: : PrCPMb: bl%=0:p%=ptr%::l%=l%+1:?p%&7F:p%=p%+1:(?p%&7F)=32 p%=ptr%+7-2*((ptr%!9 &FFFFFF)=&4D4F43) K(ptr%!9 &FFFFFF)<>&4D4F43 47:p%=ptr%+9 ptr%+11:?p%&7F::l%=l%+4 (cflg%2):: (21-l%);: : Zݤattr(ptr%)="-R",1-(ptr%?9>127),1)+"-S",1-(ptr%?10>127),1)+"-A",1-(ptr%?11>127),1) : (: 2% Catalogue manipulation routines <% =============================== F: Pݤfind(A$): p%,ptr% Z-A$,2,1)=":":D%=(A$,1)15)-1:A$=A$,3) dptr%=data%:RdDir:=0 n9p%=A$+".","."):p%<9:A$=A$,p%-1)+9-p%," ")+A$,p%) x%A$=A$,8)+A$,10,3)+" ",11)+A$ Jp%=1 11:A$,p%,1)>"`":name%?p%=A$,p%,1)-32 name%?p%=A$,p%,1) :type%=CPN%:ptr%=ptr%+4 ;name%?12=0:p%=A$,";"):p%:name%?12=A$,p%+1)*(1+exm%) name%?0=user%:p%=0: (ptr%!0 &7F7F7F7F)=name%!0 (ptr%!4 &7F7F7F7F)=name%!4 (ptr%!8 &7F7F7F7F)=name%!8 ((ptr%?12 exm%)=name%?12 type%=CPN%):p%= p%:ptr%=ptr%+stp% 2ptr%>=data%+&A00 p%:type%=CPN%:ptr%=ptr%-4 np%:p%=0 31 4:store%!p%=ptr%!p%:: IFtype%=CPN% store%!16=!(ptr%-4):len%=(store%!18 AND&FFFF)*128+128 p%:=store% =0 : ? DEFFNlen(p%):IFtype%=CPM%:=p%?15*128-128*(p%?13<>0)+p%?13 `ݤlen(p%):type%=CPM%:=p%?15*128-128*(p%?13<>0)+p%?13+16384*(p%?12 exm%)-16384*(p%?15>127) -type%=CPN%:=(ptr%!2 &FFFF)*128+128 =0 : open:type%<>CPN%: link%=ptr%!0 &FFFF "- (link% &C0)=0: L3block sector number ,0 (link% &C0)=&80: L2 block sector number 6(ReadOneBlock(store%,cpn(link%),D%) @ J: T-ݤcpn(A%):A%=A%&3FFF:=(A%15)+10*(A%16) ^: h: r Disk access routines | ==================== : 6ݤRdDir:ptr%=data%:FDCrd(data%,0,D%,1):data%?8=13 Utype%=CPN%:AmsDOS%=0:stp%=16:res%=0:dir%=0:dsz%=256:exm%=1:bsz%=256:bmx%=0:alz%=1 skew%=1:flip%=0 r$data%="Acorn CP":type%=CPM%:stp%=32:res%=30:dir%=0:dsz%=128:exm%=1:bsz%=2048:bmx%=&C4:alz%=1:skew%=2:flip%=1 i$data%="HADFS"+0+" D":type%=HADFS%:stp%=24:res%=0:dir%=71:dsz%=32:bsz%=256:bmx%=1600:alz%=1:skew%=1 r!data%=&E5E5E5E5:type%=CPM%:AmsDOS%=:stp%=32:res%=36:dir%=0:dsz%=64:exm%=1:bsz%=1024:bmx%=&AB:alz%=1:skew%=1 x(!data% &F0FF)=&E000:type%=CPM%:AmsDOS%=:stp%=32:res%=40:dir%=0:dsz%=64:exm%=1:bsz%=2048:bmx%=&AB:alz%=2:skew%=1 r!data%=&0E008031:stp%=32:res%=&28:dir%=0:dsz%=128:exm%=1:bsz%=&800:bmx%=&C0:alz%=1:skew%=1:type%=CPM%:flip%=0 /ReadBlocks(data%,0,D%,(stp%*dsz%)/bsz%):=0 =0 : ReadData(q%,ptr%) & ptr%->file info block (cpm only) < q%=(PTR within file)DIVbsz% - ie block number to fetch  p%,r% &6type%=CPM%:ReadOneBlock(data%,ptr%?(q%+16),D%): 0 type%<>CPN%: :1ReadOneBlock(data%,cpn(store%!(q%*2)),D%): D Read from CPN: N{ptr%=!ptr% &FFFF:ptr%=(ptr%15)+10*(ptr%16):ptr%=ptr%+q%*8: p%=0 7:FDCrd(data%+p%*256,conv(ptr%+p%),drv%,1):: X\ptr%=!ptr% &FFFF:ptr%=ptr%+q%*8: p%=0 7:rd(data%+p%*256,conv(ptr%+p%),drv%,1):: b: l-ReadBlocks(addr%,block%,drive%,number%) v p%=0 number%-1 1ReadOneBlock(addr%+p%*bsz%,block%+p%,drive%) : : 'ReadOneBlock(addr%,block%,drive%) "type%=CPM%:ReadOneCPMBlock: "type%=CPN%:ReadOneCPNBlock:  : ReadOneCPNBlock: p% 2 Read a block of &100 bytes -> 1xSmallSectors G sectors go: 0:0:0-0:0:9, 1:0:0-1:0:9, 0:1:0-0:1:9, 1:1:0-1:1:9... Sector%=block% 10 Cylinder%=(block% 10) 2 Track%=block% 20 (sec%=Sector%+Track%*10+Cylinder%*800 , PRINT;Cylinder%;":";Track%;":";Sector% FDCrd(addr%,sec%,drive%,1) * 4: >ReadOneCPMBlock: p% HB Read a block of &800 bytes -> 4xBigSectors -> 8xSmallSectors R, p%=0 3: Do each chunk of &200 bytes \M AmsDOS%:FDCrd(addr%+p%*512,2*(block%*(bsz%512)+p%)+res%,drive%,2):: fsector512%=block%*4+p% psector256%=sector512%*2 z(Track%=(sector256% 10)+(res% 10) Sector%=sector256% 10 Sector%=Sector%*skew% Sector%=Sector% 10 Cylinder%=Track% 80 Track%=Track% 80 -flip%: (Cylinder% 1):Track%=79-Track% (sec%=Sector%+Track%*10+Cylinder%*800 , PRINT;Cylinder%;":";Track%;":";Sector% &FDCrd(addr%+p%*512,sec%,drive%,2)   : :  FDC routines  ============ : $%FDCrd(ad%,sc%,dv%,nm%):dv%>1: .8drv$<>"":in%=(drv$):in%=0:in%=(drv$+s$):in%=0: 8"":gbpb(3,in%,ad%,nm%*256,sc%*256):#in%:in%=0: Bos%<6:FDCbbc: Los%=6:FDCarc: Vos%=32:FDCdos: `"Unsupported": j: t FDCbbc:fs%<>4:*FX143,18,4 ~)A%=&7F:sc%>799:sc%=sc%-800:dv%=dv%+2 -try%=5::?X%=dv%:X%!1=ad%:X%?5=3:X%?6=&53 X%?8=sc%10:X%?7=sc%10 6X%!9=nm%32: OSWORD:try%=try%-1:X%?10=0 try%=0 ?X%?10:"Disk error &";~X%?10" at ";dv%":";sc%10"/";sc%10 fs%<>4:"FX143,18,"+fs%  : =FDCarc:trk%=sc%10:hd%=trk%80:trk%=trk%80:sec%=sc%10 Mș"XADFS_DiscOp",,1,((trk%*2+hd%)*10+sec%)*256+(dv%<<29),ad%,256*nm% r%  : FDCdos:"Unsupported": :  :  I/O routines  ============ (%ݤh0(A%,N%):="00000000"+~A%,N%) 2$ݤd(A%,N%):=" "+A%,N%) <ݤuc(A$):A$="":="" FEA%=1A$:A$,A%,1)>"_":A$=A$,A%-1)+(A$,A%,1)&5F)+A$,A%+1) P :=A$ Z6ݤfx(A%,X%): Y%:Y%=X%256:=(&FFF4 &FFFF00)256 d: n File routines x ============= .ݤfs:A%,X%,Y%:os%<32:=(&FFDA)&FF =29 :gbpb(A%,ch%,X%!1,X%!5,X%!9):?X%=ch%:os%<32:&FFD1: (A%1):#?X%=X%!9 @A%=1 A%=2:#?X%,?X%!1:X%!1=X%!1+1:X%!5=X%!5-1: X%!5<1: HA%=3 A%=4:?X%!1=#?X%:X%!1=X%!1+1:X%!5=X%!5-1: #?X% X%!5<1:  :