From 36d84d998e8c9e102cf8268d7df012850f3f42b4 Mon Sep 17 00:00:00 2001 From: Brian Callahan Date: Sun, 4 Apr 2021 14:59:44 -0400 Subject: [PATCH] Add support for Z80 IX and IY tables. --- README.md | 4 +- source/app.d | 86 +++++++- source/d80/z80.d | 534 ++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 617 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 5c207a7..9789db1 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ d80 === `d80` is an Intel 8080/Zilog Z80 disassembler. -Supports the entire i80 instruction set and the main, CB, and ED Z80 tables -only (for now). +Supports the entire i80 instruction set and the main, CB, DD, ED, and FD Z80 +tables only (for now). Usage ----- diff --git a/source/app.d b/source/app.d index 780bdc4..2b77c06 100644 --- a/source/app.d +++ b/source/app.d @@ -44,6 +44,48 @@ static void disz80(ubyte[] b) case 0xdb: writef(insnz80[b[a]].s, b[a + 1]); break; + case 0xdd: /// DD table + switch (b[a + 1]) { + case 0x21: + case 0x22: + case 0x2a: + case 0x36: + writef(insnz80dd[b[a + 1]].s, b[a + 3], b[a + 2]); + a += insnz80dd[b[a + 1]].n; + break; + case 0x26: + case 0x2e: + case 0x34: + case 0x35: + case 0x46: + case 0x4e: + case 0x56: + case 0x5e: + case 0x66: + case 0x6e: + case 0x70: + case 0x71: + case 0x72: + case 0x73: + case 0x74: + case 0x75: + case 0x77: + case 0x7e: + case 0x86: + case 0x8e: + case 0x96: + case 0x9e: + case 0xa6: + case 0xae: + case 0xb6: + case 0xbe: + writef(insnz80dd[b[a + 1]].s, b[a + 2]); + a += insnz80dd[b[a + 1]].n; + break; + default: + writef("%s", insnz80dd[b[a + 1]].s); + } + break; case 0xed: /// ED table switch (b[a + 1]) { case 0x43: @@ -54,13 +96,55 @@ static void disz80(ubyte[] b) case 0x6b: case 0x73: case 0x7b: - write(insnz80ed[b[a + 1]].s, b[a + 3], b[a + 2]); + writef(insnz80ed[b[a + 1]].s, b[a + 3], b[a + 2]); a += insnz80ed[b[a + 1]].n; break; default: writef("%s", insnz80ed[b[a + 1]].s); } break; + case 0xfd: /// FD table + switch (b[a + 1]) { + case 0x21: + case 0x22: + case 0x2a: + case 0x36: + writef(insnz80fd[b[a + 1]].s, b[a + 3], b[a + 2]); + a += insnz80fd[b[a + 1]].n; + break; + case 0x26: + case 0x2e: + case 0x34: + case 0x35: + case 0x46: + case 0x4e: + case 0x56: + case 0x5e: + case 0x66: + case 0x6e: + case 0x70: + case 0x71: + case 0x72: + case 0x73: + case 0x74: + case 0x75: + case 0x77: + case 0x7e: + case 0x86: + case 0x8e: + case 0x96: + case 0x9e: + case 0xa6: + case 0xae: + case 0xb6: + case 0xbe: + writef(insnz80fd[b[a + 1]].s, b[a + 2]); + a += insnz80fd[b[a + 1]].n; + break; + default: + writef("%s", insnz80fd[b[a + 1]].s); + } + break; default: writef("%s", insnz80[b[a]].s); if (insnz80[b[a]].n > 1) { diff --git a/source/d80/z80.d b/source/d80/z80.d index ca0e8cd..79fe488 100644 --- a/source/d80/z80.d +++ b/source/d80/z80.d @@ -14,7 +14,7 @@ struct z80 { immutable z80[] insnz80 = [ { "nop", 1 }, { "ld\tbc, ", 3 }, - { "ld\t(bc), ", 1 }, + { "ld\t(bc), a", 1 }, { "inc\tbc", 1 }, { "inc\tb", 1 }, { "dec\tb", 1 }, @@ -36,7 +36,7 @@ immutable z80[] insnz80 = [ { "dec\td", 1 }, { "ld\td, ", 2 }, { "rla", 1 }, - { "jr\tx", 2 }, + { "jr\t", 2 }, { "add\thl, de", 1 }, { "ld\ta, (de)", 1 }, { "dec\tde" , 1 }, @@ -233,7 +233,7 @@ immutable z80[] insnz80 = [ { "jp\tc, ", 3 }, { "in\ta, (%02xh)", 2 }, { "call\tc, ", 3 }, - { "IX", 1 }, + { "IX", 2 }, { "sbc\ta, ", 2 }, { "rst\t18h", 1 }, { "ret\tpo", 1 }, @@ -265,7 +265,7 @@ immutable z80[] insnz80 = [ { "jp\tm, ", 3 }, { "ei", 1 }, { "call\tm, ", 3 }, - { "IY", 1 }, + { "IY", 2 }, { "cp\t", 2 }, { "rst\t38h", 1 } ]; @@ -534,6 +534,269 @@ immutable z80[] insnz80cb = [ { "set\t7, a", 0 } ]; +/** + * IX instructions (DD) table for Z80. + * Invalid instructions are marked nop. + */ +immutable z80[] insnz80dd = [ + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "add\tix, bc", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "add\tix, de", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "ld\tix, %02x%02xh", 2 }, + { "ld\t(%02x%02xh), ix", 2 }, + { "inc\tix", 0 }, + { "inc\tixh", 0 }, + { "dec\tixh", 0 }, + { "ld\tixh, %02xh", 1 }, + { "nop", 0 }, + { "nop", 0 }, + { "add\tix, ix", 0 }, + { "ld\tix, (%02x%02xh)", 2 }, + { "dec\tix", 0 }, + { "inc\tixl", 0 }, + { "dec\tixl", 0 }, + { "ld\tixl, %02xh", 1 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "inc\t(ix+%02xh)", 1 }, + { "dec\t(ix+%02xh)", 1 }, + { "ld\t(ix+%02xh), %02xh", 2 }, + { "nop", 0 }, + { "nop", 0 }, + { "add\tix, sp", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "ld\tb, ixh", 0 }, + { "ld\tb, ixl", 0 }, + { "ld\tb, (ix+%02xh)", 1 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "ld\tc, ixh", 0 }, + { "ld\tc, ixl", 0 }, + { "ld\tc, (ix+%02xh)", 1 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "ld\td, ixh", 0 }, + { "ld\td, ixl", 0 }, + { "ld\td, (ix+%02xh)", 1 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "ld\te, ixh", 0 }, + { "ld\te, ixl", 0 }, + { "ld\te, (ix+%02xh)", 1 }, + { "nop", 0 }, + { "ld\tixh, b", 0 }, + { "ld\tixh, c", 0 }, + { "ld\tixh, d", 0 }, + { "ld\tixh, e", 0 }, + { "ld\tixh, ixh", 0 }, + { "ld\tixh, ixl", 0 }, + { "ld\th, (ix+%02xh)", 1 }, + { "ld\tixh, a", 0 }, + { "ld\tixl, b", 0 }, + { "ld\tixl, c", 0 }, + { "ld\tixl, d", 0 }, + { "ld\tixl, e", 0 }, + { "ld\tixl, ixh", 0 }, + { "ld\tixl, ixl", 0 }, + { "ld\tl, (ix+%02xh)", 1 }, + { "ld\tixl, a", 0 }, + { "ld\t(ix+%02xh), b", 1 }, + { "ld\t(ix+%02xh), c", 1 }, + { "ld\t(ix+%02xh), d", 1 }, + { "ld\t(ix+%02xh), e", 1 }, + { "ld\t(ix+%02xh), h", 1 }, + { "ld\t(ix+%02xh), l", 1 }, + { "nop", 0 }, + { "ld\t(ix+%02xh), a", 1 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "ld\ta, ixh", 0 }, + { "ld\ta, ixl", 0 }, + { "ld\ta, (ix+%02xh)", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "add\ta, ixh", 0 }, + { "add\ta, ixl", 0 }, + { "add\ta, (ix+%02xh)", 1 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "adc\ta, ixh", 0 }, + { "adc\ta, ixl", 0 }, + { "adc\ta, (ix+%02xh)", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "sub\tixh", 0 }, + { "sub\tixl", 0 }, + { "sub\t(ix+%02xh)", 1 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "sbc\ta, ixh", 0 }, + { "sbc\ta, ixl", 0 }, + { "sbc\ta, (ix+%02xh)", 1 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "and\tixh", 0 }, + { "and\tixl", 0 }, + { "and\t(ix+%02xh)", 1 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "xor\tixh", 0 }, + { "xor\tixl", 0 }, + { "xor\t(ix+%02xh)", 1 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "or\tixh", 0 }, + { "or\tixl", 0 }, + { "or\t(ix+%02xh)", 1 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "cp\tixh", 0 }, + { "cp\tixl", 0 }, + { "cp\t(ix+%02xh)", 1 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "IX BITS", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "pop\tix", 0 }, + { "nop", 0 }, + { "ex\t(sp), ix", 0 }, + { "nop", 0 }, + { "push\tix", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "jp\t(ix)", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "ld\tsp, ix", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 } +]; + /** * Extended instructions (ED) table for Z80. * Invalid instructions are marked nop. @@ -796,3 +1059,266 @@ immutable z80[] insnz80ed = [ { "nop", 0 }, { "nop", 0 } ]; + +/** + * IY instructions (FD) table for Z80. + * Invalid instructions are marked nop. + */ +immutable z80[] insnz80fd = [ + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "add\tiy, bc", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "add\tiy, de", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "ld\tiy, %02x%02xh", 2 }, + { "ld\t(%02x%02xh), iy", 2 }, + { "inc\tiy", 0 }, + { "inc\tiyh", 0 }, + { "dec\tiyh", 0 }, + { "ld\tiyh, %02xh", 1 }, + { "nop", 0 }, + { "nop", 0 }, + { "add\tiy, iy", 0 }, + { "ld\tiy, (%02x%02xh)", 2 }, + { "dec\tiy", 0 }, + { "inc\tiyl", 0 }, + { "dec\tiyl", 0 }, + { "ld\tiyl, %02xh", 1 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "inc\t(iy+%02xh)", 1 }, + { "dec\t(iy+%02xh)", 1 }, + { "ld\t(iy+%02xh), %02xh", 2 }, + { "nop", 0 }, + { "nop", 0 }, + { "add\tiy, sp", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "ld\tb, iyh", 0 }, + { "ld\tb, iyl", 0 }, + { "ld\tb, (iy+%02xh)", 1 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "ld\tc, iyh", 0 }, + { "ld\tc, iyl", 0 }, + { "ld\tc, (iy+%02xh)", 1 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "ld\td, iyh", 0 }, + { "ld\td, iyl", 0 }, + { "ld\td, (iy+%02xh)", 1 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "ld\te, iyh", 0 }, + { "ld\te, iyl", 0 }, + { "ld\te, (iy+%02xh)", 1 }, + { "nop", 0 }, + { "ld\tiyh, b", 0 }, + { "ld\tiyh, c", 0 }, + { "ld\tiyh, d", 0 }, + { "ld\tiyh, e", 0 }, + { "ld\tiyh, iyh", 0 }, + { "ld\tiyh, iyl", 0 }, + { "ld\th, (iy+%02xh)", 1 }, + { "ld\tiyh, a", 0 }, + { "ld\tiyl, b", 0 }, + { "ld\tiyl, c", 0 }, + { "ld\tiyl, d", 0 }, + { "ld\tiyl, e", 0 }, + { "ld\tiyl, iyh", 0 }, + { "ld\tiyl, iyl", 0 }, + { "ld\tl, (iy+%02xh)", 1 }, + { "ld\tiyl, a", 0 }, + { "ld\t(iy+%02xh), b", 1 }, + { "ld\t(iy+%02xh), c", 1 }, + { "ld\t(iy+%02xh), d", 1 }, + { "ld\t(iy+%02xh), e", 1 }, + { "ld\t(iy+%02xh), h", 1 }, + { "ld\t(iy+%02xh), l", 1 }, + { "nop", 0 }, + { "ld\t(iy+%02xh), a", 1 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "ld\ta, iyh", 0 }, + { "ld\ta, iyl", 0 }, + { "ld\ta, (iy+%02xh)", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "add\ta, iyh", 0 }, + { "add\ta, iyl", 0 }, + { "add\ta, (iy+%02xh)", 1 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "adc\ta, iyh", 0 }, + { "adc\ta, iyl", 0 }, + { "adc\ta, (iy+%02xh)", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "sub\tiyh", 0 }, + { "sub\tiyl", 0 }, + { "sub\t(iy+%02xh)", 1 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "sbc\ta, iyh", 0 }, + { "sbc\ta, iyl", 0 }, + { "sbc\ta, (iy+%02xh)", 1 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "and\tiyh", 0 }, + { "and\tiyl", 0 }, + { "and\t(iy+%02xh)", 1 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "xor\tiyh", 0 }, + { "xor\tiyl", 0 }, + { "xor\t(iy+%02xh)", 1 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "or\tiyh", 0 }, + { "or\tiyl", 0 }, + { "or\t(iy+%02xh)", 1 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "cp\tiyh", 0 }, + { "cp\tiyl", 0 }, + { "cp\t(iy+%02xh)", 1 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "IY BITS", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "pop\tiy", 0 }, + { "nop", 0 }, + { "ex\t(sp), iy", 0 }, + { "nop", 0 }, + { "push\tiy", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "jp\t(iy)", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "ld\tsp, iy", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 }, + { "nop", 0 } +];