summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/devices/cpu/cdc1700/cdc1700d.cpp535
-rw-r--r--src/devices/cpu/cdc1700/cdc1700d.h37
-rw-r--r--src/devices/cpu/sigma2/sigma2d.cpp393
-rw-r--r--src/devices/cpu/sigma2/sigma2d.h40
-rw-r--r--src/tools/unidasm.cpp6
5 files changed, 1011 insertions, 0 deletions
diff --git a/src/devices/cpu/cdc1700/cdc1700d.cpp b/src/devices/cpu/cdc1700/cdc1700d.cpp
new file mode 100644
index 00000000000..3b80a51f3e2
--- /dev/null
+++ b/src/devices/cpu/cdc1700/cdc1700d.cpp
@@ -0,0 +1,535 @@
+// license:BSD-3-Clause
+// copyright-holders:AJR
+/***************************************************************************
+
+ CDC 1700 & Cyber 18 disassembler
+
+***************************************************************************/
+
+#include "emu.h"
+#include "cdc1700d.h"
+
+cdc1700_disassembler::cdc1700_disassembler()
+ : util::disasm_interface()
+{
+}
+
+cyber18_disassembler::cyber18_disassembler()
+ : cdc1700_disassembler()
+{
+}
+
+u32 cdc1700_disassembler::opcode_alignment() const
+{
+ return 1;
+}
+
+namespace {
+
+const char *const s_skip_insts[16] =
+{
+ "SAZ", "SAN",
+ "SAP", "SAM",
+ "SQZ", "SQN",
+ "SQP", "SQM",
+ "SWS", "SWN",
+ "SOV", "SNO",
+ "SPE", "SNP",
+ "SPF", "SNF"
+};
+
+const char *const s_destregs[8] =
+{
+ "0",
+ "M",
+ "Q",
+ "Q,M",
+ "A",
+ "A,M",
+ "A,Q",
+ "A,Q,M"
+};
+
+const char *const s_register_insts[15] =
+{
+ "SLS", "01X", "INP", "OUT",
+ "EIN", "IIN", "SPB", "CPB",
+ "08X", "INA", "ENA", "NOP",
+ "ENQ", "INQ", "EXI"
+};
+
+const char *const s_memory_insts[15] =
+{
+ "JMP", "MUI", "DVI",
+ "STQ", "RTJ", "STA", "SPA",
+ "ADD", "SUB", "AND", "EOR",
+ "LDA", "RAO", "LDQ", "ADQ"
+};
+
+const char *const s_field_insts[6] =
+{
+ "SFZ", "SFN",
+ "LFA", "SFA",
+ "CLF", "SEF"
+};
+
+const char *const s_misc_micro_insts[13] =
+{
+ "LMM",
+ "LRG",
+ "SRG",
+ "SIO",
+ "SPS",
+ "DMI",
+ "CPB",
+ "GPE",
+ "GPO",
+ "ASC",
+ "APM",
+ "PM0",
+ "PM1"
+};
+
+const char *const s_misc_page_insts[6] =
+{
+ "LLB",
+ "LUB",
+ "EMS",
+ "WPR",
+ "RPR",
+ "ECC"
+};
+
+const char s_reg_names[8] =
+{
+ '0',
+ '1',
+ '2',
+ '3',
+ '4',
+ 'Q',
+ 'A',
+ 'I'
+};
+
+const char *const s_reg_long_names[8] =
+{
+ "",
+ "R1",
+ "R2",
+ "R3",
+ "R4",
+ "Q",
+ "A",
+ "I"
+};
+
+} // anonymous namespace
+
+void cdc1700_disassembler::format_s8(std::ostream &stream, u8 value)
+{
+ if (BIT(value, 7))
+ {
+ stream << '-';
+ value ^= 0xff;
+ }
+ if (value > 9)
+ stream << '$';
+ util::stream_format(stream, "%X", value);
+}
+
+offs_t cdc1700_disassembler::dasm_register_reference(std::ostream &stream, offs_t pc, const data_buffer &opcodes, u16 inst)
+{
+ util::stream_format(stream, "%-5s", s_register_insts[BIT(inst, 8, 4)]);
+ u8 modifier = inst & 0x00ff;
+ if (inst >= 0x0900 && inst < 0x0e00)
+ format_s8(stream, modifier);
+ else if (modifier <= 9)
+ util::stream_format(stream, "%d", modifier);
+ else
+ util::stream_format(stream, "$%02X", modifier);
+ return 1 | SUPPORTED;
+}
+
+offs_t cyber18_disassembler::dasm_register_reference(std::ostream &stream, offs_t pc, const data_buffer &opcodes, u16 inst)
+{
+ if (inst < 0x0100 && inst != 0x0000)
+ {
+ // Type 2 skip instructions
+ util::stream_format(stream, "S%d%-3c%d", BIT(inst, 6, 2) == 0 ? 4 : BIT(inst, 6, 2), "ZNPM"[BIT(inst, 4, 2)], inst & 0x000f);
+ return 1 | STEP_COND | SUPPORTED;
+ }
+ else if (BIT(inst, 9, 3) == 2 && (inst & 0x00ff) != 0)
+ {
+ // Type 2 storage reference instructions & field reference instructions
+ u16 inst2 = opcodes.r16(pc + 1);
+ u32 flags = 0;
+ if (BIT(inst, 8))
+ {
+ if (BIT(inst, 1, 2) != 0)
+ {
+ stream << s_field_insts[BIT(inst, 0, 3) - 2];
+ flags = (BIT(inst, 2) ? 0 : STEP_COND) | SUPPORTED;
+ }
+ }
+ else switch (BIT(inst2, 8, 8))
+ {
+ case 0x50:
+ if (BIT(inst, 0, 3) == 0)
+ {
+ stream << "SJE";
+ flags = STEP_OUT | SUPPORTED;
+ }
+ else
+ {
+ util::stream_format(stream, "SJ%c", s_reg_names[BIT(inst, 0, 3)]);
+ flags = STEP_OVER | SUPPORTED;
+ }
+ break;
+
+ case 0x80:
+ if (BIT(inst, 0, 3) != 0)
+ {
+ util::stream_format(stream, "AR%c", s_reg_names[BIT(inst, 0, 3)]);
+ flags = SUPPORTED;
+ }
+ break;
+
+ case 0x90:
+ if (BIT(inst, 0, 3) != 0)
+ {
+ util::stream_format(stream, "SB%c", s_reg_names[BIT(inst, 0, 3)]);
+ flags = SUPPORTED;
+ }
+ break;
+
+ case 0xa0: case 0xa1:
+ if (BIT(inst, 0, 3) != 0)
+ {
+ util::stream_format(stream, "A%c%c", BIT(inst2, 8) ? 'M' : 'N', s_reg_names[BIT(inst, 0, 3)]);
+ flags = SUPPORTED;
+ }
+ break;
+
+ case 0xc0: case 0xc1:
+ if (BIT(inst, 0, 3) != 0)
+ {
+ util::stream_format(stream, "%cR%c", BIT(inst2, 8) ? 'S' : 'L', s_reg_names[BIT(inst, 0, 3)]);
+ flags = SUPPORTED;
+ }
+ break;
+
+ case 0xc2: case 0xc3:
+ if (BIT(inst, 0, 3) != 0)
+ {
+ util::stream_format(stream, "%cCA", BIT(inst2, 8) ? 'S' : 'L');
+ flags = SUPPORTED;
+ }
+ break;
+
+ case 0xd0: case 0xd1:
+ if (BIT(inst, 0, 3) != 0)
+ {
+ util::stream_format(stream, "O%c%c", BIT(inst2, 8) ? 'M' : 'R', s_reg_names[BIT(inst, 0, 3)]);
+ flags = SUPPORTED;
+ }
+ break;
+
+ case 0xe0:
+ if (BIT(inst, 0, 3) != 0)
+ {
+ util::stream_format(stream, "C%cE", s_reg_names[BIT(inst, 0, 3)]);
+ flags = SUPPORTED | STEP_COND;
+ }
+ break;
+
+ case 0xe2:
+ if (BIT(inst, 0, 3) != 0)
+ {
+ stream << "CCE";
+ flags = SUPPORTED | STEP_COND;
+ }
+ break;
+ }
+
+ if (flags != 0)
+ {
+ u8 delta = inst2 & 0x00ff;
+ if (delta == 0)
+ {
+ u16 addr = opcodes.r16(pc + 2);
+ util::stream_format(stream, "%c ", BIT(inst, 6, 2) == 1 ? '+' : ' ');
+ if (BIT(inst, 7))
+ {
+ // Two-word relative addressing
+ if (BIT(inst, 6))
+ stream << '(';
+ util::stream_format(stream, "$%04X", pc + 2 + addr - (BIT(addr, 15) ? 0xffff : 0));
+ if (BIT(inst, 6))
+ stream << ')';
+ }
+ else if (BIT(inst, 6))
+ {
+ // Two-word absolute addressing (32K mode assumed; 65K mode does not use bit 15 for indirection)
+ if (BIT(addr, 15))
+ stream << '(';
+ util::stream_format(stream, "$%04X", addr & 0x7fff);
+ if (BIT(addr, 15))
+ stream << ')';
+ }
+ else
+ {
+ // Two-word constant addressing
+ stream << "=N";
+ if (BIT(addr, 15) && !BIT(inst, 8) && (inst2 & 0xef00) == 0x8000)
+ {
+ stream << '-';
+ addr ^= 0xffff;
+ }
+ util::stream_format(stream, "$%04X", addr);
+ }
+ }
+ else
+ {
+ // One-word addressing
+ util::stream_format(stream, "%c ", BIT(inst, 7) ? '*' : '-');
+ if (BIT(inst, 6))
+ stream << '(';
+ if (BIT(inst, 7))
+ util::stream_format(stream, "$%04X", pc + 1 + delta - (BIT(delta, 7) ? 0xff : 0));
+ else if (BIT(inst, 3, 3) != 0 && !BIT(inst, 6))
+ format_s8(stream, delta);
+ else if (delta == 0xff && !BIT(inst, 8))
+ stream << 'I';
+ else
+ util::stream_format(stream, "$%04X", delta);
+ if (BIT(inst, 6))
+ stream << ')';
+ }
+
+ // For field reference instructions, FLDBUF and FLDLEN are specified after address but before indexing
+ if (BIT(inst, 8))
+ util::stream_format(stream, ",%d,%d", BIT(inst2, 12, 4), BIT(inst2, 8, 4) + 1);
+
+ // For LCA, SCA and CCE, first index is a character index
+ if (!BIT(inst, 8) && (inst2 & 0xde00) == 0xc200)
+ util::stream_format(stream, ",%s", s_reg_long_names[BIT(inst, 0, 3)]);
+
+ // Ra indexing is specified last
+ if (BIT(inst, 3, 3) != 0)
+ util::stream_format(stream, ",%s", s_reg_long_names[BIT(inst, 3, 3)]);
+
+ return (delta == 0 ? 3 : 2) | flags;
+ }
+ else
+ {
+ util::stream_format(stream, "%-5s$%04X", "NUM", inst);
+ return 1 | SUPPORTED;
+ }
+ }
+ else if (BIT(inst, 8, 4) == 6 && BIT(inst, 5, 3) != 0)
+ {
+ // Decrement and repeat
+ util::stream_format(stream, "DR%-3c%d", s_reg_names[BIT(inst, 5, 3)], inst & 0x000f);
+ return 1 | STEP_COND | SUPPORTED;
+ }
+ else if (BIT(inst, 8, 4) == 7 && BIT(inst, 5, 3) != 0 && BIT(inst, 0, 3) != 0)
+ {
+ // Type 2 inter-register transfer (bits 5-7 specify origin register, bits 0-2 specify destination register)
+ util::stream_format(stream, "XF%-3c%s", s_reg_names[BIT(inst, 5, 3)], s_reg_long_names[BIT(inst, 0, 3)]);
+ return 1 | SUPPORTED;
+ }
+ else if (inst > 0x0b00 && inst < 0x0c00)
+ {
+ // Miscellaneous enhanced instructions
+ if (BIT(inst, 5, 3) != 0 && BIT(inst, 0, 3) < 6)
+ util::stream_format(stream, "%-5s%s", s_misc_page_insts[BIT(inst, 0, 3)], s_reg_long_names[BIT(inst, 5, 3)]);
+ else if (inst <= 0x0b0d)
+ util::stream_format(stream, "%-5s0", s_misc_micro_insts[BIT(inst, 0, 4) - 1]);
+ else
+ util::stream_format(stream, "%-5s$%04X", "NUM", inst);
+ return 1 | SUPPORTED;
+ }
+ else
+ return cdc1700_disassembler::dasm_register_reference(stream, pc, opcodes, inst);
+}
+
+offs_t cdc1700_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params)
+{
+ u16 inst = opcodes.r16(pc);
+ if (inst >= 0x1000)
+ {
+ stream << s_memory_insts[BIT(inst, 12, 4) - 1];
+ u8 delta = inst & 0x00ff;
+ if (delta == 0)
+ {
+ u16 addr = opcodes.r16(pc + 1);
+ util::stream_format(stream, "%c ", BIT(inst, 10, 2) == 1 ? '+' : ' ');
+ if (BIT(inst, 11))
+ {
+ // Two-word relative addressing
+ if (BIT(inst, 10))
+ stream << '(';
+ util::stream_format(stream, "$%04X", pc + 1 + addr - (BIT(addr, 15) ? 0xffff : 0));
+ if (BIT(inst, 10))
+ stream << ')';
+ }
+ else if (BIT(inst, 10))
+ {
+ // Two-word absolute addressing (32K mode assumed; 65K mode does not use bit 15 for indirection)
+ if (BIT(addr, 15))
+ stream << '(';
+ util::stream_format(stream, "$%04X", addr & 0x7fff);
+ if (BIT(addr, 15))
+ stream << ')';
+ }
+ else
+ {
+ // Two-word constant addressing
+ stream << "=N";
+ if (BIT(addr, 15) && (BIT(inst, 13, 3) == 1 || BIT(inst, 13, 3) == 4 || inst >= 0xf000))
+ {
+ stream << '-';
+ addr ^= 0xffff;
+ }
+ util::stream_format(stream, "$%04X", addr);
+ }
+ }
+ else
+ {
+ // One-word addressing
+ util::stream_format(stream, "%c ", BIT(inst, 11) ? '*' : '-');
+ if (BIT(inst, 10))
+ stream << '(';
+ if (BIT(inst, 11))
+ util::stream_format(stream, "$%04X", pc + delta - (BIT(delta, 7) ? 0xff : 0));
+ else if (BIT(inst, 8, 2) != 0 && !BIT(inst, 10))
+ format_s8(stream, delta);
+ else if (delta == 0xff)
+ stream << 'I';
+ else
+ util::stream_format(stream, "$%04X", delta);
+ if (BIT(inst, 10))
+ stream << ')';
+ }
+ if (BIT(inst, 8, 2) != 0)
+ util::stream_format(stream, ",%c", "IQB"[BIT(inst, 8, 2) - 1]);
+ return (delta == 0 ? 2 : 1) | (BIT(inst, 12, 4) == 5 ? STEP_OVER : BIT(inst, 8, 8) == 0x1c ? STEP_OUT : 0) | SUPPORTED;
+ }
+ else switch (BIT(inst, 8, 4))
+ {
+ case 1:
+ // Skip instructions
+ util::stream_format(stream, "%-5s%d", s_skip_insts[BIT(inst, 4, 4)], inst & 0x000f);
+ return 1 | STEP_COND | SUPPORTED;
+
+ case 8:
+ // Interregister operations
+ switch (inst & 0x00f8)
+ {
+ case 0x08:
+ util::stream_format(stream, "%-5s%s", "TRM", s_destregs[BIT(inst, 0, 3)]);
+ break;
+
+ case 0x10:
+ util::stream_format(stream, "%-5s%s", "TRQ", s_destregs[BIT(inst, 0, 3)]);
+ break;
+
+ case 0x18:
+ util::stream_format(stream, "%-5s%s", "TRB", s_destregs[BIT(inst, 0, 3)]);
+ break;
+
+ case 0x20:
+ util::stream_format(stream, "%-5s%s", "TRA", s_destregs[BIT(inst, 0, 3)]);
+ break;
+
+ case 0x28:
+ util::stream_format(stream, "%-5s%s", "AAM", s_destregs[BIT(inst, 0, 3)]);
+ break;
+
+ case 0x30:
+ util::stream_format(stream, "%-5s%s", "AAQ", s_destregs[BIT(inst, 0, 3)]);
+ break;
+
+ case 0x38:
+ util::stream_format(stream, "%-5s%s", "AAB", s_destregs[BIT(inst, 0, 3)]);
+ break;
+
+ case 0x40:
+ util::stream_format(stream, "%-5s%s", "CLR", s_destregs[BIT(inst, 0, 3)]);
+ break;
+
+ case 0x48:
+ util::stream_format(stream, "%-5s%s", "TCM", s_destregs[BIT(inst, 0, 3)]);
+ break;
+
+ case 0x50:
+ util::stream_format(stream, "%-5s%s", "TCQ", s_destregs[BIT(inst, 0, 3)]);
+ break;
+
+ case 0x58:
+ util::stream_format(stream, "%-5s%s", "TCB", s_destregs[BIT(inst, 0, 3)]);
+ break;
+
+ case 0x60:
+ util::stream_format(stream, "%-5s%s", "TCA", s_destregs[BIT(inst, 0, 3)]);
+ break;
+
+ case 0x68:
+ util::stream_format(stream, "%-5s%s", "EAM", s_destregs[BIT(inst, 0, 3)]);
+ break;
+
+ case 0x70:
+ util::stream_format(stream, "%-5s%s", "EAQ", s_destregs[BIT(inst, 0, 3)]);
+ break;
+
+ case 0x78:
+ util::stream_format(stream, "%-5s%s", "EAB", s_destregs[BIT(inst, 0, 3)]);
+ break;
+
+ case 0x80:
+ util::stream_format(stream, "%-5s%s", "SET", s_destregs[BIT(inst, 0, 3)]);
+ break;
+
+ case 0xa8:
+ util::stream_format(stream, "%-5s%s", "LAM", s_destregs[BIT(inst, 0, 3)]);
+ break;
+
+ case 0xb0:
+ util::stream_format(stream, "%-5s%s", "LAQ", s_destregs[BIT(inst, 0, 3)]);
+ break;
+
+ case 0xb8:
+ util::stream_format(stream, "%-5s%s", "LAB", s_destregs[BIT(inst, 0, 3)]);
+ break;
+
+ case 0xe8:
+ util::stream_format(stream, "%-5s%s", "CAM", s_destregs[BIT(inst, 0, 3)]);
+ break;
+
+ case 0xf0:
+ util::stream_format(stream, "%-5s%s", "CAQ", s_destregs[BIT(inst, 0, 3)]);
+ break;
+
+ case 0xf8:
+ util::stream_format(stream, "%-5s%s", "CAB", s_destregs[BIT(inst, 0, 3)]);
+ break;
+
+ default:
+ util::stream_format(stream, "%-5s$%04X", "NUM", inst);
+ break;
+ }
+ return 1 | SUPPORTED;
+
+ case 0xf:
+ // Shift instructions
+ if (BIT(inst, 5, 2) != 0)
+ util::stream_format(stream, "%c%c%-3c%d", "QAL"[BIT(inst, 5, 2) - 1], BIT(inst, 7) ? 'L' : 'R', 'S', inst & 0x001f);
+ else
+ util::stream_format(stream, "%-5s$%04X", "NUM", inst);
+ return 1 | SUPPORTED;
+
+ default:
+ return dasm_register_reference(stream, pc, opcodes, inst);
+ }
+}
diff --git a/src/devices/cpu/cdc1700/cdc1700d.h b/src/devices/cpu/cdc1700/cdc1700d.h
new file mode 100644
index 00000000000..63dd04a924a
--- /dev/null
+++ b/src/devices/cpu/cdc1700/cdc1700d.h
@@ -0,0 +1,37 @@
+// license:BSD-3-Clause
+// copyright-holders:AJR
+
+#ifndef MAME_CPU_CDC1700_CDC1700D_H
+#define MAME_CPU_CDC1700_CDC1700D_H
+
+#pragma once
+
+class cdc1700_disassembler : public util::disasm_interface
+{
+public:
+ // construction/destruction
+ cdc1700_disassembler();
+
+protected:
+ // util::disasm_interface overrides
+ virtual u32 opcode_alignment() const override;
+ virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params) override;
+
+ virtual offs_t dasm_register_reference(std::ostream &stream, offs_t pc, const data_buffer &opcodes, u16 inst);
+
+ // formatting helpers
+ void format_s8(std::ostream &stream, u8 value);
+};
+
+class cyber18_disassembler : public cdc1700_disassembler
+{
+public:
+ // construction/destruction
+ cyber18_disassembler();
+
+protected:
+ // cdc1700_disassembler overrides
+ virtual offs_t dasm_register_reference(std::ostream &stream, offs_t pc, const data_buffer &opcodes, u16 inst) override;
+};
+
+#endif // MAME_CPU_CDC1700_CDC1700D_H
diff --git a/src/devices/cpu/sigma2/sigma2d.cpp b/src/devices/cpu/sigma2/sigma2d.cpp
new file mode 100644
index 00000000000..e62cc38994e
--- /dev/null
+++ b/src/devices/cpu/sigma2/sigma2d.cpp
@@ -0,0 +1,393 @@
+// license:BSD-3-Clause
+// copyright-holders:AJR
+/***************************************************************************
+
+ SDS/XDS Sigma 2/3 & Xerox 530 (16-bit) disassemblers
+
+***************************************************************************/
+
+#include "emu.h"
+#include "sigma2d.h"
+
+namespace {
+
+const char *const s_inst_names[16] =
+{
+ "WD", "RD",
+ "S", "MUL",
+ "B", "DIV",
+ "BC", "COPY", // non-memory instructions
+ "LDA", "AND",
+ "ADD", "SUB",
+ "LDX", "CP",
+ "STA", "IM"
+};
+
+const char *const s_shift_names[8] =
+{
+ "SARS", "SALS", "SCRS", "SCLS", // Single shifts
+ "SARD", "SALD", "SCRD", "SCLD" // Double shifts
+};
+
+const char *const s_bc_names[8] =
+{
+ "BNO", "BNC", "BAZ", "BIX",
+ "BXNO", "BXNC", "BEN", "BAN"
+};
+
+const char *const s_copy_names[32] =
+{
+ "RAND", "", "RANDI", "", "RANDC", "", "", "",
+ "ROR", "RCPY", "RORI", "RCPYI", "RORC", "RCPYC", "", "",
+ "REOR", "", "REORI", "", "REORC", "", "", "",
+ "RADD", "RCLA", "RADDI", "RCLAI", "RADDC", "RCLAC", "", ""
+};
+
+const char *const s_sigma2_reg_names[8] =
+{
+ "Z", "P",
+ "L", "T",
+ "X1", "X2",
+ "E", "A"
+};
+
+const char *const s_xerox530_reg_names[8] =
+{
+ "Z", "P",
+ "L", "T",
+ "X", "B",
+ "E", "A"
+};
+
+} // anonymous namespace
+
+sigma2_disassembler::sigma2_disassembler(const char *const *reg_names)
+ : util::disasm_interface()
+ , m_reg_names(reg_names)
+{
+}
+
+sigma2_disassembler::sigma2_disassembler()
+ : sigma2_disassembler(s_sigma2_reg_names)
+{
+}
+
+xerox530_disassembler::xerox530_disassembler()
+ : sigma2_disassembler(s_xerox530_reg_names)
+{
+}
+
+u32 sigma2_disassembler::opcode_alignment() const
+{
+ return 1;
+}
+
+offs_t sigma2_disassembler::dasm_memory_reference(std::ostream &stream, offs_t pc, const data_buffer &opcodes, u16 inst) const
+{
+ if (BIT(inst, 10))
+ {
+ // Indirect addressing
+ stream << '*';
+ }
+ if (BIT(inst, 11))
+ {
+ // Self-relative addressing
+ util::stream_format(stream, "X'%04X'", (pc + (inst & 0x00ff) - (inst & 0x0100)) & 0xffff);
+ if (BIT(inst, 9))
+ stream << ',' << m_reg_names[4];
+ }
+ else if (BIT(inst, 8, 2) == 0 || BIT(inst, 8, 3) == 6)
+ {
+ // Nonrelative direct addressing
+ util::stream_format(stream, "X'%04X'", inst & 0x00ff);
+ if (BIT(inst, 9))
+ stream << ',' << m_reg_names[4];
+
+ // Interrupt exit sequence (very special case in which LDX loads PSD and not X1)
+ if (inst == 0x00d8 && (opcodes.r16(pc + 1) & 0xf000) == 0xc000)
+ return 1 | STEP_OUT | step_over_extra(1) | SUPPORTED;
+ }
+ else
+ {
+ // Indexed addressing
+ if ((inst & 0x00ff) <= 9)
+ util::stream_format(stream, "%d,", inst & 0x00ff);
+ else
+ util::stream_format(stream, "X'%X',", inst & 0x00ff);
+ if (BIT(inst, 9))
+ stream << m_reg_names[4];
+ if (BIT(inst, 8))
+ stream << ',' << m_reg_names[5];
+ }
+
+ return 1 | SUPPORTED;
+}
+
+offs_t sigma2_disassembler::dasm_read_direct(std::ostream &stream, offs_t pc, const data_buffer &opcodes, u16 inst) const
+{
+ // RD internal control functions
+ if (inst == 0x1041)
+ {
+ stream << "SIO";
+ return 1 | SUPPORTED;
+ }
+ else if (inst == 0x1042)
+ {
+ stream << "TIO";
+ return 1 | SUPPORTED;
+ }
+ else if (inst == 0x1044)
+ {
+ stream << "TDV";
+ return 1 | SUPPORTED;
+ }
+ else if (inst == 0x1048)
+ {
+ stream << "HIO";
+ return 1 | SUPPORTED;
+ }
+ else if (inst == 0x1050)
+ {
+ stream << "AIO";
+ return 1 | SUPPORTED;
+ }
+ else if (inst > 0x1080 && inst <= 0x10bf)
+ {
+ // Multiple precision mode prefix
+ util::stream_format(stream, "%-8s%s,%d", "SMP", m_reg_names[BIT(inst, 0, 3)], BIT(inst, 3, 3));
+ return 1 | SUPPORTED;
+ }
+ else
+ {
+ // Fall back to disassembling RD using RIXS modes
+ util::stream_format(stream, "%-8s", "RD");
+ return dasm_memory_reference(stream, pc, opcodes, inst);
+ }
+}
+
+offs_t xerox530_disassembler::dasm_read_direct(std::ostream &stream, offs_t pc, const data_buffer &opcodes, u16 inst) const
+{
+ // RD internal control functions
+ if (inst == 0x1041)
+ {
+ stream << "SIO";
+ return 1 | SUPPORTED;
+ }
+ else if (inst == 0x1042)
+ {
+ stream << "TIO";
+ return 1 | SUPPORTED;
+ }
+ else if (inst == 0x1044)
+ {
+ stream << "TDV";
+ return 1 | SUPPORTED;
+ }
+ else if (inst == 0x1048)
+ {
+ stream << "HIO";
+ return 1 | SUPPORTED;
+ }
+ else if (inst == 0x1050)
+ {
+ stream << "AIO";
+ return 1 | SUPPORTED;
+ }
+ else if (inst >= 0x108a && inst <= 0x108e)
+ {
+ // General register instructions
+ u16 inst2 = opcodes.r16(pc + 1);
+ switch (BIT(inst2, 12, 4))
+ {
+ case 8:
+ util::stream_format(stream, "LW,%-5s", m_reg_names[BIT(inst, 0, 3)]);
+ break;
+
+ case 9:
+ util::stream_format(stream, "AND,%-4s", m_reg_names[BIT(inst, 0, 3)]);
+ break;
+
+ case 0xa:
+ util::stream_format(stream, "AW,%-5s", m_reg_names[BIT(inst, 0, 3)]);
+ break;
+
+ case 0xb:
+ util::stream_format(stream, "SW,%-5s", m_reg_names[BIT(inst, 0, 3)]);
+ break;
+
+ case 0xd:
+ util::stream_format(stream, "CW,%-5s", m_reg_names[BIT(inst, 0, 3)]);
+ break;
+
+ case 0xe:
+ util::stream_format(stream, "STW,%-4s", m_reg_names[BIT(inst, 0, 3)]);
+ break;
+
+ default:
+ util::stream_format(stream, "%-8sX'%04X'", "DATA", inst);
+ return 1 | SUPPORTED;
+ }
+ return 1 + dasm_memory_reference(stream, pc + 1, opcodes, inst2);
+ }
+ else if (inst == 0x109e)
+ {
+ // Floating mode: LDA, STA, ADD, SUB, MUL, DIV, CP executed as FLD, FST, FAD, FSB, FML, FDV, FCP until next branch
+ stream << "SFM";
+ return 1 | SUPPORTED;
+ }
+ else if (inst >= 0x1088 && inst <= 0x10bf)
+ {
+ u16 inst2 = opcodes.r16(pc + 1);
+ if (BIT(inst, 0, 3) <= 1 || BIT(inst, 0, 3) == 7)
+ {
+ // Field addressing instructions
+ switch (BIT(inst2, 12, 4))
+ {
+ case 5:
+ stream << "CLF";
+ break;
+
+ case 8:
+ stream << "LLF";
+ break;
+
+ case 9:
+ stream << "LAF";
+ break;
+
+ case 0xa:
+ stream << "STF";
+ break;
+
+ case 0xb:
+ stream << "SZF";
+ break;
+
+ case 0xc:
+ stream << "SOF";
+ break;
+
+ case 0xd:
+ stream << "CAF";
+ break;
+
+ case 0xf:
+ stream << "SLF";
+ break;
+
+ default:
+ util::stream_format(stream, "%-8sX'%04X'", "DATA", inst);
+ return 1 | SUPPORTED;
+ }
+ util::stream_format(stream, ",%s,%d ", BIT(inst, 3, 3) == 1 ? "0" : m_reg_names[BIT(inst, 3, 3)], util::sext(inst, 3));
+ return 1 + dasm_memory_reference(stream, pc + 1, opcodes, inst2);
+ }
+ else if (inst == 0x1096)
+ {
+ // Double-register instructions
+ switch (BIT(inst2, 12, 4))
+ {
+ case 8:
+ util::stream_format(stream, "%-8s", "LDD");
+ break;
+
+ case 0xa:
+ util::stream_format(stream, "%-8s", "DAD");
+ break;
+
+ case 0xb:
+ util::stream_format(stream, "%-8s", "DSB");
+ break;
+
+ case 0xd:
+ util::stream_format(stream, "%-8s", "CPD");
+ break;
+
+ case 0xe:
+ util::stream_format(stream, "%-8s", "STD");
+ break;
+
+ default:
+ util::stream_format(stream, "%-8sX'%04X'", "DATA", inst);
+ return 1 | SUPPORTED;
+ }
+ return 1 + dasm_memory_reference(stream, pc + 1, opcodes, inst2);
+ }
+ else if (BIT(inst, 3, 3) + BIT(inst, 0, 3) <= 8 && (BIT(inst2, 12, 4) == 8 || BIT(inst2, 12, 4) == 0xe))
+ {
+ // Multiple-register load and store instructions
+ util::stream_format(stream, "%-8s", inst2 >= 0xe000 ? "STM" : "LDM");
+ offs_t result = 1 + dasm_memory_reference(stream, pc + 1, opcodes, inst2);
+ util::stream_format(stream, ",%s,%d", m_reg_names[BIT(inst, 0, 3)], BIT(inst, 3, 3));
+ return result;
+ }
+ else
+ {
+ util::stream_format(stream, "%-8sX'%04X'", "DATA", inst);
+ return 1 | SUPPORTED;
+ }
+ }
+ else
+ {
+ // Fall back to disassembling RD using RIXS modes
+ util::stream_format(stream, "%-8s", "RD");
+ return dasm_memory_reference(stream, pc, opcodes, inst);
+ }
+}
+
+offs_t sigma2_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params)
+{
+ u16 inst = opcodes.r16(pc);
+ if ((inst & 0xf000) == 0x6000)
+ {
+ // Conditional branch instructions use self-relative addressing only
+ util::stream_format(stream, "%-8sX'%04X'", s_bc_names[BIT(inst, 9, 3)], (pc + (inst & 0x00ff) - (inst & 0x0100)) & 0xffff);
+ return 1 | STEP_COND | SUPPORTED;
+ }
+ else if ((inst & 0xf000) == 0x7000)
+ {
+ // Copy instructions
+ const char *name = s_copy_names[BIT(inst, 7, 5)];
+ if (name[0] != '\0')
+ {
+ util::stream_format(stream, "%-8s", name);
+
+ // Optionally invert source
+ if (BIT(inst, 3))
+ stream << '*';
+ util::stream_format(stream, "%s,%s", m_reg_names[BIT(inst, 0, 3)], m_reg_names[BIT(inst, 4, 3)]);
+
+ // Recognize branch-and-link calling convention
+ if (inst == 0x75a1 && (opcodes.r16(pc + 1) & 0xf000) == 0x4000)
+ return 1 | STEP_OVER | step_over_extra(1) | SUPPORTED;
+ else if ((inst & 0xfcff) == 0x7492)
+ return 1 | STEP_OUT | SUPPORTED;
+ }
+ else
+ util::stream_format(stream, "%-8sX'%04X'", "DATA", inst);
+ return 1 | SUPPORTED;
+ }
+ else if ((inst & 0xfc00) == 0x2000)
+ {
+ // Shift instructions
+ util::stream_format(stream, "%-8s%d", s_shift_names[BIT(inst, 5, 3)], BIT(inst, 0, 5));
+ if (BIT(inst, 8, 2) != 0)
+ {
+ // Shift count may be indexed
+ stream << ',';
+ if (BIT(inst, 9))
+ stream << m_reg_names[4];
+ if (BIT(inst, 8))
+ stream << ',' << m_reg_names[5];
+ }
+ return 1 | SUPPORTED;
+ }
+ else if ((inst & 0xf000) == 0x1000)
+ return dasm_read_direct(stream, pc, opcodes, inst);
+ else
+ {
+ // Memory reference instructions (RIXS)
+ util::stream_format(stream, "%-8s", s_inst_names[BIT(inst, 12, 4)]);
+ return dasm_memory_reference(stream, pc, opcodes, inst);
+ }
+}
diff --git a/src/devices/cpu/sigma2/sigma2d.h b/src/devices/cpu/sigma2/sigma2d.h
new file mode 100644
index 00000000000..afa187f1abf
--- /dev/null
+++ b/src/devices/cpu/sigma2/sigma2d.h
@@ -0,0 +1,40 @@
+// license:BSD-3-Clause
+// copyright-holders:AJR
+
+#ifndef MAME_CPU_SIGMA2_SIGMA2D_H
+#define MAME_CPU_SIGMA2_SIGMA2D_H
+
+#pragma once
+
+class sigma2_disassembler : public util::disasm_interface
+{
+public:
+ // construction/destruction
+ sigma2_disassembler();
+
+protected:
+ sigma2_disassembler(const char *const *reg_names);
+
+ // util::disasm_interface overrides
+ virtual u32 opcode_alignment() const override;
+ virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params) override;
+
+ // disassembly helpers
+ offs_t dasm_memory_reference(std::ostream &stream, offs_t pc, const data_buffer &opcodes, u16 inst) const;
+ virtual offs_t dasm_read_direct(std::ostream &stream, offs_t pc, const data_buffer &opcodes, u16 inst) const;
+
+ const char *const *const m_reg_names;
+};
+
+class xerox530_disassembler : public sigma2_disassembler
+{
+public:
+ // construction/destruction
+ xerox530_disassembler();
+
+protected:
+ // sigma2_disassembler overrides
+ virtual offs_t dasm_read_direct(std::ostream &stream, offs_t pc, const data_buffer &opcodes, u16 inst) const override;
+};
+
+#endif // MAME_CPU_SIGMA2_SIGMA2D_H
diff --git a/src/tools/unidasm.cpp b/src/tools/unidasm.cpp
index 13846a2f560..918c6fab73f 100644
--- a/src/tools/unidasm.cpp
+++ b/src/tools/unidasm.cpp
@@ -29,6 +29,7 @@ using util::BIT;
#include "cpu/bcp/bcpdasm.h"
#include "cpu/capricorn/capricorn_dasm.h"
#include "cpu/ccpu/ccpudasm.h"
+#include "cpu/cdc1700/cdc1700d.h"
#include "cpu/clipper/clipperd.h"
#include "cpu/cop400/cop410ds.h"
#include "cpu/cop400/cop420ds.h"
@@ -151,6 +152,7 @@ using util::BIT;
#include "cpu/se3208/se3208dis.h"
#include "cpu/sh/sh_dasm.h"
#include "cpu/sharc/sharcdsm.h"
+#include "cpu/sigma2/sigma2d.h"
#include "cpu/sm510/sm510d.h"
#include "cpu/sm8500/sm8500d.h"
#include "cpu/sparc/sparcdasm.h"
@@ -402,6 +404,7 @@ static const dasm_table_entry dasm_table[] =
{ "b6100", le, 0, []() -> util::disasm_interface * { return new b6100_disassembler; } },
{ "capricorn", le, 0, []() -> util::disasm_interface * { return new capricorn_disassembler; } },
{ "ccpu", le, 0, []() -> util::disasm_interface * { return new ccpu_disassembler; } },
+ { "cdc1700", be, -1, []() -> util::disasm_interface * { return new cdc1700_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); } },
{ "cdp1805", le, 0, []() -> util::disasm_interface * { return new cosmac_disassembler(cosmac_disassembler::TYPE_1805); } },
@@ -419,6 +422,7 @@ static const dasm_table_entry dasm_table[] =
{ "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; } },
+ { "cyber18", be, -1, []() -> util::disasm_interface * { return new cyber18_disassembler; } },
{ "dp8344", le, -1, []() -> util::disasm_interface * { return new dp8344_disassembler; } },
{ "ds5002fp", le, 0, []() -> util::disasm_interface * { return new ds5002fp_disassembler; } },
{ "ds80c320", le, 0, []() -> util::disasm_interface * { return new ds80c320_disassembler; } },
@@ -570,6 +574,7 @@ static const dasm_table_entry dasm_table[] =
{ "sh4", le, 0, []() -> util::disasm_interface * { return new sh_disassembler(true); } },
{ "sh4be", be, 0, []() -> util::disasm_interface * { return new sh_disassembler(true); } },
{ "sharc", le, -3, []() -> util::disasm_interface * { return new sharc_disassembler; } },
+ { "sigma2", be, -1, []() -> util::disasm_interface * { return new sigma2_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; } },
@@ -683,6 +688,7 @@ static const dasm_table_entry dasm_table[] =
{ "xavix", le, 0, []() -> util::disasm_interface * { return new xavix_disassembler; } },
{ "xavix2000", le, 0, []() -> util::disasm_interface * { return new xavix2000_disassembler; } },
{ "xavix2", le, 0, []() -> util::disasm_interface * { return new xavix2_disassembler; } },
+ { "xerox530", be, -1, []() -> util::disasm_interface * { return new xerox530_disassembler; } },
{ "z180", le, 0, []() -> util::disasm_interface * { return new z180_disassembler; } },
{ "z8", be, 0, []() -> util::disasm_interface * { return new z8_disassembler; } },
{ "z80", le, 0, []() -> util::disasm_interface * { return new z80_disassembler; } },