2068 Assembler

This file is part of and CATS Library Tape 8. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 2068

This program is a Z80 assembler written entirely in BASIC, targeting the T/S 2068 and capable of assembling Z80 source code entered interactively or merged from tape. It supports the full Z80 instruction set including ED-prefix and CB-prefix opcodes, IX/IY indexed addressing with displacement, conditional jumps and calls, pseudo-ops (ORG, EQU, DEFB, DEFW), a symbol table with forward-reference resolution, and optional hard-copy output. The assembler uses a table-driven architecture: operand types are encoded as numeric class codes (e.g., register class 1–7, indirect class with parentheses), and instruction dispatch is handled by a two-pass table scan through the DATA statements at lines 2000–2200. An embedded REM block at lines 10–70 contains commented Z80 assembly source for a short machine-code routine that prints “BOB GILDER” via ROM calls, illustrating the tool’s own use case.

Adapted from the ZX Spectrum Assembler in Phipps Associates’ Machine Code Tools.


Program Analysis

Program Structure

The assembler is organized into several well-defined regions:

  1. Lines 10–70: Embedded REM block containing commented Z80 assembly source (the program’s own demonstration).
  2. Lines 1000–1140: Initialization — function definitions, symbol table allocation, display setup, hard-copy and auto-scan options.
  3. Lines 1200–1990: Main assembly loop — line input, tokenization, operand classification, instruction lookup, code emission, symbol definition.
  4. Lines 2000–2200: DATA tables encoding the Z80 instruction set in a structured, table-driven format.
  5. Lines 5000–5210: End-of-assembly pass — symbol table listing, unresolved forward-reference patching, error summary.
  6. Lines 7200–7900: Subroutines — undefined symbol handling, line printing, operand classification, offset calculation, auto-scan source locator, symbol lookup.
  7. Lines 8300–8900: Table search routines and numeric/hex/symbol value resolution.
  8. Lines 9000–9140: Keyboard input (with uppercase normalization), hex formatter.
  9. Lines 9900–9922: Register/condition name DATA tables and forward-reference relocation DATA.

Function Definitions

FunctionPurpose
FN a(x$)Returns true if x$ is an uppercase letter A–Z
FN n(x$)Returns true if x$ is a digit 0–9
FN s$(x)Extracts the x-th scanned token from a$ using the x() position array
FN h(x)High byte of a 16-bit value (INT(x/256))
FN L(x)Low byte of a 16-bit value (x mod 256)
FN j()True if current mnemonic is JP, JR, CALL, or RET (jump-class)
FN v(x$)Extracts 16-bit address stored in bytes 7–8 of a symbol table entry
FN i(x)Reads a 16-bit little-endian word from memory at address x
FN r()Computes relative jump displacement: di - vdef*(add+2)

Symbol Table Design

The symbol table is a DIMensioned string array s$() of 8-character entries. The first entry s$(1) stores the current symbol count as CHR$ of the count value. Entries 2 through ns+1 (64 entries) hold defined labels; entries ns+3 upward (another 64 slots) hold forward-reference (unresolved) entries. Each entry stores up to 6 characters of the label name, followed by 2 bytes encoding the associated address in little-endian form using CHR$ FN L(v) + CHR$ FN h(v). The FN v(s$(y)) function recovers this address by reading CODE x$(7) + 256*CODE x$(8).

Operand Classification System

After tokenization, each operand string is classified into a numeric type stored in both t() (integer) and t$() (character). The classification table at line 9900 lists 15 register/condition names; the lookup index becomes the operand class. The string "111111112222222070000005515011" at line 7460 is a compact encoding mapping register indices to operand type codes (1=8-bit reg, 2=16-bit reg pair, etc.). Indirect addressing (parenthesized operands) shifts the type classification by 15 positions in this string. IX/IY with displacement are detected at index 13/14, setting the e flag and storing the displacement in dis.

Table-Driven Instruction Encoding

Each DATA record for an instruction has the form: a scan-code string (combining operand type digits and mnemonic), a validity expression (evaluated with VAL), a byte count, and then byte-value expressions. The two-level search uses GO SUB 8300 to match the mnemonic and GO SUB 8400 to match the full operand-type signature. Byte values are themselves BASIC expressions (e.g., "64+t(1)*8+t(2)", "198+n*8") evaluated at emit time with VAL x$, making a compact and general encoding scheme.

