2068 Assembler

Date: 198x
Type: Program
Platform(s): TS 2068

A rather nice assembler utility, adapted from the ZX Spectrum Assembler in Phipps Associates’ Machine Code Tools.

Appears on

Capital Area Timex Sinclair User Group’s Library Tape.

Source Code

   10 REM (
   20 REM org 65367!ld a,2!call 1601H!ld a,12H!rst 10H!ld a,1!rst 10H
   30 REM ld a,42H!rst 10H!ld a,4fH!rst 10H!ld a,42H!rst 10H
   40 REM ld a,20H!rst 10H!ld a,47H!rst 10H!ld a,49H!rst 10H!ld a,4cH!rst 10H
   50 REM ld a,44H!rst 10H!ld a,45H!rst 10H!ld a,52H!rst 10H!ld a,20H!rst 10H
   60 REM ret
   70 REM )
 1000 REM 2068 ASSEMBLER
 1002 REM ZXASM 48K extension
 1005 LET j=VAL "1": IF PEEK VAL "23731">VAL "127" THEN GO SUB VAL "7900"
 1010 LET ns=64: LET nu=64
 1015 CLS : PRINT " *** T/S 2068 ASSEMBLER *** ": PRINT '"RAM available:";(PEEK 23733-63)/4;"K"'"RAMTOP value : ";: LET h=FN i(23730): GO SUB 9100: PRINT h;" (";h$;"H)"
 1020 DEF FN a(x$)=(x$>="A" AND x$<="Z")
 1030 DEF FN n(x$)=(x$>="0" AND x$<="9")
 1035 DEF FN s$(x)=a$(x(x,j)+j TO x(x,2))
 1040 DEF FN h(x)=INT (x/256)
 1050 DEF FN L(x)=x-256*FN h(x)
 1060 DEF FN j()=(m$="JP" OR m$="CALL" OR m$="RET" OR m$="JR")
 1070 DEF FN v(x$)=CODE x$(7)+256*CODE x$(8)
 1080 DEF FN i(x)=PEEK x+256*PEEK (x+j)
 1085 DEF FN r()=di-vdef*(add+2)
 1090 DIM s$(ns+nu+j+j,VAL "8"): DIM L$(VAL "6"): DIM t$(VAL "2")
 1095 LET s$(j)=CHR$ NOT j
 1100 LET u=NOT j: LET er=u: LET ed=VAL "237"
 1110 LET m$="HARD COPY?": GO SUB 9000: LET hc=j+j+(CHR$ CODE a$="Y")
 1120 LET m$="Auto scan?": GO SUB 9000: LET auto=(CHR$ CODE a$="Y"): IF auto THEN LET m$="Merge source from tape?": GO SUB 9000: IF CHR$ CODE a$="Y" THEN INPUT "Enter tape name:"; LINE a$: CLS : PRINT AT 8,2;"START TAPE THEN PRESS A KEY": PAUSE 4e4: CLS : MERGE a$
 1125 IF auto THEN GO SUB 7800
 1130 LET add=FN i(VAL "23730")+VAL "1": REM get default address
 1140 CLS : PRINT #hc;"ADDR HEX      OP   OPERANDS     "
 1200 LET e=NOT j: LET vdef=j: LET ds=e: LET dd=e: LET ec=e: LET b=e: LET w=e
 1210 LET h=add: GO SUB 9100: LET m$=h$: GO SUB 7700: IF end THEN GO TO VAL "5000"
 1220 LET m$=""
 1230 DIM t(2): DIM x(4,2): LET t=NOT j: LET p=j: LET t$="00"
 1240 FOR x=j TO LEN a$: REM now scan input line
 1245 IF a$(x)=";" THEN GO TO 1300: REM ignore comments
 1250 IF t<>(a$(x)<>" " AND a$(x)<>",") THEN LET x(p,t+j)=x-j: LET p=p+t: LET t=NOT t: IF p>4 THEN GO TO 1310: REM mark word ends
 1260 NEXT x
 1300 IF x(p,j) OR p=j THEN LET x(p,j+j)=x-j
 1310 LET bx=(FN s$(j)(LEN FN s$(j))=":"): REM check for symbol
 1320 LET m$=FN s$(j+bx): REM get instruction
 1400 LET jump=FN j(): REM is this a JP/JR/CALL?
 1410 FOR t=j TO j+j: LET x$=FN s$(j+t+bx): GO SUB 7400: NEXT t: REM determine op classes
 1500 LET n$=t$+m$: REM create scanning code
 1510 LET f1=(LEN FN s$(bx+2)<>0): LET f2=(LEN FN s$(bx+3)<>0): IF f1 THEN GO TO 1600: REM find how many ops
 1520 IF m$="" THEN GO TO 1900: REM no instruction
 1530 FOR b=j TO j+j: LET i=VAL "2010+b*10": GO SUB 8300: IF NOT x THEN NEXT b: REM vet no op type
 1550 GO TO 1630
 1600 LET i=VAL "2060+f2*20": LET b=NOT j: REM vet 1/2 op types
 1610 GO SUB 8300: IF NOT x+f2 THEN LET i=2070: GO SUB 8300
 1615 IF x THEN GO TO 1650
 1620 RESTORE VAL "2000+40*(f2=0)": GO SUB 8400: IF x THEN GO TO 1800
 1630 IF NOT x THEN LET ec=VAL "9": REM invalid instruction
 1640 GO TO 1800
 1650 LET n=x-j: RESTORE i+j: LET n$=t$: GO SUB 8400: IF NOT x THEN LET ec=VAL "9"
 1800 IF ec THEN GO TO 1960: REM don't output if error
 1820 IF m$="ORG" THEN LET add=di: LET h=di: GO SUB 9100: REM check for pseudo-op
 1830 IF e THEN POKE add,dd: IF e=j+j THEN POKE add+j+j,dis: REM echeck if IX/IY class output displacement
 1840 FOR x=0 TO b-j: READ x$: POKE add+x+(e<>0)+x*(e=2),VAL x$: NEXT x: REM output machine code
 1900 IF NOT vdef THEN GO SUB 7200: REM undefined symbol?
 1910 IF NOT bx OR ec THEN GO TO 1960: REM check for label
 1920 LET L$=FN s$(bx)( TO LEN FN s$(bx)-j): GO SUB 7600: IF v THEN LET ec=2: GO TO 1960: REM does it already exist?
 1925 IF s=ns+j THEN LET ec=VAL "99": GO TO 1960: REM full table
 1930 LET v=add: IF m$="EQU" THEN LET v=di: REM re-equate
 1940 LET s$(s)=L$: LET s$(s,7 TO )=CHR$ FN L(v)+CHR$ FN h(v)
 1950 LET s$(j)=CHR$ (s-j): REM update symbol count
 1960 GO SUB 7300: IF ec THEN LET er=er+j: GO TO VAL "1200": REM print line
 1970 LET add=add+b+e: REM update address
 1990 GO TO 1200: REM await new input
 2000 DATA "11LD","1","1","64+t(1)*8+t(2)"
 2001 DATA "13LD","vdef","2","t(1)*8+6","ds"
 2002 DATA "14LD","t(1)=7","3","58","ds","dh"
 2003 DATA "15LD","(t(1)=7)*(t(2)<2)","1","t(2)*16+10"
 2004 DATA "23LD","t(1)<>6","3","t(1)*16+1","ds","dh"
 2005 DATA "24LD","t(1)=2","3","42","ds","dh"
 2006 DATA "24LD","t(1)<4","4","ed","75+t(1)*16","ds","dh"
 2007 DATA "41LD","t(2)=7","3","50","ds","dh"
 2008 DATA "42LD","t(2)=2","3","34","ds","dh"
 2009 DATA "42LD","t(2)<4","4","ed","67+t(2)*16","ds","dh"
 2010 DATA "51LD","(t(2)=7)*(t(1)<2)","1","t(1)*16+2"
 2011 DATA "99","","2100"
 2020 DATA "RET","201","NOP","0","RLCA","7","RRCA","15","RLA","23","RRA","31","DAA","39","CPL","47","SCF","55","CCF","63","HALT","118","EXX","217","DI","243","EI","251","99",""
 2030 DATA "NEG","ED","68","RETN","ED","69","RETI","ED","77","RRD","ED","103","RLD","ED","111","LDI","ED","160","LDIR","ED","176","LDD","ED","168","LDDR","ED","184","CPD","ED","169","CPDR","ED","185","CPI","ED","161","CPIR","ED","177"
 2031 DATA "INI","ED","162","INIR","ED","178","IND","ED","170","INDR","ED","186","OUTI","ED","163","OTIR","ED","179","OUTD","ED","171","OTDR","ED","187","99","",""
 2040 DATA "30JR","ABS FN r()<128","2","24","FN r()"
 2041 DATA "10INC","1","1","4+t(1)*8"
 2042 DATA "20INC","t(1)<>4","1","3+t(1)*16"
 2043 DATA "10DEC","1","1","5+t(1)*8"
 2044 DATA "20DEC","t(1)<>4","1","11+t(1)*16"
 2045 DATA "30DJNZ","ABS FN r()<128","2","16","FN r()"
 2046 DATA "60RET","1","1","192+t(1)*8"
 2047 DATA "20POP","t(1)<>3","1","193+t(1)*16-16*(t(1)=4)"
 2048 DATA "20PUSH","t(1)<>3","1","197+t(1)*16-16*(t(1)=4)"
 2049 DATA "30RST","vdef AND ds<=56","1","199+INT (ds/8)*8"
 2050 DATA "10JP","t(1)=6","1","233"
 2051 DATA "30IM","vdef*(ds<3)*(ds>=0)","2","ed","70+16*(ds=1)+24*(ds=2)"
 2052 DATA "30JP","1","3","195","ds","dh"
 2053 DATA "30CALL","1","3","205","ds","dh"
 2054 DATA "30DEFB","vdef","1","ds"
 2055 DATA "30DEFW","vdef","2","ds","dh"
 2056 DATA "30ORG","vdef","0"
 2057 DATA "30EQU","vdef AND bx","0"
 2059 DATA "99","","0"
 2060 DATA "","","SUB","","AND","XOR","OR","CP","99"
 2061 DATA "10","1","1","128+n*8+t(1)"
 2062 DATA "30","vdef","2","198+n*8","ds"
 2063 DATA "99","","0"
 2070 DATA "RLC","RRC","RL","RR","SLA","SRA","","SRL","99"
 2071 DATA "10","1","2","203","n*8+t(1)"
 2072 DATA "99","","0"
 2080 DATA "ADD","ADC","","SBC","99"
 2081 DATA "11","t(1)=7","1","128+n*8+t(2)"
 2082 DATA "13","t(1)=7","2","198+n*8","ds"
 2083 DATA "22","(t(1)=2)*(t(2)<>4)*(n=0)","1","9+t(2)*16"
 2084 DATA "22","(t(1)=2)*(t(2)<>4)*(n<>0)","2","ed","78-n*4+t(2)*16"
 2085 DATA "99","","0"
 2100 DATA "63JP","1","3","194+t(1)*8","ds","dh"
 2101 DATA "63JR","t(1)<4 AND ABS FN r()<128","2","32+t(1)*8","FN r()"
 2102 DATA "22EX","(t(1)=4)*(t(2)=4)","1","8"
 2103 DATA "22EX","(t(1)=1)*(t(2)=2)","1","235"
 2104 DATA "52EX","(t(1)=3)*(t(2)=2)","1","227"
 2112 DATA "31BIT","vdef AND ds<8","2","203","64+ds*8+t(2)"
 2113 DATA "31RES","vdef AND ds<8","2","203","128+ds*8+t(2)"
 2114 DATA "31SET","vdef AND ds<8","2","203","192+ds*8+t(2)"
 2117 DATA "63CALL","1","3","196+t(1)*8","ds","dh"
 2120 DATA "14IN","vdef AND t(1)=7","2","219","ds"
 2121 DATA "41OUT","vdef AND t(2)=7","2","211","ds"
 2122 DATA "17IN","t(1)<>6","2","ed","64+t(1)*8"
 2123 DATA "71OUT","t(2)<>6","2","ed","65+t(2)*8"
 2200 DATA "99","","0"
 2201 REM end of program
 5000 IF CODE s$(j) THEN PRINT #hc''"Symbols:"': FOR y=VAL "2" TO VAL "CODE s$(1)+1": LET h=FN v(s$(y)): GO SUB 9100: PRINT #hc;TAB VAL "((y-2)*16+1)";s$(y, TO 6);" ";h$;: NEXT y: REM list symbol table
 5010 LET n=NOT j: REM scan unresolved table
 5020 FOR t=ns+3 TO ns+2+u: LET add=FN v(s$(t)): LET c=PEEK add: LET L$=s$(t): GO SUB 7600: IF v THEN GO TO 5050: REM does it exist?
 5030 IF NOT n THEN PRINT #hc''"Unresolved:"
 5040 LET n=n+j: LET h=add: GO SUB 9100: PRINT #hc;" ";L$;" ";h$: GO TO 5100: REM no-print it
 5050 RESTORE 9920: LET di=FN i(add+j): LET ds=FN L(di): LET di=VAL "di-65536*(di>32767)": REM determine type
 5055 LET ds=VAL "ds-256*(ds>127)"
 5060 READ c$,a$,x$: IF NOT VAL c$ THEN FOR x=j TO VAL x$: READ x$: NEXT x: GO TO 5060
 5070 FOR x=j TO VAL a$: READ y$: POKE FN v(s$(t))+VAL x$+x-j,VAL y$: NEXT x: REM relocate output
 5100 NEXT t
 5200 IF er+n THEN PRINT #hc'er+n;"Error(s)": REM any errors?
 5210 GO TO 9999
 7200 REM undefined
 7210 LET u=u+j: IF u>nu THEN LET ec=VAL "98": RETURN 
 7220 LET s$(ns+u+j+j)=s$(ns+j+j, TO 6)+CHR$ FN L(add)+CHR$ FN h(add)
 7230 RETURN 
 7300 REM print detail line
 7310 IF ec THEN PRINT #hc;h$;" "; INVERSE j;"ERROR ";ec; INVERSE NOT j;TAB 14;a$: RETURN 
 7320 IF bx THEN PRINT #hc;h$;TAB VAL "13";FN s$(j)
 7330 IF m$="" THEN RETURN : REM no mnemonic entered
 7340 PRINT #hc;h$; INVERSE j;"*" AND (NOT vdef); INVERSE 0;TAB 5;: FOR y=0 TO b+e-j: LET h=PEEK (add+y): GO SUB 9120: PRINT #hc;h$;: NEXT y
 7350 PRINT #hc;TAB 14;m$;TAB 19;FN s$(j+j+bx);"," AND f2;FN s$(3+bx)
 7360 RETURN 
 7400 REM check type  classify operands
 7405 LET x=LEN x$: IF NOT x THEN RETURN 
 7410 LET ix=(x$(j)="("): IF ix THEN LET x$=x$(2 TO LEN x$-j)
 7415 GO SUB 7500
 7420 RESTORE 9900+jump: READ n: FOR x=0 TO n-j: READ c$: IF x$=c$ THEN GO TO 7450
 7425 NEXT x
 7430 LET t$(t)=("3" AND (NOT ix))+("4" AND ix)
 7440 GO SUB 8500: LET di=a+w: LET dh=FN h(di): LET ds=FN L(di): RETURN 
 7450 LET t(t)=x: IF jump AND (NOT ix) THEN LET t$(t)="6": RETURN 
 7460 LET t$(t)="111111112222222070000005515011"(ix*15+x+j)
 7470 IF x>=13 THEN LET e=j+ix-jump: LET dd=VAL "dd+(dd=0)*(221+32*(x=14))": LET dis=w: LET x=10
 7475 IF x>7 THEN LET t(t)=x-8
 7480 IF ix AND t$(t)="1" THEN LET t(t)=6
 7490 RETURN 
 7500 FOR x=j+j TO LEN x$: IF x$(x)="+" OR x$(x)="-" THEN GO TO 7550: REM calculate offset
 7510 NEXT x
 7520 LET w=NOT j: RETURN 
 7550 LET z$=x$( TO x-j): LET x$=x$(x TO ): GO SUB 8900: LET x$=z$
 7560 LET w=x
 7570 RETURN 
 7600 REM find symbol
 7610 LET v=j: REM set as found
 7620 FOR s=2 TO CODE s$(j)+j: IF L$=s$(s, TO 6) THEN LET a=FN v(s$(s)): RETURN 
 7630 NEXT s: LET v=0: REM not found
 7640 RETURN 
 7700 IF NOT auto THEN GO TO 9000
 7710 LET end=0: IF FN i(auto-1)=10730 THEN LET end=1: RETURN 
 7720 LET a$=""
 7730 IF PEEK auto=13 THEN GO TO 7760
 7735 IF PEEK auto=33 THEN LET auto=auto+1: GO TO 7770
 7740 LET a$=a$+CHR$ PEEK auto
 7750 LET auto=auto+1: GO TO 7730
 7760 LET auto=auto+6
 7770 IF NOT LEN a$ THEN GO TO 7710
 7780 GO TO 9020
 7800 REM Auto start
 7810 PRINT AT 10,10;"Searching..."
 7820 LET x=FN i(23635): LET y=FN i(23627)
 7830 IF x>=y THEN LET auto=0: RETURN 
 7840 IF PEEK (x+4)=234 THEN GO TO 7860
 7850 LET x=x+4+FN i(x+2): GO TO 7830
 7860 IF PEEK (x+5)<>40 THEN GO TO 7850
 7870 LET auto=x+6
 7880 RETURN 
 7900 REM This allows reruns
 7910 RETURN 
 8300 REM find op (1)
 8310 RESTORE i: LET x=0
 8320 READ x$: IF x$="99" THEN LET x=0: RETURN : REM scan tables
 8330 LET x=x+j: IF m$=x$ THEN RETURN : REM return if found
 8340 FOR y=j TO b: READ x$: NEXT y: REM skip to next item
 8350 GO TO 8320
 8400 REM find op (2)
 8410 READ x$,c$,y$: LET z=VAL y$: IF x$="99" THEN GO TO 8450: REM scan tables
 8420 IF x$=n$ THEN LET x=VAL c$: IF x THEN LET b=z: RETURN : REM return if found
 8430 FOR y=j TO z: READ x$: NEXT y: REM skip to next item
 8440 GO TO 8410
 8450 LET x=0: IF NOT z THEN RETURN 
 8460 RESTORE z: GO TO 8410
 8500 REM convert type   determine address
 8505 LET a=0
 8510 GO SUB 8900: IF v THEN LET a=x: LET ec=VAL "6*(x>65535 OR x<-32768)": RETURN : REM check if decimal
 8520 IF FN n(x$(j)) AND x$(LEN x$)="H" THEN FOR x=j TO LEN x$-j: LET a=VAL "a*16+CODE x$(x)-48-7*(x$(x)>""9"")": NEXT x: RETURN : REM check if hex
 8530 LET L$=x$: GO SUB 7600: IF v THEN RETURN : REM scan tables
 8560 LET ec=VAL "6*(FN a(x$(1))=0)": IF ec THEN RETURN 
 8570 LET s$(ns+2)=x$: LET vdef=NOT j: REM flag unresolved
 8580 RETURN 
 8900 REM vet numeric
 8910 LET z=j+VAL "((x$(1)=""+"") OR (x$(1)=""-"")) AND LEN x$>1"
 8920 FOR n=z TO LEN x$: IF FN n(x$(n)) THEN NEXT n
 8930 LET v=(n>LEN x$): IF v THEN LET x=VAL x$( TO n-j)
 8940 RETURN 
 9000 REM kybrd
 9010 INPUT (m$+" "); LINE a$: LET end=NOT LEN a$
 9020 FOR x=j TO LEN a$: LET a$(x)=CHR$ (CODE a$(x)-32*(a$(x)>="a")): NEXT x
 9030 RETURN 
 9100 REM h$=hex$(h)
 9110 LET h$="    ": GO TO 9130: REM 4 spaces
 9120 LET h$="  ": REM 2 spaces
 9130 LET h1=h: FOR x=LEN h$ TO j STEP -j: LET x1=h1-INT (h1/16)*16: LET h$(x)=CHR$ (x1+CODE "0"+7*(x1>9)): LET h1=INT (h1/16): NEXT x
 9140 RETURN 
 9900 DATA 15,"B","C","D","E","H","L","M","A","BC","DE","HL","SP","AF","IX","IY"
 9901 DATA 15,"NZ","Z","NC","C","PO","PE","P","M","","","HL","","","IX","IY"
 9920 DATA "(c-INT (c/8)*8)+INT (c/64)=0","1","1","ds+FN L(a-add-2)"
 9921 DATA "c=ed OR c=221 OR c=253","2","2","FN L(a+di)","FN h(a+di)"
 9922 DATA "1","2","1","FN L(a+di)","FN h(a+di)"

People

No people associated with this content.

Scroll to Top