summaryrefslogtreecommitdiffstatshomepage
path: root/src/tools
diff options
context:
space:
mode:
author Olivier Galibert <galibert@pobox.com>2017-07-05 11:44:49 +0200
committer Olivier Galibert <galibert@pobox.com>2017-11-26 17:41:27 +0100
commit6caef2579a1490f05d28bcede731cbdd45fc5c65 (patch)
tree8055384e183be3cb27e7d0894ac53dc96c09e6fa /src/tools
parent34b222062c89adbeed822f56be6130421777e11f (diff)
dvdisasm: Overhaul [O. Galibert]
Disassemblers are now independant classes. Not only the code is cleaner, but unidasm has access to all the cpu cores again. The interface to the disassembly method has changed from byte buffers to objects that give a result to read methods. This also adds support for lfsr and/or paged PCs.
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/unidasm.cpp1668
1 files changed, 1100 insertions, 568 deletions
diff --git a/src/tools/unidasm.cpp b/src/tools/unidasm.cpp
index eafca32f14f..1f093df9416 100644
--- a/src/tools/unidasm.cpp
+++ b/src/tools/unidasm.cpp
@@ -9,41 +9,246 @@
****************************************************************************/
#include "emu.h"
-#include "cpu/sparc/sparcdasm.h"
#include <algorithm>
#include <cstring>
#include <ctype.h>
+#include "cpu/8x300/8x300dasm.h"
+#include "cpu/adsp2100/2100dasm.h"
+#include "cpu/alph8201/8201dasm.h"
+#include "cpu/alto2/alto2dsm.h"
+#include "cpu/am29000/am29dasm.h"
+#include "cpu/amis2000/amis2000d.h"
+#include "cpu/apexc/apexcdsm.h"
+#include "cpu/arc/arcdasm.h"
+#include "cpu/arcompact/arcompactdasm.h"
+#include "cpu/arm/armdasm.h"
+#include "cpu/arm7/arm7dasm.h"
+#include "cpu/asap/asapdasm.h"
+#include "cpu/avr8/avr8dasm.h"
+#include "cpu/capricorn/capricorn_dasm.h"
+#include "cpu/ccpu/ccpudasm.h"
+#include "cpu/clipper/clipperd.h"
+#include "cpu/cop400/cop410ds.h"
+#include "cpu/cop400/cop420ds.h"
+#include "cpu/cop400/cop424ds.h"
+#include "cpu/cop400/cop444ds.h"
+#include "cpu/cosmac/cosdasm.h"
+#include "cpu/cp1610/1610dasm.h"
+#include "cpu/cubeqcpu/cubedasm.h"
+#include "cpu/dsp16/dsp16dis.h"
+#include "cpu/dsp32/dsp32dis.h"
+#include "cpu/dsp56k/dsp56dsm.h"
+#include "cpu/e0c6200/e0c6200d.h"
+#include "cpu/e132xs/32xsdasm.h"
+#include "cpu/es5510/es5510d.h"
+#include "cpu/esrip/esripdsm.h"
+#include "cpu/f8/f8dasm.h"
+#include "cpu/g65816/g65816ds.h"
+#include "cpu/h6280/6280dasm.h"
+#include "cpu/h8/h8d.h"
+#include "cpu/h8/h8hd.h"
+#include "cpu/h8/h8s2000d.h"
+#include "cpu/h8/h8s2600d.h"
+#include "cpu/hcd62121/hcd62121d.h"
+#include "cpu/hd61700/hd61700d.h"
+#include "cpu/hmcs40/hmcs40d.h"
+#include "cpu/hphybrid/hphybrid_dasm.h"
+#include "cpu/i386/i386dasm.h"
+#include "cpu/i8008/8008dasm.h"
+#include "cpu/i8085/8085dasm.h"
+#include "cpu/i8089/i8089_dasm.h"
+#include "cpu/i860/i860dis.h"
+#include "cpu/i960/i960dis.h"
+#include "cpu/ie15/ie15dasm.h"
+#include "cpu/jaguar/jagdasm.h"
+#include "cpu/lc8670/lc8670dsm.h"
+#include "cpu/lh5801/5801dasm.h"
+#include "cpu/lr35902/lr35902d.h"
+#include "cpu/m37710/m7700ds.h"
+#include "cpu/m6502/m4510d.h"
+#include "cpu/m6502/m6502d.h"
+#include "cpu/m6502/m6509d.h"
+#include "cpu/m6502/m6510d.h"
+#include "cpu/m6502/m65c02d.h"
+#include "cpu/m6502/m65ce02d.h"
+#include "cpu/m6502/m740d.h"
+#include "cpu/m6800/6800dasm.h"
+#include "cpu/m68000/m68kdasm.h"
+#include "cpu/m6805/6805dasm.h"
+#include "cpu/m6809/6x09dasm.h"
+#include "cpu/mb86233/mb86233d.h"
+#include "cpu/mb86235/mb86235d.h"
+#include "cpu/mb88xx/mb88dasm.h"
+#include "cpu/mc68hc11/hc11dasm.h"
+#include "cpu/mcs40/mcs40dasm.h"
+#include "cpu/mcs48/mcs48dsm.h"
+#include "cpu/mcs51/mcs51dasm.h"
+#include "cpu/mcs96/i8x9xd.h"
+#include "cpu/mcs96/i8xc196d.h"
+#include "cpu/melps4/melps4d.h"
+#include "cpu/minx/minxd.h"
+#include "cpu/mips/mips3dsm.h"
+#include "cpu/mips/r3kdasm.h"
+#include "cpu/mn10200/mn102dis.h"
+#include "cpu/nanoprocessor/nanoprocessor_dasm.h"
+#include "cpu/nec/necdasm.h"
+#include "cpu/patinhofeio/patinho_feio_dasm.h"
+#include "cpu/pdp1/pdp1dasm.h"
+#include "cpu/pdp1/tx0dasm.h"
+#include "cpu/pdp8/pdp8dasm.h"
+#include "cpu/pic16c5x/16c5xdsm.h"
+#include "cpu/pic16c62x/16c62xdsm.h"
+#include "cpu/powerpc/ppc_dasm.h"
+#include "cpu/pps4/pps4dasm.h"
+#include "cpu/psx/psxdasm.h"
+#include "cpu/rsp/rsp_dasm.h"
+#include "cpu/s2650/2650dasm.h"
+#include "cpu/saturn/saturnds.h"
+#include "cpu/sc61860/scdasm.h"
+#include "cpu/scmp/scmpdasm.h"
+#include "cpu/score/scoredsm.h"
+#include "cpu/scudsp/scudspdasm.h"
+#include "cpu/se3208/se3208dis.h"
+#include "cpu/sh/sh_dasm.h"
+#include "cpu/sharc/sharcdsm.h"
+#include "cpu/sm510/sm510d.h"
+#include "cpu/sm8500/sm8500d.h"
+#include "cpu/sparc/sparcdasm.h"
+#include "cpu/spc700/spc700ds.h"
+#include "cpu/ssem/ssemdasm.h"
+#include "cpu/ssp1601/ssp1601d.h"
+#include "cpu/superfx/sfx_dasm.h"
+#include "cpu/t11/t11dasm.h"
+#include "cpu/tlcs870/tlcs870d.h"
+#include "cpu/tlcs90/tlcs90d.h"
+#include "cpu/tlcs900/dasm900.h"
+#include "cpu/tms1000/tms1k_dasm.h"
+#include "cpu/tms32010/32010dsm.h"
+#include "cpu/tms32025/32025dsm.h"
+#include "cpu/tms32031/dis32031.h"
+#include "cpu/tms32051/dis32051.h"
+#include "cpu/tms32082/dis_mp.h"
+#include "cpu/tms32082/dis_pp.h"
+#include "cpu/tms34010/34010dsm.h"
+#include "cpu/tms57002/57002dsm.h"
+#include "cpu/tms7000/7000dasm.h"
+#include "cpu/tms9900/9900dasm.h"
+#include "cpu/tms9900/tms99com.h"
+#include "cpu/ucom4/ucom4d.h"
+#include "cpu/unsp/unspdasm.h"
+#include "cpu/upd7725/dasm7725.h"
+#include "cpu/upd7810/upd7810_dasm.h"
+#include "cpu/v60/v60d.h"
+#include "cpu/v810/v810dasm.h"
+#include "cpu/z180/z180dasm.h"
+#include "cpu/z8/z8dasm.h"
+#include "cpu/z80/z80dasm.h"
+#include "cpu/z8000/8000dasm.h"
+
+// Configuration classes
-enum display_type
+// Selected through dasm name
+struct arm7_unidasm_t : public arm7_disassembler::config
{
- _8bit,
- _8bitx,
- _16be,
- _16le,
- _24be,
- _24le,
- _32be,
- _32le,
- _40be,
- _40le,
- _48be,
- _48le,
- _56be,
- _56le,
- _64be,
- _64le
-};
+ bool t_flag;
+ arm7_unidasm_t() { t_flag = false; }
+ virtual ~arm7_unidasm_t() override = default;
+ virtual bool get_t_flag() const override { return t_flag; }
+} arm7_unidasm;
+
+// Configuration missing
+struct g65816_unidasm_t : g65816_disassembler::config
+{
+ bool m_flag;
+ bool x_flag;
+
+ g65816_unidasm_t() { m_flag = false; x_flag = false; }
+ virtual ~g65816_unidasm_t() override = default;
+ virtual bool get_m_flag() const override { return m_flag; }
+ virtual bool get_x_flag() const override { return x_flag; }
+} g65816_unidasm;
+
+// Configuration missing
+struct m740_unidasm_t : m740_disassembler::config
+{
+ u32 inst_state_base;
+ m740_unidasm_t() { inst_state_base = 0; }
+ virtual ~m740_unidasm_t() override = default;
+ virtual u32 get_state_base() const override { return inst_state_base; }
+} m740_unidasm;
+
+// Configuration missing
+struct m7700_unidasm_t : m7700_disassembler::config
+{
+ bool m_flag;
+ bool x_flag;
+
+ m7700_unidasm_t() { m_flag = false; x_flag = false; }
+ virtual ~m7700_unidasm_t() override = default;
+ virtual bool get_m_flag() const override { return m_flag; }
+ virtual bool get_x_flag() const override { return x_flag; }
+} m7700_unidasm;
+
+
+// Configuration missing
+struct s2650_unidasm_t : s2650_disassembler::config
+{
+ bool z80_mnemonics;
+ s2650_unidasm_t() { z80_mnemonics = false; }
+ virtual ~s2650_unidasm_t() override = default;
+ virtual bool get_z80_mnemonics_mode() const override { return z80_mnemonics; }
+} s2650_unidasm;
+
+// Configuration missing
+struct saturn_unidasm_t : saturn_disassembler::config
+{
+ bool nonstandard_mnemonics;
+ saturn_unidasm_t() { nonstandard_mnemonics = false; }
+ virtual ~saturn_unidasm_t() override = default;
+ virtual bool get_nonstandard_mnemonics_mode() const override { return nonstandard_mnemonics; }
+} saturn_unidasm;
+// Configuration missing
+struct superfx_unidasm_t : superfx_disassembler::config
+{
+ u16 sfr;
+ superfx_unidasm_t() { sfr = superfx_disassembler::SUPERFX_SFR_ALT0; }
+ virtual ~superfx_unidasm_t() override = default;
+ virtual u16 get_alt() const override { return sfr; }
+} superfx_unidasm;
+
+// Selected through dasm name
+struct i386_unidasm_t : i386_disassembler::config
+{
+ int mode;
+ i386_unidasm_t() { mode = 32; }
+ virtual ~i386_unidasm_t() override = default;
+ virtual int get_mode() const override { return mode; }
+} i386_unidasm;
+
+// Configuration missing
+struct z8000_unidasm_t : z8000_disassembler::config
+{
+ bool segmented_mode;
+ z8000_unidasm_t() { segmented_mode = false; }
+ virtual ~z8000_unidasm_t() override = default;
+ virtual bool get_segmented_mode() const override { return segmented_mode; }
+} z8000_unidasm;
+
+
+
+
+enum endianness { le, be };
struct dasm_table_entry
{
const char * name;
- display_type display;
- int8_t pcshift;
- cpu_disassemble_func func;
+ endianness endian;
+ int8_t pcshift;
+ std::function<util::disasm_interface *()> alloc;
};
@@ -51,363 +256,575 @@ struct options
{
const char * filename;
offs_t basepc;
- uint8_t norawbytes;
- uint8_t lower;
- uint8_t upper;
- uint8_t flipped;
+ uint8_t norawbytes;
+ uint8_t lower;
+ uint8_t upper;
+ uint8_t flipped;
int mode;
const dasm_table_entry *dasm;
- uint32_t skip;
- uint32_t count;
+ uint32_t skip;
+ uint32_t count;
};
+static const dasm_table_entry dasm_table[] =
+{
+ { "8x300", be, 0, []() -> util::disasm_interface * { return new n8x300_disassembler; } },
+ { "adsp21xx", le, -2, []() -> util::disasm_interface * { return new adsp21xx_disassembler; } },
+ { "alpha8201", le, 0, []() -> util::disasm_interface * { return new alpha8201_disassembler; } },
+ { "alto2", be, -2, []() -> util::disasm_interface * { return new alto2_disassembler; } },
+ { "am29000", be, 0, []() -> util::disasm_interface * { return new am29000_disassembler; } },
+ { "amis2000", le, 0, []() -> util::disasm_interface * { return new amis2000_disassembler; } },
+ { "apexc", be, 0, []() -> util::disasm_interface * { return new apexc_disassembler; } },
+ { "arc", be, 0, []() -> util::disasm_interface * { return new arc_disassembler; } },
+ { "arcompact", le, 0, []() -> util::disasm_interface * { return new arcompact_disassembler; } },
+ { "arm", le, 0, []() -> util::disasm_interface * { return new arm_disassembler; } },
+ { "arm_be", be, 0, []() -> util::disasm_interface * { return new arm_disassembler; } },
+ { "arm7", le, 0, []() -> util::disasm_interface * { arm7_unidasm.t_flag = false; return new arm7_disassembler(&arm7_unidasm); } },
+ { "arm7_be", be, 0, []() -> util::disasm_interface * { arm7_unidasm.t_flag = false; return new arm7_disassembler(&arm7_unidasm); } },
+ { "arm7thumb", le, 0, []() -> util::disasm_interface * { arm7_unidasm.t_flag = true; return new arm7_disassembler(&arm7_unidasm); } },
+ { "arm7thumbb", be, 0, []() -> util::disasm_interface * { arm7_unidasm.t_flag = true; return new arm7_disassembler(&arm7_unidasm); } },
+ { "asap", le, 0, []() -> util::disasm_interface * { return new asap_disassembler; } },
+ { "avr8", le, 0, []() -> util::disasm_interface * { return new avr8_disassembler; } },
+ { "capricorn", le, 0, []() -> util::disasm_interface * { return new capricorn_disassembler; } },
+ { "ccpu", le, 0, []() -> util::disasm_interface * { return new ccpu_disassembler; } },
+ { "cdp1801", le, 0, []() -> util::disasm_interface * { return new cosmac_disassembler(cosmac_disassembler::TYPE_1801); } },
+ { "cdp1802", le, 0, []() -> util::disasm_interface * { return new cosmac_disassembler(cosmac_disassembler::TYPE_1802); } },
+ { "clipper", le, 0, []() -> util::disasm_interface * { return new clipper_disassembler; } },
+ { "coldfire", be, 0, []() -> util::disasm_interface * { return new m68k_disassembler(m68k_disassembler::TYPE_COLDFIRE); } },
+ { "cop410", le, 0, []() -> util::disasm_interface * { return new cop410_disassembler; } },
+ { "cop420", le, 0, []() -> util::disasm_interface * { return new cop420_disassembler; } },
+ { "cop444", le, 0, []() -> util::disasm_interface * { return new cop444_disassembler; } },
+ { "cop424", le, 0, []() -> util::disasm_interface * { return new cop424_disassembler; } },
+ { "cp1610", be, -1, []() -> util::disasm_interface * { return new cp1610_disassembler; } },
+ { "cquestlin", be, -3, []() -> util::disasm_interface * { return new cquestlin_disassembler; } },
+ { "cquestrot", be, -3, []() -> util::disasm_interface * { return new cquestrot_disassembler; } },
+ { "cquestsnd", be, -3, []() -> util::disasm_interface * { return new cquestsnd_disassembler; } },
+ { "ds5002fp", le, 0, []() -> util::disasm_interface * { return new ds5002fp_disassembler; } },
+ { "dsp16a", le, -1, []() -> util::disasm_interface * { return new dsp16a_disassembler; } },
+ { "dsp32c", le, 0, []() -> util::disasm_interface * { return new dsp32c_disassembler; } },
+ { "dsp56k", le, -1, []() -> util::disasm_interface * { return new dsp56k_disassembler; } },
+ { "e0c6200", be, -1, []() -> util::disasm_interface * { return new e0c6200_disassembler; } },
+// { "es5510", be, 0, []() -> util::disasm_interface * { return new es5510_disassembler; } }, // Currently does nothing
+ { "esrip", be, 0, []() -> util::disasm_interface * { return new esrip_disassembler; } },
+ { "f8", le, 0, []() -> util::disasm_interface * { return new f8_disassembler; } },
+ { "g65816", le, 0, []() -> util::disasm_interface * { return new g65816_disassembler(&g65816_unidasm); } },
+ { "h6280", le, 0, []() -> util::disasm_interface * { return new h6280_disassembler; } },
+ { "h8", be, 0, []() -> util::disasm_interface * { return new h8_disassembler; } },
+ { "h8h", be, 0, []() -> util::disasm_interface * { return new h8h_disassembler; } },
+ { "h8s2000", be, 0, []() -> util::disasm_interface * { return new h8s2000_disassembler; } },
+ { "h8s2600", be, 0, []() -> util::disasm_interface * { return new h8s2600_disassembler; } },
+ { "hc11", le, 0, []() -> util::disasm_interface * { return new hc11_disassembler; } },
+ { "hcd62121", le, 0, []() -> util::disasm_interface * { return new hcd62121_disassembler; } },
+ { "hd61700", le, 0, []() -> util::disasm_interface * { return new hd61700_disassembler; } },
+ { "hd6301", le, 0, []() -> util::disasm_interface * { return new m680x_disassembler(6301); } },
+ { "hd6309", le, 0, []() -> util::disasm_interface * { return new hd6309_disassembler; } },
+ { "hd63701", le, 0, []() -> util::disasm_interface * { return new m680x_disassembler(63701); } },
+ { "hmcs40", le, -1, []() -> util::disasm_interface * { return new hmcs40_disassembler; } },
+ { "hp_hybrid", be, -1, []() -> util::disasm_interface * { return new hp_hybrid_disassembler; } },
+ { "hp_5061_3001", be, -1, []() -> util::disasm_interface * { return new hp_5061_3001_disassembler; } },
+ { "hyperstone", be, 0, []() -> util::disasm_interface * { return new hyperstone_disassembler; } },
+ { "i4004", le, 0, []() -> util::disasm_interface * { return new i4004_disassembler; } },
+ { "i4040", le, 0, []() -> util::disasm_interface * { return new i4040_disassembler; } },
+ { "i8008", le, 0, []() -> util::disasm_interface * { return new i8008_disassembler; } },
+ { "i8051", le, 0, []() -> util::disasm_interface * { return new i8051_disassembler; } },
+ { "i8052", le, 0, []() -> util::disasm_interface * { return new i8052_disassembler; } },
+ { "i8085", le, 0, []() -> util::disasm_interface * { return new i8085_disassembler; } },
+ { "i8089", le, 0, []() -> util::disasm_interface * { return new i8089_disassembler; } },
+ { "i80c51", le, 0, []() -> util::disasm_interface * { return new i80c51_disassembler; } },
+ { "i80c52", le, 0, []() -> util::disasm_interface * { return new i80c52_disassembler; } },
+ { "i860", le, 0, []() -> util::disasm_interface * { return new i860_disassembler; } },
+ { "i8x9x", le, 0, []() -> util::disasm_interface * { return new i8x9x_disassembler; } },
+ { "i8xc196", le, 0, []() -> util::disasm_interface * { return new i8xc196_disassembler; } },
+ { "i960", le, 0, []() -> util::disasm_interface * { return new i960_disassembler; } },
+ { "ie15", le, 0, []() -> util::disasm_interface * { return new ie15_disassembler; } },
+ { "jaguardsp", be, 0, []() -> util::disasm_interface * { return new jaguar_disassembler(jaguar_disassembler::JAGUAR_VARIANT_DSP); } },
+ { "jaguargpu", be, 0, []() -> util::disasm_interface * { return new jaguar_disassembler(jaguar_disassembler::JAGUAR_VARIANT_GPU); } },
+ { "konami", le, 0, []() -> util::disasm_interface * { return new konami_disassembler; } },
+ { "lc8670", be, 0, []() -> util::disasm_interface * { return new lc8670_disassembler; } },
+ { "lh5801", le, 0, []() -> util::disasm_interface * { return new lh5801_disassembler; } },
+ { "lr35902", le, 0, []() -> util::disasm_interface * { return new lr35902_disassembler; } },
+ { "m146805", le, 0, []() -> util::disasm_interface * { return new m146805_disassembler; } },
+ { "m37710", le, 0, []() -> util::disasm_interface * { return new m7700_disassembler(&m7700_unidasm); } },
+ { "m4510", le, 0, []() -> util::disasm_interface * { return new m4510_disassembler; } },
+ { "m58846", le, -1, []() -> util::disasm_interface * { return new melps4_disassembler; } },
+ { "m6502", le, 0, []() -> util::disasm_interface * { return new m6502_disassembler; } },
+ { "m6509", le, 0, []() -> util::disasm_interface * { return new m6509_disassembler; } },
+ { "m6510", le, 0, []() -> util::disasm_interface * { return new m6510_disassembler; } },
+ { "m65c02", le, 0, []() -> util::disasm_interface * { return new m65c02_disassembler; } },
+ { "m65ce02", le, 0, []() -> util::disasm_interface * { return new m65ce02_disassembler; } },
+ { "m6800", le, 0, []() -> util::disasm_interface * { return new m680x_disassembler(6800); } },
+ { "m68000", be, 0, []() -> util::disasm_interface * { return new m68k_disassembler(m68k_disassembler::TYPE_68000); } },
+ { "m68008", be, 0, []() -> util::disasm_interface * { return new m68k_disassembler(m68k_disassembler::TYPE_68008); } },
+ { "m6801", le, 0, []() -> util::disasm_interface * { return new m680x_disassembler(6801); } },
+ { "m68010", be, 0, []() -> util::disasm_interface * { return new m68k_disassembler(m68k_disassembler::TYPE_68010); } },
+ { "m6802", le, 0, []() -> util::disasm_interface * { return new m680x_disassembler(6802); } },
+ { "m68020", be, 0, []() -> util::disasm_interface * { return new m68k_disassembler(m68k_disassembler::TYPE_68020); } },
+ { "m6803", le, 0, []() -> util::disasm_interface * { return new m680x_disassembler(6803); } },
+ { "m68030", be, 0, []() -> util::disasm_interface * { return new m68k_disassembler(m68k_disassembler::TYPE_68030); } },
+ { "m68040", be, 0, []() -> util::disasm_interface * { return new m68k_disassembler(m68k_disassembler::TYPE_68040); } },
+ { "m6805", le, 0, []() -> util::disasm_interface * { return new m6805_disassembler; } },
+ { "m6808", le, 0, []() -> util::disasm_interface * { return new m680x_disassembler(6808); } },
+ { "m6809", le, 0, []() -> util::disasm_interface * { return new m6809_disassembler; } },
+ { "m68340", be, 0, []() -> util::disasm_interface * { return new m68k_disassembler(m68k_disassembler::TYPE_68340); } },
+ { "m68hc05", le, 0, []() -> util::disasm_interface * { return new m68hc05_disassembler; } },
+ { "m740", le, 0, []() -> util::disasm_interface * { return new m740_disassembler(&m740_unidasm); } },
+ { "mb86233", le, -2, []() -> util::disasm_interface * { return new mb86233_disassembler; } },
+ { "mb86235", le, -3, []() -> util::disasm_interface * { return new mb86235_disassembler; } },
+ { "mb88", le, 0, []() -> util::disasm_interface * { return new mb88_disassembler; } },
+ { "mcs48", le, 0, []() -> util::disasm_interface * { return new mcs48_disassembler(false); } },
+ { "minx", le, 0, []() -> util::disasm_interface * { return new minx_disassembler; } },
+ { "mips3be", be, 0, []() -> util::disasm_interface * { return new mips3_disassembler; } },
+ { "mips3le", le, 0, []() -> util::disasm_interface * { return new mips3_disassembler; } },
+ { "mn10200", le, 0, []() -> util::disasm_interface * { return new mn10200_disassembler; } },
+ { "nanoprocessor", le, 0, []() -> util::disasm_interface * { return new hp_nanoprocessor_disassembler; } },
+ { "nec", le, 0, []() -> util::disasm_interface * { return new nec_disassembler; } },
+ { "nsc8105", le, 0, []() -> util::disasm_interface * { return new m680x_disassembler(8105); } },
+ { "patinho_feio", le, 0, []() -> util::disasm_interface * { return new patinho_feio_disassembler; } },
+ { "pdp1", be, 0, []() -> util::disasm_interface * { return new pdp1_disassembler; } },
+ { "pdp8", be, 0, []() -> util::disasm_interface * { return new pdp8_disassembler; } },
+ { "pic16c5x", le, -1, []() -> util::disasm_interface * { return new pic16c5x_disassembler; } },
+ { "pic16c62x", le, -1, []() -> util::disasm_interface * { return new pic16c62x_disassembler; } },
+ { "powerpc", be, 0, []() -> util::disasm_interface * { return new powerpc_disassembler; } },
+ { "pps4", le, 0, []() -> util::disasm_interface * { return new pps4_disassembler; } },
+ { "psxcpu", le, 0, []() -> util::disasm_interface * { return new psxcpu_disassembler; } },
+ { "r3000be", be, 0, []() -> util::disasm_interface * { return new r3000_disassembler; } },
+ { "r3000le", le, 0, []() -> util::disasm_interface * { return new r3000_disassembler; } },
+ { "rsp", le, 0, []() -> util::disasm_interface * { return new rsp_disassembler; } },
+ { "s2650", le, 0, []() -> util::disasm_interface * { return new s2650_disassembler(&s2650_unidasm); } },
+ { "saturn", le, 0, []() -> util::disasm_interface * { return new saturn_disassembler(&saturn_unidasm); } },
+ { "sc61860", le, 0, []() -> util::disasm_interface * { return new sc61860_disassembler; } },
+ { "scmp", le, 0, []() -> util::disasm_interface * { return new scmp_disassembler; } },
+ { "scudsp", be, 0, []() -> util::disasm_interface * { return new scudsp_disassembler; } },
+ { "se3208", le, 0, []() -> util::disasm_interface * { return new se3208_disassembler; } },
+ { "sh2", be, 0, []() -> util::disasm_interface * { return new sh_disassembler(false); } },
+ { "sh4", le, 0, []() -> util::disasm_interface * { return new sh_disassembler(true); } },
+ { "sh4be", be, 0, []() -> util::disasm_interface * { return new sh_disassembler(true); } },
+ { "sharc", le, -2, []() -> util::disasm_interface * { return new sharc_disassembler; } },
+ { "sm500", le, 0, []() -> util::disasm_interface * { return new sm500_disassembler; } },
+ { "sm510", le, 0, []() -> util::disasm_interface * { return new sm510_disassembler; } },
+ { "sm511", le, 0, []() -> util::disasm_interface * { return new sm511_disassembler; } },
+ { "sm590", le, 0, []() -> util::disasm_interface * { return new sm590_disassembler; } },
+ { "sm5a", le, 0, []() -> util::disasm_interface * { return new sm5a_disassembler; } },
+ { "sm8500", le, 0, []() -> util::disasm_interface * { return new sm8500_disassembler; } },
+ { "sparcv7", be, 0, []() -> util::disasm_interface * { return new sparc_disassembler(nullptr, 7); } },
+ { "sparcv8", be, 0, []() -> util::disasm_interface * { return new sparc_disassembler(nullptr, 8); } },
+ { "sparcv9", be, 0, []() -> util::disasm_interface * { return new sparc_disassembler(nullptr, 9); } },
+ { "sparcv9vis1", be, 0, []() -> util::disasm_interface * { return new sparc_disassembler(nullptr, 9, sparc_disassembler::vis_1); } },
+ { "sparcv9vis2", be, 0, []() -> util::disasm_interface * { return new sparc_disassembler(nullptr, 9, sparc_disassembler::vis_2); } },
+ { "sparcv9vis2p", be, 0, []() -> util::disasm_interface * { return new sparc_disassembler(nullptr, 9, sparc_disassembler::vis_2p); } },
+ { "sparcv9vis3", be, 0, []() -> util::disasm_interface * { return new sparc_disassembler(nullptr, 9, sparc_disassembler::vis_3); } },
+ { "sparcv9vis3b", be, 0, []() -> util::disasm_interface * { return new sparc_disassembler(nullptr, 9, sparc_disassembler::vis_3b); } },
+ { "spc700", le, 0, []() -> util::disasm_interface * { return new spc700_disassembler; } },
+ { "ssem", le, 0, []() -> util::disasm_interface * { return new ssem_disassembler; } },
+ { "ssp1601", be, -1, []() -> util::disasm_interface * { return new ssp1601_disassembler; } },
+ { "superfx", le, 0, []() -> util::disasm_interface * { return new superfx_disassembler(&superfx_unidasm); } },
+ { "t11", le, 0, []() -> util::disasm_interface * { return new t11_disassembler; } },
+ { "tlcs870", le, 0, []() -> util::disasm_interface * { return new tlcs870_disassembler; } },
+ { "tlcs90", le, 0, []() -> util::disasm_interface * { return new tlcs90_disassembler; } },
+ { "tlcs900", le, 0, []() -> util::disasm_interface * { return new tlcs900_disassembler; } },
+ { "tms0980", be, 0, []() -> util::disasm_interface * { return new tms0980_disassembler; } },
+ { "tms1000", le, 0, []() -> util::disasm_interface * { return new tms1000_disassembler; } },
+ { "tms1100", le, 0, []() -> util::disasm_interface * { return new tms1100_disassembler; } },
+ { "tms32010", be, -1, []() -> util::disasm_interface * { return new tms32010_disassembler; } },
+ { "tms32025", be, -1, []() -> util::disasm_interface * { return new tms32025_disassembler; } },
+ { "tms32031", le, -2, []() -> util::disasm_interface * { return new tms32031_disassembler; } },
+ { "tms32051", le, -1, []() -> util::disasm_interface * { return new tms32051_disassembler; } },
+ { "tms32082_mp", be, 0, []() -> util::disasm_interface * { return new tms32082_mp_disassembler; } },
+ { "tms32082_pp", be, 0, []() -> util::disasm_interface * { return new tms32082_pp_disassembler; } },
+ { "tms34010", le, 3, []() -> util::disasm_interface * { return new tms34010_disassembler(false); } },
+ { "tms34020", le, 3, []() -> util::disasm_interface * { return new tms34010_disassembler(true); } },
+ { "tms57002", le, -2, []() -> util::disasm_interface * { return new tms57002_disassembler; } },
+ { "tms7000", le, 0, []() -> util::disasm_interface * { return new tms7000_disassembler; } },
+ { "tms9900", be, 0, []() -> util::disasm_interface * { return new tms9900_disassembler(TMS9900_ID); } },
+ { "tms9980", le, 0, []() -> util::disasm_interface * { return new tms9900_disassembler(TMS9980_ID); } },
+ { "tms9995", le, 0, []() -> util::disasm_interface * { return new tms9900_disassembler(TMS9995_ID); } },
+ { "tp0320", be, 0, []() -> util::disasm_interface * { return new tp0320_disassembler; } },
+ { "tx0_64kw", be, -2, []() -> util::disasm_interface * { return new tx0_64kw_disassembler; } },
+ { "tx0_8kw", be, -2, []() -> util::disasm_interface * { return new tx0_8kw_disassembler; } },
+ { "ucom4", le, 0, []() -> util::disasm_interface * { return new ucom4_disassembler; } },
+ { "unsp", be, 0, []() -> util::disasm_interface * { return new unsp_disassembler; } },
+ { "upd7725", be, 0, []() -> util::disasm_interface * { return new necdsp_disassembler; } },
+ { "upd7801", le, 0, []() -> util::disasm_interface * { return new upd7801_disassembler; } },
+ { "upd7807", le, 0, []() -> util::disasm_interface * { return new upd7807_disassembler; } },
+ { "upd7810", le, 0, []() -> util::disasm_interface * { return new upd7810_disassembler; } },
+ { "upd78c05", le, 0, []() -> util::disasm_interface * { return new upd78c05_disassembler; } },
+ { "upi41", le, 0, []() -> util::disasm_interface * { return new mcs48_disassembler(true); } },
+ { "v60", le, 0, []() -> util::disasm_interface * { return new v60_disassembler; } },
+ { "v810", le, 0, []() -> util::disasm_interface * { return new v810_disassembler; } },
+ { "x86_16", le, 0, []() -> util::disasm_interface * { i386_unidasm.mode = 16; return new i386_disassembler(&i386_unidasm); } },
+ { "x86_32", le, 0, []() -> util::disasm_interface * { i386_unidasm.mode = 32; return new i386_disassembler(&i386_unidasm); } },
+ { "x86_64", le, 0, []() -> util::disasm_interface * { i386_unidasm.mode = 64; return new i386_disassembler(&i386_unidasm); } },
+ { "z180", le, 0, []() -> util::disasm_interface * { return new z180_disassembler; } },
+ { "z8", le, 0, []() -> util::disasm_interface * { return new z8_disassembler; } },
+ { "z80", le, 0, []() -> util::disasm_interface * { return new z80_disassembler; } },
+ { "z8000", be, 0, []() -> util::disasm_interface * { return new z8000_disassembler(&z8000_unidasm); } },
+};
+
+class unidasm_data_buffer : public util::disasm_interface::data_buffer
+{
+public:
+ std::vector<u8> data;
+ offs_t base_pc;
+ u32 size;
-CPU_DISASSEMBLE( adsp21xx );
-CPU_DISASSEMBLE( alpha8201 );
-CPU_DISASSEMBLE( am29000 );
-CPU_DISASSEMBLE( amis2000 );
-CPU_DISASSEMBLE( apexc );
-CPU_DISASSEMBLE( arcompact );
-CPU_DISASSEMBLE( arm );
-CPU_DISASSEMBLE( arm_be );
-CPU_DISASSEMBLE( arm7arm );
-CPU_DISASSEMBLE( arm7arm_be );
-CPU_DISASSEMBLE( arm7thumb );
-CPU_DISASSEMBLE( arm7thumb_be );
-CPU_DISASSEMBLE( asap );
-CPU_DISASSEMBLE( avr8 );
-CPU_DISASSEMBLE( capricorn );
-CPU_DISASSEMBLE( ccpu );
-CPU_DISASSEMBLE( cdp1801 );
-CPU_DISASSEMBLE( cdp1802 );
-CPU_DISASSEMBLE( clipper );
-CPU_DISASSEMBLE( coldfire );
-CPU_DISASSEMBLE( cop410 );
-CPU_DISASSEMBLE( cop420 );
-CPU_DISASSEMBLE( cop444 );
-CPU_DISASSEMBLE( cop424 );
-CPU_DISASSEMBLE( cp1610 );
-CPU_DISASSEMBLE( cquestlin );
-CPU_DISASSEMBLE( cquestrot );
-CPU_DISASSEMBLE( cquestsnd );
-CPU_DISASSEMBLE( ds5002fp );
-CPU_DISASSEMBLE( dsp16a );
-CPU_DISASSEMBLE( dsp32c );
-CPU_DISASSEMBLE( dsp56k );
-CPU_DISASSEMBLE( e0c6200 );
-CPU_DISASSEMBLE( esrip );
-CPU_DISASSEMBLE( f8 );
-CPU_DISASSEMBLE( g65816_generic );
-CPU_DISASSEMBLE( h6280 );
-CPU_DISASSEMBLE( hc11 );
-CPU_DISASSEMBLE( hcd62121 );
-CPU_DISASSEMBLE( hd61700 );
-CPU_DISASSEMBLE( hd6301 );
-CPU_DISASSEMBLE( hd6309 );
-CPU_DISASSEMBLE( hd63701 );
-CPU_DISASSEMBLE( hmcs40 );
-CPU_DISASSEMBLE( hp_hybrid );
-CPU_DISASSEMBLE( hp_5061_3001 );
-CPU_DISASSEMBLE( hp_nanoprocessor );
-CPU_DISASSEMBLE( hyperstone_generic );
-CPU_DISASSEMBLE( i4004 );
-CPU_DISASSEMBLE( i4040 );
-CPU_DISASSEMBLE( i8008 );
-CPU_DISASSEMBLE( i8051 );
-CPU_DISASSEMBLE( i8052 );
-CPU_DISASSEMBLE( i8085 );
-CPU_DISASSEMBLE( i8089 );
-CPU_DISASSEMBLE( i80c51 );
-CPU_DISASSEMBLE( i80c52 );
-CPU_DISASSEMBLE( i860 );
-CPU_DISASSEMBLE( i960 );
-CPU_DISASSEMBLE( ie15 );
-CPU_DISASSEMBLE( jaguardsp );
-CPU_DISASSEMBLE( jaguargpu );
-CPU_DISASSEMBLE( konami );
-CPU_DISASSEMBLE( lh5801 );
-CPU_DISASSEMBLE( lr35902 );
-CPU_DISASSEMBLE( m58846 );
-CPU_DISASSEMBLE( m37710_generic );
-CPU_DISASSEMBLE( m6800 );
-CPU_DISASSEMBLE( m68000 );
-CPU_DISASSEMBLE( m68008 );
-CPU_DISASSEMBLE( m6801 );
-CPU_DISASSEMBLE( m68010 );
-CPU_DISASSEMBLE( m6802 );
-CPU_DISASSEMBLE( m68020 );
-CPU_DISASSEMBLE( m6803 );
-CPU_DISASSEMBLE( m68030 );
-CPU_DISASSEMBLE( m68040 );
-CPU_DISASSEMBLE( m6805 );
-CPU_DISASSEMBLE( m146805 );
-CPU_DISASSEMBLE( m68hc05 );
-CPU_DISASSEMBLE( m6808 );
-CPU_DISASSEMBLE( m6809 );
-CPU_DISASSEMBLE( m68340 );
-CPU_DISASSEMBLE( mb86233 );
-CPU_DISASSEMBLE( mb88 );
-CPU_DISASSEMBLE( mcs48 );
-CPU_DISASSEMBLE( minx );
-CPU_DISASSEMBLE( mips3be );
-CPU_DISASSEMBLE( mips3le );
-CPU_DISASSEMBLE( mn10200 );
-CPU_DISASSEMBLE( n8x300 );
-CPU_DISASSEMBLE( nec );
-CPU_DISASSEMBLE( nsc8105 );
-CPU_DISASSEMBLE( pdp1 );
-CPU_DISASSEMBLE( pdp8 );
-CPU_DISASSEMBLE( pic16c5x );
-CPU_DISASSEMBLE( pic16c62x );
-CPU_DISASSEMBLE( powerpc );
-CPU_DISASSEMBLE( pps4 );
-CPU_DISASSEMBLE( psxcpu_generic );
-CPU_DISASSEMBLE( r3000be );
-CPU_DISASSEMBLE( r3000le );
-CPU_DISASSEMBLE( rsp );
-CPU_DISASSEMBLE( s2650 );
-CPU_DISASSEMBLE( saturn );
-CPU_DISASSEMBLE( sc61860 );
-CPU_DISASSEMBLE( scmp );
-CPU_DISASSEMBLE( scudsp );
-CPU_DISASSEMBLE( se3208 );
-CPU_DISASSEMBLE( sh2 );
-CPU_DISASSEMBLE( sh4 );
-CPU_DISASSEMBLE( sh4be );
-CPU_DISASSEMBLE( sharc );
-CPU_DISASSEMBLE( sm500 );
-CPU_DISASSEMBLE( sm510 );
-CPU_DISASSEMBLE( sm511 );
-CPU_DISASSEMBLE( sm5a );
-CPU_DISASSEMBLE( sm8500 );
-CPU_DISASSEMBLE( spc700 );
-CPU_DISASSEMBLE( ssem );
-CPU_DISASSEMBLE( ssp1601 );
-CPU_DISASSEMBLE( superfx );
-CPU_DISASSEMBLE( t11 );
-CPU_DISASSEMBLE( t90 );
-CPU_DISASSEMBLE( tlcs900 );
-CPU_DISASSEMBLE( tms0980 );
-CPU_DISASSEMBLE( tms1000 );
-CPU_DISASSEMBLE( tms1100 );
-CPU_DISASSEMBLE( tms32010 );
-CPU_DISASSEMBLE( tms32025 );
-CPU_DISASSEMBLE( tms3203x );
-CPU_DISASSEMBLE( tms32051 );
-CPU_DISASSEMBLE( tms34010 );
-CPU_DISASSEMBLE( tms34020 );
-CPU_DISASSEMBLE( tms57002 );
-CPU_DISASSEMBLE( tms7000 );
-CPU_DISASSEMBLE( tms9900 );
-CPU_DISASSEMBLE( tms9980 );
-CPU_DISASSEMBLE( tms9995 );
-CPU_DISASSEMBLE( tp0320 );
-CPU_DISASSEMBLE( tx0_64kw );
-CPU_DISASSEMBLE( tx0_8kw );
-CPU_DISASSEMBLE( ucom4 );
-CPU_DISASSEMBLE( unsp );
-CPU_DISASSEMBLE( upd7725 );
-CPU_DISASSEMBLE( upd7801 );
-CPU_DISASSEMBLE( upd7807 );
-CPU_DISASSEMBLE( upd7810 );
-CPU_DISASSEMBLE( upd78c05 );
-CPU_DISASSEMBLE( upi41 );
-CPU_DISASSEMBLE( v60 );
-CPU_DISASSEMBLE( v70 );
-CPU_DISASSEMBLE( v810 );
-CPU_DISASSEMBLE( x86_16 );
-CPU_DISASSEMBLE( x86_32 );
-CPU_DISASSEMBLE( x86_64 );
-CPU_DISASSEMBLE( z180 );
-CPU_DISASSEMBLE( z8 );
-CPU_DISASSEMBLE( z80 );
-CPU_DISASSEMBLE( z8000 );
-
-CPU_DISASSEMBLE( sparcv7 ) { static sparc_disassembler dasm(nullptr, 7); return dasm.dasm(stream, pc, big_endianize_int32(*reinterpret_cast<const uint32_t *>(oprom))); }
-CPU_DISASSEMBLE( sparcv8 ) { static sparc_disassembler dasm(nullptr, 8); return dasm.dasm(stream, pc, big_endianize_int32(*reinterpret_cast<const uint32_t *>(oprom))); }
-CPU_DISASSEMBLE( sparcv9 ) { static sparc_disassembler dasm(nullptr, 9); return dasm.dasm(stream, pc, big_endianize_int32(*reinterpret_cast<const uint32_t *>(oprom))); }
-CPU_DISASSEMBLE( sparcv9vis1 ) { static sparc_disassembler dasm(nullptr, 9, sparc_disassembler::vis_1); return dasm.dasm(stream, pc, big_endianize_int32(*reinterpret_cast<const uint32_t *>(oprom))); }
-CPU_DISASSEMBLE( sparcv9vis2 ) { static sparc_disassembler dasm(nullptr, 9, sparc_disassembler::vis_2); return dasm.dasm(stream, pc, big_endianize_int32(*reinterpret_cast<const uint32_t *>(oprom))); }
-CPU_DISASSEMBLE( sparcv9vis2p ) { static sparc_disassembler dasm(nullptr, 9, sparc_disassembler::vis_2p); return dasm.dasm(stream, pc, big_endianize_int32(*reinterpret_cast<const uint32_t *>(oprom))); }
-CPU_DISASSEMBLE( sparcv9vis3 ) { static sparc_disassembler dasm(nullptr, 9, sparc_disassembler::vis_3); return dasm.dasm(stream, pc, big_endianize_int32(*reinterpret_cast<const uint32_t *>(oprom))); }
-CPU_DISASSEMBLE( sparcv9vis3b ) { static sparc_disassembler dasm(nullptr, 9, sparc_disassembler::vis_3b); return dasm.dasm(stream, pc, big_endianize_int32(*reinterpret_cast<const uint32_t *>(oprom))); }
+ unidasm_data_buffer(util::disasm_interface *disasm, const dasm_table_entry *entry);
+ virtual ~unidasm_data_buffer() = default;
+ void decrypt(const unidasm_data_buffer &buffer, bool opcode);
-static const dasm_table_entry dasm_table[] =
+ virtual u8 r8 (offs_t pc) const override { return lr8 (pc); }
+ virtual u16 r16(offs_t pc) const override { return lr16(pc); }
+ virtual u32 r32(offs_t pc) const override { return lr32(pc); }
+ virtual u64 r64(offs_t pc) const override { return lr64(pc); }
+
+private:
+ std::function<u8 (offs_t pc)> lr8;
+ std::function<u16 (offs_t pc)> lr16;
+ std::function<u32 (offs_t pc)> lr32;
+ std::function<u64 (offs_t pc)> lr64;
+
+ util::disasm_interface *disasm;
+ const dasm_table_entry *entry;
+
+ template<typename T> const T *get_ptr(offs_t pc) const {
+ if(pc < base_pc)
+ return nullptr;
+ offs_t delta = (pc - base_pc) * sizeof(T);
+ if(delta >= size)
+ return nullptr;
+ return reinterpret_cast<const T *>(&data[delta]);
+ }
+
+ template<typename T> T get(offs_t pc) const {
+ auto p = get_ptr<T>(pc);
+ return p ? *p : 0;
+ }
+};
+
+struct dasm_line
{
- { "8x300", _16be, 0, CPU_DISASSEMBLE_NAME(n8x300) },
- { "adsp21xx", _24le, -2, CPU_DISASSEMBLE_NAME(adsp21xx) },
- { "alpha8201", _8bit, 0, CPU_DISASSEMBLE_NAME(alpha8201) },
- { "am29000", _32be, 0, CPU_DISASSEMBLE_NAME(am29000) },
- { "amis2000", _8bit, 0, CPU_DISASSEMBLE_NAME(amis2000) },
- { "apexc", _32be, 0, CPU_DISASSEMBLE_NAME(apexc) },
- { "arcompact", _16le, 0, CPU_DISASSEMBLE_NAME(arcompact) },
- { "arm", _32le, 0, CPU_DISASSEMBLE_NAME(arm) },
- { "arm_be", _32be, 0, CPU_DISASSEMBLE_NAME(arm_be) },
- { "arm7", _32le, 0, CPU_DISASSEMBLE_NAME(arm7arm) },
- { "arm7_be", _32be, 0, CPU_DISASSEMBLE_NAME(arm7arm_be) },
- { "arm7thumb", _16le, 0, CPU_DISASSEMBLE_NAME(arm7thumb) },
- { "arm7thumbb", _16be, 0, CPU_DISASSEMBLE_NAME(arm7thumb_be) },
- { "asap", _32le, 0, CPU_DISASSEMBLE_NAME(asap) },
- { "avr8", _16le, 0, CPU_DISASSEMBLE_NAME(avr8) },
- { "capricorn", _8bit, 0, CPU_DISASSEMBLE_NAME(capricorn) },
- { "ccpu", _8bit, 0, CPU_DISASSEMBLE_NAME(ccpu) },
- { "cdp1801", _8bit, 0, CPU_DISASSEMBLE_NAME(cdp1801) },
- { "cdp1802", _8bit, 0, CPU_DISASSEMBLE_NAME(cdp1802) },
- { "clipper", _16le, 0, CPU_DISASSEMBLE_NAME(clipper) },
- { "coldfire", _16be, 0, CPU_DISASSEMBLE_NAME(coldfire) },
- { "cop410", _8bit, 0, CPU_DISASSEMBLE_NAME(cop410) },
- { "cop420", _8bit, 0, CPU_DISASSEMBLE_NAME(cop420) },
- { "cop444", _8bit, 0, CPU_DISASSEMBLE_NAME(cop444) },
- { "cop424", _8bit, 0, CPU_DISASSEMBLE_NAME(cop424) },
- { "cp1610", _16be, -1, CPU_DISASSEMBLE_NAME(cp1610) },
- { "cquestlin", _64be, -3, CPU_DISASSEMBLE_NAME(cquestlin) },
- { "cquestrot", _64be, -3, CPU_DISASSEMBLE_NAME(cquestrot) },
- { "cquestsnd", _64be, -3, CPU_DISASSEMBLE_NAME(cquestsnd) },
- { "ds5002fp", _8bit, 0, CPU_DISASSEMBLE_NAME(ds5002fp) },
- { "dsp16a", _16le, -1, CPU_DISASSEMBLE_NAME(dsp16a) },
- { "dsp32c", _32le, 0, CPU_DISASSEMBLE_NAME(dsp32c) },
- { "dsp56k", _16le, -1, CPU_DISASSEMBLE_NAME(dsp56k) },
- { "e0c6200", _16be, -1, CPU_DISASSEMBLE_NAME(e0c6200) },
- { "esrip", _64be, 0, CPU_DISASSEMBLE_NAME(esrip) },
- { "f8", _8bit, 0, CPU_DISASSEMBLE_NAME(f8) },
- { "g65816", _8bit, 0, CPU_DISASSEMBLE_NAME(g65816_generic) },
- { "h6280", _8bit, 0, CPU_DISASSEMBLE_NAME(h6280) },
-// { "h8", _16be, 0, CPU_DISASSEMBLE_NAME(h8) },
-// { "h8_24", _16be, 0, CPU_DISASSEMBLE_NAME(h8_24) },
-// { "h8_32", _16be, 0, CPU_DISASSEMBLE_NAME(h8_32) },
- { "hc11", _8bit, 0, CPU_DISASSEMBLE_NAME(hc11) },
- { "hcd62121", _8bit, 0, CPU_DISASSEMBLE_NAME(hcd62121) },
- { "hd61700", _8bit, 0, CPU_DISASSEMBLE_NAME(hd61700) },
- { "hd6301", _8bit, 0, CPU_DISASSEMBLE_NAME(hd6301) },
- { "hd6309", _8bit, 0, CPU_DISASSEMBLE_NAME(hd6309) },
- { "hd63701", _8bit, 0, CPU_DISASSEMBLE_NAME(hd63701) },
- { "hmcs40", _16le, -1, CPU_DISASSEMBLE_NAME(hmcs40) },
- { "hp_hybrid", _16be, -1, CPU_DISASSEMBLE_NAME(hp_hybrid) },
- { "hp_5061_3001",_16be, -1, CPU_DISASSEMBLE_NAME(hp_5061_3001) },
- { "hyperstone", _16be, 0, CPU_DISASSEMBLE_NAME(hyperstone_generic) },
- { "i4004", _8bit, 0, CPU_DISASSEMBLE_NAME(i4004) },
- { "i4040", _8bit, 0, CPU_DISASSEMBLE_NAME(i4040) },
- { "i8008", _8bit, 0, CPU_DISASSEMBLE_NAME(i8008) },
- { "i8051", _8bit, 0, CPU_DISASSEMBLE_NAME(i8051) },
- { "i8052", _8bit, 0, CPU_DISASSEMBLE_NAME(i8052) },
- { "i8085", _8bit, 0, CPU_DISASSEMBLE_NAME(i8085) },
- { "i8089", _8bit, 0, CPU_DISASSEMBLE_NAME(i8089) },
- { "i80c51", _8bit, 0, CPU_DISASSEMBLE_NAME(i80c51) },
- { "i80c52", _8bit, 0, CPU_DISASSEMBLE_NAME(i80c52) },
- { "i860", _64le, 0, CPU_DISASSEMBLE_NAME(i860) },
- { "i960", _32le, 0, CPU_DISASSEMBLE_NAME(i960) },
- { "ie15", _8bit, 0, CPU_DISASSEMBLE_NAME(ie15) },
- { "jaguardsp", _16be, 0, CPU_DISASSEMBLE_NAME(jaguardsp) },
- { "jaguargpu", _16be, 0, CPU_DISASSEMBLE_NAME(jaguargpu) },
- { "konami", _8bit, 0, CPU_DISASSEMBLE_NAME(konami) },
- { "lh5801", _8bit, 0, CPU_DISASSEMBLE_NAME(lh5801) },
- { "lr35902", _8bit, 0, CPU_DISASSEMBLE_NAME(lr35902) },
- { "m58846", _16le, -1, CPU_DISASSEMBLE_NAME(m58846) },
- { "m37710", _8bit, 0, CPU_DISASSEMBLE_NAME(m37710_generic) },
- { "m6800", _8bit, 0, CPU_DISASSEMBLE_NAME(m6800) },
- { "m68000", _16be, 0, CPU_DISASSEMBLE_NAME(m68000) },
- { "m68008", _16be, 0, CPU_DISASSEMBLE_NAME(m68008) },
- { "m6801", _8bit, 0, CPU_DISASSEMBLE_NAME(m6801) },
- { "m68010", _16be, 0, CPU_DISASSEMBLE_NAME(m68010) },
- { "m6802", _8bit, 0, CPU_DISASSEMBLE_NAME(m6802) },
- { "m68020", _16be, 0, CPU_DISASSEMBLE_NAME(m68020) },
- { "m6803", _8bit, 0, CPU_DISASSEMBLE_NAME(m6803) },
- { "m68030", _16be, 0, CPU_DISASSEMBLE_NAME(m68030) },
- { "m68040", _16be, 0, CPU_DISASSEMBLE_NAME(m68040) },
- { "m6805", _8bit, 0, CPU_DISASSEMBLE_NAME(m6805) },
- { "m146805", _8bit, 0, CPU_DISASSEMBLE_NAME(m146805) },
- { "m68hc05", _8bit, 0, CPU_DISASSEMBLE_NAME(m68hc05) },
- { "m6808", _8bit, 0, CPU_DISASSEMBLE_NAME(m6808) },
- { "m6809", _8bit, 0, CPU_DISASSEMBLE_NAME(m6809) },
- { "m68340", _16be, 0, CPU_DISASSEMBLE_NAME(m68340) },
- { "mb86233", _32le, -2, CPU_DISASSEMBLE_NAME(mb86233) },
- { "mb88", _8bit, 0, CPU_DISASSEMBLE_NAME(mb88) },
- { "mcs48", _8bit, 0, CPU_DISASSEMBLE_NAME(mcs48) },
- { "minx", _8bit, 0, CPU_DISASSEMBLE_NAME(minx) },
- { "mips3be", _32be, 0, CPU_DISASSEMBLE_NAME(mips3be) },
- { "mips3le", _32le, 0, CPU_DISASSEMBLE_NAME(mips3le) },
- { "mn10200", _16le, 0, CPU_DISASSEMBLE_NAME(mn10200) },
- { "nanoprocessor",_8bit, 0, CPU_DISASSEMBLE_NAME(hp_nanoprocessor) },
- { "nec", _8bit, 0, CPU_DISASSEMBLE_NAME(nec) },
- { "nsc8105", _8bit, 0, CPU_DISASSEMBLE_NAME(nsc8105) },
- { "pdp1", _32be, 0, CPU_DISASSEMBLE_NAME(pdp1) },
- { "pdp8", _16be, 0, CPU_DISASSEMBLE_NAME(pdp8) },
- { "pic16c5x", _16le, -1, CPU_DISASSEMBLE_NAME(pic16c5x) },
- { "pic16c62x", _16le, -1, CPU_DISASSEMBLE_NAME(pic16c62x) },
- { "powerpc", _32be, 0, CPU_DISASSEMBLE_NAME(powerpc) },
- { "pps4", _8bit, 0, CPU_DISASSEMBLE_NAME(pps4) },
- { "psxcpu", _32le, 0, CPU_DISASSEMBLE_NAME(psxcpu_generic) },
- { "r3000be", _32be, 0, CPU_DISASSEMBLE_NAME(r3000be) },
- { "r3000le", _32le, 0, CPU_DISASSEMBLE_NAME(r3000le) },
- { "rsp", _32le, 0, CPU_DISASSEMBLE_NAME(rsp) },
- { "s2650", _8bit, 0, CPU_DISASSEMBLE_NAME(s2650) },
- { "saturn", _8bit, 0, CPU_DISASSEMBLE_NAME(saturn) },
- { "sc61860", _8bit, 0, CPU_DISASSEMBLE_NAME(sc61860) },
- { "scmp", _8bit, 0, CPU_DISASSEMBLE_NAME(scmp) },
- { "scudsp", _32be, 0, CPU_DISASSEMBLE_NAME(scudsp) },
- { "se3208", _16le, 0, CPU_DISASSEMBLE_NAME(se3208) },
- { "sh2", _16be, 0, CPU_DISASSEMBLE_NAME(sh2) },
- { "sh4", _16le, 0, CPU_DISASSEMBLE_NAME(sh4) },
- { "sh4be", _16be, 0, CPU_DISASSEMBLE_NAME(sh4be) },
- { "sharc", _48le, -2, CPU_DISASSEMBLE_NAME(sharc) },
- { "sm500", _8bit, 0, CPU_DISASSEMBLE_NAME(sm500) },
- { "sm510", _8bit, 0, CPU_DISASSEMBLE_NAME(sm510) },
- { "sm511", _8bit, 0, CPU_DISASSEMBLE_NAME(sm511) },
- { "sm5a", _8bit, 0, CPU_DISASSEMBLE_NAME(sm5a) },
- { "sm8500", _8bit, 0, CPU_DISASSEMBLE_NAME(sm8500) },
- { "sparcv7", _32be, 0, CPU_DISASSEMBLE_NAME(sparcv7) },
- { "sparcv8", _32be, 0, CPU_DISASSEMBLE_NAME(sparcv8) },
- { "sparcv9", _32be, 0, CPU_DISASSEMBLE_NAME(sparcv9) },
- { "sparcv9vis1", _32be, 0, CPU_DISASSEMBLE_NAME(sparcv9vis1) },
- { "sparcv9vis2", _32be, 0, CPU_DISASSEMBLE_NAME(sparcv9vis2) },
- { "sparcv9vis2p",_32be, 0, CPU_DISASSEMBLE_NAME(sparcv9vis2p) },
- { "sparcv9vis3", _32be, 0, CPU_DISASSEMBLE_NAME(sparcv9vis3) },
- { "sparcv9vis3b",_32be, 0, CPU_DISASSEMBLE_NAME(sparcv9vis3b) },
- { "spc700", _8bit, 0, CPU_DISASSEMBLE_NAME(spc700) },
- { "ssem", _32le, 0, CPU_DISASSEMBLE_NAME(ssem) },
- { "ssp1601", _16be, -1, CPU_DISASSEMBLE_NAME(ssp1601) },
-// { "superfx", _8bit, 0, CPU_DISASSEMBLE_NAME(superfx) },
- { "t11", _16le, 0, CPU_DISASSEMBLE_NAME(t11) },
-// { "t90", _8bit, 0, CPU_DISASSEMBLE_NAME(t90) },
- { "tlcs900", _8bit, 0, CPU_DISASSEMBLE_NAME(tlcs900) },
- { "tms0980", _16be, 0, CPU_DISASSEMBLE_NAME(tms0980) },
- { "tms1000", _8bit, 0, CPU_DISASSEMBLE_NAME(tms1000) },
- { "tms1100", _8bit, 0, CPU_DISASSEMBLE_NAME(tms1100) },
- { "tms32010", _16be, -1, CPU_DISASSEMBLE_NAME(tms32010) },
- { "tms32025", _16be, -1, CPU_DISASSEMBLE_NAME(tms32025) },
- { "tms3203x", _32le, -2, CPU_DISASSEMBLE_NAME(tms3203x) },
- { "tms32051", _16le, -1, CPU_DISASSEMBLE_NAME(tms32051) },
- { "tms34010", _8bit, 3, CPU_DISASSEMBLE_NAME(tms34010) },
- { "tms34020", _8bit, 3, CPU_DISASSEMBLE_NAME(tms34020) },
- { "tms57002", _32le, -2, CPU_DISASSEMBLE_NAME(tms57002) },
- { "tms7000", _8bit, 0, CPU_DISASSEMBLE_NAME(tms7000) },
- { "tms9900", _16be, 0, CPU_DISASSEMBLE_NAME(tms9900) },
- { "tms9980", _8bit, 0, CPU_DISASSEMBLE_NAME(tms9980) },
- { "tms9995", _8bit, 0, CPU_DISASSEMBLE_NAME(tms9995) },
- { "tp0320", _16be, 0, CPU_DISASSEMBLE_NAME(tp0320) },
- { "tx0_64kw", _32be, -2, CPU_DISASSEMBLE_NAME(tx0_64kw) },
- { "tx0_8kw", _32be, -2, CPU_DISASSEMBLE_NAME(tx0_8kw) },
- { "ucom4", _8bit, 0, CPU_DISASSEMBLE_NAME(ucom4) },
- { "unsp", _16be, 0, CPU_DISASSEMBLE_NAME(unsp) },
- { "upd7725", _32be, 0, CPU_DISASSEMBLE_NAME(upd7725) },
- { "upd7801", _8bit, 0, CPU_DISASSEMBLE_NAME(upd7801) },
- { "upd7807", _8bit, 0, CPU_DISASSEMBLE_NAME(upd7807) },
- { "upd7810", _8bit, 0, CPU_DISASSEMBLE_NAME(upd7810) },
- { "upd78c05", _8bit, 0, CPU_DISASSEMBLE_NAME(upd78c05) },
- { "upi41", _8bit, 0, CPU_DISASSEMBLE_NAME(upi41) },
- { "v60", _8bit, 0, CPU_DISASSEMBLE_NAME(v60) },
- { "v70", _8bit, 0, CPU_DISASSEMBLE_NAME(v70) },
- { "v810", _16le, 0, CPU_DISASSEMBLE_NAME(v810) },
- { "x86_16", _8bit, 0, CPU_DISASSEMBLE_NAME(x86_16) },
- { "x86_32", _8bit, 0, CPU_DISASSEMBLE_NAME(x86_32) },
- { "x86_64", _8bit, 0, CPU_DISASSEMBLE_NAME(x86_64) },
- { "z180", _8bit, 0, CPU_DISASSEMBLE_NAME(z180) },
- { "z8", _8bit, 0, CPU_DISASSEMBLE_NAME(z8) },
- { "z80", _8bit, 0, CPU_DISASSEMBLE_NAME(z80) },
-// { "z8000", _16be, 0, CPU_DISASSEMBLE_NAME(z8000) },
+ offs_t pc;
+ offs_t size;
+ std::string dasm;
};
+unidasm_data_buffer::unidasm_data_buffer(util::disasm_interface *_disasm, const dasm_table_entry *_entry) : disasm(_disasm), entry(_entry)
+{
+ u32 flags = disasm->interface_flags();
+ u32 page_mask = flags & util::disasm_interface::PAGED ? (1 << disasm->page_address_bits()) - 1 : 0;
+
+ if(flags & util::disasm_interface::NONLINEAR_PC) {
+ switch(entry->pcshift) {
+ case -1:
+ lr8 = [](offs_t pc) -> u8 { throw emu_fatalerror("debug_disasm_buffer::debug_data_buffer: r8 access on 16-bits granularity bus\n"); };
+ lr16 = [this](offs_t pc) -> u16 {
+ const u16 *src = get_ptr<u16>(pc);
+ return src[0];
+ };
+
+ switch(entry->endian) {
+ case le:
+ lr32 = [this, page_mask](offs_t pc) -> u32 {
+ offs_t lpc = disasm->pc_real_to_linear(pc);
+ u32 r = 0;
+ for(int j=0; j != 2; j++) {
+ r |= get<u16>(disasm->pc_linear_to_real(lpc)) << (j*16);
+ lpc = (lpc & ~page_mask) | ((lpc + 1) & page_mask);
+ }
+ return r;
+ };
+ lr64 = [this, page_mask](offs_t pc) -> u64 {
+ offs_t lpc = disasm->pc_real_to_linear(pc);
+ u64 r = 0;
+ for(int j=0; j != 4; j++) {
+ r |= u64(get<u16>(disasm->pc_linear_to_real(lpc))) << (j*16);
+ lpc = (lpc & ~page_mask) | ((lpc + 1) & page_mask);
+ }
+ return r;
+ };
+ break;
+
+ case be:
+ lr32 = [this, page_mask](offs_t pc) -> u32 {
+ offs_t lpc = disasm->pc_real_to_linear(pc);
+ u32 r = 0;
+ for(int j=0; j != 2; j++) {
+ r |= get<u16>(disasm->pc_linear_to_real(lpc)) << ((1-j)*16);
+ lpc = (lpc & ~page_mask) | ((lpc + 1) & page_mask);
+ }
+ return r;
+ };
+ lr64 = [this, page_mask](offs_t pc) -> u64 {
+ offs_t lpc = disasm->pc_real_to_linear(pc);
+ u64 r = 0;
+ for(int j=0; j != 4; j++) {
+ r |= u64(get<u16>(disasm->pc_linear_to_real(lpc))) << ((3-j)*16);
+ lpc = (lpc & ~page_mask) | ((lpc + 1) & page_mask);
+ }
+ return r;
+ };
+ break;
+ }
+ break;
+
+ case 0:
+ lr8 = [this](offs_t pc) -> u8 {
+ const u8 *src = get_ptr<u8>(pc);
+ return src[0];
+ };
+
+ switch(entry->endian) {
+ case le:
+ lr16 = [this, page_mask](offs_t pc) -> u16 {
+ offs_t lpc = disasm->pc_real_to_linear(pc);
+ u16 r = 0;
+ for(int j=0; j != 2; j++) {
+ r |= get<u8>(disasm->pc_linear_to_real(lpc)) << (j*8);
+ lpc = (lpc & ~page_mask) | ((lpc + 1) & page_mask);
+ }
+ return r;
+ };
+ lr32 = [this, page_mask](offs_t pc) -> u32 {
+ offs_t lpc = disasm->pc_real_to_linear(pc);
+ u32 r = 0;
+ for(int j=0; j != 2; j++) {
+ r |= get<u8>(disasm->pc_linear_to_real(lpc)) << (j*8);
+ lpc = (lpc & ~page_mask) | ((lpc + 1) & page_mask);
+ }
+ return r;
+ };
+ lr64 = [this, page_mask](offs_t pc) -> u64 {
+ offs_t lpc = disasm->pc_real_to_linear(pc);
+ u64 r = 0;
+ for(int j=0; j != 8; j++) {
+ r |= u64(get<u8>(disasm->pc_linear_to_real(lpc))) << (j*8);
+ lpc = (lpc & ~page_mask) | ((lpc + 1) & page_mask);
+ }
+ return r;
+ };
+ break;
+
+ case be:
+ lr16 = [this, page_mask](offs_t pc) -> u16 {
+ offs_t lpc = disasm->pc_real_to_linear(pc);
+ u16 r = 0;
+ for(int j=0; j != 2; j++) {
+ r |= get<u8>(disasm->pc_linear_to_real(lpc)) << ((1-j)*8);
+ lpc = (lpc & ~page_mask) | ((lpc + 1) & page_mask);
+ }
+ return r;
+ };
+ lr32 = [this, page_mask](offs_t pc) -> u32 {
+ offs_t lpc = disasm->pc_real_to_linear(pc);
+ u32 r = 0;
+ for(int j=0; j != 2; j++) {
+ r |= get<u8>(disasm->pc_linear_to_real(lpc)) << ((3-j)*8);
+ lpc = (lpc & ~page_mask) | ((lpc + 1) & page_mask);
+ }
+ return r;
+ };
+ lr64 = [this, page_mask](offs_t pc) -> u64 {
+ offs_t lpc = disasm->pc_real_to_linear(pc);
+ u64 r = 0;
+ for(int j=0; j != 8; j++) {
+ r |= u64(get<u8>(disasm->pc_linear_to_real(lpc))) << ((7-j)*8);
+ lpc = (lpc & ~page_mask) | ((lpc + 1) & page_mask);
+ }
+ return r;
+ };
+ break;
+ }
+ break;
+ }
+ } else {
+ switch(entry->pcshift) {
+ case 0:
+ lr8 = [this](offs_t pc) -> u8 {
+ const u8 *p = get_ptr<u8>(pc);
+ return p ?
+ p[0]
+ : 0x00;
+ };
+ switch(entry->endian) {
+ case le:
+ lr16 = [this](offs_t pc) -> u16 {
+ const u8 *p = get_ptr<u8>(pc);
+ return p ?
+ p[0] |
+ (p[1] << 8)
+ : 0x0000;
+ };
+ lr32 = [this](offs_t pc) -> u32 {
+ const u8 *p = get_ptr<u8>(pc);
+ return p ?
+ p[0] |
+ (p[1] << 8) |
+ (p[2] << 16) |
+ (p[3] << 24)
+ : 0x00000000;
+ };
+ lr64 = [this](offs_t pc) -> u64 {
+ const u8 *p = get_ptr<u8>(pc);
+ return p ?
+ p[0] |
+ (p[1] << 8) |
+ (p[2] << 16) |
+ (p[3] << 24) |
+ (u64(p[4]) << 32) |
+ (u64(p[5]) << 40) |
+ (u64(p[6]) << 48) |
+ (u64(p[7]) << 56)
+ : 0x0000000000000000; };
+ break;
+ case be:
+ lr16 = [this](offs_t pc) -> u16 {
+ const u8 *p = get_ptr<u8>(pc);
+ return p ?
+ (p[0] << 8) |
+ p[1]
+ : 0x0000;
+ };
+ lr32 = [this](offs_t pc) -> u32 {
+ const u8 *p = get_ptr<u8>(pc);
+ return p ?
+ (p[0] << 24) |
+ (p[1] << 16) |
+ (p[2] << 8) |
+ p[3]
+ : 0x00000000;
+ };
+ lr64 = [this](offs_t pc) -> u64 {
+ const u8 *p = get_ptr<u8>(pc);
+ return p ?
+ (u64(p[0]) << 56) |
+ (u64(p[1]) << 48) |
+ (u64(p[2]) << 40) |
+ (u64(p[3]) << 32) |
+ (p[4] << 24) |
+ (p[5] << 16) |
+ (p[6] << 8) |
+ p[7]
+ : 0x0000000000000000; };
+ break;
+ }
+ break;
+
+ case -1:
+ lr8 = [this](offs_t pc) -> u8 { abort(); };
+ lr16 = [this](offs_t pc) -> u16 {
+ const u16 *p = get_ptr<u16>(pc);
+ return p ?
+ p[0]
+ : 0x0000;
+ };
+ switch(entry->endian) {
+ case le:
+ lr32 = [this](offs_t pc) -> u32 {
+ const u16 *p = get_ptr<u16>(pc);
+ return p ?
+ p[0] |
+ (p[1] << 16)
+ : 0x00000000;
+ };
+ lr64 = [this](offs_t pc) -> u64 {
+ const u16 *p = get_ptr<u16>(pc);
+ return p ?
+ p[0] |
+ (p[1] << 16) |
+ (u64(p[2]) << 32) |
+ (u64(p[3]) << 48)
+ : 0x0000000000000000;
+ };
+ break;
+ case be:
+ lr32 = [this](offs_t pc) -> u32 {
+ const u16 *p = get_ptr<u16>(pc);
+ return p ?
+ (p[0] << 16)|
+ p[1]
+ : 0x00000000;
+ };
+ lr64 = [this](offs_t pc) -> u64 {
+ const u16 *p = get_ptr<u16>(pc);
+ return p ?
+ (u64(p[0]) << 48) |
+ (u64(p[1]) << 32) |
+ (p[2] << 16) |
+ p[3]
+ : 0x0000000000000000;
+ };
+ break;
+ }
+ break;
+
+ case -2:
+ lr8 = [this](offs_t pc) -> u8 { abort(); };
+ lr16 = [this](offs_t pc) -> u16 { abort(); };
+ lr32 = [this](offs_t pc) -> u16 {
+ const u32 *p = get_ptr<u32>(pc);
+ return p ?
+ p[0]
+ : 0x00000000;
+ };
+ switch(entry->endian) {
+ case le:
+ lr64 = [this](offs_t pc) -> u64 {
+ const u32 *p = get_ptr<u32>(pc);
+ return p ?
+ p[0] |
+ (u64(p[1]) << 32)
+ : 0x0000000000000000;
+ };
+ break;
+ case be:
+ lr64 = [this](offs_t pc) -> u64 {
+ const u32 *p = get_ptr<u32>(pc);
+ return p ?
+ (u64(p[0]) << 32) |
+ p[1]
+ : 0x0000000000000000;
+ };
+ break;
+ }
+ break;
+
+ case -3:
+ lr8 = [this](offs_t pc) -> u8 { abort(); };
+ lr16 = [this](offs_t pc) -> u16 { abort(); };
+ lr32 = [this](offs_t pc) -> u32 { abort(); };
+ lr64 = [this](offs_t pc) -> u64 {
+ const u64 *p = get_ptr<u64>(pc);
+ return p ?
+ p[0]
+ : 0x0000000000000000;
+ };
+ break;
+
+ case 3:
+ assert(entry->endian == );
+ lr8 = [this](offs_t pc) -> u8 { abort(); };
+ lr32 = [this](offs_t pc) -> u32 { abort(); };
+ lr64 = [this](offs_t pc) -> u64 { abort(); };
+ lr16 = [this](offs_t pc) -> u16 {
+ if(pc < base_pc)
+ return 0x0000;
+ offs_t delta = (pc - base_pc) >> 3;
+ if(delta >= size)
+ return 0x0000;
+ return reinterpret_cast<const u16 *>(&data[delta])[0];
+ };
+ break;
+
+ default:
+ abort();
+ }
+ }
+}
+
+void unidasm_data_buffer::decrypt(const unidasm_data_buffer &buffer, bool opcode)
+{
+ abort();
+}
static int parse_options(int argc, char *argv[], options *opts)
{
@@ -420,92 +837,87 @@ static int parse_options(int argc, char *argv[], options *opts)
memset(opts, 0, sizeof(*opts));
// loop through arguments
- for (unsigned arg = 1; arg < argc; arg++)
- {
+ for(unsigned arg = 1; arg < argc; arg++) {
char *curarg = argv[arg];
// is it a switch?
- if (curarg[0] == '-')
- {
- if (pending_base || pending_arch || pending_mode || pending_skip || pending_count)
+ if(curarg[0] == '-') {
+ if(pending_base || pending_arch || pending_mode || pending_skip || pending_count)
goto usage;
- if (tolower((uint8_t)curarg[1]) == 'a')
+ if(tolower((uint8_t)curarg[1]) == 'a')
pending_arch = true;
- else if (tolower((uint8_t)curarg[1]) == 'b')
+ else if(tolower((uint8_t)curarg[1]) == 'b')
pending_base = true;
- else if (tolower((uint8_t)curarg[1]) == 'f')
+ else if(tolower((uint8_t)curarg[1]) == 'f')
opts->flipped = true;
- else if (tolower((uint8_t)curarg[1]) == 'l')
+ else if(tolower((uint8_t)curarg[1]) == 'l')
opts->lower = true;
- else if (tolower((uint8_t)curarg[1]) == 'm')
+ else if(tolower((uint8_t)curarg[1]) == 'm')
pending_mode = true;
- else if (tolower((uint8_t)curarg[1]) == 's')
+ else if(tolower((uint8_t)curarg[1]) == 's')
pending_skip = true;
- else if (tolower((uint8_t)curarg[1]) == 'c')
+ else if(tolower((uint8_t)curarg[1]) == 'c')
pending_count = true;
- else if (tolower((uint8_t)curarg[1]) == 'n')
+ else if(tolower((uint8_t)curarg[1]) == 'n')
opts->norawbytes = true;
- else if (tolower((uint8_t)curarg[1]) == 'u')
+ else if(tolower((uint8_t)curarg[1]) == 'u')
opts->upper = true;
else
goto usage;
}
// base PC
- else if (pending_base)
+ else if(pending_base)
{
int result;
- if (curarg[0] == '0' && curarg[1] == 'x')
+ if(curarg[0] == '0' && curarg[1] == 'x')
result = sscanf(&curarg[2], "%x", &opts->basepc);
- else if (curarg[0] == '$')
+ else if(curarg[0] == '$')
result = sscanf(&curarg[1], "%x", &opts->basepc);
else
result = sscanf(&curarg[0], "%x", &opts->basepc);
- if (result != 1)
+ if(result != 1)
goto usage;
pending_base = false;
}
// mode
- else if (pending_mode)
+ else if(pending_mode)
{
- if (sscanf(curarg, "%d", &opts->mode) != 1)
+ if(sscanf(curarg, "%d", &opts->mode) != 1)
goto usage;
pending_mode = false;
}
// architecture
- else if (pending_arch)
- {
+ else if(pending_arch) {
int curarch;
- for (curarch = 0; curarch < ARRAY_LENGTH(dasm_table); curarch++)
- if (core_stricmp(curarg, dasm_table[curarch].name) == 0)
+ for(curarch = 0; curarch < ARRAY_LENGTH(dasm_table); curarch++)
+ if(core_stricmp(curarg, dasm_table[curarch].name) == 0)
break;
- if (curarch == ARRAY_LENGTH(dasm_table))
+ if(curarch == ARRAY_LENGTH(dasm_table))
goto usage;
opts->dasm = &dasm_table[curarch];
pending_arch = false;
}
// skip bytes
- else if (pending_skip)
- {
- if (sscanf(curarg, "%d", &opts->skip) != 1)
+ else if(pending_skip) {
+ if(sscanf(curarg, "%d", &opts->skip) != 1)
goto usage;
pending_skip = false;
}
// size
- else if (pending_count)
- {
- if (sscanf(curarg, "%d", &opts->count) != 1)
+ else if(pending_count) {
+ if(sscanf(curarg, "%d", &opts->count) != 1)
goto usage;
pending_count = false;
}
// filename
- else if (opts->filename == nullptr)
+ else if(opts->filename == nullptr)
opts->filename = curarg;
// fail
@@ -514,11 +926,11 @@ static int parse_options(int argc, char *argv[], options *opts)
}
// if we have a dangling option, error
- if (pending_base || pending_arch || pending_mode || pending_skip || pending_count)
+ if(pending_base || pending_arch || pending_mode || pending_skip || pending_count)
goto usage;
// if no file or no architecture, fail
- if (opts->filename == nullptr || opts->dasm == nullptr)
+ if(opts->filename == nullptr || opts->dasm == nullptr)
goto usage;
return 0;
@@ -531,12 +943,12 @@ usage:
const int colwidth = 1 + std::strlen(std::max_element(std::begin(dasm_table), std::end(dasm_table), [](const dasm_table_entry &a, const dasm_table_entry &b) { return std::strlen(a.name) < std::strlen(b.name); })->name);
const int columns = std::max(1, 80 / colwidth);
const int numrows = (ARRAY_LENGTH(dasm_table) + columns - 1) / columns;
- for (unsigned curarch = 0; curarch < numrows * columns; curarch++)
+ for(unsigned curarch = 0; curarch < numrows * columns; curarch++)
{
const int row = curarch / columns;
const int col = curarch % columns;
const int index = col * numrows + row;
- if (col == 0)
+ if(col == 0)
printf("\n ");
printf("%-*s", colwidth, (index < ARRAY_LENGTH(dasm_table)) ? dasm_table[index].name : "");
}
@@ -547,191 +959,311 @@ usage:
int main(int argc, char *argv[])
{
- osd_file::error filerr;
- int displayendian;
- int displaychunk;
- uint32_t curbyte;
- uint32_t length;
- int maxchunks;
- uint32_t curpc;
+ // Parse options first
options opts;
- int numbytes;
- void *data;
- int result = 0;
-
- // parse options first
- if (parse_options(argc, argv, &opts))
+ if(parse_options(argc, argv, &opts))
return 1;
- // load the file
- filerr = util::core_file::load(opts.filename, &data, length);
- if (filerr != osd_file::error::NONE)
+ // Load the file
+ void *data;
+ uint32_t length;
+ osd_file::error filerr = util::core_file::load(opts.filename, &data, length);
+ if(filerr != osd_file::error::NONE)
{
fprintf(stderr, "Error opening file '%s'\n", opts.filename);
return 1;
}
- // precompute parameters
- displaychunk = (opts.dasm->display / 2) + 1;
- displayendian = opts.dasm->display % 2;
- switch (displaychunk)
- {
- case 1: maxchunks = 6; break;
- case 2: maxchunks = 3; break;
- default: maxchunks = 1; break;
+ // Build the disasm object
+ std::unique_ptr<util::disasm_interface> disasm(opts.dasm->alloc());
+ u32 flags = disasm->interface_flags();
+
+ // Compute the granularity in bytes (1-8)
+ offs_t granularity = opts.dasm->pcshift < 0 ? disasm->opcode_alignment() << -opts.dasm->pcshift : disasm->opcode_alignment() >> opts.dasm->pcshift;
+
+ // Build the base buffer and fill it (with a margin)
+ unidasm_data_buffer base_buffer(disasm.get(), opts.dasm);
+ u32 rounded_size = (((length - opts.skip) | (granularity - 1)) & ~(granularity - 1));
+ base_buffer.data.resize(rounded_size + 8, 0x00);
+ base_buffer.size = length;
+ base_buffer.base_pc = opts.basepc;
+ memcpy(&base_buffer.data[0], (const u8 *)data + opts.skip, length - opts.skip);
+
+ // Build the decryption buffers if needed
+ unidasm_data_buffer opcodes_buffer(disasm.get(), opts.dasm), params_buffer(disasm.get(), opts.dasm);
+ if(flags & util::disasm_interface::INTERNAL_DECRYPTION) {
+ opcodes_buffer.decrypt(base_buffer, true);
+ if((flags & util::disasm_interface::SPLIT_DECRYPTION) == util::disasm_interface::SPLIT_DECRYPTION)
+ params_buffer.decrypt(base_buffer, false);
}
- // run it
- try
- {
- if (length > opts.skip)
- length = length - opts.skip;
- if ((length > opts.count) && (opts.count != 0))
- length = opts.count;
- curpc = opts.basepc;
-
- std::stringstream stream;
- for (curbyte = 0; curbyte < length; curbyte += numbytes)
- {
- uint8_t *oprom = (uint8_t *)data + opts.skip + curbyte;
- uint32_t pcdelta;
- int numchunks;
+ // Select the buffers to actually use
+ unidasm_data_buffer *popcodes = opcodes_buffer.data.empty() ? &base_buffer : &opcodes_buffer;
+ unidasm_data_buffer *pparams = params_buffer.data.empty() ? popcodes : &params_buffer;
- // disassemble
- stream.str("");
- pcdelta = (*opts.dasm->func)(nullptr, stream, curpc, oprom, oprom, opts.mode) & DASMFLAG_LENGTHMASK;
- std::string buffer = stream.str();
+ // Compute the pc warparound
+ offs_t pclength = opts.dasm->pcshift < 0 ? rounded_size >> -opts.dasm->pcshift : rounded_size << opts.dasm->pcshift;
+ offs_t limit = opts.basepc + pclength;
+ offs_t pc_mask;
+ if(!limit)
+ pc_mask = 0xffffffff;
+ else {
+ for(pc_mask = 2; pc_mask && pc_mask < limit; pc_mask *= 2);
+ pc_mask--;
+ }
- if (opts.dasm->pcshift < 0)
- numbytes = pcdelta << -opts.dasm->pcshift;
- else
- numbytes = pcdelta >> opts.dasm->pcshift;
-
- // force upper or lower
- if (opts.lower)
- {
- std::transform(
- std::begin(buffer),
- std::end(buffer),
- std::begin(buffer),
- [](char c) { return tolower(c); });
- }
- else if (opts.upper)
- {
- std::transform(
- std::begin(buffer),
- std::end(buffer),
- std::begin(buffer),
- [](char c) { return toupper(c); });
- }
+ // Compute the page warparound
+ offs_t page_mask = flags & util::disasm_interface::PAGED ? (1 << disasm->page_address_bits()) - 1 : 0;
- // round to the nearest display chunk
- numbytes = ((numbytes + displaychunk - 1) / displaychunk) * displaychunk;
- if (numbytes == 0)
- numbytes = displaychunk;
- numchunks = numbytes / displaychunk;
-
- // non-flipped case
- if (!opts.flipped)
- {
- // output the address
- printf("%08X: ", curpc);
-
- // output the raw bytes
- if (!opts.norawbytes)
- {
- int firstchunks = (numchunks < maxchunks) ? numchunks : maxchunks;
- int chunknum, bytenum;
- for (chunknum = 0; chunknum < firstchunks; chunknum++)
- {
- for (bytenum = 0; bytenum < displaychunk; bytenum++)
- printf("%02X", oprom[displayendian ? (displaychunk - 1 - bytenum) : bytenum]);
- printf(" ");
- oprom += displaychunk;
- }
- for ( ; chunknum < maxchunks; chunknum++)
- printf("%*s ", displaychunk * 2, "");
- printf(" ");
- }
-
- // output the disassembly
- printf("%s\n", buffer.c_str());
-
- // output additional raw bytes
- if (!opts.norawbytes && numchunks > maxchunks)
- {
- for (numchunks -= maxchunks; numchunks > 0; numchunks -= maxchunks)
- {
- int firstchunks = (numchunks < maxchunks) ? numchunks : maxchunks;
- int chunknum, bytenum;
- printf(" ");
- for (chunknum = 0; chunknum < firstchunks; chunknum++)
- {
- for (bytenum = 0; bytenum < displaychunk; bytenum++)
- printf("%02X", oprom[displayendian ? (displaychunk - 1 - bytenum) : bytenum]);
- printf(" ");
- oprom += displaychunk;
- }
- printf("\n");
- }
- }
- }
+ // Next pc computation lambdas
+ std::function<offs_t (offs_t, offs_t)> next_pc;
+ std::function<offs_t (offs_t, offs_t)> next_pc_wrap;
+ if(flags & util::disasm_interface::NONLINEAR_PC) {
+ // lfsr pc is always paged
+ next_pc = [pc_mask, page_mask, dis = disasm.get()](offs_t pc, offs_t size) {
+ offs_t lpc = dis->pc_real_to_linear(pc);
+ offs_t lpce = lpc + size;
+ if((lpc ^ lpce) & ~page_mask)
+ lpce = (lpc | page_mask) + 1;
+ lpce &= pc_mask;
+ return dis->pc_linear_to_real(lpce);
+ };
+ next_pc_wrap = [pc_mask, page_mask, dis = disasm.get()](offs_t pc, offs_t size) {
+ offs_t lpc = dis->pc_real_to_linear(pc);
+ offs_t lpce = (lpc & ~page_mask) | ((lpc + size) & page_mask);
+ return dis->pc_linear_to_real(lpce);
+ };
- // flipped case
- else
- {
- // output the disassembly and address
- printf("\t%-40s ; %08X", buffer.c_str(), curpc);
-
- // output the raw bytes
- if (!opts.norawbytes)
- {
- int chunknum, bytenum;
- printf(": ");
- for (chunknum = 0; chunknum < numchunks; chunknum++)
- {
- for (bytenum = 0; bytenum < displaychunk; bytenum++)
- printf("%02X", oprom[displayendian ? (displaychunk - 1 - bytenum) : bytenum]);
- printf(" ");
- oprom += displaychunk;
- }
- }
- printf("\n");
- }
+ } else if(flags & util::disasm_interface::PAGED) {
+ next_pc = [pc_mask, page_mask](offs_t pc, offs_t size) {
+ offs_t pce = pc + size;
+ if((pc ^ pce) & ~page_mask)
+ pce = (pc | page_mask) + 1;
+ pce &= pc_mask;
+ return pce;
+ };
+ next_pc_wrap = [pc_mask, page_mask](offs_t pc, offs_t size) {
+ offs_t pce = (pc & ~page_mask) | ((pc + size) & page_mask);
+ return pce;
+ };
- // advance
- curpc += pcdelta;
- }
+ } else {
+ next_pc = [pc_mask](offs_t pc, offs_t size) {
+ return (pc + size) & pc_mask;
+ };
+ next_pc_wrap = [pc_mask](offs_t pc, offs_t size) {
+ return (pc + size) & pc_mask;
+ };
}
- catch (emu_fatalerror &fatal)
- {
- fprintf(stderr, "%s\n", fatal.string());
- result = 1;
- if (fatal.exitcode() != 0)
- result = fatal.exitcode();
+
+ // Compute the shift amount from pc delta to granularity-sized elements
+ u32 granularity_shift = 31 - count_leading_zeros(disasm->opcode_alignment());
+
+ // Number of pc steps to disassemble
+ u32 count = pclength;
+
+ if((count > opts.count) && (opts.count != 0))
+ count = opts.count;
+
+ // pc to string conversion
+ std::function<std::string (offs_t pc)> pc_to_string;
+ int aw = 32 - count_leading_zeros(pc_mask);
+ bool is_octal = false; // Parameter? Per-cpu config?
+ if((flags & util::disasm_interface::PAGED2LEVEL) == util::disasm_interface::PAGED2LEVEL) {
+ int bits1 = disasm->page_address_bits();
+ int bits2 = disasm->page2_address_bits();
+ int bits3 = aw - bits1 - bits2;
+ offs_t sm1 = (1 << bits1) - 1;
+ int sh2 = bits1;
+ offs_t sm2 = (1 << bits2) - 1;
+ int sh3 = bits1+bits2;
+
+ if(is_octal) {
+ int nc1 = (bits1+2)/3;
+ int nc2 = (bits2+2)/3;
+ int nc3 = (bits3+2)/3;
+ pc_to_string = [nc1, nc2, nc3, sm1, sm2, sh2, sh3](offs_t pc) -> std::string {
+ return util::string_format("%0*o:%0*o:%0*o",
+ nc3, pc >> sh3,
+ nc2, (pc >> sh2) & sm2,
+ nc1, pc & sm1);
+ };
+ } else {
+ int nc1 = (bits1+3)/4;
+ int nc2 = (bits2+3)/4;
+ int nc3 = (bits3+3)/4;
+ pc_to_string = [nc1, nc2, nc3, sm1, sm2, sh2, sh3](offs_t pc) -> std::string {
+ return util::string_format("%0*x:%0*x:%0*x",
+ nc3, pc >> sh3,
+ nc2, (pc >> sh2) & sm2,
+ nc1, pc & sm1);
+ };
+ }
+
+ } else if(flags & util::disasm_interface::PAGED) {
+ int bits1 = disasm->page_address_bits();
+ int bits2 = aw - bits1;
+ offs_t sm1 = (1 << bits1) - 1;
+ int sh2 = bits1;
+
+ if(is_octal) {
+ int nc1 = (bits1+2)/3;
+ int nc2 = (bits2+2)/3;
+ pc_to_string = [nc1, nc2, sm1, sh2](offs_t pc) -> std::string {
+ return util::string_format("%0*o:%0*o",
+ nc2, pc >> sh2,
+ nc1, pc & sm1);
+ };
+ } else {
+ int nc1 = (bits1+3)/4;
+ int nc2 = (bits2+3)/4;
+ pc_to_string = [nc1, nc2, sm1, sh2](offs_t pc) -> std::string {
+ return util::string_format("%0*x:%0*x",
+ nc2, pc >> sh2,
+ nc1, pc & sm1);
+ };
+ }
+
+ } else {
+ int bits1 = aw;
+
+ if(is_octal) {
+ int nc1 = (bits1+2)/3;
+ pc_to_string = [nc1](offs_t pc) -> std::string {
+ return util::string_format("%0*o",
+ nc1, pc);
+ };
+ } else {
+ int nc1 = (bits1+3)/4;
+ pc_to_string = [nc1](offs_t pc) -> std::string {
+ return util::string_format("%0*x",
+ nc1, pc);
+ };
+ }
}
- catch (emu_exception &)
- {
- fprintf(stderr, "Caught unhandled emulator exception\n");
- result = 1;
+
+ // Lower/upper optional transform
+ std::function<std::string (const std::string &)> tf;
+ if(opts.lower)
+ tf = [](const std::string &str) -> std::string {
+ std::string result = str;
+ std::transform(result.begin(), result.end(), result.begin(), [](char c) { return tolower(c); });
+ return result;
+ };
+ else if(opts.upper)
+ tf = [](const std::string &str) -> std::string {
+ std::string result = str;
+ std::transform(result.begin(), result.end(), result.begin(), [](char c) { return toupper(c); });
+ return result;
+ };
+ else
+ tf = [](const std::string &str) -> std::string {
+ return str;
+ };
+
+
+ // Do the disassembly
+ std::vector<dasm_line> dasm_lines;
+ offs_t curpc = opts.basepc;
+ for(u32 i=0; i < count;) {
+ std::ostringstream stream;
+ offs_t result = disasm->disassemble(stream, curpc, *popcodes, *pparams);
+ offs_t len = result & util::disasm_interface::LENGTHMASK;
+ dasm_lines.emplace_back(dasm_line{ curpc, len, stream.str() });
+ curpc = next_pc(curpc, len);
+ i += len;
}
- catch (tag_add_exception &aex)
- {
- fprintf(stderr, "Tag '%s' already exists in tagged map\n", aex.tag());
- result = 1;
+
+ // Compute the extrema
+ offs_t max_len = 0;
+ size_t max_text = 0;
+ for(const auto &l : dasm_lines) {
+ if(max_len < l.size)
+ max_len = l.size;
+ size_t s = l.dasm.size();
+ if(max_text < s)
+ max_text = s;
}
- catch (std::exception &ex)
- {
- fprintf(stderr, "Caught unhandled %s exception: %s\n", typeid(ex).name(), ex.what());
- result = 1;
+
+ // Build the raw bytes generator and compute the field size
+ max_len >>= granularity_shift;
+ std::function<std::string (offs_t pc, offs_t size)> dump_raw_bytes;
+
+ switch(granularity) {
+ case 1:
+ dump_raw_bytes = [step = disasm->opcode_alignment(), next_pc, base_buffer](offs_t pc, offs_t size) -> std::string {
+ std::string result = "";
+ for(offs_t i=0; i != size; i++) {
+ if(i)
+ result += ' ';
+ result += util::string_format("%02x", base_buffer.r8(pc));
+ pc = next_pc(pc, step);
+ }
+ return result;
+ };
+ max_len = (max_len * 3) - 1;
+ break;
+
+ case 2:
+ dump_raw_bytes = [step = disasm->opcode_alignment(), next_pc, base_buffer](offs_t pc, offs_t size) -> std::string {
+ std::string result = "";
+ for(offs_t i=0; i != size; i++) {
+ if(i)
+ result += ' ';
+ result += util::string_format("%04x", base_buffer.r16(pc));
+ pc = next_pc(pc, step);
+ }
+ return result;
+ };
+ max_len = (max_len * 5) - 1;
+ break;
+
+ case 4:
+ dump_raw_bytes = [step = disasm->opcode_alignment(), next_pc, base_buffer](offs_t pc, offs_t size) -> std::string {
+ std::string result = "";
+ for(offs_t i=0; i != size; i++) {
+ if(i)
+ result += ' ';
+ result += util::string_format("%08x", base_buffer.r32(pc));
+ pc = next_pc(pc, step);
+ }
+ return result;
+ };
+ max_len = (max_len * 9) - 1;
+ break;
+
+ case 8:
+ dump_raw_bytes = [step = disasm->opcode_alignment(), next_pc, base_buffer](offs_t pc, offs_t size) -> std::string {
+ std::string result = "";
+ for(offs_t i=0; i != size; i++) {
+ if(i)
+ result += ' ';
+ result += util::string_format("%016x", base_buffer.r64(pc));
+ pc = next_pc(pc, step);
+ }
+ return result;
+ };
+ max_len = (max_len * 17) - 1;
+ break;
}
- catch (...)
- {
- fprintf(stderr, "Caught unhandled exception\n");
- result = 1;
+
+ if(opts.flipped) {
+ if(opts.norawbytes)
+ for(const auto &l : dasm_lines)
+ util::stream_format(std::cout, "%-*s ; %s\n", max_text, tf(l.dasm), tf(pc_to_string(l.pc)));
+ else
+ for(const auto &l : dasm_lines)
+ util::stream_format(std::cout, "%-*s ; %s: %s\n", max_text, tf(l.dasm), tf(pc_to_string(l.pc)), tf(dump_raw_bytes(l.pc, l.size >> granularity_shift)));
+ } else {
+ if(opts.norawbytes)
+ for(const auto &l : dasm_lines)
+ util::stream_format(std::cout, "%s: %s\n", tf(pc_to_string(l.pc)), tf(l.dasm));
+ else
+ for(const auto &l : dasm_lines)
+ util::stream_format(std::cout, "%s: %-*s %s\n", tf(pc_to_string(l.pc)), max_len, tf(dump_raw_bytes(l.pc, l.size >> granularity_shift)), tf(l.dasm));
}
free(data);
- return result;
+ return 0;
}