The variable n$ at line 1500 concatenates the two operand type characters with the mnemonic to form the composite key used in the second-level search. The DATA sections are organized by operand-count class: lines 2010–2011 for zero-operand single-byte, 2020–2031 for zero-operand multi-byte, 2040–2059 for single-operand, 2060–2085 for one/two-operand arithmetic, and 2100–2200 for conditional forms.

Forward Reference Resolution

When an operand cannot be resolved at assembly time, the symbol name is stored in s$(ns+2) and the vdef flag is set. The address of the instruction needing patching is added to the unresolved table (lines 7200–7230). At end-of-assembly (lines 5020–5100), each unresolved entry is looked up in the symbol table; if found, the relocation DATA at lines 9920–9922 is used to determine how many bytes to patch and what values to write. Three relocation cases are handled: relative jumps (case 0), ED/DD/FD prefixed instructions (case 1), and absolute 16-bit addresses (case 2), distinguished by inspecting the first opcode byte at the patch address.

Auto-Scan Mode

The auto-scan feature (lines 7800–7880 and 7700–7780) locates BASIC source lines in memory by searching the BASIC program area using the system variables at addresses 23635 (PROG) and 23627 (VARS), walking line headers to find a line beginning with token 234 (the keyword encoding checked at line 7840) and the character code 40 at offset 5. This allows the assembler to read its own source program’s REM blocks or embedded assembly source directly from the BASIC line store without tape or keyboard input.

Hex Formatter

Lines 9100–9140 implement a hex formatter that converts an integer h into a 4-digit (or 2-digit) hex string h$ by repeated modulo-16 decomposition. Digits above 9 are adjusted by adding 7 to the character code to produce A–F, a standard Sinclair BASIC hex-formatting idiom.

Notable Techniques

  • The scalar variable j is initialized to 1 and used pervasively as a literal 1 substitute, saving tokenized bytes in the program store.
  • NOT j evaluates to 0 and NOT NOT j to 1, used to initialize boolean flags compactly.
  • VAL "number" is used extensively in GO TO, GO SUB, and numeric contexts as a memory optimization to store numbers as strings rather than 5-byte floating-point literals.
  • Validity expressions in the DATA tables (e.g., "vdef AND ds<=56") are evaluated via VAL c$ at runtime, giving a data-driven conditional assembly check without additional BASIC code.
  • Byte-value expressions in DATA (e.g., "192+t(1)*8") are similarly VAL-evaluated, encoding the Z80 opcode arithmetic directly in the table strings.
  • The PRINT #hc; idiom sends output to stream hc, which is 0 (screen only), 1 (printer only), or 2 (both), depending on the hard-copy option selected at startup.
  • Line 1095 uses CHR$ NOT j (i.e., CHR$ 0) to initialize the symbol count byte in s$(1).

Embedded Demo Source

The REM block at lines 10–70, delimited by ( and ) markers, contains Z80 assembly source that, when assembled, produces a routine at address 65367 that calls ROM routine 1601H to select channel 2, then prints the string “BOB GILDER” character by character using RST 10H. This serves as both a usage example and a signature for the program’s author.

Potential Anomalies

  • The FN r() displacement formula uses vdef as a multiplier: when a symbol is unresolved, vdef is non-zero (1), so the displacement is computed; when resolved at the second pass, this may produce an incorrect relative value on the first pass, which is corrected during forward-reference patching.
  • Error code 99 at line 1925 is used for a full symbol table, while error code 98 at line 7210 covers a full unresolved table; error code 9 (line 1630) flags an unrecognized instruction, and code 6 (line 8510) flags an out-of-range value.
  • The auto-scan search at line 7840 checks PEEK(x+4)=234; the meaning of token 234 depends on the ROM token set and is used here as a heuristic marker rather than a portable line-structure field.

Content

Appears On

The power-user's tape. Assemble and disassemble Z80 code, manage databases with Quicksort, trace BASIC program flow, or decode resistor color codes — Tape 8 is an essential toolkit for the serious TS 2068 programmer.

Related Products

Related Articles

Related Content

Image Gallery

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)"

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

People

No people associated with this content.

Scroll to Top