summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/mcs96
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/mcs96')
-rw-r--r--src/devices/cpu/mcs96/i8x9x.cpp23
-rw-r--r--src/devices/cpu/mcs96/i8x9x.h3
-rw-r--r--src/devices/cpu/mcs96/i8x9xd.cpp19
-rw-r--r--src/devices/cpu/mcs96/i8x9xd.h26
-rw-r--r--src/devices/cpu/mcs96/i8xc196.cpp5
-rw-r--r--src/devices/cpu/mcs96/i8xc196.h3
-rw-r--r--src/devices/cpu/mcs96/i8xc196d.cpp18
-rw-r--r--src/devices/cpu/mcs96/i8xc196d.h26
-rw-r--r--src/devices/cpu/mcs96/mcs96.cpp272
-rw-r--r--src/devices/cpu/mcs96/mcs96.h40
-rw-r--r--src/devices/cpu/mcs96/mcs96d.cpp278
-rw-r--r--src/devices/cpu/mcs96/mcs96d.h64
-rw-r--r--src/devices/cpu/mcs96/mcs96make.py25
13 files changed, 463 insertions, 339 deletions
diff --git a/src/devices/cpu/mcs96/i8x9x.cpp b/src/devices/cpu/mcs96/i8x9x.cpp
index c3a6c7876af..cdb65bd3954 100644
--- a/src/devices/cpu/mcs96/i8x9x.cpp
+++ b/src/devices/cpu/mcs96/i8x9x.cpp
@@ -10,6 +10,7 @@
#include "emu.h"
#include "i8x9x.h"
+#include "i8x9xd.h"
i8x9x_device::i8x9x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
mcs96_device(mconfig, type, tag, owner, clock, 8),
@@ -18,9 +19,9 @@ i8x9x_device::i8x9x_device(const machine_config &mconfig, device_type type, cons
{
}
-offs_t i8x9x_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options)
+util::disasm_interface *i8x9x_device::create_disassembler()
{
- return disasm_generic(stream, pc, oprom, opram, options, disasm_entries);
+ return new i8x9x_disassembler;
}
device_memory_interface::space_config_vector i8x9x_device::memory_space_config() const
@@ -72,7 +73,7 @@ void i8x9x_device::commit_hso_cam()
void i8x9x_device::ad_start(uint64_t current_time)
{
- ad_result = (io->read_word(2*((ad_command & 7) + A0)) << 6) | 8 | (ad_command & 7);
+ ad_result = (io->read_word((ad_command & 7) + A0) << 6) | 8 | (ad_command & 7);
ad_done = current_time + 88;
internal_update(current_time);
}
@@ -86,7 +87,7 @@ void i8x9x_device::serial_send(uint8_t data)
void i8x9x_device::serial_send_done()
{
serial_send_timer = 0;
- io->write_word(SERIAL*2, serial_send_buf);
+ io->write_word(SERIAL, serial_send_buf);
pending_irq |= IRQ_SERIAL;
sp_stat |= 0x20;
check_irq();
@@ -133,11 +134,11 @@ void i8x9x_device::io_w8(uint8_t adr, uint8_t data)
break;
case 0x0f:
logerror("%s: io port 1 %02x (%04x)\n", tag(), data, PPC);
- io->write_word(P1*2, data);
+ io->write_word(P1, data);
break;
case 0x10:
logerror("%s: io port 2 %02x (%04x)\n", tag(), data, PPC);
- io->write_word(P2*2, data);
+ io->write_word(P2, data);
break;
case 0x11:
logerror("%s: sp con %02x (%04x)\n", tag(), data, PPC);
@@ -216,16 +217,16 @@ uint8_t i8x9x_device::io_r8(uint8_t adr)
return timer_value(2, total_cycles()) >> 8;
case 0x0e: {
static int last = -1;
- if(io->read_word(P0*2) != last) {
- last = io->read_word(P0*2);
+ if(io->read_word(P0) != last) {
+ last = io->read_word(P0);
logerror("%s: read p0 %02x\n", tag(), io->read_word(P0*2));
}
- return io->read_word(P0*2);
+ return io->read_word(P0);
}
case 0x0f:
- return io->read_word(P1*2);
+ return io->read_word(P1);
case 0x10:
- return io->read_word(P2*2);
+ return io->read_word(P2);
case 0x11: {
uint8_t res = sp_stat;
sp_stat &= 0x80;
diff --git a/src/devices/cpu/mcs96/i8x9x.h b/src/devices/cpu/mcs96/i8x9x.h
index 8fda92de323..5684a95afc3 100644
--- a/src/devices/cpu/mcs96/i8x9x.h
+++ b/src/devices/cpu/mcs96/i8x9x.h
@@ -30,9 +30,8 @@ protected:
virtual void device_reset() override;
virtual space_config_vector memory_space_config() const override;
- static const disasm_entry disasm_entries[0x100];
+ virtual util::disasm_interface *create_disassembler() override;
- virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override;
virtual void do_exec_full() override;
virtual void do_exec_partial() override;
virtual void internal_update(uint64_t current_time) override;
diff --git a/src/devices/cpu/mcs96/i8x9xd.cpp b/src/devices/cpu/mcs96/i8x9xd.cpp
new file mode 100644
index 00000000000..40b66d9d492
--- /dev/null
+++ b/src/devices/cpu/mcs96/i8x9xd.cpp
@@ -0,0 +1,19 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert
+/***************************************************************************
+
+ i8x9x.h
+
+ MCS96, 8x9x branch, the original version
+
+***************************************************************************/
+
+#include "emu.h"
+#include "i8x9xd.h"
+
+i8x9x_disassembler::i8x9x_disassembler() : mcs96_disassembler(disasm_entries)
+{
+}
+
+#include "cpu/mcs96/i8x9xd.hxx"
+
diff --git a/src/devices/cpu/mcs96/i8x9xd.h b/src/devices/cpu/mcs96/i8x9xd.h
new file mode 100644
index 00000000000..72227f7933f
--- /dev/null
+++ b/src/devices/cpu/mcs96/i8x9xd.h
@@ -0,0 +1,26 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert
+/***************************************************************************
+
+ i8x9x.h
+
+ MCS96, 8x9x branch, the original version
+
+***************************************************************************/
+
+#ifndef MAME_CPU_MCS96_I8X9XD_H
+#define MAME_CPU_MCS96_I8X9XD_H
+
+#include "mcs96d.h"
+
+class i8x9x_disassembler : public mcs96_disassembler
+{
+public:
+ i8x9x_disassembler();
+ virtual ~i8x9x_disassembler() = default;
+
+private:
+ static const disasm_entry disasm_entries[0x100];
+};
+
+#endif
diff --git a/src/devices/cpu/mcs96/i8xc196.cpp b/src/devices/cpu/mcs96/i8xc196.cpp
index adffde72dc0..d415630f0fa 100644
--- a/src/devices/cpu/mcs96/i8xc196.cpp
+++ b/src/devices/cpu/mcs96/i8xc196.cpp
@@ -10,15 +10,16 @@
#include "emu.h"
#include "i8xc196.h"
+#include "i8xc196d.h"
i8xc196_device::i8xc196_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
mcs96_device(mconfig, type, tag, owner, clock, 16)
{
}
-offs_t i8xc196_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options)
+util::disasm_interface *i8xc196_device::create_disassembler()
{
- return disasm_generic(stream, pc, oprom, opram, options, disasm_entries);
+ return new i8xc196_disassembler;
}
void i8xc196_device::io_w8(uint8_t adr, uint8_t data)
diff --git a/src/devices/cpu/mcs96/i8xc196.h b/src/devices/cpu/mcs96/i8xc196.h
index bd5489a1721..a82c1ea0515 100644
--- a/src/devices/cpu/mcs96/i8xc196.h
+++ b/src/devices/cpu/mcs96/i8xc196.h
@@ -17,9 +17,8 @@ class i8xc196_device : public mcs96_device {
protected:
i8xc196_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
- static const disasm_entry disasm_entries[0x100];
+ virtual util::disasm_interface *create_disassembler() override;
- virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override;
virtual void do_exec_full() override;
virtual void do_exec_partial() override;
diff --git a/src/devices/cpu/mcs96/i8xc196d.cpp b/src/devices/cpu/mcs96/i8xc196d.cpp
new file mode 100644
index 00000000000..8d56aad09e7
--- /dev/null
+++ b/src/devices/cpu/mcs96/i8xc196d.cpp
@@ -0,0 +1,18 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert
+/***************************************************************************
+
+ i8xc196.h
+
+ MCS96, c196 branch, the enhanced 16 bits bus version
+
+***************************************************************************/
+
+#include "emu.h"
+#include "i8xc196d.h"
+
+i8xc196_disassembler::i8xc196_disassembler() : mcs96_disassembler(disasm_entries)
+{
+}
+
+#include "cpu/mcs96/i8xc196d.hxx"
diff --git a/src/devices/cpu/mcs96/i8xc196d.h b/src/devices/cpu/mcs96/i8xc196d.h
new file mode 100644
index 00000000000..53c4f65db2f
--- /dev/null
+++ b/src/devices/cpu/mcs96/i8xc196d.h
@@ -0,0 +1,26 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert
+/***************************************************************************
+
+ i8xc196.h
+
+ MCS96, c196 branch, the enhanced 16 bits bus version
+
+***************************************************************************/
+
+#ifndef MAME_CPU_MCS96_I8XC196D_H
+#define MAME_CPU_MCS96_I8XC196D_H
+
+#include "mcs96d.h"
+
+class i8xc196_disassembler : public mcs96_disassembler
+{
+public:
+ i8xc196_disassembler();
+ virtual ~i8xc196_disassembler() = default;
+
+private:
+ static const disasm_entry disasm_entries[0x100];
+};
+
+#endif
diff --git a/src/devices/cpu/mcs96/mcs96.cpp b/src/devices/cpu/mcs96/mcs96.cpp
index 92a8ed23a37..fa7e75498b3 100644
--- a/src/devices/cpu/mcs96/mcs96.cpp
+++ b/src/devices/cpu/mcs96/mcs96.cpp
@@ -23,7 +23,7 @@ mcs96_device::mcs96_device(const machine_config &mconfig, device_type type, cons
void mcs96_device::device_start()
{
program = &space(AS_PROGRAM);
- direct = &program->direct();
+ direct = program->direct<0>();
m_icountptr = &icount;
state_add(STATE_GENPC, "GENPC", PC).noshow();
@@ -156,276 +156,6 @@ void mcs96_device::state_string_export(const device_state_entry &entry, std::str
}
}
-std::string mcs96_device::regname(uint8_t reg)
-{
- char res[32];
- switch(reg) {
- case 0x18:
- strcpy(res, "sp");
- break;
-
- case 0x19:
- strcpy(res, "sph");
- break;
-
- default:
- sprintf(res, "%02x", reg);
- break;
- }
- return res;
-}
-
-offs_t mcs96_device::disasm_generic(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options, const disasm_entry *entries)
-{
- bool prefix_fe = false;
- int off = 0;
- if(oprom[0] == 0xfe && entries[oprom[1]].opcode_fe) {
- prefix_fe = true;
- pc++;
- off++;
- oprom++;
- }
- const disasm_entry &e = entries[oprom[0]];
- uint32_t flags = e.flags | DASMFLAG_SUPPORTED;
- util::stream_format(stream, "%s", prefix_fe ? e.opcode_fe : e.opcode);
-
- switch(e.mode) {
- case DASM_none:
- flags |= 1;
- break;
-
- case DASM_nop_2:
- util::stream_format(stream, " %02x", oprom[1]);
- flags |= 2;
- break;
-
- case DASM_rel8: {
- int delta = oprom[1];
- if(delta & 0x80)
- delta -= 0x100;
- util::stream_format(stream, " %04x", (pc+2+delta) & 0xffff);
- flags |= 2;
- break;
- }
-
- case DASM_rel11: {
- int delta = ((oprom[0] << 8) | oprom[1]) & 0x7ff;
- if(delta & 0x400)
- delta -= 0x800;
- util::stream_format(stream, " %04x", (pc+2+delta) & 0xffff);
- flags |= 2;
- break;
- }
-
- case DASM_rel16: {
- int delta = oprom[1] | (oprom[2] << 8);
- util::stream_format(stream, " %04x", (pc+3+delta) & 0xffff);
- flags |= 3;
- break;
- }
-
- case DASM_rrel8: {
- int delta = oprom[2];
- if(delta & 0x80)
- delta -= 0x100;
- util::stream_format(stream, " %s, %04x", regname(oprom[1]), (pc+3+delta) & 0xffff);
- flags |= 3;
- break;
- }
-
- case DASM_brrel8: {
- int delta = oprom[2];
- if(delta & 0x80)
- delta -= 0x100;
- util::stream_format(stream, " %d, %s, %04x", oprom[0] & 7, regname(oprom[1]), (pc+3+delta) & 0xffff);
- flags |= 3;
- break;
- }
-
- case DASM_direct_1:
- util::stream_format(stream, " %s", regname(oprom[1]));
- flags |= 2;
- break;
-
- case DASM_direct_2:
- util::stream_format(stream, " %s, %s", regname(oprom[2]), regname(oprom[1]));
- flags |= 3;
- break;
-
- case DASM_direct_3:
- util::stream_format(stream, " %s, %s, %s", regname(oprom[3]), regname(oprom[2]), regname(oprom[1]));
- flags |= 4;
- break;
-
- case DASM_immed_1b:
- util::stream_format(stream, " #%02x", oprom[1]);
- flags |= 2;
- break;
-
- case DASM_immed_2b:
- util::stream_format(stream, " %s, #%02x", regname(oprom[2]), oprom[1]);
- flags |= 3;
- break;
-
- case DASM_immed_or_reg_2b:
- if(oprom[1] >= 0x10)
- util::stream_format(stream, " %s, %s", regname(oprom[2]), regname(oprom[1]));
- else
- util::stream_format(stream, " %s, #%02x", regname(oprom[2]), oprom[1]);
- flags |= 3;
- break;
-
- case DASM_immed_3b:
- util::stream_format(stream, " %s, %s, #%02x", regname(oprom[3]), regname(oprom[2]), oprom[1]);
- flags |= 4;
- break;
-
- case DASM_immed_1w:
- util::stream_format(stream, " #%02x%02x", oprom[2], oprom[1]);
- flags |= 3;
- break;
-
- case DASM_immed_2w:
- util::stream_format(stream, " %s, #%02x%02x", regname(oprom[3]), oprom[2], oprom[1]);
- flags |= 4;
- break;
-
- case DASM_immed_3w:
- util::stream_format(stream, " %s, %s, #%02x%02x", regname(oprom[4]), regname(oprom[3]), oprom[2], oprom[1]);
- flags |= 5;
- break;
-
- case DASM_indirect_1n:
- util::stream_format(stream, " [%s]", regname(oprom[1]));
- flags |= 2;
- break;
-
- case DASM_indirect_1:
- if(oprom[1] & 0x01) {
- util::stream_format(stream, " [%s]+", regname(oprom[1]-1));
- flags |= 2;
- } else {
- util::stream_format(stream, " [%s]", regname(oprom[1]));
- flags |= 2;
- }
- break;
-
- case DASM_indirect_2:
- if(oprom[1] & 0x01) {
- util::stream_format(stream, " %s, [%s]+", regname(oprom[2]), regname(oprom[1]-1));
- flags |= 3;
- } else {
- util::stream_format(stream, " %s, [%s]", regname(oprom[2]), regname(oprom[1]));
- flags |= 3;
- }
- break;
-
- case DASM_indirect_3:
- if(oprom[1] & 0x01) {
- util::stream_format(stream, " %s, %s, [%s]+", regname(oprom[3]), regname(oprom[2]), regname(oprom[1]-1));
- flags |= 4;
- } else {
- util::stream_format(stream, " %s, %s, [%s]", regname(oprom[3]), regname(oprom[2]), regname(oprom[1]));
- flags |= 4;
- }
- break;
-
- case DASM_indexed_1:
- if(oprom[1] & 0x01) {
- if(oprom[1] == 0x01)
- util::stream_format(stream, " %02x%02x", oprom[3], oprom[2]);
- else
- util::stream_format(stream, " %02x%02x[%s]", oprom[3], oprom[2], regname(oprom[1]-1));
- flags |= 4;
- } else {
- int delta = oprom[2];
- if(delta & 0x80)
- delta -= 0x100;
- if(oprom[1] == 0x00) {
- if(delta < 0)
- util::stream_format(stream, " %04x", delta & 0xffff);
- else
- util::stream_format(stream, " %02x", delta);
- } else {
- if(delta < 0)
- util::stream_format(stream, " -%02x[%s]", -delta, regname(oprom[1]));
- else
- util::stream_format(stream, " %02x[%s]", delta, regname(oprom[1]));
- }
- flags |= 3;
- }
- break;
-
- case DASM_indexed_2:
- if(oprom[1] & 0x01) {
- if(oprom[1] == 0x01)
- util::stream_format(stream, " %s, %02x%02x", regname(oprom[4]), oprom[3], oprom[2]);
- else
- util::stream_format(stream, " %s, %02x%02x[%s]", regname(oprom[4]), oprom[3], oprom[2], regname(oprom[1]-1));
- flags |= 5;
- } else {
- int delta = oprom[2];
- if(delta & 0x80)
- delta -= 0x100;
- if(oprom[1] == 0x00) {
- if(delta < 0)
- util::stream_format(stream, " %s, %04x", regname(oprom[3]), delta & 0xffff);
- else
- util::stream_format(stream, " %s, %02x", regname(oprom[3]), delta);
- } else {
- if(delta < 0)
- util::stream_format(stream, " %s, -%02x[%s]", regname(oprom[3]), -delta, regname(oprom[1]));
- else
- util::stream_format(stream, " %s, %02x[%s]", regname(oprom[3]), delta, regname(oprom[1]));
- }
- flags |= 4;
- }
- break;
-
- case DASM_indexed_3:
- if(oprom[1] & 0x01) {
- if(oprom[1] == 0x01)
- util::stream_format(stream, " %s, %s, %02x%02x", regname(oprom[5]), regname(oprom[4]), oprom[3], oprom[2]);
- else
- util::stream_format(stream, " %s, %s, %02x%02x[%s]", regname(oprom[5]), regname(oprom[4]), oprom[3], oprom[2], regname(oprom[1]-1));
- flags |= 6;
- } else {
- int delta = oprom[2];
- if(delta & 0x80)
- delta -= 0x100;
- if(oprom[1] == 0x00) {
- if(delta < 0)
- util::stream_format(stream, " %s, %s, %04x", regname(oprom[4]), regname(oprom[3]), delta & 0xffff);
- else
- util::stream_format(stream, " %s, %s, %02x", regname(oprom[4]), regname(oprom[3]), delta);
- } else {
- if(delta < 0)
- util::stream_format(stream, " %s, %s, -%02x[%s]", regname(oprom[4]), regname(oprom[3]), -delta, regname(oprom[1]));
- else
- util::stream_format(stream, " %s, %s, %02x[%s]", regname(oprom[4]), regname(oprom[3]), delta, regname(oprom[1]));
- }
- flags |= 5;
- }
- break;
-
- default:
- fprintf(stderr, "Unhandled dasm mode %d\n", e.mode);
- abort();
- };
-
- return flags+off;
-}
-
-uint32_t mcs96_device::disasm_min_opcode_bytes() const
-{
- return 1;
-}
-
-uint32_t mcs96_device::disasm_max_opcode_bytes() const
-{
- return 7;
-}
-
void mcs96_device::io_w8(uint8_t adr, uint8_t data)
{
switch(adr) {
diff --git a/src/devices/cpu/mcs96/mcs96.h b/src/devices/cpu/mcs96/mcs96.h
index 159d04bbdc3..3ff9f02d4d2 100644
--- a/src/devices/cpu/mcs96/mcs96.h
+++ b/src/devices/cpu/mcs96/mcs96.h
@@ -41,38 +41,6 @@ protected:
F_Z = 0x8000
};
- struct disasm_entry {
- const char *opcode, *opcode_fe;
- int mode;
- offs_t flags;
- };
-
- enum {
- DASM_none, /* No parameters */
- DASM_nop_2, /* One ignored parameter byte */
- DASM_rel8, /* Relative, 8 bits */
- DASM_rel11, /* Relative, 11 bits */
- DASM_rel16, /* Relative, 16 bits */
- DASM_rrel8, /* Register + relative, 8 bits */
- DASM_brrel8, /* Bit test + register + relative, 8 bits */
- DASM_direct_1, /* Register-direct references, 1 operator */
- DASM_direct_2, /* Register-direct references, 2 operators */
- DASM_direct_3, /* Register-direct references, 3 operators */
- DASM_immed_1b, /* Immediate references to byte, 1 operator */
- DASM_immed_2b, /* Immediate references to byte, 2 operators */
- DASM_immed_or_reg_2b, /* Immediate references to byte or register, 2 operators */
- DASM_immed_3b, /* Immediate references to byte, 3 operators */
- DASM_immed_1w, /* Immediate references to word, 1 operator */
- DASM_immed_2w, /* Immediate references to word, 2 operators */
- DASM_immed_3w, /* Immediate references to word, 3 operators */
- DASM_indirect_1n, /* Indirect normal, 1 operator */
- DASM_indirect_1, /* Indirect, normal or auto-incrementing, 1 operator */
- DASM_indirect_2, /* Indirect, normal or auto-incrementing, 2 operators */
- DASM_indirect_3, /* Indirect, normal or auto-incrementing, 3 operators */
- DASM_indexed_1, /* Indexed, short or long, 1 operator */
- DASM_indexed_2, /* Indexed, short or long, 2 operators */
- DASM_indexed_3 /* Indexed, short or long, 3 operators */
- };
mcs96_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int data_width);
@@ -95,14 +63,9 @@ protected:
virtual void state_export(const device_state_entry &entry) override;
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;
- virtual uint32_t disasm_max_opcode_bytes() const override;
- virtual offs_t disasm_generic(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options, const disasm_entry *entries);
-
address_space_config program_config;
address_space *program;
- direct_read_data *direct;
+ direct_read_data<0> *direct;
int icount, bcount, inst_state, cycles_scaling;
uint8_t pending_irq;
@@ -122,7 +85,6 @@ protected:
virtual uint16_t io_r16(uint8_t adr) = 0;
void recompute_bcount(uint64_t event_time);
- static std::string regname(uint8_t reg);
inline void next(int cycles) { icount -= cycles_scaling*cycles; inst_state = STATE_FETCH; }
inline void next_noirq(int cycles) { icount -= cycles_scaling*cycles; inst_state = STATE_FETCH_NOIRQ; }
diff --git a/src/devices/cpu/mcs96/mcs96d.cpp b/src/devices/cpu/mcs96/mcs96d.cpp
new file mode 100644
index 00000000000..1508fb3ca5f
--- /dev/null
+++ b/src/devices/cpu/mcs96/mcs96d.cpp
@@ -0,0 +1,278 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert
+/***************************************************************************
+
+ mcs96.h
+
+ MCS96, 8098/8398/8798 branch
+
+***************************************************************************/
+
+#include "emu.h"
+#include "mcs96d.h"
+
+mcs96_disassembler::mcs96_disassembler(const disasm_entry *entries) : m_entries(entries)
+{
+}
+
+u32 mcs96_disassembler::opcode_alignment() const
+{
+ return 1;
+}
+
+std::string mcs96_disassembler::regname(uint8_t reg)
+{
+ switch(reg) {
+ case 0x18:
+ return "sp";
+ break;
+
+ case 0x19:
+ return "sph";
+ break;
+
+ default:
+ return util::string_format("%02x", reg);
+ break;
+ }
+}
+
+offs_t mcs96_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params)
+{
+ bool prefix_fe = false;
+ int off = 0;
+ if(opcodes.r8(pc) == 0xfe && m_entries[opcodes.r8(pc+1)].opcode_fe) {
+ prefix_fe = true;
+ pc++;
+ off++;
+ }
+ const disasm_entry &e = m_entries[opcodes.r8(pc)];
+ uint32_t flags = e.flags | SUPPORTED;
+ util::stream_format(stream, "%s", prefix_fe ? e.opcode_fe : e.opcode);
+
+ switch(e.mode) {
+ case DASM_none:
+ flags |= 1;
+ break;
+
+ case DASM_nop_2:
+ util::stream_format(stream, " %02x", opcodes.r8(pc+1));
+ flags |= 2;
+ break;
+
+ case DASM_rel8: {
+ int delta = opcodes.r8(pc+1);
+ if(delta & 0x80)
+ delta -= 0x100;
+ util::stream_format(stream, " %04x", (pc+2+delta) & 0xffff);
+ flags |= 2;
+ break;
+ }
+
+ case DASM_rel11: {
+ int delta = ((opcodes.r8(pc) << 8) | opcodes.r8(pc+1)) & 0x7ff;
+ if(delta & 0x400)
+ delta -= 0x800;
+ util::stream_format(stream, " %04x", (pc+2+delta) & 0xffff);
+ flags |= 2;
+ break;
+ }
+
+ case DASM_rel16: {
+ int delta = opcodes.r8(pc+1) | (opcodes.r8(pc+2) << 8);
+ util::stream_format(stream, " %04x", (pc+3+delta) & 0xffff);
+ flags |= 3;
+ break;
+ }
+
+ case DASM_rrel8: {
+ int delta = opcodes.r8(pc+2);
+ if(delta & 0x80)
+ delta -= 0x100;
+ util::stream_format(stream, " %s, %04x", regname(opcodes.r8(pc+1)), (pc+3+delta) & 0xffff);
+ flags |= 3;
+ break;
+ }
+
+ case DASM_brrel8: {
+ int delta = opcodes.r8(pc+2);
+ if(delta & 0x80)
+ delta -= 0x100;
+ util::stream_format(stream, " %d, %s, %04x", opcodes.r8(pc) & 7, regname(opcodes.r8(pc+1)), (pc+3+delta) & 0xffff);
+ flags |= 3;
+ break;
+ }
+
+ case DASM_direct_1:
+ util::stream_format(stream, " %s", regname(opcodes.r8(pc+1)));
+ flags |= 2;
+ break;
+
+ case DASM_direct_2:
+ util::stream_format(stream, " %s, %s", regname(opcodes.r8(pc+2)), regname(opcodes.r8(pc+1)));
+ flags |= 3;
+ break;
+
+ case DASM_direct_3:
+ util::stream_format(stream, " %s, %s, %s", regname(opcodes.r8(pc+3)), regname(opcodes.r8(pc+2)), regname(opcodes.r8(pc+1)));
+ flags |= 4;
+ break;
+
+ case DASM_immed_1b:
+ util::stream_format(stream, " #%02x", opcodes.r8(pc+1));
+ flags |= 2;
+ break;
+
+ case DASM_immed_2b:
+ util::stream_format(stream, " %s, #%02x", regname(opcodes.r8(pc+2)), opcodes.r8(pc+1));
+ flags |= 3;
+ break;
+
+ case DASM_immed_or_reg_2b:
+ if(opcodes.r8(pc+1) >= 0x10)
+ util::stream_format(stream, " %s, %s", regname(opcodes.r8(pc+2)), regname(opcodes.r8(pc+1)));
+ else
+ util::stream_format(stream, " %s, #%02x", regname(opcodes.r8(pc+2)), opcodes.r8(pc+1));
+ flags |= 3;
+ break;
+
+ case DASM_immed_3b:
+ util::stream_format(stream, " %s, %s, #%02x", regname(opcodes.r8(pc+3)), regname(opcodes.r8(pc+2)), opcodes.r8(pc+1));
+ flags |= 4;
+ break;
+
+ case DASM_immed_1w:
+ util::stream_format(stream, " #%02x%02x", opcodes.r8(pc+2), opcodes.r8(pc+1));
+ flags |= 3;
+ break;
+
+ case DASM_immed_2w:
+ util::stream_format(stream, " %s, #%02x%02x", regname(opcodes.r8(pc+3)), opcodes.r8(pc+2), opcodes.r8(pc+1));
+ flags |= 4;
+ break;
+
+ case DASM_immed_3w:
+ util::stream_format(stream, " %s, %s, #%02x%02x", regname(opcodes.r8(pc+4)), regname(opcodes.r8(pc+3)), opcodes.r8(pc+2), opcodes.r8(pc+1));
+ flags |= 5;
+ break;
+
+ case DASM_indirect_1n:
+ util::stream_format(stream, " [%s]", regname(opcodes.r8(pc+1)));
+ flags |= 2;
+ break;
+
+ case DASM_indirect_1:
+ if(opcodes.r8(pc+1) & 0x01) {
+ util::stream_format(stream, " [%s]+", regname(opcodes.r8(pc+1)-1));
+ flags |= 2;
+ } else {
+ util::stream_format(stream, " [%s]", regname(opcodes.r8(pc+1)));
+ flags |= 2;
+ }
+ break;
+
+ case DASM_indirect_2:
+ if(opcodes.r8(pc+1) & 0x01) {
+ util::stream_format(stream, " %s, [%s]+", regname(opcodes.r8(pc+2)), regname(opcodes.r8(pc+1)-1));
+ flags |= 3;
+ } else {
+ util::stream_format(stream, " %s, [%s]", regname(opcodes.r8(pc+2)), regname(opcodes.r8(pc+1)));
+ flags |= 3;
+ }
+ break;
+
+ case DASM_indirect_3:
+ if(opcodes.r8(pc+1) & 0x01) {
+ util::stream_format(stream, " %s, %s, [%s]+", regname(opcodes.r8(pc+3)), regname(opcodes.r8(pc+2)), regname(opcodes.r8(pc+1)-1));
+ flags |= 4;
+ } else {
+ util::stream_format(stream, " %s, %s, [%s]", regname(opcodes.r8(pc+3)), regname(opcodes.r8(pc+2)), regname(opcodes.r8(pc+1)));
+ flags |= 4;
+ }
+ break;
+
+ case DASM_indexed_1:
+ if(opcodes.r8(pc+1) & 0x01) {
+ if(opcodes.r8(pc+1) == 0x01)
+ util::stream_format(stream, " %02x%02x", opcodes.r8(pc+3), opcodes.r8(pc+2));
+ else
+ util::stream_format(stream, " %02x%02x[%s]", opcodes.r8(pc+3), opcodes.r8(pc+2), regname(opcodes.r8(pc+1)-1));
+ flags |= 4;
+ } else {
+ int delta = opcodes.r8(pc+2);
+ if(delta & 0x80)
+ delta -= 0x100;
+ if(opcodes.r8(pc+1) == 0x00) {
+ if(delta < 0)
+ util::stream_format(stream, " %04x", delta & 0xffff);
+ else
+ util::stream_format(stream, " %02x", delta);
+ } else {
+ if(delta < 0)
+ util::stream_format(stream, " -%02x[%s]", -delta, regname(opcodes.r8(pc+1)));
+ else
+ util::stream_format(stream, " %02x[%s]", delta, regname(opcodes.r8(pc+1)));
+ }
+ flags |= 3;
+ }
+ break;
+
+ case DASM_indexed_2:
+ if(opcodes.r8(pc+1) & 0x01) {
+ if(opcodes.r8(pc+1) == 0x01)
+ util::stream_format(stream, " %s, %02x%02x", regname(opcodes.r8(pc+4)), opcodes.r8(pc+3), opcodes.r8(pc+2));
+ else
+ util::stream_format(stream, " %s, %02x%02x[%s]", regname(opcodes.r8(pc+4)), opcodes.r8(pc+3), opcodes.r8(pc+2), regname(opcodes.r8(pc+1)-1));
+ flags |= 5;
+ } else {
+ int delta = opcodes.r8(pc+2);
+ if(delta & 0x80)
+ delta -= 0x100;
+ if(opcodes.r8(pc+1) == 0x00) {
+ if(delta < 0)
+ util::stream_format(stream, " %s, %04x", regname(opcodes.r8(pc+3)), delta & 0xffff);
+ else
+ util::stream_format(stream, " %s, %02x", regname(opcodes.r8(pc+3)), delta);
+ } else {
+ if(delta < 0)
+ util::stream_format(stream, " %s, -%02x[%s]", regname(opcodes.r8(pc+3)), -delta, regname(opcodes.r8(pc+1)));
+ else
+ util::stream_format(stream, " %s, %02x[%s]", regname(opcodes.r8(pc+3)), delta, regname(opcodes.r8(pc+1)));
+ }
+ flags |= 4;
+ }
+ break;
+
+ case DASM_indexed_3:
+ if(opcodes.r8(pc+1) & 0x01) {
+ if(opcodes.r8(pc+1) == 0x01)
+ util::stream_format(stream, " %s, %s, %02x%02x", regname(opcodes.r8(pc+5)), regname(opcodes.r8(pc+4)), opcodes.r8(pc+3), opcodes.r8(pc+2));
+ else
+ util::stream_format(stream, " %s, %s, %02x%02x[%s]", regname(opcodes.r8(pc+5)), regname(opcodes.r8(pc+4)), opcodes.r8(pc+3), opcodes.r8(pc+2), regname(opcodes.r8(pc+1)-1));
+ flags |= 6;
+ } else {
+ int delta = opcodes.r8(pc+2);
+ if(delta & 0x80)
+ delta -= 0x100;
+ if(opcodes.r8(pc+1) == 0x00) {
+ if(delta < 0)
+ util::stream_format(stream, " %s, %s, %04x", regname(opcodes.r8(pc+4)), regname(opcodes.r8(pc+3)), delta & 0xffff);
+ else
+ util::stream_format(stream, " %s, %s, %02x", regname(opcodes.r8(pc+4)), regname(opcodes.r8(pc+3)), delta);
+ } else {
+ if(delta < 0)
+ util::stream_format(stream, " %s, %s, -%02x[%s]", regname(opcodes.r8(pc+4)), regname(opcodes.r8(pc+3)), -delta, regname(opcodes.r8(pc+1)));
+ else
+ util::stream_format(stream, " %s, %s, %02x[%s]", regname(opcodes.r8(pc+4)), regname(opcodes.r8(pc+3)), delta, regname(opcodes.r8(pc+1)));
+ }
+ flags |= 5;
+ }
+ break;
+
+ default:
+ fprintf(stderr, "Unhandled dasm mode %d\n", e.mode);
+ abort();
+ };
+
+ return flags+off;
+}
diff --git a/src/devices/cpu/mcs96/mcs96d.h b/src/devices/cpu/mcs96/mcs96d.h
new file mode 100644
index 00000000000..453727258bf
--- /dev/null
+++ b/src/devices/cpu/mcs96/mcs96d.h
@@ -0,0 +1,64 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert, R. Belmont
+/***************************************************************************
+
+ mcs96.h
+
+ MCS96
+
+***************************************************************************/
+
+#ifndef MAME_CPU_MCS96_MCS96D_H
+#define MAME_CPU_MCS96_MCS96D_H
+
+#pragma once
+
+class mcs96_disassembler : public util::disasm_interface
+{
+public:
+ struct disasm_entry {
+ const char *opcode, *opcode_fe;
+ int mode;
+ offs_t flags;
+ };
+
+ mcs96_disassembler(const disasm_entry *entries);
+ virtual ~mcs96_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 &params) override;
+
+protected:
+ enum {
+ DASM_none, /* No parameters */
+ DASM_nop_2, /* One ignored parameter byte */
+ DASM_rel8, /* Relative, 8 bits */
+ DASM_rel11, /* Relative, 11 bits */
+ DASM_rel16, /* Relative, 16 bits */
+ DASM_rrel8, /* Register + relative, 8 bits */
+ DASM_brrel8, /* Bit test + register + relative, 8 bits */
+ DASM_direct_1, /* Register-direct references, 1 operator */
+ DASM_direct_2, /* Register-direct references, 2 operators */
+ DASM_direct_3, /* Register-direct references, 3 operators */
+ DASM_immed_1b, /* Immediate references to byte, 1 operator */
+ DASM_immed_2b, /* Immediate references to byte, 2 operators */
+ DASM_immed_or_reg_2b, /* Immediate references to byte or register, 2 operators */
+ DASM_immed_3b, /* Immediate references to byte, 3 operators */
+ DASM_immed_1w, /* Immediate references to word, 1 operator */
+ DASM_immed_2w, /* Immediate references to word, 2 operators */
+ DASM_immed_3w, /* Immediate references to word, 3 operators */
+ DASM_indirect_1n, /* Indirect normal, 1 operator */
+ DASM_indirect_1, /* Indirect, normal or auto-incrementing, 1 operator */
+ DASM_indirect_2, /* Indirect, normal or auto-incrementing, 2 operators */
+ DASM_indirect_3, /* Indirect, normal or auto-incrementing, 3 operators */
+ DASM_indexed_1, /* Indexed, short or long, 1 operator */
+ DASM_indexed_2, /* Indexed, short or long, 2 operators */
+ DASM_indexed_3 /* Indexed, short or long, 3 operators */
+ };
+
+ const disasm_entry *m_entries;
+
+ static std::string regname(uint8_t reg);
+};
+
+#endif
diff --git a/src/devices/cpu/mcs96/mcs96make.py b/src/devices/cpu/mcs96/mcs96make.py
index b4844942e3d..2a9398cd662 100644
--- a/src/devices/cpu/mcs96/mcs96make.py
+++ b/src/devices/cpu/mcs96/mcs96make.py
@@ -117,7 +117,7 @@ class OpcodeList:
self.opcode_per_id[i] = inf
def save_dasm(self, f, t):
- print("const %s_device::disasm_entry %s_device::disasm_entries[0x100] = {" % (t, t), file=f)
+ print("const %s_disassembler::disasm_entry %s_disassembler::disasm_entries[0x100] = {" % (t, t), file=f)
for i in range(0, 0x100):
if i in self.opcode_per_id:
opc = self.opcode_per_id[i]
@@ -125,9 +125,9 @@ class OpcodeList:
if i + 0xfe00 in self.opcode_per_id:
alt = "\"" + self.opcode_per_id[i+0xfe00].name + "\""
if opc.name == "scall" or opc.name == "lcall":
- flags = "DASMFLAG_STEP_OVER"
+ flags = "STEP_OVER"
elif opc.name == "rts":
- flags = "DASMFLAG_STEP_OUT"
+ flags = "STEP_OUT"
else:
flags = "0"
print("\t{ \"%s\", %s, DASM_%s, %s }," % (opc.name, alt, opc.amode, flags), file=f)
@@ -170,25 +170,26 @@ class OpcodeList:
print("}", file=f)
def main(argv):
- if len(argv) != 4:
+ if len(argv) != 5:
print(USAGE % argv[0])
return 1
-
- t = argv[1]
- opcodes = OpcodeList(argv[2], t == "i8xc196")
+
+ m = argv[1]
+ t = argv[2]
+ opcodes = OpcodeList(argv[3], t == "i8xc196")
try:
- f = open(argv[3], "w")
+ f = open(argv[4], "w")
except Exception:
err = sys.exc_info()[1]
- sys.stderr.write("cannot write file %s [%s]\n" % (argv[3], err))
+ sys.stderr.write("cannot write file %s [%s]\n" % (argv[4], err))
sys.exit(1)
- if t != "mcs96":
+ if t != "mcs96" and m == "d":
opcodes.save_dasm(f, t)
- if t != "i8x9x":
+ if t != "i8x9x" and m == "s":
opcodes.save_opcodes(f, t)
- if t != "mcs96":
+ if t != "mcs96" and m == "s":
opcodes.save_exec(f, t)
f.close()