I decided to make my own disassembler. It supports both the classic Z80 and the eZ80. This was written in a single day, but seems to work quite well now. You can find the latest release binary and source code on GitHub.
CPU features:
Sample disassembly of the first 256 bytes of my TI-84 Plus C SE ROM image (it was the first .bin file I could think of):
Code:
I also figured out how to make your console application figure out whether it's been invoked from a command line or from another GUI application. The code that does this calls out to a native Win32 function and might or might not cause problems on Mono/Linux/Macs. If it does, let me know; in the meantime, if you're feeling bold, you can recompile it without the WIN_32 define to disable all that code.
CPU features:
- Supports eZ80 CPU
- Supports classic Z80 CPU
- Select ADL and non-ADL modes
- By default, reads input hexadecimal to disassemble from command line
- Supports reading input from text file with hexadecimal
- Supports reading input from binary file
- Supports writing output to stdout and/or a text file
- Optionally set base address input instruction stream starts at, allows below option
- Optionally show branch labels for output
- Optionally prefix every instruction with its address
- Optionally display opcode data being displayed for each instruction
- Optionally align instruction arguments with tabs or spaces
- IRC mode: write all output to one continuous line broken with backslashes
Sample disassembly of the first 256 bytes of my TI-84 Plus C SE ROM image (it was the first .bin file I could think of):
Code:
C:\somepath\eZDisasm -Ideb csepage0.bin 0000
0000: DB02 in a, (02)
0002: E680 and 80
0004: C37802 jp label_0278
0007: FF rst 38h
0008: C39417 jp label_1794
000B: 00 nop
000C: 00 nop
000D: 00 nop
000E: 00 nop
000F: C9 ret
0010: C3E70B jp label_0BE7
0013: FDCB0266 bit 4, (iy + 02)
0017: C9 ret
0018: C3E012 jp label_12E0
001B: CD743F call label_3F74
001E: 00 nop
001F: C9 ret
0020: C36B18 jp label_186B
0023: CD7A3F call label_3F7A
0026: 00 nop
0027: C9 ret
0028: C3A827 jp label_27A8
002B: 97 sub a
002C: 328F9B ld (loc_9B8F), a
002F: C9 ret
0030: C31D20 jp label_201D
0033: 7E ld a, (hl)
0034: 23 inc hl
0035: 66 ld h, (hl)
0036: 6F ld l, a
0037: C9 ret
0038: 1834 jr label_006E
label_003A:
003A: DB04 in a, (04)
003C: CB7F bit 7, a
003E: C22D01 jp nz, label_012D
0041: CB6F bit 5, a
0043: C23B01 jp nz, label_013B
0046: CB77 bit 6, a
0048: C25501 jp nz, label_0155
004B: C3C900 jp label_00C9
004E: FF rst 38h
004F: FF rst 38h
0050: C32D28 jp label_282D
0053: C3B00A jp label_0AB0
0056: 5A ld e, d
0057: A5 and l
0058: FF rst 38h
0059: C34B25 jp label_254B
005C: C37825 jp label_2578
005F: FF rst 38h
0060: FF rst 38h
0061: FF rst 38h
0062: 3C inc a
0063: 8B adc a, e
0064: 00 nop
0065: 34 inc (hl)
0066: 2E30 ld l, 30
0068: 2020 jr nz, label_008A
006A: 2020 jr nz, label_008C
006C: 2000 jr nz, label_006E
label_006E:
006E: 08 ex ex, ex'
006F: D9 exx
0070: DB55 in a, (55)
0072: EEFF xor FF
0074: E61F and 1F
0076: 28C2 jr z, label_003A
0078: FDCB3A46 bit 0, (iy + 3A)
007C: 2808 jr z, label_0086
007E: 062C ld b, 2C
0080: 4F ld c, a
0081: CDE702 call label_02E7
0084: 2857 jr z, label_00DD
label_0086:
0086: DB56 in a, (56)
0088: 47 ld b, a
0089: B7 or a
label_008A:
008A: 2825 jr z, label_00B1
label_008C:
008C: FDCB095E bit 3, (iy + 09)
0090: CAD101 jp z, label_01D1
0093: DB07 in a, (07)
0095: FE81 cp 81
0097: C2D101 jp nz, label_01D1
009A: 78 ld a, b
009B: CB67 bit 4, a
009D: C22301 jp nz, label_0123
00A0: CB6F bit 5, a
00A2: C22801 jp nz, label_0128
00A5: CB77 bit 6, a
00A7: 206B jr nz, label_0114
00A9: CB7F bit 7, a
00AB: 206C jr nz, label_0119
00AD: CB4F bit 1, a
00AF: 206D jr nz, label_011E
label_00B1:
00B1: DB55 in a, (55)
00B3: 47 ld b, a
00B4: E611 and 11
00B6: EE11 xor 11
00B8: CA3A00 jp z, label_003A
00BB: DB07 in a, (07)
00BD: FE81 cp 81
00BF: C2D101 jp nz, label_01D1
00C2: CB60 bit 4, b
00C4: CA4901 jp z, label_0149
00C7: 1846 jr label_010F
label_00C9:
00C9: CB57 bit 2, a
00CB: C2E201 jp nz, label_01E2
00CE: CB67 bit 4, a
00D0: C2D101 jp nz, label_01D1
00D3: 1F rra
00D4: DA5C01 jp c, label_015C
00D7: 1F rra
00D8: DA6801 jp c, label_0168
00DB: 1808 jr label_00E5
label_00DD:
00DD: F5 push af
00DE: 3E08 ld a, 08
00E0: D303 out (03), a
00E2: F1 pop af
00E3: D303 out (03), a
label_00E5:
00E5: 3E0B ld a, 0B
00E7: FDCB1646 bit 0, (iy + 16)
00EB: 2802 jr z, label_00EF
00ED: C604 add a, 04
label_00EF:
00EF: D303 out (03), a
00F1: 08 ex ex, ex'
00F2: D9 exx
00F3: FB ei
00F4: ED4D reti
00F6: FDCB034E bit 1, (iy + 03)
00FA: 200E jr nz, label_010A
00FC: FDCB17CE set 1, (iy + 17)
I also figured out how to make your console application figure out whether it's been invoked from a command line or from another GUI application. The code that does this calls out to a native Win32 function and might or might not cause problems on Mono/Linux/Macs. If it does, let me know; in the meantime, if you're feeling bold, you can recompile it without the WIN_32 define to disable all that code.