10 REM > AsmZ80 4.02
   20 REM Z80 Assembler, from a file
   30 REM Based on RAW's Amstrad assembler
   40 REM Can do Basic or Text file
   50 :
   60 PRINT"RAW/JGH Assembler v4.02 BBC"
   70 PROCInit:ln%=0:l_flg%=0:org%=-1:P%=-1:in%=0:out%=0
   80 PRINT;maxlabs;" labels available"'
   90 ON ERROR REPORT:PROCClose:PRINT:END
  100 INPUT"Input file: "in$:in%=OPENIN(in$):IFin%=0:PRINT"'"in$"' not found":END
  110 INPUT"Output file: "out$:errs%=0
  120 FORpass=1 TO 2:PTR#in%=0:inside%=FALSE:PRINT"Pass ";pass
  130   IFpass=2:IFout$<>"":OSCLI"Save "+out$+" 0+"+STR$~(P%-org%)+" "+STR$~E%+" "+STR$~org%:out%=OPENOUT(out$)
  140   REPEATPROCDoLine:UNTILEOF#in% OR errs%>99::IFerrs%:pass=2
  150   IFerrs%=100:PRINT"Too many errors"
  160 NEXT:IFout%:CLOSE#out%:out%=0:$name%=out$:!X%=name%:X%!2=org%:A%=2:CALL&FFDD:X%!6=E%:A%=3:CALL&FFDD
  170 CLOSE#in%:in%=0:IFerrs%=0:GOSUB3200
  180 END
  190 :
  200 DEFPROCInit
  210 maxlabs=(HIMEM-LOMEM-2000)DIV40
  220 numl=0:DIM type$(69),label$(maxlabs),value(maxlabs),cond$(7)
  230 DIM ctrl% 31,name% 127:X%=ctrl%:Y%=X%DIV256
  240 RESTORE 3160:FORi%=0 TO 69:READ type$(i%):NEXT
  250 RESTORE 3180:FORi%=0 TO 7:READ cond$(i%):NEXT
  260 ENDPROC
  270 :
  280 DEFPROCerr(A$):PRINTTAB(19);left$;:IFright$<>"":PRINT",";right$;
  290 PRINT'A$" at line ";ln%:errs%=errs%+1:ENDPROC
  300 :
  310 DEFPROCClose:IFin%:A%=in%:in%=0:CLOSE#A%
  320 IFout%:A%=out%:out%=0:CLOSE#A%
  330 ENDPROC
  340 :
  350 DEFPROCDoLine:textl$=FNreadL:textr$="":right$="":IFtextl$="":ENDPROC
  360 I%=INSTR(textl$," "):IFMID$(textl$,I%+1,1)=" ":REPEAT:textl$=LEFT$(textl$,I%)+MID$(textl$,I%+2):UNTILMID$(textl$,I%+1,1)<>" "
  370 textr$="":IFINSTR(";\",LEFT$(textl$,1)):GOTO580
  380 IFl_flg%:PRINT;ln%;TAB(5);
  390 IFNOTinside%:PROCoutside:ENDPROC
  400 IFLEFT$(textl$,1)="]":inside%=FALSE:ENDPROC
  410 IFP%=-1:errs%=100:PROCerr("Origin?"):ENDPROC
  420 byte1=-1:byte2=-1:byte3=-1:byte4=-1:index=-1
  430 IFpass=2:PRINTRIGHT$("000"+STR$~P%,4)": ";
  440 i%=INSTR(textl$+" "," "):textl$=FNup(LEFT$(textl$,i%))+MID$(textl$,i%+1)
  450 i%=-1:FORj%=69 TO 0 STEP-1
  460   IFINSTR(textl$,type$(j%))=1:i%=j%:j%=0
  470 NEXT:IFi%=-1:PROCerr("Bad statement"):ENDPROC
  480 IFi%<36:ON i% GOSUB 2170,2290,2510,1770,2390,1470,1690,1810,1730,1730,1730,1730,1690,1690,2070,1690,1290,1690,1210,1690,1690,1320,1370,2070,1730,1730,1730,1730,1570,1520,890,1730,1730,1730,1730
  490 IFi%>35:i%=i%-35:ON i% GOSUB 1730,1690,1820,1730,1730,1420,1730,1730,820,820,2410,1650,1730,1730,1960,1690,1690,1950,1730,1980,1690,1970,1690,1730,790,2270,1690,2420,1910,1930,1940,1790,1800,690
  500 IFindex>-1:PROCout(index)
  510 IFbyte1>-1:PROCout(byte1)
  520 IFbyte2>-1:PROCout(byte2)
  530 IFbyte3>-1:PROCout(byte3)
  540 IFbyte4>-1:PROCout(byte4)
  550 I%=INSTR(textl$," "):IFI%=0 ORLEFT$(textl$,3)="DEF":GOTO580
  560 J%=1:FORz%=I%TO LEN(textl$):IFMID$(textl$,z%,1)=" ":J%=z%
  570 NEXT:textl$=LEFT$(LEFT$(textl$,I%-1)+"    ",4)+" "+MID$(textl$,J%+1)
  580 ln%=line%:IFpass=1:ENDPROC
  590 PRINTTAB(19);left$;:IFright$="":PRINT ELSE PRINT",";right$
  600 ENDPROC
  610 :
  620 DEFPROCoutside
  630 IFLEFT$(textl$,1)="[":inside%=TRUE:ENDPROC
  640 IFINSTR(textl$,"=")=0:ENDPROC
  650 IFASCtextl$>126 OR INSTR(textl$,"$")<>0:ENDPROC
  660 left$="."+left$:GOSUB 2170:IFLEFT$(left$,4)=".P%=":P%=x:org%=P%:E%=P%
  670 ENDPROC
  680 :
  690 REM -----DEF-----
  700 IFMID$(textl$,4,1)="S":x$=MID$(left$,6):GOSUB 2850:P%=P%+x:RETURN
  710 frst=INSTR(left$,""""):IFfrst=0:frst=6:last=LEN(left$):GOTO730 ELSE frst=frst+1
  720 last=INSTR(left$,"""",frst+1):IFlast=0:last=LEN(left$) ELSE last=last-1
  730 IFMID$(textl$,4,1)="M":FORj%=frst TO last:PROCout(ASC(MID$(left$,j%,1))):NEXT:RETURN
  740 IFMID$(textl$,4,1)="N":FORj%=frst TO last-1:PROCout(ASC(MID$(left$,j%,1))):NEXT:PROCout(ASC(MID$(left$,last1))OR&80):RETURN
  750 x$=MID$(textl$,INSTR(left$," ")+1):GOSUB 2850
  760 IFMID$(textl$,4,1)="B":byte1=x ELSE GOSUB 2760:byte1=lb:byte2=hb
  770 RETURN
  780 :
  790 REM -----RST-----
  800 x$=MID$(textl$,5):x=EVAL(x$)AND&38:byte1=&C7 OR x:RETURN
  810 :
  820 REM -----PUSH/POP-----
  830 x$=RIGHT$(textl$,2)
  840 IFx$="IX" OR x$="IY":index=-&DD*(x$="IX")-&FD*(x$="IY"):x$="HL"
  850 IFx$="AF":byte1=-&F5*(INSTR(textl$,"U")>0)-&F1*(INSTR(textl$,"O")>0):RETURN
  860 GOSUB 3080:IFINSTR(textl$,"POP"):byte1=&C1 OR 16*EVAL("&"+x$) ELSE byte1=&C5 OR 16*EVAL("&"+x$)
  870 RETURN
  880 :
  890 REM -----LD-----
  900 textr$=FNreadR
  910 IFINSTR(textl$,"IX")+INSTR(textr$,"IX"):index=&DD
  920 IFINSTR(textl$,"IY")+INSTR(textr$,"IY"):index=&FD
  930 IFINSTR(textl$,"(")+INSTR(textr$,"(")=0:GOTO1120:REM no brackets
  940 IFINSTR(textl$,"("):GOTO1030:REM left bracket
  950 IFtextr$="(HL)" x$=RIGHT$(textl$,1):GOSUB3040:byte1=&46 OR 8*EVAL("&"+x$):RETURN
  960 x$=textr$:IFx$="(BC)" OR x$="(DE)":byte1=-&A*(x$="(BC)")-&1A*(x$="(DE)"):RETURN
  970 IFINSTR(textl$,"HL")+INSTR(textl$,"I"):byte1=&2A:x$=MID$(right$,2,LEN(right$)-2):GOSUB 2850:GOSUB 2760:byte2=lb:byte3=hb:RETURN
  980 IFINSTR(textr$,"I"):x$=RIGHT$(textl$,1):GOSUB 3040:byte1=&46 OR 8*EVAL("&"+x$):x$=MID$(right$,5,LEN(right$)-5):GOSUB 2850:byte2=x:RETURN
  990 IFRIGHT$(textl$,2)=" A":byte1=&3A:x$=MID$(textr$,2,LEN(textr$)-2):GOSUB 2850:GOSUB 2760:byte2=lb:byte3=hb:RETURN
 1000 IFINSTR(RIGHT$(textl$,2)," "):PROCerr("Must be A or double register"):RETURN
 1010 byte1=&ED:x$=RIGHT$(textl$,2):GOSUB 3080:byte2=&4B OR 16*EVAL("&"+x$):x$=MID$(right$,2,LEN(right$)-2):GOSUB 2850:GOSUB 2760:byte3=lb:byte4=hb:RETURN
 1020 :
 1030 IFLEFT$(textr$,1)="I" OR textr$="HL":byte1=&22:x$=MID$(left$,5,LEN(left$)-5):GOSUB 2850:GOSUB 2760:byte2=lb:byte3=hb:RETURN
 1040 IFINSTR(textl$,"(I"):GOTO 1100
 1050 x$=MID$(textl$,5,1):IFx$="B" OR x$="D":byte1=-&2*(x$="B")-&12*(x$="D"):RETURN
 1060 x$=textr$:IFx$="BC" OR x$="DE" OR x$="SP":byte1=&ED:GOSUB 3080:byte2=&43 OR 16*EVAL("&"+x$):x$=MID$(left$,5,LEN(left$)-5):GOSUB 2850:GOSUB 2760:byte3=lb:byte4=hb:RETURN
 1070 IFINSTR(textl$,"H")=0:byte1=&32:x$=MID$(left$,5,LEN(left$)-5):GOSUB 2850:GOSUB 2760:byte2=lb:byte3=hb:RETURN
 1080 x$=textr$:IFx$>="A" AND x$<="L":GOSUB 3040:byte1=&70 OR EVAL("&"+x$):RETURN
 1090 byte1=&36:GOSUB 2850:byte2=x:RETURN
 1100 IFtextr$>"A" AND textr$<"L":x$=textr$:GOSUB 3040:byte1=&70 OR EVAL("&"+x$):x$=MID$(left$,8,LEN(left$)-8):GOSUB 2850:byte2=x:RETURN
 1110 byte1=&36:x$=MID$(left$,8,LEN(left$)-8):GOSUB 2850:byte2=x:x$=right$:GOSUB 2850:byte3=x:RETURN
 1120 IFRIGHT$(textl$,1)="I" OR textr$="I":byte1=&ED:byte2=-&57*(textr$="I")-&47*(textr$="A"):RETURN
 1130 IFRIGHT$(textl$,1)="R" OR textr$="R":byte1=&ED:byte2=-&5F*(textr$="I")-&4F*(textr$="A"):RETURN
 1140 IFINSTR(textl$,"I"):byte1=&21:x$=textr$:GOSUB 2850:GOSUB 2760:byte2=lb:byte3=hb:RETURN
 1150 IFtextr$="HL" OR LEFT$(textr$,1)="I":byte1=&F9:RETURN
 1160 IFMID$(textl$,LEN(textl$)-1,1)>" ":x$=RIGHT$(textl$,2):GOSUB 3080:byte1=&01 OR 16*EVAL("&"+x$):x$=right$:GOSUB 2850:GOSUB 2760:byte2=lb:byte3=hb:RETURN
 1170 x$=RIGHT$(textl$,1):GOSUB 3040
 1180 IFtextr$>="A" AND textr$<="L":byte1=&40 OR 8*EVAL("&"+x$):x$=textr$:GOSUB 3040:byte1=byte1 OR EVAL("&"+x$):RETURN
 1190 byte1=&06 OR 8*EVAL("&"+x$):x$=right$:GOSUB 2850:byte2=x:RETURN
 1200 :
 1210 REM ---- EX ----
 1220 textr$=FNreadR
 1230 IFtextr$="IX":index=&DD
 1240 IFtextr$="IY":index=&FD
 1250 IFINSTR(textl$,"S"):byte1=&E3:RETURN
 1260 IFtextr$="HL":byte1=&EB ELSE byte1=&08
 1270 RETURN
 1280 :
 1290 REM ---- DJNZ ----
 1300 byte1=&10:x$=MID$(left$,INSTR(left$," ")+1):GOSUB 2850:GOSUB 2800:byte2=x:RETURN
 1310 :
 1320 REM ---- IM ----
 1330 byte1=&ED:x=VAL(RIGHT$(textl$,1))
 1340 byte2=-&46*(x=0)-&56*(x=1)-&5E*(x=2)
 1350 RETURN
 1360 :
 1370 REM ---- IN ----
 1380 textr$=FNreadR
 1390 IFtextr$="(C)" OR textr$="(BC)":byte1=&ED:x$=RIGHT$(textl$,1):GOSUB 3040:byte2=&40 OR 8*EVAL("&"+x$):RETURN
 1400 byte1=&DB:x$=MID$(right$,2,INSTR(right$,")")-2):GOSUB 2850:byte2=x:RETURN
 1410 :
 1420 REM ---- OUT ----
 1430 textr$=FNreadR
 1440 IFINSTR(textl$,"(C)"OR INSTR(textl$,"(BC)"):byte1=&ED:x$=textr$:GOSUB 3040:byte2=&41 OR 8*EVAL("&"+x$):RETURN
 1450 byte1=&D3:x$=MID$(textl$,6,INSTR(textl$,")")-6):GOSUB 2850:byte2=x:RETURN
 1460 :
 1470 REM ---- CALL ----
 1480 x$=RIGHT$(textl$,2):GOSUB 2690
 1490 IFx=-1:x$=MID$(left$,6):GOSUB 2850:GOSUB 2760:byte1=&CD:byte2=lb:byte3=hb:RETURN
 1500 byte1=&C4 OR (8*x):textr$=FNreadR:x$=right$:GOSUB 2850:GOSUB 2760:byte2=lb:byte3=hb:RETURN
 1510 :
 1520 REM ---- JR ----
 1530 x$=RIGHT$(textl$,2):GOSUB 2690
 1540 IFx=-1:x$=MID$(left$,4):GOSUB 2850:GOSUB 2800:byte1=&18:byte2=x:RETURN
 1550 byte1=&20 OR (8*x):textr$=FNreadR:x$=right$:GOSUB 2850:GOSUB 2800:byte2=x:RETURN
 1560 :
 1570 REM ---- JP ----
 1580 IFINSTR(textl$,"X"):index=&DD
 1590 IFINSTR(textl$,"Y"):index=&FD
 1600 IFINSTR(textl$,"("):byte1=&E9:RETURN
 1610 x$=RIGHT$(textl$,2):GOSUB 2690
 1620 IFx=-1:x$=MID$(left$,4):GOSUB 2850:GOSUB 2760:byte1=&C3:byte2=lb:byte3=hb:RETURN
 1630 byte1=&C2 OR (8*x):textr$=FNreadR:x$=right$:GOSUB 2850:GOSUB 2760:byte2=lb:byte3=hb:RETURN
 1640 :
 1650 REM ---- RET ----
 1660 IFtextl$="RET":byte1=&C9 ELSE x$=RIGHT$(textl$,2):GOSUB 2690:byte1=&C0 OR (8*x)
 1670 RETURN
 1680 :
 1690 REM ---- ODDS & ENDS ----
 1700 x$=textl$:byte1=-&1F*(x$="RRA")-&F*(x$="RRCA")-&37*(x$="SCF")-&3F*(x$="CCF")-&2F*(x$="CPL")-&27*(x$="DAA")-&F3*(x$="DI")-&FB*(x$="EI")-&D9*(x$="EXX")-&76*(x$="HALT")-&17*(x$="RLA")-&7*(x$="RLCA")
 1710 RETURN
 1720 :
 1730 x$=textl$:x=-&A9*(x$="CPD")-&67*(x$="RRD")-&B9*(x$="CPDR")-&A1*(x$="CPI")-&B1*(x$="CPIR")-&AA*(x$="IND")-&BA*(x$="INDR")-&A2*(x$="INI")-&B2*(x$="INIR")-&A8*(x$="LDD")-&B8*(x$="LDDR")-&A0*(x$="LDI")-&B0*(x$="LDIR")
 1740 byte2=x-&44*(x$="NEG")-&BB*(x$="OTDR")-&B3*(x$="OTIR")-&AB*(x$="OUTD")-&A3*(x$="OUTI")-&4D*(x$="RETI")-&45*(x$="RETN")-&6F*(x$="RLD")
 1750 byte1=&ED:RETURN
 1760 :
 1770 REM ---- AND/SUB/XOR ----
 1780 byte=&A6:GOTO 1840: and
 1790 byte=&96:GOTO 1840: sub
 1800 byte=&AE:GOTO 1840: xor
 1810 byte=&BE:textl$="CP "+MID$(textl$,3):GOTO1840: cp
 1820 byte=&B6:textl$="OR "+MID$(textl$,3):GOTO1840: or
 1830 :
 1840 IFINSTR(textl$,"I"):GOTO1880
 1850 IFINSTR(textl$,"HL"):byte1=byte:RETURN
 1860 x$=RIGHT$(textl$,1):IF(x$>="A" AND x$<="L"AND INSTR(textl$,"&")=0:GOSUB 3040:byte1=(byte AND &F8) OR EVAL("&"+x$):RETURN
 1870 byte1=byte OR &40:x$=MID$(textl$,5):GOSUB 2850:byte2=x:RETURN
 1880 IFINSTR(textl$,"IX"):index=&DD ELSE index=&FD
 1890 byte1=byte:x$=MID$(left$,9,INSTR(left$,")")-9):GOSUB 2850:byte2=x:RETURN
 1900 :
 1910 REM ---- SLA/SRA/SRL/RLC/RL/RRC/RR -----
 1920 byte=&26:GOTO 2000: sla
 1930 byte=&2E:GOTO 2000: sra
 1940 byte=&3E:GOTO 2000: srl
 1950 byte=&06:GOTO 2000: rlc
 1960 byte=&16:textl$="RL "+MID$(textl$,3):GOTO 2000: rl
 1970 byte=&0E:GOTO 2000: rrc
 1980 byte=&1E:textl$="RR "+MID$(textl$,3):GOTO 2000: rr
 1990 :
 2000 IFINSTR(textl$,"I"):GOTO 2040
 2010 byte1=&CB
 2020 IFINSTR(textl$,"HL"):byte2=byte:RETURN
 2030 x$=RIGHT$(textl$,1):IFx$>="A" AND x$<="L":GOSUB 3040:byte2=(byte AND &F8) OR EVAL("&"+x$):RETURN
 2040 IFINSTR(textl$,"IX"):index=&DD ELSE index=&FD
 2050 byte1=&CB:x$=MID$(left$,9,INSTR(left$,")")-9):GOSUB 2850:byte2=x:byte3=byte:RETURN
 2060 :
 2070 REM ---- INC/DEC ----
 2080 IFINSTR(textl$,"I",3):GOTO2130
 2090 byte=-1*(textl$<"I")
 2100 IFINSTR(textl$,"(H"):byte1=&34 OR byte:RETURN
 2110 IFRIGHT$(textl$,2)<"!":x$=RIGHT$(textl$,1):GOSUB 3040:byte1=byte OR (&04 OR 8*EVAL("&"+x$)):RETURN
 2120 byte=-8*(textl$<"I"):x$=RIGHT$(textl$,2):GOSUB 3080:byte1=byte OR (&03 OR 16*EVAL("&"+x$)):RETURN
 2130 IFINSTR(textl$,"IX"):index=&DD ELSE index=&FD
 2140 IFINSTR(textl$,"("):byte=-1*(textl$<"I"):byte1=&34 OR byte:x$=MID$(left$,9,INSTR(left$,")")-9):GOSUB 2850:byte2=x:RETURN
 2150 byte=-8*(textl$<"I"):byte1=&23 OR byte:RETURN
 2160 :
 2170 REM ---- LABEL ----
 2180 k%=-1:x$=MID$(left$,2):IFASCx$>126:RETURN
 2190 IFINSTR(x$,"=")>0:x$=LEFT$(x$,INSTR(x$,"=")-1)
 2200 FORj%=0 TO numl:IFx$=label$(j%):k%=j%
 2210 NEXT:IFk%=-1:k%=numl:numl=numl+1
 2220 IFnuml>maxlabs:PROCerr("Too many labels"):ENDPROC
 2230 label$(k%)=x$:IFINSTR(left$,"=")=0:x=P%:value(k%)=x:RETURN
 2240 x$=MID$(left$,INSTR(left$,"=")+1):GOSUB 2850:value(k%)=x
 2250 RETURN
 2260 :
 2270 REM ---- SBC/ADC ----
 2280 byte=&9E:GOTO 2300: sbc
 2290 byte=&8E:GOTO 2300: adc
 2300 textr$=FNreadR
 2310 IFINSTR(textl$,"HL"):x$=textr$:GOSUB 3080:byte1=&ED:byte2=(&42 OR 16*EVAL("&"+x$))+(8 AND textl$<"S"):RETURN
 2320 IFtextr$>="A" AND textr$<="L":byte=byte AND &F8:x$=textr$:GOSUB 3040:byte1=byte+EVAL("&"+x$):RETURN
 2330 IFtextr$="(HL)":byte1=byte:RETURN
 2340 IFINSTR(textr$,"I"):GOTO 2360
 2350 byte1=byte OR &40:x$=right$:GOSUB 2850:byte2=x:RETURN
 2360 IFINSTR(textr$,"IX"):index=&DD ELSE index=&FD
 2370 byte1=byte:x$=MID$(right$,5,INSTR(right$,")")-5):GOSUB 2850:byte2=x:RETURN
 2380 :
 2390 REM ---- BIT/SET/RES ----
 2400 byte=&40:GOTO 2430: bit
 2410 byte=&80:GOTO 2430: res
 2420 byte=&C0:GOTO 2430: set
 2430 textr$=FNreadR:x=VAL(RIGHT$(textl$,1)):byte2=byte+8*x
 2440 IFINSTR(textr$,"I"):GOTO 2480: ix/iy
 2450 byte1=&CB
 2460 IFtextr$="(HL)":byte2=byte2+&6:RETURN
 2470 x$=textr$:GOSUB 3040:byte2=byte2+EVAL("&"+x$):RETURN
 2480 IFINSTR(textr$,"IX"):index=&DD ELSE index=&FD
 2490 byte3=byte2+&6:byte1=&CB:x$=MID$(right$,5,INSTR(right$,")")-5):GOSUB 2850:byte2=x:RETURN
 2500 :
 2510 REM ---- ADD ----
 2520 textr$=FNreadR
 2530 IFINSTR(textl$,"Y"):index=&FD
 2540 IFINSTR(textl$,"X"):index=&DD
 2550 IFINSTR(textl$,"L"OR INSTR(textl$,"I"):x$=textr$:GOSUB 3080:byte1=&09 OR 16*EVAL("&"+x$):RETURN
 2560 IFtextr$>="A" AND textr$<="L":x$=textr$:GOSUB 3040:byte1=&80+EVAL("&"+x$):RETURN
 2570 IFtextr$="(HL)":byte1=&86:RETURN
 2580 IFINSTR(textr$,"I"):GOTO 2600: adc a,(ix/iy+n)
 2590 byte1=&C6:x$=right$:GOSUB 2850:byte2=x:RETURN
 2600 IFINSTR(textr$,"Y"):index=&FD ELSE index=&DD
 2610 byte1=&86:x$=MID$(right$,5,INSTR(right$,")")-5):GOSUB 2850:byte2=x:RETURN
 2620 :
 2630 DEFPROCout(x):P%=P%+1:IFpass=1:ENDPROC
 2640 IFout%:BPUT#out%,x
 2650 IFPOS>16:PRINT'SPC6;
 2660 PRINTRIGHT$("0"+STR$~x,2);" ";
 2670 ENDPROC
 2680 :
 2690 REM ---- GET CODE FOR CONDITION x$ -> x ----
 2700 x=-1
 2710 FORj%=0 TO 7
 2720   IFx$=cond$(j%):x=j%
 2730 NEXT
 2740 RETURN
 2750 :
 2760 REM ---- X -> lowbyte,hibyte ----
 2770 lb=x AND 255:hb=x DIV 256
 2780 RETURN
 2790 :
 2800 REM ---- CALCULATE JUMP ----
 2810 IFx>255:x=x-P%-2:IFx>255:PROCerr("Too far for relative jump"):ENDPROC
 2820 IFx<0:x=x+256
 2830 RETURN
 2840 :
 2850 REM ---- x$,number/label -> x,number ----
 2860 xf=0:REM PRINT"#"x$"#"
 2870 IFLEFT$(x$,1)="<":x$=MID$(x$,2):GOSUB 2850:x=x AND 255:RETURN
 2880 IFLEFT$(x$,1)=">":x$=MID$(x$,2):GOSUB 2850:x=x DIV 256:RETURN
 2890 IFx$<"!":REPEAT:x$=MID$(x$,2):UNTILx$+"#">="!"
 2900 ins=INSTR(x$,"+"):xx=0:IFins=0:GOTO 2960
 2910 xx$=MID$(x$,ins+1):x$=LEFT$(x$,ins-1)
 2920 IFLEFT$(xx$,1)="&":xx=EVAL(xx$)-65536*(EVAL(xx$)<0):GOTO2960
 2930 IFLEFT$(xx$,1)>="0" AND LEFT$(xx$,1)<="9":xx=VAL(xx$):GOTO2960
 2940 IFLEFT$(xx$,1)="%":xx=EVAL(xx$):GOTO2960:REM **** binary ****
 2950 PROCerr("Illegal index. Must be a number"):ENDPROC
 2960 IFLEFT$(x$,1)="&":x=xx+EVAL(x$)-65536*(EVAL(x$)<0):RETURN
 2970 IFLEFT$(x$,1)>="0" AND LEFT$(x$,1)<="9":x=xx+VAL(x$):RETURN
 2980 IFLEFT$(x$,1)="%":x=xx+EVAL(xx$):RETURN:REM **** binary ****
 2990 x=-1:FORj%=0 TO numl:IFlabel$(j%)=x$:x=xx+value(j%):j%=numl+1:xf=-1
 3000 NEXT:IFNOTxf:IFpass=1:x=P%:RETURN
 3010 IFNOTxf:PROCerr("No such label"):errs%=errs%+(NOTinside%):RETURN
 3020 RETURN
 3030 :
 3040 REM ----- x$,register -> x$,hex code -----
 3050 x$=STR$~(ASC(x$)-66-8*(x$="A")+2*(x$="H")+5*(x$="L"))
 3060 RETURN
 3070 :
 3080 REM x$,reg pair -> x$,hex code
 3090 IFx$="BC":x$="0"
 3100 IFx$="DE":x$="1"
 3110 IFx$="HL" OR x$="IX" OR x$="IY":x$="2"
 3120 IFx$="SP":x$="3"
 3130 RETURN
 3140 :
 3150 REM ----- CLASSES -----
 3160 DATA END,.,ADC,ADD,AND,BIT,CALL,CCF,CP,CPD,CPDR,CPI,CPIR,CPL,DAA,DEC,DI,DJNZ,EI,EX,EXX,HALT,IM,IN,INC,IND,INDR,INI,INIR,JP,JR,LD,LDD,LDDR,LDI,LDIR,NEG,NOP,OR,OTDR,OTIR
 3170 DATA OUT,OUTD,OUTI,POP,PUSH,RES,RET,RETI,RETN,RL,RLA,RLCA,RLC,RLD,RR,RRA,RRC,RRCA,RRD,RST,SBC,SCF,SET,SLA,SRA,SRL,SUB,XOR,DEF
 3180 DATA NZ," Z",NC," C",PO,PE," P"," M"
 3190 :
 3200 REM ---- LABELS USED ----
 3210 PRINT'"Labels defined:"
 3220 FORa=0 TO numl-1
 3230   PRINTLEFT$(label$(a)+RIGHT$(STRING$(6," ."),12-LENlabel$(a)),12)"&"RIGHT$("0000"+STR$~value(a),4)"   ";
 3240 NEXT:IFPOS:PRINT
 3250 RETURN
 3260 :
 3270 DEFFNup(A$):LOCALA%:FORA%=1TOLENA$:IFMID$(A$,A%,1)>"`":A$=LEFT$(A$,A%-1)+CHR$(ASCMID$(A$,A%,1)AND&DF)+MID$(A$,A%+1)
 3280 NEXT:=A$
 3290 :
 3300 DEFFNreadL:left$=FNexp(FNread):=FNup(left$)
 3310 DEFFNreadR:right$=FNread:=FNup(right$)
 3320 DEFFNread:LOCAL A$,B$,C$:C$=",:"
 3330 REPEAT:B$=FNbget:A$=A$+B$:IFB$="""" ORINSTR(";\",LEFT$(A$,1)):C$=CHR$0
 3340 UNTILB$=CHR$13 OR INSTR(C$,B$) OR B$="" OR B$=":"
 3350 IFB$=CHR$13:line%=256*ASCFNbget+ASCFNbget:B$=FNbget:B$=CHR$13
 3360 =LEFT$(A$,LENA$-LENB$)
 3370 DEFFNbget:IFEOF#in%:=""
 3380 =CHR$BGET#in%
 3390 :
 3400 DEFFNexp(A$):IFA$="":=""
 3410 LOCAL A,B$,C$:REPEAT:A=A+1:UNTILMID$(A$,A,1)>"~" OR A>LENA$:IFA>LENA$:=A$
 3420 FORA=1 TO LEN A$:B$=MID$(A$,A,1)
 3430   IFB$=CHR$128:B$="AND"
 3440   IFB$=CHR$132:B$="OR"
 3450   IFB$=CHR$151:B$="ASC"
 3460   IFB$=CHR$214:B$="CALL"
 3470   IFB$=CHR$221:B$="DEF"
 3480   IFB$=CHR$224:B$="END"
 3490 C$=C$+B$:NEXT:=C$