summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/devices/cpu/ddp516/ddp516d.cpp2
-rw-r--r--src/devices/cpu/v620/v620dasm.cpp187
-rw-r--r--src/devices/cpu/v620/v620dasm.h15
-rw-r--r--src/tools/unidasm.cpp1
4 files changed, 139 insertions, 66 deletions
diff --git a/src/devices/cpu/ddp516/ddp516d.cpp b/src/devices/cpu/ddp516/ddp516d.cpp
index a841cdc2ddc..e8a367713c5 100644
--- a/src/devices/cpu/ddp516/ddp516d.cpp
+++ b/src/devices/cpu/ddp516/ddp516d.cpp
@@ -2,7 +2,7 @@
// copyright-holders:AJR
/***************************************************************************
- Computer Control Company/Honeywell DDP-516 disassembler
+ Honeywell (Computer Control Division) DDP-516 disassembler
Alternate disassemblers are provided for Prime Computer's 16S, 32S,
32R, 64R and 64V instruction modes, which are increasingly elaborate
diff --git a/src/devices/cpu/v620/v620dasm.cpp b/src/devices/cpu/v620/v620dasm.cpp
index 74af4537df8..73f0b1aa203 100644
--- a/src/devices/cpu/v620/v620dasm.cpp
+++ b/src/devices/cpu/v620/v620dasm.cpp
@@ -17,11 +17,16 @@ v620_disassembler::v620_disassembler()
{
}
-v75_disassembler::v75_disassembler()
+v620f_disassembler::v620f_disassembler()
: v620_disassembler()
{
}
+v75_disassembler::v75_disassembler()
+ : v620f_disassembler()
+{
+}
+
u32 v620_disassembler::opcode_alignment() const
{
return 1;
@@ -85,28 +90,32 @@ static const char *const s_rr_ops[3] =
"ADR", "SBR", "T"
};
-const std::unordered_map<u16, std::array<const char *, 3>> s_cond_map =
+static const char *const s_jxif_ops[10][3] =
{
- { 0000, { "JMP", "JMPM", "XEC" } }, // unconditional
- { 0001, { "JOF", "JOFM", "XOF" } }, // overflow set
- { 0002, { "JAP", "JAPM", "XAP" } }, // A positive
- { 0004, { "JAN", "JANM", "XAN" } }, // A negative
- { 0007, { "JOFN", "JOFNM", "XOFN" } }, // overflow not set (620/f)
- { 0010, { "JAZ", "JAZM", "XAZ" } }, // A zero
- { 0016, { "JANZ", "JANZM", "XANZ" } }, // A not zero (620/f)
- { 0020, { "JBZ", "JBZM", "XBZ" } }, // B zero
- { 0026, { "JBNZ", "JBNZM", "XBNZ" } }, // B not zero (620/f)
- { 0040, { "JXZ", "JXZM", "XXZ" } }, // X zero
- { 0046, { "JXNZ", "JXNZM", "XXNZ" } }, // X not zero (620/f)
- { 0100, { "JSS1", "JS1M", "XS1M" } }, // sense switch 1 set
- { 0106, { "JS1N", "JS1NM", "XS1NM" } }, // sense switch 1 not set (620/f)
- { 0200, { "JSS2", "JS2M", "XS2M" } }, // sense switch 2 set
- { 0206, { "JS2N", "JS2NM", "XS2NM" } }, // sense switch 2 not set (620/f)
- { 0400, { "JSS3", "JS3M", "XS3M" } }, // sense switch 3 set
- { 0406, { "JS3N", "JS3NM", "XS3NM" } } // sense switch 3 not set (620/f)
+ { "JMP", "JMPM", "XEC" }, // unconditional (00x000)
+ { "JOF", "JOFM", "XOF" }, // overflow set (00x001)
+ { "JAP", "JAPM", "XAP" }, // A positive (00x002)
+ { "JAN", "JANM", "XAN" }, // A negative (00x004)
+ { "JAZ", "JAZM", "XAZ" }, // A zero (00x010)
+ { "JBZ", "JBZM", "XBZ" }, // B zero (00x020)
+ { "JXZ", "JXZM", "XXZ" }, // X zero (00x040)
+ { "JSS1", "JS1M", "XS1M" }, // sense switch 1 set (00x100)
+ { "JSS2", "JS2M", "XS2M" }, // sense switch 2 set (00x200)
+ { "JSS3", "JS3M", "XS3M" } // sense switch 3 set (00x400)
};
-const std::unordered_map<u8, const char *> s_fpp_map =
+static const char *const s_jxif_ext_ops[7][3] =
+{
+ { "JOFN", "JOFNM", "XOFN" }, // overflow not set (00x007)
+ { "JANZ", "JANZM", "XANZ" }, // A not zero (00x016)
+ { "JBNZ", "JBNZM", "XBNZ" }, // B not zero (00x026)
+ { "JXNZ", "JXNZM", "XXNZ" }, // X not zero (00x046)
+ { "JS1N", "JS1NM", "XS1NM" }, // sense switch 1 not set (00x106)
+ { "JS2N", "JS2NM", "XS2NM" }, // sense switch 2 not set (00x206)
+ { "JS3N", "JS3NM", "XS3NM" } // sense switch 3 not set (00x406)
+};
+
+static const std::unordered_map<u8, const char *> s_fpp_map =
{
{ 0001, "FDV" },
{ 0010, "FAD" },
@@ -140,6 +149,53 @@ void v620_disassembler::format_address(std::ostream &stream, u16 addr) const
util::stream_format(stream, "%05o", addr);
}
+offs_t v620_disassembler::dasm_jxif(std::ostream &stream, u16 inst, u16 dest, offs_t pc, const v620_disassembler::data_buffer &opcodes) const
+{
+ // Jump and execute instructions
+ const u16 cond = BIT(inst, 0, 9);
+ if ((cond & (cond - 1)) == 0)
+ {
+ const char *op = s_jxif_ops[32 - count_leading_zeros_32(cond)][BIT(inst, 9, 2) - 1];
+ if (BIT(dest, 15))
+ util::stream_format(stream, "%-8s", std::string(op) + "*");
+ else
+ util::stream_format(stream, "%-8s", op);
+ }
+ else
+ {
+ std::string name = util::string_format("%cIF", inst < 03000 ? 'J' : 'X');
+ if (!BIT(inst, 9))
+ name += 'M';
+ if (BIT(dest, 15))
+ name += '*';
+ util::stream_format(stream, "%-8s", name);
+ format_number(stream, cond);
+ stream << ',';
+ }
+ format_address(stream, dest & 077777);
+ if (inst == 001000 && BIT(dest, 15))
+ return 2 | STEP_OUT | SUPPORTED;
+ else
+ return 2 | (BIT(inst, 10) ? STEP_OVER : 0) | (cond != 0 ? STEP_COND : 0) | SUPPORTED;
+}
+
+offs_t v620f_disassembler::dasm_jxif(std::ostream &stream, u16 inst, u16 dest, offs_t pc, const v620_disassembler::data_buffer &opcodes) const
+{
+ const u16 cond = BIT(inst, 0, 9);
+ if (cond == 0007 || (cond >= 0016 && (((cond - 6) & (cond - 7)) == 0)))
+ {
+ const char *op = s_jxif_ext_ops[32 - 3 - count_leading_zeros_32(cond)][BIT(inst, 9, 2) - 1];
+ if (BIT(dest, 15))
+ util::stream_format(stream, "%-8s", std::string(op) + "*");
+ else
+ util::stream_format(stream, "%-8s", op);
+ format_address(stream, dest & 077777);
+ return 2 | (BIT(inst, 10) ? STEP_OVER : 0) | STEP_COND | SUPPORTED;
+ }
+ else
+ return v620_disassembler::dasm_jxif(stream, inst, dest, pc, opcodes);
+}
+
offs_t v620_disassembler::dasm_004xxx(std::ostream &stream, u16 inst, offs_t pc, const v620_disassembler::data_buffer &opcodes) const
{
if (inst < 004600)
@@ -176,14 +232,28 @@ offs_t v75_disassembler::dasm_004xxx(std::ostream &stream, u16 inst, offs_t pc,
return 2 | SUPPORTED;
}
else
- return v620_disassembler::dasm_004xxx(stream, inst, pc, opcodes);
+ return v620f_disassembler::dasm_004xxx(stream, inst, pc, opcodes);
}
offs_t v620_disassembler::dasm_misc(std::ostream &stream, u16 inst, offs_t pc, const v620_disassembler::data_buffer &opcodes) const
{
+ if (inst == 007400)
+ stream << "ROF";
+ else if (inst == 007401)
+ stream << "SOF";
+ else
+ {
+ util::stream_format(stream, "%-8s", "DATA");
+ format_number(stream, inst);
+ }
+ return 1 | SUPPORTED;
+}
+
+offs_t v620f_disassembler::dasm_misc(std::ostream &stream, u16 inst, offs_t pc, const v620f_disassembler::data_buffer &opcodes) const
+{
if ((inst & 0177700) == 006400)
{
- // Bit test (620/f)
+ // Bit test (620/f-10 Optional Instruction Set)
u16 dest = opcodes.r16(pc + 1);
util::stream_format(stream, "%s%-6c", "BT", BIT(dest, 15) ? '*' : ' ');
format_number(stream, BIT(inst, 0, 6));
@@ -193,7 +263,7 @@ offs_t v620_disassembler::dasm_misc(std::ostream &stream, u16 inst, offs_t pc, c
}
else if (inst == 006505 || inst == 006506)
{
- // Jump and set return in index (620/f)
+ // Jump and set return in index
u16 dest = opcodes.r16(pc + 1);
util::stream_format(stream, "%s%-5c", "JSR", BIT(dest, 15) ? '*' : ' ');
format_address(stream, dest & 077777);
@@ -202,7 +272,7 @@ offs_t v620_disassembler::dasm_misc(std::ostream &stream, u16 inst, offs_t pc, c
}
else if ((inst & 0177704) == 006604)
{
- // Skip on register equal (620/f)
+ // Skip on register equal (620/f-10 Optional Instruction Set)
u8 mode = BIT(inst, 0, 3);
u16 addr = opcodes.r16(pc + 1);
util::stream_format(stream, "%s%-5c", "SRE", BIT(addr, 15) ? '*' : ' ');
@@ -219,7 +289,7 @@ offs_t v620_disassembler::dasm_misc(std::ostream &stream, u16 inst, offs_t pc, c
}
else if ((inst & 0177774) == 006704)
{
- // Indexed jump (620/f)
+ // Indexed jump
u8 mode = BIT(inst, 0, 3);
u16 dest = opcodes.r16(pc + 1);
util::stream_format(stream, "%s%-4c", "IJMP", BIT(dest, 15) ? '*' : ' ');
@@ -232,21 +302,13 @@ offs_t v620_disassembler::dasm_misc(std::ostream &stream, u16 inst, offs_t pc, c
format_address(stream, (mode == 4 ? pc + 1 + dest : dest) & 077777);
return 2 | SUPPORTED;
}
- else
+ else if (inst == 007402)
{
- if (inst == 007400)
- stream << "ROF";
- else if (inst == 007401)
- stream << "SOF";
- else if (inst == 007402)
- stream << "TSA"; // switches to A (620/f)
- else
- {
- util::stream_format(stream, "%-8s", "DATA");
- format_number(stream, inst);
- }
+ stream << "TSA"; // switches to A
return 1 | SUPPORTED;
}
+ else
+ return v620_disassembler::dasm_misc(stream, inst, pc, opcodes);
}
offs_t v75_disassembler::dasm_misc(std::ostream &stream, u16 inst, offs_t pc, const v75_disassembler::data_buffer &opcodes) const
@@ -307,7 +369,7 @@ offs_t v75_disassembler::dasm_misc(std::ostream &stream, u16 inst, offs_t pc, co
return 2 | STEP_COND | SUPPORTED;
}
else
- return v620_disassembler::dasm_misc(stream, inst, pc, opcodes);
+ return v620f_disassembler::dasm_misc(stream, inst, pc, opcodes);
}
offs_t v620_disassembler::dasm_io(std::ostream &stream, u16 inst, offs_t pc, const v620_disassembler::data_buffer &opcodes) const
@@ -349,7 +411,7 @@ offs_t v620_disassembler::dasm_io(std::ostream &stream, u16 inst, offs_t pc, con
}
}
-offs_t v75_disassembler::dasm_io(std::ostream &stream, u16 inst, offs_t pc, const v620_disassembler::data_buffer &opcodes) const
+offs_t v620f_disassembler::dasm_io(std::ostream &stream, u16 inst, offs_t pc, const v620f_disassembler::data_buffer &opcodes) const
{
if ((inst & 0177000) == 0104000)
{
@@ -358,6 +420,11 @@ offs_t v75_disassembler::dasm_io(std::ostream &stream, u16 inst, offs_t pc, cons
return 1 | SUPPORTED;
}
+ return v620_disassembler::dasm_io(stream, inst, pc, opcodes);
+}
+
+offs_t v75_disassembler::dasm_io(std::ostream &stream, u16 inst, offs_t pc, const v75_disassembler::data_buffer &opcodes) const
+{
if ((inst & 0177400) == 0105400)
{
// Floating point processor option
@@ -374,7 +441,7 @@ offs_t v75_disassembler::dasm_io(std::ostream &stream, u16 inst, offs_t pc, cons
}
}
- return v620_disassembler::dasm_io(stream, inst, pc, opcodes);
+ return v620f_disassembler::dasm_io(stream, inst, pc, opcodes);
}
offs_t v620_disassembler::disassemble(std::ostream &stream, offs_t pc, const v620_disassembler::data_buffer &opcodes, const v620_disassembler::data_buffer &params)
@@ -450,6 +517,18 @@ offs_t v620_disassembler::disassemble(std::ostream &stream, offs_t pc, const v62
// Increment or decrement
switch (inst & 000477)
{
+ case 001:
+ util::stream_format(stream, "%cCA", BIT(inst, 7) ? 'D' : 'I');
+ break;
+
+ case 002:
+ util::stream_format(stream, "%cCB", BIT(inst, 7) ? 'D' : 'I');
+ break;
+
+ case 004:
+ util::stream_format(stream, "%cCX", BIT(inst, 7) ? 'D' : 'I');
+ break;
+
case 011:
util::stream_format(stream, "%cAR", BIT(inst, 7) ? 'D' : 'I');
break;
@@ -549,33 +628,13 @@ offs_t v620_disassembler::disassemble(std::ostream &stream, offs_t pc, const v62
return dasm_004xxx(stream, inst, pc, opcodes);
else if (inst >= 001000 && inst < 004000)
{
- // Jump and execute instructions
- u16 dest = opcodes.r16(pc + 1);
- u16 cond = BIT(inst, 0, 9);
- auto lookup = s_cond_map.find(cond);
- if (lookup != s_cond_map.end())
- {
- if (BIT(dest, 15))
- util::stream_format(stream, "%-8s", std::string(lookup->second[BIT(inst, 9, 2) - 1]) + "*");
- else
- util::stream_format(stream, "%-8s", lookup->second[BIT(inst, 9, 2) - 1]);
- }
- else
+ if (inst == 001006)
{
- std::string name = util::string_format("%cIF", inst < 03000 ? 'J' : 'X');
- if (!BIT(inst, 9))
- name += 'M';
- if (BIT(dest, 15))
- name += '*';
- util::stream_format(stream, "%-8s", name);
- format_number(stream, cond);
- stream << ',';
+ stream << "USKP"; // first documented for 620/f, but probably supported on earlier models
+ return 1 | SUPPORTED;
}
- format_address(stream, dest & 077777);
- if (inst == 001000 && BIT(dest, 15))
- return 2 | STEP_OUT | SUPPORTED;
else
- return 2 | (BIT(inst, 10) ? STEP_OVER : 0) | (cond != 0 ? STEP_COND : 0) | SUPPORTED;
+ return dasm_jxif(stream, inst, opcodes.r16(pc + 1), pc, opcodes);
}
else
{
diff --git a/src/devices/cpu/v620/v620dasm.h b/src/devices/cpu/v620/v620dasm.h
index 50054231c57..8c93150cf9b 100644
--- a/src/devices/cpu/v620/v620dasm.h
+++ b/src/devices/cpu/v620/v620dasm.h
@@ -17,6 +17,7 @@ protected:
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_jxif(std::ostream &stream, u16 inst, u16 dest, offs_t pc, const v620_disassembler::data_buffer &opcodes) const;
virtual offs_t dasm_004xxx(std::ostream &stream, u16 inst, offs_t pc, const data_buffer &opcodes) const;
virtual offs_t dasm_misc(std::ostream &stream, u16 inst, offs_t pc, const data_buffer &opcodes) const;
virtual offs_t dasm_io(std::ostream &stream, u16 inst, offs_t pc, const data_buffer &opcodes) const;
@@ -26,7 +27,19 @@ protected:
void format_address(std::ostream &stream, u16 addr) const;
};
-class v75_disassembler : public v620_disassembler
+class v620f_disassembler : public v620_disassembler
+{
+public:
+ // construction/destruction
+ v620f_disassembler();
+
+protected:
+ virtual offs_t dasm_jxif(std::ostream &stream, u16 inst, u16 dest, offs_t pc, const v620_disassembler::data_buffer &opcodes) const override;
+ virtual offs_t dasm_misc(std::ostream &stream, u16 inst, offs_t pc, const data_buffer &opcodes) const override;
+ virtual offs_t dasm_io(std::ostream &stream, u16 inst, offs_t pc, const data_buffer &opcodes) const override;
+};
+
+class v75_disassembler : public v620f_disassembler
{
public:
// construction/destruction
diff --git a/src/tools/unidasm.cpp b/src/tools/unidasm.cpp
index 0553d8f338c..a639c963088 100644
--- a/src/tools/unidasm.cpp
+++ b/src/tools/unidasm.cpp
@@ -694,6 +694,7 @@ static const dasm_table_entry dasm_table[] =
{ "upi41", le, 0, []() -> util::disasm_interface * { return new mcs48_disassembler(true, false); } },
{ "v60", le, 0, []() -> util::disasm_interface * { return new v60_disassembler; } },
{ "v620", be, -1, []() -> util::disasm_interface * { return new v620_disassembler; } },
+ { "v620f", be, -1, []() -> util::disasm_interface * { return new v620f_disassembler; } },
{ "v75", be, -1, []() -> util::disasm_interface * { return new v75_disassembler; } },
{ "v810", le, 0, []() -> util::disasm_interface * { return new v810_disassembler; } },
{ "v850", le, 0, []() -> util::disasm_interface * { return new v850_disassembler; } },