> TubeHost  Serial Tube Host System 4 v0.26 - Added client/host filename conversion (& v0.27 - Configurable .inf usage 2( v0.27a - "" is a wildcard filename <4 v0.27b - host_LOAD, host_SAVE convert filename FX v0.28 - reads file header, correct filename for *command, */command, *RENAME done PP v0.29 - *RUN looks for file.bin, data transfer in blocks, implemented *EX Z v0.29a - COM configurable d= v0.29b - Uses KBD translation, RDCH sends Escape change nJ v0.29c - hnd% used for handles that don't need to be closed on error x: ! Note, os% test differences:  os%=6 - RISC OS 6 os%=%000x0xxx - Any dir.file/ext filing system & os%=8 - Unix/Linux/etc 6 os%=%000x1xxx - Any dir/file.ext filing system - os%=32 - BBC BASIC for Windows 6 os%>31 - Any dir\file.ext filing system : &A%=0:X%=1:os%=((&FFF4)&FF00)256 "_BAUD$="19200" : Default baud #_DEBUG$="0" : Default debug +_PFX$="&9B" : Default escape prefix )_COM$="1" : Default serial port 4_RST$="0" : Send reset sequence on startup ._MTU$="32" : Maximum transaction size $_INF$="1" : Use .inf files ": ,v ctrl0% 131,string% 255,escflg% 0:ctrl%=ctrl0%+2:ch%=0:in%=0:out%=0:ser%=0:serout%=0:serin%=0:fn$="":ver$="0.29c" 6Hclient%=0:host%=2*((os%>31)32)+4*(os%8): :close::exit():Ș @GChoices_Init("J.G.Harston","TubeHost"):baud%=_BAUD$:dbg%=_DEBUG$ JQPFX%=_PFX$:INF%=_INF$:inf%=INF%:max%=_MTU$*1024: max%<1024:max%=&7FFFFFFF TJ"Tube Host v";ver$;" at ";baud%;", MTU=";max%:tmp$="." ^Kf_init:os%=32:ș "SetWindowText",@hwnd%,"Tube Host v"+ver$:tmp$=@tmp$ h1 report:_ERROR:close: err:exit():Ș rEquit%=:open:"Couldn't open serial port":A%=(100):exit(-1): |'_RST$:_RESET:_RST$="0":SerFlush , REPEAT:PRINTFNc(FNRdByte);:UNTIL quit% : RdByte: quit% close:exit(0) Ș : :  ݤopen mos%=32:serin%=("COM"+_COM$+": baud="+baud%+" parity=N data=8 stop=1 octs=on"):serout%=serin%:=serin%=0 0A%=baud%:A%>63:A%=(A%75)/2:A%<4:A%=A%+1 ""FX7,"+A%:"FX8,"+A%:*FX2,2 Gos%=6:serin%="Serial:":serout%="Serial:":=(serin%=0)(serout%=0) =0 :  close ch% :A%=ch% :ch%=0 :#A% in% :A%=in% :in%=0 :#A% &out%:A%=out%:out%=0:#A% 0serout%=serin%:serout%=0 :(serout%:A%=serout%:serout%=0:#A%: D(serin% :A%=serin% :serin%=0 :#A%: N*FX2 X b: l ݤerr v(=-1 (<128 <>17 <>28 -1) : report:dbg%=0: os%=32:*OUTPUT 0 -:" at line "+Þ,<128 <>17 <>28)  : exit(A%) ) os%=32:Ș A% "FX1,"+(A%255):Ș  : #ݤd0(A%,N%)="00000000"+A%,N%) #ݤh0(A%,N%)="0000000"+~A%,N%) 1ݤc(A%):A%=A%127:A%<32 A%=127:="." =A% :  :  Inward   x VDU x *! esc,esc VDU esc 4= esc,n MOS function, control block follows > H: R: \ OS_RDCH f ======= p" Tube data &00 -- Carry Char z0ݤ_0 :dbg%2:"OS_RDCH "; &EscOff:os%=32:A%=kbd_GET A%= 1EscOn:A%=27:WrCmd(&81): Send EscapeChange 7WrByte((A%=27)&80) :dbg%2:"-- "h0(&00,2)" "; .WrByte(A%) :dbg%2:h0(A%,2) =0 : :  OS_CLI  ====== - Tube data &02 string &0D -- &7F or &80 ,ݤ_2 :dbg%:"OS_CLI "; -RdString :dbg%:$string%" "; Y%=string%:A%=mos_cli . A%>=0:WrByte(A%) :dbg%:"-- "h0(A%,2) =0 : $: . SHORT_BYTE 8 ========== B Tube data &04 X A -- X L%ݤ_4 :dbg%:"OS_BYTE "; V)X%=RdByte :dbg%:h0(X%,2)" "; `)A%=RdByte :dbg%:h0(A%,2)" "; jA%=mos_byte t> A%>&7B: A%<&7F:WrCmd(&80-(A%=125)): Send EscapeChange ~(WrByte(X%) :dbg%:"-- "h0(X%,2) =0 :  LONG_BYTE  ========= $ Tube data &06 X Y A -- Cy Y X %ݤ_6 :dbg%:"OS_BYTE "; )X%=RdByte :dbg%:h0(X%,2)" "; )Y%=RdByte :dbg%:h0(Y%,2)" "; )A%=RdByte :dbg%:h0(A%,2)" "; A%=mos_byte 4 A%<0:=0 : Reply already sent, eg *FX142 4 A%=&81: X%=27:WrCmd(&81): Send EscapeChange 5WrByte((A%&100)2) :dbg%:"-- "h0(A%2,2)" ";  2WrByte(Y%) :dbg%:h0(Y%,2)" "; .WrByte(X%) :dbg%:h0(X%,2) =0 (: 2: < OS_WORD F ======= P4 Tube data &08 A in_len block out_len -- block Z*ݤ_8 :dbg%:"OS_WORD "; d.A%=RdByte :dbg%:h0(A%,2)" "; n2inlen%=RdByte :dbg%:h0(inlen%,2)" "; xHRdBlock(inlen%) :dbg%:inlen%:D%=0inlen%-1:h0(ctrl%?D%,2);: 3outlen%=RdByte :dbg%:h0(outlen%,2)" "; #X%=ctrl%:Y%=X%256:A%=mos_word RWrBlock(outlen%) :dbg%:"-- ";:outlen%:D%=0outlen%-1:h0(ctrl%?D%,2);: ": :dbg%: =0 : :  OS_RDLINE  ========= 3 Tube data &0A block -- &FF or &7F string &0D ,ݤ_A :dbg%2:"OS_RDLN "; fRdBlock(5) :dbg%2:h0(ctrl%!0,4)" "h0(ctrl%?2,2)" "h0(ctrl%?3,2)" "h0(ctrl%?4,2)" "; )X%=ctrl%:Y%=string%:A%=0:A%=mos_word 0(A%&100) :dbg%2:"-- "h0(&80,2) (A%&100):WrByte(&80):=0 4WrByte(&7F) :dbg%2:"-- "h0(&7F,2)" "; ")WrString :dbg%2:$string% ,=0 6: @: J OS_ARGS T ======= ^: Tube data &0C handle block function -- result block h*ݤ_C :dbg%:"OS_ARGS "; r.X%=ctrl%:Y%=RdByte :dbg%:h0(Y%,2)" "; |.RdBlock(4) :dbg%:h0(!X%,8);" "; .A%=RdByte :dbg%:h0(A%,2)" "; Y%=Y%&7F:A%=mos_args 1WrByte(A%) :dbg%:"-- "h0(A%,2)" "; )WrBlock(4) :dbg%:h0(!X%,8) =0 : :  OS_BGET  ======= ) Tube data &0E handle -- Carry byte ,ݤ_E :dbg%1:"OS_BGET "; 0Y%=RdByte :dbg%1:h0(Y%,2)" "; Y%=Y%&7F:A%=mos_bget =WrByte((A%&100)2):dbg%1:"-- "h0((A%&100)2,2)" "; *WrByte(A%) :dbg%1:h0(A%,2) =0 &: 0: : OS_BPUT D ======= N' Tube data &10 handle byte -- &7F X,ݤ_10 :dbg%1:"OS_BPUT "; b0Y%=RdByte :dbg%1:h0(Y%,2)" "; l0A%=RdByte :dbg%1:h0(A%,2)" "; vY%=Y%&7F:A%=mos_bput 0WrByte(&7F) :dbg%1:"-- "h0(&7F,2) =0 : :  OS_FIND  ======= 2 Tube data &12 function string &0D -- handle & &12 &00 handle -- &7F *ݤ_12 :dbg%:"OS_FIND "; .A%=RdByte :dbg%:h0(A%,2)" ";  A%=0 ,Y%=RdByte :dbg%:h0(Y%,2)" "; KY%=Y%&7F:A%=mos_find: Y%=0 Y%=serin%:A%=open: Reopen serial port ,WrByte(&7F) :dbg%:"-- "h0(&7F,2)  =0   +RdString :dbg%:$string%" "; *3Y%=string%-1:Y%=Y%+1:?Y%<33:?Y%=13:Y%=string% 4NwildcardsNull:=0 : BB4W throws up a dialogue box with wildcards and "" >&$Y%=fn_convert($Y%,client%,host%) H Y%=mos_find:Y%:Y%=Y% &80 R-WrByte(Y%) :dbg%:"-- "h0(Y%,2) \=0 f: p: z OS_FILE  ======= ? Tube data &14 block string function -- result block *ݤ_14 :dbg%:"OS_FILE "; DRdBlock(16) :dbg%: D%=0 12 4:h0(ctrl%!D%,8)" ";: ,RdString :dbg%:$string%;" "; .A%=RdByte :dbg%:h0(A%,2)" "; 3Y%=string%-1:Y%=Y%+1:?Y%<33:?Y%=13:Y%=string% NwildcardsNull:=0 : BB4W throws up a dialogue box with wildcards and "" .fn$=$Y%:$Y%=fn_convert($Y%,client%,host%) X%=ctrl%-2:A%=mos_file .WrByte(A%) :dbg%:"-- "h0(A%,2); FWrBlock(16) :dbg%: D%=0 12 4:" "h0(ctrl%!D%,8);:: =0 : :  OS_GBPB $ ======= .9 Tube data &16 block function -- block Carry result 8*ݤ_16 :dbg%:"OS_GBPB "; BVRdBlock(13) :dbg%:h0(?ctrl%,2)" ";: D%=1 9 4:h0(ctrl%!D%,8)" ";: L.A%=RdByte :dbg%:h0(A%,2)" "; VX%=ctrl%:?X%=?X%&7F `A%=mos_gbpb:?X%=?X%&80 j`WrBlock(13) :dbg%:"-- "h0(?ctrl%,2)" ";: D%=1 9 4:h0(ctrl%!D%,8)" ";: t6WrByte((A%&100)2):dbg%:h0((A%&100)2,2)" "; ~-WrByte(A%) :dbg%:h0(A%,2) =0 : : OS_FSC ====== % Tube data &18 X Y A -- &FF Y X B -- &7F then string &0D -- &7F/&40/&80 +ݤ_18 :dbg%:"OS_FSC "; /X%=RdByte :dbg%:h0(X%,2)" "; /Y%=RdByte :dbg%:h0(Y%,2)" "; /A%=RdByte :dbg%:h0(A%,2)" "; Cdbg%:"OPTEOF*/ CMDRUNCATNEWHNDWRNEX INFRUNREN",A%*3+1,3)" "; : * A%>127 A%<2 A%=6 A%=7 A%=8 A%=1:Y%=Y%127 : =EOF A%=mos_fsc (1WrByte(&FF) :dbg%:"-- "h0(&FF,2)" "; 2+WrByte(Y%) :dbg%:h0(Y%,2)" "; <'WrByte(X%) :dbg%:h0(X%,2) F=0 P Z3WrByte(&7F) :dbg%:"-- "h0(&7F,2)" "; d,RdString :dbg%:$string%" "; nY%=string%:A%=mos_fsc x( A%>=0:WrByte(A%):dbg%:h0(A%,2) =0 : :  Null routines  ============= ݤ_1A=0 ݤ_1C=0 : L OS_RESYNC - Called within error handler to allow Host to resynchronise  =========  Tube data &1E -- &00 +ݤ_1E :dbg%:"OS_SYNC "; /WrByte(&00) :dbg%:"-- "h0(&00,2) =0 : : " _ERROR ,_$string%="HostFS error: ",<128 <>17 <>28)+$+" ("+Þ+")",<128 <>17 <>28)+0 6FWrCmd(&00) :dbg%:"ERROR "h0(PFX%,2)" "h0(&00,2)" "; @0A%=: =28:A%=253:$string%="Bad address"+0 J,WrByte(A%) :dbg%:h0(A%,2)" "; TB%=0 ^ hA%=string%?B% r$WrByte(A%) :dbg%:c(A%); | B%=B%+1 A%=0 :dbg%:  : : _RESET EWrCmd(&00) :dbg%:"RESET "h0(PFX%,2)" "h0(&00,2)" "; -WrByte(&00) :dbg%:h0(&00,2)" "; )WrByte(&00) :dbg%:h0(&00,2) 8 REPEAT:A%=FNRdByte:IFA%:VDUA% :REM Startup string = UNTILA%=0:PROCWrByte(&00) :REM Acknowledge startup  : : ݤwildcardsNull:os%<>32:= +?Y%=13 $Y%="""": 204,"Bad filename" ݤwildcards:os%<>32:= &-(client%96)=0:$Y%,"*")+$Y%,"#")=0:= 0-(client%96) :$Y%,"*")+$Y%,"?")=0:= : 253,"Wildcards" D= N: X: b!EscOff:os%=32:"ESC OFF": l"FX229": v EscOn:os%=32:"ESC OFF": "FX229,1": : :  I/O routines  ============ : ݤRdByte  bB%=SerIn:B%=PFX%:B%=SerIn:B%<>PFX%:(B%&81)=0:client%=B%&60:A%=("FN_"+~(B%&1E)):B%=-1 B%>=0 =B% : WrByte(A%) %SerOut(A%): A%=PFX%:SerOut(A%)  : WrCmd(A%) *SerOut(PFX%):SerOut(A%): 4: >RdBlock(N%): N%=0: H+ D%=N%-1 0 -1:ctrl%?D%=RdByte:: R: \WrBlock(N%): N%=0: f, D%=N%-1 0 -1:WrByte(ctrl%?D%):: p: zRdString 4D%=0::B%=RdByte:string%?D%=B%:D%=D%+1:B%=13: : WrString 5D%=0::B%=string%?D%:WrByte(B%):D%=D%+1:B%=13: : :  Low level routines  ================== : ݤSerIn:serin%:=#serin% =0 : (SerOut(A%):serout%:#serout%,A%:  : 2SerFlush:serin%:ȕ #serin%:B%=#serin%:: $ .: 8: Bݤargs(A%,Y%,X%) L2"@ARGS "h0(A%,2)" "h0(Y%,2)" "h0(X%,8)" "; V=0 `: j: t Choices System ~ ============== %Choices_Init(Pub$,App$): A$,A%  os%=32 &Choices_Rd(@dir$+"\"+App$+".ini") 5A$=Reg_Rd("Software\"+Pub$+"\"+App$+"\Settings") A$<>"":Choices_Rd(A$)   os%=6 ?ș "OS_GetEnv" A$:A$=A$,A$,"""")+1):A$=A$,A$,"""")-1) 4 A%=Pub$,"."):A%:Pub$=Pub$,A%-1)+Pub$,A%+1) 8A%=0:A%=Pub$," "):A%:Pub$=Pub$,A%-1)+Pub$,A%+1) &A%=0:Choices_Rd(A$+".^.Choices") 4Choices_Rd("Choices:"+Pub$+"."+App$+".Choices")    : Choices_Rd(file$): A$,A% (in%=(file$) 2 in% < FA$=#in%: A$,1)="#":A$="" PA%=A$,":"): A% Z&A%=A%-1::A%=A%+1: A$,A%,1)<>" " d6Var_Assign("_"+A$,A%-1)+"$",""""+A$,A%+1)+"""") n x #in%:#in%:in%=0     > BBCMOS  BBC MOS Interface > Within this library, all filenames are locally formatted (; 2ݤmos_args <' Y%=0: A%=0:=fs : =FS F Y%=-1 Y%=&7F P Ȏ A% Z4 0:!X%=0:=0 : =PTR#-1 dI 2:!X%=((os%=32)255)-(-1):=0 : =EXT#-1, number in keyboard buffer nF 5:!X%=((os%=32)255)=(-1):=0 : =EOF#-1, keyboard buffer empty? x  Y% Ȏ A% " 0:!X%=#Y%:=0 : =PTR " 1:#Y%=!X%:=0 : PTR= " 2:!X%=#Y%:=0 : =EXT " 3:#Y%=!X%:=0 : EXT= $ 4:!X%=#Y%:=0 : =Alloc " 5:!X%=#Y%:=0 : =EOF $ 6:#Y%=!X%:=0 : Alloc=   < os%=6: >&FFFF:ș "OS_Args",A%,Y%,!X% A%,Y%,!X%:=A% !X%=args(A%,Y%,!X%) <=A% : Unchanged=unsupported : "ݤmos_bget , Y%=0 60 os%=32:A%=kbd_GET A%= : =BGET#0 @=((A%=27)&100)+A% J T/ os%=32:=((#Y%=#Y%)256)+#Y% : =BGET#Y ^ A%=&FFD7 h$=((A%&1000000)&10000)(A%&FF) r: |ݤmos_bput  Y%=0: A% #Y%,A% =A% : ݤmos_find  A%=0:#Y%:=A% " (A%&C0)=&40:=f_openin($Y%) # (A%&C0)=&80:=f_openout($Y%) " (A%&C0)=&C0:=f_openup($Y%) =0 : ݤmos_file  A%=6: : :=0  A%=A%&FF  A%<5 A%=&FF:=host_file T os%=6:ș "OS_File",A%,Y%,X%!2,X%!6,X%!10,X%!14 A%,,X%!2,X%!6,X%!10,X%!14:=A% I A%=5:X%!2=0:X%!6=0:X%!10=0:X%!14=0:A%=Y%:Y%=X%256:=file_info($A%) &` A%=6:f_delete($Y%): inf%<>0 os%=32:f_delete($Y%+s$+"inf"):=1: Should return filetype 0& A%=6:=1: Should return filetype :C A%=7:"SAVE """+f_name($Y%)+""" "+~+"+"+~(X%!14-X%!10):=1 D A%=8:f_cdir($Y%):=2 N=A% X: bݤmos_gbpb:=host_gbpb l: v ݤmos_cli DY%=Y%-1::Y%=Y%+1:?Y%<>32 ?Y%<>"*" : Skip '*'s and ' 's QA%=&103: ?Y%="/":Y%=Y%+1:A%=&102 : Fall through into FSC :  ݤmos_fsc Oosc%=A%256:A%=A%255 : b8=called from OSCLI  Ȏ A% > 0: : *OPT  Ȏ X% / 0: : *OPT 0 - reset options max%=_MTU$*1024 dbg%=_DEBUG$ =0 G 1: : *OPT 1 - message levels (needs Client support) 6 2: : *OPT 2 - error handling level  J 3: : *OPT 3 - maximum block size (CFS: interblock gap) 9 Y%=0:Y%=_MTU$ : *OPT 3,0 - use default size  ? Y%=255:Y%=0 : *OPT 3,255 - unlimited block size *+max%=Y%*1024: max%<1024:max%=&7FFFFFFF 4=0 >- 4: : *OPT 4 - boot option H- 5:dbg%=Y%:=0 : *OPT 5 - debug level Rc 6: : *OPT 6 - transmission delay (HADFS: internal drive, ANFS: claim workspace) \` 7: : *OPT 7 - (HADFS: external drive, ANFS: user options) f p=0 z= 1:A%=5:X%=ctrl%:A%=mos_args:X%=?X%:Y%=X%:=A% : =EOF A 7:X%=&80:Y%=&9F:=0 : Handles L 255:=0 : Boot filing system ` X%=Break type, Y%=0 Boot, Y<>0 NoBoot (Y%=0 Shift Break, Y%=8 Break, Y%=&FF CoPro startup) 3 CoPro checks returned X.b7 for startup action ; Filing system checks returned Y.b1-b0 for boot action : B 3: : *command B ?Y%="|":=0 : *| comment M ?Y%="\":Y%=Y%+1 : *\command -> *command E ?Y%=13:=0 : Null string 6A%=$Y%+" "," "):B%=$Y%,"."):B%:A%>B%+1:A%=B%+1 ?A$=":"+uc($Y%,A%-1)):Y%=Y%+A%-1 : A$=command <ȕ ?Y%=32:Y%=Y%+1: : Skip spaces * A$,1)=".":A$=A$,A$-1) A$=A$+":" UA%=":CAT::::RUN::::CAT::::DELETE:CREATE:CDIR:::EX:::::INFO::::::::::RENAME:",A$) * A%=0:A%=3osc%:Y%=string%:=host_fsc $A%=3+A%7: A%=3:A%=5 . A%>5 A%<9 8@X%=Y%-1:X%=X%+1:?X%<33:?X%=13 : Terminate string B A%=7 LEX%=X%-1::X%=X%+1:?X%<>32 : *CREATE filename length Vctrl%!14=("&"+$X%) `"ctrl%!2=0:ctrl%!6=0:ctrl%!10=0 j tL$Y%=fn_convert($Y%,client%,host%):X%=ctrl%:!X%=Y%:A%=A%&100:=mos_file ~ A%=A%osc%  =host_fsc : ݤmos_word  Ȏ A% & 0: ""A$:$Y%=A$:X%=Y%:Y%=A$:=0  1:!X%=:X%?4=0:=0  2:=!X%:=0  5:X%?4=?!X%:=0  6:?!X%=X%?4:=0  7: !X%,X%!2,X%!4,X%!6:=0 V 8: X%?0,X%?1,X%?2,X%?3,X%?4,X%?5,X%?6,X%?7,X%?8,X%?9,X%?10,X%?11,X%?12,X%?13:=0  & 9:X%?4=!X%&FFFF,X%!2&FFFF):=0  14:$X%=$:=0  15:$=$X%:=0 ( 2Y%=X%256:A%=(&FFF1)&FF < F=A% P: Zݤmos_byte d A%=0 n2X%=(os%&D7)((client%64)2)((client%32)4) x X%<>os%:X%=X%&80 B=0 : =HOST  K A%>123:A%<127:?escflg%=128*(A%1):"FX15" : Clear/Set/Ack Escape A A%=&7F:A%=5:X%=ctrl%:A%=mos_args:X%=?X%:Y%=X%:=&7F : =EOF W A%=&81:os%=32:X%=kbd_INKEY((X%255)+256*Y%):Y%=X%256:=A%-256*(X%=-1) : =INKEY U A%=&81:X%=((X%255)+256*Y%):Y%=X%256:=A%-256*(X%=-1) : =INKEY L A%=&82:X%=membot%65536:Y%=X%256:=A% : high order address L A%=&83:X%=membot%:Y%=X%256:=A% : bottom of memory I A%=&84:X%=memtop%:Y%=X%256:=A% : top of memory D A%=&86:X%=:Y%=:=A% : =POS, =VPOS  os%=32 ? A%=&80:X%=7:ȗ X%,A%,A%:Y%=X%256:=&80 : =ADVAL(7) ? A%=&80:X%=8:ȗ A%,X%,A%:Y%=X%256:=&80 : =ADVAL(8) ? A%=&80:X%=9:ȗ A%,A%,X%:Y%=X%256:=&80 : =ADVAL(9) 7 A%=&87:X%=(,):Y%=:=A% : =MODE  A%=&A0 " Ȏ X% ,5 0,128:ș "GetRgnBox",@vdu%!60,ctrl%:X%=ctrl%!0 65 1 :ș "GetRgnBox",@vdu%!60,ctrl%:X%=ctrl%!1 @5 2,129:ș "GetRgnBox",@vdu%!60,ctrl%:X%=ctrl%!4 J5 3 :ș "GetRgnBox",@vdu%!60,ctrl%:X%=ctrl%!5 T5 4,130:ș "GetRgnBox",@vdu%!60,ctrl%:X%=ctrl%!8 ^= 5 :ș "GetRgnBox",@vdu%!60,ctrl%:X%=(ctrl%!8-1)256 h6 6,131:ș "GetRgnBox",@vdu%!60,ctrl%:X%=ctrl%!12 r@ 7 :ș "GetRgnBox",@vdu%!60,ctrl%:X%=(ctrl%!12/2-1)256 |$ 8,132:X%=@vdu%!24 @vdu%!216 & 9,133:X%=@vdu%!36 @vdu%!220-1 & 10,134:X%=@vdu%!28 @vdu%!216-1 $ 11,135:X%=@vdu%!32 @vdu%!220  12,136:X%=2*@vdu%!0  13 :X%=2*@vdu%!0 256  14,137:X%=2*@vdu%!4  15 :X%=2*@vdu%!4 256  16,138:X%=2*@vdu%!8  17 :X%=2*@vdu%!8 256 E 18,139:ș "GetRgnBox",@vdu%!60,ctrl%:X%=2*(ctrl%!12-@vdu%!12-1) K 19 :ș "GetRgnBox",@vdu%!60,ctrl%:X%=2*(ctrl%!12-@vdu%!12-1) 256  20,142:X%=@vdu%!16  21 :X%=@vdu%!16 256 C 22,143:ș "GetRgnBox",@vdu%!60,ctrl%:X%=(ctrl%!12-@vdu%!20-1) I 23 :ș "GetRgnBox",@vdu%!60,ctrl%:X%=(ctrl%!12-@vdu%!20-1) 256  24 :X%= & 25 :X%= 0 36 :X%=@vdu%!8 : 37 :X%=@vdu%!8 256 DC 38 :ș "GetRgnBox",@vdu%!60,ctrl%:X%=(ctrl%!12-@vdu%!12-1) NI 39 :ș "GetRgnBox",@vdu%!60,ctrl%:X%=(ctrl%!12-@vdu%!12-1) 256 X 85 :X%= b 87,155:X%=@vdu%?70 l 88,156:X%=@vdu%?71 v 89,153:X%=@vdu%?65  90,154:X%=@vdu%?67 + 91,151:X%=3-(@vdu%?64-7)2:X%<0:X%=1 + 92,152:X%=3-(@vdu%?66-7)2:X%<0:X%=1  96,3 :X%=@vdu%?73  98 : Left colour mask  99 : Right colour mask  109 :X%=@vdu%?65  110 :X%=@vdu%?67  155 :X%=@vdu%?70  156 :X%=@vdu%?71  153 :X%=@vdu%?65  154 :X%=@vdu%?67  X%=0   Y%=X%256:=&A0   * 4E Note: Client program should do ((os%=32)AND255)-ADVAL for -1/-2 >C A%=&80:X%=((X%255)((X%>127)-256)):Y%=X%256:=A% : =ADVAL H A%=&A0 R@ X%<16: X%<>3:=A% : =VDU(n) \ X%=3:X%=96 fȎ r%(1) p 16:A%=138 z 18:A%=139  20:A%=142  22:A%=143  36:A%=144  38:A%=145  77:A%=148  80:A%=149  83:A%=150  87:A%=155  88:A%=156  89:A%=153  90:A%=154  91:A%=151  92:A%=152  96:A%=3  !A%=X%: A%<128:X%=0:Y%=0:=&A0 $ .?!ctrl%=A%:ctrl%!4=-1:ș "OS_ReadVduVariables",ctrl%,ctrl%+8 8X%=ctrl%!8:Y%=X%256:=&A0 B L7A%=&FFF4:X%=(A%&FFFF00)256:Y%=(A%&FF0000)65536 V"=(A%&1000000)&10000+(A%&FF) `:  > HostTx a Assumes a reliable (all bytes get through) error-free (no bytes are corrupted) link channel c Within this library, all filenames are passed as internal filenames with external name in fn$ ( v0.27 OSFILE 1-4 2l v0.28 Reads file header, correct filename for *command, */command, *RENAME done, *file checks for .bin <5 v0.29 Data transfers done in blocks, added *EX. FB Changed name to HostTx as now almost completely generalised. PH v0.29c hnd% used for handles that don't need to be closed on error Z2 Added dng%AND8 output from PROCsend/PROCread d; n: x File load/save routines  ======================= > fn$ set by external caller to originally passed filename ݤhost_file =L%=X%!2:E%=X%!6:T%=X%!14:A%:?X%=file_info($Y%):S%=X%!10 A%>0 A%<5  L%=X%!2:E%=X%!6:T%=X%!14  ?X%=FNfile_info($Y%)  inf%=0:=?X% # A%=1:X%!2=L%:X%!6=E%:X%!14=T%  A%=2:X%!2=L%  A%=3:X%!6=E%  A%=4:X%!14=T% lY%=string%:A$=$Y%:$Y%=fn_leaf(A$)+" "+h0(X%!2,8)+" "+h0(X%!6,8)+" "+h0(X%!10,8): +" "+FNh0(X%!14,2) 2"SAVE "+A$+s$+"inf "+~Y%+"+"+~($Y%+1):=?X% L OSCLI"SAVE "+FNfn_noext(A$)+s$+"inf "+STR$~Y%+"+"+STR$~(LEN$Y%+1):=?X%  "'A%=&FF:T%=X%!2:(E%255)=0:X%!2=L% ,-A%=&FF:?X%:X%!2=-1: 252,"Bad address" 6A%=&FF:A%=&40 A%=&80 @ch%=mos_find J3A%=&40:ch%=0: 214,"File '"+fn$+"' not found" T/A%=&80:ch%=0: 192,"Can't save '"+fn$+"'" ^ A%=&40 hUY%=host_send(X%+2,ch%,#ch%):X%!2=T% : Send the file r |XY%=X%!14-X%!10:T%=host_read(X%+10,ch%,Y%):X%!10=Y%:X%!14=&33 : Fetch the file  #ch%:ch%=0 ! A%=&80 os%>31 inf%<>0 bY%=string%:?X%=file_info($Y%):X%!2=L%:X%!6=E%:X%!10=S%:=?X% : No change, no new .inf file HA$=$Y%:$Y%=fn_leaf(A$)+" "+h0(L%,8)+" "+h0(E%,8)+" "+h0(X%!10,8) -"SAVE "+A$+s$+"inf "+~Y%+"+"+~($Y%+1) G OSCLI"SAVE "+FNfn_noext(A$)+s$+"inf "+STR$~Y%+"+"+STR$~(LEN$Y%+1) X%!2=L%:X%!6=E%  Z=1 : Return 'File' : :  File read/write routines  ======================== ݤhost_gbpb  X%=>control block &DA%=0 A%>4:=host_info : Read filing system information 0+hnd%=?X%:(A%1):#hnd%=X%!9 : Set PTR :KA%>2:X%!5=host_send(X%+1,hnd%,X%!5) X%!5=host_read(X%+1,hnd%,X%!5) D9X%!9=#hnd% : Return updated PTR NS=(#hnd%)&100 : Return Carry in b8, 0 in b0-b7 for 'supported' X: b: l$ File filing system information v$ ============================== ݤhost_info  os%<>32:=A% % sh%,dir%,res%,ptr%: dir% 317  Ȏ A%  6: 5ș "GetCurrentDirectory",255,string%:A$=$$string% ,B$=A$,1):A$=fn_leaf(A$): A$="":A$="\" $A$=fn_convert(A$,host%,client%) &WrCmd(&E0) : Load data )WrByte(X%?4) : Send address WrByte(X%?3) WrByte(X%?2) WrByte(X%?1) WrByte(1)  WrByte(B$) WrByte(A$)  $string%=A$+0 * WrString 4)WrCmd(&B0) : End transfer >X%!1=X%!1+$string% H=0 R 8 \ ptr%=X%!9 f@ș "FindFirstFile",".\*.*",dir% sh% : Initialise search p sh%<>-1 z 7A$=$$(dir%+44) : Get object name S A$="." A$=".." uc(A$,4))=".INF":ptr%=ptr%+1: Step past special objects  ptr%=0 ș "FindClose",sh% $A$=fn_convert(A$,host%,client%) &WrCmd(&E0) : Load data )WrByte(X%?4) : Send address WrByte(X%?3) WrByte(X%?2) WrByte(X%?1) &WrByte(A$) : name length $string%=A$ (WrString : Name string )WrCmd(&B0) : End transfer 1X%!1=X%!1+1+A$ : Update data address =X%!5=X%!5-1 : Count=Count-number transfered $:X%!9=X%!9+1 : Increment returned pointer .=0 8 B=ptr%=ptr%-1 : Decrement requested pointer L=ș "FindNextFile",sh%,dir% res% : Step to next object VB res%=0 : Loop until no more found `ș "FindClose",sh% j t@=0 : Return at end of directory ~ =A% : :  Filing control routines  ======================= ݤhost_fsc ! 0 - *OPT - done by BBCMOS ! 1 - EOF - done by BBCMOS  2 - */  3 - *command  4 - *RUN  5 - *CAT / 6 - New filing system - done by BBCMOS  / 7 - Handles - done by BBCMOS / 8 - OSCLI warning - done by BBCMOS  9 - *EX ( 10 - *INFO 2 11 - LIBRUN < 12 - *RENAME FF 255 - Boot filing system - done by BBCMOS (should this be here?) P String has spaces skipped Z% sh%,dir%,res%,ptr%: dir% 317 dZosc%=A% 256:A%=A% 255: A%=9: os%<>32:A%=5 : *EX not implemented for non-Windows n Ȏ A% x< 5: : *CAT ?Y%<>13:$Y%=$Y%+"." Ewildcards:=0 : BB4W throws up a dialogue box with wildcards out%=(tmp$+"!") V os%=32: "OUTPUT "+out%: "DIR "+fn_convert($Y%,client%,host%)+"*.*":*OUTPUT 0 #out%:out%=0 4 osc%=0:WrByte(&40) :dbg%:h0(&40,2)" "; in%=(tmp$+"!")::A%=#in% %(host%64)=64 (client%96)=0 1 A%=46:A%=47 A%=47:A%=92 A%=92:A%=46  %(host%96)=0 (client%64)=64 1 A%=46:A%=92 A%=47:A%=46 A%=92:A%=47  J((host%96)<>0 (client%96)=0) ((host%96)=0 (client%96)<>0) $ A%=35 A%=63:A%=A%28 : # ? $ A%=36 A%=60:A%=A%24 : < $ "$ A%=61 A%=64:A%=A%125 : = @ ,$ A%=62 A%=94:A%=A%96 : > ^ 6 @L((host%64)=64 (client%96)=32) ((host%96)=32 (client%64)=64) J! A%=47:A%=92 A%=92:A%=47 T ^ osc%: A% WrByte(A%) h#in%:#in%:in%=0 r! in%=OPENIN(tmp$+"!"):REPEAT |O PROCPrText(FNfn_convert(GET$#in%,host%,client%)):IF osc%=0:PROCWrByte(10) 5 UNTILEOF#in%:CLOSE#in%:in%=0:PROCPrText(CHR$10) =0 B 9,10: : *EX, *INFO Ewildcards:=0 : BB4W throws up a dialogue box with wildcards ex%=A%=9:res%=0 JX%=Y%-1:X%=X%+1:?X%<33:?X%=13 : Terminate at space or 7fn$=$Y%:$Y%=fn_convert($Y%,client%,host%):X%=ctrl% 5 osc%=0:WrByte(&40) :dbg%:h0(&40,2);" "; " ex%:fn$=$Y%: fn$="":fn$="." G ex%:ș "FindFirstFile",fn$+"\*.*",dir% sh% : Initialise search  U ex%: sh%<>-1:$Y%=$$(dir%+44): $Y%="." $Y%=".." uc($Y%,4))=".INF":$Y%="" # ex%: $Y%<>"":$Y%=fn$+"\"+$Y% H $Y%<>"":A%=file_info($Y%): A%=0: 214,"File '"+fn$+"' not found" 4A$=fn_convert(fn_leaf($Y%),host%,client%),12) 2A$=A$+13-A$," ")+h0(X%!2,8)+" "+h0(X%!6,8) &IA$=A$+" "+h0(X%!10,8)+" "+f_access(X%?14,A%)+" "+f_date(X%!15)+10 0 $Y%<>"":PrText(A$) :+ ex%:ș "FindNextFile",sh%,dir% res% D res%=0 N ex%:ș "FindClose",sh% X=0 b? 12 : *RENAME l3wildcards:=0 : Can't do wildcarded rename vVX%=Y%-1:X%=X%+1:?X%<33:A%=?X%:?X%=13:fn1$=$Y% : fn1$ terminate at space or I?X%=A%:X%=X%-1::X%=X%+1:?X%<>32 : Skip spaces to fn2 VA%=X%:X%=X%-1:X%=X%+1:?X%<33:?X%=13:fn2$=$A% : fn2$ terminate at space or 9$Y%=f_name(fn_convert(fn1$,client%,host%)):X%=ctrl% 9 file_info($Y%)=0: 214,"File '"+fn1$+"' not found" =A%=Y%+$Y%+1:$A%=f_name(fn_convert(fn2$,client%,host%)) A fn1$<>fn2$: file_info($A%): 196,"File '"+fn2$+"' exists" -fn1$=$Y%:fn2$=$A%:A%?-1=32:"Rename "+$Y% fn1$=fn1$+s$+"inf" fn2$=fn2$+s$+"inf" $ fn1$=FNfn_noext(fn1$)+s$+"inf" $ fn2$=FNfn_noext(fn2$)+s$+"inf"  : :=0 P "Rename "+fn1$+" "+fn2$ : Rename any .inf file =0  B 3: : *command @Y%=Y%-1::Y%=Y%+1:?Y%<>32 ?Y%<>"*" : Skip '*'s and ' 's  MX%=Y%:?Y%="\":Y%=Y%+1 : *\command -> *command *4A%=$Y%+" "," "):B%=$Y%,"."):B%:A%>B%+1:A%=B% 4?A$=":"+uc($Y%,A%-1)):Y%=Y%+A%-1 : A$=command ><ȕ ?Y%=32:Y%=Y%+1: : Skip spaces H)A$,1)=".":A$=A$,A$-1) A$=A$+":" R;C$=":ACCESS:DIR:FREE:GO:HELP:LOAD:LIB:SAVE:":A%=C$,A$) \3 A%:=("FNhost_"+C$,A%+1,C$,":",A%+1)-A%-1)) f( A%=0:?X%="\": 254,"Bad command" pUY%=X%:A%=3 : Fall through to */filename z  A%=2 A%=3 A%=4 M: : */, *command, *RUN E ?Y%=13:=0 : Null string "X%=Y%::X%=X%+1:?X%<33:?X%=13 .fn$=$Y%:$Y%=fn_convert($Y%,client%,host%) .X%=ctrl%:X%!2=0:X%!6=0:?X%=file_info($Y%) D ?X%=0: $Y%,4)<>s$+"bin":$Y%=$Y%+s$+"bin":?X%=file_info($Y%) = ?X%=0:A%=3: 254,"Bad command" : *command > ?X%=0: 214,"File '"+fn$+"' not found" : */, *RUN K (X%!2 X%!6)=-1: 252,"Bad address" : No load or exec address A%=&40:ch%=mos_find + ch%=0: 214,"Couldn't open '"+fn$+"'" AY%=host_send(X%+2,ch%,#ch%) : Send file #ch%:ch%=0 ^WrCmd(&C0) : Send 'address' command QWrByte(X%?9):WrByte(X%?8):WrByte(X%?7):WrByte(X%?6) : Send start address $[=&80 : Return 'execute' . 8=0 B: L,ݤhost_send(addr%,hnd%,num%): blk%,len% V%:len%=num%: len%>max%:len%=max% `< dbg%8:'6;"Load ";h0(!addr%,8);"+";h0(len%,8);" "; jgblk%=len%:WrCmd(&E0) : Send 'load' command tWWrByte(addr%?3):WrByte(addr%?2):WrByte(addr%?1):WrByte(addr%?0) : Send address ~R blk%: #hnd%::WrByte(#hnd%):blk%=blk%-1: blk%=0 #hnd% : Send data llen%=len%-blk%:!addr%=!addr%+len%:num%=num%-len% : Update address, count `WrCmd(&B0) : End transfer "SerFlush:blk%=(10):SerFlush  num%=0 #hnd% =num% : ,ݤhost_read(addr%,hnd%,num%): blk%,len% %:len%=num%: len%>max%:len%=max% < dbg%8:'6;"Save ";h0(!addr%,8);"+";h0(len%,8);" "; gblk%=len%:WrCmd(&F0) : Send 'save' command WWrByte(addr%?3):WrByte(addr%?2):WrByte(addr%?1):WrByte(addr%?0) : Send address R blk%::#hnd%,RdByte:blk%=blk%-1: blk%=0 : Read data llen%=len%-blk%:!addr%=!addr%+len%:num%=num%-len% : Update address, count `WrCmd(&B0) : End transfer "SerFlush:blk%=(10):SerFlush  num%=0 ( =num% 2: <: F Support *commands P ================= Zݤhost_HELP d=A%=uc($Y%,4))="TUBE" uc($Y%,4))="HOSTFS" ?Y%="." n0 osc%=0:WrByte(&40) :dbg%:h0(&40,2) xPrText(10) !PrText("TubeHost "+ver$+10) A%=0:=0 3 PROCPrText(" ACCESS "+CHR$10) !PrText(" CAT ()"+10) 'PrText(" CREATE "+10) PrText(" CDIR "+10) !PrText(" DELETE "+10) PrText(" DIR "+10) PrText(" EX ()"+10) ! PROCPrText(" FREE"+CHR$10) PrText(" GO "+10) #PrText(" HELP ()"+10) PrText(" INFO "+10) (PrText(" LOAD ()"+10)  PrText(" OPT ,"+10) & PROCPrText(" LIB "+CHR$10) "#PrText(" RUN "+10) ,-PrText(" RENAME "+10) 6FPrText(" SAVE |+ ( ())"+10) @=0 J: Tݤhost_ACCESS:=0 ^ݤhost_FREE:=0 hݤhost_LIB:=0 r: |5ݤhost_DIR:?Y%=13:$Y%=fn_convert("&",0,client%) fn$=$Y%:wildcards:=0 7f_dir(fn_convert($Y%,client%,host%)):INF%=inf%:=0 : ݤhost_GO  dbg%: ?Y%=13:  ?Y%=13:_RESET:=-1 !X%=("&"+$Y%) $WrCmd(&C0) : Set Address %WrByte(X%?3) : Send address WrByte(X%?2) WrByte(X%?1) WrByte(X%?0) =&80 : ݤhost_LOAD X%=Y%::X%=X%+1:?X%<33 &A%=X%-1::A%=A%+1:?A%<>32 0-?X%=13:?A%=13:A%=-1 A%=("&"+uc($A%)) :X%=ctrl%:X%!2=A%:X%?6=A%=-1 D.fn$=$Y%:$Y%=fn_convert($Y%,client%,host%) NA%=&FF:A%=host_file:=0 X: bݤhost_SAVE l X%=Y% vFX%=X%-1::X%=X%+1:?X%<33:A%=X%:$A%=uc($A%) : A%=end of filename FX%=X%-1::X%=X%+1:?X%<>32:S%=X%:?A%=13 : S%=start of START BX%=X%-1::X%=X%+1:?X%<"0":A%=X% : A%=end of START 3X%=X%-1::X%=X%+1:?X%="+" ?X%>"/" ?X%=13 &P%=?X%="+":P%::X%=X%+1:?X%<>32 QE%=X%:L%=S%:R%=S% : E%=start of END/LEN ,X%=X%-1::X%=X%+1:?X%<"0":?A%=13:A%=X% X%=X%-1::X%=X%+1:?X%<>32 e?X%<>13:R%=X%:X%=X%-1::X%=X%+1:?X%<"0":?A%=13:A%=X%:X%=X%-1::X%=X%+1:?X%<>32:?X%<>13:L%=X% 3?A%=13:X%=ctrl%:X%!2=("&"+$L%):X%!6=("&"+$R%) BX%!10=("&"+$S%):P%:X%!14=("&"+$E%)+X%!10 X%!14=("&"+$E%) .fn$=$Y%:$Y%=fn_convert($Y%,client%,host%) A%=&00:A%=host_file:=0 : : PrText(A$) osc%:A$;13;: $string%=A$:WrString * 4: >: H*ݤfile_info(A$): A%,L%,E%:L%=-1:E%=-1 R: \ Check for file header fin%=f_openin(A$): in% p. A%=0 127: #in%:X%?A%=0 X%?A%=#in% z& A%:#in%:in%=0 : Read header  X%!(X%?7)=&29432800 )A%=X%?6 : Code type ,L%=&FFFF8000 : Sideways ROM ) A%&40:L%=&8000 : Language ROM  A%&20 &A%=X%?7:A%=A%+1:X%?A%=0 A%>123 / A%<124:L%=X%!(A%+1) : Relocation address  E%=L%   :  Check for .inf file AI$=A$+s$+"inf": IF FNf_info(I$)=0:I$=FNfn_noext(A$)+s$+"inf"  : :=f_info(A$) ! f_info(I$)=1 X%!10<120 $2A%=X%!10:"LOAD "+I$+" "+~X%:X%!A%=&D20:A%=X% .5:A%=A%+1:?A%=32:A%=A%+1:?A%<>32:L%=("&"+$A%) 85:A%=A%+1:?A%=32:A%=A%+1:?A%<>32:E%=("&"+$A%) B LX%!2=L%:X%!6=E% VP=f_info(A$): Fills in Size and Attr, on RISCOS also fills in Load and Exec `: j: t Convert filenames ~ ================= ݤfn_convert(A$,from%,to%)  inf%=INF% )uc(A$,5))=":INF:":inf%=:A$=A$,6) +uc(A$,7))=":NOINF:":inf%=:A$=A$,8) from%=to% A$="":=A$  x00xxxxx - BBC  x01xxxxx - Unix  x1xxxxxx - DOS 1(from%96)=0 :(to%64)=64:=fn_bbctodos(A$) 2(from%96)=0 :(to%96)=32:=fn_bbctounix(A$) 1(from%64)=64:(to%96)=0 :=fn_dostobbc(A$) 2(from%64)=64:(to%96)=32:=fn_dostounix(A$) 2(from%96)=32:(to%96)=0 :=fn_unixtobbc(A$)  2(from%96)=32:(to%64)=64:=fn_unixtodos(A$) =A$ : (6 REM Support functions from BLib.File, BLib.FInfo 26 REM ============================================ <: F*ݤf_access(A%,T%):A$:(A%128):A$="P" P(T%2):A$=A$+"D" Z(A%8):A$=A$+"L" d(A%2):A$=A$+"W" n(A%1):A$=A$+"R" x(A%5)=4:A$=A$+"E"  A$=A$+"/":(A%32):A$=A$+"w" (A%16):A$=A$+"r" (A%80)=64:A$=A$+"e" =A$+" ",8) : aݤf_date(A%)=d0(A%31,2)+"/"+d0((A%&F00)256,2)+"/"+d0((A%&F000)4096+(A%&E0)/2+1981,4) & > BLib.Filename 1.01 25-Jan-2011 A Convert between BBC, DOS/Windows and UNIX/ZIP/URL filenames K!Keep FNfn_frombbc(), FNfn_tobbc(), FNfn_unixtodos(), FNfn_dostounix() 2: <: F5ݤfn_bbctodos(A$):A%,B%,H%:H%=32::fn_frombbc() P5ݤfn_bbctounix(A$):A%,B%,H%:H%=8::fn_frombbc() Z%ݤfn_frombbc(A$):A%,B%,H%:H%=os% dA$=""(H%-24)=0:=A$ nLA$,1)=":":A%=A$+".","."):A$=A$,2,A%-2)+":"+A$,A%-(A$,A%+1,1)="$")) x A%=0::A%=A%+1:B%=A$,A%,1) 7B%=35B%=63:A$=A$,A%-1)+(B%28)+A$,A%+1) : # ? 7B%=61B%=64:A$=A$,A%-1)+(B%125)+A$,A%+1): = @ 7B%=36B%=60:A$=A$,A%-1)+(B%24)+A$,A%+1) : < $ 7B%=62B%=94:A$=A$,A%-1)+(B%96)+A$,A%+1) : > ^ =B%="$":(H%-24)=8:A$=A$,A%-1)+"/"+A$,A%+1-(A%<>A$)) ;B%="$":(H%-32):A$=A$,A%-1)+"\"+A$,A%+1-(A%<>A$)) 'B%="@":A$=A$,A%-1)+"."+A$,A%+1) 0B%="^":A$=A$,A%-1)+".."+A$,A%+1):A%=A%+1 'B%="/":A$=A$,A%-1)+"."+A$,A%+1) 3B%=".":(H%-24)=8:A$=A$,A%-1)+"/"+A$,A%+1) 1B%=".":(H%-32):A$=A$,A%-1)+"\"+A$,A%+1) 1B%="\":(H%-32):A$=A$,A%-1)+"/"+A$,A%+1) : IFB%=ASC"&":A$=LEFT$(A$,A%-1)+"%HOME%"+MID$(A$,A%+1) A%>A$:=A$ : Zݤfn_fromunix(A$):(os%-24)=8:=A$ (os%-24)=0:=fn_unixtobbc(A$)::fn_dostounix() "Vݤfn_fromdos(A$):(os%-32):=A$ (os%-24)=0:=fn_dostobbc(A$)::fn_dostounix() ,Xݤfn_tounix(A$):(os%-24)=8:=A$ (os%-24)=0:=fn_bbctounix(A$)::fn_dostounix() 6Tݤfn_todos(A$):(os%-32):=A$ (os%-24)=0:=fn_bbctodos(A$)::fn_dostounix() @(ݤfn_unixtodos(A$)::fn_dostounix() Jݤfn_dostounix(A$) TA$,"/")+A$,"\")=0:=A$ ^Z A%,B%:A%=0::A%=A%+1:B%=A$,A%,1):B%="/"B%="\":A$=A$,A%-1)+(B%115)+A$,A%+1) hA%>=A$:=A$ r: |3ݤfn_dostobbc(A$):A%,B%,H%:H%=32::fn_tobbc() 3ݤfn_unixtobbc(A$):A%,B%,H%:H%=8::fn_tobbc() #ݤfn_tobbc(A$):A%,B%,H%:H%=os% A$=""(H%-24)=0:=A$ A$="/":(H%-24)=8:="$" A$="\":(H%-32):="$"  A%=0::A%=A%+1:B%=A$,A%,1) 6B%=35B%=63:A$=A$,A%-1)+(B%28)+A$,A%+1): # ? ;A$,A%,2)="..":A$=A$,A%-1)+"^"+A$,A%+2):A%=A%-1:B%=0 &A$,A%)=".":A$=A$,A%-1)+"@":B%=0 ?A$,A%,2)="./":(H%-24)=8:A$=A$,A%-1)+"@"+A$,A%+1):B%=0 =A$,A%,2)=".\":(H%-32):A$=A$,A%-1)+"@"+A$,A%+1):B%=0 G IFMID$(A$,A%,6)="%HOME%":A$=LEFT$(A$,A%-1)+"&"+MID$(A$,A%+6):B%=0 'B%=".":A$=A$,A%-1)+"/"+A$,A%+1) 1B%="\":(H%-32):A$=A$,A%-1)+"."+A$,A%+1) 1B%="/":(H%-32):A$=A$,A%-1)+"\"+A$,A%+1) 3B%="/":(H%-24)=8:A$=A$,A%-1)+"."+A$,A%+1) &4B%=":":A$=":"+A$,A%-1)+".$"+A$,A%+1):A%=A%+2 0A%>A$:=A$ :: " > BLib.File 1.02 J.G.Harston + Platform-independant filing functions : (: 25 PROCf_init - initialise filing-system variables <5 ----------------------------------------------- F f_init P0):B%:A%=B%-1 A%:=A$,A%) +":$%&^@\-",A$,1)):=A$,A$+d$,d$)-1) ="" : : ) FNfn_leaf(path$) - returns leafname ) ----------------------------------- &ݤfn_leaf(A$):A%,B%:A%=A$,":",2) +B%=A%:A%=A$,d$,A%+1):A%=0:=A$,B%+1) : : ) FNfn_path(path$) - returns pathname ) ----------------------------------- "&ݤfn_path(A$):A%,B%:A%=A$,":",2) ,)B%=A%:A%=A$,d$,A%+1):A%=0:=A$,B%) 6: @: J4 FNfn_ext(path$) - returns leafname's extension T4 ---------------------------------------------- ^ݤfn_ext(A$):A$,s$)=0:="" h1 A%:A%=A$+1:A%=A%-1:":"+d$+s$,A$,A%,1)) r A$,A%,1)=s$:=A$,A%) ="" |: : 8 FNfn_noext(path$) - returns path with no extension 8 -------------------------------------------------- !ݤfn_noext(A$):A$,s$)=0:=A$ 1 A%:A%=A$+1:A%=A%-1:":"+s$+d$,A$,A%,1)) "A$,A%,1)=s$:=A$,A%-1) =A$ : : = FNfn_fullpath(path$, file$) - return full absolute path = ------------------------------------------------------- ݤfn_fullpath(P$,A$) '"$%&^\-",A$,1)):(os%-24)=0:=A$ A$,":")A$,1)=d$:=A$ =P$+d$,P$,1)<>d$)+A$ : : &9 PROCf_gbpb() - multiple get-bytes or put-bytes call 09 --------------------------------------------------- :%f_gbpb(A%,chn%,addr%,num%,ptr%) D=?X%=chn%:X%!1=addr%:X%!5=num%:X%!9=ptr%:<&FFFF:&FFD1: NA%=1A%=3:#?X%=X%!9 X5:A%=1A%=2:#?X%,?X%!1 A%=3A%=4:?X%!1=#?X% b5X%!1=X%!1+1:X%!5=X%!5-1:(#?X% A%>2) X%!5<1: l: v: - FNfs - get current filing system number - --------------------------------------- )ݤfs:<&FFFF:A%,Y%,E%:=(&FFDA)&FF =29 : : ( PROCf_dir(dir$) - select directory + PROCf_delete(object$) - delete object + ------------------------------------- >f_dir(A$):(os%-24):A$="cd "+A$ A$="dir "+f_name(A$) Ff_delete(A$):(os%-24)=8:A$="rm "+A$ A$="delete "+f_name(A$)  A$: : :  D PROCf_cdir(dir$) - create a directory only if it doesn't exist D --------------------------------------------------------------  :f_cdir(A$):(os%-24):A$="mkdir "+A$ A$="cdir "+A$ * 4 A$: > H : : R A$: \: f: pE FNf_name(path$) - ensure no extension if no extension specified zE --------------------------------------------------------------- ݤf_name(A$) Ios%>31:A%,B%:B%=A%:A%=A$,"\",A%+1):A%=0:A$,".",B%)=0:A$=A$+"." =A$ : : B FNf_openin(file$) - open an input file ensuring no extension B ------------------------------------------------------------ !ݤf_openin(A$)=(f_name(A$)) : : C FNf_openup(file$) - open an update file ensuring no extension C ------------------------------------------------------------- !ݤf_openup(A$)=(f_name(A$)) : : D FNf_openout(file$) - open an output file ensuring no extension $D -------------------------------------------------------------- ."ݤf_openout(A$)=(f_name(A$)) 8: B: L@ FNf_info(object$) - returns file type, file info in X%!... V@ ---------------------------------------------------------- `Oݤf_info(A$):<&FFFF:$name%=A$:?X%=name%:X%?1=name%256:A%=5:=(&FFDD)&FF jos%<>32:=0 tdir%,sh%:dir%319 ~*ș"FindFirstFile",f_name(A$),dir%sh% Lsh%=-1:ș"GetFileAttributes",f_name(A$)sh%:=((sh%16)16+1)(sh%<>-1)  Eh? Shouldn't exit there 5ș"FindClose",sh%:X%!10=dir%!32:dir%!28:X%!10=-1 ,X%?14=(?dir%1)*8+(&33 ((?dir%16)=0)) *ș"FileTimeToSystemTime",dir%+20,X%+16 BA%=(X%!16&FFFF)-1981:X%?15=X%?22+(A%&70)*2:X%?16=X%?18+A%*16 8X%?17=X%?24:X%?18=X%?26:X%?19=X%?28:=(?dir%16)16+1 : : 3 PROCf_settype(object%, type%) - set file type 3 ---------------------------------------------  f_settype(A$,A%):os%=32: H<&FFFF:f_info(A$):X%?3=A%:X%?4=(A%256)&F0:X%?5=&FF:A%=1:&FFDD   : :  > BLib.Win.BBCKbd 0.11 ' Returns BBC-style keypress values : (2ݤkbd_GET: A%:A%=kbd_INKEY(100):A%<>-1:=A% 2: <&ݤkbd_INKEY(T%): A%,S%:T%<0:=T% F*A%=(T%):S%=(-116)+(-232)+(-348) PA%=8A%=&87:A%=&7F ZA%<&80:=A% d4A%=A%-&10:A%>&7F:(A%15)>9:A%=A%&40:S%=0:=A% n9S%:A%>&CA:A%<&D0:=("&"+"09E8ABAFAE",A%*2-405,2)) xFA%<&80:=("&"+"8C8DC88B9F9ECD7F8C8D8E8FCECFCECF",A%*2-223,2))S% =A% " > BLib.String 1.00 09Aug1998 : # String Manipulation Functions (# ============================= 2: <7 FNs() - strip spaces from start and end of string F7 ------------------------------------------------- P/ݤs(A$):A$,1)=" ":A$=A$,2):A$,1)<>" " Z+A$,1)=" ":A$=A$,A$-1):A$,1)<>" " d=A$ n: x+ FNuc() - convert string to upper case + ------------------------------------- ݤuc(A$): B$:A$="":="" 5B$=B$+(A$((A$<"@")&DF)):A$=A$,2):A$="":=B$ : + FNlc() - convert string to lower case + ------------------------------------- ݤlc(A$): B$:A$="":="" 5B$=B$+(A$((A$<"_")&20)):A$=A$,2):A$="":=B$ :  > BLib.Variable # Variable assignment functions # ============================= (@!Keep FNVar_S(), FNVar_I(), FNVar_B(), FNVar_F(), FNVar_R() 2;|!Keep Var_S(); Var_I(); Var_B(); Var_F(); Var_R() <: F Var_Assign(Var$,Val$) P8 Sets the variable in 'Var$' to the value in 'Val$' Z8 -------------------------------------------------- d: nVar_Assign(Var$,Val$) x7 Var$,1)="$":A%=("FNVar_S("+Var$+","+Val$+")"): 7 Var$,1)="%":A%=("FNVar_I("+Var$+","+Val$+")"): 7 Var$,1)="&":A%=("FNVar_B("+Var$+","+Val$+")"): 7 Var$,1)="#":A%=("FNVar_F("+Var$+","+Val$+")"): (A%=("FNVar_R("+Var$+","+Val$+")"):  : ݤVar_S( a$,b$):a$=b$:=0 ݤVar_I( a%,b%):a%=b%:=0 ݤVar_B( a&,b&):a&=b&:=0 ݤVar_F( a#,b#):a#=b#:=0 ݤVar_R( a, b ):a =b :=0 : 0 > BLib.Win.Reg v1.04 20Sep2010 J.G.Harston % v1.00 18May2006 Initial version 0 v1.01 09Feb2007 Finds required buffer size (" v1.02 13Aug2007 B% localised 2D v1.03 25Apr2009 Michael Hutton: uses $$B%, added PROCReg_Del() <. v1.04 20Sep2010 Shortened variable names F: P. Simple Windows registry access functions Z. ======================================== d: n/ Reg_Rd(Key$) - Read a user registry entry x/ ----------------------------------------- : 'ݤReg_Rd(K$): K%,R%,L%,T%,I$,V$,B% (I$=K$::K%=I$,"\"):K%:I$=I$,K%+1) K%=0:K$=K$,K$-I$-1) 4ș "RegOpenKeyEx",&80000001,K$,0,&20001,^K% R% R%=0 4ș "RegQueryValueEx",K%,I$,0,^T%,0,^L%: B% L% 0ș "RegQueryValueEx",K%,I$,0,^T%,B%,^L% R%  R%=0:B%?(L%-1)=0:V$=$$B% ș "RegCloseKey",K%  =V$ : : 7 Reg_Wr(Key$,Value$) - Write a user registry entry 7 ------------------------------------------------- ": ,!Reg_Wr(K$,V$): K%,D%,R%,I$ 6(I$=K$::K%=I$,"\"):K%:I$=I$,K%+1) @K%=0:K$=K$,K$-I$-1) JAș "RegCreateKeyEx",&80000001,K$,0,"",0,&F003F,0,^K%,^D% R% T R%=0 ^)ș "RegSetValueEx",K%,I$,0,1,V$,V$+1 hș "RegCloseKey",K% r | : : 2 Reg_Del(Key$) - delete a user registry entry 2 -------------------------------------------- : Reg_Del(K$): K%,R% ?ș "RegCreateKeyEx",&80000001,K$,0,"",0,&F003F,0,^K%,0 R%  R%=0  ș "RegDeleteTree",K%,0 R% ș "RegCloseKey",K%