summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/sm510/sm510d.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/sm510/sm510d.c')
-rw-r--r--src/devices/cpu/sm510/sm510d.c215
1 files changed, 215 insertions, 0 deletions
diff --git a/src/devices/cpu/sm510/sm510d.c b/src/devices/cpu/sm510/sm510d.c
new file mode 100644
index 00000000000..70e6b2c8ed6
--- /dev/null
+++ b/src/devices/cpu/sm510/sm510d.c
@@ -0,0 +1,215 @@
+// license:BSD-3-Clause
+// copyright-holders:hap
+/*
+
+ Sharp SM510 MCU family disassembler
+
+*/
+
+#include "emu.h"
+#include "debugger.h"
+#include "sm510.h"
+
+
+// common lookup tables
+
+enum e_mnemonics
+{
+ mILL, mEXT,
+ mLB, mLBL, mSBM, mEXBLA, mINCB, mDECB,
+ mATPL, mRTN0, mRTN1, mTL, mTML, mTM, mT,
+ mEXC, mBDC, mEXCI, mEXCD, mLDA, mLAX, mPTW, mWR, mWS,
+ mKTA, mATBP, mATX, mATL, mATFC, mATR,
+ mADD, mADD11, mADX, mCOMA, mROT, mRC, mSC,
+ mTB, mTC, mTAM, mTMI, mTA0, mTABL, mTIS, mTAL, mTF1, mTF4,
+ mRM, mSM,
+ mPRE, mSME, mRME, mTMEL,
+ mSKIP, mCEND, mIDIV
+};
+
+static const char *const s_mnemonics[] =
+{
+ "?", "",
+ "LB", "LBL", "SBM", "EXBLA", "INCB", "DECB",
+ "ATPL", "RTN0", "RTN1", "TL", "TML", "TM", "T",
+ "EXC", "BDC", "EXCI", "EXCD", "LDA", "LAX", "PTW", "WR", "WS",
+ "KTA", "ATBP", "ATX", "ATL", "ATFC", "ATR",
+ "ADD", "ADD11", "ADX", "COMA", "ROT", "RC", "SC",
+ "TB", "TC", "TAM", "TMI", "TA0", "TABL", "TIS", "TAL", "TF1", "TF4",
+ "RM", "SM",
+ "PRE", "SME", "RME", "TMEL",
+ "SKIP", "CEND", "IDIV"
+};
+
+// number of bits per opcode parameter, 8 or larger means 2-byte opcode
+static const UINT8 s_bits[] =
+{
+ 0, 8,
+ 4, 8, 0, 0, 0, 0,
+ 0, 0, 0, 4+8, 2+8, 6, 6,
+ 2, 0, 2, 2, 2, 4, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 4, 0, 0, 0, 0,
+ 0, 0, 0, 2, 0, 0, 0, 0, 0, 0,
+ 2, 2,
+ 8, 0, 0, 0,
+ 0, 0, 0
+};
+
+#define _OVER DASMFLAG_STEP_OVER
+#define _OUT DASMFLAG_STEP_OUT
+
+static const UINT32 s_flags[] =
+{
+ 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, _OUT, _OUT, 0, _OVER, _OVER, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,
+ 0, 0, 0, 0,
+ 0, _OVER, 0
+};
+
+// next program counter in sequence (relative)
+static const INT8 s_next_pc[0x40] =
+{
+ 32, -1 /* rollback */, -1, 30, 30, -3, -3, 28, 28, -5, -5, 26, 26, -7, -7, 24,
+ 24, -9, -9, 22, 22, -11, -11, 20, 20, -13, -13, 18, 18, -15, -15, 16,
+ 16, -17, -17, 14, 14, -19, -19, 12, 12, -21, -21, 10, 10, -23, -23, 8,
+ 8, -25, -25, 6, 6, -27, -27, 4, 4, -29, -29, 2, 2, -31, -31, 0 /* gets stuck here */
+};
+
+
+
+// common disasm
+
+static offs_t sm510_common_disasm(const UINT8 *lut_mnemonic, const UINT8 *lut_extended, char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram)
+{
+ // get raw opcode
+ UINT8 op = oprom[0];
+ UINT8 instr = lut_mnemonic[op];
+ int len = 1;
+
+ int bits = s_bits[instr];
+ UINT8 mask = op & ((1 << (bits & 7)) - 1);
+ UINT16 param = mask;
+ if (bits >= 8)
+ {
+ // note: disasm view shows correct parameter, but raw view does not
+ // note2: oprom array negative index doesn't work either :(
+ param = oprom[s_next_pc[pc & 0x3f]];
+ len++;
+ }
+
+ // extended opcode
+ bool is_extended = (instr == mEXT);
+ if (is_extended)
+ instr = lut_extended[param];
+
+ // disassemble it
+ char *dst = buffer;
+ dst += sprintf(dst, "%-6s ", s_mnemonics[instr]);
+ if (bits > 0)
+ {
+ if (bits <= 4)
+ {
+ if (param < 10)
+ dst += sprintf(dst, "%d", param);
+ else
+ dst += sprintf(dst, "$%X", param);
+ }
+ else if (bits <= 8)
+ {
+ if (!is_extended)
+ dst += sprintf(dst, "$%02X", param);
+ }
+ else
+ {
+ UINT16 address = (param << 4 & 0xc00) | (mask << 6 & 0x3c0) | (param & 0x03f);
+ dst += sprintf(dst, "$%03X", address);
+ }
+
+ // show param offset
+ if (bits >= 8)
+ dst += sprintf(dst, " [$%03X]", pc + s_next_pc[pc & 0x3f]);
+ }
+
+ return len | s_flags[instr] | DASMFLAG_SUPPORTED;
+}
+
+
+// SM510 disasm
+
+static const UINT8 sm510_mnemonic[0x100] =
+{
+/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
+ mSKIP, mATBP, mSBM, mATPL, mRM, mRM, mRM, mRM, mADD, mADD11,mCOMA, mEXBLA,mSM, mSM, mSM, mSM, // 0
+ mEXC, mEXC, mEXC, mEXC, mEXCI, mEXCI, mEXCI, mEXCI, mLDA, mLDA, mLDA, mLDA, mEXCD, mEXCD, mEXCD, mEXCD, // 1
+ mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, // 2
+ mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, // 3 - note: $3A has synonym DC(decimal correct)
+
+ mLB, mLB, mLB, mLB, mLB, mLB, mLB, mLB, mLB, mLB, mLB, mLB, mLB, mLB, mLB, mLB, // 4
+ 0, mTB, mTC, mTAM, mTMI, mTMI, mTMI, mTMI, mTIS, mATL, mTA0, mTABL, 0, mCEND, mTAL, mLBL, // 5
+ mATFC, mATR, mWR, mWS, mINCB, mIDIV, mRC, mSC, mTF1, mTF4, mKTA, mROT, mDECB, mBDC, mRTN0, mRTN1, // 6
+ mTL, mTL, mTL, mTL, mTL, mTL, mTL, mTL, mTL, mTL, mTL, mTL, mTML, mTML, mTML, mTML, // 7
+
+ mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, // 8
+ mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, // 9
+ mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, // A
+ mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, // B
+
+ mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, // C
+ mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, // D
+ mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, // E
+ mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM // F
+};
+
+CPU_DISASSEMBLE(sm510)
+{
+ return sm510_common_disasm(sm510_mnemonic, NULL, buffer, pc, oprom, opram);
+}
+
+
+// SM511 disasm
+
+static const UINT8 sm511_mnemonic[0x100] =
+{
+/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
+ mROT, 0, mSBM, mATPL, mRM, mRM, mRM, mRM, mADD, mADD11,mCOMA, mEXBLA,mSM, mSM, mSM, mSM, // 0
+ mEXC, mEXC, mEXC, mEXC, mEXCI, mEXCI, mEXCI, mEXCI, mLDA, mLDA, mLDA, mLDA, mEXCD, mEXCD, mEXCD, mEXCD, // 1
+ mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, // 2
+ mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, // 3
+
+ mLB, mLB, mLB, mLB, mLB, mLB, mLB, mLB, mLB, mLB, mLB, mLB, mLB, mLB, mLB, mLB, // 4
+ mKTA, mTB, mTC, mTAM, mTMI, mTMI, mTMI, mTMI, mTIS, mATL, mTA0, mTABL, mATX, 0, mTAL, mLBL, // 5
+ mEXT, mPRE, mWR, mWS, mINCB, 0, mRC, mSC, mTML, mTML, mTML, mTML, mDECB, mPTW, mRTN0, mRTN1, // 6
+ mTL, mTL, mTL, mTL, mTL, mTL, mTL, mTL, mTL, mTL, mTL, mTL, mTL, mTL, mTL, mTL, // 7
+
+ mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, // 8
+ mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, // 9
+ mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, // A
+ mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, // B
+
+ mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, // C
+ mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, // D
+ mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, // E
+ mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM // F
+};
+
+static const UINT8 sm511_extended[0x10] =
+{
+ mRME, mSME, mTMEL, mATFC, mBDC, mATBP, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60 3
+};
+
+CPU_DISASSEMBLE(sm511)
+{
+ // create extended opcode table
+ UINT8 ext[0x100];
+ memset(ext, 0, 0x100);
+ memcpy(ext + 0x30, sm511_extended, 0x10);
+
+ return sm510_common_disasm(sm511_mnemonic, ext, buffer, pc, oprom, opram);
+}