--- mon/src/mon_z80.cpp 2002/08/04 14:53:33 1.4 +++ mon/src/mon_z80.cpp 2007/01/21 17:32:05 1.8 @@ -1,7 +1,7 @@ /* * mon_z80.cpp - Z80 disassembler * - * cxmon (C) 1997-2002 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 @@ -27,7 +27,7 @@ // Addressing modes -enum { +enum AddrMode { A_IMPL, A_IMM8, // xx A_IMM16, // xxxx @@ -58,7 +58,7 @@ enum { }; // Mnemonics -enum { +enum Mnemonic { M_ADC, M_ADD, M_AND, M_BIT, M_CALL, M_CCF, M_CP, M_CPD, M_CPDR, M_CPI, M_CPIR, M_CPL, M_DAA, M_DEC, M_DI, M_DJNZ, M_EI, M_EX, M_EXX, M_HALT, M_IM0, M_IM1, M_IM2, M_IN, M_INC, M_IND, M_INDR, M_INI, M_INIR, M_JP, @@ -79,7 +79,7 @@ static const char mnem_3[] = "cddtlf ddi static const char mnem_4[] = " l r r z t012 r r r r rr di h in a a "; // Mnemonic for each opcode -static const char mnemonic[256] = { +static const Mnemonic mnemonic[256] = { M_NOP , M_LD , M_LD , M_INC , M_INC , M_DEC , M_LD , M_RLCA, // 00 M_EX , M_ADD, M_LD , M_DEC , M_INC , M_DEC , M_LD , M_RRCA, M_DJNZ, M_LD , M_LD , M_INC , M_INC , M_DEC , M_LD , M_RLA , // 10 @@ -117,7 +117,7 @@ static const char mnemonic[256] = { // Source/destination addressing modes for each opcode #define A(d,s) (((A_ ## d) << 8) | (A_ ## s)) -static const short adr_mode[256] = { +static const int adr_mode[256] = { A(IMPL,IMPL) , A(REG3,IMM16) , A(BC_IND,A) , A(REG3,IMPL) , A(REG2,IMPL) , A(REG2,IMPL) , A(REG2,IMM8) , A(IMPL,IMPL) , // 00 A(AF_AF,IMPL) , A(HL,REG3) , A(A,BC_IND) , A(REG3,IMPL) , A(REG2,IMPL) , A(REG2,IMPL) , A(REG2,IMM8) , A(IMPL,IMPL) , A(REL,IMPL) , A(REG3,IMM16) , A(DE_IND,A) , A(REG3,IMPL) , A(REG2,IMPL) , A(REG2,IMPL) , A(REG2,IMM8) , A(IMPL,IMPL) , // 10 @@ -208,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: @@ -229,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; } @@ -244,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]); @@ -275,10 +291,11 @@ static void operand(SFILE *f, char mode, case A_BIT_REG1: { // undoc int reg = op & 7; - if (reg == 6) + if (reg == 6) { mon_sprintf(f, "%d", (op >> 3) & 7); - else + } else { mon_sprintf(f, "%d,%s", (op >> 3) & 7, reg_name[reg]); + } break; } @@ -316,7 +333,7 @@ static void operand(SFILE *f, char mode, } } -static int print_instr(SFILE *f, char mnem, char dst_mode, char src_mode, uint32 adr, uint8 op, bool ix, bool iy) +static int print_instr(SFILE *f, Mnemonic mnem, AddrMode dst_mode, AddrMode src_mode, uint32 adr, uint8 op, bool ix, bool iy) { uint32 orig_adr = adr; @@ -349,7 +366,9 @@ static int disass_cb(SFILE *f, uint32 ad } // Decode mnemonic and addressing modes - char mnem = M_ILLEGAL, dst_mode = A_IMPL, src_mode = A_IMPL; + Mnemonic mnem = M_ILLEGAL; + AddrMode dst_mode = A_IMPL, src_mode = A_IMPL; + switch (op & 0xc0) { case 0x00: dst_mode = A_REG1X; @@ -362,7 +381,7 @@ 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; @@ -406,7 +425,9 @@ static int disass_ed(SFILE *f, uint32 ad uint8 op = mon_read_byte(adr); // Decode mnemonic and addressing modes - char mnem, dst_mode = A_IMPL, src_mode = A_IMPL; + Mnemonic mnem; + AddrMode dst_mode = A_IMPL, src_mode = A_IMPL; + switch (op) { case 0x40: case 0x48: @@ -415,10 +436,10 @@ static int disass_ed(SFILE *f, uint32 ad case 0x60: case 0x68: case 0x78: - mon_sprintf(f, "in %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 (c)"); + mon_sprintf(f, "in (c)"); return 1; case 0x41: @@ -428,10 +449,10 @@ static int disass_ed(SFILE *f, uint32 ad case 0x61: case 0x69: case 0x79: - mon_sprintf(f, "out (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 (c),0"); + mon_sprintf(f, "out (c),0"); return 1; case 0x42: @@ -500,16 +521,16 @@ static int disass_ed(SFILE *f, uint32 ad break; case 0x47: - mon_sprintf(f, "ld i,a"); + mon_sprintf(f, "ld i,a"); return 1; case 0x4f: - mon_sprintf(f, "ld r,a"); + mon_sprintf(f, "ld r,a"); return 1; case 0x57: - mon_sprintf(f, "ld a,i"); + mon_sprintf(f, "ld a,i"); return 1; case 0x5f: - mon_sprintf(f, "ld a,r"); + mon_sprintf(f, "ld a,r"); return 1; case 0x67: mnem = M_RRD; break; @@ -547,7 +568,7 @@ static int disass(SFILE *f, uint32 adr, if (op == 0xcb) return disass_cb(f, adr + 1, ix, iy) + 1; else - return print_instr(f, mnemonic[op], adr_mode[op] >> 8, adr_mode[op] & 0xff, adr + 1, op, ix, iy) + 1; + return print_instr(f, mnemonic[op], AddrMode(adr_mode[op] >> 8), AddrMode(adr_mode[op] & 0xff), adr + 1, op, ix, iy) + 1; } int disass_z80(FILE *f, uint32 adr)