10
20
30
40
50
60
70
80
90 :
100 bugfix%=FALSE:
110 ON ERROR PROCpr:REPORT:PROCClose_All:PRINT" at line ";ERL:END
120 A$=FNOS_GetEnv:ver$="0.14":debug%=0:PROCInit:A%=FN_DEBUG(STR$debug%)
130 IFbugfix%:IFPAGE>&FFFFF:SYS "GetCommandLine" TO name%:IFINSTR($$name%,"bbcwin.exe")=0:A$="-"
140 IF A$="-":A$=""
150 quiet%=A$<>""
160 IF A$="":PRINT"6502 Emulator v"ver$" (C)2006 J.G.Harston"'"Memory start: &"FNh0(mem%,8)" MemSz: &"FNh0(mz%,6)
170 IF A$="":PRINT"Program space: &"FNh0(mbot%,6)"-&"FNh0(mtop%,6)" ";(mtop%-mbot%);" bytes"'
180 ON ERROR PROCError:A$=""
190 IF A$<>"":A%=FN_RUN(A$)
200 IF run%:PROCGo
210 IF quiet%:A%=FN_QUIT("")
220 ON ERROR PROCError:A$=""
230 quiet%=TRUE:REPEAT INPUT LINE"65Em> "A$:PROCcmd(A$,TRUE):UNTIL0
240 END
250 :
260 DEFPROCInit
270 d$=".":s$="/":IFos%>6:d$="/":s$=".":IFos%=32:d$="\"
280 IFbugfix%:IFPAGE>&FFFFF:run$=@dir$+"*"
290 runpath$=run$:IF LEFT$(runpath$,1)="""":runpath$=MID$(runpath$,2,LEN runpath$-2)
300 REPEAT runpath$=LEFT$(runpath$):UNTIL INSTR(d$+":",RIGHT$(runpath$,1))
310 IFos%=32:mx%=@vdu%!208:my%=@vdu%!212:mw%=@vdu%!216:mh%=@vdu%!220:mc%=@vdu%?73+1
320 mz%=FNmemsize:mm%=mz%-1:mtop%=mz%:mbot%=0:run%=FALSE:trace0%=0:trace1%=&FFFF
330 DIM ctrl% 31,name% 255,mem% mz%:zp%=name%:X%=ctrl%:Y%=X%DIV256
340 ra%=0:rx%=0:ry%=0:rp%=0:rs%=&1FF:rpc%=0
350 osw0%=FALSE:err%=&100:escflg%=&FF:prog%=&F800:iobase%=-1:memmax%=&F800
360
370 OSCLI"Load """+FNf_name(runpath$+"TOS64")+""" "+STR$~(mem%+&F800)
380 A%=mem%!&FFB7 AND &FFFF:FOR B%=0 TO &35:mem%?(B%+&200)=mem%?(A%+B%):NEXT
390 mem%!&F0=&800:mem%!&F4=&8000:mem%?escflg%=0
400 PROCEscInit:ENDPROC
410 :
420 DEFFNmemsize:A%=2^INT(LN(HIMEM-LOMEM-1024)/LN2):IF A%<&10000:=A% ELSE =&10000
430 :
440 DEFPROCError:X%=ctrl%:Y%=X%DIV256:IF INKEY-1:run%=FALSE
450 IF NOTrun%:PROCpr:REPORT:PROCClose_All:PRINTLEFT$(" at line "+STR$ERL,ERR<128 AND ERR<>17):IF INKEY-1:PROCRegDump
460 IF ERR=25:IFrun%:IF os%=32:run%=FALSE:VDU 23,22,mx%;my%;mw%,mh%,mc%,128:run%=TRUE:ENDPROC
470 IF ERR=17:mem%?255=255:rp%=rp%OR(osw0%AND1):osw0%=FALSE:ENDPROC
480 IF run%:mem%!err%=ERR*256:A%=ERR<128 AND ERR<>17:$(mem%+err%+7)=LEFT$("PDPEm: ",A%)+REPORT$+LEFT$(" at line "+STR$ERL,A%AND(ERL>0))+CHR$0:rpc%=err%:IFERR=17:mem%?escflg%=&FF
490 ENDPROC
500 DEFPROCpr:IF?(TOP-3):ENDPROC ELSE PRINT:ENDPROC
510 :
520 DEFPROCcmd(A$,link%):REPEAT:A$=FNs(A$):IFLEFT$(A$,1)="*":A$=MID$(A$,2)
530 UNTIL LEFT$(A$,1)<>"*" AND LEFT$(A$,1)<>" ":reset%=0
540 IF A$=""ORLEFT$(A$,1)="|":ENDPROC
550
560 IF LEFT$(A$,1)=".":OSCLI "."+MID$(A$,2)+LEFT$(LEFT$("\",LENA$>2)+"*.*",os%=32):ENDPROC
570 IF LEFT$(A$,1)="/":A$="RUN "+MID$(A$,2)
580 IF FNuc(LEFT$(A$,2))="FX":IF VALMID$(A$,3) OR (MID$(A$,3,1)="0"):OSCLIA$:ENDPROC
590 A%=INSTR(A$+" "," "):C$=FNuc(LEFT$(A$,A%-1)):T$=MID$(A$,A%+1)
600 A%=INSTR(" BASIC CORE DEBUG GO HELP LOAD MDUMP MDIS MEDIT QUIT RUN RESET SAVE BASE "," "+C$+" ")
610 IF A%:A%=EVAL("FN_"+C$+"(T$)"):ENDPROC
620 A%=FN_run(C$+" "+T$,link%):ENDPROC
630 :
640 DEFFN_HELP(A$):PRINT'"6502 Emulator ";ver$:IF FNuc(A$)<>"6502":=0
650 PRINT" BASIC"'" CORE <core>"'" DEBUG (<value> (<lowaddr> <highaddr>))";CHR$8'" GO (<addr>)"'" HELP"
660 PRINT" LOAD <afsp> <addr>"'" MDUMP <addr>"'" MDIS <addr>"'" QUIT"'" RESET (<afsp>)"'" RUN <afsp>"
670 PRINT" SAVE <fsp> <start> <end>|+<length> (<exec> (<load>))"
680 =0
690 :
700 DEFFN_BASE(A$):iobase%=EVAL("&"+FNuc(A$)):=0
710 :
720 DEFFN_MDIS(A$):LOCAL N%,P%,C%
730 PROCaddrs:P%=start%:N%=16:IF num%<2:size%=256
740 REPEAT:C%=16:REPEATPRINTFNo0(P%,6);" ";:A$=FNdis(P%)
750 FOR A%=0 TO N%-1 STEP 2:PRINTFNo0(mem%!(P%+A%)AND&FFFF,6);" ";:NEXT
760 PRINTSPC(21-3.5*N%);:FOR A%=0 TO N%-1:PRINTFNc(mem%?(P%+A%));:NEXT:PRINTSPC(7-N%);A$
770 P%=(P%+N%)AND&FFFF:C%=C%-1:size%=size%-N%:UNTIL C%=0 OR size%<0:IF size%>0:A%=GET ELSE A%=0
780 UNTIL A%=27 OR size%<0:=0
790 :
800 DEFFN_MDUMP(A$):LOCAL N%,P%,C%
810 PROCaddrs:P%=start%:N%=16:IF num%<2:size%=256
820 REPEAT:C%=16:REPEATPRINTFNh0(P%,4);" ";
830 FOR A%=0 TO N%-1:PRINTFNh0(mem%?(P%+A%),2);" ";:NEXT
840 FOR A%=0 TO N%-1:PRINTFNc(mem%?(P%+A%));:NEXT:PRINT
850 P%=(P%+N%)AND&FFFF:C%=C%-1:size%=size%-N%:UNTIL C%=0 OR size%<0:IF size%>0:A%=GET ELSE A%=0
860 UNTIL A%=27 OR size%<0:=0
870 :
880 DEFFN_MEDIT(A$):=0
890 :
900 DEFFN_SAVE(A$)
910 PROCfname:PROCaddrs
920 IF num%<2:ERROR 252,"Bad address"
930 IF start%>=0:start%=mem%+(start%ANDmm%)
940 OSCLI "SAVE """+FNf_name(F$)+""" "+STR$~start%+"+"+STR$~size%+" "+STR$~exec%+" "+STR$~load%
950 =0
960 :
970 DEFFN_LOAD(A$)
980 PROCfname:PROCaddrs:IF num%=0:load%=-1
990 =FN_load(F$,load%,TRUE)
1000 :
1010 DEFFN_QUIT(A$):IF VAL A$:halt%=TRUE:=0
1020 PROCClose_All:
1030 OSCLI"QUIT":=0
1040 :
1050 DEFFN_BASIC(A$):
1060 PRINT"BASIC"':=FN_RUN(""""+runpath$+FNf_name("Basic")+"""")
1070 :
1080 DEFFN_RESET(A$):CLS:A%=-1
1090
1100
1110
1120
1130 PRINT'"6502 Tube Emulator":IF A$<>"":A%=FN_load(A$,-1,TRUE)
1140
1150
1160 PRINT'"Econet Station 128"':IF A%<0:=0
1170 hdr%=mem%+A%:IF hdr%!(hdr%?7)=&29432800:B%=hdr%+9:REPEATVDU?B%:B%=B%+1:UNTIL?B%=0
1180 IF hdr%-mem%=0:VDU11,11
1190 PRINT':F$="":rp%=0:=FN_go
1200 :
1210 DEFFN_load(RETURN F$,A%,F%)
1220 in%=0:size%=0:IF A%=-1 THEN
1230 in%=FNf_openin(F$):IF in%=0:IF F%:F$=F$+s$:in%=FNf_openin(F$)
1240 IF in% THEN
1250 size%=EXT#in%:PROCgbpb(4,in%,hdr%,256,0)
1260 IF hdr%!(hdr%?7)=&29432800 AND (hdr%?6 AND 32)<>0 THEN
1270 A%=hdr%?7:REPEATA%=A%+1:UNTILhdr%?A%=0:A%=hdr%!(A%+1)
1280 ELSE
1290 IF A%<0:IF PAGE<&FFFFF:SYS"XOS_File",5,F$,-1 TO ,,A%
1300 ENDIF
1310 ELSE
1320 A%=-2:
1330 ENDIF
1340 ENDIF
1350
1360
1370
1380 IF in%:IF F% OR A%=-1:CLOSE#in%:in%=0
1390 IF A%=-2:IF F%:ERROR 214,"File not found"
1400 IF A%=-1 OR (A%+size%>mm%):ERROR 252,"Bad address"
1410 IF F%:OSCLI"Load """+FNf_name(F$)+""" "+STR$~(mem%+A%)
1420 =A%
1430 :
1440 DEFPROCsyscmd(cli$):IF os%<>32:OSCLI cli$:ENDPROC
1450 LOCAL ch%,err$,tmp$:tmp$=@tmp$+STR$TIME+"."
1460 LOCAL ERROR:ON ERROR LOCAL:RESTORE ERROR:IF ERR=214:OSCLI cli$:ENDPROC ELSE ERROR ERR,REPORT$:ENDPROC
1470 OSCLI cli$+" 2>"+tmp$:ch%=OPENIN(tmp$):IF ch%=0:ENDPROC
1480 err$=GET$#ch%:CLOSE#ch%:OSCLI"Delete "+tmp$:IF RIGHT$(err$,1)=",":RIGHT$(err$,1)="."
1490 ERROR 254,err$:ENDPROC
1500 :
1510 DEFFN_RUN(A$)
1520 IF PAGE<&FFFFF:SYS"XOS_File",5,A$ TO ,,A%:A%=A%AND&FFF00:IF A%=&FFB00=FN_BASIC(A$)
1530 IF PAGE<&FFFFF:IF A%=&BBC00:A%=&8000
1540 =FN_run(A$,FALSE)
1550 DEFFN_run(A$,osc%):A$=FNs(A$):IF A$="":=0
1560 C$=A$:PROCfname:hdr%=zp%:A%=FN_load(F$,-1,FALSE):IF A%<0:IF osc%:PROCsyscmd(C$):=0
1570 IF A%=-2:ERROR 214,"File not found"
1580 rp%=1:=FN_go
1590 DEFFN_go
1600
1610
1620
1630
1640
1650 membot%=&800:err%=&100:escflg%=&FF:B%=A%
1660 IF hdr%!(hdr%?7)=&29432800 THEN
1670
1680 IF (hdr%?6 AND 64)=0 :CLOSE#in%:in%=0:ERROR 249,"Not a language":=0
1690 IF (hdr%?6 AND 15)>3:CLOSE#in%:in%=0:ERROR 249,"Not 6502 code":=0
1700 IF (hdr%?6 AND 32)<>0:B%=hdr%?7:REPEATB%=B%+1:UNTILhdr%?B%=0:B%=A%+hdr%!(B%+5)
1710 ENDIF
1720 prog%=A%:IF prog%<&8000:memtop%=memmax% ELSE memtop%=prog%
1730 load%=A%:rpc%=A%:IFin%:CLOSE#in%:in%=0
1740 PROCGo:=0
1750 :
1760 DEFFN_GO(A$):IF A$="":=0
1770 A%=INSTR(A$,";"):rpc%=FNhex(A$):IF A%:A$=MID$(A$,A%+1) ELSE A$=""
1780 F$="":A%=rpc%:hdr%=mem%+A%:rp%=1:=FN_go
1790 :
1800 DEFFN_CORE(A$):
1810 A$=FNf_name(FNs(LEFT$(A$,INSTR(A$+" "," ")-1))):IFA$="":A$="core"
1820 OSCLI"Save "+A$+" "+STR$~mem%+"+"+STR$~mz%
1830 PROCSetType(A$,&FFD)
1840 =0
1850 :
1860 DEFFN_DEBUG(A$):IFA$="":PRINT"1=Register Dump"'"3=Single Step":=0
1870 debug%=0:trace0%=0:trace1%=&FFFF:IF FNuc(A$)="OFF":=0
1880 debug%=EVAL(A$):IF(debug%AND1):IF VPOS<9:REPEAT PRINT:UNTIL VPOS>8
1890 A%=INSTR(A$," "):IF A%:trace0%=FNhex(MID$(A$,A%+1)):A$=MID$(A$,A%+1)
1900 A%=INSTR(A$," "):IF A%:trace1%=FNhex(MID$(A$,A%+1))
1910 =0
1920 :
1930 DEFPROCSetType(A$,A%):IF os%>8:ENDPROC
1940 OSCLI"SetType "+A$+" "+STR$~A%
1950 ENDPROC
1960 :
1970 DEFFNhex(A$)
1980 IFFNuc(LEFT$(A$,2))="&O":=EVAL("&"+FNh0(FNoct(MID$(A$,3)),8)) ELSE =EVAL("&"+FNuc(A$))
1990 DEFFNoct(A$):LOCAL A%:REPEAT
2000 IF A$>"/" AND A$<":":A%=A%*8+VAL LEFT$(A$,1):A$=MID$(A$,2)
2010 UNTIL NOT(A$>"/" AND A$<":"):=A%
2020 :
2030 DEFPROCfname
2040 IFLEFT$(A$,1)="""":A%=INSTR(A$+"""","""",2):F$=MID$(A$,2,A%-2) ELSE A%=INSTR(A$+" "," "):F$=LEFT$(A$,A%-1)
2050 A$=FNs(MID$(A$,A%+1)):ENDPROC
2060 :
2070 DEFPROCaddrs
2080 num%=0:start%=0:size%=0:load%=0:exec%=0
2090 A$=FNs(A$):IF A$="":ENDPROC
2100 num%=INSTR(A$,"+"):IF num%=0:num%=INSTR(A$+" "," ")
2110 start%=FNhex(LEFT$(A$,num%-1)):load%=start%:exec%=load%:A$=FNs(MID$(A$,num%)):num%=1:IF A$="":ENDPROC
2120 IF LEFT$(A$,1)="+":size%=0:A$=FNs(MID$(A$,2)) ELSE size%=start%
2130 num%=INSTR(A$+" "," "):size%=FNhex(LEFT$(A$,num%-1))-size%:A$=FNs(MID$(A$,num%+1)):num%=2:IF A$="":ENDPROC
2140 num%=INSTR(A$+" "," "):exec%=FNhex(LEFT$(A$,num%-1)):A$=FNs(MID$(A$,num%+1)):num%=3:IF A$="":ENDPROC
2150 num%=INSTR(A$+" "," "):load%=FNhex(LEFT$(A$,num%-1)):A$=FNs(MID$(A$,num%+1)):num%=4
2160 ENDPROC
2170 :
2180 DEFPROCRegDump:PRINT"A=&"FNh0(ra%,2)" X=&"FNh0(rx%,2)" Y=&"FNh0(ry%,2)" P=&"FNh0(rp%,2);" ";
2190 FOR A%=7 TO 0 STEP -1:PRINTMID$("-CZIDB5VN",(((rp%AND(2^A%))<>0)AND(A%+1))+1,1);:NEXT:PRINT" "
2200 PRINT "XY=&";:PROCDumpLine(rx%+256*ry%):PRINT
2210 PRINT " S=&";:PROCDumpLine(rs%):PRINT
2220 PRINT "PC=&";:PROCDumpLine(rpc%)
2230 A%=FNDis_Code(65,rpc%,mem%+rpc%):PRINT$(X%+4);SPC(56-POS)
2240
2250
2260
2270
2280
2290 ENDPROC
2300 :
2310 DEFPROCDumpLine(m%):PRINT FNh0(m%,4)" ";
2320 FOR B%=m% TO m%+7:PRINT FNc(mem%?B%);:NEXT:VDU32
2330 FOR B%=m% TO m%+7:PRINT FNh0(mem%?(B%ANDmm%)AND&FF,2)" ";:NEXT
2340 ENDPROC
2350 :
2360 DEFFNdis(A%):N%=FNDis_Code(65,A%,mem%+(A%ANDmm%)):=$(X%+4)
2370 :
2380 DEFFNc(A%):A%=A%AND255:IF A%<32 OR A%>126:="." ELSE =CHR$ A%
2390 :
2400 DEFPROCEscInit:esch%=esch%:IFesch%:ENDPROC
2410 IFos%=32 THEN
2420 DIM P% 36, L% -1:[OPT 8:.escyes:mov byte [edi-1],0:mov eax,-1:ret
2430 .esch%:mov ecx,256:mov edi,[@vdu%-148]:mov al,27:cld
2440 repnz scasb:jz escyes:xor eax,eax:ret:.escb%:dw 0:dw 0:]:ENDPROC
2450 ENDIF
2460 DIM esch% 31:FOR P=0 TO 1:P%=esch%:[OPT P*2:MOV R11,R11,LSL #1
2470 LDR R12,escb%:STRB R11,[R12]:MOV PC,R14:.escb%:EQUD mem%+escflg%:]:NEXT:escho%=0:ENDPROC
2480 DEFPROCEscOff:escho%=escho%:IFescho%:ENDPROC
2490 IFos%<>32:SYS "OS_ChangeEnvironment",9,esch%,0,0 TO ,escho%,escRo%,escbo%:ENDPROC
2500 OSCLI"ESC OFF":escho%=TRUE:ON TIME IFUSResch%:mem%?escflg%=&FF:RETURN ELSE RETURN
2510 ENDPROC
2520 DEFPROCEscOn:escho%=escho%:IFescho%=0:ENDPROC
2530 IFos%<>32:SYS "OS_ChangeEnvironment",9,escho%,escRo%,escbo%:escho%=0:ENDPROC
2540 ON TIME OFF:escho%=0:OSCLI"ESC ON":ENDPROC
2550 :