Improve MCS-96 (i8x9x) disassembly

- Properly decode names of directly addressed SFRs. This involves a major refactoring of the instruction execution/description unit to keep track of operand sizes and write-only destinations (since 8X9X maps numerous write-only SFRs to the same addresses as read-only SFRs).
- Correct operand size for immediate modes of ADDCB and SUBCB and indexed mode of MULB.
- Correct destination register for execution of the indexed mode of 2-argument ANDB.
- Correct assembler syntax of JBC and JBS (the bit specifier follows the register).
This commit is contained in:
AJR 2018-10-25 23:08:48 -04:00
parent d6e77a5df0
commit 69b071a533
7 changed files with 689 additions and 412 deletions

View File

@ -15,5 +15,72 @@ i8x9x_disassembler::i8x9x_disassembler() : mcs96_disassembler(disasm_entries)
{
}
std::string i8x9x_disassembler::regname8(uint8_t reg, bool is_dest) const
{
switch(reg) {
case 0x02:
return is_dest ? "ad_command" : "ad_result_lo";
case 0x03:
return is_dest ? "hsi_mode" : "ad_result_hi";
case 0x06:
return is_dest ? "hso_command" : "hsi_status";
case 0x07:
return "sbuf";
case 0x0a:
if (is_dest)
return "watchdog";
break;
case 0x0e:
return is_dest ? "baud_rate" : "port0";
case 0x0f:
return "port1";
case 0x10:
return "port2";
case 0x11:
return is_dest ? "sp_con" : "sp_stat";
case 0x15:
return is_dest ? "ioc0" : "ios0";
case 0x16:
return is_dest ? "ioc1" : "ios1";
case 0x17:
if (is_dest)
return "pwm_control";
break;
}
return mcs96_disassembler::regname8(reg, is_dest);
}
std::string i8x9x_disassembler::regname16(uint8_t reg, bool is_dest) const
{
switch(reg) {
case 0x04:
return is_dest ? "hso_time" : "hsi_time";
case 0x0a:
if (!is_dest)
return "timer1";
break;
case 0x0c:
if (!is_dest)
return "timer2";
break;
}
return mcs96_disassembler::regname16(reg, is_dest);
}
#include "cpu/mcs96/i8x9xd.hxx"

View File

@ -19,6 +19,10 @@ public:
i8x9x_disassembler();
virtual ~i8x9x_disassembler() = default;
protected:
virtual std::string regname8(uint8_t reg, bool is_dest) const override;
virtual std::string regname16(uint8_t reg, bool is_dest) const override;
private:
static const disasm_entry disasm_entries[0x100];
};

View File

@ -26,13 +26,13 @@ protected:
#define O(o) void o ## _196_full(); void o ## _196_partial()
O(bmov_direct_2);
O(bmovi_direct_2);
O(cmpl_direct_2);
O(djnzw_rrel8);
O(bmov_direct_2w);
O(bmovi_direct_2w);
O(cmpl_direct_2w);
O(djnzw_wrrel8);
O(idlpd_none);
O(pop_indexed_1);
O(pop_indirect_1);
O(pop_indexed_1w);
O(pop_indirect_1w);
O(popa_none);
O(pusha_none);

View File

