YAZD is a simple command line disassembler for Z80 binary code files. It's based on the disassembler in z80ex, ported to C#.
YAZD supports the following:
- Disassembly of all Z80 instructions, as supported by z80ex.
- Code path analysis can usually tell the difference between code and data.
- Generates labelled assembly language listings.
- Can also generate more detailed listing files with byte code and assembly source.
- Can detect procedure boundaries and generate call graphs
- Can generate reference listings to all external addresses and I/O ports.
- Can highlight all word literals (use to help find other memory address references).
- Can generate plain text, or hyperlinked HTML output files.
- Handles references to addresses not aligned with instruction (eg: self modifying code)
- Data segments are listed 1 DB byte per line with ASCII character in comments.
Requires:
- Windows and .NET 4.6.1 or later
- Linux/OSX with Mono (not tested, should work)
dotnet tool install --global yazd
Note: if this is the first global tool you've installed, you'll probably need to logout/in for the changes to you path by dotnet to be picked up.
yazd source.bin [destination.asm] [options] [@responsefile]
Options:
--addr:N Z-80 base address of first byte after header, default=0x0000
--start:N Z-80 address to disassemble from, default=addr
--end:N Z-80 address to stop at, default=eof
--len:N Number of bytes to disassemble (instead of --end)
--entry:N Specifies an entry point (see below)
--xref Include referenced locations of labels
--list Generate a listing file (more detail, can't be assembled)
--hex:<format> Specify hex literal formatting (options: $, dollar, &, amper, x or h)
--html Generates a HTML file, with hyperlinked references
--open Automatically opens the generated file with default associated app
--lowercase|lc Render in lowercase
--markwordrefs|mwr Highlight with a comment literal word values (as they may be addresses)
--reloffs Show the offset of relative address mode instructions
--header:N Skip N header bytes at start of file
--help Show these help instruction
--v Show version information
Numeric arguments can be in decimal (no prefix) or hex if prefixed with '0x'.
If one or more --entry
arguments are specified (recommended), the file is disassembled by
following the code paths from those entry points. All unvisited regions will be rendered
as 'DB' directives.
If the --entry
argument is not specified, the file is disassembled from top to bottom.
Output is sent to stdout if no destination file specified.
Response file containing arguments can be specified using the @ prefix
Example:
yazd --addr:0x0400 --entry:0x1983 -list robotf.bin robotf.lst
Typical source mode output. Note that YAZD is normally smart enough to tell the difference between local labels and procedure boundaries. This helps divide up the listing making it easier to understand.
ORG 0900h
; Entry Point
; --- START PROC L0900 ---
L0900: LD A,0Ah
OUT (0Ch),A
LD A,2Fh ; '/'
OUT (0Dh),A
LD HL,0F800h
LD C,80h
L090D: LD E,C
LD D,03h
L0910: XOR A
BIT 0,E
JR Z,L0917
OR 0F0h
L0917: BIT 1,E
JR Z,L091D
OR 0Fh
L091D: LD B,05h
LD (HL),A
INC HL
DJNZ L091F
RRC E
RRC E
DEC D
JR NZ,L0910
LD (HL),A
INC HL
INC C
JR NZ,L090D
JP L1042
; --- START PROC L0932 ---
L0932: PUSH BC
LD C,A
LD B,A
LD A,12h
OUT (0Ch),A
LD A,B
RRCA
RRCA
RRCA
RRCA
Unreachable addresses are automatically detected and rendered as DB directives when the --entry
argument
is used. If something is incorrectly detected as data instead of code, just add an extra --entry
parameter;
L0A46: DEC HL
CALL L0FB2
DEC A
AND 03h
DJNZ L0A3D
RET
L0A50: DB 00h
; --- START PROC L0A51 ---
L0A51: LD A,(L0A5F)
OR A
The --xref
option, causes the referencing locations of any label to also be included:
; Referenced from 09BEh
L09C4: LD (HL),8Ch
JR L09CE
; Referenced from 09BAh
L09C8: LD (HL),0B0h
JR L09CE
; Referenced from 09B6h
L09CC: LD (HL),80h
; Referenced from 09C2h, 09CAh, 09C6h
L09CE: INC A
CALL L0FB2
AND 03h
ADD HL,DE
DJNZ L09B5
LD A,(L0A50)
LD B,40h ; '@'
CP 03h
If an instruction references a memory address that not aligned with the start of an instruction, its disassembly is updated to use the instruction's label with an offset. This usually occurs with self modifying code and helps to produce a listing that can be directly re-assembled.
LD (L0BED+1),A ; reference not aligned to instruction
L0BED: SET 3,(HL)
In listing mode (--list
), the address and byte code is included on the left:
; Entry Point
; --- START PROC L0900 ---
0900: 3E 0A L0900: LD A,0Ah
0902: D3 0C OUT (0Ch),A
0904: 3E 2F LD A,2Fh ; '/'
0906: D3 0D OUT (0Dh),A
0908: 21 00 F8 LD HL,0F800h
090B: 0E 80 LD C,80h
090D: 59 L090D: LD E,C
090E: 16 03 LD D,03h
0910: AF L0910: XOR A
Listing mode also causes the generation of reference information, including references to external memory addresses:
references to external address 8009:
0F18 CALL 8009h
0F43 CALL 8009h
0F66 CALL 8009h
21E7 CALL 8009h
236E CALL 8009h
2373 CALL 8009h
references to external address F0E2:
2354 LD (0F0E2h),A
Possible address references are also listed. This includes any instruction that uses a literal word value.
possible references to internal address 0900:
200E LD BC,0900h
201E LD BC,0900h
2037 LD BC,0900h
204F LD BC,0900h
possible references to internal address 0A5F:
0A60 LD HL,0A5Fh
----------
0A51 LD A,(L0A5F)
105B LD A,(L0A5F)
(Note the instructions after the dashed separator are references to the same literal value, but instances where it's known to be an address.)
Possible references to external addresses are listed separately since they're less likely to need patching to make a source file for assembly:
possible references to external address CC00:
0DCF LD BC,0CC00h
possible references to external address F000:
096F LD HL,0F000h
0A8D LD HL,0F000h
0AA2 LD DE,0F000h
0BDD LD DE,0F000h
0C9C LD HL,0F000h
0E17 LD DE,0F000h
1485 LD HL,0F000h
Port references are also listed:
references to port 02h
0C83 IN A,(02h)
0C95 IN A,(02h)
0FCA IN A,(02h)
0FDA IN A,(02h)
0C87 OUT (02h),A
0C99 OUT (02h),A
0FCE OUT (02h),A
0FDE OUT (02h),A
references to port 0Bh
094F OUT (0Bh),A
096A OUT (0Bh),A
The listing file also includes a few metrics on all the located procedures:
Procedures (96):
Proc Length References Dependants
L0900 0032 0 1
L0932 003D 5 0
L096F 0032 2 0
L09A1 00AF 6 1
L0A51 000E 6 3
L0A60 000E 1 0
and a call graph. Entry points, external routines and recursive routines are highighted:
Call Graph:
L0900 - Entry Point
L1042
L0BF0
L0A6E
8009h - External
L0A51
L0AB4
L102E
L1000
L0A51 - Recusive
L0FB2
L0B93