10
20 ver$="0.00":
30 ver$="0.01":
40 ver$="0.02":
50 ver$="1.00":
60 ver$="1.02":
70 ver$="1.04":
80 ver$="1.05":
90 :
100 MODE&87:PRINTSPC5"Spectrum/BBC fileserver "ver$'SPC3"with local keyboard for Spectrum"
110 IFFNfx(0,1)=5:*SerFix
120 PROCInit:ONERROR:IFFNerr:PROCend:END
130 PRINT'"Ready...":*FX15
140 PROCon:REPEATUNTILFNdo:PROCend:END
150 :
160 DEFFNerr:IFNOTcomm%:*FX3
170 REPORT:IFcomm%:PRINT'CHR$93; ELSE PROCreply(ERR,FNerror,TRUE):IFERR<128 AND ERR<>17:PRINT" at line ";ERL
180 OSCLI"FX3":PROCCloseOut:PROCCloseIn
190 =(ERR<128 AND ERR<>17)OR(ERR=17 ANDINKEY-1)
200 :
210 DEFPROCCloseIn:IFin%:A%=in%:in%=0:CLOSE#A%
220 ENDPROC
230 DEFPROCCloseOut:IFout%:A%=out%:out%=0:CLOSE#A%
240 ENDPROC
250 :
260 DEFPROCend:IFnid%:?&D71=nid%
270 PROCoff:*FX4
280 *FX220,27
290 END
300 :
310 DEFPROCon:*FX2,1
320
330
340 ENDPROC
350 :
360 DEFPROCoff:*FX2
370
380
390 ENDPROC
400 :
410 DEFPROCInit:*FX181,1
420 DIM ctrl%31,data%99,ft$(3):X%=ctrl%:Y%=X%DIV256
430 ft$(0)="Program":ft$(1)="Numbers":ft$(2)="Character":ft$(3)="Bytes"
440 out%=0:in%=0:P6502%=FNfx(132,0):IFP6502%<&8000:P6502%=&8000
450 P6502%=(P6502%?6 AND &F)=0
460 nid%=0:A%=FNfx(0,1):IFA%>2 AND A%<6:IFFNfx(130,0)=&FFFF:nid%=?&D71:?&D71=64
470 PRINT'SPC4"f0 to clear, f0+Shift to quit"'SPC3"Cursors send CHR$135 to CHR$139"
480 *FX7,7
490 *FX8,7
500 *FX15
510 *FX220,128
520 *FX4,1
530 *FX3
540 ENDPROC
550 :
560 DEFFNfx(A%,X%):LOCALY%:Y%=X%DIV256:=((USR&FFF4)AND&FFFF00)DIV256
570 DEFFNfile(A$,A%):$data%=A$:?X%=data%:X%?1=data%DIV256:=(USR&FFDD)AND&FF
580 DEFFNh0(A%,N%)=RIGHT$("0000000"+STR$~A%,N%)
590 :
600 DEFFNdo:X%=ctrl%:Y%=X%DIV256:PRINT":";:f$=FNinput:A%=ASCf$
610 I%=INSTR("*CDEHILMRSX",CHR$A%):IFI%>1:PRINTMID$("*CATDIRERASEHELPINFOLOADMKDIRRENAMESAVEEXIT",VALMID$("0102050813172125303640",2*I%-1,2),VALMID$("13354445644",I%,1));
620 IFA%>63:OSCLI"FX2,1":OSCLI"FX3,86":INPUTLINE" "f$:OSCLI"FX3":f$=FNfn_unspec(f$):PRINTf$:*FX2,2
630 I%=INSTR("DEMR",CHR$A%):IFI%:f$=MID$("DIRDELETECDIRRENAME",VALMID$("01041014",2*I%-1,2),VALMID$("3646",I%,1))+" "+f$:A%=ASC"D"
640 IFA%=ASC"*":OSCLI"FX3,3":comm%=TRUE:OSCLIf$:VDU93:comm%=FALSE:OSCLI"FX3":=0
650 IFA%=ASC"D":OSCLIf$:PROCreply(0,"",TRUE):=0
660 IFA%=ASC"C":PROCCat:=0
670 IFA%=ASC"H":PROCreply(0,"Cat Dir Erase Help Info Load Mkdir Rename Save eXit",TRUE):=0
680 IFA%=ASC"I":PROCInfo:=0
690 IFA%=ASC"L":PROCLoad:=0
700 IFA%=ASC"S":PROCSave:=0
710 IFA%=ASC"X":PROCreply(0,"Exiting",TRUE):PRINT'"Exit:":=TRUE
720 PROCreply(254,"Not recognised",TRUE):=0
730 :
740 DEFFNinput:A$="":OSCLI"FX2,2":*FX3,3
750 REPEATREPEAT:A%=INKEY(0):IFA%<>-1:VDUA%
760 UNTILADVAL(-2):OSCLI"FX2,1":A%=GET:*FX2,2
770 IFA%>31 AND A%<127 AND LENA$<250:A$=A$+CHR$A%:IFLENA$>1 OR A$="*":VDUA%
780 IF(A%=127 OR A%=8) AND A$<>"":A$=LEFT$(A$,LENA$-1):VDU8,32,8
790 UNTIL A%=10 OR A%=13 OR (LENA$=1 AND A$<>"*"):IFASCA$=42:PRINT
800 *FX3
810 =A$
820 :
830
840
850
860
870 DEFPROCSave:*FX2,1
880 addr$="":A%=INSTR(f$," "):IF A%:addr$=MID$(f$,A%+1):f$=LEFT$(f$,A%-1)
890 out%=OPENOUT(f$):PROCreply(192,"Can't open "+f$,out%=0):IFout%=0:ENDPROC
900 type%=GET AND 3:length%=GET+256*GET
910 start%=GET+256*GET:prog%=GET+256*GET:autoline%=GET+256*GET
920 REPEAT:PROCPrInfo
930 IF addr$<>"":PRINT "Set addresses to: ";addr$
940 IF addr$<>"":start% =VALaddr$:addr$=MID$(addr$+" ",INSTR(addr$," ")+1)
950 IF addr$<>"":prog% =VALaddr$:addr$=MID$(addr$+" ",INSTR(addr$," ")+1)
960 IF addr$<>"":autoline%=VALaddr$:addr$=MID$(addr$+" ",INSTR(addr$," ")+1)
970 IF addr$<>"":type% =VALaddr$:addr$=MID$(addr$+" ",INSTR(addr$," ")+1)
980 UNTIL addr$=""
990 load%=start%:exec%=prog%:IFtype%=0:load%=autoline%
1000 IFtype%=1 OR type%=2:load%=prog%:exec%=start%
1010 load%=load%+type%*&10000:exec%=exec%+type%*&10000
1020 IFlength%:FORz%=1TOlength%:BPUT#out%,GET:NEXT
1030 CLOSE#out%:out%=0:A%=FNfile(f$,5):X%!2=load%:X%!6=exec%:A%=FNfile(f$,1)
1040 *FX2,2
1050 ENDPROC
1060 :
1070 DEFPROCLoad
1080 fn$=f$:A%=FNfile(f$,5):IF A%=0:PROCTapName:A%=0:IF f$<>fn$:A%=FNfile(f$,5)
1090 load%=X%!2:exec%=X%!6:length%=X%!10:tap%=(load%AND&FFFFFF00)=&FFF11D00
1100 IFA%=1:IFtap%:IFlength%<25:PROCreply(214,fn$+" too short",TRUE):ENDPROC
1110 PROCreply(214,fn$+" not found",A%<>1):IFA%<>1:ENDPROC
1120 type%=(load%AND&30000)DIV&10000
1130 in%=OPENIN(f$):IFtap%:PROCTapInfo
1140 start%=load%AND&FFFF:prog%=exec%AND&FFFF:autoline%=start%
1150 IFtype%=1 OR type%=2:start%=prog%:prog%=autoline%
1160 PROCPrInfo:*FX3,7
1170 VDUtype%,length%;start%;prog%;autoline%;
1180 IFlength%:FORz%=1TOlength%:VDUBGET#in%:NEXT
1190 CLOSE#in%:in%=0:*FX3
1200 ENDPROC
1210 :
1220 DEFPROCPrInfo
1230 PRINT"Type ";type%;" (";ft$(type%);")"
1240 PRINT"Length: &"FNh0(length%,4);SPC8"Start: &"FNh0(start%,4)
1250 PRINT"Program: &"FNh0(prog%,4);SPC5"Autostart: ";autoline%
1260 ENDPROC
1270 :
1280 DEFPROCTapName
1290 A%=LENf$:REPEATA%=A%-1:UNTILA%=0 OR MID$(f$,A%,1)="."
1300 f$=LEFT$(f$,A%)+LEFT$(MID$(f$,A%+1)+"/tap",10)
1310 ENDPROC
1320 :
1330 DEFPROCTapInfo
1340 A%=BGET#in%+BGET#in%+BGET#in%:type%=BGET#in%
1350 FORA%=1TO12:prog%=BGET#in%:NEXT
1360 load%=BGET#in%+256*BGET#in%:exec%=BGET#in%+256*BGET#in%
1370 A%=BGET#in%+BGET#in%+BGET#in%+BGET#in%:length%=EXT#in%-25
1380 ENDPROC
1390 :
1400 DEFPROCCat:*FX3,3
1410 IFf$<>"":f$=" of "+f$
1420 PRINTCHR$0;"Catalog";f$;SPC(25-LEN f$);
1430 X%!9=0:REPEAT
1440 X%!1=data%:X%!5=1:A%=8:CALL&FFD1
1450 IFX%!5=0:?(data%+?data%+1)=13:f$=$(data%+1):PRINTf$;SPC(16-LEN f$);
1460 UNTILX%!5<>0:PRINTCHR$13;:*FX3
1470 ENDPROC
1480 :
1490 DEFPROCInfo
1500 fn$=f$:A%=FNfile(f$,5):IF A%=0:PROCTapName:A%=0:IF f$<>fn$:A%=FNfile(f$,5)
1510 IFA%=0:PROCreply(214,fn$+" not found",TRUE):ENDPROC
1520 start%=X%!2:exec%=X%!6:length%=X%!10:attr%=X%!14
1530 IF(start%AND&FFFFFF00)=&FFF11D00 AND length%>25:in%=OPENIN(f$):PROCTapInfo:CLOSE#in%:in%=0
1540 IFA%=2:PROCreply(0,LEFT$(fn$+STRING$(10," "),10)+" <dir>",TRUE):ENDPROC
1550 PROCreply(0,LEFT$(fn$+STRING$(10," "),10)+" "+FNh0(start%,6)+" "+FNh0(exec%,6)+" "+FNh0(length%,6),TRUE):ENDPROC
1560 ENDPROC
1570 :
1580 DEFPROCreply(err%,A$,F%):IFerr%=13:err%=12
1590 IFF%:IFerr%:PRINT"Error ";A$
1600 *FX3,7
1610 IFF%:PRINTCHR$err%;A$;
1620 PRINTCHR$13;:*FX3
1630 ENDPROC
1640 :
1650 DEFFNerror:LOCAL A%,A$:IFP6502%:A%=1+(!&FD AND &FFFF):A$="":REPEAT:A$=A$+CHR$?A%:A%=A%+1:UNTIL?A%=0:=A$ ELSE =REPORT$
1660 :
1670 DEFPROCSetAddr(A$,ld%,ex%):X%!2=ld%:A%=FNfile(A$,2):X%!6=ex%:A%=FNfile(A$,3):ENDPROC
1680 DEFFNfn_unspec(B$):IF B$="":="_"
1690 LOCALB%,C$:A$="""#$%&:<>*./@[\]^{|}~":C$="'?S;+;()+/.=(/)'(')'"
1700 FOR A%=1 TO LEN B$:B%=INSTR(A$,MID$(B$,A%,1))
1710 IF B%:B$=LEFT$(B$,A%-1)+MID$(C$,B%,1)+MID$(B$,A%+1)
1720 IF MID$(B$,A%,1)<"!" OR MID$(B$,A%,1)>"~":B$=LEFT$(B$,A%-1)+"_"+MID$(B$,A%+1)
1730 NEXT:=B$
1740 DEFPROCDump:*FX2,1
1750 REPEATA%=GET:PRINT" "FNh0(A%,2);:VDU8,8,10:IFA%>31 AND A%<>127:VDUA% ELSE VDU32
1760 VDU11,9,32:IFPOS<1:PRINT
1770 UNTIL0:*FX2
1780 ENDPROC