--- mon/src/mon_z80.cpp 2000/10/15 15:07:16 1.1 +++ mon/src/mon_z80.cpp 2007/01/14 14:01:09 1.7 @@ -1,7 +1,7 @@ /* * mon_z80.cpp - Z80 disassembler * - * cxmon (C) 1997-2000 Christian Bauer, Marc Hellwig + * cxmon (C) 1997-2007 Christian Bauer, Marc Hellwig * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -46,10 +46,12 @@ enum { A_COND, // condition code (bits 3..5 of opcode) A_COND2, // condition code (bits 3..4 of opcode) A_BIT, // bit number (bits 3..5 of opcode) + A_BIT_REG1, // bit number (bits 3..5 of opcode) followed by 8-bit register (bits 0..2 of opcode) A_RST, // restart A_BC_IND, // (bc) A_DE_IND, // (de) A_HL_IND, // (hl) or (ix) or (iy) + A_XY_IND, // (ix+d) or (iy+d) A_SP_IND, // (sp) A_DE_HL, // de,hl A_AF_AF, // af,af' @@ -206,7 +208,7 @@ static void operand(SFILE *f, char mode, break; case A_REL: - mon_sprintf(f, "$%04x", (adr + 2 + (int8)mon_read_byte(adr)) & 0xffff); adr++; + mon_sprintf(f, "$%04x", (adr + 1 + (int8)mon_read_byte(adr)) & 0xffff); adr++; break; case A_A: @@ -227,12 +229,14 @@ static void operand(SFILE *f, char mode, if (reg == 6) { if (ix || iy) { mon_sprintf(f, "(%s+$%02x)", ix ? "ix" : "iy", mon_read_byte(adr)); adr++; - } else + } else { mon_sprintf(f, "(hl)"); - } else if (mode == A_REG1) + } + } else if (mode == A_REG1) { mon_sprintf(f, "%s", ix ? reg_name_ix[reg] : (iy ? reg_name_iy[reg] : reg_name[reg])); - else + } else { mon_sprintf(f, "%s", reg_name[reg]); + } break; } @@ -242,22 +246,36 @@ static void operand(SFILE *f, char mode, if (reg == 6) { if (ix || iy) { mon_sprintf(f, "(%s+$%02x)", ix ? "ix" : "iy", mon_read_byte(adr)); adr++; - } else + } else { mon_sprintf(f, "(hl)"); - } else if (mode == A_REG2) + } + } else if (mode == A_REG2) { mon_sprintf(f, "%s", ix ? reg_name_ix[reg] : (iy ? reg_name_iy[reg] : reg_name[reg])); - else + } else { mon_sprintf(f, "%s", reg_name[reg]); + } break; } - case A_REG3: - mon_sprintf(f, reg_name_16[(op >> 4) & 3]); + case A_REG3: { + int reg = (op >> 4) & 3; + if (reg == 2 && (ix || iy)) { + mon_sprintf(f, ix ? "ix" : "iy"); + } else { + mon_sprintf(f, reg_name_16[reg]); + } break; + } - case A_REG4: - mon_sprintf(f, reg_name_16_2[(op >> 4) & 3]); + case A_REG4: { + int reg = (op >> 4) & 3; + if (reg == 2 && (ix || iy)) { + mon_sprintf(f, ix ? "ix" : "iy"); + } else { + mon_sprintf(f, reg_name_16_2[reg]); + } break; + } case A_COND: mon_sprintf(f, cond_name[(op >> 3) & 7]); @@ -271,6 +289,16 @@ static void operand(SFILE *f, char mode, mon_sprintf(f, "%d", (op >> 3) & 7); break; + case A_BIT_REG1: { // undoc + int reg = op & 7; + if (reg == 6) { + mon_sprintf(f, "%d", (op >> 3) & 7); + } else { + mon_sprintf(f, "%d,%s", (op >> 3) & 7, reg_name[reg]); + } + break; + } + case A_RST: mon_sprintf(f, "$%02x", op & 0x38); break; @@ -287,6 +315,10 @@ static void operand(SFILE *f, char mode, mon_sprintf(f, ix ? "(ix)" : (iy ? "(iy)" : "(hl)")); break; + case A_XY_IND: // undoc + mon_sprintf(f, "(%s+$%02x)", ix ? "ix" : "iy", mon_read_byte(adr)); adr++; + break; + case A_SP_IND: mon_sprintf(f, "(sp)"); break; @@ -334,10 +366,12 @@ static int disass_cb(SFILE *f, uint32 ad } // Decode mnemonic and addressing modes - char mnem, dst_mode = A_IMPL, src_mode = A_IMPL; + char mnem = M_ILLEGAL, dst_mode = A_IMPL, src_mode = A_IMPL; switch (op & 0xc0) { case 0x00: - dst_mode = A_REG1; + dst_mode = A_REG1X; + if ((ix || iy) && ((op & 7) != 6)) + src_mode = A_XY_IND; switch ((op >> 3) & 7) { case 0: mnem = M_RLC; break; case 1: mnem = M_RRC; break; @@ -345,18 +379,36 @@ static int disass_cb(SFILE *f, uint32 ad case 3: mnem = M_RR; break; case 4: mnem = M_SLA; break; case 5: mnem = M_SRA; break; - case 6: mnem = M_SL1; break; + case 6: mnem = M_SL1; break; // undoc case 7: mnem = M_SRL; break; } break; case 0x40: - mnem = M_BIT; dst_mode = A_BIT; src_mode = A_REG1; + mnem = M_BIT; dst_mode = A_BIT; + if (ix || iy) + src_mode = A_XY_IND; + else + src_mode = A_REG1; break; case 0x80: - mnem = M_RES; dst_mode = A_BIT; src_mode = A_REG1; + mnem = M_RES; + if (ix || iy) { + dst_mode = A_BIT_REG1; + src_mode = A_XY_IND; + } else { + dst_mode = A_BIT; + src_mode = A_REG1; + } break; case 0xc0: - mnem = M_SET; dst_mode = A_BIT; src_mode = A_REG1; + mnem = M_SET; + if (ix || iy) { + dst_mode = A_BIT_REG1; + src_mode = A_XY_IND; + } else { + dst_mode = A_BIT; + src_mode = A_REG1; + } break; } @@ -380,10 +432,10 @@ static int disass_ed(SFILE *f, uint32 ad case 0x60: case 0x68: case 0x78: - mon_sprintf(f, "in\t%s,(c)", reg_name[(op >> 3) & 7]); + mon_sprintf(f, "in %s,(c)", reg_name[(op >> 3) & 7]); return 1; case 0x70: - mon_sprintf(f, "in\t(c)"); + mon_sprintf(f, "in (c)"); return 1; case 0x41: @@ -393,10 +445,10 @@ static int disass_ed(SFILE *f, uint32 ad case 0x61: case 0x69: case 0x79: - mon_sprintf(f, "out\t(c),%s", reg_name[(op >> 3) & 7]); + mon_sprintf(f, "out (c),%s", reg_name[(op >> 3) & 7]); return 1; case 0x71: // undoc - mon_sprintf(f, "out\t(c),0"); + mon_sprintf(f, "out (c),0"); return 1; case 0x42: @@ -465,16 +517,16 @@ static int disass_ed(SFILE *f, uint32 ad break; case 0x47: - mon_sprintf(f, "ld\ti,a"); + mon_sprintf(f, "ld i,a"); return 1; case 0x4f: - mon_sprintf(f, "ld\tr,a"); + mon_sprintf(f, "ld r,a"); return 1; case 0x57: - mon_sprintf(f, "ld\ta,i"); + mon_sprintf(f, "ld a,i"); return 1; case 0x5f: - mon_sprintf(f, "ld\ta,r"); + mon_sprintf(f, "ld a,r"); return 1; case 0x67: mnem = M_RRD; break; @@ -498,7 +550,7 @@ static int disass_ed(SFILE *f, uint32 ad case 0xbb: mnem = M_OTDR; break; default: - mnem = M_ILLEGAL; + mnem = M_NOP; break; }