summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu')
-rw-r--r--src/devices/cpu/dspp/dspp.cpp55
-rw-r--r--src/devices/cpu/dspp/dsppdasm.cpp676
-rw-r--r--src/devices/cpu/dspp/dsppdasm.h12
-rw-r--r--src/devices/cpu/sh/sh4fe.cpp3
4 files changed, 599 insertions, 147 deletions
diff --git a/src/devices/cpu/dspp/dspp.cpp b/src/devices/cpu/dspp/dspp.cpp
index 0a82905bec1..1e889a32bec 100644
--- a/src/devices/cpu/dspp/dspp.cpp
+++ b/src/devices/cpu/dspp/dspp.cpp
@@ -157,11 +157,11 @@ void dspp_device::device_start()
// Register our state for the debugger
state_add(DSPP_PC, "PC", m_core->m_pc);
- state_add(DSPP_ACC, "ACC", m_core->m_acc);
+ state_add(DSPP_ACC, "ACC", m_core->m_acc).mask(0xfffff);
state_add(STATE_GENPC, "GENPC", m_core->m_pc).noshow();
+ state_add(STATE_GENPCBASE, "GENPCBASE", m_core->m_pc).noshow();
#if 0
state_add(STATE_GENFLAGS, "GENFLAGS", m_core->m_flags).callimport().callexport().formatstr("%6s").noshow();
- state_add(STATE_GENPCBASE, "GENPCBASE", m_ppc).noshow();
state_add(DSPP_PS, "PS", m_core->m_flagsio).callimport().callexport();
for (int regnum = 0; regnum < 32; regnum++)
@@ -441,18 +441,15 @@ void dspp_device::parse_operands(uint32_t numops)
// Immediate value
if ((operand & 0xc000) == 0xc000)
{
- val = operand & 0x1fff;
-
if (operand & 0x2000)
{
// Left justify
- val = val << 3;
+ val = (operand & 0x1fff) << 3;
}
else
{
// Sign extend if right justified
- if (val & 0x1000)
- val |= 0xe000;
+ val = uint16_t(util::sext(operand, 13));
}
m_core->m_operands[opidx++].value = val;
}
@@ -949,38 +946,6 @@ inline void dspp_device::exec_control()
}
}
-//-------------------------------------------------
-// sign_extend8 - Sign extend 8-bits to 32-bits
-//-------------------------------------------------
-
-static inline int32_t sign_extend8(uint8_t val)
-{
- return (int32_t)(int8_t)val;
-}
-
-
-//-------------------------------------------------
-// sign_extend16 - Sign extend 16-bits to 32-bits
-//-------------------------------------------------
-
-static inline int32_t sign_extend16(uint16_t val)
-{
- return (int32_t)(int16_t)val;
-}
-
-
-//-------------------------------------------------
-// sign_extend20 - Sign extend 20-bits to 32-bits
-//-------------------------------------------------
-
-static inline int32_t sign_extend20(uint32_t val)
-{
- if (val & 0x00080000)
- return (int32_t)(0xfff00000 | val);
- else
- return (int32_t)val;
-}
-
//-------------------------------------------------
// exec_arithmetic - Execute an arithmetic op
@@ -1013,8 +978,8 @@ inline void dspp_device::exec_arithmetic()
{
uint32_t mul_sel = (m_core->m_op >> 12) & 1;
- int32_t op1 = sign_extend16(read_next_operand());
- int32_t op2 = sign_extend16(mul_sel ? read_next_operand() : m_core->m_acc >> 4);
+ int32_t op1 = int16_t(read_next_operand());
+ int32_t op2 = int16_t(mul_sel ? read_next_operand() : m_core->m_acc >> 4);
mul_res = (op1 * op2) >> 11;
}
@@ -1202,7 +1167,7 @@ inline void dspp_device::exec_arithmetic()
if (alu_op < 8)
{
// Arithmetic
- m_core->m_acc = sign_extend20(alu_res) >> shift;
+ m_core->m_acc = util::sext(alu_res, 20) >> shift;
}
else
{
@@ -1222,11 +1187,11 @@ inline void dspp_device::exec_arithmetic()
if (m_core->m_flag_over)
m_core->m_acc = m_core->m_flag_neg ? 0x7ffff : 0xfff80000;
else
- m_core->m_acc = sign_extend20(alu_res);
+ m_core->m_acc = util::sext(alu_res, 20);
}
else
{
- m_core->m_acc = sign_extend20(alu_res) << shift;
+ m_core->m_acc = util::sext(alu_res << shift, 20);
}
}
@@ -1458,7 +1423,7 @@ void dspp_device::process_next_dma(int32_t channel)
int16_t dspp_device::decode_sqxd(int8_t data, int16_t prev)
{
- int16_t temp = sign_extend8(data & 0xfe);
+ int16_t temp = int8_t(data & 0xfe);
int32_t expanded = (temp * iabs(temp)) << 1;
int16_t output;
diff --git a/src/devices/cpu/dspp/dsppdasm.cpp b/src/devices/cpu/dspp/dsppdasm.cpp
index 6b43df5d452..ff534ac79c7 100644
--- a/src/devices/cpu/dspp/dsppdasm.cpp
+++ b/src/devices/cpu/dspp/dsppdasm.cpp
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Philip Bennett
+// copyright-holders:Philip Bennett, AJR
/***************************************************************************
dsppdasm.c
@@ -18,107 +18,583 @@
uint32_t dspp_disassembler::opcode_alignment() const
{
- return 2;
+ return 1;
+}
+
+
+//-------------------------------------------------
+// format_operand - Format the value encoded by
+// an instruction operand
+//-------------------------------------------------
+
+void dspp_disassembler::format_operand(std::ostream &stream, uint16_t operand)
+{
+ uint32_t numregs = 0;
+
+ if (operand & 0x8000)
+ {
+ // Immediate value
+ if ((operand & 0xc000) == 0xc000)
+ {
+ uint16_t val;
+
+ if (operand & 0x2000)
+ {
+ // Left justify
+ val = (operand & 0x1fff) << 3;
+ }
+ else
+ {
+ // Sign extend if right justified
+ val = util::sext(operand, 13);
+ }
+ util::stream_format(stream, "#0x%04X", val);
+ }
+ else if((operand & 0xe000) == 0x8000)
+ {
+ // Address operand
+ uint16_t addr = operand & 0x03ff;
+
+ if (operand & 0x0400)
+ {
+ // Indirect
+ stream << '@';
+ }
+ util::stream_format(stream, "[0x%03X]", addr);
+
+ if (operand & 0x0800)
+ {
+ // Write Back
+ stream << '!';
+ }
+ }
+ else if ((operand & 0xe000) == 0xa000)
+ {
+ // 1 or 2 register operand
+ numregs = (operand & 0x0400) ? 2 : 1;
+ }
+ }
+ else
+ {
+ numregs = 3;
+ }
+
+ if (numregs > 0)
+ {
+ uint32_t shifter, regdi;
+
+ // Shift successive register operands from a single operand word
+ for (uint32_t i = 0; i < numregs; ++i)
+ {
+ if (i > 0)
+ stream << ", ";
+
+ shifter = ((numregs - i) - 1) * 5;
+ regdi = (operand >> shifter) & 0x1f;
+
+ if (regdi & 0x0010)
+ {
+ // Indirect?
+ stream << '@';
+ }
+ util::stream_format(stream, "[R%d]", regdi & 0xf);
+
+ if (numregs == 2)
+ {
+ if ((i == 0) && (operand & 0x1000))
+ stream << '!';
+ else if ((i == 1) && (operand & 0x0800))
+ stream << '!';
+ }
+ else if (numregs == 1)
+ {
+ if (operand & 0x800)
+ stream << '!';
+ }
+ }
+ }
+}
+
+
+
+//**************************************************************************
+// OPCODE DISASSEMBLY
+//**************************************************************************
+
+//-------------------------------------------------
+// dasm_super_special - Disassemble a super
+// special control op
+//-------------------------------------------------
+
+offs_t dspp_disassembler::dasm_super_special(std::ostream &stream, uint16_t op)
+{
+ uint32_t sel = (op >> 7) & 7;
+
+ switch (sel)
+ {
+ case 1: // BAC
+ {
+ stream << "BAC";
+ return 1 | SUPPORTED;
+ }
+
+ case 4: // RTS
+ {
+ stream << "RTS";
+ return 1 | STEP_OUT | SUPPORTED;
+ }
+
+ case 5: // OP_MASK
+ {
+ stream << "OP_MASK";
+ return 1 | SUPPORTED;
+ }
+
+ case 7: // SLEEP
+ {
+ stream << "SLEEP";
+ return 1 | SUPPORTED;
+ }
+
+ case 0: // NOP
+ {
+ stream << "NOP";
+ return 1 | SUPPORTED;
+ }
+
+ default: // Unused
+ {
+ util::stream_format(stream, "0x%04X", op);
+ return 1 | SUPPORTED;
+ }
+ }
+}
+
+
+//-------------------------------------------------
+// dasm_special - Disassemble a special control op
+//-------------------------------------------------
+
+offs_t dspp_disassembler::dasm_special(std::ostream &stream, offs_t pc, const data_buffer &opcodes, uint16_t op)
+{
+ switch ((op >> 10) & 7)
+ {
+ case 0:
+ {
+ return dasm_super_special(stream, op);
+ }
+ case 1: // JUMP
+ {
+ util::stream_format(stream, "JUMP 0x%03X", op & 0x3ff);
+ return 1 | SUPPORTED;
+ }
+ case 2: // JSR
+ {
+ util::stream_format(stream, "JSR 0x%03X", op & 0x3ff);
+ return 1 | STEP_OVER | SUPPORTED;
+ }
+ case 3: // BFM
+ {
+ util::stream_format(stream, "BFM 0x%03X", op & 0x3ff);
+ return 1 | SUPPORTED;
+ }
+ case 4: // MOVEREG
+ {
+ uint32_t regdi = op & 0x3f;
+
+ util::stream_format(stream, "MOVEREG %sR%d, ", (regdi & 0x0010) ? "@" : "", regdi & 0xf);
+ format_operand(stream, opcodes.r16(pc + 1));
+ return 2 | SUPPORTED;
+ }
+ case 5: // RBASE
+ {
+ util::stream_format(stream, "RBASE%d 0x%03X", (op & 3) << 2, op & 0x3fc);
+ return 1 | SUPPORTED;
+ }
+ case 6: // MOVED
+ {
+ util::stream_format(stream, "MOVE [0x%03X], ", op & 0x3ff);
+ format_operand(stream, opcodes.r16(pc + 1));
+ return 2 | SUPPORTED;
+ }
+ case 7: // MOVEI
+ {
+ util::stream_format(stream, "MOVE @[0x%03X], ", op & 0x3ff);
+ format_operand(stream, opcodes.r16(pc + 1));
+ return 2 | SUPPORTED;
+ }
+
+ default:
+ {
+ util::stream_format(stream, "0x%04X", op);
+ return 1 | SUPPORTED;
+ }
+ }
+}
+
+
+//-------------------------------------------------
+// dasm_branch - Disassemble a branch control op
+//-------------------------------------------------
+
+offs_t dspp_disassembler::dasm_branch(std::ostream &stream, uint16_t op)
+{
+ uint32_t mode = (op >> 13) & 3;
+ uint32_t select = (op >> 12) & 1;
+ uint32_t mask = (op >> 10) & 3;
+
+ char flag0, flag1;
+
+ if (select == 0)
+ {
+ flag0 = 'N';
+ flag1 = 'V';
+ }
+ else
+ {
+ flag0 = 'C';
+ flag1 = 'Z';
+ }
+
+ bool mask0 = (mask & 2) != 0;
+ bool mask1 = (mask & 1) != 0;
+
+ if (mode == 2)
+ stream << "BFC ";
+ else
+ stream << "BTC ";
+
+ if (mask0 && mask1)
+ {
+ stream << flag1;
+ stream << flag0;
+ }
+ else if (mask0)
+ {
+ stream << flag0;
+ }
+ else if (mask1)
+ {
+ stream << flag1;
+ }
+ else
+ {
+ stream << '0';
+ }
+
+ util::stream_format(stream, ", 0x%03X", op & 0x3ff);
+ return 1 | (mask0 || mask1 ? STEP_COND : 0) | SUPPORTED;
+}
+
+
+//-------------------------------------------------
+// dasm_complex_branch - Disassemble a complex
+// branch control op
+//-------------------------------------------------
+
+offs_t dspp_disassembler::dasm_complex_branch(std::ostream &stream, uint16_t op)
+{
+ uint32_t type = (op >> 10) & 7;
+
+ switch (type)
+ {
+ case 0: // BLT
+ stream << "BLT";
+ break;
+ case 1: // BLE
+ stream << "BLE";
+ break;
+ case 2: // BGE
+ stream << "BGE";
+ break;
+ case 3: // BGT
+ stream << "BGT";
+ break;
+ case 4: // BHI
+ stream << "BHI";
+ break;
+ case 5: // BLS
+ stream << "BLS";
+ break;
+ case 6: // BXS
+ stream << "BXS";
+ break;
+ case 7: // BXC
+ stream << "BXC";
+ break;
+ }
+
+ util::stream_format(stream, " 0x%03X", op & 0x3ff);
+ return 1 | STEP_COND | SUPPORTED;
+}
+
+
+//-------------------------------------------------
+// dasm_control - Disassemble a control op
+//-------------------------------------------------
+
+offs_t dspp_disassembler::dasm_control(std::ostream &stream, offs_t pc, const data_buffer &opcodes, uint16_t op)
+{
+ uint32_t mode = (op >> 13) & 3;
+
+ switch (mode)
+ {
+ // Special
+ case 0:
+ {
+ return dasm_special(stream, pc, opcodes, op);
+ }
+
+ // Branches
+ case 1: case 2:
+ {
+ return dasm_branch(stream, op);
+ }
+
+ // Complex branches
+ case 3:
+ {
+ return dasm_complex_branch(stream, op);
+ }
+
+ default:
+ {
+ util::stream_format(stream, "0x%04X", op);
+ return 1 | SUPPORTED;
+ }
+ }
+}
+
+
+//-------------------------------------------------
+// dasm_arithmetic - Disassemble an arithmetic op
+//-------------------------------------------------
+
+offs_t dspp_disassembler::dasm_arithmetic(std::ostream &stream, offs_t pc, const data_buffer &opcodes, uint16_t op)
+{
+ // Decode the various fields
+ uint32_t numops = (op >> 13) & 3;
+ uint32_t muxa = (op >> 10) & 3;
+ uint32_t muxb = (op >> 8) & 3;
+ uint32_t alu_op = (op >> 4) & 0xf;
+ uint32_t barrel_code = op & 0xf;
+
+ uint32_t opidx = 0;
+
+ // Check for operand overflow
+ if (numops == 0 && ((muxa == 1) || (muxa == 2) || (muxb == 1) || (muxb == 2)))
+ numops = 4;
+
+ // Implicit barrel shift
+ if (barrel_code == 8)
+ ++numops;
+
+ if (muxa == 3 || muxb == 3)
+ {
+ uint32_t mul_sel = (op >> 12) & 1;
+
+ ++opidx;
+ if (mul_sel)
+ ++opidx;
+ }
+
+ if (alu_op < 8)
+ stream << "TRA ";
+ else
+ stream << "TRL ";
+
+ if (alu_op != 1)
+ {
+ if (alu_op == 9)
+ stream << "NOT ";
+
+ switch (muxa)
+ {
+ case 0:
+ {
+ stream << "ACC";
+ break;
+ }
+ case 1: case 2:
+ {
+ format_operand(stream, opcodes.r16(pc + 1 + opidx++));
+ break;
+ }
+ case 3:
+ {
+ uint32_t mul_sel = (op >> 12) & 1;
+
+ format_operand(stream, opcodes.r16(pc + 1));
+ stream << " * ";
+ if (mul_sel)
+ format_operand(stream, opcodes.r16(pc + 2));
+ else
+ stream << "ACC";
+ break;
+ }
+ }
+ }
+
+ switch (alu_op)
+ {
+ case 0: // _TRA
+ {
+ break;
+ }
+ case 1: // _NEG
+ {
+ stream << "-";
+ break;
+ }
+ case 2: // _+
+ {
+ stream << " + ";
+ break;
+ }
+ case 3: // _+C
+ {
+ stream << " + C";
+ break;
+ }
+ case 4: // _-
+ {
+ stream << " - ";
+ break;
+ }
+ case 5: // _-B
+ {
+ stream << " - B";
+ break;
+ }
+ case 6: // _++
+ {
+ stream << "++";
+ break;
+ }
+ case 7: // _--
+ {
+ stream << "--";
+ break;
+ }
+ case 8: // _TRL
+ {
+ break;
+ }
+ case 9: // _NOT
+ {
+ break;
+ }
+ case 10: // _AND
+ {
+ stream << " AND ";
+ break;
+ }
+ case 11: // _NAND
+ {
+ stream << " NAND ";
+ break;
+ }
+ case 12: // _OR
+ {
+ stream << " OR ";
+ break;
+ }
+ case 13: // _NOR
+ {
+ stream << " NOR ";
+ break;
+ }
+ case 14: // _XOR
+ {
+ stream << " XOR ";
+ break;
+ }
+ case 15: // _XNOR
+ {
+ stream << " XNOR ";
+ break;
+ }
+ }
+
+ if (alu_op == 1 || alu_op == 2 || alu_op == 4 || alu_op >= 10)
+ {
+ switch (muxb)
+ {
+ case 0:
+ {
+ stream << "ACC";
+ break;
+ }
+ case 1: case 2:
+ {
+ format_operand(stream, opcodes.r16(pc + 1 + opidx++));
+ break;
+ }
+ case 3:
+ {
+ uint32_t mul_sel = (op >> 12) & 1;
+
+ format_operand(stream, opcodes.r16(pc + 1));
+ stream << " * ";
+ if (mul_sel)
+ format_operand(stream, opcodes.r16(pc + 2));
+ else
+ stream << "ACC";
+ break;
+ }
+ }
+ }
+
+ // Barrel shift
+ static const int32_t shifts[8] = { 0, 1, 2, 3, 4, 5, 8, 16 };
+
+ if (barrel_code == 8)
+ {
+ stream << " SHIFT ";
+ format_operand(stream, opcodes.r16(pc + 1 + opidx++));
+ }
+
+ else if (barrel_code & 8)
+ {
+ // Right shift
+ uint32_t shift = shifts[(~barrel_code + 1) & 7];
+
+ if (shift != 0)
+ {
+ util::stream_format(stream, " >> %d", shift);
+ }
+ }
+ else
+ {
+ // Left shift
+ uint32_t shift = shifts[barrel_code];
+
+ if (shift == 16)
+ {
+ // Clip and saturate
+ stream << " SAT";
+ }
+ else if (shift != 0)
+ {
+ util::stream_format(stream, " << %d", shift);
+ }
+ }
+
+ if (opidx < numops)
+ {
+ stream << ", ";
+ format_operand(stream, opcodes.r16(pc + 1 + opidx));
+ }
+
+ return (numops + 1) | SUPPORTED;
}
offs_t dspp_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params)
{
-#if 0
- uint32_t op = oprom[0] | (oprom[1] << 8) | (oprom[2] << 16) | (oprom[3] << 24);
- int opcode = op >> 27;
- int cond = (op >> 21) & 1;
- int rdst = (op >> 22) & 31;
- int rsrc1 = (op >> 16) & 31;
- int rsrc2 = op & 0xffff;
- int rsrc2_iszero = (!rsrc2 || rsrc2 == 0xffe0);
- uint32_t flags = 0;
-
- switch (opcode)
- {
- case 0x00: sprintf(buffer, "trap $00"); flags = DASMFLAG_STEP_OVER; break;
- case 0x01: sprintf(buffer, "b%s $%08x", condition[rdst & 15], pc + ((INT32)(op << 10) >> 8)); break;
- case 0x02: if ((op & 0x003fffff) == 3)
- {
- uint32_t nextop = oprom[4] | (oprom[5] << 8) | (oprom[6] << 16) | (oprom[7] << 24);
- if ((nextop >> 27) == 0x10 && ((nextop >> 22) & 31) == rdst && (nextop & 0xffff) == 0)
- {
- uint32_t nextnextop = oprom[8] | (oprom[9] << 8) | (oprom[10] << 16) | (oprom[11] << 24);
- sprintf(buffer, "llit%s $%08x,%s", setcond[cond], nextnextop, reg[rdst]);
- return 12 | DASMFLAG_STEP_OVER | DASMFLAG_SUPPORTED;
- }
- }
- if (rdst)
- {
- flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1);
- sprintf(buffer, "bsr %s,$%08x", reg[rdst], pc + ((INT32)(op << 10) >> 8));
- }
- else
- sprintf(buffer, "bra $%08x", pc + ((INT32)(op << 10) >> 8));
- break;
- case 0x03: sprintf(buffer, "lea%s %s[%s],%s", setcond[cond], reg[rsrc1], src2(op,2), reg[rdst]); break;
- case 0x04: sprintf(buffer, "leah%s %s[%s],%s", setcond[cond], reg[rsrc1], src2(op,1), reg[rdst]); break;
- case 0x05: sprintf(buffer, "subr%s %s,%s,%s", setcond[cond], reg[rsrc1], src2(op,0), reg[rdst]); break;
- case 0x06: sprintf(buffer, "xor%s %s,%s,%s", setcond[cond], reg[rsrc1], src2(op,0), reg[rdst]); break;
- case 0x07: sprintf(buffer, "xorn%s %s,%s,%s", setcond[cond], reg[rsrc1], src2(op,0), reg[rdst]); break;
- case 0x08: if (!rsrc1 && !rdst && rsrc2_iszero)
- sprintf(buffer, "nop");
- else if (!rsrc1)
- sprintf(buffer, "mov%s %s,%s", setcond[cond], src2(op,0), reg[rdst]);
- else if (rsrc2_iszero)
- sprintf(buffer, "mov%s %s,%s", setcond[cond], reg[rsrc1], reg[rdst]);
- else
- sprintf(buffer, "add%s %s,%s,%s", setcond[cond], reg[rsrc1], src2(op,0), reg[rdst]); break;
- case 0x09: sprintf(buffer, "sub%s %s,%s,%s", setcond[cond], reg[rsrc1], src2(op,0), reg[rdst]); break;
- case 0x0a: sprintf(buffer, "addc%s %s,%s,%s", setcond[cond], reg[rsrc1], src2(op,0), reg[rdst]); break;
- case 0x0b: sprintf(buffer, "subc%s %s,%s,%s", setcond[cond], reg[rsrc1], src2(op,0), reg[rdst]); break;
- case 0x0c: sprintf(buffer, "and%s %s,%s,%s", setcond[cond], reg[rsrc1], src2(op,0), reg[rdst]); break;
- case 0x0d: sprintf(buffer, "andn%s %s,%s,%s", setcond[cond], reg[rsrc1], src2(op,0), reg[rdst]); break;
- case 0x0e: if (!rsrc1 && !rdst && rsrc2_iszero)
- sprintf(buffer, "nop");
- else if (!rsrc1)
- sprintf(buffer, "mov%s %s,%s", setcond[cond], src2(op,0), reg[rdst]);
- else if (rsrc2_iszero)
- sprintf(buffer, "mov%s %s,%s", setcond[cond], reg[rsrc1], reg[rdst]);
- else
- sprintf(buffer, "or%s %s,%s,%s", setcond[cond], reg[rsrc1], src2(op,0), reg[rdst]); break;
- case 0x0f: sprintf(buffer, "orn%s %s,%s,%s", setcond[cond], reg[rsrc1], src2(op,0), reg[rdst]); break;
- case 0x10: sprintf(buffer, "ld%s %s[%s],%s", setcond[cond], reg[rsrc1], src2(op,2), reg[rdst]); break;
- case 0x11: sprintf(buffer, "ldh%s %s[%s],%s", setcond[cond], reg[rsrc1], src2(op,1), reg[rdst]); break;
- case 0x12: sprintf(buffer, "lduh%s %s[%s],%s", setcond[cond], reg[rsrc1], src2(op,1), reg[rdst]); break;
- case 0x13: sprintf(buffer, "sth%s %s[%s],%s", setcond[cond], reg[rsrc1], src2(op,1), reg[rdst]); break;
- case 0x14: sprintf(buffer, "st%s %s[%s],%s", setcond[cond], reg[rsrc1], src2(op,2), reg[rdst]); break;
- case 0x15: sprintf(buffer, "ldb%s %s[%s],%s", setcond[cond], reg[rsrc1], src2(op,0), reg[rdst]); break;
- case 0x16: sprintf(buffer, "ldub%s %s[%s],%s", setcond[cond], reg[rsrc1], src2(op,0), reg[rdst]); break;
- case 0x17: sprintf(buffer, "stb%s %s[%s],%s", setcond[cond], reg[rsrc1], src2(op,0), reg[rdst]); break;
- case 0x18: sprintf(buffer, "ashr%s %s,%s,%s", setcond[cond], reg[rsrc1], src2(op,0), reg[rdst]); break;
- case 0x19: sprintf(buffer, "lshr%s %s,%s,%s", setcond[cond], reg[rsrc1], src2(op,0), reg[rdst]); break;
- case 0x1a: sprintf(buffer, "ashl%s %s,%s,%s", setcond[cond], reg[rsrc1], src2(op,0), reg[rdst]); break;
- case 0x1b: sprintf(buffer, "rotl%s %s,%s,%s", setcond[cond], reg[rsrc1], src2(op,0), reg[rdst]); break;
- case 0x1c: sprintf(buffer, "getps %s", reg[rdst]); break;
- case 0x1d: sprintf(buffer, "putps %s", src2(op,0)); break;
- case 0x1e: if (rdst && rsrc2_iszero)
- {
- flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1);
- sprintf(buffer, "jsr%s %s,%s", setcond[cond], reg[rdst], reg[rsrc1]);
- }
- else if (rdst)
- {
- flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1);
- sprintf(buffer, "jsr%s %s,%s[%s]", setcond[cond], reg[rdst], reg[rsrc1], src2(op,2));
- }
- else if (rsrc2_iszero)
- {
- if (rsrc1 == 28)
- flags = DASMFLAG_STEP_OUT;
- sprintf(buffer, "jmp%s %s", setcond[cond], reg[rsrc1]);
- }
- else
- sprintf(buffer, "jmp%s %s[%s]", setcond[cond], reg[rsrc1], src2(op,2));
- break;
- case 0x1f: sprintf(buffer, "trap $1f"); flags = DASMFLAG_STEP_OVER; break;
- }
-
- sprintf(buffer, "????");
-#endif
- return 4 | 2 | SUPPORTED;
+ // Decode and disassemble
+ uint16_t op = opcodes.r16(pc);
+ if (op & 0x8000)
+ return dasm_control(stream, pc, opcodes, op);
+ else
+ return dasm_arithmetic(stream, pc, opcodes, op);
}
diff --git a/src/devices/cpu/dspp/dsppdasm.h b/src/devices/cpu/dspp/dsppdasm.h
index 538f0a96c0e..b7af27ccccd 100644
--- a/src/devices/cpu/dspp/dsppdasm.h
+++ b/src/devices/cpu/dspp/dsppdasm.h
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Philip Bennett
+// copyright-holders:Philip Bennett, AJR
/*
DSPP disassembler shim
*/
@@ -17,6 +17,16 @@ public:
virtual uint32_t opcode_alignment() const override;
virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params) override;
+
+private:
+ static void format_operand(std::ostream &stream, uint16_t operand);
+
+ static offs_t dasm_control(std::ostream &stream, offs_t pc, const data_buffer &opcodes, uint16_t op);
+ static offs_t dasm_super_special(std::ostream &stream, uint16_t op);
+ static offs_t dasm_special(std::ostream &stream, offs_t pc, const data_buffer &opcodes, uint16_t op);
+ static offs_t dasm_branch(std::ostream &stream, uint16_t op);
+ static offs_t dasm_complex_branch(std::ostream &stream, uint16_t op);
+ static offs_t dasm_arithmetic(std::ostream &stream, offs_t pc, const data_buffer &opcodes, uint16_t op);
};
#endif // MAME_CPU_DSPP_DSPPDASM_H
diff --git a/src/devices/cpu/sh/sh4fe.cpp b/src/devices/cpu/sh/sh4fe.cpp
index cb3afaba6fe..8474cb48171 100644
--- a/src/devices/cpu/sh/sh4fe.cpp
+++ b/src/devices/cpu/sh/sh4fe.cpp
@@ -28,7 +28,8 @@ uint16_t sh4_frontend::read_word(opcode_desc &desc)
if (desc.physpc >= 0xe0000000)
return m_sh->m_pr16(desc.physpc);
- return m_sh->m_pr16(desc.physpc & SH34_AM);
+ desc.physpc &= SH34_AM; // TODO: mmu translate
+ return m_sh->m_pr16(desc.physpc);
}