diff options
author | 2017-07-05 11:44:49 +0200 | |
---|---|---|
committer | 2017-11-26 17:41:27 +0100 | |
commit | 6caef2579a1490f05d28bcede731cbdd45fc5c65 (patch) | |
tree | 8055384e183be3cb27e7d0894ac53dc96c09e6fa /src/devices/cpu/tms32082 | |
parent | 34b222062c89adbeed822f56be6130421777e11f (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/devices/cpu/tms32082')
-rw-r--r-- | src/devices/cpu/tms32082/dis_mp.cpp | 173 | ||||
-rw-r--r-- | src/devices/cpu/tms32082/dis_mp.h | 35 | ||||
-rw-r--r-- | src/devices/cpu/tms32082/dis_pp.cpp | 135 | ||||
-rw-r--r-- | src/devices/cpu/tms32082/dis_pp.h | 33 | ||||
-rw-r--r-- | src/devices/cpu/tms32082/tms32082.cpp | 16 | ||||
-rw-r--r-- | src/devices/cpu/tms32082/tms32082.h | 8 |
6 files changed, 218 insertions, 182 deletions
diff --git a/src/devices/cpu/tms32082/dis_mp.cpp b/src/devices/cpu/tms32082/dis_mp.cpp index 0bb6e45d2c5..75c63543256 100644 --- a/src/devices/cpu/tms32082/dis_mp.cpp +++ b/src/devices/cpu/tms32082/dis_mp.cpp @@ -3,12 +3,12 @@ // TMS32082 MP Disassembler #include "emu.h" - +#include "dis_mp.h" #define SIMM15(v) (int32_t)((v & 0x4000) ? (v | 0xffffe000) : (v)) #define UIMM15(v) (v) -static const char *BCND_CONDITION[32] = +const char *tms32082_mp_disassembler::BCND_CONDITION[32] = { "nev.b", "gt0.b", "eq0.b", "ge0.b", "lt0.b", "ne0.b", "le0.b", "alw.b", "nev.h", "gt0.h", "eq0.h", "ge0.h", "lt0.h", "ne0.h", "le0.h", "alw.h", @@ -16,7 +16,7 @@ static const char *BCND_CONDITION[32] = "nev.d", "gt0.d", "eq0.d", "ge0.d", "lt0.d", "ne0.d", "le0.d", "alw.d", }; -static const char *BITNUM_CONDITION[32] = +const char *tms32082_mp_disassembler::BITNUM_CONDITION[32] = { "eq.b", "ne.b", "gt.b", "le.b", "lt.b", "ge.b", "hi.b", "ls.b", "lo.b", "hs.b", "eq.h", "ne.h", "gt.h", "le.h", "lt.h", "ge.h", @@ -24,87 +24,75 @@ static const char *BITNUM_CONDITION[32] = "lt.w", "ge.w", "hi.w", "ls.w", "lo.w", "hs.w", "?", "?", }; -static const char *MEMOP_S[2] = +const char *tms32082_mp_disassembler::MEMOP_S[2] = { ":s", "" }; -static const char *MEMOP_M[2] = +const char *tms32082_mp_disassembler::MEMOP_M[2] = { ":m", "" }; -static const char *FLOATOP_PRECISION[4] = +const char *tms32082_mp_disassembler::FLOATOP_PRECISION[4] = { "s", "d", "i", "u" }; -static const char *ACC_SEL[4] = +const char *tms32082_mp_disassembler::ACC_SEL[4] = { "A0", "A1", "A2", "A3" }; -static const char *FLOATOP_ROUND[4] = +const char *tms32082_mp_disassembler::FLOATOP_ROUND[4] = { "n", "z", "p", "m" }; -static std::ostream *output; -static const uint8_t *opdata; -static int opbytes; - -static uint32_t fetch(void) +uint32_t tms32082_mp_disassembler::fetch(offs_t &pos, const data_buffer &opcodes) { - uint32_t d = ((uint32_t)(opdata[0]) << 24) | ((uint32_t)(opdata[1]) << 16) | ((uint32_t)(opdata[2]) << 8) | opdata[3]; - opdata += 4; - opbytes += 4; + uint32_t d = opcodes.r32(pos); + pos += 4; return d; } -static char* get_creg_name(uint32_t reg) +std::string tms32082_mp_disassembler::get_creg_name(uint32_t reg) { - static char buffer[64]; - switch (reg) { - case 0x0000: sprintf(buffer, "EPC"); break; - case 0x0001: sprintf(buffer, "EIP"); break; - case 0x0002: sprintf(buffer, "CONFIG"); break; - case 0x0004: sprintf(buffer, "INTPEN"); break; - case 0x0006: sprintf(buffer, "IE"); break; - case 0x0008: sprintf(buffer, "FPST"); break; - case 0x000a: sprintf(buffer, "PPERROR"); break; - case 0x000d: sprintf(buffer, "PKTREQ"); break; - case 0x000e: sprintf(buffer, "TCOUNT"); break; - case 0x000f: sprintf(buffer, "TSCALE"); break; - case 0x0010: sprintf(buffer, "FLTOP"); break; - case 0x0011: sprintf(buffer, "FLTADR"); break; - case 0x0012: sprintf(buffer, "FLTTAG"); break; - case 0x0013: sprintf(buffer, "FLTDTL"); break; - case 0x0014: sprintf(buffer, "FLTDTH"); break; - case 0x0020: sprintf(buffer, "SYSSTK"); break; - case 0x0021: sprintf(buffer, "SYSTMP"); break; - case 0x0030: sprintf(buffer, "MPC"); break; - case 0x0031: sprintf(buffer, "MIP"); break; - case 0x0033: sprintf(buffer, "ECOMCNTL"); break; - case 0x0034: sprintf(buffer, "ANASTAT"); break; - case 0x0039: sprintf(buffer, "BRK1"); break; - case 0x003a: sprintf(buffer, "BRK2"); break; - case 0x4000: sprintf(buffer, "IN0P"); break; - case 0x4001: sprintf(buffer, "IN1P"); break; - case 0x4002: sprintf(buffer, "OUTP"); break; - default: sprintf(buffer, "CR %04X", reg); + case 0x0000: return "EPC"; + case 0x0001: return "EIP"; + case 0x0002: return "CONFIG"; + case 0x0004: return "INTPEN"; + case 0x0006: return "IE"; + case 0x0008: return "FPST"; + case 0x000a: return "PPERROR"; + case 0x000d: return "PKTREQ"; + case 0x000e: return "TCOUNT"; + case 0x000f: return "TSCALE"; + case 0x0010: return "FLTOP"; + case 0x0011: return "FLTADR"; + case 0x0012: return "FLTTAG"; + case 0x0013: return "FLTDTL"; + case 0x0014: return "FLTDTH"; + case 0x0020: return "SYSSTK"; + case 0x0021: return "SYSTMP"; + case 0x0030: return "MPC"; + case 0x0031: return "MIP"; + case 0x0033: return "ECOMCNTL"; + case 0x0034: return "ANASTAT"; + case 0x0039: return "BRK1"; + case 0x003a: return "BRK2"; + case 0x4000: return "IN0P"; + case 0x4001: return "IN1P"; + case 0x4002: return "OUTP"; + default: return util::string_format("CR %04X", reg); } - - return buffer; } -static char* format_vector_op(uint32_t op, uint32_t imm32) +std::string tms32082_mp_disassembler::format_vector_op(uint32_t op, uint32_t imm32) { - static char buffer[256]; - static char dest[64]; - char *b = buffer; - + std::string result; int rd = (op >> 27) & 0x1f; int rs = (op >> 22) & 0x1f; int src1 = (op & 0x1f); @@ -121,85 +109,87 @@ static char* format_vector_op(uint32_t op, uint32_t imm32) bool regdest = (op & (1 << 10)) == 0 && (op & (1 << 6)) == 0; // accumulator or register destination - if (regdest) - sprintf(dest, "R%d", rd); - else - sprintf(dest, "A%d", acc); + std::string dest = regdest ? util::string_format("R%d", rd) : util::string_format("A%d", acc); // base op switch (subop) { - case 0xc0: b += sprintf(b, "vadd.%s%s R%d, R%d, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd2], src1, rs, rs); break; - case 0xc1: b += sprintf(b, "vadd.%s%s 0x%08X, R%d, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd2], imm32, rs, rs); break; - case 0xc2: b += sprintf(b, "vsub.%s%s R%d, R%d, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd2], rs, src1, rs); break; - case 0xc3: b += sprintf(b, "vsub.%s%s R%d, 0x%08X, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd2], rs, imm32, rs); break; - case 0xc4: b += sprintf(b, "vmpy.%s%s R%d, R%d, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd2], src1, rs, rs); break; - case 0xc5: b += sprintf(b, "vmpy.%s%s 0x%08X, R%d, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd2], imm32, rs, rs); break; + case 0xc0: result += util::string_format("vadd.%s%s R%d, R%d, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd2], src1, rs, rs); break; + case 0xc1: result += util::string_format("vadd.%s%s 0x%08X, R%d, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd2], imm32, rs, rs); break; + case 0xc2: result += util::string_format("vsub.%s%s R%d, R%d, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd2], rs, src1, rs); break; + case 0xc3: result += util::string_format("vsub.%s%s R%d, 0x%08X, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd2], rs, imm32, rs); break; + case 0xc4: result += util::string_format("vmpy.%s%s R%d, R%d, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd2], src1, rs, rs); break; + case 0xc5: result += util::string_format("vmpy.%s%s 0x%08X, R%d, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd2], imm32, rs, rs); break; case 0xd6: case 0xc6: - b += sprintf(b, "vmsub.s%s R%d, %s, R%d", FLOATOP_PRECISION[pd2], src1, z ? "0" : ACC_SEL[acc], rs); + result += util::string_format("vmsub.s%s R%d, %s, R%d", FLOATOP_PRECISION[pd2], src1, z ? "0" : ACC_SEL[acc], rs); break; case 0xd7: case 0xc7: - b += sprintf(b, "vmsub.s%s 0x%08X, %s, R%d", FLOATOP_PRECISION[pd2], imm32, z ? "0" : ACC_SEL[acc], rs); + result += util::string_format("vmsub.s%s 0x%08X, %s, R%d", FLOATOP_PRECISION[pd2], imm32, z ? "0" : ACC_SEL[acc], rs); break; case 0xd8: case 0xc8: - b += sprintf(b, "vrnd.%s%s R%d, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd4], src1, rs); + result += util::string_format("vrnd.%s%s R%d, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd4], src1, rs); break; case 0xd9: case 0xc9: - b += sprintf(b, "vrnd.%s%s 0x%08X, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd4], imm32, rs); + result += util::string_format("vrnd.%s%s 0x%08X, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd4], imm32, rs); break; - case 0xca: b += sprintf(b, "vrnd.%s%s R%d, R%d", FLOATOP_PRECISION[2 + p1], FLOATOP_PRECISION[pd2],src1, rs); break; - case 0xcb: b += sprintf(b, "vrnd.%s%s 0x%08X, R%d", FLOATOP_PRECISION[2 + p1], FLOATOP_PRECISION[pd2], imm32, rs); break; + case 0xca: result += util::string_format("vrnd.%s%s R%d, R%d", FLOATOP_PRECISION[2 + p1], FLOATOP_PRECISION[pd2],src1, rs); break; + case 0xcb: result += util::string_format("vrnd.%s%s 0x%08X, R%d", FLOATOP_PRECISION[2 + p1], FLOATOP_PRECISION[pd2], imm32, rs); break; case 0xcc: case 0xdc: - b += sprintf(b, "vmac.ss%s R%d, R%d, %s, %s", FLOATOP_PRECISION[(op >> 9) & 1], src1, rs, z ? "0" : ACC_SEL[acc], (regdest && rd == 0) ? ACC_SEL[acc] : dest); + result += util::string_format("vmac.ss%s R%d, R%d, %s, %s", FLOATOP_PRECISION[(op >> 9) & 1], src1, rs, z ? "0" : ACC_SEL[acc], (regdest && rd == 0) ? ACC_SEL[acc] : dest); break; case 0xcd: case 0xdd: - b += sprintf(b, "vmac.ss%s 0x%08X, R%d, %s, %s", FLOATOP_PRECISION[(op >> 9) & 1], imm32, rs, z ? "0" : ACC_SEL[acc], (regdest && rd == 0) ? ACC_SEL[acc] : dest); + result += util::string_format("vmac.ss%s 0x%08X, R%d, %s, %s", FLOATOP_PRECISION[(op >> 9) & 1], imm32, rs, z ? "0" : ACC_SEL[acc], (regdest && rd == 0) ? ACC_SEL[acc] : dest); break; case 0xce: case 0xde: - b += sprintf(b, "vmsc.ss%s R%d, R%d, %s, %s", FLOATOP_PRECISION[(op >> 9) & 1], src1, rs, z ? "0" : ACC_SEL[acc], (regdest && rd == 0) ? ACC_SEL[acc] : dest); + result += util::string_format("vmsc.ss%s R%d, R%d, %s, %s", FLOATOP_PRECISION[(op >> 9) & 1], src1, rs, z ? "0" : ACC_SEL[acc], (regdest && rd == 0) ? ACC_SEL[acc] : dest); break; case 0xcf: case 0xdf: - b += sprintf(b, "vmsc.ss%s 0x%08X, R%d, %s, %s", FLOATOP_PRECISION[(op >> 9) & 1], imm32, rs, z ? "0" : ACC_SEL[acc], (regdest && rd == 0) ? ACC_SEL[acc] : dest); + result += util::string_format("vmsc.ss%s 0x%08X, R%d, %s, %s", FLOATOP_PRECISION[(op >> 9) & 1], imm32, rs, z ? "0" : ACC_SEL[acc], (regdest && rd == 0) ? ACC_SEL[acc] : dest); break; - default: b += sprintf(b, "?"); break; + default: result += '?'; break; } // align the line end - int len = strlen(buffer); + int len = result.size(); if (len < 30) { for (int i=0; i < (30-len); i++) { - b += sprintf(b, " "); + result += ' '; } } // optional load/store op switch (vector_ls_bits) { - case 0x01: b += sprintf(b, "|| vst.s R%d", rd); break; - case 0x03: b += sprintf(b, "|| vst.d R%d", rd); break; - case 0x04: b += sprintf(b, "|| vld0.s R%d", rd); break; - case 0x05: b += sprintf(b, "|| vld1.s R%d", rd); break; - case 0x06: b += sprintf(b, "|| vld0.d R%d", rd); break; - case 0x07: b += sprintf(b, "|| vld1.d R%d", rd); break; + case 0x01: result += util::string_format("|| vst.s R%d", rd); break; + case 0x03: result += util::string_format("|| vst.d R%d", rd); break; + case 0x04: result += util::string_format("|| vld0.s R%d", rd); break; + case 0x05: result += util::string_format("|| vld1.s R%d", rd); break; + case 0x06: result += util::string_format("|| vld0.d R%d", rd); break; + case 0x07: result += util::string_format("|| vld1.d R%d", rd); break; } - return buffer; + return result; +} + + +u32 tms32082_mp_disassembler::opcode_alignment() const +{ + return 4; } -static offs_t tms32082_disasm_mp(std::ostream &stream, offs_t pc, const uint8_t *oprom) +offs_t tms32082_mp_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { output = &stream; - opdata = oprom; - opbytes = 0; + offs_t pos = pc; uint32_t flags = 0; - uint32_t op = fetch(); + uint32_t op = fetch(pos, opcodes); int rd = (op >> 27) & 0x1f; int link = rd; @@ -310,7 +300,7 @@ static offs_t tms32082_disasm_mp(std::ostream &stream, offs_t pc, const uint8_t uint32_t imm32 = 0; if (op & (1 << 12)) // fetch 32-bit immediate if needed - imm32 = fetch(); + imm32 = fetch(pos, opcodes); int m = op & (1 << 15) ? 0 : 1; int s = op & (1 << 11) ? 0 : 1; @@ -502,10 +492,5 @@ static offs_t tms32082_disasm_mp(std::ostream &stream, offs_t pc, const uint8_t } } - return opbytes | flags | DASMFLAG_SUPPORTED; -} - -CPU_DISASSEMBLE(tms32082_mp) -{ - return tms32082_disasm_mp(stream, pc, oprom); + return (pos - pc) | flags | SUPPORTED; } diff --git a/src/devices/cpu/tms32082/dis_mp.h b/src/devices/cpu/tms32082/dis_mp.h new file mode 100644 index 00000000000..8c3a0721c1a --- /dev/null +++ b/src/devices/cpu/tms32082/dis_mp.h @@ -0,0 +1,35 @@ +// license:BSD-3-Clause +// copyright-holders:Ville Linde +// TMS32082 MP Disassembler + +#ifndef MAME_CPU_TMS32082_DIS_MP_H +#define MAME_CPU_TMS32082_DIS_MP_H + +#pragma once + +class tms32082_mp_disassembler : public util::disasm_interface +{ +public: + tms32082_mp_disassembler() = default; + virtual ~tms32082_mp_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *BCND_CONDITION[32]; + static const char *BITNUM_CONDITION[32]; + static const char *MEMOP_S[2]; + static const char *MEMOP_M[2]; + static const char *FLOATOP_PRECISION[4]; + static const char *ACC_SEL[4]; + static const char *FLOATOP_ROUND[4]; + + std::ostream *output; + + uint32_t fetch(offs_t &pos, const data_buffer &opcodes); + std::string get_creg_name(uint32_t reg); + std::string format_vector_op(uint32_t op, uint32_t imm32); +}; + +#endif diff --git a/src/devices/cpu/tms32082/dis_pp.cpp b/src/devices/cpu/tms32082/dis_pp.cpp index b685ab54b4f..8a3a6475ba0 100644 --- a/src/devices/cpu/tms32082/dis_pp.cpp +++ b/src/devices/cpu/tms32082/dis_pp.cpp @@ -3,9 +3,9 @@ // TMS32082 PP Disassembler #include "emu.h" +#include "dis_pp.h" - -static const char *REG_NAMES[128] = +const char *tms32082_pp_disassembler::REG_NAMES[128] = { // 0 - 15 "a0", "a1", "a2", "a3", "a4", "???", "a6", "a7", @@ -33,7 +33,7 @@ static const char *REG_NAMES[128] = "???", "???", "???", "???", "tag0", "tag1", "tag2", "tag3" }; -static const char *CONDITION_CODES[16] = +const char *tms32082_pp_disassembler::CONDITION_CODES[16] = { "", "[p] ", "[ls] ", "[hi] ", "[lt] ", "[le] ", "[ge] ", "[gt] ", @@ -41,50 +41,40 @@ static const char *CONDITION_CODES[16] = "[v] ", "[nv] ", "[n] ", "[nn] " }; -static const char *TRANSFER_SIZE[4] = +const char *tms32082_pp_disassembler::TRANSFER_SIZE[4] = { "b:", "h:", "w:", "" }; - -static std::ostream *output; - -static char *format_address_mode(int mode, int areg, int s, int limx) +std::string tms32082_pp_disassembler::format_address_mode(int mode, int areg, int s, int limx) { - static char buffer[64]; - - memset(buffer, 0, sizeof(char)*64); - switch (mode) { - case 0x4: sprintf(buffer, "*(a%d++=x%d)", areg, limx); break; - case 0x5: sprintf(buffer, "*(a%d--=x%d)", areg, limx); break; - case 0x6: sprintf(buffer, "*(a%d++0x%04X)", areg, limx); break; - case 0x7: sprintf(buffer, "*(a%d--0x%04X)", areg, limx); break; - case 0x8: sprintf(buffer, "*(a%d+x%d)", areg, limx); break; - case 0x9: sprintf(buffer, "*(a%d-x%d)", areg, limx); break; - case 0xa: sprintf(buffer, "*(a%d+0x%04X)", areg, limx); break; - case 0xb: sprintf(buffer, "*(a%d-0x%04X)", areg, limx); break; - case 0xc: sprintf(buffer, "*(a%d+=x%d)", areg, limx); break; - case 0xd: sprintf(buffer, "*(a%d-=x%d)", areg, limx); break; - case 0xe: sprintf(buffer, "*(a%d+=0x%04X)", areg, limx); break; - case 0xf: sprintf(buffer, "*(a%d-=0x%04X)", areg, limx); break; + case 0x4: return util::string_format("*(a%d++=x%d)", areg, limx); + case 0x5: return util::string_format("*(a%d--=x%d)", areg, limx); + case 0x6: return util::string_format("*(a%d++0x%04X)", areg, limx); + case 0x7: return util::string_format("*(a%d--0x%04X)", areg, limx); + case 0x8: return util::string_format("*(a%d+x%d)", areg, limx); + case 0x9: return util::string_format("*(a%d-x%d)", areg, limx); + case 0xa: return util::string_format("*(a%d+0x%04X)", areg, limx); + case 0xb: return util::string_format("*(a%d-0x%04X)", areg, limx); + case 0xc: return util::string_format("*(a%d+=x%d)", areg, limx); + case 0xd: return util::string_format("*(a%d-=x%d)", areg, limx); + case 0xe: return util::string_format("*(a%d+=0x%04X)", areg, limx); + case 0xf: return util::string_format("*(a%d-=0x%04X)", areg, limx); } - return buffer; + return ""; } -static void format_transfer(uint64_t op) +void tms32082_pp_disassembler::format_transfer(uint64_t op) { - char buffer[128]; - char *b = buffer; + std::string buffer; int lmode = (op >> 35) & 0xf; int gmode = (op >> 13) & 0xf; bool is_nop = false; - memset(buffer, 0, sizeof(char)*128); - switch (lmode) { case 0x0: @@ -106,8 +96,8 @@ static void format_transfer(uint64_t op) int dreg = (dstbank << 3) | dst; int sreg = (srcbank << 3) | src; - b += sprintf(b, "%s", CONDITION_CODES[cond]); - b += sprintf(b, "%s = %s", REG_NAMES[dreg], REG_NAMES[sreg]); + buffer += util::string_format("%s", CONDITION_CODES[cond]); + buffer += util::string_format("%s = %s", REG_NAMES[dreg], REG_NAMES[sreg]); break; } case 0x01: // Format 8: Conditional DU ||Conditional Field Move @@ -122,8 +112,8 @@ static void format_transfer(uint64_t op) int dreg = (dstbank << 3) | dst; int sreg = (4 << 3) | src; - b += sprintf(b, "%s", CONDITION_CODES[cond]); - b += sprintf(b, "%s = [%s%d]%s", REG_NAMES[dreg], TRANSFER_SIZE[size], itm, REG_NAMES[sreg]); + buffer += util::string_format("%s", CONDITION_CODES[cond]); + buffer += util::string_format("%s = [%s%d]%s", REG_NAMES[dreg], TRANSFER_SIZE[size], itm, REG_NAMES[sreg]); break; } case 0x02: case 0x03: // Format 10: Conditional Non-D Data Unit @@ -142,8 +132,8 @@ static void format_transfer(uint64_t op) } else { - b += sprintf(b, "%s", CONDITION_CODES[cond]); - b += sprintf(b, "%s = %s", REG_NAMES[dreg], REG_NAMES[sreg]); + buffer += util::string_format("%s", CONDITION_CODES[cond]); + buffer += util::string_format("%s = %s", REG_NAMES[dreg], REG_NAMES[sreg]); } break; } @@ -161,14 +151,14 @@ static void format_transfer(uint64_t op) int greg = (bank << 3) | reg; - b += sprintf(b, "%s", CONDITION_CODES[cond]); + buffer += util::string_format("%s", CONDITION_CODES[cond]); switch (le) { - case 0: b += sprintf(b, "&%s%s = %s", TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, gimx), REG_NAMES[greg]); break; - case 1: b += sprintf(b, "%s = %s", REG_NAMES[greg], format_address_mode(gmode, ga, s, gimx)); break; - case 2: b += sprintf(b, "%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, gimx)); break; - case 3: b += sprintf(b, "%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, gimx)); break; + case 0: buffer += util::string_format("&%s%s = %s", TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, gimx), REG_NAMES[greg]); break; + case 1: buffer += util::string_format("%s = %s", REG_NAMES[greg], format_address_mode(gmode, ga, s, gimx)); break; + case 2: buffer += util::string_format("%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, gimx)); break; + case 3: buffer += util::string_format("%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, gimx)); break; } } else // Format 5: Global (Long Offset) @@ -190,10 +180,10 @@ static void format_transfer(uint64_t op) switch (le) { - case 0: b += sprintf(b, "&%s%s = %s", TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, offset), REG_NAMES[greg]); break; - case 1: b += sprintf(b, "%s = %s", REG_NAMES[greg], format_address_mode(gmode, ga, s, offset)); break; - case 2: b += sprintf(b, "%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, offset)); break; - case 3: b += sprintf(b, "%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, offset)); break; + case 0: buffer += util::string_format("&%s%s = %s", TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, offset), REG_NAMES[greg]); break; + case 1: buffer += util::string_format("%s = %s", REG_NAMES[greg], format_address_mode(gmode, ga, s, offset)); break; + case 2: buffer += util::string_format("%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, offset)); break; + case 3: buffer += util::string_format("%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, offset)); break; } } break; @@ -210,12 +200,12 @@ static void format_transfer(uint64_t op) { case 0x00: // Format 2: Move || Local { - b += sprintf(b, "move||local <TODO>"); + buffer += util::string_format("move||local <TODO>"); break; } case 0x01: // Format 3: Field Move || Local { - b += sprintf(b, "field move||local <TODO>"); + buffer += util::string_format("field move||local <TODO>"); break; } case 0x02: case 0x03: // Format 6: Non-D DU || Local @@ -231,10 +221,10 @@ static void format_transfer(uint64_t op) switch (le) { - case 0: b += sprintf(b, "&%s%s = %s", TRANSFER_SIZE[size], format_address_mode(lmode, la, s, limx), REG_NAMES[reg]); break; - case 1: b += sprintf(b, "%s = %s", REG_NAMES[reg], format_address_mode(lmode, la, s, limx)); break; - case 2: b += sprintf(b, "%s = &%s%s", REG_NAMES[reg], TRANSFER_SIZE[size], format_address_mode(lmode, la, s, limx)); break; - case 3: b += sprintf(b, "%s = &%s%s", REG_NAMES[reg], TRANSFER_SIZE[size], format_address_mode(lmode, la, s, limx)); break; + case 0: buffer += util::string_format("&%s%s = %s", TRANSFER_SIZE[size], format_address_mode(lmode, la, s, limx), REG_NAMES[reg]); break; + case 1: buffer += util::string_format("%s = %s", REG_NAMES[reg], format_address_mode(lmode, la, s, limx)); break; + case 2: buffer += util::string_format("%s = &%s%s", REG_NAMES[reg], TRANSFER_SIZE[size], format_address_mode(lmode, la, s, limx)); break; + case 3: buffer += util::string_format("%s = &%s%s", REG_NAMES[reg], TRANSFER_SIZE[size], format_address_mode(lmode, la, s, limx)); break; } break; } @@ -263,10 +253,10 @@ static void format_transfer(uint64_t op) switch (le) { - case 0: b += sprintf(b, "&%s%s = %s", TRANSFER_SIZE[size], format_address_mode(lmode, la, s, offset), REG_NAMES[reg]); break; - case 1: b += sprintf(b, "%s = %s", REG_NAMES[reg], format_address_mode(lmode, la, s, offset)); break; - case 2: b += sprintf(b, "%s = &%s%s", REG_NAMES[reg], TRANSFER_SIZE[size], format_address_mode(lmode, la, s, offset)); break; - case 3: b += sprintf(b, "%s = &%s%s", REG_NAMES[reg], TRANSFER_SIZE[size], format_address_mode(lmode, la, s, offset)); break; + case 0: buffer += util::string_format("&%s%s = %s", TRANSFER_SIZE[size], format_address_mode(lmode, la, s, offset), REG_NAMES[reg]); break; + case 1: buffer += util::string_format("%s = %s", REG_NAMES[reg], format_address_mode(lmode, la, s, offset)); break; + case 2: buffer += util::string_format("%s = &%s%s", REG_NAMES[reg], TRANSFER_SIZE[size], format_address_mode(lmode, la, s, offset)); break; + case 3: buffer += util::string_format("%s = &%s%s", REG_NAMES[reg], TRANSFER_SIZE[size], format_address_mode(lmode, la, s, offset)); break; } break; } @@ -294,10 +284,10 @@ static void format_transfer(uint64_t op) // local transfer switch (local_le) { - case 0: b += sprintf(b, "&%s%s = %s", TRANSFER_SIZE[local_size], format_address_mode(lmode, la, local_s, local_imx), REG_NAMES[lreg]); break; - case 1: b += sprintf(b, "%s = %s", REG_NAMES[lreg], format_address_mode(lmode, la, local_s, local_imx)); break; - case 2: b += sprintf(b, "%s = &%s%s", REG_NAMES[lreg], TRANSFER_SIZE[local_size], format_address_mode(lmode, la, local_s, local_imx)); break; - case 3: b += sprintf(b, "%s = &%s%s", REG_NAMES[lreg], TRANSFER_SIZE[local_size], format_address_mode(lmode, la, local_s, local_imx)); break; + case 0: buffer += util::string_format("&%s%s = %s", TRANSFER_SIZE[local_size], format_address_mode(lmode, la, local_s, local_imx), REG_NAMES[lreg]); break; + case 1: buffer += util::string_format("%s = %s", REG_NAMES[lreg], format_address_mode(lmode, la, local_s, local_imx)); break; + case 2: buffer += util::string_format("%s = &%s%s", REG_NAMES[lreg], TRANSFER_SIZE[local_size], format_address_mode(lmode, la, local_s, local_imx)); break; + case 3: buffer += util::string_format("%s = &%s%s", REG_NAMES[lreg], TRANSFER_SIZE[local_size], format_address_mode(lmode, la, local_s, local_imx)); break; } util::stream_format(*output, ", "); @@ -305,10 +295,10 @@ static void format_transfer(uint64_t op) // global transfer switch (global_le) { - case 0: b += sprintf(b, "&%s%s = %s", TRANSFER_SIZE[global_size], format_address_mode(gmode, ga, global_s, global_imx), REG_NAMES[greg]); break; - case 1: b += sprintf(b, "%s = %s", REG_NAMES[greg], format_address_mode(gmode, ga, global_s, global_imx)); break; - case 2: b += sprintf(b, "%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[global_size], format_address_mode(gmode, ga, global_s, global_imx)); break; - case 3: b += sprintf(b, "%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[global_size], format_address_mode(gmode, ga, global_s, global_imx)); break; + case 0: buffer += util::string_format("&%s%s = %s", TRANSFER_SIZE[global_size], format_address_mode(gmode, ga, global_s, global_imx), REG_NAMES[greg]); break; + case 1: buffer += util::string_format("%s = %s", REG_NAMES[greg], format_address_mode(gmode, ga, global_s, global_imx)); break; + case 2: buffer += util::string_format("%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[global_size], format_address_mode(gmode, ga, global_s, global_imx)); break; + case 3: buffer += util::string_format("%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[global_size], format_address_mode(gmode, ga, global_s, global_imx)); break; } break; } @@ -320,7 +310,7 @@ static void format_transfer(uint64_t op) util::stream_format(*output, " || %s", buffer); } -static void format_alu_op(int aluop, int a, const char *dst_text, const char *a_text, const char *b_text, const char *c_text) +void tms32082_pp_disassembler::format_alu_op(int aluop, int a, const char *dst_text, const char *a_text, const char *b_text, const char *c_text) { if (a) // arithmetic { @@ -409,13 +399,17 @@ static void format_alu_op(int aluop, int a, const char *dst_text, const char *a_ } } -static offs_t tms32082_disasm_pp(std::ostream &stream, offs_t pc, const uint8_t *oprom) +u32 tms32082_pp_disassembler::opcode_alignment() const +{ + return 8; +} + +offs_t tms32082_pp_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { output = &stream; uint32_t flags = 0; - uint64_t op = ((uint64_t)(oprom[0]) << 56) | ((uint64_t)(oprom[1]) << 48) | ((uint64_t)(oprom[2]) << 40) | ((uint64_t)(oprom[3]) << 32) | - ((uint64_t)(oprom[4]) << 24) | ((uint64_t)(oprom[5]) << 16) | ((uint64_t)(oprom[6]) << 8) | ((uint64_t)(oprom[7])); + uint64_t op = opcodes.r64(pc); switch (op >> 60) { @@ -695,10 +689,5 @@ static offs_t tms32082_disasm_pp(std::ostream &stream, offs_t pc, const uint8_t break; } - return 8 | flags | DASMFLAG_SUPPORTED; -} - -CPU_DISASSEMBLE(tms32082_pp) -{ - return tms32082_disasm_pp(stream, pc, oprom); + return 8 | flags | SUPPORTED; } diff --git a/src/devices/cpu/tms32082/dis_pp.h b/src/devices/cpu/tms32082/dis_pp.h new file mode 100644 index 00000000000..6541eeccb70 --- /dev/null +++ b/src/devices/cpu/tms32082/dis_pp.h @@ -0,0 +1,33 @@ +// license:BSD-3-Clause +// copyright-holders:Ville Linde +// TMS32082 PP Disassembler + +#ifndef MAME_CPU_TMS32082_DIS_PP_H +#define MAME_CPU_TMS32082_DIS_PP_H + +#pragma once + +class tms32082_pp_disassembler : public util::disasm_interface +{ +public: + tms32082_pp_disassembler() = default; + virtual ~tms32082_pp_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *REG_NAMES[128]; + static const char *CONDITION_CODES[16]; + static const char *TRANSFER_SIZE[4]; + + + std::ostream *output; + + + std::string format_address_mode(int mode, int areg, int s, int limx); + void format_transfer(uint64_t op); + void format_alu_op(int aluop, int a, const char *dst_text, const char *a_text, const char *b_text, const char *c_text); +}; + +#endif diff --git a/src/devices/cpu/tms32082/tms32082.cpp b/src/devices/cpu/tms32082/tms32082.cpp index e2a975ea995..baf7289fe4b 100644 --- a/src/devices/cpu/tms32082/tms32082.cpp +++ b/src/devices/cpu/tms32082/tms32082.cpp @@ -9,11 +9,10 @@ #include "emu.h" #include "tms32082.h" +#include "dis_pp.h" +#include "dis_mp.h" #include "debugger.h" -extern CPU_DISASSEMBLE(tms32082_mp); -extern CPU_DISASSEMBLE(tms32082_pp); - DEFINE_DEVICE_TYPE(TMS32082_MP, tms32082_mp_device, "tms32082_mp", "TMS32082 MP") DEFINE_DEVICE_TYPE(TMS32082_PP, tms32082_pp_device, "tms32082_pp", "TMS32082 PP") @@ -64,13 +63,12 @@ device_memory_interface::space_config_vector tms32082_pp_device::memory_space_co }; } -offs_t tms32082_mp_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) + +util::disasm_interface *tms32082_mp_device::create_disassembler() { - return CPU_DISASSEMBLE_NAME(tms32082_mp)(this, stream, pc, oprom, opram, options); + return new tms32082_mp_disassembler; } - - void tms32082_mp_device::set_command_callback(write32_delegate callback) { m_cmd_callback = callback; @@ -502,9 +500,9 @@ tms32082_pp_device::tms32082_pp_device(const machine_config &mconfig, const char } -offs_t tms32082_pp_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *tms32082_pp_device::create_disassembler() { - return CPU_DISASSEMBLE_NAME(tms32082_pp)(this, stream, pc, oprom, opram, options); + return new tms32082_pp_disassembler; } void tms32082_pp_device::device_start() diff --git a/src/devices/cpu/tms32082/tms32082.h b/src/devices/cpu/tms32082/tms32082.h index c1d4674dbeb..de7949ec29f 100644 --- a/src/devices/cpu/tms32082/tms32082.h +++ b/src/devices/cpu/tms32082/tms32082.h @@ -93,9 +93,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 4; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 8; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; address_space_config m_program_config; @@ -181,9 +179,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 8; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 8; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; address_space_config m_program_config; |