m68kdasm: decode ptest & pflush (#4190)

* m68kdasm: decode ptest & pflush

this adds some more decoding to someof the MMU instructions. The
following encodings are now properly decoded:

$ ./unidasm test.bin -arch m68040
00: f010 8216  ptestr #6, (A0), 0
04: f010 8209  ptestr D1, (A0), 0
08: f010 8200  ptestr %sfc, (A0), 0
0c: f010 8201  ptestr %dfc, (A0), 0
10: f010 8310  ptestr #0, (A0), 0, @A1
14: f010 8000  ptestw %sfc, (A0), 0
18: f548       ptestw (A0)
1a: f568       ptestr (A0)
1c: f500       pflushn (A0)
1e: f501       pflushn (A1)
20: f509       pflush (A1)
22: f510       pflushan
24: f518       pflusha

* m68kdasm: fix whitespace for MMU instructions
This commit is contained in:
dxl 2018-10-24 21:49:37 +02:00 committed by R. Belmont
parent ada980907d
commit c7103b12f1
2 changed files with 76 additions and 30 deletions

View File

@ -2422,23 +2422,6 @@ std::string m68k_disassembler::d68000_pea()
return util::string_format("pea %s", get_ea_mode_str_32(m_cpu_ir)); return util::string_format("pea %s", get_ea_mode_str_32(m_cpu_ir));
} }
// this is a 68040-specific form of PFLUSH
std::string m68k_disassembler::d68040_pflush()
{
auto limit = limit_cpu_types(M68040_PLUS);
if(limit.first)
return limit.second;
if (m_cpu_ir & 0x10)
{
return util::string_format("pflusha%s", (m_cpu_ir & 8) ? "" : "n");
}
else
{
return util::string_format("pflush%s(A%d)", (m_cpu_ir & 8) ? "" : "n", m_cpu_ir & 7);
}
}
std::string m68k_disassembler::d68000_reset() std::string m68k_disassembler::d68000_reset()
{ {
return util::string_format("reset"); return util::string_format("reset");
@ -2916,7 +2899,53 @@ std::string m68k_disassembler::d68020_unpk_mm()
return util::string_format("unpk -(A%d), -(A%d), %s; (2+)", m_cpu_ir&7, (m_cpu_ir>>9)&7, get_imm_str_u16()); return util::string_format("unpk -(A%d), -(A%d), %s; (2+)", m_cpu_ir&7, (m_cpu_ir>>9)&7, get_imm_str_u16());
} }
std::string m68k_disassembler::fc_to_string(uint16_t modes)
{
uint16_t fc = modes & 0x1f;
if (fc == 0)
{
return "%sfc";
}
else if (fc == 1)
{
return "%dfc";
}
else if ((fc >> 3) == 1)
{
return util::string_format("D%d", fc & 7);
}
else if ((fc >> 3) == 2)
{
return util::string_format("#%d", fc & 7);
}
return util::string_format("unknown fc %x", fc);
}
std::string m68k_disassembler::d68040_p000()
{
if ((m_cpu_ir & 0xffd8) == 0xf548) // 68040 PTEST
{
return util::string_format("ptest%c (A%d)", (m_cpu_ir & 0x20) ? 'r' : 'w', m_cpu_ir & 7);
}
if ((m_cpu_ir & 0xffe0) == 0xf500) // 68040 PFLUSH
{
switch((m_cpu_ir >> 3) & 3)
{
case 0:
return util::string_format("pflushn (A%d)", m_cpu_ir & 7);
case 1:
return util::string_format("pflush (A%d)", m_cpu_ir & 7);
case 2:
return "pflushan";
case 3:
return "pflusha";
}
}
return util::string_format("unknown instruction: %04x", m_cpu_ir);
}
// PFLUSH: 001xxx0xxxxxxxxx // PFLUSH: 001xxx0xxxxxxxxx
// PLOAD: 001000x0000xxxxx // PLOAD: 001000x0000xxxxx
// PVALID1: 0010100000000000 // PVALID1: 0010100000000000
@ -2937,11 +2966,11 @@ std::string m68k_disassembler::d68851_p000()
{ {
if (modes & 0x0200) if (modes & 0x0200)
{ {
return util::string_format("pload #%d, %s", (modes>>10)&7, str); return util::string_format("pload #%d, %s", (modes>>10)&7, str);
} }
else else
{ {
return util::string_format("pload %s, #%d", str, (modes>>10)&7); return util::string_format("pload %s, #%d", str, (modes>>10)&7);
} }
} }
@ -2957,17 +2986,32 @@ std::string m68k_disassembler::d68851_p000()
if (modes == 0x2800) // PVALID (FORMAT 1) if (modes == 0x2800) // PVALID (FORMAT 1)
{ {
return util::string_format("pvalid VAL, %s", str); return util::string_format("pvalid VAL, %s", str);
} }
if ((modes & 0xfff8) == 0x2c00) // PVALID (FORMAT 2) if ((modes & 0xfff8) == 0x2c00) // PVALID (FORMAT 2)
{ {
return util::string_format("pvalid A%d, %s", modes & 0xf, str); return util::string_format("pvalid A%d, %s", modes & 0xf, str);
} }
if ((modes & 0xe000) == 0x8000) // PTEST if ((modes & 0xe000) == 0x8000) // PTEST
{ {
return util::string_format("ptest #%d, %s", modes & 0x1f, str); if (modes & 0x100) {
return util::string_format("ptest%c %s, %s, %d, @A%d",
(modes & 0x200) ? 'r' : 'w',
fc_to_string(modes),
str,
(modes >> 10) & 7,
(modes >> 4) & 7);
}
else
{
return util::string_format("ptest%c %s, %s, %d",
(modes & 0x200) ? 'r' : 'w',
fc_to_string(modes),
str,
(modes >> 10) & 7);
}
} }
switch ((modes>>13) & 0x7) switch ((modes>>13) & 0x7)
@ -2978,22 +3022,22 @@ std::string m68k_disassembler::d68851_p000()
{ {
if (modes & 0x0200) if (modes & 0x0200)
{ {
return util::string_format("pmovefd %s, %s", m_mmuregs[(modes>>10)&7], str); return util::string_format("pmovefd %s, %s", m_mmuregs[(modes>>10)&7], str);
} }
else else
{ {
return util::string_format("pmovefd %s, %s", str, m_mmuregs[(modes>>10)&7]); return util::string_format("pmovefd %s, %s", str, m_mmuregs[(modes>>10)&7]);
} }
} }
else else
{ {
if (modes & 0x0200) if (modes & 0x0200)
{ {
return util::string_format("pmove %s, %s", m_mmuregs[(modes>>10)&7], str); return util::string_format("pmove %s, %s", m_mmuregs[(modes>>10)&7], str);
} }
else else
{ {
return util::string_format("pmove %s, %s", str, m_mmuregs[(modes>>10)&7]); return util::string_format("pmove %s, %s", str, m_mmuregs[(modes>>10)&7]);
} }
} }
break; break;
@ -3001,11 +3045,11 @@ std::string m68k_disassembler::d68851_p000()
case 3: // MC68030 to/from status reg case 3: // MC68030 to/from status reg
if (modes & 0x0200) if (modes & 0x0200)
{ {
return util::string_format("pmove mmusr, %s", str); return util::string_format("pmove mmusr, %s", str);
} }
else else
{ {
return util::string_format("pmove %s, mmusr", str); return util::string_format("pmove %s, mmusr", str);
} }
break; break;
@ -3302,7 +3346,7 @@ const m68k_disassembler::opcode_struct m68k_disassembler::m_opcode_info[] =
{&m68k_disassembler::d68020_pack_rr , 0xf1f8, 0x8140, 0x000}, {&m68k_disassembler::d68020_pack_rr , 0xf1f8, 0x8140, 0x000},
{&m68k_disassembler::d68020_pack_mm , 0xf1f8, 0x8148, 0x000}, {&m68k_disassembler::d68020_pack_mm , 0xf1f8, 0x8148, 0x000},
{&m68k_disassembler::d68000_pea , 0xffc0, 0x4840, 0x27b}, {&m68k_disassembler::d68000_pea , 0xffc0, 0x4840, 0x27b},
{&m68k_disassembler::d68040_pflush , 0xffe0, 0xf500, 0x000}, {&m68k_disassembler::d68040_p000 , 0xff80, 0xf500, 0x000},
{&m68k_disassembler::d68000_reset , 0xffff, 0x4e70, 0x000}, {&m68k_disassembler::d68000_reset , 0xffff, 0x4e70, 0x000},
{&m68k_disassembler::d68000_ror_s_8 , 0xf1f8, 0xe018, 0x000}, {&m68k_disassembler::d68000_ror_s_8 , 0xf1f8, 0xe018, 0x000},
{&m68k_disassembler::d68000_ror_s_16 , 0xf1f8, 0xe058, 0x000}, {&m68k_disassembler::d68000_ror_s_16 , 0xf1f8, 0xe058, 0x000},

