SPECTRUM DISASSEMBLER
by David Hawkins
from Popular Computing Weekly 23rd September 1982

Breaking up is always hard to do

David Hawkins explains how to disassemble Z80 instructions into mnemonics.


The ability of Sinclair Spectrum BASIC to hold relatively complex data
structures in a "visible" form, ie. in the program listing, is well
demonstrated by this Z80 disassembler. This is made possible by the
new (to ZX BASIC) commands: DATA (with expressions as data), RESTORE
(with a line number pointer), READ and multi-statement lines for
greater speed (less line numbers for GO TO , GO SUB, RETURN, RESTORE,
etc. to search through).

The program provides a disassembly of all Z80 instructions - indexed
or otherwise - into mnemonics and, optionally into byte values
(decimals and characters / keywords). Illegal instructions are BEEPed
and FLASHed, whereupon the program goes into byte printing mode. JR
opcodes are printed with actual addresses. The program prints 2-3
lines a second.

The instruction relationships and mnemonics are held in DATA statement
tables as opcode (or pointer), arguments (or pointers) and brackets
requirements. Some opcodes and arguments are contained in array
tables, so certain DATA lines hold pointers to the arrays - notice how
an opcode can be built from two parts as in line 3231.

Each instruction byte is rearranged and split to form a pointer to a
DATA line. As certain instructions have a slightly different
structure, the opcode is replaced where relevant by an indicator and
pointer to a further line; eg. line 1001 points to line 4000 modified
by variable b.

The lower case letters u to z are used to indicate special editing
requirements before output; ie. insert index registers, calculate
displacements, double byte values, etc.

The program automatically determines the number of bytes in the
instruction so printing the correct number of byte values is simple.


Variables Used
a to e   - components of split byte.
f        - index register displacement.
g        - indicates which argument is bracketed
           (0 = none); also used for byte printing.
i        - used for index instruction validation.
k        - indicates instruction classification.
l        - instruction block pointer.
m        - modifies 1 pointer; also indicates which
           argument is being edited.
p        - address of byte being examined.
p1       - address of first byte of instruction.
q        - contents of byte being examined.
s        - indicates if byte values are to be printed;
           0 = no, 1 = yes.
z        - table initialisation FOR loop counter.
a$ to c$ - opcode and two arguments.
d$       - holds arguments for editing.
i$       - holds "HL", "IX" or "IY" as required.
n$       - contains flashing "?" for errors.
o$ to y$ - mnemonic tables.
z$       - holds "+" or null for index register displacement.


Detailed Description
1          Print title, set Caps Lock and initialise.

Main program
100        Input start address.
110        Get first byte, set class and index defaults.
120        HALT opcode.
13         Determine class of instruction.
150-180    Index instructions.
200        Split byte and rearrange; set DATA pointer
           to line and READ first item.
230        If extended structure read next two items
           (line no. and modifier), reset DATA pointer
           and READ item.
240        Check for Invalid opcode.
250        Read two arguments and brackets indicator.
260-270    Check/edit both arguments.
280        If index instruction check if index editing
           was done.
300-310    Insert brackets if necessary.
700        Print disassembled instruction.
720        Print byte values if required.
740        Check for interrupt.

Argument editing
920        "u" - displaced address.
930        "v" - single byte value.
94         "w' - double byte value.
945        "^"- invalid argument.
950        Set index edit flag.
955        "y" - index register.
980-990    "x" - index register and displacement.

Tables
1001-1371  Instruction byte not equal 203 or 237.
2071-2371  Instruction byte = 203.
3071-3371  Instruction byte = 237.
4001-4048  Extended instructions.

Miscellaneous
4500-4560  Handle interrupts.
4900-6000  Determine mode and set up mnemonic arrays.

When the program is RUN it will ask if byte values are to be printed -
press B (bytes to be printed) or N (not printed). Next, it will ask
for a start address for disassembly. Printing will continue until a
key is pressed. The options are: A - new address, B - byte values, N -
no byte values, or C - continue.

Figure 1 shows the output address and mnemonics only, Figure 2 shows
address, mnemonics and byte values. Figure 3 contains the program
listing.


Possible enhancements

Use a 16K array to map and disassemble the ROM, marking addresses of
CALLs, JPs, etc. Follow only these established instruction addresses
in the disassembly. Place these symbolics into a large array and write
with address array to Microdrive files for subsequent
searching/editing. Symbolic names can be given to many addresses - eg.
system variables - and commonly used subroutines.

Next requirement - editor/assembler. Watch this space!