@ -123,34 +123,34 @@ protected:
#define O(o) void o ## _full(); void o ## _partial()
O(add_direct_2); O(add_direct_3); O(add_immed_2w); O(add_immed_3w); O(add_indexed_2); O(add_indexed_3); O(add_indirect_2); O(add_indirect_3);
O(addb_direct_2); O(addb_direct_3); O(addb_immed_2b); O(addb_immed_3b); O(addb_indexed_2); O(addb_indexed_3); O(addb_indirect_2); O(addb_indirect_3);
O(addc_direct_2); O(addc_immed_2w); O(addc_indexed_2); O(addc_indirect_2);
O(addcb_direct_2); O(addcb_immed_2w); O(addcb_indexed_2); O(addcb_indirect_2);
O(and_direct_2); O(and_direct_3); O(and_immed_2w); O(and_immed_3w); O(and_indexed_2); O(and_indexed_3); O(and_indirect_2); O(and_indirect_3);
O(andb_direct_2); O(andb_direct_3); O(andb_immed_2b); O(andb_immed_3b); O(andb_indexed_2); O(andb_indexed_3); O(andb_indirect_2); O(andb_indirect_3);
O(add_direct_2w); O(add_direct_3w); O(add_immed_2w); O(add_immed_3w); O(add_indexed_2w); O(add_indexed_3w); O(add_indirect_2w); O(add_indirect_3w);
O(addb_direct_2b); O(addb_direct_3b); O(addb_immed_2b); O(addb_immed_3b); O(addb_indexed_2b); O(addb_indexed_3b); O(addb_indirect_2b); O(addb_indirect_3b);
O(addc_direct_2w); O(addc_immed_2w); O(addc_indexed_2w); O(addc_indirect_2w);
O(addcb_direct_2b); O(addcb_immed_2b); O(addcb_indexed_2b); O(addcb_indirect_2b);
O(and_direct_2w); O(and_direct_3w); O(and_immed_2w); O(and_immed_3w); O(and_indexed_2w); O(and_indexed_3w); O(and_indirect_2w); O(and_indirect_3w);
O(andb_direct_2b); O(andb_direct_3b); O(andb_immed_2b); O(andb_immed_3b); O(andb_indexed_2b); O(andb_indexed_3b); O(andb_indirect_2b); O(andb_indirect_3b);
O(br_indirect_1n);
O(clr_direct_1);
O(clrb_direct_1);
O(clr_direct_1w);
O(clrb_direct_1b);
O(clrc_none);
O(clrvt_none);
O(cmp_direct_2); O(cmp_immed_2w); O(cmp_indexed_2); O(cmp_indirect_2);
O(cmpb_direct_2); O(cmpb_immed_2b); O(cmpb_indexed_2); O(cmpb_indirect_2);
O(dec_direct_1);
O(decb_direct_1);
O(cmp_direct_2w); O(cmp_immed_2w); O(cmp_indexed_2w); O(cmp_indirect_2w);
O(cmpb_direct_2b); O(cmpb_immed_2b); O(cmpb_indexed_2b); O(cmpb_indirect_2b);
O(dec_direct_1w);
O(decb_direct_1b);
O(di_none);
O(div_direct_2); O(div_immed_2w); O(div_indexed_2); O(div_indirect_2);
O(divb_direct_2); O(divb_immed_2b); O(divb_indexed_2); O(divb_indirect_2);
O(divu_direct_2); O(divu_immed_2w); O(divu_indexed_2); O(divu_indirect_2);
O(divub_direct_2); O(divub_immed_2b); O(divub_indexed_2); O(divub_indirect_2);
O(div_direct_2w); O(div_immed_2w); O(div_indexed_2w); O(div_indirect_2w);
O(divb_direct_2e); O(divb_immed_2e); O(divb_indexed_2w); O(divb_indirect_2w);
O(divu_direct_2w); O(divu_immed_2w); O(divu_indexed_2w); O(divu_indirect_2w);
O(divub_direct_2e); O(divub_immed_2e); O(divub_indexed_2w); O(divub_indirect_2w);
O(djnz_rrel8);
O(djnzw_rrel8);
O(djnzw_wrrel8);
O(ei_none);
O(ext_direct_1);
O(extb_direct_1);
O(ext_direct_1w);
O(extb_direct_1b);
O(idlpd_none);
O(inc_direct_1);
O(incb_direct_1);
O(inc_direct_1w);
O(incb_direct_1b);
O(jbc_brrel8);
O(jbs_brrel8);
O(jc_rel8);
@ -170,53 +170,53 @@ protected:
O(jv_rel8);
O(jvt_rel8);
O(lcall_rel16);
O(ld_direct_2); O(ld_immed_2w); O(ld_indexed_2); O(ld_indirect_2);
O(ldb_direct_2); O(ldb_immed_2b); O(ldb_indexed_2); O(ldb_indirect_2);
O(ldbse_direct_2); O(ldbse_immed_2b); O(ldbse_indexed_2); O(ldbse_indirect_2);
O(ldbze_direct_2); O(ldbze_immed_2b); O(ldbze_indexed_2); O(ldbze_indirect_2);
O(ld_direct_2w); O(ld_immed_2w); O(ld_indexed_2w); O(ld_indirect_2w);
O(ldb_direct_2b); O(ldb_immed_2b); O(ldb_indexed_2b); O(ldb_indirect_2b);
O(ldbse_direct_2e); O(ldbse_immed_2e); O(ldbse_indexed_2w); O(ldbse_indirect_2w);
O(ldbze_direct_2e); O(ldbze_immed_2e); O(ldbze_indexed_2w); O(ldbze_indirect_2w);
O(ljmp_rel16);
O(mul_direct_2); O(mul_direct_3); O(mul_immed_2w); O(mul_immed_3w); O(mul_indexed_2); O(mul_indexed_3); O(mul_indirect_2); O(mul_indirect_3);
O(mulb_direct_2); O(mulb_direct_3); O(mulb_immed_2b); O(mulb_immed_3b); O(mulb_indexed_2); O(mulb_indexed_3); O(mulb_indirect_2); O(mulb_indirect_3);
O(mulu_direct_2); O(mulu_direct_3); O(mulu_immed_2w); O(mulu_immed_3w); O(mulu_indexed_2); O(mulu_indexed_3); O(mulu_indirect_2); O(mulu_indirect_3);
O(mulub_direct_2); O(mulub_direct_3); O(mulub_immed_2b); O(mulub_immed_3b); O(mulub_indexed_2); O(mulub_indexed_3); O(mulub_indirect_2); O(mulub_indirect_3);
O(neg_direct_1);
O(negb_direct_1);
O(mul_direct_2w); O(mul_direct_3w); O(mul_immed_2w); O(mul_immed_3w); O(mul_indexed_2w); O(mul_indexed_3w); O(mul_indirect_2w); O(mul_indirect_3w);
O(mulb_direct_2b); O(mulb_direct_3e); O(mulb_immed_2b); O(mulb_immed_3e); O(mulb_indexed_2b); O(mulb_indexed_3e); O(mulb_indirect_2b); O(mulb_indirect_3e);
O(mulu_direct_2w); O(mulu_direct_3w); O(mulu_immed_2w); O(mulu_immed_3w); O(mulu_indexed_2w); O(mulu_indexed_3w); O(mulu_indirect_2w); O(mulu_indirect_3w);
O(mulub_direct_2b); O(mulub_direct_3e); O(mulub_immed_2b); O(mulub_immed_3e); O(mulub_indexed_2b); O(mulub_indexed_3e); O(mulub_indirect_2b); O(mulub_indirect_3e);
O(neg_direct_1w);
O(negb_direct_1b);
O(nop_none);
O(norml_direct_2);
O(not_direct_1);
O(notb_direct_1);
O(or_direct_2); O(or_immed_2w); O(or_indexed_2); O(or_indirect_2);
O(orb_direct_2); O(orb_immed_2b); O(orb_indexed_2); O(orb_indirect_2);
O(pop_direct_1); O(pop_indexed_1); O(pop_indirect_1);
O(norml_direct_2e);
O(not_direct_1w);
O(notb_direct_1b);
O(or_direct_2w); O(or_immed_2w); O(or_indexed_2w); O(or_indirect_2w);
O(orb_direct_2b); O(orb_immed_2b); O(orb_indexed_2b); O(orb_indirect_2b);
O(pop_direct_1w); O(pop_indexed_1w); O(pop_indirect_1w);
O(popf_none);
O(push_direct_1); O(push_immed_1w); O(push_indexed_1); O(push_indirect_1);
O(push_direct_1w); O(push_immed_1w); O(push_indexed_1w); O(push_indirect_1w);
O(pushf_none);
O(ret_none);
O(rst_none);
O(scall_rel11);
O(setc_none);
O(shl_immed_or_reg_2b);
O(shl_immed_or_reg_2w);
O(shlb_immed_or_reg_2b);
O(shll_immed_or_reg_2b);
O(shr_immed_or_reg_2b);
O(shra_immed_or_reg_2b);
O(shll_immed_or_reg_2w);
O(shr_immed_or_reg_2w);
O(shra_immed_or_reg_2w);
O(shrab_immed_or_reg_2b);
O(shral_immed_or_reg_2b);
O(shral_immed_or_reg_2w);
O(shrb_immed_or_reg_2b);
O(shrl_immed_or_reg_2b);
O(shrl_immed_or_reg_2w);
O(sjmp_rel11);
O(skip_immed_1b);
O(st_direct_2); O(st_indexed_2); O(st_indirect_2);
O(stb_direct_2); O(stb_indexed_2); O(stb_indirect_2);
O(sub_direct_2); O(sub_direct_3); O(sub_immed_2w); O(sub_immed_3w); O(sub_indexed_2); O(sub_indexed_3); O(sub_indirect_2); O(sub_indirect_3);
O(subb_direct_2); O(subb_direct_3); O(subb_immed_2b); O(subb_immed_3b); O(subb_indexed_2); O(subb_indexed_3); O(subb_indirect_2); O(subb_indirect_3);
O(subc_direct_2); O(subc_immed_2w); O(subc_indexed_2); O(subc_indirect_2);
O(subcb_direct_2); O(subcb_immed_2w); O(subcb_indexed_2); O(subcb_indirect_2);
O(st_direct_2w); O(st_indexed_2w); O(st_indirect_2w);
O(stb_direct_2b); O(stb_indexed_2b); O(stb_indirect_2b);
O(sub_direct_2w); O(sub_direct_3w); O(sub_immed_2w); O(sub_immed_3w); O(sub_indexed_2w); O(sub_indexed_3w); O(sub_indirect_2w); O(sub_indirect_3w);
O(subb_direct_2b); O(subb_direct_3b); O(subb_immed_2b); O(subb_immed_3b); O(subb_indexed_2b); O(subb_indexed_3b); O(subb_indirect_2b); O(subb_indirect_3b);
O(subc_direct_2w); O(subc_immed_2w); O(subc_indexed_2w); O(subc_indirect_2w);
O(subcb_direct_2b); O(subcb_immed_2b); O(subcb_indexed_2b); O(subcb_indirect_2b);
O(trap_none);
O(xch_direct_2);
O(xchb_direct_2);
O(xor_direct_2); O(xor_immed_2w); O(xor_indexed_2); O(xor_indirect_2);
O(xorb_direct_2); O(xorb_immed_2b); O(xorb_indexed_2); O(xorb_indirect_2);
O(xch_direct_2w);
O(xchb_direct_2b);
O(xor_direct_2w); O(xor_immed_2w); O(xor_indexed_2w); O(xor_indirect_2w);
O(xorb_direct_2b); O(xorb_immed_2b); O(xorb_indexed_2b); O(xorb_indirect_2b);
O(fetch);
O(fetch_noirq);

