ZXAS

Products: ZXAS
Date: 198x
Type: Cassette
Platform(s): TS 1000

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 20RAND 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 30STOP 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.

Content

Appears On

Related Products

Learn and program in machine code the easy way with this powerful Z80 assembler, commissioned specially for the ZX80 &...

Related Articles

Related Content

Image Gallery

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<C▀ RETURN+""7#F RETURNA""5[:]#Q▘Y▛█7# LPRINT ###6[=]#5C#8 FASTE[=]#TAN )X#=STR$ TAN )3#=TAN                                        LN B#[J]5 #)▘#▘ COPY▘# GOSUB [K]M[~~]#M["]#▞#▖5#RND777LN ▚#C-7#[S]4 CLS[R]) # GOSUB #S▞Y▘M["]#TAN ;/ LLIST F#F# GOSUB #▚#777#[R]C CLS RETURN(4 OR 6[▒]#5[~~]#OE[▒]#6▜#E█#6▙#E▜#7#[R]C CLS▞#▖[S]4=7#7# GOSUB #▚#7LN ▚#C SCROLLY▝M["]#TAN  RETURN)4▒U[~~]# RETURN▝#-# RETURN*4▛[S]C OR 7#/ RAND  RETURN:TAB )#7# RETURNL4*▞ 7#▖CHR$ 0ACS #4>#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><TAN #▞▖ACS Z( UNPLOT LEN 0><# NEW?LEN 0><TAN E▚# GOSUB #[£]#▘ CONT ▀LN ##▘# LN ##:~~LN ##:▘LN ##<E▙#LN ###LN ##< OR 5[?]# OR :  OR #7 OR #£U[:]#[)]ACS #C▖<</▀LN ##<Y▖[T]4 FASTE▜#▞#▖# RETURN;C>[S]C?,[S]4▌< GOSUB #[£]##>7</ DIM 6▜#E[£]#)5 ;6[£]#U[:]##▞ 5[?]# GOSUB #▙# GOSUB [K] GOSUB #▙#E£RND▘""▝,, GOSUB #[£]#[R] GOSUB PIK▞LN [£]#LN B#Y#<= RETURNACS #COS E▜## RETURN;ASN #####TAB ##▞  LET  PRINT ( UNPLOT #[£]##CHR$ 0 IF L##CHR$ A PAUSE L#7/ LET  FAST OR 5  )▘  OR F#CHR$ 0 IF ###CHR$ A PAUSE ###CHR$ . OR #; ( UNPLOT [R] GOSUB # FAST5  ▞~~;( CLEAR FOR  LPRINT / OR  LPRINT TAN #4▀ OR  LPRINT TAN Y▌M["]# LPRINT  LPRINT TAN )  #CHR$ G PAUSE [=]##CHR$ 0 IF [=]##▞▖ACS 6S)ACS 7#EXP  #( POKE #[N]#7/ TO TAN #COS Y▌M["]#TAN ADCADDANDBITCALCP DECIN INCJP JR LD OR OUTPOPPUSRESRETRL RLCRR RRCRSTSBCSETSLASRASRLSUBXOR   6▜#Y COPYM[<]#: )[1]#,[R]CM[Y]C▞<<<£/ NEXT <7,[Y]C"<<,<£F[Y]4,/ LIST <7,[Y]C:£FFF▞▀7<,[Y]4▞( SAVE #M[<]#LN L#C£▞█ RETURN▘C▞ RETURN*4.▞[/]#M[?]#7#[R]C CLS RETURNATAB [$]#7# RETURN.4INKEY$ Y▘# CLEAR#:RND RETURN▀C£:█ RETURN(C▞ RETURN/4G:""7#[R]C CLS RETURN8K.CHR$ 0S*#[J]LEN ▒( UNPLOT ▟#:ACS  GOSUB #[?]#7# RETURN.Y▝ASN  CLEAR#Y▖M["]#TAN ▞[4] RETURN▝C/▞[S] RETURN▌C>▞[K] RETURN£C£▞[(] RETURN0C▞ RETURN14"▞[C]:▘ GOSUB #[:]## #▞( RETURN>C9▞  RETURN<C3▞/ RETURN=C;▞▒ RETURN+C<▞4 RETURN;C$▞C RETURN,C▛ RETURN.TAB EXP #▞SLN [5]#   Y▝M[:]# RETURN<C▖ RETURN+4*7#F RETURNA4(Y▘M[:]#U[(]#LEN ▛M[?]####7#[R]C CLS RETURN AND 4▝Q(# RETURNA IF ## RETURNM PAUSE ##▞▛ RETURNIC9▞  RETURNBC3▖ RETURNCC,▖ RETURNDC+▖ RETURNEC(▖ RETURNHC"▖ RETURNLC▞Y▖M["]#TAN 5[:]#U[:]##- ;#▚#### RETURN(COU[:]# RETURN▝4▞Y▖M["]#TAN U[?]#LEN #:▝# GOSUB #[:]## RETURN$C?LN 6# OR #[R]4 LPRINT #M[(]####7LN ## FOR / INPUT 7# RETURNH457# RETURNL4SIN 7# RETURN)4▝Q)# RETURN)4[V]5[:]##▞ ,,Y▞▚#### RETURNI4[C]7#7# RETURN+4▝Q+ RETURN-4▝Q-#VAL 7# RETURN$C<LN 6# OR #[R]C▛ LPRINT Y▌M["]#TAN # OR /,,7LN ###[R]4 GOSUB ##AT # RETURN)4▝Q)# RETURN)4## RETURN+4▛ACS #4CHR$ #/" RETURN-4P[J][>]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 <F/ PAUSE <<[R]COS / GOTO LN ##U[<]#:#[R]C▞ RETURN▘CL:PI# RETURN▀C▞Y▖M["]#TAN 7# RETURN.4 POKE 7LN ##Y▖[S] IF [7]##LEN (( UNPLOT CHR$ (5[:]#Q▝GQ GOSUB G####7# RETURN.4M7#LN ###[T]4▖-D/># 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 </ RUN  RETURN"TAB [H]#E▜#777#[R]C CLS RETURN(4▝Q(LN ### RETURN▛TAB  UNPLOT #LN TAB ## RETURN▒4G#▞# RETURNIC£▞# RETURNRC▞Y▖M["]#TAN 7# RETURN.4 POKE 7# RETURNA4 INPUT 5[:]#Q▝GQ GOSUB G#### RETURN▞ASN  OR #7# RETURN.4CHR$ 7##▞# RETURNIC TO ▞# RETURNRC OR LN TAB ## RETURN▞ASN [9]# RETURN▒C=5[:]#Q▘GYRND█ACS 5ACS 5ACS 5▟#####M[:]## RETURN$C- RETURN0 AND [7]# RETURNAABS [7]#LN 6# OR #[R]TAB [7]##/=7# RETURN0 AND [7]# RETURNGABS [7]#LN ###[R]TAB [7]#5[:]#ACS AACS AACS AY▞▚Q▝G#G####7LN ###M[?]# RETURN▖4▞Y▖M["]#TAN  RETURN▖K:7# RETURN)4▝Q)# RETURN)COS / CONT  RETURN▛COS 7# RETURN+4▝Q+ RETURN-4▝Q-# PRINT 7# RETURN$C= RETURN0SG RETURNAKCLN 6# OR #[R]44# OR />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

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

People

No people associated with this content.

Scroll to Top