> CPMFiler 1.31a > 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 v1.27 28-Apr-2007 Physical disk access on RISC OS, TYPE handles LF/CR/LFCR/CRLF d; v1.28 12-Aug-2007 Slogger DDCPM image and disk access nV v1.29 28-Mar-2019 Copy from CPN gets correct name, gets length from EX correctly xL DUMP tidier final line, tidied COPY, added (C)onfirm # v1.29a 30-Mar-2019 Tidying up M v1.29b 01-Apr-2019 Added ReadSector so can use smaller directory buffer G Uses FNMount, changing FNRdDir to PROCRdDir(), new disk read code X v1.29c 02-Apr-2019 Rewrote DirLst, checks user, added USER *, testing other images X Now small enough to run on BBC again, tidied command list, uses common Syntax code W v1.30 20-Mar-2020 Rewritten file access code to match new disk access code, reads  multiple extents 9 v1.30b Examine Einstein disk to find alz%,bsh%,drm% T v1.30c Optimised search for directory, calculates geometry, Torch images fixed . v1.31 31-Mar-2020 Updated version number . v1.31a Added AcornCPMv2 hard disk images :  test%=TRUE*0 Kos%=fx(0,1)&FF:10,8:A%=:13:A%<50:&87:>&7C00:&83:>&4000:&80  <&FFFF:=fx(132,0) ( IF test%:MODE &80:HIMEM=PAGE+&6300 ":init:"CPMFiler v"ver$" by J.G.Harston"': err: ,:X%=ctrl%:Y%=X%256: : 6 8:wdt%=+1: @4 IF test%:DIMA%-1:PRINT"freemem=";HIMEM-A%;" "; JU drv$="":(D%+65);user%,user%>-1);pmt$; "["drv$;":"+user%,user%>-1)"] "; T ""A$:do(s(A$)) ^ h: r+init:pmt$=">":ver$="1.31a":max%=&0FFF |@ ctrl% 31,name% 19,store% 255,data% max%:X%=ctrl%:Y%=X%256 fs%:"FX143,18,"+fs% ECloseAll:A%=<>17 <>28:" at line "+Þ,<128 A%):=-1 A% 4CloseAll: in%=in%:IFin%:A%=in%:in%=0:CLOSE#A% 'out%=out%:out%:A%=out%:out%=0:#A% 'dsk%=dsk%:dsk%:A%=dsk%:dsk%=0:#A% & 0: :do(A$): A$="?":A$="HELP" D A$,1)=";" A$="": N A$,1)="*":A$,2): X! A$,1)=".":A$="CAT "+A$,2) b6A%=A$+" "," "):B$=uc(A$,A%-1)):A$=s(A$,A%+1)) l2 B$=2 B$,1)=":" B$<":":B$=(B$+17)+":" vE B$=2 B$,1)=":" B$>"@" B$<"Q":D%=B$-65:drv$="":bsz%=0: 0A%=cmd$,":"+B$+":"): A%=0:"Bad command": #A%=("FN_"+B$+"("""+A$+""")"): : 0ݤsyn(S$): A$="":"Syntax: "B$" "S$:= = :  Commands  ======== Q; _INFO, _COPY, _QUIT, _FREE, _MAP, _USER, _BLOCK : Prevent crunching C; _HELP, _TYPE, _DUMP, _DISS, _DIR, _STAT, _MOUNT, _SET : ݤ_QUIT(A$):"Quit"   os%>5:*QUIT   : ݤ_HELP(A$):p%=2:q%=2:  3A%=cmd$,":",p%): " "cmd$,p%,A%-p%);:p%=A%+1 *1A%=hlp$,":",q%): 8)hlp$,q%,A%-q%):q%=A%+1 4 p%>cmd$:=0 >: HNݤ_MOUNT(A$):bsz%=0: A$="":=0 A$=1:do(A$+":"):=0 D%=-1:drv$=A$:=0 R'ݤ_USER(A$):user%=A$ (A$<"0"):=0 \ݤ_DIR(A$):LstDir(1):=0 fݤ_STAT(A$):LstDir(3):=0 p DEFFN_SET(A$):A$=FNuc(A$) z IF A$="INT":seq%=FALSE:=0  IF A$="SEQ":seq%=TRUE:=0  =0 : (ݤ_BLOCK(A$): syn(""):= $sect%=("&"+uc(A$)): Mount:= ?ptr%=store%:!store%=sect%:store%!16=sect%:ln%=bsz%:dump:=0 : #ݤ_DUMP(A$): syn(""):=  look:=  dump:=0 : file0:ext%=0:M%=bsz%-1: =" " A$<="~" B$=B$+A$ B$=B$+"." V/O%=O%+1:: B$::B%=B%+ln%:file2: ln%<1: `: j#ݤ_TYPE(A$): syn(""):= t6msk%=A$," [")<>0:msk%=(msk%&80) &7F: look:= ~file0:last%=0 >: P%=0 ln%-1:file1:Q%=?O% msk%: ?O%=26:P%=ln%:Q%=0 5 msk%=&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::file2: ln%<1:=0 : #ݤ_DISS(A$): syn(""):= NA%=A$," "): A%:addr%=("&"+uc(A$,A%+1))):A$=s(A$,A%-1)) addr%=&100  look:= WA%=190:!X%=&502004:X%!4=0: &FFF1: $(X%+4),"Z80")=0:"No Z80 DisAssem routine":= Ifile0::P%=0::file1:!X%=&50200C:X%!4=addr%:X%!8=!O%:A%=190: &FFF1 K h0(addr%,4)" ";: Q%=0 X%?3-1: h0(O%?Q%,2)" ";:: (12-3*X%?3); E Q%=0 X%?3-1: c(O%?Q%):: (5-X%?3);$(X%+4): (X%?2 64):  )A%=O%-data%: A%+X%?3>M%:X%?3=M%-O%+1 Gaddr%=addr%+X%?3:O%=O%+X%?3:P%=P%+X%?3: P%>ln%-1:file2: ln%<1:=0 " Misses bytes at end of block (: 2ݤ_FREE(A$): Mount:= < CPN%:"Not yet done.":=0 F@map(0):used%=0: A%=0 dmx%:used%=used%-(tst(A%)<>0): A% Pfree%=dsize%bsz%-used%: Z:h0(free%,4)" Blocks = "d(free%*bsz%,9)" bytes free" d:h0(used%,4)" Blocks = "d(used%*bsz%,9)" bytes used" n=0 x: ݤ_MAP(A$): Mount:=  CPN%:"Not yet done.":=0 9map(4): A%=0 dmx%: (A% 31)=0:'h0(A%,2*alz%);  32: tst(A%): 35 46 : =0 :  This needs speeding up  map(A%) ."FREE SPACE"" MAP",A%)" ON "(D%+65)":"; % A%=0 255 4:store%!A%=0: A% 0 A%=0 (drm%+1)/(blm%+1)/4-1:set(A%): A% ( dmx% 8>255:'"Buffer overflow": / p%=0 drm%: (p% 15)=0:RdDir(p% 16) 1 q%=(p% 15)*32+16 (p% 15)*32+31 alz% ,A%=data%!q% &FFFF: alz%=1:A%=A% &FF " A%:set(A%) , q%: p%: 6>set(A%):store%?(A% 8)=store%?(A% 8) (2^(A% 7)): @-ݤtst(A%):=store%?(A% 8) (2^(A% 7)) J: T$ݤ_INFO(A$): A$<>"":=_STAT(A$) ^ Mount:= h"Disk Information:" rL"exm= "d(exm%,2)" stp="d(stp%,4)" drm="d(drm%,5)" alz="d(alz%,5) |L"bsh= "d(bsh%,2)" blm="d(blm%,4)" bsz="d(bsz%,5)" dmx="d(dmx%,5) "res= "d(res%,2)" spt="d(spt%*ltp%*(2^bps%)128,4)" hds="d(hds%,5)" tks=";d(hds%/ltp%*(dsize%/hds%/spt%/ssz%+0.9),5) U"den= "d(den%,2)" sec0="d(sec0%,3)" psec="d(ssz%/ltp%,4)" lsec="d(ssz%,4) X"skew="d(skew%,2)" flip="d(flip%,3)" trk= ""INTSEQ",(seq%1)*3+1,3)" "type$' 2"Directory starts at &"h0(res%*ssz%/ltp%,6) 8"Directory entries:"4;(drm%+1);" x ";stp%;" bytes" &"Directory size:"7;(drm%+1)*stp% @"Data area starts at &"h0(res%*ssz%/ltp%+(drm%+1)*stp%,6) #"Block size:"10"&"h0(bsz%,4) 0"Disk size:"12;dsize%" (";dsize%1024;"K)" =0 : Aݤ_COPY(A$): syn(" (onfirm)"):= 5A%=A$+" "," "):src$=A$,A%-1):dst$=s(A$,A%+1)) :cnf%=uc(dst$,2))=" C": cnf%:dst$=s(dst$,dst$-2)) B os%<6: dst$,"::")dst$,1)="-":"FS prefix unsupported":= < src$="*" src$="*.*":CopyDirectory CopyOneFile(1) &=0 0: :: D File copying code N ================= X: bCopyDirectory l Mount: v;dest$=dst$: dest$<>"":A%=file(dest$,8):dest$=dest$+d$ 6m%=(stp% 48)-1: p%=0 drm%:RdDir(p% (m%+1)) 5ptr%=data%+(p% m%)*stp%+(CPN% 4):A$="":A%=1: 1 ptr%?A%<>32:A$=A$+(ptr%?A%):A%=A%+1 A%=9 E A%>8:A$=A$+".":: ptr%?A%<>32:A$=A$+(ptr%?A%):A%=A%+1 A%=12 + A%>11: user%>=0: ?ptr%<>user%:A$="" & CPN%:ptr%=ptr%-4: !ptr%=0:A$="" ' CPN%=0: ptr%?12 ( exm%):A$=""  CPN%=0: ?ptr%>127:A$="" 9 A$<>"":src$=A$:dst$=dest$+fn_undos(A$):CopyObject  p%: : CopyObject = cnf%: "Copy "src$;:cnf%=yna(cnf%): cnf%>0:: 13 ptr%=info:CopyOneFile(0)   :  CopyOneFile(one%) ** dst$="":" filename missing": 4+ "Copying "src$;(12-src$)" to "dst$; >8 one%:ptr%=find(src$,0): ptr%=0:" - not found": HIln%=len(ptr%):open:"Save "+dst$+" "+~+"+"+~ln%+" 0 0": ln%=0: R1out%=(dst$): out%=0:" - can't open dest": \+file0:" **%";:: P%=0 ln%-1:file1 f4 (P% 1023)=0: 8;8;8;d(100*P%ln%,2);"%"; p'#out%,?O%:O%=O%+1::file2: ln%<1 z##out%:out%=0:127;127;127: : :  Object display routines  ======================= : LstDir(cflg%): Mount: Cptr%=0: A$<>"":ptr%=find(A$,0): ptr%=0:"'"A$"' not found":  (cflg%3)=3:"D:"; $ x%=1 (wdt% 32) (CPN%<>0) q (cflg%3)=3:"FILENAME.EXT U LENGTH RSA ";: CPN%=0:"EX <- -- -- -- -- -- ALLOCATION -- -- -- -- -- ->"; % (cflg%3)=3: CPN%:"Sect "; 3 x%:x%=0: 8: ptr%:PrInfo: : Single file Dm%=(stp% 48)-1: p%=0 drm%: (p% m%)=0:RdDir(p% (m%+1)) %ptr%=data%+(p% m%)*stp%:PrInfo  p%: :  $: . PrInfo 8 CPN%=0: ?ptr%>127: B0 CPN%: ?ptr%+ptr%?1=0 ?ptr%+ptr%?1=510: L' user%>=0: ptr%?(CPN%4)<>user%: V x%=0:(65+D%)":"; `:PrN(ptr%+(CPN%4)+1):x%=x%+1: x%>=wdt% 16:x%=0:: j (cflg% 2)=0:" : ";: t< d(ptr%?(CPN%4),3);d(len(ptr%),7)" "attr(ptr%)" "; ~ CPN%=0: h0(ptr%?12,2);:q%=ptr%+16: " "h0(!q%,2*alz%);:q%=q%+alz%: ?q%=0 ?(q%+alz%-1)=0 q%>ptr%+31: q%>ptr%+31: 8 . CPN%: h0(!ptr%,4);4;: x%127),1)+"-S",1-(ptr%?10>127),1)+"-A",1-(ptr%?11>127),1) : .ݤc(A%):A%=A%127:A%>31:A%<127:=A% =46 : : % Catalogue manipulation routines % =============================== : Dݤlook:src$=A$:ptr%=find(src$,0): ptr%:ln%=len(ptr%):open:= "'"src$"' not found":= : (ݤfind(A$,ext%): p%,ptr% 2. A$,2,1)=":":D%=(A$,1)15)-1:A$=A$,3) < Mount:=0 F:A%=A$+".","."): A%<9:A$=A$,A%-1)+9-A%," ")+A$,A%) P2A%=A$+".","."):A$=A$,8)+A$+" ",A%+1),11) ZC$name%=user%+A$: A%=1 11: name%?A%>95:name%?A%=name%?A%-32 dI A%:m%=(stp% 48)-1: p%=0 drm%: (p% m%)=0:RdDir(p% (m%+1)) n?ptr%=data%+(p% m%)*stp%+(CPN% 4): user%<0:?name%=?ptr% x (ptr%!0 &7F7F7F1F)=name%!0: (ptr%!4 &7F7F7F7F)=name%!4: (ptr%!8 &7F7F7F7F)=name%!8: CPN% (ptr%?12 ( exm%))=ext%:p%=drm%+1 ptr%=0 + p%: ptr%:ptr%=ptr%-(CPN% 4):=info =0 : ,ݤlen(p%): CPN%:=(p%!2 &FFFF)*128+128 8=16384*(p%?12 exm%)+128*p%?15+p%?13+128*(p%?13<>0) : 9ݤinfo: A%=0 31 4:store%!A%=ptr%!A%: A%:=store% : open: CPN%=0: link%=ptr%!0 &FFFF 0 (link% &C0)=&00: L3 block sector number 0 (link% &C0)=&80: L2 block sector number #ReadCPN(store%,cpn(link%),D%)  : -ݤcpn(A%):A%=A%&3FFF:=(A%15)+10*(A%16) ": ,M Read 512 bytes of directory, dir%=512-byte offset from start of block 0 6.RdDir(dir%):ReadBigSector(data%,dir%): @: J: T Disk access routines ^ ==================== h Internal disk errors are: r& -1 Unsupported on this hardware | -2 Disk/image not present  -3 Past end of image -4  -5 Not a recognised disk * -6 Can only do subset of disk types : ݤMount: bsz%:=0 dbsz%=0:drm%=2:res%=0:sec0%=0:spt%=10:den%=1:ssz%=256:hds%=1:skew%=1:flip%=0:ltp%=1:seq%=1:CPN%= ,dsz%=0:res%=dir:type$="": res%<0:=res% S res%=&00:type$="AmstradDOS":bsh%=3:exm%=0:dmx%=&0B3:bps%=9:sec0%=&C1:spt%=036 Z res%=&01:type$="HardDisk" :bsh%=5:exm%=1:dmx%=2046:bps%=8:sec0%=0:::spt%=256:drm%=8 Z res%=&12:type$="Spectrum+3":bsh%=3:exm%=0:dmx%=&0AE:bps%=9:sec0%=1:::spt%=036:hds%=2 S res%=&1A:type$="IBM" :bsh%=3:exm%=0:dmx%=&000:bps%=7:sec0%=1:::spt%=026 q res%=&1E:type$="AcornCPM" :bsh%=4:exm%=1:dmx%=0195:bps%=8:sec0%=0:::spt%=020:hds%=2:flip%=1:skew%=2:ltp%=2 S res%=&24:type$="AmstradSYS":bsh%=3:exm%=0:dmx%=&0AA:bps%=9:sec0%=&41:spt%=036 S res%=&28:type$="Einstein" :bsh%=3:exm%=1:dmx%=0189:bps%=9:sec0%=1:::spt%=040 k res%=&3C:type$="SloggerCPM":bsh%=5:exm%=3:dmx%=0195:bps%=9:sec0%=0:::spt%=040:hds%=2:flip%=1:skew%=-2 &Z CPN% :type$="TorchCPN" :bsh%=1:exm%=0:dmx%=1599:bps%=8:sec0%=0:::spt%=020:hds%=2 0: :- Additional checks for hard drive images Dc res%=0: dsz%>&FFFFF:type$="AcornCPMv2":bsh%=5:exm%=1:dmx%=512:bps%=8:sec0%=0:spt%=256:drm%=4 N: X; type$="":pr(0):"Unrecognised disk &"h0(res%,2):=-5 bF bps%<8 bps%>9:"Can only do 256-byte and 512-byte sectors":=-6 l: vC dmx%<256:alz%=1 alz%=2 : Allocation size d res%=&28:fdcRd(data%,D%,-&28,1):alz%=2-((data%?1 2) 2):bsh%=2+alz%:drm%=3-alz%: Einstein Bblm%=2^bsh%-1 : Block mask Bbsz%=2^(7+bsh%) : Block size Edrm%=bsz%*drm%/32-1 : Directory max Cssz%=2^bps%*ltp% : Sector size Xspt%=(spt%*128) (2^bps%) ltp% : Convert to logical sectors per track H CPN%:stp%=16 stp%=32 : Directory entry size @ bps%<9:den%=1 den%=2 : Disk density J CPN%:drm%=159:seq%=1:fdcRd(data%,D%,18,1): !data%=&D9D8D7D6:seq%=0 Sres%=res%*256/(ssz%/ltp%) : Convert to physical sectors Adsize%=(dmx%+1)*bsz%+res%*ssz%/ltp% : Disk size =0 :  Search for a directory 0ݤdir:fdcRd(data%,D%,0,1): err%:=err%-256 Adata%!16=0: chk(data%+4):CPN%=:=0 : Specific Torch test Cdata%?8=13: uc($data%)="ACORN CP":=&1E : Quick initial test *C uc($data%)="SLOGGER ":=&3C : Quick initial test 4 ptr%=-1: >>ptr%=ptr%+1:fdcRd(data%,D%,ptr%,1) : Try this density H` err%:den%=3-den%:bps%=bps%1:ssz%=ssz%&300:fdcRd(data%,D%,ptr%,1): Try swapping density RIfnd%=chk(data%) : Is there a directory here \/ fnd% ptr%>&FE: err%:=err%-256 =ptr% f: p$ Check possible directory entry zDݤchk(p%): p%?0>&22:= : User number must be &0x, &1x, &20-&22  p%!12 &E080E0:= < IF p%?12>31 :fnd%=FALSE :REM ExtentLo must be 0-31 7 IF p%?13>127:fnd%=FALSE :REM LC must be 0-127 < IF p%?14>31 :fnd%=FALSE :REM ExtentHi must be 0-31 2 p%?15>128:= : RC must be 0-128 FA%=1::fnd%=""":=?*,.",c(p%?A%)):A%=A%+1: A%=12 fnd%:=fnd%=0 : & ptr%->file info block (cpm only) > q%=(PTR within file) DIV bsz% - ie block offset to fetch ReadData(q%,ptr%) 3 CPN%:ReadCPN(data%,cpn(store%!(q%*2)),D%): . alz%=1:ReadCPM(data%,ptr%?(q%+16),D%): /ReadCPM(data%,ptr%!(q%*2+16) &FFFF,D%): : 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... $"ReadCPN(addr%,block%,drive%) .Z seq% :Sc%=block% 10:Hd%=(block% 10) 2:Tk%=block% 20:sec%=Sc%+Tk%*10+Hd%*800 8Y seq%=0:Sc%=block% 10:Hd%=(block% 10) 2:Tk%=block% 20:sec%=Sc%+Tk%*40+Hd%*20 BfdcRd(addr%,drive%,sec%,1) L V: `C Read a block of &0800 bytes -> 4xBigSectors -> 8xSmallSectors j@ Read a block of &1000 bytes -> 8xBigSectors -> 8xDDSectors t@ReadCPM(addr%,block%,drive%): Do each chunk of &200 bytes ~O S%=0 (bsz% 512)-1:ReadBigSector(addr%+S%*512,block%*(bsz% 512)+S%) : :  ReadBigSector(ad%,sec512%) .fdcRd(ad%,D%,sec512%*(512/ssz%),512/ssz%)  : :  FDC routines  ============ : !fdcRd(addr%,drv%,sec%,num%) ]err%=0:sec%=sec%+res%/ltp%::fdcRdOne:addr%=addr%+ssz%:sec%=sec%+1:num%=num%-1:num%<1: fdcRdOne:s0%=sec%  G addr%>data%+max%+1 addr%+ssz%>data%+max%+2:"Buffer overflow": . A%=0 ssz%-1 4:addr%!A%=0::drv%>7: JTk%=sec% spt%:Sc%=sec% spt%: flip%: Tk%>79:Tk%=239-Tk%: 159-Tk% (I seq%=0: hds%>1:Hd%=Tk% 1:Tk%=Tk% 2 Hd%=Tk% 80:Tk%=Tk% 80 2" skew%>1:Sc%=Sc%*skew% spt% <= skew%<0:Sc%=(Sc%*-skew% spt%)-(Sc%>4): Slogger botch Fsec%=(Hd%*80+Tk%)*spt%+Sc% Ph PRINT FNh0(s0%,4)" H:";Hd%;" T:";Tk%;" S:";Sc%;" D:";den%;" -> ";~sec%;" -> ";~sec%*ssz%:REM IFGET Zdrv$="":fdcOp(1): dFdsk%=f_openin(drv$):dsk%=0:err%=-2:pr(27):"image not found";: nWdsz%=#dsk%:sec%*ssz%>dsz%:#dsk%:dsk%=0:err%=-3:pr(33):"past end of image"4;: x6f_gbpb(3,dsk%,addr%,ssz%,sec%*ssz%):#dsk%:dsk%=0  : pr(A%):<>A%: 13;"Disk error: ";: : fdcOp(op%):err%=-1  os%=6:err%=fdcArc  os%<6:err%=fdcBBC  bsz%=0:  err%=FNfdcErr(err%)  err%: :  err%=-1:"Unsupported": > err%:"Disk error &"h0(err%,2)" at ";drv%":"h0(sec%,6)  :  DEFFNfdcErr(err%) " IF err%:IF POS:PRINT ,a IF err%=-1:P."Unsupported" ELSE IF err%:PRINT"Disk error &"FNh0(err%,2)" at ";drv%":";~sec% 6 =err% @: J;fdcInit(dskrec%,bps%,spt%,hds%,den%,trks%,sec0%): i% TDdskrec%?0=bps%:dskrec%?1=spt%*ltp%:dskrec%?2=hds%:dskrec%?3=den% ^7 i%=4 59 4:dskrec%!i%=0::dskrec%!64=&20000000 h ";~offset%:IFGET Oș"XADFS_DiscOp",,op%+64+(diskrec%<<6),offset%+(drv%<<29),addr%,ssz% err%  =err% :  ݤfdcBBC  P."sec=";sec% h P."hd:";drv%+2*(sec%DIV(40*spt%*ltp%));" trk:";(sec%DIVspt%)MOD80;" sec:";sec0%+(sec%MODspt%)*ltp% qden%=1:op%=1:=disk(addr%,&53,drv%+2*(sec%(40*spt%*ltp%)),(sec%spt%)80,sec0%+(sec%spt%)*ltp%,ltp%,den%)  IFden%=1:IFop%=1:sec%=sec%*ltp%:=FNdisk(addr%,&53,drv%+2*(sec%DIV(80*spt%*ltp%)),(sec%DIV(spt%*ltp%))MOD80,sec0%+sec%MOD(spt%*ltp%),ltp%,den%) `den%>1:op%=1:=scsi(addr%,&08,drv%,sec0%+sec%,1): Needs fiddling for non-256-byte sectors =-1 &: 0: :- Translate leafname if not saving to DOS D- ======================================= N, . # $ ^ & @ % ~ become / ? < > + = ; \ X%ݤfn_undos(A$):B%:(os%-32):=A$ bUA%=1 A$:B%=".#$^&@%~",A$,A%,1)):B%:A$=A$,A%-1)+"/?<>+=;\",B%,1)+A$,A%+1) l :=A$ v: ݤyna(A%):A%=0:=0 +"? (Y/N/A)";::A%="YAN",(&DF)):A% +7,127);"YesAllNo ",A%*3-2,3);:=A%-2 :