View File

@ -20,16 +20,67 @@ u32 mcs96_disassembler::opcode_alignment() const
return 1;
}
std::string mcs96_disassembler::regname(uint8_t reg)
std::string mcs96_disassembler::regname8(uint8_t reg, bool is_dest) const
{
switch(reg) {
case 0x00:
return "r0";
case 0x08:
return "int_mask";
case 0x09:
return "int_pending";
case 0x1c:
return "al";
case 0x1d:
return "ah";
case 0x1e:
return "dl";
case 0x1f:
return "dh";
case 0x20:
return "bl";
case 0x21:
return "bh";
case 0x22:
return "cl";
case 0x23:
return "ch";
default:
return util::string_format("%02x", reg);
}
}
std::string mcs96_disassembler::regname16(uint8_t reg, bool is_dest) const
{
switch(reg) {
case 0x00:
return "r0";
case 0x18:
return "sp";
break;
case 0x19:
return "sph";
break;
case 0x1c:
return "ax";
case 0x1e:
return "dx";
case 0x20:
return "bx";
case 0x22:
return "cx";
default:
return util::string_format("%02x", reg);
@ -37,6 +88,30 @@ std::string mcs96_disassembler::regname(uint8_t reg)
}
}
std::string mcs96_disassembler::regname_indirect(uint8_t reg) const
{
if(BIT(reg, 0))
return util::string_format("[%s]+", regname16(reg & 0xfe, false));
else
return util::string_format("[%s]", regname16(reg, false));
}
std::string mcs96_disassembler::regname_indexed(uint8_t reg, int8_t delta) const
{
if(reg == 0x00) {
if(delta < 0)
return util::string_format("%04x", uint8_t(delta) | 0xff00);
else
return util::string_format("%02x", delta);
} else {
if(delta < 0)
return util::string_format("-%02x[%s]", -delta, regname16(reg, false));
else
return util::string_format("%02x[%s]", delta, regname16(reg, false));
}
}
offs_t mcs96_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params)
{
bool prefix_fe = false;
@ -60,14 +135,10 @@ offs_t mcs96_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
flags |= 2;
break;
case DASM_rel8: {
int delta = opcodes.r8(pc+1);
if(delta & 0x80)
delta -= 0x100;
util::stream_format(stream, " %04x", (pc+2+delta) & 0xffff);
case DASM_rel8:
util::stream_format(stream, " %04x", (pc+2+int8_t(opcodes.r8(pc+1))) & 0xffff);
flags |= 2;
break;
}
case DASM_rel11: {
int delta = ((opcodes.r8(pc) << 8) | opcodes.r8(pc+1)) & 0x7ff;
@ -78,43 +149,63 @@ offs_t mcs96_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
break;
}
case DASM_rel16: {
int delta = opcodes.r8(pc+1) | (opcodes.r8(pc+2) << 8);
util::stream_format(stream, " %04x", (pc+3+delta) & 0xffff);
case DASM_rel16:
util::stream_format(stream, " %04x", (pc+3+opcodes.r16(pc+1)) & 0xffff);
flags |= 3;
break;
}
case DASM_rrel8: {
int delta = opcodes.r8(pc+2);
if(delta & 0x80)
delta -= 0x100;
util::stream_format(stream, " %s, %04x", regname(opcodes.r8(pc+1)), (pc+3+delta) & 0xffff);
case DASM_rrel8:
util::stream_format(stream, " %s, %04x", regname8(opcodes.r8(pc+1), true), (pc+3+int8_t(opcodes.r8(pc+2))) & 0xffff);
flags |= 3;
break;
}
case DASM_brrel8: {
int delta = opcodes.r8(pc+2);
if(delta & 0x80)
delta -= 0x100;
util::stream_format(stream, " %d, %s, %04x", opcodes.r8(pc) & 7, regname(opcodes.r8(pc+1)), (pc+3+delta) & 0xffff);
case DASM_brrel8:
util::stream_format(stream, " %s, %d, %04x", regname8(opcodes.r8(pc+1), false), opcodes.r8(pc) & 7, (pc+3+int8_t(opcodes.r8(pc+2))) & 0xffff);
flags |= 3;
break;
}
case DASM_direct_1:
util::stream_format(stream, " %s", regname(opcodes.r8(pc+1)));
case DASM_wrrel8:
util::stream_format(stream, " %s, %04x", regname16(opcodes.r8(pc+1), true), (pc+3+int8_t(opcodes.r8(pc+2))) & 0xffff);
flags |= 3;
break;
case DASM_direct_1b:
util::stream_format(stream, " %s", regname8(opcodes.r8(pc+1), true));
flags |= 2;
break;
case DASM_direct_2:
util::stream_format(stream, " %s, %s", regname(opcodes.r8(pc+2)), regname(opcodes.r8(pc+1)));
case DASM_direct_1w:
util::stream_format(stream, " %s", regname16(opcodes.r8(pc+1), opcodes.r8(pc) == 0x01 || opcodes.r8(pc) == 0xcc));
flags |= 2;
break;
case DASM_direct_2b:
util::stream_format(stream, " %s, %s", regname8(opcodes.r8(pc+2), opcodes.r8(pc) == 0xb0), regname8(opcodes.r8(pc+1), opcodes.r8(pc) == 0xc4));
flags |= 3;
break;
case DASM_direct_3:
util::stream_format(stream, " %s, %s, %s", regname(opcodes.r8(pc+3)), regname(opcodes.r8(pc+2)), regname(opcodes.r8(pc+1)));
case DASM_direct_2e:
util::stream_format(stream, " %s, %s", regname16(opcodes.r8(pc+2), (opcodes.r8(pc) & 0xef) == 0xac), regname8(opcodes.r8(pc+1), opcodes.r8(pc) == 0x0f));
flags |= 3;
break;
case DASM_direct_2w:
util::stream_format(stream, " %s, %s", regname16(opcodes.r8(pc+2), opcodes.r8(pc) == 0xa0), regname16(opcodes.r8(pc+1), opcodes.r8(pc) == 0xc0));
flags |= 3;
break;
case DASM_direct_3b:
util::stream_format(stream, " %s, %s, %s", regname8(opcodes.r8(pc+3), true), regname8(opcodes.r8(pc+2), false), regname8(opcodes.r8(pc+1), false));
flags |= 4;
break;
case DASM_direct_3e:
util::stream_format(stream, " %s, %s, %s", regname16(opcodes.r8(pc+3), true), regname8(opcodes.r8(pc+2), false), regname8(opcodes.r8(pc+1), false));
flags |= 4;
break;
case DASM_direct_3w:
util::stream_format(stream, " %s, %s, %s", regname16(opcodes.r8(pc+3), true), regname16(opcodes.r8(pc+2), false), regname16(opcodes.r8(pc+1), false));
flags |= 4;
break;
@ -124,147 +215,169 @@ offs_t mcs96_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
break;
case DASM_immed_2b:
util::stream_format(stream, " %s, #%02x", regname(opcodes.r8(pc+2)), opcodes.r8(pc+1));
util::stream_format(stream, " %s, #%02x", regname8(opcodes.r8(pc+2), opcodes.r8(pc) == 0xb1), opcodes.r8(pc+1));
flags |= 3;
break;
case DASM_immed_2e:
util::stream_format(stream, " %s, #%02x", regname16(opcodes.r8(pc+2), (opcodes.r8(pc) & 0xef) == 0xad), opcodes.r8(pc+1));
flags |= 3;
break;
case DASM_immed_or_reg_2b:
if(opcodes.r8(pc+1) >= 0x10)
util::stream_format(stream, " %s, %s", regname(opcodes.r8(pc+2)), regname(opcodes.r8(pc+1)));
util::stream_format(stream, " %s, %s", regname8(opcodes.r8(pc+2), false), regname8(opcodes.r8(pc+1), false));
else
util::stream_format(stream, " %s, #%02x", regname(opcodes.r8(pc+2)), opcodes.r8(pc+1));
util::stream_format(stream, " %s, #%02x", regname8(opcodes.r8(pc+2), false), opcodes.r8(pc+1));
flags |= 3;
break;
case DASM_immed_3b:
util::stream_format(stream, " %s, %s, #%02x", regname(opcodes.r8(pc+3)), regname(opcodes.r8(pc+2)), opcodes.r8(pc+1));
util::stream_format(stream, " %s, %s, #%02x", regname8(opcodes.r8(pc+3), true), regname8(opcodes.r8(pc+2), false), opcodes.r8(pc+1));
flags |= 4;
break;
case DASM_immed_3e:
util::stream_format(stream, " %s, %s, #%02x", regname16(opcodes.r8(pc+3), true), regname8(opcodes.r8(pc+2), false), opcodes.r8(pc+1));
flags |= 4;
break;
case DASM_immed_1w:
util::stream_format(stream, " #%02x%02x", opcodes.r8(pc+2), opcodes.r8(pc+1));
util::stream_format(stream, " #%04x", opcodes.r16(pc+1));
flags |= 3;
break;
case DASM_immed_2w:
util::stream_format(stream, " %s, #%02x%02x", regname(opcodes.r8(pc+3)), opcodes.r8(pc+2), opcodes.r8(pc+1));
util::stream_format(stream, " %s, #%04x", regname16(opcodes.r8(pc+3), opcodes.r8(pc) == 0xa1), opcodes.r16(pc+1));
flags |= 4;
break;
case DASM_immed_or_reg_2w:
if(opcodes.r8(pc+1) >= 0x10)
util::stream_format(stream, " %s, %s", regname16(opcodes.r8(pc+2), false), regname8(opcodes.r8(pc+1), false));
else
util::stream_format(stream, " %s, #%02x", regname16(opcodes.r8(pc+2), false), opcodes.r8(pc+1));
flags |= 3;
break;
case DASM_immed_3w:
util::stream_format(stream, " %s, %s, #%02x%02x", regname(opcodes.r8(pc+4)), regname(opcodes.r8(pc+3)), opcodes.r8(pc+2), opcodes.r8(pc+1));
util::stream_format(stream, " %s, %s, #%04x", regname16(opcodes.r8(pc+4), true), regname16(opcodes.r8(pc+3), false), opcodes.r16(pc+1));
flags |= 5;
break;
case DASM_indirect_1n:
util::stream_format(stream, " [%s]", regname(opcodes.r8(pc+1)));
util::stream_format(stream, " [%s]", regname16(opcodes.r8(pc+1), false));
flags |= 2;
break;
case DASM_indirect_1:
if(opcodes.r8(pc+1) & 0x01) {
util::stream_format(stream, " [%s]+", regname(opcodes.r8(pc+1)-1));
flags |= 2;
} else {
util::stream_format(stream, " [%s]", regname(opcodes.r8(pc+1)));
flags |= 2;
}
case DASM_indirect_1w:
util::stream_format(stream, " %s", regname_indirect(opcodes.r8(pc+1)));
flags |= 2;
break;
case DASM_indirect_2:
if(opcodes.r8(pc+1) & 0x01) {
util::stream_format(stream, " %s, [%s]+", regname(opcodes.r8(pc+2)), regname(opcodes.r8(pc+1)-1));
flags |= 3;
} else {
util::stream_format(stream, " %s, [%s]", regname(opcodes.r8(pc+2)), regname(opcodes.r8(pc+1)));
flags |= 3;
}
case DASM_indirect_2b:
util::stream_format(stream, " %s, %s", regname8(opcodes.r8(pc+2), opcodes.r8(pc) == 0xb2), regname_indirect(opcodes.r8(pc+1)));
flags |= 3;
break;
case DASM_indirect_3:
if(opcodes.r8(pc+1) & 0x01) {
util::stream_format(stream, " %s, %s, [%s]+", regname(opcodes.r8(pc+3)), regname(opcodes.r8(pc+2)), regname(opcodes.r8(pc+1)-1));
flags |= 4;
} else {
util::stream_format(stream, " %s, %s, [%s]", regname(opcodes.r8(pc+3)), regname(opcodes.r8(pc+2)), regname(opcodes.r8(pc+1)));
flags |= 4;
}
case DASM_indirect_2w:
util::stream_format(stream, " %s, %s", regname16(opcodes.r8(pc+2), opcodes.r8(pc) == 0xa2), regname_indirect(opcodes.r8(pc+1)));
flags |= 3;
break;
case DASM_indexed_1:
case DASM_indirect_3b:
util::stream_format(stream, " %s, %s, %s", regname8(opcodes.r8(pc+3), true), regname8(opcodes.r8(pc+2), false), regname_indirect(opcodes.r8(pc+1)));
flags |= 4;
break;
case DASM_indirect_3e:
util::stream_format(stream, " %s, %s, %s", regname16(opcodes.r8(pc+3), true), regname8(opcodes.r8(pc+2), false), regname_indirect(opcodes.r8(pc+1)));
flags |= 4;
break;
case DASM_indirect_3w:
util::stream_format(stream, " %s, %s, %s", regname16(opcodes.r8(pc+3), true), regname16(opcodes.r8(pc+2), false), regname_indirect(opcodes.r8(pc+1)));
flags |= 4;
break;
case DASM_indexed_1w:
if(opcodes.r8(pc+1) & 0x01) {
if(opcodes.r8(pc+1) == 0x01)
util::stream_format(stream, " %02x%02x", opcodes.r8(pc+3), opcodes.r8(pc+2));
util::stream_format(stream, " %04x", opcodes.r16(pc+2));
else
util::stream_format(stream, " %02x%02x[%s]", opcodes.r8(pc+3), opcodes.r8(pc+2), regname(opcodes.r8(pc+1)-1));
util::stream_format(stream, " %04x[%s]", opcodes.r16(pc+2), regname16(opcodes.r8(pc+1)-1, false));
flags |= 4;
} else {
int delta = opcodes.r8(pc+2);
if(delta & 0x80)
delta -= 0x100;
if(opcodes.r8(pc+1) == 0x00) {
if(delta < 0)
util::stream_format(stream, " %04x", delta & 0xffff);
else
util::stream_format(stream, " %02x", delta);
} else {
if(delta < 0)
util::stream_format(stream, " -%02x[%s]", -delta, regname(opcodes.r8(pc+1)));
else
util::stream_format(stream, " %02x[%s]", delta, regname(opcodes.r8(pc+1)));
}
util::stream_format(stream, "%s", regname_indexed(opcodes.r8(pc+1), opcodes.r8(pc+2)));
flags |= 3;
}
break;
case DASM_indexed_2:
case DASM_indexed_2b: {
bool is_dest = opcodes.r8(pc) == 0xb3;
if(opcodes.r8(pc+1) & 0x01) {
if(opcodes.r8(pc+1) == 0x01)
util::stream_format(stream, " %s, %02x%02x", regname(opcodes.r8(pc+4)), opcodes.r8(pc+3), opcodes.r8(pc+2));
util::stream_format(stream, " %s, %04x", regname8(opcodes.r8(pc+4), is_dest), opcodes.r16(pc+2));
else
util::stream_format(stream, " %s, %02x%02x[%s]", regname(opcodes.r8(pc+4)), opcodes.r8(pc+3), opcodes.r8(pc+2), regname(opcodes.r8(pc+1)-1));
util::stream_format(stream, " %s, %04x[%s]", regname8(opcodes.r8(pc+4), is_dest), opcodes.r16(pc+2), regname16(opcodes.r8(pc+1)-1, false));
flags |= 5;
} else {
int delta = opcodes.r8(pc+2);
if(delta & 0x80)
delta -= 0x100;
if(opcodes.r8(pc+1) == 0x00) {
if(delta < 0)
util::stream_format(stream, " %s, %04x", regname(opcodes.r8(pc+3)), delta & 0xffff);
else
util::stream_format(stream, " %s, %02x", regname(opcodes.r8(pc+3)), delta);
} else {
if(delta < 0)
util::stream_format(stream, " %s, -%02x[%s]", regname(opcodes.r8(pc+3)), -delta, regname(opcodes.r8(pc+1)));
else
util::stream_format(stream, " %s, %02x[%s]", regname(opcodes.r8(pc+3)), delta, regname(opcodes.r8(pc+1)));
}
util::stream_format(stream, " %s, %s", regname8(opcodes.r8(pc+3), is_dest), regname_indexed(opcodes.r8(pc+1), opcodes.r8(pc+2)));
flags |= 4;
}
break;
}
case DASM_indexed_3:
case DASM_indexed_2w: {
bool is_dest = opcodes.r8(pc) == 0xa3 || (opcodes.r8(pc) & 0xef) == 0xaf;
if(opcodes.r8(pc+1) & 0x01) {
if(opcodes.r8(pc+1) == 0x01)
util::stream_format(stream, " %s, %s, %02x%02x", regname(opcodes.r8(pc+5)), regname(opcodes.r8(pc+4)), opcodes.r8(pc+3), opcodes.r8(pc+2));
util::stream_format(stream, " %s, %04x", regname16(opcodes.r8(pc+4), is_dest), opcodes.r16(pc+2));
else
util::stream_format(stream, " %s, %s, %02x%02x[%s]", regname(opcodes.r8(pc+5)), regname(opcodes.r8(pc+4)), opcodes.r8(pc+3), opcodes.r8(pc+2), regname(opcodes.r8(pc+1)-1));
util::stream_format(stream, " %s, %04x[%s]", regname16(opcodes.r8(pc+4), is_dest), opcodes.r16(pc+2), regname16(opcodes.r8(pc+1)-1, false));
flags |= 5;
} else {
util::stream_format(stream, " %s, %s", regname16(opcodes.r8(pc+3), is_dest), regname_indexed(opcodes.r8(pc+1), opcodes.r8(pc+2)));
flags |= 4;
}
break;
}
case DASM_indexed_3b:
if(opcodes.r8(pc+1) & 0x01) {
if(opcodes.r8(pc+1) == 0x01)
util::stream_format(stream, " %s, %s, %04x", regname8(opcodes.r8(pc+5), true), regname8(opcodes.r8(pc+4), false), opcodes.r16(pc+2));
else
util::stream_format(stream, " %s, %s, %04x[%s]", regname8(opcodes.r8(pc+5), true), regname8(opcodes.r8(pc+4), false), opcodes.r16(pc+2), regname16(opcodes.r8(pc+1)-1, false));
flags |= 6;
} else {
int delta = opcodes.r8(pc+2);
if(delta & 0x80)
delta -= 0x100;
if(opcodes.r8(pc+1) == 0x00) {
if(delta < 0)
util::stream_format(stream, " %s, %s, %04x", regname(opcodes.r8(pc+4)), regname(opcodes.r8(pc+3)), delta & 0xffff);
else
util::stream_format(stream, " %s, %s, %02x", regname(opcodes.r8(pc+4)), regname(opcodes.r8(pc+3)), delta);
} else {
if(delta < 0)
util::stream_format(stream, " %s, %s, -%02x[%s]", regname(opcodes.r8(pc+4)), regname(opcodes.r8(pc+3)), -delta, regname(opcodes.r8(pc+1)));
else
util::stream_format(stream, " %s, %s, %02x[%s]", regname(opcodes.r8(pc+4)), regname(opcodes.r8(pc+3)), delta, regname(opcodes.r8(pc+1)));
}
util::stream_format(stream, " %s, %s, %s", regname8(opcodes.r8(pc+4), true), regname8(opcodes.r8(pc+3), false), regname_indexed(opcodes.r8(pc+1), opcodes.r8(pc+2)));
flags |= 5;
}
break;
case DASM_indexed_3e:
if(opcodes.r8(pc+1) & 0x01) {
if(opcodes.r8(pc+1) == 0x01)
util::stream_format(stream, " %s, %s, %04x", regname16(opcodes.r8(pc+5), true), regname8(opcodes.r8(pc+4), false), opcodes.r16(pc+2));
else
util::stream_format(stream, " %s, %s, %04x[%s]", regname16(opcodes.r8(pc+5), true), regname8(opcodes.r8(pc+4), false), opcodes.r16(pc+2), regname16(opcodes.r8(pc+1)-1, false));
flags |= 6;
} else {
util::stream_format(stream, " %s, %s, %s", regname16(opcodes.r8(pc+4), true), regname8(opcodes.r8(pc+3), false), regname_indexed(opcodes.r8(pc+1), opcodes.r8(pc+2)));
flags |= 5;
}
break;
case DASM_indexed_3w:
if(opcodes.r8(pc+1) & 0x01) {
if(opcodes.r8(pc+1) == 0x01)
util::stream_format(stream, " %s, %s, %04x", regname16(opcodes.r8(pc+5), true), regname16(opcodes.r8(pc+4), false), opcodes.r16(pc+2));
else
util::stream_format(stream, " %s, %s, %04x[%s]", regname16(opcodes.r8(pc+5), true), regname16(opcodes.r8(pc+4), false), opcodes.r16(pc+2), regname16(opcodes.r8(pc+1)-1, false));
flags |= 6;
} else {
util::stream_format(stream, " %s, %s, %s", regname16(opcodes.r8(pc+4), true), regname16(opcodes.r8(pc+3), false), regname_indexed(opcodes.r8(pc+1), opcodes.r8(pc+2)));
flags |= 5;
}
break;

View File

@ -35,30 +35,48 @@ protected:
DASM_rel8, /* Relative, 8 bits */
DASM_rel11, /* Relative, 11 bits */
DASM_rel16, /* Relative, 16 bits */
DASM_rrel8, /* Register + relative, 8 bits */
DASM_rrel8, /* Register (8-bit) + relative, 8 bits */
DASM_brrel8, /* Bit test + register + relative, 8 bits */
DASM_direct_1, /* Register-direct references, 1 operator */
DASM_direct_2, /* Register-direct references, 2 operators */
DASM_direct_3, /* Register-direct references, 3 operators */
DASM_immed_1b, /* Immediate references to byte, 1 operator */
DASM_immed_2b, /* Immediate references to byte, 2 operators */
DASM_immed_or_reg_2b, /* Immediate references to byte or register, 2 operators */
DASM_immed_3b, /* Immediate references to byte, 3 operators */
DASM_immed_1w, /* Immediate references to word, 1 operator */
DASM_immed_2w, /* Immediate references to word, 2 operators */
DASM_immed_3w, /* Immediate references to word, 3 operators */
DASM_wrrel8, /* Register (16-bit) + relative, 8 bits */
DASM_direct_1b, /* Register-direct references, 1 operator, 8 bits */
DASM_direct_2b, /* Register-direct references, 2 operators, 8 bits */
DASM_direct_2e, /* Register-direct references, 2 operators, 8 bits extended to 16 */
DASM_direct_3b, /* Register-direct references, 3 operators, 8 bits */
DASM_direct_3e, /* Register-direct references, 3 operators, 8 bits extended to 16 */
DASM_direct_1w, /* Register-direct references, 1 operator, 16 bits */
DASM_direct_2w, /* Register-direct references, 2 operators, 16 bits */
DASM_direct_3w, /* Register-direct references, 3 operators, 16 bits */
DASM_immed_1b, /* Immediate references to byte, 1 operator, 8 bits */
DASM_immed_2b, /* Immediate references to byte, 2 operators, 8 bits */
DASM_immed_2e, /* Immediate references to byte, 2 operators, 8 bits extended to 16 */
DASM_immed_or_reg_2b, /* Immediate references to byte or register, 2 operators, 8 bits */
DASM_immed_3b, /* Immediate references to byte, 3 operators, 8 bits */
DASM_immed_3e, /* Immediate references to byte, 3 operators, 8 bits extended to 16 */
DASM_immed_1w, /* Immediate references to word, 1 operator, 16 bits */
DASM_immed_2w, /* Immediate references to word, 2 operators, 16 bits */
DASM_immed_or_reg_2w, /* Immediate references to byte or register, 2 operators, 16 bits */
DASM_immed_3w, /* Immediate references to word, 3 operators, 16 bits */
DASM_indirect_1n, /* Indirect normal, 1 operator */
DASM_indirect_1, /* Indirect, normal or auto-incrementing, 1 operator */
DASM_indirect_2, /* Indirect, normal or auto-incrementing, 2 operators */
DASM_indirect_3, /* Indirect, normal or auto-incrementing, 3 operators */
DASM_indexed_1, /* Indexed, short or long, 1 operator */
DASM_indexed_2, /* Indexed, short or long, 2 operators */
DASM_indexed_3 /* Indexed, short or long, 3 operators */
DASM_indirect_1w, /* Indirect, normal or auto-incrementing, 1 operator, 16 bits */
DASM_indirect_2b, /* Indirect, normal or auto-incrementing, 2 operators, 8 bits */
DASM_indirect_2w, /* Indirect, normal or auto-incrementing, 2 operators, 16 bits */
DASM_indirect_3b, /* Indirect, normal or auto-incrementing, 3 operators, 8 bits */
DASM_indirect_3e, /* Indirect, normal or auto-incrementing, 3 operators, 8 bits extended to 16 */
DASM_indirect_3w, /* Indirect, normal or auto-incrementing, 3 operators, 16 bits */
DASM_indexed_1w, /* Indexed, short or long, 1 operator, 16 bits */
DASM_indexed_2b, /* Indexed, short or long, 2 operators, 8 bits */
DASM_indexed_2w, /* Indexed, short or long, 2 operators, 16 bits */
DASM_indexed_3b, /* Indexed, short or long, 3 operators, 8 bits */
DASM_indexed_3e, /* Indexed, short or long, 3 operators, 8 bits extended to 16 */
DASM_indexed_3w /* Indexed, short or long, 3 operators, 16 bits */
};
const disasm_entry *m_entries;
static std::string regname(uint8_t reg);
virtual std::string regname8(uint8_t reg, bool is_dest) const;
virtual std::string regname16(uint8_t reg, bool is_dest) const;
std::string regname_indirect(uint8_t reg) const;
std::string regname_indexed(uint8_t reg, int8_t delta) const;
};
#endif

File diff suppressed because it is too large Load Diff