summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author AJR <ajrhacker@users.noreply.github.com>2019-06-20 17:00:50 -0400
committer AJR <ajrhacker@users.noreply.github.com>2019-06-20 17:01:38 -0400
commit81eec8d860a3582f36b32f33cd2cfb86be7257dd (patch)
treee77b151659aa3eb46ac037388de2e715c2e437b3
parent3e8d6aadc8a3b9a7efaecc852d32c3d6d833b7e5 (diff)
Preliminary disassembler and skeleton CPU device for Elan RISC II/RII series architecture
-rw-r--r--scripts/src/cpu.lua17
-rw-r--r--scripts/target/mame/arcade.lua1
-rw-r--r--scripts/target/mame/mess.lua1
-rw-r--r--src/devices/cpu/rii/riidasm.cpp546
-rw-r--r--src/devices/cpu/rii/riidasm.h33
-rw-r--r--src/devices/cpu/rii/riscii.cpp105
-rw-r--r--src/devices/cpu/rii/riscii.h75
-rw-r--r--src/mame/drivers/vtech_eu3a12.cpp14
-rw-r--r--src/tools/unidasm.cpp2
9 files changed, 793 insertions, 1 deletions
diff --git a/scripts/src/cpu.lua b/scripts/src/cpu.lua
index 1fb7e3262cd..9a491f9f198 100644
--- a/scripts/src/cpu.lua
+++ b/scripts/src/cpu.lua
@@ -2880,3 +2880,20 @@ if (CPUS["NS32000"]~=null or _OPTIONS["with-tools"]) then
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/ns32000/ns32000dasm.cpp")
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/ns32000/ns32000dasm.h")
end
+
+--------------------------------------------------
+-- Elan RISC II series
+--@src/devices/cpu/rii/riscii.h,CPUS["RII"] = true
+--------------------------------------------------
+
+if (CPUS["RII"]~=null) then
+ files {
+ MAME_DIR .. "src/devices/cpu/rii/riscii.cpp",
+ MAME_DIR .. "src/devices/cpu/rii/riscii.h",
+ }
+end
+
+if (CPUS["RII"]~=null or _OPTIONS["with-tools"]) then
+ table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/rii/riidasm.cpp")
+ table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/rii/riidasm.h")
+end
diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua
index 41d04212a4b..2f675097397 100644
--- a/scripts/target/mame/arcade.lua
+++ b/scripts/target/mame/arcade.lua
@@ -134,6 +134,7 @@ CPUS["HMCS40"] = true
CPUS["ST62XX"] = true
CPUS["DSPP"] = true
CPUS["HPC"] = true
+--CPUS["RII"] = true
--------------------------------------------------
-- specify available sound cores
diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua
index 05d675c88ea..2a3c89bb3ef 100644
--- a/scripts/target/mame/mess.lua
+++ b/scripts/target/mame/mess.lua
@@ -142,6 +142,7 @@ CPUS["NS32000"] = true
CPUS["HPC"] = true
CPUS["MEG"] = true
CPUS["DSPV"] = true
+CPUS["RII"] = true
--------------------------------------------------
-- specify available sound cores; some of these are
diff --git a/src/devices/cpu/rii/riidasm.cpp b/src/devices/cpu/rii/riidasm.cpp
new file mode 100644
index 00000000000..7041955f378
--- /dev/null
+++ b/src/devices/cpu/rii/riidasm.cpp
@@ -0,0 +1,546 @@
+// license:BSD-3-Clause
+// copyright-holders:AJR
+/***************************************************************************
+
+ ELAN Microelectronics RISC II (RII) Series disassembler
+
+***************************************************************************/
+
+#include "util/disasmintf.h"
+#include "riidasm.h"
+
+#include "util/strformat.h"
+
+using osd::u32;
+using util::BIT;
+using offs_t = u32;
+
+// FIXME: this set is an amalgam of ePG3231-EM202, EPD3332 and EPD3338
+const char *const riscii_disassembler::s_regs[0x60] =
+{
+ "INDF0", "FSR0", "PCL", "PCM", "PCH", "BSR", "STKPTR", "BSR1",
+ "INDF1", "FSR1", "ACC", "TABPTRL", "TABPTRM", "TABPTRH", "CPUCON", "STATUS",
+ "TRL2", "PRODL", "PRODH", "ADOTL", "ADOTH", "UARTTX", "UARTRX", "PORTA",
+ "PORTB", "PORTC", "PORTD", "PORTE", "PORTF", "PORTG", "PORTH", "PORTI",
+ "PFS", "STBCON", "INTCON", "INTSTA", "TRL0L", "TRL0H", "TRL1", "TR01CON",
+ "TR2CON", "TRLIR", nullptr, "POST_ID", "ADCON", "PAINTEN", "PAINTSTA", "PAWAKE",
+ "UARTCON", "UARTSTA", "PORTJ", "PORTK", "DCRB", "DCRC", "DCRDE", "DCRFG",
+ "DCRHI", "DCRJK", "PBCON", "PCCON", "PLLF", "T0CL", "T0CH", "SPICON",
+ "SPISTA", "SPRL", "SPRM", "SPRH", "SFCR", "ADDL1~ADDL4", "ADDM1~ADDM4", "ADDH1~ADDH4",
+ "ENV1~4/SPHDR", "MTCON1~4/SPHTCON", "MTRL1~4/SPHTRL", "VOCON", "TR1C", "TR2C", "ADCF", nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr
+};
+
+riscii_disassembler::riscii_disassembler(const char *const regs[])
+ : util::disasm_interface()
+ , m_regs(regs)
+{
+}
+
+u32 riscii_disassembler::opcode_alignment() const
+{
+ return 1;
+}
+
+void riscii_disassembler::format_register(std::ostream &stream, u8 reg) const
+{
+ if (reg < 0x60 && m_regs[reg] != nullptr)
+ stream << m_regs[reg];
+ else
+ util::stream_format(stream, "R%02Xh", reg);
+}
+
+void riscii_disassembler::format_immediate(std::ostream &stream, u8 data) const
+{
+ stream << "#";
+ if (data >= 0xa0)
+ stream << "0";
+ util::stream_format(stream, "%02Xh", data);
+}
+
+offs_t riscii_disassembler::disassemble(std::ostream &stream, offs_t pc, const riscii_disassembler::data_buffer &opcodes, const riscii_disassembler::data_buffer &params)
+{
+ u16 opcode = opcodes.r16(pc);
+ offs_t words = 1;
+
+ if (BIT(opcode, 15))
+ {
+ if (BIT(opcode, 14))
+ {
+ u32 dst = (pc & 0x3e000) | (opcode & 0x1fff);
+ util::stream_format(stream, "%-8s%05X", BIT(opcode, 13) ? "SCALL" : "SJMP", dst);
+ if (BIT(opcode, 13))
+ words |= STEP_OVER;
+ }
+ else
+ {
+ u8 preg = (opcode & 0x1f00) >> 8;
+ if (BIT(opcode, 13))
+ {
+ util::stream_format(stream, "%-8s", "MOVPR");
+ format_register(stream, preg);
+ stream << ",";
+ format_register(stream, opcode & 0x00ff);
+ }
+ else
+ {
+ util::stream_format(stream, "%-8s", "MOVRP");
+ format_register(stream, opcode & 0x00ff);
+ stream << ",";
+ format_register(stream, preg);
+ }
+ }
+ }
+ else switch (opcode & 0xff00)
+ {
+ case 0x0000:
+ if (opcode == 0x0000)
+ stream << "NOP";
+ else if (opcode == 0x0001)
+ stream << "WDTC";
+ else if (opcode == 0x0002)
+ stream << "SLEP";
+ else if ((opcode & 0x00f0) == 0x0020)
+ {
+ u32 dst = u32(opcode & 0x000f) << 16 | opcodes.r16(pc + 1);
+ util::stream_format(stream, "%-8s%05X", "LJMP", dst);
+ words = 2;
+ }
+ else if ((opcode & 0x00f0) == 0x0030)
+ {
+ u32 dst = u32(opcode & 0x000f) << 16 | opcodes.r16(pc + 1);
+ util::stream_format(stream, "%-8s%05X", "LCALL", dst);
+ words = 2 | STEP_OVER;
+ }
+ else
+ stream << "???";
+ break;
+
+ case 0x0200:
+ util::stream_format(stream, "%-8sA,", "OR");
+ format_register(stream, opcode & 0x00ff);
+ break;
+
+ case 0x0300:
+ util::stream_format(stream, "%-8s", "OR");
+ format_register(stream, opcode & 0x00ff);
+ stream << ",A";
+ break;
+
+ case 0x0400:
+ util::stream_format(stream, "%-8sA,", "AND");
+ format_register(stream, opcode & 0x00ff);
+ break;
+
+ case 0x0500:
+ util::stream_format(stream, "%-8s", "AND");
+ format_register(stream, opcode & 0x00ff);
+ stream << ",A";
+ break;
+
+ case 0x0600:
+ util::stream_format(stream, "%-8sA,", "XOR");
+ format_register(stream, opcode & 0x00ff);
+ break;
+
+ case 0x0700:
+ util::stream_format(stream, "%-8s", "XOR");
+ format_register(stream, opcode & 0x00ff);
+ stream << ",A";
+ break;
+
+ case 0x0800:
+ util::stream_format(stream, "%-8s", "COMA");
+ format_register(stream, opcode & 0x00ff);
+ break;
+
+ case 0x0900:
+ util::stream_format(stream, "%-8s", "COM");
+ format_register(stream, opcode & 0x00ff);
+ break;
+
+ case 0x0a00:
+ util::stream_format(stream, "%-8s", "RRCA");
+ format_register(stream, opcode & 0x00ff);
+ break;
+
+ case 0x0b00:
+ util::stream_format(stream, "%-8s", "RRC");
+ format_register(stream, opcode & 0x00ff);
+ break;
+
+ case 0x0c00:
+ util::stream_format(stream, "%-8s", "RLCA");
+ format_register(stream, opcode & 0x00ff);
+ break;
+
+ case 0x0d00:
+ util::stream_format(stream, "%-8s", "RLC");
+ format_register(stream, opcode & 0x00ff);
+ break;
+
+ case 0x0e00:
+ util::stream_format(stream, "%-8s", "SWAPA");
+ format_register(stream, opcode & 0x00ff);
+ break;
+
+ case 0x0f00:
+ util::stream_format(stream, "%-8s", "SWAP");
+ format_register(stream, opcode & 0x00ff);
+ break;
+
+ case 0x1000:
+ util::stream_format(stream, "%-8sA,", "ADD");
+ format_register(stream, opcode & 0x00ff);
+ break;
+
+ case 0x1100:
+ util::stream_format(stream, "%-8s", "ADD");
+ format_register(stream, opcode & 0x00ff);
+ stream << ",A";
+ break;
+
+ case 0x1200:
+ util::stream_format(stream, "%-8sA,", "ADC");
+ format_register(stream, opcode & 0x00ff);
+ break;
+
+ case 0x1300:
+ util::stream_format(stream, "%-8s", "ADC");
+ format_register(stream, opcode & 0x00ff);
+ stream << ",A";
+ break;
+
+ case 0x1400:
+ util::stream_format(stream, "%-8sA,", "ADDDC");
+ format_register(stream, opcode & 0x00ff);
+ break;
+
+ case 0x1500:
+ util::stream_format(stream, "%-8s", "ADDDC");
+ format_register(stream, opcode & 0x00ff);
+ stream << ",A";
+ break;
+
+ case 0x1600:
+ util::stream_format(stream, "%-8sA,", "SUB");
+ format_register(stream, opcode & 0x00ff);
+ break;
+
+ case 0x1700:
+ util::stream_format(stream, "%-8s", "SUB");
+ format_register(stream, opcode & 0x00ff);
+ stream << ",A";
+ break;
+
+ case 0x1800:
+ util::stream_format(stream, "%-8sA,", "SUBB");
+ format_register(stream, opcode & 0x00ff);
+ break;
+
+ case 0x1900:
+ util::stream_format(stream, "%-8s", "SUBB");
+ format_register(stream, opcode & 0x00ff);
+ stream << ",A";
+ break;
+
+ case 0x1a00:
+ util::stream_format(stream, "%-8sA,", "SUBDB");
+ format_register(stream, opcode & 0x00ff);
+ break;
+
+ case 0x1b00:
+ util::stream_format(stream, "%-8s", "SUBDB");
+ format_register(stream, opcode & 0x00ff);
+ stream << ",A";
+ break;
+
+ case 0x1c00:
+ util::stream_format(stream, "%-8s", "INCA");
+ format_register(stream, opcode & 0x00ff);
+ break;
+
+ case 0x1d00:
+ util::stream_format(stream, "%-8s", "INC");
+ format_register(stream, opcode & 0x00ff);
+ break;
+
+ case 0x1e00:
+ util::stream_format(stream, "%-8s", "DECA");
+ format_register(stream, opcode & 0x00ff);
+ break;
+
+ case 0x1f00:
+ util::stream_format(stream, "%-8s", "DEC");
+ format_register(stream, opcode & 0x00ff);
+ break;
+
+ case 0x2000:
+ util::stream_format(stream, "%-8sA,", "MOV");
+ format_register(stream, opcode & 0x00ff);
+ break;
+
+ case 0x2100:
+ util::stream_format(stream, "%-8s", "MOV");
+ format_register(stream, opcode & 0x00ff);
+ stream << ",A";
+ break;
+
+ case 0x2200:
+ util::stream_format(stream, "%-8s", "SHRA");
+ format_register(stream, opcode & 0x00ff);
+ break;
+
+ case 0x2300:
+ util::stream_format(stream, "%-8s", "SHLA");
+ format_register(stream, opcode & 0x00ff);
+ break;
+
+ case 0x2400:
+ util::stream_format(stream, "%-8s", "CLR");
+ format_register(stream, opcode & 0x00ff);
+ break;
+
+ case 0x2500:
+ util::stream_format(stream, "%-8s", "TEST");
+ format_register(stream, opcode & 0x00ff);
+ break;
+
+ case 0x2600:
+ util::stream_format(stream, "%-8sA,", "MUL");
+ format_register(stream, opcode & 0x00ff);
+ break;
+
+ case 0x2700:
+ util::stream_format(stream, "%-8s", "RPT");
+ format_register(stream, opcode & 0x00ff);
+ break;
+
+ case 0x2b00:
+ switch (opcode & 0x00ff)
+ {
+ case 0xfe:
+ stream << "RET";
+ words |= STEP_OUT;
+ break;
+
+ case 0xff:
+ stream << "RETI";
+ words |= STEP_OUT;
+ break;
+
+ default:
+ stream << "???";
+ break;
+ }
+ break;
+
+ case 0x2c00:
+ util::stream_format(stream, "%-8s0,", "TBRD");
+ format_register(stream, opcode & 0x00ff);
+ break;
+
+ case 0x2d00:
+ util::stream_format(stream, "%-8s1,", "TBRD"); // increment mode
+ format_register(stream, opcode & 0x00ff);
+ break;
+
+ case 0x2e00:
+ util::stream_format(stream, "%-8s2,", "TBRD"); // decrement mode
+ format_register(stream, opcode & 0x00ff);
+ break;
+
+ case 0x2f00:
+ util::stream_format(stream, "%-8sA,", "TBRD");
+ format_register(stream, opcode & 0x00ff);
+ break;
+
+ case 0x3000: case 0x3100: case 0x3200: case 0x3300:
+ case 0x3400: case 0x3500: case 0x3600: case 0x3700:
+ case 0x3800: case 0x3900: case 0x3a00: case 0x3b00:
+ case 0x3c00: case 0x3d00: case 0x3e00: case 0x3f00:
+ util::stream_format(stream, "%-8s%05X", "S0CALL", opcode & 0x0fff);
+ words |= STEP_OVER;
+ break;
+
+ case 0x4000:
+ util::stream_format(stream, "%-8s", "TBPTL");
+ format_immediate(stream, opcode & 0x00ff);
+ break;
+
+ case 0x4100:
+ util::stream_format(stream, "%-8s", "TBPTM");
+ format_immediate(stream, opcode & 0x00ff);
+ break;
+
+ case 0x4200:
+ util::stream_format(stream, "%-8s", "TBPTH");
+ format_immediate(stream, opcode & 0x00ff);
+ break;
+
+ case 0x4300:
+ util::stream_format(stream, "%-8s", "BANK");
+ format_immediate(stream, opcode & 0x00ff);
+ break;
+
+ case 0x4400:
+ util::stream_format(stream, "%-8sA,", "OR");
+ format_immediate(stream, opcode & 0x00ff);
+ break;
+
+ case 0x4500:
+ util::stream_format(stream, "%-8sA,", "AND");
+ format_immediate(stream, opcode & 0x00ff);
+ break;
+
+ case 0x4600:
+ util::stream_format(stream, "%-8sA,", "XOR");
+ format_immediate(stream, opcode & 0x00ff);
+ break;
+
+ case 0x4700:
+ util::stream_format(stream, "%-8sA,", "JGE");
+ format_immediate(stream, opcode & 0x00ff);
+ util::stream_format(stream, ",%05X", (pc & 0x30000) | opcodes.r16(pc + 1));
+ words = 2;
+ break;
+
+ case 0x4800:
+ util::stream_format(stream, "%-8sA,", "JLE");
+ format_immediate(stream, opcode & 0x00ff);
+ util::stream_format(stream, ",%05X", (pc & 0x30000) | opcodes.r16(pc + 1));
+ words = 2;
+ break;
+
+ case 0x4900:
+ util::stream_format(stream, "%-8sA,", "JE");
+ format_immediate(stream, opcode & 0x00ff);
+ util::stream_format(stream, ",%05X", (pc & 0x30000) | opcodes.r16(pc + 1));
+ words = 2;
+ break;
+
+ case 0x4a00:
+ util::stream_format(stream, "%-8sA,", "ADD");
+ format_immediate(stream, opcode & 0x00ff);
+ break;
+
+ case 0x4b00:
+ util::stream_format(stream, "%-8sA,", "ADC");
+ format_immediate(stream, opcode & 0x00ff);
+ break;
+
+ case 0x4c00:
+ util::stream_format(stream, "%-8sA,", "SUB");
+ format_immediate(stream, opcode & 0x00ff);
+ break;
+
+ case 0x4d00:
+ util::stream_format(stream, "%-8sA,", "SUBB");
+ format_immediate(stream, opcode & 0x00ff);
+ break;
+
+ case 0x4e00:
+ util::stream_format(stream, "%-8sA,", "MOV");
+ format_immediate(stream, opcode & 0x00ff);
+ break;
+
+ case 0x4f00:
+ util::stream_format(stream, "%-8sA,", "MUL");
+ format_immediate(stream, opcode & 0x00ff);
+ break;
+
+ case 0x5000:
+ util::stream_format(stream, "%-8sA,", "JDNZ");
+ format_register(stream, opcode & 0x00ff);
+ util::stream_format(stream, ",%05X", (pc & 0x30000) | opcodes.r16(pc + 1));
+ words = 2;
+ break;
+
+ case 0x5100:
+ util::stream_format(stream, "%-8s", "JDNZ");
+ format_register(stream, opcode & 0x00ff);
+ util::stream_format(stream, ",%05X", (pc & 0x30000) | opcodes.r16(pc + 1));
+ words = 2;
+ break;
+
+ case 0x5200:
+ util::stream_format(stream, "%-8sA,", "JINZ");
+ format_register(stream, opcode & 0x00ff);
+ util::stream_format(stream, ",%05X", (pc & 0x30000) | opcodes.r16(pc + 1));
+ words = 2;
+ break;
+
+ case 0x5300:
+ util::stream_format(stream, "%-8s", "JINZ");
+ format_register(stream, opcode & 0x00ff);
+ util::stream_format(stream, ",%05X", (pc & 0x30000) | opcodes.r16(pc + 1));
+ words = 2;
+ break;
+
+ case 0x5500:
+ util::stream_format(stream, "%-8sA,", "JGE");
+ format_register(stream, opcode & 0x00ff);
+ util::stream_format(stream, ",%05X", (pc & 0x30000) | opcodes.r16(pc + 1));
+ words = 2;
+ break;
+
+ case 0x5600:
+ util::stream_format(stream, "%-8sA,", "JLE");
+ format_register(stream, opcode & 0x00ff);
+ util::stream_format(stream, ",%05X", (pc & 0x30000) | opcodes.r16(pc + 1));
+ words = 2;
+ break;
+
+ case 0x5700:
+ util::stream_format(stream, "%-8sA,", "JE");
+ format_register(stream, opcode & 0x00ff);
+ util::stream_format(stream, ",%05X", (pc & 0x30000) | opcodes.r16(pc + 1));
+ words = 2;
+ break;
+
+ case 0x5800: case 0x5900: case 0x5a00: case 0x5b00:
+ case 0x5c00: case 0x5d00: case 0x5e00: case 0x5f00:
+ util::stream_format(stream, "%-8s", "JBC");
+ format_register(stream, opcode & 0x00ff);
+ util::stream_format(stream, ",%d,%05X", (opcode & 0x0700) >> 8, (pc & 0x30000) | opcodes.r16(pc + 1));
+ words = 2;
+ break;
+
+ case 0x6000: case 0x6100: case 0x6200: case 0x6300:
+ case 0x6400: case 0x6500: case 0x6600: case 0x6700:
+ util::stream_format(stream, "%-8s", "JBS");
+ format_register(stream, opcode & 0x00ff);
+ util::stream_format(stream, ",%d,%05X", (opcode & 0x0700) >> 8, (pc & 0x30000) | opcodes.r16(pc + 1));
+ words = 2;
+ break;
+
+ case 0x6800: case 0x6900: case 0x6a00: case 0x6b00:
+ case 0x6c00: case 0x6d00: case 0x6e00: case 0x6f00:
+ util::stream_format(stream, "%-8s", "BC");
+ format_register(stream, opcode & 0x00ff);
+ util::stream_format(stream, ",%d", (opcode & 0x0700) >> 8);
+ break;
+
+ case 0x7000: case 0x7100: case 0x7200: case 0x7300:
+ case 0x7400: case 0x7500: case 0x7600: case 0x7700:
+ util::stream_format(stream, "%-8s", "BS");
+ format_register(stream, opcode & 0x00ff);
+ util::stream_format(stream, ",%d", (opcode & 0x0700) >> 8);
+ break;
+
+ case 0x7800: case 0x7900: case 0x7a00: case 0x7b00:
+ case 0x7c00: case 0x7d00: case 0x7e00: case 0x7f00:
+ util::stream_format(stream, "%-8s", "BTG");
+ format_register(stream, opcode & 0x00ff);
+ util::stream_format(stream, ",%d", (opcode & 0x0700) >> 8);
+ break;
+
+ default:
+ stream << "???";
+ break;
+
+ }
+
+ return words | SUPPORTED;
+}
diff --git a/src/devices/cpu/rii/riidasm.h b/src/devices/cpu/rii/riidasm.h
new file mode 100644
index 00000000000..eba4b9a7ab9
--- /dev/null
+++ b/src/devices/cpu/rii/riidasm.h
@@ -0,0 +1,33 @@
+// license:BSD-3-Clause
+// copyright-holders:AJR
+
+#ifndef MAME_CPU_RII_RIIDASM_H
+#define MAME_CPU_RII_RIIDASM_H
+
+#pragma once
+
+class riscii_disassembler : public util::disasm_interface
+{
+public:
+ riscii_disassembler() : riscii_disassembler(s_regs) { }
+
+protected:
+ // construction/destruction
+ riscii_disassembler(const char *const regs[]);
+
+ // disassembler 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;
+
+private:
+ static const char *const s_regs[0x60];
+
+ // internal helpers
+ void format_register(std::ostream &stream, u8 reg) const;
+ void format_immediate(std::ostream &stream, u8 data) const;
+
+ // register names
+ const char *const *m_regs;
+};
+
+#endif // MAME_CPU_RII_RIIDASM_H
diff --git a/src/devices/cpu/rii/riscii.cpp b/src/devices/cpu/rii/riscii.cpp
new file mode 100644
index 00000000000..9a0b84d1acf
--- /dev/null
+++ b/src/devices/cpu/rii/riscii.cpp
@@ -0,0 +1,105 @@
+// license:BSD-3-Clause
+// copyright-holders:AJR
+/***************************************************************************
+
+ ELAN Microelectronics RISC II (RII) Series
+
+ Architecture is very similar to the GI/Microchip PIC series, with
+ 16-bit opcodes and a paged 8-bit register file.
+
+ Currently this device is just a stub with no actual execution core.
+
+***************************************************************************/
+
+#include "emu.h"
+#include "riscii.h"
+#include "riidasm.h"
+
+// device type definitions
+DEFINE_DEVICE_TYPE(RISCII, riscii_series_device, "riscii", "Elan RISC II")
+
+
+std::unique_ptr<util::disasm_interface> riscii_series_device::create_disassembler()
+{
+ return std::make_unique<riscii_disassembler>();
+}
+
+riscii_series_device::riscii_series_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : cpu_device(mconfig, RISCII, tag, owner, clock)
+ , m_program_config("program", ENDIANNESS_LITTLE, 16, 18, -1)
+ , m_program(nullptr)
+ , m_pc(0)
+ , m_acc(0)
+ , m_fsr0(0)
+ , m_bsr(0)
+ , m_tabptr(0)
+ , m_stkptr(0)
+ , m_cpucon(0)
+ , m_status(0)
+ , m_icount(0)
+{
+ m_fsr1.w = 0;
+ m_prod.w = 0;
+}
+
+device_memory_interface::space_config_vector riscii_series_device::memory_space_config() const
+{
+ return space_config_vector {
+ std::make_pair(AS_PROGRAM, &m_program_config),
+ };
+}
+
+void riscii_series_device::device_start()
+{
+ m_program = &space(AS_PROGRAM);
+
+ set_icountptr(m_icount);
+
+ state_add(RII_PC, "PC", m_pc).mask(0x3ffff);
+ state_add(STATE_GENPC, "GENPC", m_pc).callimport().noshow();
+ state_add(STATE_GENPCBASE, "CURPC", m_pc).callimport().noshow();
+ state_add(RII_ACC, "ACC", m_acc);
+ state_add(RII_FSR0, "FSR0", m_fsr0);
+ state_add(RII_FSR1, "FSR1", m_fsr1.b.l);
+ state_add(RII_BSR, "BSR", m_bsr).mask(0x1f);
+ state_add(RII_BSR1, "BSR1", m_fsr1.b.h).mask(0x1f);
+ state_add(RII_TABPTR, "TABPTR", m_tabptr).mask(0xffffff);
+ state_add(RII_STKPTR, "STKPTR", m_stkptr);
+ state_add(RII_CPUCON, "CPUCON", m_cpucon).mask(0x9f);
+ state_add(RII_STATUS, "STATUS", m_status);
+ state_add(RII_PROD, "PROD", m_prod.w);
+
+ save_item(NAME(m_pc));
+ save_item(NAME(m_acc));
+ save_item(NAME(m_fsr0));
+ save_item(NAME(m_bsr));
+ save_item(NAME(m_fsr1.w));
+ save_item(NAME(m_tabptr));
+ save_item(NAME(m_stkptr));
+ save_item(NAME(m_cpucon));
+ save_item(NAME(m_status));
+ save_item(NAME(m_prod.w));
+}
+
+void riscii_series_device::device_reset()
+{
+ m_pc = 0x00000;
+ m_fsr0 = 0x00;
+ m_bsr = 0x00;
+ m_fsr1.w = 0x0080;
+ m_tabptr = 0x000000;
+ m_stkptr = 0x00;
+ m_cpucon &= 0x01;
+}
+
+void riscii_series_device::execute_run()
+{
+ debugger_instruction_hook(m_pc);
+
+ m_icount = 0;
+}
+
+void riscii_series_device::execute_set_input(int inputnum, int state)
+{
+ // TODO
+}
diff --git a/src/devices/cpu/rii/riscii.h b/src/devices/cpu/rii/riscii.h
new file mode 100644
index 00000000000..7550bd2458b
--- /dev/null
+++ b/src/devices/cpu/rii/riscii.h
@@ -0,0 +1,75 @@
+// license:BSD-3-Clause
+// copyright-holders:AJR
+/***************************************************************************
+
+ ELAN Microelectronics RISC II (RII) Series
+
+***************************************************************************/
+
+#ifndef MAME_CPU_RII_RISCII_H
+#define MAME_CPU_RII_RISCII_H 1
+
+#pragma once
+
+
+
+class riscii_series_device : public cpu_device
+{
+public:
+ enum
+ {
+ RII_PC,
+ RII_ACC,
+ RII_FSR0,
+ RII_FSR1,
+ RII_BSR,
+ RII_BSR1,
+ RII_TABPTR,
+ RII_STKPTR,
+ RII_CPUCON,
+ RII_STATUS,
+ RII_PROD
+ };
+
+ // construction/destruction
+ riscii_series_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ // device_execute_interface overrides
+ virtual void execute_run() override;
+ virtual void execute_set_input(int inputnum, int state) override;
+
+ // device_disasm_interface overrides
+ virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
+
+ // device_memory_interface overrides
+ virtual space_config_vector memory_space_config() const override;
+
+private:
+ // address spaces
+ address_space_config m_program_config;
+ address_space *m_program;
+
+ // internal state
+ u32 m_pc;
+ u8 m_acc;
+ u8 m_fsr0;
+ u8 m_bsr;
+ PAIR16 m_fsr1;
+ u32 m_tabptr;
+ u8 m_stkptr;
+ u8 m_cpucon;
+ u8 m_status;
+ PAIR16 m_prod;
+
+ // execution sequencing
+ s32 m_icount;
+};
+
+DECLARE_DEVICE_TYPE(RISCII, riscii_series_device)
+
+#endif // MAME_CPU_RII_RISCII_H
diff --git a/src/mame/drivers/vtech_eu3a12.cpp b/src/mame/drivers/vtech_eu3a12.cpp
index b7275c1b049..f60f3ffc1bc 100644
--- a/src/mame/drivers/vtech_eu3a12.cpp
+++ b/src/mame/drivers/vtech_eu3a12.cpp
@@ -4,6 +4,7 @@
// CPU die is an Elan EU3A12 (Elan "RISC II Series" quasi-PIC with 16-bit opcodes)
#include "emu.h"
+#include "cpu/rii/riscii.h"
#include "screen.h"
class vreadere_state : public driver_device
@@ -11,12 +12,17 @@ class vreadere_state : public driver_device
public:
vreadere_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag)
+ , m_maincpu(*this, "maincpu")
{ }
void vreadere(machine_config &config);
private:
virtual uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
+
+ void prog_map(address_map &map);
+
+ required_device<cpu_device> m_maincpu;
};
uint32_t vreadere_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
@@ -24,12 +30,18 @@ uint32_t vreadere_state::screen_update(screen_device &screen, bitmap_rgb32 &bitm
return 0;
}
+void vreadere_state::prog_map(address_map &map)
+{
+ map(0x00000, 0x3ffff).rom().region("maincpu", 0);
+}
+
static INPUT_PORTS_START( vreadere )
INPUT_PORTS_END
void vreadere_state::vreadere(machine_config &config)
{
- // UNKNOWN(config, "maincpu", unknown); // CPU type is unknown, epoxy blob
+ RISCII(config, m_maincpu, 10'000'000); // CPU type is unknown, epoxy blob
+ m_maincpu->set_addrmap(AS_PROGRAM, &vreadere_state::prog_map);
/* video hardware */
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
diff --git a/src/tools/unidasm.cpp b/src/tools/unidasm.cpp
index c437b260c8d..29252657d35 100644
--- a/src/tools/unidasm.cpp
+++ b/src/tools/unidasm.cpp
@@ -110,6 +110,7 @@ using util::BIT;
#include "cpu/powerpc/ppc_dasm.h"
#include "cpu/pps4/pps4dasm.h"
#include "cpu/psx/psxdasm.h"
+#include "cpu/rii/riidasm.h"
#include "cpu/rsp/rsp_dasm.h"
#include "cpu/s2650/2650dasm.h"
#include "cpu/saturn/saturnds.h"
@@ -434,6 +435,7 @@ static const dasm_table_entry dasm_table[] =
{ "psxcpu", le, 0, []() -> util::disasm_interface * { return new psxcpu_disassembler; } },
{ "mips1be", be, 0, []() -> util::disasm_interface * { return new mips1_disassembler; } },
{ "mips1le", le, 0, []() -> util::disasm_interface * { return new mips1_disassembler; } },
+ { "rii", le, -1, []() -> util::disasm_interface * { return new riscii_disassembler; } },
{ "rsp", le, 0, []() -> util::disasm_interface * { return new rsp_disassembler; } },
{ "s2650", le, 0, []() -> util::disasm_interface * { return new s2650_disassembler(&s2650_unidasm); } },
{ "saturn", le, 0, []() -> util::disasm_interface * { return new saturn_disassembler(&saturn_unidasm); } },