--- title: "ZXAS" id: 51827 type: "computer_media" slug: "zxas" url: "http://localhost/computer_media/zxas/" markdown_url: "http://localhost/computer_media/zxas.md" published_at: "2023-08-13T23:14:34+00:00" modified_at: "2026-04-04T20:17:55+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2019/02/20230809-041332.jpg" excerpt: "A complete Z80 assembler packed into a single REM statement, supporting the full Z80 instruction set including IX/IY indexed addressing and bit manipulation opcodes." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Bug-Byte Software" slug: "bug-byte-software" taxonomy: "post_tag" url: "http://localhost/tag/bug-byte-software/" - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 1000" slug: "ts1000" taxonomy: "post_tag" url: "http://localhost/tag/ts1000/" model: - name: "Timex/Sinclair 1000" slug: "ts-1000" taxonomy: "model" url: "http://localhost/model/ts-1000/" genre: - name: "Machine Language" slug: "machine-language" taxonomy: "genre" url: "http://localhost/type/machine-language/" - name: "Programming" slug: "programming" taxonomy: "genre" url: "http://localhost/type/programming/" media_type: "Cassette" download_url: "https://archive.org/download/timex-sinclair-software-archive/ZXAS (198x)(Bug-Byte)(UK)(TS1000)(Cassette).p.zip" mediadate: "198x" producer_company: - id: 10706 title: "Bug-Byte Software" type: "company" url: "http://localhost/company/bug-byte-software/" related_products: - id: 14822 title: "ZXAS" type: "product" url: "http://localhost/product/zxas/" media_type_tags: "Machine Language, Programming" --- # ZXAS ZXAS is a Z80 assembler written in machine code, embedded as a REM statement in line 10, with a BASIC loader that invokes it via RAND USR 16514. The program assembles Z80 mnemonics — including ADC, ADD, AND, BIT, CALL, DEC, INC, JP, JR, LD, OR, OUT, POP, PUSH, RES, RET, RL, RLC, RR, RRC, RST, SBC, SET, SLA, SRA, SRL, SUB, and XOR — along with register names such as BC, DE, HL, SP, IX, and IY. The error-reporting routine at lines 9050 reads an error code from address 32651 via PEEK and displays it on screen. A separate input routine at lines 9010–9040 accepts an address value, stores it in two bytes at 32640–32641 using standard high/low byte decomposition, and then invokes a second machine code entry point at address 28565. *** ## Program Analysis ### Program Structure The program consists of just three functional BASIC lines plus a small utility block: 1. `Line 10` — A `REM` statement that contains the entire machine code assembler binary. The tokenized BASIC keywords and graphic characters visible in the listing are artifacts of the raw binary being interpreted as BASIC text. 2. `Line 20` — `RAND USR 16514` launches the assembler by jumping into the machine code stored in the `REM` body. Address 16514 is two bytes past the start of line 10’s data (past the line number and length bytes), pointing directly at the first opcode. 3. `Line 30` — `STOP` acts as a guard in case execution falls through. 4. `Lines 9000–9060` — A utility block for configuring the assembler’s output address: accepts a target address via `INPUT`, POKEs the high byte to 32641 and the low byte to 32640, then calls a second entry point at address 28565 via `RAND USR 28565`, and finally reports any error code read from address 32651 with `PEEK`. ### Machine Code Embedding in REM Storing machine code inside a `REM` statement is a standard technique: the BASIC interpreter skips the content entirely, but the bytes are present in memory at a known, fixed address. Since the program is the first (and only) line loaded, line 10 begins at the canonical system address 16509, and the `REM` data starts at 16514, making `RAND USR 16514` a precise and reliable entry point without requiring any address arithmetic at runtime. ### Address Passing Convention The utility block at lines 9010–9040 accepts a 16-bit target address in variable `ZZZ` and decomposes it into high and low bytes: - `POKE 32641, INT (ZZZ/256)` — stores the high byte - `POKE 32640, ZZZ - 256*INT (ZZZ/256)` — stores the low byte (equivalent to `ZZZ MOD 256`, but MOD is not available in this BASIC dialect) Addresses 32640–32641 fall in the upper RAM area and serve as a parameter block that the machine code routine reads before beginning assembly. ### Supported Z80 Instruction Set The mnemonic strings embedded in the `REM` data (visible as readable ASCII amid the binary noise) confirm support for a comprehensive Z80 instruction set. Identified mnemonics include: - Arithmetic/logical: `ADD`, `ADC`, `SUB`, `SBC`, `AND`, `OR`, `XOR`, `CP`, `INC`, `DEC` - Bit manipulation: `BIT`, `SET`, `RES`, `RL`, `RLC`, `RR`, `RRC`, `SLA`, `SRA`, `SRL`, `RLA`, `RLCA`, `RRA`, `RRCA`, `RLD`, `RRD` - Load/transfer: `LD`, `LDR`, `LDD`, `LDIR`, `LDDR` - Jump/call: `JP`, `JR`, `CALL`, `RET`, `RST`, `DJNZ` - Stack: `PUSH`, `POP` - Miscellaneous: `OUT`, `IN`, `EX`, `EXX`, `NOP`, `HALT`, `DI`, `EI`, `CCF`, `SCF`, `DAA`, `CPL`, `NEG`, `RETN`, `RETI`, `IM` - Registers: `BC`, `DE`, `HL`, `SP`, `IX`, `IY`, and individual 8-bit registers `B`, `C`, `D`, `E`, `H`, `L`, `A` ### Error Reporting After assembly completes, `line 9050` reads a result code from the fixed address 32651 using `PEEK` and prints it as `ERROR n`. This single-byte error code is written by the machine code routine itself, providing a minimal but functional diagnostic channel back to BASIC. ### FAST/SLOW Mode Usage `Line 9000` issues `FAST` before the assembly run to disable the display interrupt and maximize execution speed, while `line 9060` restores `SLOW` mode afterward. This is conventional practice when invoking computationally intensive machine code from BASIC, preventing display refresh overhead during the assembly pass. ### Notable Techniques - The entire assembler — parser, code generator, and output routine — is self-contained within the `REM` data, requiring no additional files or memory setup beyond the two-byte address parameter block. - Using `RAND USR` rather than `GOTO USR` avoids disturbing the BASIC random-number seed register in a way that could cause issues, and is the idiomatic way to call machine code with no return value needed in BASIC. - The high/low byte decomposition at lines 9020–9030 uses repeated `INT (ZZZ/256)` rather than bit-shifting, since this BASIC dialect lacks bitwise shift operators. ## Source Code ``` 10 REM 5[=]RND▘█)) # GOSUB [K]5 #6▖RNDTAN )[:]# RETURN£4▛:Z# RETURNF/# RETURN$4?:#£# RETURNLTAB [7]#7# RETURNT/R RETURN?4▛: # RETURNP/G RETURN▞:*C▞ RETURN▛4::3# RETURNAC. RETURNDC6#[7]# RETURN(4▛#:R RETURNF/,, RETURN)4-#:B RETURNATAB [7]# FOR Q▘G####Y▚[)]#/A RETURN▀4-#:# RETURN0C/:# RETURN1C>:# RETURN2C£#[7]# RETURN:4<# RETURNG:#TAB [7]# FOR Q▝GQ GOSUB G#### RETURN▒4=#:[V] RETURNDC▛:[N] RETURNITAB [7]#7# RETURNR/ AND RETURN▝TAB ### RETURNX4"5[:]#Q▘GQ OR ###F7#[R]C CLS RETURN AND 4▝Q(# RETURN(4#7LN ### RETURN▖TAB [7]#7# RETURN OR 4▝Q)# RETURN)TAB [7]#7# RETURN.TAB [7]#7LN ##5[:]#Q▘# RETURN▀4▞GQ STOP###OGQ<> RETURN▌C PAUSE Q CLEAR RETURN▞C GOTO #[7]# RETURNA4B7# RETURNFTAB [7]#7# RETURN.TAB [7]#7# RETURNATAB [7]#7# RETURNFTAB [7]#5[:]#Q▘GQ▒###LN ### RETURN▝TAB [7]#7Y.[Y]TAB [7]#7LN ##Y▀[S]TAB [7]#5[:]#Q▘GQ FOR #### RETURNNTAB [7]#7# RETURNZTAB [7]#▘( ###[J]M["]####77# RETURN REM TAN 5 COPY COPY6ORND#D▝ OR STR$ FASTVAL LN #AT LPRINT SGN OR TAN :ACS GOSUB #[?]# RETURN#CHR$ AACS #C"# RETURN▖4 FOR Y▀M["]#TAN ▌C RUN 6▜# ▌F#CHR$ 0##[R]CA▌F#CHR$ 0▗#ACS 6ACS 6▙▟##[R]C=F#CHR$ 0#▗▙▗▗▗▙[R]▗▗SSIN ▟#[J] 5 #ACS 5EXP #,, GOSUB #▙##7#E▜#F7#[R]C CLSCHR$ AACS #C▞Y▖M["]#TAN #CHR$ YACS #C NEXT # IF #E£RND76[£]#FY#W:/▞47Q ( CLS7#$4 POKE TAN Y COPYW[R] GOSUB PIK IF ,,LEN 0><# NEW?LEN 0>[S]C?,[S]4▌< GOSUB #[£]##>7▞[K] RETURN£C£▞[(] RETURN0C▞ RETURN14"▞[C]:▘ GOSUB #[:]## #▞( RETURN>C9▞ RETURN]ACS #CSTR$ #5[:]##LEN ▝# RETURN▖C▒G#LEN ▞G#/£GG#LEN ▞GG#I[(]QACS G##:<> RETURNXC£: CLEAR RETURNYC▞Y▖M["]#TAN I[?]####BCDEHLSPIXIY )##▞ ▖,[Y]4,,<7,[Y]COS # RETURN▌ PAUSE [7]# RETURN▀ASN [7]#Y RAND LEN (( UNPLOT ##2 RETURN▀C>2<> RETURN▌C£2 CLEAR RETURN▞C▞Y▖M["]# OR 5[:]#Q▘#[R]4▀G/▖OG#G####BCDEHL(A # RETURN(4▝Q(LN USR #▞ COPY▖,[Y]COS [R]COS 7# RETURN0S- RETURNGK>LN ###[R]4"## LET RETURN+C= RETURN-C▛ LPRINT Y▖M["]#TAN # RETURN▟K PRINT GOSUB #/▌ACS #4 GOSUB #M[(]# # RETURN)4▝Q)# RETURN)4>=TAN VAL LN >#AT U["]#[R]""ACS 5ACS 5ACS 5Y#▟#U[?]# RETURN▀4~~5[:]#Q▘G####K=## RETURN#TAB [7]##:~~ RETURN▘C NEW:, RETURN▝C STEP RETURN▛C*5[:]#Q▀G#Q<> RETURN▌C▝Q CLEARG##G##### RETURNLC# RETURN$C< RETURN0 AND [7]# RETURNAABS [7]#LN 6# OR FAST OR SGN /?7# RETURN0 AND [7]# RETURNGABS [7]#LN ##U["]#[R]"" FAST5[:]#Q▀GQUG#G# LPRINT # RETURN)4▝Q)# RETURN)ASN ###[7]#Y▀M[:]#YUM[?]#7# RETURN0 AND [7]# RETURNAABS [7]#LN 6## RETURN)4▝Q)# RETURN)TAB [7]# OR #[R]TAB [7]##[J]ACS 5EXP #5 #,,#7#5[:]##GG RETURN▀C▘G#G##### RETURNL4.7LN 6# OR #[R]TAB [7]#[J]ACS 9EXP #▘ #,,#7#STR$ OR SGN TAN RETURN$C> RETURN0 AND [7]# RETURNAABS [7]#LN 6# OR FAST OR SGN TAN 7# RETURN0 AND [7]# RETURNGABS [7]####LN >#U["]#[R]""U[?]# RETURN▛ASN ▙#7# RETURN.TAB [7]#7LN TAB #U[?]#:<> RETURN▌C▞ RETURN▞4U: CLEAR#M[?]## RETURN▞ASN [7]# RETURN▒C(LEN #5[:]#Q▀GG##G####LN [=]#U["]#[R]""#[R]TAB [7]#5[:]#Q▖#M[>]#YQ/<>:> RETURN▝C▞ RETURN▘4>:▝5[:]#Q▘G## RETURN▛TAB [7]##### RETURN▒C£5[:]#Q▘LEN #G####LN [=]#U["]#[R]""#[R]TAB [7]#5[:]#Q▝GQQG####LN [=]#U["]#[R]""# RETURN)4▝Q)# RETURN)TAB [7]#7# RETURN.TAB [7]#7STR$ LN ##SGN # RETURN▛#5[:]#4£ RETURNATAB [7]#Q▀GQM/W# RETURN▘4▖:#/: RETURN▝4▖:#/▞ RETURN▖4":#Q▖GQ GOSUB G#/0 RETURN▀4▛Q▀GQ6/) RETURN▌4▖:<>/▝: CLEARQ▖G#GQ6G#G####7# RETURN.TAB [7]#7# RETURN(4▝Q(# RETURN(4#7VAL LN [=]#AT # RETURN)4▝Q)# RETURN)TAB [7]#5[:]#Q▖# RETURN▌K0 RETURN▀4"PGQEG#G####YVLEN (( UNPLOT GQ GOSUB G#/ GOTO ▞<> RETURN▌C▝▞ CLEARG#/<># RETURN▖4▌# RETURNAKEVAL LN [=]#AT U["]#[R]""5[:]#Q▀# RETURN▌K▒Y LET LEN (( UNPLOT /ASN OGQ<> RETURN▌C▝Q CLEARY5/[W]LN ##5[:]##Q▝ RETURN▀4▛PGQ RAND ###GQ<> RETURN▌C NEXT Q CLEAR RETURN▞C GOSUB #[7]# RETURN▒C▌ RETURN▞TAB ##7#[R]C CLSLN ### RETURN▛CL5[:]#Q▘ RETURN▌K,#Y LIST LEN (( UNPLOT #U[<]#:▀ RETURN▒C▝:"#▟G####OGQ<> RETURN▌C▝Q CLEAR▞4/ STEP LN TAB ## RETURN▒ASN [7]# RETURN▞C2▖Y SAVE LEN ▒( UNPLOT 5[:]#Q▘G#U[<]#▞▌ RETURN▞C▘▌#█####LN >#U["]#[R]""5[:]#Q▘U[<]#:P RETURN▞C▝:OG# RETURN▀4▖####HQ▀GG##G#I[?]Q<> RETURN▌C▛Q CLEAR RETURN▞TAB [7]#### RETURN:C" RETURN?4#7# RETURNHTAB [7]#7#[R]C CLSLN ### RETURN▖ASN [7]# RETURN▛4)# RETURNATAB [7]#7# RETURNFTAB [7]#: LET /" RETURN▌K.Y[L]LEN (( UNPLOT #5[:]#Q▘U[<]# RETURN?#4▝LEN ▖G####5[:]#Q▝GQ<> RETURN▌C▝Q CLEAR: LPRINT / TO RETURN-4L7#[R]C CLSCHR$ 0 IF [7]# RETURN▖ABS [7]##Y[R]▖LEN (( UNPLOT #7# RETURN0C,, RETURN8TAB [7]##LEN ▒#5[:]#Q▘G#### RETURN,,CPI RETURN▖4,,7# RETURNLTAB [7]#/P RETURN)TAB 6#7#[R]CF5[:]#Q▘ RETURNI4":#OGQ GOSUB G####:# RETURNNC LET RETURN;C▛▞#▖[S]TAB [7]#GQTAN ###7#[R]C CLS RETURNZ4▖▞▝/Y RETURNC4▖▞▖/Q RETURNM4▖▞▒/I RETURNN4<7# RETURNZ4▖▞▘/4 RETURNCTAB [7]#▞▀/* RETURNPC▖▞ /?7#▞▌ RETURNOC▛▖ RETURNEC▝▖F#[R]CMY[S]LEN ▒( UNPLOT #U[<]# RETURN): C▒ RETURN,,:▝C▝:▖#▟M[?]##[R]4▛WM[:]####7# RETURN.TAB [7]#7/#U[<]#▞LN RETURN▖C▝▞##M[?]# RETURNLN CZ# RETURN(4▝Q(# RETURN(4N7LN ##7# RETURN)4▝Q)# RETURN)TAB [7]#5[:]#Q▘# RETURN▀4▞GQ DIM ###OGQ<> RETURN▌C PAUSE Q CLEAR RETURN▞TAB [7]#/ DIM LN [=]#U["]#[R]""5[:]#Q▀GG#G#### RETURN~~TAB STR$ #7#[R]C CLS RETURNN:▒4▀: 7# RETURNC▞KC~~ RETURNZ▞4C▖Y//~~7# RETURN.TAB [7]#7#▟M[?]#Y▝M[:]## RETURNLC2)##STR$ Y COPYM[(]#LN U#U["]#[R]4▖ LET ###U[(]# RETURN COPYCOS / POKE LN [=]#U[~~]# RETURN▘4▛[J]M[(]####E▙# FOR GOSUB #)# ;#[R]C▞Y▞M["]#TAN #CHR$ █/ LPRINT LN TAB #7# RETURN▞ASN [7]# RETURN▒ASN [7]#▖YSLEN ▒( UNPLOT M[(]#TAN 7# RETURNCTAB [7]#7# RETURN)4▝Q)# RETURN)TAB [7]#TAN RETURN$C# RETURN▛TAB ##7#[R]C CLSLN [9]## RETURN.TAB [7]#7# RETURN(4▝Q(# RETURN(C,LN [O]##[R]TAB [7]#U["]#[R]""5[:]#Q▝GQ<=G####LN [Z]#U["]#[R]""5[:]#Q▝GQ GOSUB ###7# RETURNDASN ["]# RETURNIASN ["]#F7#[R]C CLS# RETURN(4▝Q(# RETURN(44LN [Z]#7# RETURN.TAB [7]#7LN [9]#U["]#[R]""5[:]#Q▝GQ GOSUB GO###LN [O]## RETURN.TAB [7]#7# RETURNBTAB [7]#U["]#[R]""#[R]TAB [7]#5[:]#Q▝GQPEEK G####5[:]#Q▝GQ GOSUB GQ[F] RETURNDASN ##Q[7]###CPEXIMINLDRLRROTDIDJEICCHANENOSCDA E▜#)[4]#: £,[R]ASN [7]#0[Y]C▀0/ NEXT 7,[Y]C▖0F/ REM 7# RETURN▘4(# RETURNL4=5[:]#Q▘GQJ### RETURN▖C▌ RETURN▌TAB S#▞ # RETURNIC▛ RETURNDTAB [7]#ACS **7# RETURNR4▝ACS STEP 5[:]#Q▝GQ GOSUB 7Y[4]█## RETURN▌C▞O RETURN▘C▘O###U[<]#▞[▒][R]TAN RETURN,,C▖ RETURN"4)5[:]#Q▘GACS 5ACS 5YINT ▟##### # RND 20 RAND USR 16514 30 STOP 9000 FAST 9010 INPUT ZZZ 9020 POKE 32641,INT (ZZZ/256) 9030 POKE 32640,ZZZ-256*INT (ZZZ/256) 9040 RAND USR 28565 9050 PRINT AT 21,0;"ERROR ";PEEK 32651 9060 SLOW ```