10 REM > Startup
   20 REM 6502 Tube Emulator written in BASIC
   30 REM v0.10 Initial program based on PDP11Em
   40 REM v0.11 &x3 opcodes interface with host
   50 REM v0.12 Uses runpath for resources
   60 REM v0.13 Updated with same base code as PDPTube
   70 REM v0.14 Added more updates from PDPTube
   80 :
   90 bugfix%=FALSE:REM Error in OS_GetEnv
  100 ON ERROR PROCpr:REPORT:PROCClose_All:PRINT" at line ";ERL:END
  110 A$=FNOS_GetEnv:ver$="0.14":debug%=0:PROCInit:A%=FN_DEBUG(STR$debug%)
  120 IFbugfix%:IFPAGE>&FFFFF:SYS "GetCommandLine" TO name%:IFINSTR($$name%,"bbcwin.exe")=0:A$="-"
  130 IF A$="-":A$=""
  140 quiet%=A$<>""
  150 IF A$="":PRINT"6502 Emulator v"ver$" (C)2006 J.G.Harston"'"Memory start:  &"FNh0(mem%,8)" MemSz: &"FNh0(mz%,6)" MemMsk: &"FNh0(mm%,6)
  160 IF A$="":PRINT"Program space: &"FNh0(mbot%,6)"-&"FNh0(mtop%,6)"  ";(mtop%-mbot%);" bytes"'
  170 ON ERROR PROCError:A$=""
  180 IF A$<>"":A%=FN_RUN(A$)
  190 IF run%:PROCGo
  200 IF quiet%:A%=FN_QUIT("")
  210 ON ERROR PROCError:A$=""
  220 quiet%=TRUE:REPEAT INPUT LINE"65Em> "A$:PROCcmd(A$,TRUE):UNTIL0
  230 END
  240 :
  250 DEFPROCInit
  260 d$=".":s$="/":IFos%>6:d$="/":s$=".":IFos%=32:d$="\"
  270 IFbugfix%:IFPAGE>&FFFFF:run$=@dir$+"*"
  280 runpath$=run$:IF LEFT$(runpath$,1)="""":runpath$=MID$(runpath$,2,LEN runpath$-2)
  290 REPEAT runpath$=LEFT$(runpath$):UNTIL INSTR(d$+":",RIGHT$(runpath$,1))
  300 IFos%=32:mx%=@vdu%!208:my%=@vdu%!212:mw%=@vdu%!216:mh%=@vdu%!220:mc%=@vdu%?73+1
  310 mz%=FNmemsize:mm%=mz%-1:mtop%=mz%:mbot%=0:run%=FALSE:trace0%=0:trace1%=&FFFF
  320 DIM ctrl% 31,name% 255,mem% mz%:zp%=name%:X%=ctrl%:Y%=X%DIV256
  330 ra%=0:rx%=0:ry%=0:rp%=0:rs%=&1FF:rpc%=0
  340 osw0%=FALSE:err%=&100:escflg%=&FF:prog%=&F800
  350 REM Initial state:
  360 OSCLI"Load """+FNf_name(runpath$+"TOS64")+""" "+STR$~(mem%+&F800)
  370 A%=mem%!&FFB7 AND &FFFF:FOR B%=0 TO &35:mem%?(B%+&200)=mem%?(A%+B%):NEXT
  380 mem%!&F0=&800:mem%!&F4=&8000:mem%?escflg%=0
  390 PROCEscInit:ENDPROC
  400 :
  410 DEFFNmemsize:A%=2^INT(LN(HIMEM-LOMEM-1024)/LN2):IF A%<&10000:=A% ELSE =&10000
  420 :
  430 DEFPROCError:X%=ctrl%:Y%=X%DIV256:IF INKEY-1:run%=FALSE
  440 IF NOTrun%:PROCpr:REPORT:PROCClose_All:PRINTLEFT$(" at line "+STR$ERL,ERR<128 AND ERR<>17):IF INKEY-1:PROCRegDump
  450 IF ERR=25:IFrun%:IF os%=32:run%=FALSE:VDU 23,22,mx%;my%;mw%,mh%,mc%,128:run%=TRUE:ENDPROC
  460 IF ERR=17:mem%?255=255:rp%=rp%OR(osw0%AND1):osw0%=FALSE:ENDPROC
  470 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
  480 ENDPROC
  490 DEFPROCpr:IF?(TOP-3):ENDPROC ELSE PRINT:ENDPROC
  500 :
  510 DEFPROCcmd(A$,link%):REPEAT:A$=FNs(A$):IFLEFT$(A$,1)="*":A$=MID$(A$,2)
  520 UNTIL LEFT$(A$,1)<>"*" AND LEFT$(A$,1)<>" ":reset%=0
  530 IF A$=""ORLEFT$(A$,1)="|":ENDPROC
  540 REM IF LEFT$(A$,1)="*":OSCLI MID$(A$,2):ENDPROC
  550 IF LEFT$(A$,1)=".":OSCLI "."+MID$(A$,2)+LEFT$(LEFT$("\",LENA$>2)+"*.*",os%=32):ENDPROC
  560 IF LEFT$(A$,1)="/":A$="RUN "+MID$(A$,2)
  570 IF FNuc(LEFT$(A$,2))="FX":IF VALMID$(A$,3) OR (MID$(A$,3,1)="0"):OSCLIA$:ENDPROC
  580 A%=INSTR(A$+" "," "):C$=FNuc(LEFT$(A$,A%-1)):T$=MID$(A$,A%+1)
  590 A%=INSTR(" BASIC CORE DEBUG GO HELP LOAD MDUMP MDIS MEDIT QUIT RUN RESET SAVE "," "+C$+" ")
  600 IF A%:A%=EVAL("FN_"+C$+"(T$)"):ENDPROC
  610 A%=FN_run(C$+" "+T$,link%):ENDPROC
  620 :
  630 DEFFN_HELP(A$):PRINT'"6502 Emulator ";ver$:IF FNuc(A$)<>"6502":=0
  640 PRINT"  BASIC"'"  CORE  <core>"'"  DEBUG (<value> (<lowaddr> <highaddr>))";CHR$8'"  GO    (<addr>)"'"  HELP"
  650 PRINT"  LOAD  <afsp> <addr>"'"  MDUMP <addr>"'"  MDIS  <addr>"'"  QUIT"'"  RESET (<afsp>)"'"  RUN   <afsp>"
  660 PRINT"  SAVE  <fsp> <start> <end>|+<length> (<exec> (<load>))"
  670 =0
  680 :
  690 DEFFN_MDIS(A$):LOCAL N%,P%,C%
  700 PROCaddrs:P%=start%:N%=16:IF num%<2:size%=256
  710 REPEAT:C%=16:REPEATPRINTFNo0(P%,6);" ";:A$=FNdis(P%)
  720     FOR A%=0 TO N%-1 STEP 2:PRINTFNo0(mem%!(P%+A%)AND&FFFF,6);" ";:NEXT
  730     PRINTSPC(21-3.5*N%);:FOR A%=0 TO N%-1:PRINTFNc(mem%?(P%+A%));:NEXT:PRINTSPC(7-N%);A$
  740   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
  750 UNTIL A%=27 OR size%<0:=0
  760 :
  770 DEFFN_MDUMP(A$):LOCAL N%,P%,C%
  780 PROCaddrs:P%=start%:N%=16:IF num%<2:size%=256
  790 REPEAT:C%=16:REPEATPRINTFNh0(P%,4);" ";
  800     FOR A%=0 TO N%-1:PRINTFNh0(mem%?(P%+A%),2);" ";:NEXT
  810     FOR A%=0 TO N%-1:PRINTFNc(mem%?(P%+A%));:NEXT:PRINT
  820   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
  830 UNTIL A%=27 OR size%<0:=0
  840 :
  850 DEFFN_MEDIT(A$):=0
  860 :
  870 DEFFN_SAVE(A$)
  880 PROCfname:PROCaddrs
  890 IF num%<2:ERROR 252,"Bad address"
  900 IF start%>=0:start%=mem%+(start%ANDmm%)
  910 OSCLI "SAVE """+FNf_name(F$)+""" "+STR$~start%+"+"+STR$~size%+" "+STR$~exec%+" "+STR$~load%
  920 =0
  930 :
  940 DEFFN_LOAD(A$)
  950 PROCfname:PROCaddrs:IF num%=0:load%=-1
  960 =FN_load(F$,load%,TRUE)
  970 :
  980 DEFFN_QUIT(A$):IF VAL A$:halt%=TRUE:=0
  990 PROCClose_All:REM IF os%=32:PRINT"Press SPACE to exit";:A%=GET
 1000 OSCLI"QUIT":=0
 1010 :
 1020 DEFFN_BASIC(A$):REM =FN_RUN("<65Tube$Basic> "+A$)
 1030 PRINT"BASIC"':=FN_RUN(""""+runpath$+FNf_name("Basic")+"""")
 1040 :
 1050 DEFFN_RESET(A$):CLS:A%=-1
 1060 REM IF FNuc(A$)="TUBE":IF client$<>"":OSCLI"Load """+client$+""" "+STR$~(mem%+&F800):memmax%=&F500:A$=""
 1070 REM IF memmax%<&F800 THEN
 1080 REM PRINT'$(mem%+&F805):A%=mem%!&F5FC AND &FFFF
 1090 REM ELSE
 1100 PRINT'"6502 Tube Emulator":IF A$<>"":A%=FN_load(A$,-1,TRUE)
 1110 REM ENDIF
 1120 REM IF FNuc(A$)="NOTUBE":memmax%=&FF00:A$=""
 1130 PRINT'"Econet Station 128"':IF A%<0:=0
 1140 hdr%=mem%+A%:IF hdr%!(hdr%?7)=&29432800:B%=hdr%+9:REPEATVDU?B%:B%=B%+1:UNTIL?B%=0
 1150 IF hdr%-mem%=0:VDU11,11
 1160 PRINT':F$="":rp%=0:=FN_go
 1170 :
 1180 DEFFN_load(RETURN F$,A%,F%)
 1190 in%=0:size%=0:IF A%=-1 THEN
 1200   in%=FNf_openin(F$):IF in%=0:IF F%:F$=F$+s$:in%=FNf_openin(F$)
 1210   IF in% THEN
 1220     size%=EXT#in%:PROCgbpb(4,in%,hdr%,256,0)
 1230     IF hdr%!(hdr%?7)=&29432800 AND (hdr%?6 AND 32)<>0 THEN
 1240       A%=hdr%?7:REPEATA%=A%+1:UNTILhdr%?A%=0:A%=hdr%!(A%+1)
 1250     ELSE
 1260       IF A%<0:IF PAGE<&FFFFF:SYS"XOS_File",5,F$,-1 TO ,,A%
 1270     ENDIF
 1280   ELSE
 1290     A%=-2:REM Not found
 1300   ENDIF
 1310 ENDIF
 1320 REM IF A%<0:IF F%:IF in%=0:ERROR 214,"File not found"
 1330 REM IF A%<0 OR F%:IF in%:CLOSE#in%:in%=0
 1340 REM IF A%<0:IF F%:ERROR 252,"Bad address"
 1350 IF in%:IF F% OR A%=-1:CLOSE#in%:in%=0
 1360 IF A%=-2:IF F%:ERROR 214,"File not found"
 1370 IF A%=-1 OR (A%+size%>mm%):ERROR 252,"Bad address"
 1380 IF F%:OSCLI"Load """+FNf_name(F$)+""" "+STR$~(mem%+A%)
 1390 =A%
 1400 :
 1410 DEFPROCsyscmd(cli$):IF os%<>32:OSCLI cli$:ENDPROC
 1420 LOCAL ch%,err$,tmp$:tmp$=@tmp$+STR$TIME+"."
 1430 LOCAL ERROR:ON ERROR LOCAL:RESTORE ERROR:IF ERR=214:OSCLI cli$:ENDPROC ELSE ERROR ERR,REPORT$:ENDPROC
 1440 OSCLI cli$+" 2>"+tmp$:ch%=OPENIN(tmp$):IF ch%=0:ENDPROC
 1450 err$=GET$#ch%:CLOSE#ch%:OSCLI"Delete "+tmp$:IF RIGHT$(err$,1)=",":RIGHT$(err$,1)="."
 1460 ERROR 254,err$:ENDPROC
 1470 :
 1480 DEFFN_RUN(A$)
 1490 IF PAGE<&FFFFF:SYS"XOS_File",5,A$ TO ,,A%:A%=A%AND&FFF00:IF A%=&FFB00=FN_BASIC(A$)
 1500 IF PAGE<&FFFFF:IF A%=&BBC00:A%=&8000
 1510 =FN_run(A$,FALSE)
 1520 DEFFN_run(A$,osc%):A$=FNs(A$):IF A$="":=0
 1530 C$=A$:PROCfname:hdr%=zp%:A%=FN_load(F$,-1,FALSE):IF A%<0:IF osc%:PROCsyscmd(C$):=0
 1540 IF A%=-2:ERROR 214,"File not found"
 1550 rp%=1:=FN_go
 1560 DEFFN_go
 1570 REM A%  = entry address as 6502 address
 1580 REM hdr%=>Acorn ROM header in mem%+A% address
 1590 REM in% =open file being loaded
 1600 REM F$  =file being loaded or "" if already in memory
 1610 membot%=base%:err%=memmax%:escflg%=err%+255:B%=A%
 1620 IF hdr%!(hdr%?7)=&29432800 THEN
 1630   REM Acorn ROM header
 1640   IF (hdr%?6 AND 64)=0 :CLOSE#in%:in%=0:ERROR 249,"Not a language":=0
 1650   IF (hdr%?6 AND 15)>3:CLOSE#in%:in%=0:ERROR 249,"Not 6502 code":=0
 1660   IF (hdr%?6 AND 32)<>0:B%=hdr%?7:REPEATB%=B%+1:UNTILhdr%?B%=0:B%=A%+hdr%!(B%+5)
 1670 ENDIF
 1680 prog%=A%:IF prog%<&8000:memtop%=memmax% ELSE memtop%=prog%
 1690 load%=A%:rpc%=A%:IFin%:CLOSE#in%:in%=0
 1700 PROCGo:=0
 1710 :
 1720 DEFFN_GO(A$):IF A$="":=0
 1730 A%=INSTR(A$,";"):rpc%=FNhex(A$):IF A%:A$=MID$(A$,A%+1) ELSE A$=""
 1740 F$="":A%=rpc%:hdr%=mem%+A%:rp%=1:=FN_go
 1750 :
 1760 DEFFN_CORE(A$):REM Dump core
 1770 A$=FNf_name(FNs(LEFT$(A$,INSTR(A$+" "," ")-1))):IFA$="":A$="core"
 1780 OSCLI"Save "+A$+" "+STR$~mem%+"+"+STR$~mz%
 1790 PROCSetType(A$,&FFD)
 1800 =0
 1810 :
 1820 DEFFN_DEBUG(A$):IFA$="":PRINT"1=Register Dump"'"3=Single Step":=0
 1830 debug%=0:trace0%=0:trace1%=&FFFF:IF FNuc(A$)="OFF":=0
 1840 debug%=EVAL(A$):IF(debug%AND1):IF VPOS<9:REPEAT PRINT:UNTIL VPOS>8
 1850 A%=INSTR(A$," "):IF A%:trace0%=FNhex(MID$(A$,A%+1)):A$=MID$(A$,A%+1)
 1860 A%=INSTR(A$," "):IF A%:trace1%=FNhex(MID$(A$,A%+1))
 1870 =0
 1880 :
 1890 DEFPROCSetType(A$,A%):IF os%>8:ENDPROC
 1900 OSCLI"SetType "+A$+" "+STR$~A%
 1910 ENDPROC
 1920 :
 1930 DEFFNhex(A$)
 1940 IFFNuc(LEFT$(A$,2))="&O":=EVAL("&"+FNh0(FNoct(MID$(A$,3)),8)) ELSE =EVAL("&"+FNuc(A$))
 1950 DEFFNoct(A$):LOCAL A%:REPEAT
 1960   IF A$>"/" AND A$<":":A%=A%*8+VAL LEFT$(A$,1):A$=MID$(A$,2)
 1970 UNTIL NOT(A$>"/" AND A$<":"):=A%
 1980 :
 1990 DEFPROCfname
 2000 IFLEFT$(A$,1)="""":A%=INSTR(A$+"""","""",2):F$=MID$(A$,2,A%-2) ELSE A%=INSTR(A$+" "," "):F$=LEFT$(A$,A%-1)
 2010 A$=FNs(MID$(A$,A%+1)):ENDPROC
 2020 :
 2030 DEFPROCaddrs
 2040 num%=0:start%=0:size%=0:load%=0:exec%=0
 2050 A$=FNs(A$):IF A$="":ENDPROC
 2060 num%=INSTR(A$,"+"):IF num%=0:num%=INSTR(A$+" "," ")
 2070 start%=FNhex(LEFT$(A$,num%-1)):load%=start%:exec%=load%:A$=FNs(MID$(A$,num%)):num%=1:IF A$="":ENDPROC
 2080 IF LEFT$(A$,1)="+":size%=0:A$=FNs(MID$(A$,2)) ELSE size%=start%
 2090 num%=INSTR(A$+" "," "):size%=FNhex(LEFT$(A$,num%-1))-size%:A$=FNs(MID$(A$,num%+1)):num%=2:IF A$="":ENDPROC
 2100 num%=INSTR(A$+" "," "):exec%=FNhex(LEFT$(A$,num%-1)):A$=FNs(MID$(A$,num%+1)):num%=3:IF A$="":ENDPROC
 2110 num%=INSTR(A$+" "," "):load%=FNhex(LEFT$(A$,num%-1)):A$=FNs(MID$(A$,num%+1)):num%=4
 2120 ENDPROC
 2130 :
 2140 DEFPROCRegDump:PRINT"A=&"FNh0(ra%,2)" X=&"FNh0(rx%,2)" Y=&"FNh0(ry%,2)" P=&"FNh0(rp%,2);" ";
 2150 FOR A%=7 TO 0 STEP -1:PRINTMID$("-CZIDB5VN",(((rp%AND(2^A%))<>0)AND(A%+1))+1,1);:NEXT:PRINT"  "
 2160 PRINT "XY=&";:PROCDumpLine(rx%+256*ry%):PRINT
 2170 PRINT " S=&";:PROCDumpLine(rs%):PRINT
 2180 PRINT "PC=&";:PROCDumpLine(rpc%)
 2190 A%=FNDis_Code(65,rpc%,mem%+rpc%):PRINT$(X%+4);SPC(56-POS)
 2200 REM PRINT "2A=&";:PROCDumpLine(mem%!&2A AND&FFFF):PRINT
 2210 REM PRINT "0B=&";:PROCDumpLine(mem%!&0B AND&FFFF):PRINT
 2220 REM PRINT "39=&";:PROCDumpLine(mem%!&39 AND&FFFF):PRINT
 2230 REM PRINT "19=&";:PROCDumpLine(mem%!&19 AND&FFFF):PRINT
 2240 REM PRINT "15=&";FNh0(mem%?&15,2)
 2250 ENDPROC
 2260 :
 2270 DEFPROCDumpLine(m%):PRINT FNh0(m%,4)" ";
 2280 FOR B%=m% TO m%+7:PRINT FNc(mem%?B%);:NEXT:VDU32
 2290 FOR B%=m% TO m%+7:PRINT FNh0(mem%?(B%ANDmm%)AND&FF,2)" ";:NEXT
 2300 ENDPROC
 2310 :
 2320 DEFFNdis(A%):N%=FNDis_Code(65,A%,mem%+(A%ANDmm%)):=$(X%+4)
 2330 :
 2340 DEFFNc(A%):A%=A%AND255:IF A%<32 OR A%>126:="." ELSE =CHR$ A%
 2350 :
 2360 DEFPROCEscInit:esch%=esch%:IFesch%:ENDPROC
 2370 IFos%=32 THEN
 2380   DIM P% 36, L% -1:[OPT 8:.escyes:mov byte [edi-1],0:mov eax,-1:ret
 2390   .esch%:mov ecx,256:mov edi,[@vdu%-148]:mov al,27:cld
 2400   repnz scasb:jz escyes:xor eax,eax:ret:.escb%:dw 0:dw 0:]:ENDPROC
 2410 ENDIF
 2420 DIM esch% 31:FOR P=0 TO 1:P%=esch%:[OPT P*2:MOV R11,R11,LSL #1
 2430 LDR R12,escb%:STRB R11,[R12]:MOV PC,R14:.escb%:EQUD mem%+escflg%:]:NEXT:escho%=0:ENDPROC
 2440 DEFPROCEscOff:escho%=escho%:IFescho%:ENDPROC
 2450 IFos%<>32:SYS "OS_ChangeEnvironment",9,esch%,0,0 TO ,escho%,escRo%,escbo%:ENDPROC
 2460 OSCLI"ESC OFF":escho%=TRUE:ON TIME IFUSResch%:mem%?escflg%=&FF:RETURN ELSE RETURN
 2470 ENDPROC
 2480 DEFPROCEscOn:escho%=escho%:IFescho%=0:ENDPROC
 2490 IFos%<>32:SYS "OS_ChangeEnvironment",9,escho%,escRo%,escbo%:escho%=0:ENDPROC
 2500 ON TIME OFF:escho%=0:OSCLI"ESC ON":ENDPROC
 2510 :
   10 REM > 6502
   20 :
   30 DEFPROCGo:abort%=FALSE:halt%=0:run%=TRUE:PROCEscOff
   40 REPEAT:IF(debug%AND1):IF rpc%>=trace0% AND rpc%<=trace1%:x%=POS:y%=VPOS:VDU30:PROCRegDump:VDU31,x%,y%:IF(debug%AND2):IF GET
   50 B%=mem%?rpc%:rpc%=rpc%+1:UNTIL EVAL("FNm"+STR$~(B%AND&1C)+"+FN_"+STR$~(B%AND(((B%AND1)<>1)OR&E3))):PROCEscOn:run%=FALSE:IF NOTquiet% OR abort%:PROCRegDump
   60 ENDPROC
   70 :
   80 :
   90 DEFFNbr(A%):rpc%=rpc%+1:IFA%=0:=0
  100 IFmem%?(rpc%-1)<128:rpc%=(rpc%+mem%?(rpc%-1))AND&FFFF:=0
  110 rpc%=(rpc%+mem%?(rpc%-1)-256)AND&FFFF:=0
  120 :
  130 :
  140 DEFFNm0 :A%=(mem%!((mem%?rpc%+rx%)AND&FF))AND&FFFF:=0     :REM (zp,X)
  150 DEFFNm4 :A%=mem%?rpc%:=0                                  :REM zp
  160 DEFFNm8 :A%=rpc%:=0                                       :REM #n
  170 DEFFNmC :A%=(mem%!rpc%)AND&FFFF:rpc%=rpc%+1:=0            :REM abs
  180 DEFFNm10:A%=(mem%!(mem%?rpc%)+ry%)AND&FFFF:=0             :REM (zp),Y
  190 DEFFNm12:A%=(mem%!(mem%?rpc%))AND&FFFF:=0                 :REM (zp)
  200 DEFFNm14:A%=(mem%?rpc%+rx%)AND&FF:=0                      :REM zp,X
  210 DEFFNm18:A%=(mem%!rpc%+ry%)AND&FFFF:rpc%=rpc%+(B%AND1):=0 :REM abs,Y
  220 DEFFNm1C:A%=(mem%!rpc%+rx%)AND&FFFF:rpc%=rpc%+1:=0        :REM abs,X
  230 :
  240 :
  250 DEFFN_1 :ra%=ra%ORmem%?A%:rp%=(rp%AND&7D)OR(ra%AND128)OR((ra%=0)AND2):rpc%=rpc%+1:=0 :REM ORA
  260 DEFFN_21:ra%=ra%ANDmem%?A%:rp%=(rp%AND&7D)OR(ra%AND128)OR((ra%=0)AND2):rpc%=rpc%+1:=0:REM AND
  270 DEFFN_41:ra%=ra%EORmem%?A%:rp%=(rp%AND&7D)OR(ra%AND128)OR((ra%=0)AND2):rpc%=rpc%+1:=0:REM EOR
  280 DEFFN_61:ra%=ra%+mem%?A%+(rp%AND1):rp%=(rp%AND254)+(ra%DIV256):ra%=ra%AND255:rp%=(rp%AND&3D)OR(ra%AND128)OR(((ra%AND128)DIV2)EOR(ra%AND64))OR((ra%=0)AND2):rpc%=rpc%+1:=0                         :REM ADC
  290 DEFFN_81:IFA%=rpc%:=FN_8A ELSE mem%?A%=ra%:rpc%=rpc%+1:=0                            :REM STA
  300 DEFFN_A1:ra%=mem%?A%:rp%=(rp%AND&7D)OR(ra%AND128)OR((ra%=0)AND2):rpc%=rpc%+1:=0      :REM LDA
  310 DEFFN_C1:A%=ra%-mem%?A%:rp%=(rp%AND254)+(((A%EOR256)AND256)DIV256):A%=A%AND255:rp%=(rp%AND&3D)OR(A%AND128)OR((A%=0)AND2):rpc%=rpc%+1:=0                                                           :REM CMP
  320 DEFFN_E1:ra%=ra%-mem%?A%-(1-(rp%AND1)):rp%=(rp%AND254)+(((ra%EOR256)AND256)DIV256):ra%=ra%AND255:rp%=(rp%AND&3D)OR(ra%AND128)OR(((ra%AND128)DIV2)EOR(ra%AND64))OR((ra%=0)AND2):rpc%=rpc%+1:=0     :REM SBC
  330 :
  340 DEFFN_12:=FNm12+FN_1                                  :REM ORA (zp)
  350 DEFFN_32:=FNm12+FN_21                                 :REM AND (zp)
  360 DEFFN_52:=FNm12+FN_41                                 :REM EOR (zp)
  370 DEFFN_72:=FNm12+FN_61                                 :REM ADC (zp)
  380 DEFFN_92:=FNm12+FN_81                                 :REM STA (zp)
  390 DEFFN_B2:=FNm12+FN_A1                                 :REM LDA (zp)
  400 DEFFN_D2:=FNm12+FN_C1                                 :REM CMP (zp)
  410 DEFFN_F2:=FNm12+FN_E1                                 :REM SBC (zp)
  420 :
  430 :
  440 DEFFN_8 :mem%?rs%=rp%:rs%=rs%-1:=0                                             :REM PHP
  450 DEFFN_28:rs%=rs%+1:rp%=mem%?rs%:=0                                             :REM PLP
  460 DEFFN_48:mem%?rs%=ra%:rs%=rs%-1:=0                                             :REM PHA
  470 DEFFN_5A:mem%?rs%=ry%:rs%=rs%-1:=0                                             :REM PHY
  480 DEFFN_68:rs%=rs%+1:ra%=mem%?rs%:rp%=(rp%AND&7D)OR(ra%AND128)OR((ra%=0)AND2):=0 :REM PLA
  490 DEFFN_7A:rs%=rs%+1:ry%=mem%?rs%:rp%=(rp%AND&7D)OR(ry%AND128)OR((ry%=0)AND2):=0 :REM PLY
  500 DEFFN_DA:mem%?rs%=rx%:rs%=rs%-1:=0                                             :REM PHX
  510 DEFFN_FA:rs%=rs%+1:rx%=mem%?rs%:rp%=(rp%AND&7D)OR(rx%AND128)OR((rx%=0)AND2):=0 :REM PLX
  520 :
  530 :
  540 DEFFN_10:=FNbr((rp%AND128)EOR128)                     :REM BPL
  550 DEFFN_30:=FNbr(rp%AND128)                             :REM BMI
  560 DEFFN_50:=FNbr((rp%AND64)EOR64)                       :REM BVC
  570 DEFFN_70:=FNbr(rp%AND64)                              :REM BVS
  580 DEFFN_80:=FNbr(1)                                     :REM BRA
  590 DEFFN_90:=FNbr((rp%EOR1)AND1)                         :REM BCC
  600 DEFFN_B0:=FNbr(rp%AND1)                               :REM BCS
  610 DEFFN_D0:=FNbr((rp%AND2)EOR2)                         :REM BNE
  620 DEFFN_F0:=FNbr(rp%AND2)                               :REM BEQ
  630 :
  640 :
  650 DEFFN_18:rp%=rp%AND&FE:=0                             :REM CLC
  660 DEFFN_38:rp%=rp%OR1:=0                                :REM SEC
  670 DEFFN_58:rp%=rp%AND&FB:=0                             :REM CLI
  680 DEFFN_78:rp%=rp%OR4:=0                                :REM SEI
  690 DEFFN_B8:rp%=rp%AND&BF:=0                             :REM CLV
  700 DEFFN_D8:rp%=rp%AND&F7:=0                             :REM CLD
  710 DEFFN_F8:rp%=rp%OR8:PRINT"**BCD not supported***":=0  :REM SED
  720 :
  730 :
  740 DEFFN_0:rpc%=rpc%+1:rs%=rs%-3:mem%?(rs%+1)=rp%OR&10:mem%?(rs%+2)=rpc%:mem%?(rs%+3)=rpc%DIV256:rpc%=(mem%!&FFFE)AND&FFFF:rp%=rp%OR4:=0                                      :REM BRK
  750 DEFFN_20:a%=mem%!rpc%:rpc%=rpc%+1:rs%=rs%-2:mem%?(rs%+1)=rpc%:mem%?(rs%+2)=rpc%DIV256:rpc%=a%AND&FFFF:=0
  760 :REM JSR
  770 DEFFN_40:rp%=mem%?(rs%+1):rpc%=(mem%!(rs%+2))AND&FFFF:rs%=rs%+3:rpc%=rpc%+1:=0 :REM RTI
  780 DEFFN_4C:rpc%=A%:=0                                           :REM JMP abs
  790 DEFFN_60:rpc%=(mem%!(rs%+1))AND&FFFF:rs%=rs%+2:rpc%=rpc%+1:=0 :REM RTS
  800 DEFFN_6C:rpc%=(mem%!A%)AND&FFFF:=0                            :REM JMP (abs)
  810 DEFFN_7C:rpc%=(mem%!A%)AND&FFFF:=0                            :REM JMP (abs,X)
  820 DEFFN_EA:=0                                                   :REM NOP
  830 :
  840 :
  850 DEFFN_8A:ra%=rx%:rp%=(rp%AND&7D)OR(ra%AND128)OR((ra%=0)AND2):=0             :REM TXA
  860 DEFFN_98:ra%=ry%:rp%=(rp%AND&7D)OR(ra%AND128)OR((ra%=0)AND2):=0             :REM TYA
  870 DEFFN_9A:rs%=rx%+&100:=0                                                    :REM TXS
  880 DEFFN_A8:ry%=ra%:rp%=(rp%AND&7D)OR(ry%AND128)OR((ry%=0)AND2):=0             :REM TAY
  890 DEFFN_AA:rx%=ra%:rp%=(rp%AND&7D)OR(rx%AND128)OR((rx%=0)AND2):=0             :REM TAX
  900 DEFFN_BA:rx%=rs%AND&FF:rp%=(rp%AND&7D)OR(rx%AND128)OR((rx%=0)AND2):=0       :REM TSX
  910 :
  920 :
  930 DEFFN_1A:ra%=(ra%+1)AND&FF:rp%=(rp%AND&7D)OR(ra%AND128)OR((ra%=0)AND2):=0 :REM INC A
  940 DEFFN_3A:ra%=(ra%-1)AND&FF:rp%=(rp%AND&7D)OR(ra%AND128)OR((ra%=0)AND2):=0 :REM DEC A
  950 DEFFN_88:ry%=(ry%-1)AND&FF:rp%=(rp%AND&7D)OR(ry%AND128)OR((ry%=0)AND2):=0 :REM DEY
  960 DEFFN_C8:ry%=(ry%+1)AND&FF:rp%=(rp%AND&7D)OR(ry%AND128)OR((ry%=0)AND2):=0 :REM INY
  970 DEFFN_CA:rx%=(rx%-1)AND&FF:rp%=(rp%AND&7D)OR(rx%AND128)OR((rx%=0)AND2):=0 :REM DEX
  980 DEFFN_E8:rx%=(rx%+1)AND&FF:rp%=(rp%AND&7D)OR(rx%AND128)OR((rx%=0)AND2):=0 :REM INX
  990 :
 1000 DEFFN_C6:        :REM DEC zp
 1010 DEFFN_CE:        :REM DEC abs
 1020 DEFFN_D6:        :REM DEC zp,X
 1030 DEFFN_DE:        :REM DEC abs,X
 1040 mem%?A%=(mem%?A%-1)AND&FF:rp%=(rp%AND&7D)OR((mem%?A%)AND128)OR((mem%?A%=0)AND2):rpc%=rpc%+1:=0
 1050 :
 1060 DEFFN_E6:        :REM INC zp
 1070 DEFFN_EE:        :REM INC abs
 1080 DEFFN_F6:        :REM INC zp,X
 1090 DEFFN_FE:        :REM INC abs,X
 1100 mem%?A%=(mem%?A%+1)AND&FF:rp%=(rp%AND&7D)OR((mem%?A%)AND128)OR((mem%?A%=0)AND2):rpc%=rpc%+1:=0
 1110 :
 1120 :
 1130 DEFFN_A2:A%=rpc% :REM LDX #n
 1140 DEFFN_A6:        :REM LDX zp
 1150 DEFFN_AE:        :REM LDX abs
 1160 DEFFN_B6:A%=(mem%?rpc%+ry%)AND&FF            :REM zp,X
 1170 DEFFN_BE:A%=(A%-rx%+ry%)AND&FFFF:rpc%=rpc%+1 :REM abs,Y
 1180 rx%=mem%?A%:rp%=(rp%AND&7D)OR(rx%AND128)OR((rx%=0)AND2):rpc%=rpc%+1:=0
 1190 :
 1200 DEFFN_A0:A%=rpc% :REM LDY #n
 1210 DEFFN_A4:        :REM LDY zp
 1220 DEFFN_AC:        :REM LDY abs
 1230 DEFFN_B4:        :REM LDY zp,X
 1240 DEFFN_BC:        :REM LDY abs,X
 1250 ry%=mem%?A%:rp%=(rp%AND&7D)OR(ry%AND128)OR((ry%=0)AND2):rpc%=rpc%+1:=0
 1260 :
 1270 :
 1280 DEFFN_86:        :REM STX zp
 1290 DEFFN_8E:        :REM STX abs
 1300 DEFFN_96:A%=(A%-rx%+ry%)AND&FFFF :REM STX zp,Y
 1310 mem%?A%=rx%:rpc%=rpc%+1:=0
 1320 :
 1330 DEFFN_84:        :REM STY zp
 1340 DEFFN_8C:        :REM STY abs
 1350 DEFFN_94:        :REM STY zp,X
 1360 mem%?A%=ry%:rpc%=rpc%+1:=0
 1370 :
 1380 :
 1390 DEFFN_64:                    :REM CLR zp
 1400 DEFFN_74:                    :REM CLR zp,X
 1410 DEFFN_9C:A%=(A%-rx%)AND&FFFF :REM CLR abs
 1420 DEFFN_9E:                    :REM CLR abs,X
 1430 mem%?A%=0:rpc%=rpc%+1:=0
 1440 :
 1450 :
 1460 DEFFN_A :ra%=ra%*2:rp%=(rp%AND&FE)+ra%DIV256:ra%=ra%AND&FF:rp%=(rp%AND&7D)OR(ra%AND128)OR((ra%=0)AND2):=0:                     :REM ASL A
 1470 DEFFN_6 :         :REM ASL zp
 1480 DEFFN_E :         :REM ASL abs
 1490 DEFFN_16:         :REM ASL zp,X
 1500 DEFFN_1E:         :REM ASL abs,X
 1510 a%=mem%?A%*2:rp%=(rp%AND&FE)+a%DIV256:mem%?A%=a%:rp%=(rp%AND&7D)OR(mem%?A%AND128)OR((mem%?A%=0)AND2):rpc%=rpc%+1:=0
 1520 :
 1530 DEFFN_2A:ra%=ra%*2+(rp%AND1):rp%=(rp%AND&FE)+ra%DIV256:ra%=ra%AND&FF:rp%=(rp%AND&7D)OR(ra%AND128)OR((ra%=0)AND2):=0            :REM ROL A
 1540 DEFFN_26:         :REM ROL zp
 1550 DEFFN_2E:         :REM ROL abs
 1560 DEFFN_36:         :REM ROL zp,X
 1570 DEFFN_3E:         :REM ROL abs,X
 1580 a%=mem%?A%*2+(rp%AND1):rp%=(rp%AND&FE)+a%DIV256:mem%?A%=a%:rp%=(rp%AND&7D)OR(mem%?A%AND128)OR((mem%?A%=0)AND2):rpc%=rpc%+1:=0
 1590 :
 1600 DEFFN_4A:rp%=(rp%AND&FE)OR(ra%AND1):ra%=ra%DIV2:rp%=(rp%AND&7D)OR(ra%AND128)OR((ra%=0)AND2):=0                           :REM LSR A
 1610 DEFFN_46:         :REM LSR zp
 1620 DEFFN_4E:         :REM LSR abs
 1630 DEFFN_56:         :REM LSR zp,X
 1640 DEFFN_5E:         :REM LSR abs,X
 1650 rp%=(rp%AND&FE)OR(mem%?A%AND1):mem%?A%=mem%?A%DIV2:rp%=(rp%AND&7D)OR(mem%?A%AND128)OR((mem%?A%=0)AND2):rpc%=rpc%+1:=0
 1660 :
 1670 DEFFN_6A:ra%=ra%+256*(rp%AND1):rp%=(rp%AND&FE)+(ra%AND1):ra%=ra%DIV2:rp%=(rp%AND&7D)OR(ra%AND128)OR((ra%=0)AND2):=0            :REM ROR A
 1680 DEFFN_66:         :REM ROR zp
 1690 DEFFN_6E:         :REM ROR abs
 1700 DEFFN_76:         :REM ROR zp,X
 1710 DEFFN_7E:         :REM ROR abs,X
 1720 a%=mem%?A%+256*(rp%AND1):rp%=(rp%AND&FE)+(a%AND1):mem%?A%=a%DIV2:rp%=(rp%AND&7D)OR(mem%?A%AND128)OR((mem%?A%=0)AND2):rpc%=rpc%+1:=0
 1730 :
 1740 :
 1750 DEFFN_89:A%=rpc%  :REM BIT #n
 1760 DEFFN_24:         :REM BIT zp
 1770 DEFFN_2C:         :REM BIT abs
 1780 DEFFN_34:         :REM BIT zp,X
 1790 DEFFN_3C:         :REM BIT abs,X
 1800 rp%=(rp%AND&3D)OR(mem%?A%AND&C0)OR(((mem%?A%ANDra%)=0)AND2):rpc%=rpc%+1:=0
 1810 :
 1820 :
 1830 DEFFN_C0:A%=rpc%  :REM CPY #n
 1840 DEFFN_C4:         :REM CPY zp
 1850 DEFFN_CC:         :REM CPY abs
 1860 A%=ry%-mem%?A%:rp%=(rp%AND254)+(((A%EOR256)AND256)DIV256):A%=A%AND255:rp%=(rp%AND&3D)OR(A%AND128)OR((A%=0)AND2):rpc%=rpc%+1:=0
 1870 :
 1880 DEFFN_E0:A%=rpc%  :REM CPX #n
 1890 DEFFN_E4:         :REM CPX zp
 1900 DEFFN_EC:         :REM CPX abs
 1910 A%=rx%-mem%?A%:rp%=(rp%AND254)+(((A%EOR256)AND256)DIV256):A%=A%AND255:rp%=(rp%AND&3D)OR(A%AND128)OR((A%=0)AND2):rpc%=rpc%+1:=0
 1920 :
 1930 DEFFN_4 :Z%=FNm4  :REM TSB zp
 1940 DEFFN_C :Z%=FNmC  :REM TSB abs
 1950 rp%=(rp%AND253)+(((mem%?A% AND ra%)=0)AND2):mem%?A%=mem%?A% OR ra%:rpc%=rpc%+1:=0
 1960 :
 1970 DEFFN_14:Z%=FNm4  :REM TRB zp
 1980 DEFFN_1C:Z%=FNmC  :REM TRB abs
 1990 rp%=(rp%AND253)+(((mem%?A% AND ra%)=0)AND2):mem%?A%=mem%?A% AND NOT ra%:rpc%=rpc%+1:=0
 2000 :
 2010 :
 2020 REM MOS Interface
 2030 DEFFN_3 :         :REM OSCLI /OSBYTE
 2040 DEFFN_23:         :REM OSWORD/OSWRCH
 2050 DEFFN_43:         :REM OSRDCH/OSFILE
 2060 DEFFN_63:         :REM OSARGS/OSBGET
 2070 DEFFN_83:         :REM OSBPUT/OSGBPB
 2080 DEFFN_A3:         :REM OSFIND/OSQUIT
 2090 DEFFN_C3:         :REM OSLANG/  -
 2100 DEFFN_E3:         :REM   -   /  -
 2110 =FNmos(mem%?(rpc%-1))
 2120 :
 2130 :
 2140 DEFFN_2 :  :REM ---
 2150 DEFFN_22:  :REM ---
 2160 DEFFN_42:  :REM ---
 2170 DEFFN_44:  :REM ---
 2180 DEFFN_54:  :REM ---
 2190 DEFFN_5C:  :REM ---
 2200 DEFFN_62:  :REM ---
 2210 DEFFN_82:  :REM ---
 2220 DEFFN_C2:  :REM ---
 2230 DEFFN_D4:  :REM ---
 2240 DEFFN_DC:  :REM ---
 2250 DEFFN_E2:  :REM ---
 2260 DEFFN_F4:  :REM ---
 2270 DEFFN_FC:  :REM ---
 2280 =0
   10 REM > MOS
   20 DEFFNmos(m%):LOCAL X%,Y%
   30 A%=ra%:X%=rx%+256*ry%:Y%=ry%:C%=rp%:rp%=0
   40 CASE m% OF
   50   WHEN &13,&FFF4:=FNmos_byte
   60   WHEN &33,&FFEE:VDU A%:=0
   70   WHEN &FFEC:VDU 13:=0
   80   WHEN &FFE7:CALL &FFE7:=0
   90   WHEN &FFE3:CALL &FFE3:=0
  100   WHEN &43,&FFE0:ra%=GET:rp%=(ra%=27)AND1:=0
  110   WHEN &73,&FFD7:=FNmos_bget
  120   WHEN &83,&FFD4:=FNmos_bput
  130   WHEN &A3,&FFCE:=FNmos_find
  140   WHEN &63,&FFDA:=FNmos_args
  150   WHEN &B3:=FNmos_quit
  160   WHEN &C3:=FNmos_lang
  170 ENDCASE
  180 X%=X%+mem%:Y%=X%DIV256
  190 CASE m% OF
  200   WHEN &03,&FFF7:=FNmos_cli
  210   WHEN &23,&FFF1:=FNmos_word
  220   WHEN &53,&FFDD:=FNmos_file
  230   WHEN &93,&FFD1:=FNmos_gbpb
  240 ENDCASE
  250 =0
  260 :
  270 DEFFNmos_cli:PROCcmd($X%,TRUE):=0
  280 :
  290 DEFFNmos_byte
  300 IF A%=&82:rx%=0:ry%=&00:=0
  310 IF A%=&83:rx%=0:ry%=&08:=0
  320 IF A%=&84:rx%=prog%AND255:ry%=prog%DIV256:=0
  330 IF A%>123:IFA%<127:mem%?escflg%=128*(A%AND1):OSCLI"FX15" :REM Clear/Set/Ack Escape
  340 IF os%<>32:X%=X%AND255:A%=USR&FFF4:rx%=(A%AND&FF00)DIV256:ry%=(A%AND&FF0000)DIV65536:rp%=(A%AND&1000000)DIV&1000000:=0
  350 IF A%=128:IFrx%=7:MOUSE rx%,A%,A%:ry%=(rx%>>8)AND255:rx%=rx%AND255:=0
  360 IF A%=128:IFrx%=8:MOUSE A%,rx%,A%:ry%=(rx%>>8)AND255:rx%=rx%AND255:=0
  370 CASE A% OF
  380   WHEN   0:rx%=32:=0
  390   WHEN 127:rx%=EOF#rx%:=0
  400   WHEN 128:A%=ADVAL(rx%+256*ry%):rx%=A%:ry%=A%DIV256:=0
  410   WHEN 129:A%=INKEY(rx%+256*ry%):rx%=A%:ry%=A%DIV256:PROCcarry(A%=-1):=0
  420   WHEN 134:rx%=POS:ry%=VPOS:=0
  430   WHEN 135:rx%=GET(POS,VPOS):ry%=MODE:=0
  440   WHEN 160:
        ry%=rx%+1:ry%=(@vdu%!(((ry%AND-4)+VALMID$("0312",(ry%AND3)+1,1)-2)*4))DIV(8*(1+(ry%AND1)))
        rx%=(@vdu%!(((rx%AND-4)+VALMID$("0312",(rx%AND3)+1,1)-2)*4))DIV(8*(1+(rx%AND1))):=0
  450 ENDCASE
  460 =0
  470 :
  480 DEFFNmos_word
  490 IFA%=0:A%=!X%AND&FFFF:mem%?255=0:osw0%=TRUE:PROCEscOn:INPUTLINE""A$:PROCEscOff:$(mem%+A%)=A$:osw0%=FALSE:ry%=LENA$:=0
  500 IFos%<>32 OR A%=10:CALL &FFF1:=0
  510 CASE A% OF
  520   WHEN 1:!X%=TIME:=0
  530   WHEN 2:TIME=!X%:=0
  540   WHEN 7:SOUND !X%,X%!2,X%!4,X%!6:=0
  550   WHEN 8:ENVELOPE ?X%,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
  560   WHEN 14:$X%=TIME$:=0
  570   WHEN 15:TIME$=$X%:=0
  580 ENDCASE
  590 =0
  600 :
  610 DEFFNmos_file
  620 IFA%=254:IFX%?5 =&FF:X%?5=0 ELSE IF A%=254:X%!2=X%!2+mem%
  630 IFA%=255:IFX%?5 =&FF:X%?5=0 ELSE IF A%=255:X%!2=X%!2+mem%
  640 IFA%=0  :IFX%?13=&FF:X%?13=0:X%?17=0 ELSE IF A%=0:X%!10=X%!10+mem%:X%!14=X%!14+mem%
  650 fn%=mem%+(!X% AND &FFFF)
  660 IF os%<32:SYS "OS_File",A%,fn%,X%!2,X%!6,X%!10,X%!14 TO ra%,,X%!2,X%!6,X%!10,X%!14 ELSE ra%=FNfile($fn%,A%)
  670 REM SYS "OS_File",A%,mem%+(!X% AND &FFFF),X%!2,X%!6,X%!10,X%!14 TO ra%,,X%!2,X%!6,X%!10,X%!14
  680 =0
  690 REM DEFPROCaddr(A%):IFX%!A%<&10000:X%!A%=mem%+A%!X%
  700 REM ENDPROC
  710 :
  720 DEFFNmos_bget:ra%=(USR&FFD7):rp%=ra%DIV256:ra%=ra%AND255:=0
  730 :
  740 DEFFNmos_bput:CALL &FFD7:=0
  750 :
  760 DEFFNmos_find:IFA%=0:CLOSE#Y%:=0
  770 IF (A%AND&C0)=&40:ra%=FNopenin($(mem%+X%)):=0
  780 IF (A%AND&C0)=&80:ra%=FNopenout($(mem%+X%)):=0
  790 IF (A%AND&C0)=&C0:ra%=FNopenup($(mem%+X%)):=0
  800 :
  810 DEFFNmos_gbpb
  820 ra%=X%?5   :IFra%=&FF:X%?5=0   ELSE X%!1=X%!1+mem%
  830 A%=USR&FFD1:IFra%=&FF:X%?5=&FF ELSE X%!1=X%!1-mem%
  840 ra%=A%AND255:rp%=A%DIV256:=0
  850 :
  860 DEFFNmos_args
  870 IFY%=0:IFA%=0:ra%=FNfs:=0
  880 IFY%=0:mem%!X%=FNargs(ra%,Y%,mem%!X%):=0
  890 IFA%=0:mem%!X%=PTR#Y%:ra%=0:=0
  900 IFA%=1:PTR#Y%=mem%!X%:ra%=0:=0
  910 IFA%=2:mem%!X%=EXT#Y%:ra%=0:=0
  920 IFA%=3:EXT#Y%=mem%!X%:ra%=0:=0
  930 IFA%=4:mem%!X%=EXT#Y%:ra%=0:=0
  940 mem%!X%=FNargs(A%,Y%,mem%!X%)
  950 =0
  960 :
  970 DEFFNmos_quit:=TRUE
  980 DEFFNmos_lang:=0
      REM > Dis65
 4570 DEFFNDis_Name(cpu%)="65x02"
 4580 DEFFNDis_Code(cpu%,Ptr%,Data%):LOCALop%,ins%,md%,b0%,num%
 4590 num%=1:op%=?Data%:ins%=op%DIV32:md%=(op%AND31)DIV4:b0%=(op%AND3)
 4600 X%!0=0:$(X%+4)=FN_diss:X%?3=num%:=num%
 4610 DEFFN_diss
 4620 IF(op%AND&F)=8:=MID$("PHPCLCPLPSECPHACLIPLASEIDEYTYATAYCLVINYCLDINXSED",1+3*(op%DIV16),3)
 4630 IF(op%AND&8F)=&8A:=MID$("TXATXSTAXTSXDEXPHXNOPPLX",3*(op%DIV16)-23,3)
 4640 IFop%=&20:="JSR "+FNmde(3)
 4650 IF(op%AND&9F)=0:X%?2=(op%AND64):=MID$("BRK***RTIRTS",ins%*3+1,3)
 4660 IF(op%AND&DF)=&5A:=MID$("PHYPLY",ins%*3-5,3)
 4670 IFop%=&89:="BIT "+FNmde(2)
 4680 IFb0%=1:=FNalu(ins%)+" "+FNmde(md%)
 4690 IF(op%AND31)=&12:=FNalu(ins%)+" "+FNmde(8)
 4700 IF(op%AND&EF)=&64:="STZ "+FNmde(md%)
 4710 IF(op%AND&FD)=&9C:="STZ "+FNmde(b0%*2+3)
 4720 IF(op%AND&D7)=&96:=FNrot(ins%)+" "+FNmde(md%AND3)+",Y"
 4730 IF(op%AND7)=6:=FNrot(ins%)+" "+FNmde(md%)
 4740 IF(op%AND&1F)=16:num%=2:="B"+MID$("PLMIVCVSCCCSNEEQ",1+2*ins%,2)+" "+FNjr(Data%?1)
 4750 IF(op%AND&8F)=10:=FNrot((ins%+(md%AND4)*1.5)EOR((md%>4)AND1))+" A"
 4760 IF(op%AND&E7)=4:="T"+MID$("SR",1+(md%DIV4),1)+"B "+FNmde(md%AND3)
 4770 IF(op%AND&D3)=&C0:=FNbxy(ins%)+" "+FNmde(((md%EOR3)-1)AND3)
 4780 IF(op%AND&E7)=&24:="BIT "+FNmde(md%)
 4790 IF(op%AND&C7)=&84:=FNbxy(ins%)+" "+FNmde(md%)
 4800 IF(op%AND&FD)=&A0:="LD"+MID$("YX",1+((op%AND2)DIV2),1)+" "+FNmde(2)
 4810 IF(op%AND&CF)=&4C:IFop%<>&5C:X%?2=64:="JMP "+LEFT$("(",op%>&5F)+FNmde(md%)+LEFT$(")",op%>&5F)
 4820 IFop%=&80:num%=2:X%?2=64:="BRA "+FNjr(Data%?1)
 4830 X%?2=128:="EQUB &"+FNh0(op%,2)
 4840 DEFFNalu(A%)=MID$("ORAANDEORADCSTALDACMPSBC",A%*3+1,3)
 4850 DEFFNrot(A%)=MID$("ASLROLLSRRORSTXLDXDECINC",A%*3+1,3)
 4860 DEFFNbxy(A%)=MID$("***BIT***STZSTYLDYCPYCPX",A%*3+1,3)
 4870 DEFFNmde(A%):num%=2:IFA%=2:="#&"+FNh0(Data%?1,2)
 4880 IF(A%AND2):num%=3:="&"+FNh0(Data%!1,4)+LEFT$(",X",A%=7)+LEFT$(",Y",A%=6)
 4890 IF(A%AND1):="&"+FNh0(Data%?1,2)+LEFT$(",X",A%=5)
 4900 ="(&"+FNh0(Data%!1,2)+LEFT$(",X",A%=0)+")"+LEFT$(",Y",A%=4)
 4910 DEFFNjr(A%):IFA%<128:="&"+FNh0(Ptr%+A%+2,4)ELSE="&"+FNh0(Ptr%+A%+2-256,4)
   10 REM > BLib.Close 1.00 09Aug1998
   20 :
   30 REM Close Handling
   40 REM ~~~~~~~~~~~~~~
   50 :
   60 DEFPROCClose_All
   70 in%=in%:IFin%:A%=in%:in%=0:CLOSE#A%
   80 out%=out%:IFout%:A%=out%:out%=0:CLOSE#A%
   90 ENDPROC
   10 REM > BLib.String 1.00 09Aug1998
   20 :
   30 REM String Manipulation Functions
   40 REM =============================
   50 :
   60 REM FNs() - strip spaces from start and end of string
   70 REM -------------------------------------------------
   80 DEFFNs(A$):IFLEFT$(A$,1)=" ":REPEATA$=MID$(A$,2):UNTILLEFT$(A$,1)<>" "
   90 IFRIGHT$(A$,1)=" ":REPEATA$=LEFT$(A$,LENA$-1):UNTILRIGHT$(A$,1)<>" "
  100 =A$
  110 :
  120 REM FNuc() - convert string to upper case
  130 REM -------------------------------------
  140 DEFFNuc(A$):LOCAL B$:IFA$="":=""
  150 REPEATB$=B$+CHR$(ASCA$AND((A$<"@")OR&DF)):A$=MID$(A$,2):UNTILA$="":=B$
  160 :
  170 REM FNlc() - convert string to lower case
  180 REM -------------------------------------
  190 DEFFNlc(A$):LOCAL B$:IFA$="":=""
  200 REPEATB$=B$+CHR$(ASCA$OR((A$<"_")AND&20)):A$=MID$(A$,2):UNTILA$="":=B$
  210 :
   10 REM > BLib.Number 1.01 09Aug1988
   20 REM v1.00 09Aug1988 JGH: First version
   30 REM v1.01 12Feb1992 JGH: Added Octal and Binary
   40 REM v1.02 15Sep2009 JGH: Octal and Binary works for &8xxxxxxx
   50 :
   60 REM Number Output Routines
   70 REM ~~~~~~~~~~~~~~~~~~~~~~
   80 :
   90 REM Hexadecimal padded with zeros
  100 DEFFNh0(A%,N%):=RIGHT$("0000000"+STR$~A%,N%)
  110 :
  120 REM Hexadecimal padded with spaces
  130 DEFFNh(A%,N%):=RIGHT$("       "+STR$~A%,N%)
  140 :
  150 REM Decimal padded with zeros
  160 DEFFNd0(A%,N%):=RIGHT$("00000000"+STR$A%,N%)
  170 :
  180 REM Decimal padded with spaces
  190 DEFFNd(A%,N%):=RIGHT$("         "+STR$A%,N%)
  200 :
  210 REM Octal padded with zeros
  220 DEFFNo0(A%,N%):LOCAL A$,B%,L%:IFA%<0:B%=2:A%=A%AND&7FFFFFFF
  230 REPEATA$=STR$(A%AND7)+A$:A%=A%DIV8:L%=L%+3:UNTILL%>27:=RIGHT$(STR$(A%+B%)+A$,N%)
  240 :
  250 REM Octal padded with spaces
  260 DEFFNo(A%,N%):LOCAL A$:IFA%<0:=FNo0(A%,N%)
  270 REPEATA$=STR$(A%AND7)+A$:A%=A%DIV8:UNTILA%=0:=RIGHT$(STRING$(N%," ")+A$,N%)
  280 :
  290 REM Binary padded with zeros
  300 DEFFNb0(A%,N%):LOCAL A$,B$,L%:B$="0":IFA%<0:B$="1":A%=A%AND&7FFFFFFF
  310 REPEATA$=STR$(A%AND1)+A$:A%=A%DIV2:L%=L%+1:UNTILL%>30:=RIGHT$(B$+A$,N%)
  320 :
  330 REM Binary padded with spaces
  340 DEFFNb(A%,N%):LOCAL A$:IFA%<0:=FNb0(A%,N%)
  350 REPEATA$=STR$(A%AND1)+A$:A%=A%DIV2:UNTILA%=0:=RIGHT$(STRING$(N%," ")+A$,N%)
  360 :
  370 REM Drive character for supplied number
  380 DEFFNdrv(A%):=CHR$(48+A%-7*(A%>9))
  390 :
  400 REM Drive number for supplied character
  410 DEFFNDrv(A$):=ASCA$-48+7*(A$>"9")AND31
  420 :
   10 REM > BLib.ProgEnv 1.06 20Apr2020
   20 :
   30 REM Program Environment Functions
   40 REM =============================
   50 :
   60 REM Return command line tail, sets run$ to execution filename
   70 REM Works on BBCIO,BBC09,T6502,T6809,TZ80,ZX80,PDP11,ARMEval,ARMCoPro,RISCOS,DOS,Windows
   80 REM ------------------------------------------------------------------------------------
   90 DEFFNOS_GetEnv:LOCALA$,A%,X%,Y%:X%=1:os%=((USR&FFF4)AND&FF00)DIV256
  100 IFos%>31:IFPAGE>&FFFFF:DIMX%LOCAL256:SYS"GetModuleFileName",0,X%,255:run$=$$X%:=@cmd$
  110 A%=&600-&7B00*(PAGE>&8000)-&3F00*(PAGE>&C000):IF!(PAGE-&108)=@%:A%=PAGE-&208
  120 IF?(TOP-3)=0:A%=&100:IFHIMEM<&FFFF:A%=PAGE-&300:IF!(HIMEM+512)=@%:A%=HIMEM
  130 A$=$A%:IFPAGE=&8F00:run$=A$:SYS16TOA$,,A%:SYS72,"",A%:A$=MID$(A$,1+INSTR(A$+" "," ",1+INSTR(A$," "))):IFLENA$=0:A$=run$
  140 FORY%=-1TO0:A$=" "+A$:REPEATA$=MID$(A$,2):UNTILASCA$<>32:IFASCA$=34:A%=INSTR(A$,"""",2)+1 ELSE A%=INSTR(A$+" "," ")
  150   IFY%:run$=MID$(A$,1-(ASCA$=34),A%-1+2*(ASCA$=34)):A$=MID$(A$,A%+1)
  160 NEXT:=A$
  170 :
  180 REM Run a program, passing it a command line
  190 REM If program is *Command, called with OSCLI, else CHAINed
  200 REM -------------------------------------------------------
  210 DEFPROCos(A$):IFASCA$=42:OSCLIA$ ELSE IFLENA$:CHAINA$
  220 ENDPROC
  230 :
  240 REM Exit program, setting return value
  250 REM ----------------------------------
  260 DEFPROCexit(A%):OSCLI"FX1,"+STR$(A%AND255):quit$=quit$:A$=quit$:quit$="":PROCos(A$)
  270 IFPAGE>&FFFFF:QUIT A% ELSE END
  280 ENDPROC
  290 :
   10 REM > BLib.Generic.FileIO 1.05 22Mar2008
   20 REM v1.05 22Mar2009 Optimised CDIR in FNfile()
   30 REM v1.04 22Mar2008 FNf_scan strips spaces
   40 REM v1.03 15Feb2008 Add veneer functions in f_ domain
   50 REM v1.02 28Apr2007 Added functions to FNfile on DOS, PROCcdir, FNopenout
   60 REM v1.01 07Sep2006 FNargs avoid zero page on RISC OS
   70 REM v1.00 09Aug1988 Initial version
   80 :
   90 REM General File Interface Routines
  100 REM ===============================
  110 :
  120 REM FNfile(), PROCgbpb(), FNfs are callable on Windows
  130 REM --------------------------------------------------
  140 :
  150 REM Returns file type, file info in X%!...
  160 REM --------------------------------------
  170 DEFFNfile(A$,A%):IFA%<>8:IFPAGE<&FFFFF:$name%=A$:?X%=name%:X%?1=name%DIV256:=(USR&FFDD)AND&FF
  180 A$=FNf_name(A$):IFA%=255 OR A%=5:X%!14=OPENIN(A$):IFX%!14:X%!10=EXT#X%!14:CLOSE#X%!14:X%!14=&33
  190 IFA%=255:IFX%?6=0:OSCLI"LOAD """+A$+""" "+STR$~X%!2:=1
  200 IFA%=5:IFX%!14:=1 ELSE IFA%=5:=0
  210 IFA%=0:OSCLI"SAVE """+A$+""" "+STR$~X%!10+" "+STR$~X%!14:X%!10=X%!14-X%!10:=1
  220 IFA%=7:OSCLI"SAVE """+A$+""" "+STR$~PAGE+"+"+STR$~X%!10:X%!10=X%!14-X%!10:=1
  230 IFA%<>8:=0
  240 IF(os%AND-24):A$="mkdir "+A$ ELSE A$="cdir "+A$
  250 IFHIMEM>&FFFF:LOCAL ERROR:ON ERROR LOCAL:=0
  260 OSCLIA$:=2
  270 :
  280 REM General OSGBPB call
  290 REM -------------------
  300 DEFPROCf_gbpb(A%,chn%,addr%,num%,ptr%)
  310 ?X%=chn%:X%!1=addr%:X%!5=num%:X%!9=ptr%:IFPAGE<&FFFFF:CALL&FFD1:ENDPROC
  320 IFA%=1ORA%=3:PTR#?X%=X%!9
  330 REPEAT:IFA%=1ORA%=2:BPUT#?X%,?X%!1 ELSE IFA%=3ORA%=4:?X%!1=BGET#?X%
  340 X%!1=X%!1+1:X%!5=X%!5-1:UNTIL(EOF#?X% AND A%>2)OR X%!5<1:ENDPROC
  350 :
  360 DEFPROCgbpb(A%,chn%,addr%,num%,ptr%)
  370 ?X%=chn%:X%!1=addr%:X%!5=num%:X%!9=ptr%:IFPAGE<&FFFFF:CALL&FFD1:ENDPROC
  380 IFA%=1ORA%=3:PTR#?X%=X%!9
  390 REPEAT:IFA%=1ORA%=2:BPUT#?X%,?X%!1 ELSE IFA%=3ORA%=4:?X%!1=BGET#?X%
  400 X%!1=X%!1+1:X%!5=X%!5-1:UNTIL(EOF#?X% AND A%>2)OR X%!5<1:ENDPROC
  410 :
  420 REM Return current disk (5), directory (6) or library (7) name
  430 REM ----------------------------------------------------------
  440 DEFFNgbpb(A%):IFPAGE>&FFFFF:=""
  450 X%!1=name%:CALL&FFD1:A%=name%+((1+?name%)AND((A%AND-2)=6)):A%?(1+?A%)=13:=$(A%+1)
  460 :
  470 REM Returns entry in current directory, or null string if at end
  480 REM ------------------------------------------------------------
  490 DEFFNf_scan(ptr%):IFPAGE>&FFFFF:=""
  500 X%!1=name%:X%!5=1:X%!9=ptr%:A%=8:CALL&FFD1:IFX%!5=1:=""
  510 A%=name%+1:A%!(A%?-1)=&D20:A%?(INSTR($A%," ")-1)=13:=$A%
  520 :
  530 DEFFNgbpb8(ptr%):IFPAGE>&FFFFF:=""
  540 X%!1=name%:X%!5=1:X%!9=ptr%:A%=8:CALL&FFD1:IFX%!5=1:=""
  550 A%=name%+1:A%!(A%?-1)=&D20:A%?(INSTR($A%," ")-1)=13:=$A%
  560 :
  570 REM OSARGS call with data.  Returns any returned data
  580 REM -------------------------------------------------
  590 DEFFNf_args(A%,Y%,ptr%):LOCAL X%,E%:IF?(TOP-3)=0:E%=Y%:Y%=0
  600 IF FALSE THEN
  610   LOCAL !&70:X%=&70:!X%=ptr%:CALL&FFDA:=!X%
  620 ELSE
  630   SYS"OS_Args",A%,Y%,ptr% TO ,,ptr%
  640   SAVE:=ptr%
  650   :
  660   DEFFNargs(A%,Y%,ptr%):LOCAL X%,E%:IF?(TOP-3)=0:E%=Y%:Y%=0
  670   IF FALSE THEN
  680     LOCAL !&70:X%=&70:!X%=ptr%:CALL&FFDA:=!X%
  690   ELSE
  700     SYS"OS_Args",A%,Y%,ptr% TO ,,ptr%
  710     SAVE:=ptr%
  720     :
  730     REM OSARGS call ignoring X, returns A
  740     REM ---------------------------------
  750     DEFFNf_argsA(A%):IF FALSE THEN
  760       LOCAL X%,Y%,E%,!&70:X%=&70:=(USR&FFDA)AND&FF
  770     ELSE
  780       SYS"OS_Args",A% TO A%
  790       SAVE:=A%
  800       :
  810       DEFFNargsA(A%):IF FALSE THEN
  820         LOCAL X%,Y%,E%,!&70:X%=&70:=(USR&FFDA)AND&FF
  830       ELSE
  840         SYS"OS_Args",A% TO A%
  850         SAVE:=A%
  860         :
  870         REM Get current filing system number
  880         REM --------------------------------
  890         DEFFNfs:IF(os%AND-32)=0:LOCAL A%,Y%,E%:=(USR&FFDA)AND&FF
  900         =29
  910         :
  920         REM Delete an object
  930         REM ----------------
  940         DEFPROCf_delete(A$):IF(os%AND-24):A$="del "+A$ ELSE A$="delete "+A$
  950         OSCLIA$:ENDPROC
  960         :
  970         REM Select a directory
  980         REM ------------------
  990         DEFPROCf_dir(A$):IF(os%AND-24):A$="cd "+A$ ELSE A$="dir "+A$
 1000         OSCLIA$:ENDPROC
 1010         :
 1020         REM Create a directory only if it doesn't exist
 1030         REM -------------------------------------------
 1040         DEFPROCf_cdir(A$):
 1050         IF(os%AND-24):A$="mkdir "+A$ ELSE A$="cdir "+A$
 1060         IF FALSE THEN
 1070           OSCLIA$:ENDPROC
 1080         ENDIF
 1090         LOCAL ERROR:ON ERROR LOCAL:ENDPROC
 1100         OSCLIA$
 1110         ENDPROC
 1120         :
 1130         REM Open an input file ensuring no extension
 1140         REM ----------------------------------------
 1150         DEFFNf_openin(A$)=OPENIN(FNf_name(A$))
 1160         :
 1170         REM Open an output file ensuring no extension
 1180         REM -----------------------------------------
 1190         DEFFNf_openout(A$)=OPENOUT(FNf_name(A$))
 1200         :
 1210         REM Open an update file ensuring no extension
 1220         REM -----------------------------------------
 1230         DEFFNf_openup(A$)=OPENUP(FNf_name(A$))
 1240         :
 1250         DEFFNf_name(A$):IFos%AND-32:LOCALA%,B%:REPEATB%=A%:A%=INSTR(A$,"\",A%+1):UNTILA%=0:IFINSTR(A$,".",B%)=0:A$=A$+"."
 1260         =A$