ZXDB is a Z80 disassembler that decodes machine code instructions from memory and displays them as human-readable assembly mnemonics. The program’s core logic is embedded entirely within a large REM statement at line 1, which holds the machine code routine invoked via USR 16640. The short BASIC wrapper at lines 10 and 9990–9999 allows the user to input an address, stores it as a two-byte little-endian value at addresses 32640–32641, and then calls the disassembler routine via RAND USR 28565. If an error occurs during execution, line 9999 displays an error code by PEEKing address 32651.
Program Analysis
Program Structure
The program consists of just six active BASIC lines plus one massive line 1 REM block:
| Line | Purpose |
|---|---|
1 | REM statement containing the entire machine code disassembler engine |
10 | Calls the machine code via USR 16640 and PRINTs the result (initial entry) |
9990 | Waits for user to INPUT a target address into variable ZZZ |
9995 | POKEs low byte of address to 32640 |
9996 | POKEs high byte of address to 32641 |
9997 | Calls the disassembler engine via RAND USR 28565 |
9999 | Displays error code from PEEK 32651 if execution falls through |
Machine Code Storage in REM
The entire disassembler is stored inside the REM statement at line 1. The BASIC line structure means the REM data begins at a fixed, predictable offset from the program start. USR 16640 at line 10 jumps directly into this data, which is the standard technique for embedding machine code in a REM statement — the address 16640 corresponds to the byte immediately following the REM token and length bytes within the line 1 structure in RAM.
The machine code at address 28565, called via RAND USR 28565 at line 9997, is a secondary entry point within the same REM block, likely the main disassembly loop that reads from the address stored at 32640–32641.
Address Parameter Passing
The target address to disassemble is passed to the machine code by splitting it into low and high bytes using integer arithmetic:
- Low byte:
ZZZ - 256 * INT(ZZZ/256)— equivalent toZZZ MOD 256 - High byte:
INT(ZZZ/256)
These are stored at a fixed two-byte location (32640–32641) in RAM, which the machine code routine reads as a 16-bit little-endian pointer — consistent with Z80 native byte ordering.
REM Block Content
The REM statement at line 1 is exceptionally large and contains the full Z80 disassembler lookup tables and decode logic encoded as raw bytes. The tokenized BASIC keyword sequences visible in the listing (such as GOSUB, INKEY$, ASN, LN, RETURN, NEW, SCROLL, and many others) are artifacts of the disassembler interpreting bytes that happen to correspond to BASIC token values when the listing is rendered — the REM contents are machine code data, not executable BASIC. The mnemonic strings for Z80 instructions (LD, ADD, ADC, SUB, SBC, AND, XOR, OR, CP, INC, DEC, DJNZ, JR, JP, CALL, RET, RETI, RETN, RST, PUSH, POP, EX, EXX, LDI, LDD, LDIR, LDDR, CPI, CPD, CPIR, CPDR, INI, IND, INIR, INDR, OUTI, OUTD, OTIR, OTDR, RLC, RRC, RL, RR, SLA, SRA, SLL, SRL, BIT, RES, SET, DAA, CPL, SCF, CCF, NOP, HALT, DI, EI, NEG, RLD, RRD, IM, IN, OUT) are all visible embedded in the REM data, confirming comprehensive Z80 instruction set coverage including CB, DD, ED, and FD prefix opcodes.
Notable Techniques
- The REM-as-machine-code idiom avoids the need for a separate LOAD of binary data — the disassembler is self-contained within the single BASIC file.
- Two separate USR entry points (16640 and 28565) suggest the machine code has an initialization phase and a separate per-instruction decode loop.
- Error reporting is handled non-intrusively: line 9999 only executes if control returns to BASIC abnormally, using
PEEK 32651to retrieve a status byte written by the machine code. - The use of
RAND USRrather than plainUSRin an expression avoids a type-mismatch error if the machine code routine does not return a clean numeric value to BASIC.
Z80 Instruction Coverage
String fragments visible in the REM data confirm coverage of all major Z80 instruction groups:
- 8-bit and 16-bit load instructions (LD, LDI, LDD, LDIR, LDDR, STAX, LDAX, SHLD, LHLD)
- Arithmetic and logic (ADD, ADC, SUB, SBC, AND, XOR, OR, CP, NEG, DAA, CPL, SCF, CCF)
- Rotate and shift (RLC, RRC, RL, RR, SLA, SRA, SLL, SRL, RLD, RRD)
- Bit manipulation (BIT, RES, SET)
- Jump, call, and return (JR, JP, DJNZ, CALL, RET, RETI, RETN, RST)
- Block instructions (LDI, LDD, LDIR, LDDR, CPI, CPD, CPIR, CPDR, INI, IND, INIR, INDR, OUTI, OUTD, OTIR, OTDR)
- Miscellaneous (NOP, HALT, DI, EI, IM, IN, OUT, EX, EXX, PUSH, POP, PCHL/SPHL equivalents)
The presence of Intel 8080 mnemonics such as STAX, LDAX, SHLD, LHLD, XCHG, XTHL, PCHL, SPHL alongside standard Z80 mnemonics suggests the disassembler may optionally support or at minimum recognizes 8080-compatible notation for certain instructions.
Content
Image Gallery
Source Code
1 REM PRINT FASTSTR$ VAL E2RND RETURN#C: RETURN#C=#762RNDAT SGN LPRINT LET TAN E(RND)PI GOSUB #/ INPUT ▘ RUN ▝) RUN ▝E£RND; GOSUB PI FOR 55 ; GOSUB [K]/>= <> FASTVAL STR$ FASTY COPYMPRNDLN D▝Y COPYMBRND59RND#7#ACS ,,[3] PLOT ALEN #LEN ▌ACS ▒S IF WACS ,,S CLSA ##ACS #C▝CHR$ ▀ LPRINT SGN AT <> LPRINT TAN E▖RNDL GOTO COPYT RAND /▀# PLOT RNDYVAL M#INKEY$ LN [K]#Y*LN #INKEY$ LN #INKEY$ #LN #INKEY$ LN [K]## RETURNBASN █# RETURNDASN LLIST # RETURNSASN [Z]INKEY$ RETURNAASN CPI RETURNQASN TAB # RETURNGASN #INKEY$ RETURNFASN #PI RETURNMASN [)]PI RETURNWASN X# RETURNCASN [A]PI RETURNEASN [/]INKEY$ RETURNVASN ▐INKEY$ Y?LN #INKEY$ # INKEY$ LN #INKEY$ DIM PRINT #7## LET TAN #[W]RNDVAL LN ▙RNDAT TAN LN [K]#Y=LN #INKEY$ #▜#LN #INKEY$ LN X#LN USR #LN #INKEY$ RETURNQ4 NEXT # INKEY$ LN #INKEY$ FOR .<LN ##Y-LN #INKEY$ LN ▜## RETURNQASN INKEY$ RETURN#TAB [1]INKEY$ #>#[1]INKEY$ : ) OR PILN ▜## RETURN#C~~#>£<#J></ INPUT LN #INKEY$ F FASTINKEY$ ) OR PI LPRINT 7LN ##ASN INKEY$ FAST,[I] FOR 7[A] FOR 7<TAB <=INKEY$ ▌TAB CONT INKEY$ LN [K]##[)]##[/]#LN [K]#LN [U]#LN [K]#LN #INKEY$ RETURNQASN INKEY$ RETURNCTAB <=INKEY$ FOR VAL LN ▜# FOR #AT RETURN#ASN <=INKEY$ #7#-PILN #INKEY$ # RETURNQASN INKEY$ :4 FASTLN [K]#LN [U]#LN [K]# LPRINT #7VAL # NEW# RETURNRNDS▝▞ #AT LN #INKEY$ $TAB YPILN #INKEY$ RETURNQTAB LPI#CPIY>LN #INKEY$ LN ▜##LN #INKEY$ FOR LN #INKEY$ FOR ##[V]4▝#[U]74 PLOT # INKEY$ LN #INKEY$ FOR LN #INKEY$ [R] GOSUB # FASTLN #INKEY$ #AT TAN LN █PI RETURNIC▒,, FOR ,,▀ GOSUB [S]/<> FOR ▀ GOSUB [K]/NOT LN █PI FOR , GOSUB [5]C6 PRINT FLN X##LN [Z]#LN FAST# FOR LN X# FOR ,LN [Z]#LN [K]#7LN #INKEY$ RETURN#ASN INKEY$ LET < LLIST INKEY$ /PEEK [/]## COPY< COPY COPY COPY[*]#SQR #[?]▝ RND▒/[+] ~~ [(]#[/]# . , # U#INKEY$ RETURNVAL TAB ##LN [K]#U #[R]TAB [N]#E STOPPI6 UNPLOT PIY▝[R]LN [O]#▞▝LN ##:▖LN R#ACS RND PRINT CODE #INKEY$ LN X# LET $4 LIST ACS RND PRINT ATN [?]#CODE ##LN [K]# LET (>=XR4PEEK E RETURNPILN X#LN USR #▞NE SAVE PI#[P]FATN ▜#[J]M**PI# RETURNGASN .# RETURNWASN [E]# RETURNRASN FAST# RETURNLASN OR # RETURNPASN CONT # RETURNQASN G# RETURNOASN TAB # RETURNZASN SAVE # RETURNTASN ## RETURNNASN [4]##[O]COS #[H]#6 SAVE PITAN PCSPIXIYAFBCDEHLS▌5[8]#/▀5[G]# PRINT ▞▒#7LN #INKEY$ LN FAST#ACS RNDCODE FAST#( LET LN [K]# LET TAN E STOPPI# CONT # # INKEY$ LN J# LET 6 NEXT PI6 OR PI#)#LN #INKEY$ ##INKEY$ LN [K]#LN PAUSE #CHR$ A AND 3# RETURN$ABS 3##LN ▜# FOR # RETURN£ASN 8#5F#LN ###5 FOR PILN #### SAVE #E LET PI## SAVE #▘▀▝▌▖ ▛ ▞ FOR #7#7 FOR TAN CMZV ABS PEEK ##ATN # ) STOPPISQR 2 FOR TAN 6▌#YTAN M#INKEY$ TAN LN ATN #YVAL M#INKEY$ LN ##ASN INKEY$ LN ##ASN ▛####E▌# FOR :▞5 GOSUB PILN [+]#COS $TAB ▄#E STOPPI7LN [+]#COS £TAN #[V]7TAB [1]##[U]7TAN PRINT #7CODE #INKEY$ ATN FAST# LET TAN LN [P]#6 RETURNPI###VAL STR$ FASTE##LN "# LPRINT SGN AT ###U #JM #### FASTE###NOT # FASTE STOPPIVAL STR$ PRINT LN :# LET SGN AT LPRINT TAN LN #INKEY$ LN [K]#F6 UNPLOT PIE UNPLOT PI7LN "#LN [K]#LN ▜## RETURNQASN INKEY$ #[O]ASN GOTO #F6 UNPLOT PI# GOTO #LN X#6 UNPLOT PI#76 IF PI▞▀# RETURNLN ASN [,]# RETURN#ASN E# RETURNTAN ASN ##5ATN #▞,LN [Q]#TAB 5#5 #;LN #INKEY$ ▞▀ DIM LN [U]## FAST#▞▀5##LN COS #E UNPLOT PI#B#DB # INPUT AT NEW LET TAN LN J#6 IF PIVAL 5[D]#▞▀LN COS #LN ##AT COS #[+]#▞▝#COS #ETLN C#6 IF PI5[>]#▞▀LN COS ## NEWSE UNPLOT PI#[Z]#RST5[A]##LN T# NEW▛▗▌LN ###▐#NZZ NCC POPEP M ) COPY COPY▌ SAVE #[A]7[I]7<TAB [T]# FOR D FOR TAN #LN #INKEY$ 7( RAND ### 5▒#▖LN COS #5 GOTO ##LN S# NEW▀LN [8]##▐#BC DE HL AF BC DE HL SP POP PUSH5▖#LN COS ##<>#5##LN COS ##£#LD LN ###LN T# NEW▛LN P## NEW▛ PRINT LN ## LET 5INKEY$ # NEW▛LN #####INKEY$ BCDEHLMA▞▀52##COS #▐#SQR 8TAN 5##LN COS ##LN T# NEW▛#P#5##LN COS ####INCDECLN [+]## NEW▛#P#ADDADCSUBSBCANDXOROR CP #LN T# NEW▛5##LN [8]##COS ##▗▄#- ;▞▀TAN #LN T# NEW▀5 GOSUB #LN [8]#LN ▐#YA##INKEY$ Y COPYMBRND#(▖ 5##LN COS ##£# #LN T# NEW▀5 SCROLL#LN [8]##COS #DAACPLSCFCCF5▝##LN T# NEW▘LN [8]##COS #DI EI 5:##COS #NOPOUTIN 5)#LN PLOT #E UNPLOT PI76 UNPLOT PILN ACS # #LN PI#Y;LN #INKEY$ LN FAST## NEW# RETURNRNDSQR # ##INKEY$ #[Z]#5[X]#▞▀#COS # #LN PI#Y,##INKEY$ 5##LN COS ##LN T# NEW▛LN P#LN ###1#LD 5###LN T# NEW▛LN [8]#LN COS ##1# PRINT 5▟#LN T#▞▖▗▗LN ##LN ▐# LET ASN FAST#TAN LN [U]#VAL 5[Q]#▞▖LN COS #AT LN ##ASN SCROLL#LN [+]##▀# CALLLN TAB # FOR 6 IF PITAN E UNPLOT PI7#7#TAN F STR$ FOR E IF PI#[X]TAB LLIST ##[W]TAB LLIST #E UNPLOT PI76 IF PIE UNPLOT PISGN TAN LN TAB #6 UNPLOT PILN ASN # FOR LN [U]#TAN 5,,#LN COS #LN £#LN ### SCROLL#LD 5 SAVE ## STEP ## NEW▒58#ASN 2#777LN COS ## SCROLL#STALDALN [U]#VAL 5##▞▀LN COS #AT LN ##ASN SCROLL## NEW▘TAB [▒]#LN [+]##▀# JP ▖# NEW▒5##ASN ##)▖ ;LN COS ## SCROLL#SHLDLHLD▖5█## NEW▒ASN ##)▖ ;LN COS ##<>#STAXLDAX5[,]##LN T# NEW▘▗▗LN ##▖#COS #XTHLXCHG# RETURN DIM ATN [T]#5[L]#LN S##[?]#PCHLSPHLE LET PI6 IF PITAN 5TAN #LN COS ##£#ADDSIN ""SIN SIN INT VAL INT AT INT ▀""RNDSIN ▖SIN ▌""█ SCROLL▛INT " SCROLLB RUN NEXT COPY SCROLL▝ RUN PEEK SIN ▞SIN LEN SIN CODE INT ▘ RUN MSIN TAB RUN 6 RUN STOP LOAD DIM INT ,,####CHR$ #£#+#5#######[I]#LN #**# NEXT #▒###*#####[,]# IF #>#E###[▒]#[6]#""#33333333TAN LN #INKEY$ ##DDDDD;6[A]RND# INKEY$ FOR E UNPLOT PI76 UNPLOT PI#[+]#[0] AND INKEY$ STR$ FASTLN "# LPRINT LN [K]#SGN ### V#[/]#/SEARND#[B]"" TO LN #INKEY$ 6##6 STOPPI6 NEXT PI LN [-]#LN #INKEY$ DIM E NEXT PI#U###[Y]TAB [V]##M##7#U####M##7#U####M##TAN E### INPUT TAB NEWLEN ASN INT #7776 NEXT PI#[-]#LN J##TAN #6 LET PI PRINT LPRINT 6 FOR PINN GOSUB # FASTPIL##LN ##ASN [K]#LN [)]# CLEAR5 RNDLN ##LN [-]#E NEXT PI6 OR PI6##LN ▛#E NEXT PI#LN ##6 NEXT PIL##E OR PI6 STOPPILN [-]#E FASTPI RAND LN ##E LET PI CLEARE DIM PI### CLEAR5 RND# INKEY$ JKLMN5 : OR ▀ OR ▀ OR ▀; ▘ NEXT PI N NEXT PI [7]Q#INKEY$ N[-]###▌## RETURN(ASN [,]# RETURNKASN [8]# RETURNSASN [M]# RETURN4ASN [V]# RETURNCASN CODE # INPUT "" NEWSIN ASN SGN ## INPUT CODE NEWSIN ASN SGN ## INPUT TAB NEWSIN ASN SGN #E IF PITAN <>6 SCROLLPI CLEAR6 DIM PITAN U INPUT PIXTAB [$]##[H]#U FOR PILN 4#ASN [$]#E UNPLOT PI7TAN U FOR PILN 2##[E]#U FOR PILN 9##[E]#U FOR PILN 7##[E]#5##TAN LN LOAD ##[E]#""COS SQR ** STEP CONT LIST SAVE =#-#;#.#2#4#7#9#: RAND )NOT #5▒ ,[C][5]ASN ▝#<HTAB RUN #HD FOR 5 TO #; FOR E FOR PI# FOR #7# FOR DIM INPUT █ NEW█TAN INPUT ▖ NEW▖TAN INPUT ▘ NEW▘TAN INPUT RND NEWRNDTAN # NEWS#A TAN E FASTPI#7# FOR TAN #[I]7[A]COS 7$TAB R#£TAN SIN ▀#,,INT ▝ SCROLL▖LEN RND""█""AT ACS STOP SCROLL RAND COPY▞SIN LEN SIN PEEK RUN 6 SCROLL▘INT # COPYLN COPYTAB SIN CODE SIN ##6 LOAD PI##6 GOSUB PITAN E FOR PI FAST LET E GOSUB PI##E LOAD PI##TAN 5 LN #INKEY$ RETURN#ASN INKEY$ LN #INKEY$ #LN [4]#**DDDD[P]##▗#CHR$ 0** RETURN(ZTAN IY+M[C]## REM #Y#LN #INKEY$ Y###INKEY$ #LN [Z]## PRINT ????LN COS # LET NEW?LEN 0##INKEY$ IM :▒#7LN [Z]#LN FAST#$TAB CHR$ ##[K]#Y ##INKEY$ E UNPLOT PI7#6 UNPLOT PILN ACS ##TAN ▌ SAVE [Y]7#7#7COS # RUN #LN #INKEY$ ###▌ SAVE [Y]7#7#7COS #,,#▞▀5[B]#LN ▐###PI#▞▀# RETURN CLEARASN [G]# RETURN<>ASN [G]# RETURN GOSUB ASN (# RETURNACS ASN [;]# RETURN OR ASN ##CHR$ ( IF ##LN ## PRINT CODE ## LET LN ▙#E UNPLOT PI76 UNPLOT PIE IF PI# LET #E UNPLOT PI7 PRINT ##*[3]#;7 LET 6 IF PITAN LN ####INKEY$ YELN #INKEY$ YX##INKEY$ DJNZ NZ, Z, NC, C, LN REM # NEW""ASN AND # RETURN""ASN VAL # RETURNRNDASN ACS #5USR #LN COS # #LN T# NEW▛LEN 0LN ▀## NEW▛#P#5NOT ##[I]#5SGN ##[I]#BITRESSET#LN T#LN SCROLL#LN ▌##[Z]# NEW?#▗█TAN RLCRRCRL RR SLASRASLLSRL▞▀5 GOSUB #LN ###COS #LN REM #5##▞▌LN [Q]#5##ASN Q##5▙#▞:LN ,,#▞▖STR$ COS SGN # NEW▀ RETURN▝#ASN ##5## NEW▘LN ###LN T# NEW▛#P#▌LN T# NEW▘5##LN ###£#LN SCROLL#▞▀#▄#CIN COUTSBCADC SCROLL[4] SCROLL[5] SCROLL[6] SCROLL[7] SCROLL#[L]#[W]#TAB #COS #P#######################1##[;]##[;]##E##L##6##F#▛▛▛ NEW▘LEN XM SAVE #LN [E]# RETURNACS ASN 5# NEWSIN INPUT ▚ASN *##▛▛ NEW▀ RETURN▘ASN INPUT ##▞$5 IF #LN ,,#▞▀STR$ COS SGN 5TAN #LN COS #5 RUN #▞▀LN ▐## NEWK# RETURN4TAB £####IY,P##O##F##7##6##E##Q[.]# STOP[X]# DIM ACS # RAND LLIST # LPRINT [K]# FAST[K]#5U#LN REM #VAL LN REM #▛▛ NEW▀ASN ##5SGN #X#▗█LN ##▞▀LN COS ##LN T# NEW▛LN ##AT #+##LN T#LN SCROLL#LN ▌#AT #+#:0▞▀5INT #LN COS ####INKEY$ IM:1###:2###LN ##5[,,]##LN T# NEW▀▞▖▗▗LN ###COS #I,A R,A A,I A,R LN J#6 IF PI#? NEW▖5[D]##▄#RETNRETI5 AND ## NEW/▖?#▄#5 REM ##[O]#5 IF ##[O]#5~~##LN T# NEW▀#▗▗▟▞▌#▄#LDI LDD LDIRLDDRCPI CPD CPIRCPDRINI IND INIRINDROUTI OUTD OTIR OTDR SSPD52#LN COS ## SCROLL#5L##9#LSPD5Y#LN [O]## SCROLL#SBCDLBCDSDEDLDED5###LN ##LN REM ##+#5###LN T#LN ##5[B]#▞▝#COS # NEW▘#▗█▞▀#▄#YL###YSLN #INKEY$ 5[B]#LN [>]#YDLN #INKEY$ LN FAST## SCROLL##LN #INKEY$ 7###INKEY$ 5##LN COS #LN REM #LN +#LN ##LN REM ##PI#▖# NEW▖5▖#LN ▄####5 CONT #LN [>]#5[B]#▞▝#▐#U SAVE # RETURNXE SCROLLPIASN OR #E DIM PI6 IF PI5 REM ##""#5 GOTO ##""#XTPCSPLN ### NEW▛ RETURN▞ASN ▖##LN :#LN ####P##LN T#LN P#LN ##VAL LN REM #LN +#AT TAN LN [+]##:#58#▌#COS #NEGRLD5B#▌#COS #5R##H#RRD▞▀5,,#LN COS #▞▀5 RUN #LN ▐## SCROLL#LN [K]# FOR LN X## FOR #[Z]#LN STR$ # PRINT U INPUT PIX4▌E UNPLOT PI77 LET TAN Y RETURN<= RETURN RETURN#TAN LEN 0#▀##U(RND CLEAR[-]2 RETURNUATN FAST## FAST## RETURN CODE #INKEY$ 7( RUN TAN ** PRINT LN FAST#U FOR PI5Y#ACS #LN [3]#ACS #LN [3]#ACS #LN [3]#ACS #LN [3]# LET TAN LN [-]#[*]5 SAVE PI#7## INKEY$ JR /▘
10 PRINT USR 16640
9990 FAST
9994 INPUT ZZZ
9995 POKE 32640,ZZZ-256*INT (ZZZ/256)
9996 POKE 32641,INT (ZZZ/256)
9997 RAND USR 28565
9999 PRINT AT 21,0;"ERROR ";PEEK 32651
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.