View File

@ -117,6 +117,8 @@ protected:
inline std::string get_ea_mode_str_16(u16 instruction) { return get_ea_mode_str(instruction, 1); } inline std::string get_ea_mode_str_16(u16 instruction) { return get_ea_mode_str(instruction, 1); }
inline std::string get_ea_mode_str_32(u16 instruction) { return get_ea_mode_str(instruction, 2); } inline std::string get_ea_mode_str_32(u16 instruction) { return get_ea_mode_str(instruction, 2); }
std::string fc_to_string(uint16_t modes);
inline std::pair<bool, std::string> limit_cpu_types(u32 allowed); inline std::pair<bool, std::string> limit_cpu_types(u32 allowed);
std::string d68000_illegal(); std::string d68000_illegal();
@ -337,7 +339,6 @@ protected:
std::string d68020_pack_rr(); std::string d68020_pack_rr();
std::string d68020_pack_mm(); std::string d68020_pack_mm();
std::string d68000_pea(); std::string d68000_pea();
std::string d68040_pflush();
std::string d68000_reset(); std::string d68000_reset();
std::string d68000_ror_s_8(); std::string d68000_ror_s_8();
std::string d68000_ror_s_16(); std::string d68000_ror_s_16();
@ -420,6 +421,7 @@ protected:
std::string d68000_unlk(); std::string d68000_unlk();
std::string d68020_unpk_rr(); std::string d68020_unpk_rr();
std::string d68020_unpk_mm(); std::string d68020_unpk_mm();
std::string d68040_p000();
std::string d68851_p000(); std::string d68851_p000();
std::string d68851_pbcc16(); std::string d68851_pbcc16();
std::string d68851_pbcc32(); std::string d68851_pbcc32();