z80dasm 1.1.5

06.08.2017 12:26

This is becoming a summer of retro computing blog posts, isn't it? In any case, today I'm pleased to announce the release of z80dasm 1.1.5, the latest version of my disassembler for the Z80 CPU machine code.

Ast Moore recently noticed that z80dasm doesn't recognize several well known undocumented instructions. When I made z80dasm on the base of Jan Panteltje's dz80 several years ago my goal was to make a disassembler that would correctly produce an assembly listing for Galaksija's ROM. While I did add support for the sli instruction back then, it seems that Galaksija didn't use any of the other undocumented instructions.

z80dasm 1.1.4 did correctly include unknown instructions in the disassembly as raw hex values with defb directives, however it guessed the length of some of them wrong, which desynced the instruction decoder and produced garbage output. The output would still assemble back into the same binary, but the point of a disassembler is to produce human-readable output, so that was not very useful.

Fixing this problem was a bit more involved than I expected, but not for the usual reasons. One of the guidelines I had with z80dasm was to keep z80dasm and z80asm a matched pair. Being able to reproduce back the original binary from disassembled source is very useful when hacking on old software as well as in testing z80dasm. Unfortunately, it turned out that z80asm is quite bad at supporting these undocumented instructions as well. For instance, inc and dec with ixl and ixh register operands are not recognized at all. Some other instructions, like add with these undocumented operands produce wrong opcodes.

I guess this is not surprising. In contrast to the official instruction set there is no authoritative documentation for these instructions, so even the names differ in different sources. For example, both sli a and sll a mnemonics are commonly used for the cb 37 opcode.

I tried to fix some of the problems with z80asm I found, but it turned out to be quite time consuming. Both z80asm and z80dasm are written in, by today's standards, quite an archaic C style, with lots of pointer arithmetic and packing various unrelated things into a single int variable to save space. While I'm still fairly familiar with z80dasm code, the modifications I did to z80asm took a several sheets of paper to figure out.

$ hd
00000000  ed 70 dd 2c dd 23 23 3d  ed 71 dd 09              |.p.,.##=.q..|
$ z80dasm example.bin
; z80dasm 1.1.5
; command line: z80dasm example.bin

	org	00100h

	defb 0edh,070h	;in f,(c)
	defb 0ddh,02ch	;inc ixl
	inc ix
	inc hl	
	dec a	
	defb 0edh,071h	;out (c),0
	add ix,bc

In the end, I gave up and solved the problem of z80asm compatibility by leaving z80dasm to decode undocumented instructions as defb directives. However, the instruction lengths should now be decoded correctly and also the mnemonic is included in a comment for better readability. There is now also a new --undoc option in 1.1.5. If it's specified on the command-line, z80dasm will place all instructions directly into the disassembly.

As before, you can get the source code for z80dasm in a release tarball or from the git repository. See the README file for install instructions and the included man page for explanations of all command-line options. z80dasm is also included in Debian, however 1.1.5 has not been uploaded yet.

Posted by Tomaž | Categories: Code

Add a new comment

(No HTML tags allowed. Separate paragraphs with a blank line.)