# HG changeset patch # User Mike Pavone # Date 1358914865 28800 # Node ID 0ae589d4c3f9b2701eb1c0a8ae4d2a04cafaa60b # Parent 693ad04b965e6766ad6754532ad5b63b430de142 Add support for 2-byte IX instructions to decoder diff -r 693ad04b965e -r 0ae589d4c3f9 notes.txt --- a/notes.txt Mon Jan 21 21:59:09 2013 -0800 +++ b/notes.txt Tue Jan 22 20:21:05 2013 -0800 @@ -56,11 +56,21 @@ x86-64 registers in Z80 core -ax = AF +ax = HL bx = BC cx = DE -dx = HL +dx = IX +ebp = current cycle count +rsi = context pointer +edi = target cycle count +rsp = native stack pointer +r8 = IY +r9 = SP +r10 = A (maybe AF?) +r11 = z80 ram address +r12 = cartridge address if bank is pointed at ROM +r13 = scratch1 +r14 = scratch2 +r15 = ?maybe z80 bank register? -1. native stack pointer -2. current cycle count -3. target cycle count + diff -r 693ad04b965e -r 0ae589d4c3f9 z80inst.c --- a/z80inst.c Mon Jan 21 21:59:09 2013 -0800 +++ b/z80inst.c Tue Jan 22 20:21:05 2013 -0800 @@ -490,7 +490,280 @@ BIT_BLOCK(Z80_SET, 7) }; -z80inst z80_tbl_ix[256 +z80inst z80_tbl_ix[256] = { + //0 + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + {Z80_ADD, Z80_IX, Z80_REG, Z80_BC, 0}, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + //1 + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + {Z80_ADD, Z80_IX, Z80_REG, Z80_DE, 0}, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + //2 + NOP2, + {Z80_LD, Z80_IX, Z80_IMMED, Z80_UNUSED, 0}, + {Z80_LD, Z80_IX, Z80_IMMED_INDIRECT | Z80_DIR, Z80_UNUSED, 0}, + {Z80_INC, Z80_IX, Z80_UNUSED, Z80_UNUSED, 0}, + {Z80_INC, Z80_IXH, Z80_UNUSED, Z80_UNUSED, 0}, + {Z80_DEC, Z80_IXH, Z80_UNUSED, Z80_UNUSED, 0}, + {Z80_LD, Z80_IXH, Z80_IMMED, Z80_UNUSED, 0}, + NOP2, + NOP2, + {Z80_ADD, Z80_IX, Z80_REG, Z80_IX, 0}, + {Z80_LD, Z80_IX, Z80_IMMED_INDIRECT, Z80_UNUSED, 0}, + {Z80_DEC, Z80_IX, Z80_UNUSED, Z80_UNUSED, 0}, + {Z80_INC, Z80_IXL, Z80_UNUSED, Z80_UNUSED, 0}, + {Z80_DEC, Z80_IXL, Z80_UNUSED, Z80_UNUSED, 0}, + {Z80_LD, Z80_IXL, Z80_IMMED, Z80_UNUSED, 0}, + NOP2, + //3 + NOP2, + NOP2, + NOP2, + NOP2, + {Z80_INC, Z80_UNUSED, Z80_IX_DISPLACE, 0, 0}, + {Z80_DEC, Z80_UNUSED, Z80_IX_DISPLACE, 0, 0}, + {Z80_LD, Z80_USE_IMMED, Z80_IX_DISPLACE | Z80_DIR, 0, 0}, + NOP2, + NOP2, + {Z80_ADD, Z80_IX, Z80_REG, Z80_SP, 0}, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + //4 + NOP2, + NOP2, + NOP2, + NOP2, + {Z80_LD, Z80_B, Z80_REG, Z80_IXH, 0}, + {Z80_LD, Z80_B, Z80_REG, Z80_IXL, 0}, + {Z80_LD, Z80_B, Z80_IX_DISPLACE, 0, 0}, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + {Z80_LD, Z80_C, Z80_REG, Z80_IXH, 0}, + {Z80_LD, Z80_C, Z80_REG, Z80_IXL, 0}, + {Z80_LD, Z80_C, Z80_IX_DISPLACE, 0, 0}, + NOP2, + //5 + NOP2, + NOP2, + NOP2, + NOP2, + {Z80_LD, Z80_D, Z80_REG, Z80_IXH, 0}, + {Z80_LD, Z80_D, Z80_REG, Z80_IXL, 0}, + {Z80_LD, Z80_D, Z80_IX_DISPLACE, 0, 0}, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + {Z80_LD, Z80_E, Z80_REG, Z80_IXH, 0}, + {Z80_LD, Z80_E, Z80_REG, Z80_IXL, 0}, + {Z80_LD, Z80_E, Z80_IX_DISPLACE, 0, 0}, + NOP2, + //6 + {Z80_LD, Z80_IXH, Z80_REG, Z80_B, 0}, + {Z80_LD, Z80_IXH, Z80_REG, Z80_C, 0}, + {Z80_LD, Z80_IXH, Z80_REG, Z80_D, 0}, + {Z80_LD, Z80_IXH, Z80_REG, Z80_E, 0}, + {Z80_LD, Z80_IXH, Z80_REG, Z80_IXH, 0}, + {Z80_LD, Z80_IXH, Z80_REG, Z80_IXL, 0}, + {Z80_LD, Z80_H, Z80_IX_DISPLACE, 0, 0}, + {Z80_LD, Z80_IXH, Z80_REG, Z80_A, 0}, + {Z80_LD, Z80_IXL, Z80_REG, Z80_B, 0}, + {Z80_LD, Z80_IXL, Z80_REG, Z80_C, 0}, + {Z80_LD, Z80_IXL, Z80_REG, Z80_D, 0}, + {Z80_LD, Z80_IXL, Z80_REG, Z80_E, 0}, + {Z80_LD, Z80_IXL, Z80_REG, Z80_IXH, 0}, + {Z80_LD, Z80_IXL, Z80_REG, Z80_IXL, 0}, + {Z80_LD, Z80_L, Z80_IX_DISPLACE, 0, 0}, + {Z80_LD, Z80_IXL, Z80_REG, Z80_A, 0}, + //7 + {Z80_LD, Z80_B, Z80_IX_DISPLACE | Z80_DIR, 0, 0}, + {Z80_LD, Z80_C, Z80_IX_DISPLACE | Z80_DIR, 0, 0}, + {Z80_LD, Z80_D, Z80_IX_DISPLACE | Z80_DIR, 0, 0}, + {Z80_LD, Z80_E, Z80_IX_DISPLACE | Z80_DIR, 0, 0}, + {Z80_LD, Z80_H, Z80_IX_DISPLACE | Z80_DIR, 0, 0}, + {Z80_LD, Z80_L, Z80_IX_DISPLACE | Z80_DIR, 0, 0}, + NOP2, + {Z80_LD, Z80_A, Z80_IX_DISPLACE | Z80_DIR, 0, 0}, + NOP2, + NOP2, + NOP2, + NOP2, + {Z80_LD, Z80_A, Z80_REG, Z80_IXH, 0}, + {Z80_LD, Z80_A, Z80_REG, Z80_IXL, 0}, + {Z80_LD, Z80_A, Z80_IX_DISPLACE, 0, 0}, + NOP2, + //8 + NOP2, + NOP2, + NOP2, + NOP2, + {Z80_ADD, Z80_A, Z80_REG, Z80_IXH, 0}, + {Z80_ADD, Z80_A, Z80_REG, Z80_IXL, 0}, + {Z80_ADD, Z80_A, Z80_IX_DISPLACE, 0, 0}, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + {Z80_ADC, Z80_A, Z80_REG, Z80_IXH, 0}, + {Z80_ADC, Z80_A, Z80_REG, Z80_IXL, 0}, + {Z80_ADC, Z80_A, Z80_IX_DISPLACE, 0, 0}, + NOP2, + //9 + NOP2, + NOP2, + NOP2, + NOP2, + {Z80_SUB, Z80_A, Z80_REG, Z80_IXH, 0}, + {Z80_SUB, Z80_A, Z80_REG, Z80_IXL, 0}, + {Z80_SUB, Z80_A, Z80_IX_DISPLACE, 0, 0}, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + {Z80_SBC, Z80_A, Z80_REG, Z80_IXH, 0}, + {Z80_SBC, Z80_A, Z80_REG, Z80_IXL, 0}, + {Z80_SBC, Z80_A, Z80_IX_DISPLACE, 0, 0}, + NOP2, + //A + NOP2, + NOP2, + NOP2, + NOP2, + {Z80_AND, Z80_A, Z80_REG, Z80_IXH, 0}, + {Z80_AND, Z80_A, Z80_REG, Z80_IXL, 0}, + {Z80_AND, Z80_A, Z80_IX_DISPLACE, 0, 0}, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + {Z80_XOR, Z80_A, Z80_REG, Z80_IXH, 0}, + {Z80_XOR, Z80_A, Z80_REG, Z80_IXL, 0}, + {Z80_XOR, Z80_A, Z80_IX_DISPLACE, 0, 0}, + NOP2, + //B + NOP2, + NOP2, + NOP2, + NOP2, + {Z80_OR, Z80_A, Z80_REG, Z80_IXH, 0}, + {Z80_OR, Z80_A, Z80_REG, Z80_IXL, 0}, + {Z80_OR, Z80_A, Z80_IX_DISPLACE, 0, 0}, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + {Z80_CP, Z80_A, Z80_REG, Z80_IXH, 0}, + {Z80_CP, Z80_A, Z80_REG, Z80_IXL, 0}, + {Z80_CP, Z80_A, Z80_IX_DISPLACE, 0, 0}, + NOP2, + //C + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + //D + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + //E + NOP2, + {Z80_POP, Z80_IX, Z80_UNUSED, Z80_UNUSED, 0}, + NOP2, + {Z80_EX, Z80_IX, Z80_REG_INDIRECT | Z80_DIR, Z80_SP, 0}, + NOP2, + {Z80_PUSH, Z80_IX, Z80_UNUSED, Z80_UNUSED, 0}, + NOP2, + NOP2, + NOP2, + {Z80_JP, Z80_UNUSED, Z80_REG_INDIRECT, Z80_IX, 0}, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + //F + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + {Z80_LD, Z80_SP, Z80_REG, Z80_IX, 0}, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2, + NOP2 +}; uint8_t * z80_decode(uint8_t * istream, z80inst * decoded) { @@ -498,6 +771,11 @@ istream++; memcpy(decoded, z80_tbl_bit + *istream, sizeof(z80inst)); } else if (*istream == 0xDD) { + istream++; + if (*istream == 0xCB) { + } else { + memcpy(decoded, z80_tbl_ix + *istream, sizeof(z80inst)); + } } else if (*istream == 0xED) { istream++; if (*istream < 0x40 || *istream >= 0xC0) { @@ -510,19 +788,22 @@ memcpy(decoded, z80_tbl_a + *istream, sizeof(z80inst)); } - if ((decoded->addr_mode & 0xF) == Z80_IMMED && decoded->op != Z80_RST && decoded->op != Z80_IM) { + if ((decoded->addr_mode & 0x1F) == Z80_IX_DISPLACE || (decoded->addr_mode & 0x1F) == Z80_IY_DISPLACE) { + decoded->ea_reg = *(++istream); + } else if ((decoded->addr_mode & 0x1F) == Z80_IMMED && decoded->op != Z80_RST && decoded->op != Z80_IM) { decoded->immed = *(++istream); if (decoded->reg >= Z80_BC && decoded->reg < Z80_USE_IMMED) { decoded->immed |= *(++istream) << 8; } else if (decoded->immed & 0x80) { decoded->immed |= 0xFF00; } - } else if ((decoded->addr_mode & 0xF) == Z80_IMMED_INDIRECT) { + } else if ((decoded->addr_mode & 0x1F) == Z80_IMMED_INDIRECT) { decoded->immed = *(++istream); if (decoded->op != Z80_OUT && decoded->op != Z80_IN) { decoded->immed |= *(++istream) << 8; } - } else if (decoded->reg == Z80_USE_IMMED && decoded->op != Z80_BIT && decoded->op != Z80_RES && decoded->op != Z80_SET) { + } + if (decoded->reg == Z80_USE_IMMED && decoded->op != Z80_BIT && decoded->op != Z80_RES && decoded->op != Z80_SET) { decoded->immed = *(++istream); } return istream+1; @@ -608,6 +889,8 @@ "l", "", "a", + "ixh", + "ixl", "i", "r", "bc", @@ -615,6 +898,8 @@ "hl", "sp", "af", + "ix", + "iy", }; char * z80_conditions[Z80_CC_M+1] = { @@ -632,7 +917,7 @@ { int len = sprintf(dst, "%s", z80_mnemonics[decoded->op]); if (decoded->addr_mode & Z80_DIR) { - switch (decoded->addr_mode & 0xF) + switch (decoded->addr_mode & 0x1F) { case Z80_REG: len += sprintf(dst+len, " %s", z80_regs[decoded->ea_reg]); @@ -646,6 +931,12 @@ case Z80_IMMED_INDIRECT: len += sprintf(dst+len, " (%d)", decoded->immed); break; + case Z80_IX_DISPLACE: + len += sprintf(dst+len, " (ix+%d)", decoded->ea_reg); + break; + case Z80_IY_DISPLACE: + len += sprintf(dst+len, " (iy+%d)", decoded->ea_reg); + break; } if (decoded->reg == Z80_USE_IMMED) { len += sprintf(dst+len, " %d", decoded->immed); @@ -680,6 +971,12 @@ case Z80_IMMED_INDIRECT: len += sprintf(dst+len, "%s (%d)", decoded->reg == Z80_UNUSED ? "" : "," , decoded->immed); break; + case Z80_IX_DISPLACE: + len += sprintf(dst+len, "%s (ix+%d)", decoded->reg == Z80_UNUSED ? "" : "," , decoded->ea_reg); + break; + case Z80_IY_DISPLACE: + len += sprintf(dst+len, "%s (iy+%d)", decoded->reg == Z80_UNUSED ? "" : "," , decoded->ea_reg); + break; } } return len; diff -r 693ad04b965e -r 0ae589d4c3f9 z80inst.h --- a/z80inst.h Mon Jan 21 21:59:09 2013 -0800 +++ b/z80inst.h Tue Jan 22 20:21:05 2013 -0800 @@ -79,6 +79,8 @@ Z80_H, Z80_L, Z80_A=7, + Z80_IXH, + Z80_IXL, Z80_I, Z80_R, Z80_BC, @@ -86,6 +88,8 @@ Z80_HL, Z80_SP, Z80_AF, + Z80_IX, + Z80_IY, Z80_USE_IMMED, Z80_UNUSED }; @@ -106,7 +110,8 @@ Z80_REG_INDIRECT, Z80_IMMED, Z80_IMMED_INDIRECT, - Z80_REG_DISPLACE + Z80_IX_DISPLACE, + Z80_IY_DISPLACE }; #define Z80_DIR 0x80