summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author AJR <ajrhacker@users.noreply.github.com>2024-06-19 13:08:13 -0400
committer AJR <ajrhacker@users.noreply.github.com>2024-06-19 13:08:17 -0400
commitc6a47e34df1dbd106bd9a45ab56a9fb28e6fe16e (patch)
tree7f8e8b2a6599dd13b7a52ecdd9704f356560ae51
parent9a57e389bfb04546a4b4b6de66256ed27c83f3ef (diff)
Create stub MSM66573 device so Challenge Gear driver can have a CPU type
-rw-r--r--scripts/src/cpu.lua10
-rw-r--r--src/devices/cpu/olms66k/msm665xx.cpp233
-rw-r--r--src/devices/cpu/olms66k/msm665xx.h98
3 files changed, 340 insertions, 1 deletions
diff --git a/scripts/src/cpu.lua b/scripts/src/cpu.lua
index ced7880632c..0e29529f0dd 100644
--- a/scripts/src/cpu.lua
+++ b/scripts/src/cpu.lua
@@ -4086,9 +4086,17 @@ if opt_tool(CPUS, "PALM") then
end
--------------------------------------------------
--- Oki OLMS-66K/nX-8 series, disassembler only
+-- Oki OLMS-66K/nX-8 series
+--@src/devices/cpu/olms66k/msm665xx.h,CPUS["OLMS66K"] = true
--------------------------------------------------
+if CPUS["OLMS66K"] then
+ files {
+ MAME_DIR .. "src/devices/cpu/olms66k/msm665xx.cpp",
+ MAME_DIR .. "src/devices/cpu/olms66k/msm665xx.h",
+ }
+end
+
if opt_tool(CPUS, "OLMS66K") then
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/olms66k/nx8dasm.cpp")
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/olms66k/nx8dasm.h")
diff --git a/src/devices/cpu/olms66k/msm665xx.cpp b/src/devices/cpu/olms66k/msm665xx.cpp
new file mode 100644
index 00000000000..73b35499849
--- /dev/null
+++ b/src/devices/cpu/olms66k/msm665xx.cpp
@@ -0,0 +1,233 @@
+// license:BSD-3-Clause
+// copyright-holders:AJR
+/****************************************************************************
+
+ Oki MSM665xx 16-bit microcontroller family (nX-8/500S core)
+
+ Currently this is just one stub device with no actual execution core.
+
+****************************************************************************/
+
+#include "emu.h"
+#include "msm665xx.h"
+#include "nx8dasm.h"
+
+// device type definition
+DEFINE_DEVICE_TYPE(MSM66573, msm66573_device, "msm66573", "Oki MSM66573")
+
+
+msm665xx_device::msm665xx_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, address_map_constructor mem_map, address_map_constructor data_map)
+ : cpu_device(mconfig, type, tag, owner, clock)
+ , m_program_config("program", ENDIANNESS_LITTLE, 8, 20, 0, mem_map)
+ , m_data_config("iram", ENDIANNESS_LITTLE, 16, 20, 0, data_map)
+ , m_acc(0)
+ , m_pc(0)
+ , m_ppc(0)
+ , m_psw(0)
+ , m_lrb(0)
+ , m_ssp(0)
+ , m_csr(0)
+ , m_dsr(0)
+ , m_tsr(0)
+ , m_romwin(0x30)
+ , m_icount(0)
+{
+}
+
+device_memory_interface::space_config_vector msm665xx_device::memory_space_config() const
+{
+ return space_config_vector {
+ std::make_pair(AS_PROGRAM, &m_program_config),
+ std::make_pair(AS_DATA, &m_data_config)
+ };
+}
+
+std::unique_ptr<util::disasm_interface> msm665xx_device::create_disassembler()
+{
+ return std::make_unique<nx8_500s_disassembler>(m_psw);
+}
+
+
+msm66573_device::msm66573_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : msm665xx_device(mconfig, MSM66573, tag, owner, clock,
+ address_map_constructor(), // TODO: 64KB internal ROM (optional)
+ address_map_constructor(FUNC(msm66573_device::data_map), this))
+{
+}
+
+void msm66573_device::data_map(address_map &map)
+{
+ map(0x00000, 0x00001).rw(FUNC(msm66573_device::ssp_r), FUNC(msm66573_device::ssp_w));
+ map(0x00002, 0x00003).rw(FUNC(msm66573_device::lrb_r), FUNC(msm66573_device::lrb_w));
+ map(0x00004, 0x00005).rw(FUNC(msm66573_device::psw_r), FUNC(msm66573_device::psw_w));
+ map(0x00006, 0x00007).rw(FUNC(msm66573_device::acc_r), FUNC(msm66573_device::acc_w));
+ map(0x00008, 0x00008).rw(FUNC(msm66573_device::tsr_r), FUNC(msm66573_device::tsr_w));
+ map(0x00009, 0x00009).rw(FUNC(msm66573_device::dsr_r), FUNC(msm66573_device::dsr_w));
+ map(0x0000b, 0x0000b).rw(FUNC(msm66573_device::romwin_r), FUNC(msm66573_device::romwin_w));
+ // TODO: many, many other SFRs
+ map(0x00200, 0x011ff).ram().share("internal");
+}
+
+
+void msm665xx_device::device_start()
+{
+ // get address spaces and access caches
+ space(AS_PROGRAM).specific(m_program_space);
+ space(AS_PROGRAM).cache(m_program_cache);
+ space(AS_DATA).specific(m_data_space);
+ space(AS_DATA).cache(m_data_cache);
+
+ set_icountptr(m_icount);
+
+ // debug state
+ state_add(MSM665XX_ACC, "ACC", m_acc);
+ state_add(MSM665XX_PC, "PC", m_pc);
+ state_add<u32>(STATE_GENPC, "GENPC",
+ [this]() { return u32(m_csr) << 16 | m_pc; },
+ [this](u32 data) { m_csr = (data >> 16) & 0x0f; m_pc = data & 0xffff; m_ppc = data & 0xfffff; }
+ ).mask(0xfffff).noshow();
+ state_add<u32>(STATE_GENPCBASE, "GENPCBASE", m_ppc,
+ [this](u32 data) { m_csr = (data >> 16) & 0x0f; m_pc = data & 0xffff; m_ppc = data & 0xfffff; }
+ ).mask(0xfffff).noshow();
+ state_add(MSM665XX_PSW, "PSW", m_psw);
+ //state_add(STATE_GENFLAGS, "FLAGS", m_psw).formatstr("%9s").noshow(); // TODO
+ state_add(MSM665XX_LRB, "LRB", m_lrb);
+ state_add(MSM665XX_SSP, "SSP", m_ssp);
+ u16 *fixed = static_cast<u16 *>(memshare("internal")->ptr());
+ for (int n = 0; n < 4; n++)
+ state_add<u16>(MSM665XX_PR0 + n, std::array<const char *, 4>{{"X1", "X2", "DP", "USP"}}[n],
+ [this, fixed, n]() { return fixed[(m_psw & 0x07) << 2 | n]; },
+ [this, fixed, n](u16 data) { fixed[(m_psw & 0x07) << 2 | n] = data; }
+ );
+ for (int n = 0; n < 4; n++)
+ state_add<u16>(MSM665XX_ER0 + n, util::string_format("R%d", n).c_str(),
+ [this, fixed, n]() { return fixed[(m_lrb & 0x00ff) << 2 | n]; },
+ [this, fixed, n](u16 data) { fixed[(m_lrb & 0x00ff) << 2 | n] = data; }
+ );
+ for (int n = 0; n < 8; n++)
+ state_add<u8>(MSM665XX_R0 + n, util::string_format("R%d", n).c_str(),
+ [this, fixed, n]() { return util::little_endian_cast<const u8>(fixed)[(m_lrb & 0x00ff) << 3 | n]; },
+ [this, fixed, n](u8 data) { util::little_endian_cast<u8>(fixed)[(m_lrb & 0x00ff) << 3 | n] = data; }
+ ).noshow();
+ state_add(MSM665XX_CSR, "CSR", m_csr).mask(0x0f);
+ state_add(MSM665XX_DSR, "DSR", m_dsr).mask(0x0f);
+ state_add(MSM665XX_TSR, "TSR", m_tsr).mask(0x0f);
+ state_add(MSM665XX_ROMWIN, "ROMWIN", m_romwin);
+
+ // save state
+ save_item(NAME(m_acc));
+ save_item(NAME(m_pc));
+ save_item(NAME(m_ppc));
+ save_item(NAME(m_psw));
+ save_item(NAME(m_lrb));
+ save_item(NAME(m_ssp));
+ save_item(NAME(m_csr));
+ save_item(NAME(m_dsr));
+ save_item(NAME(m_tsr));
+ save_item(NAME(m_romwin));
+}
+
+void msm665xx_device::device_reset()
+{
+ // PC will be initialized from vector following reset; LRB and ROMWIN are undefined at reset
+ m_acc = 0;
+ m_psw = 0;
+ m_ssp = 0xffff;
+ m_csr = 0;
+ m_dsr = 0;
+ m_tsr = 0;
+}
+
+
+u16 msm665xx_device::ssp_r()
+{
+ return m_ssp;
+}
+
+void msm665xx_device::ssp_w(u16 data)
+{
+ m_ssp = data;
+}
+
+u16 msm665xx_device::lrb_r()
+{
+ return m_lrb;
+}
+
+void msm665xx_device::lrb_w(offs_t offset, u16 data, u16 mem_mask)
+{
+ m_lrb = (m_lrb & ~mem_mask) | (data & mem_mask);
+}
+
+u16 msm665xx_device::psw_r()
+{
+ return m_psw;
+}
+
+void msm665xx_device::psw_w(offs_t offset, u16 data, u16 mem_mask)
+{
+ m_psw = (m_psw & ~mem_mask) | (data & mem_mask);
+}
+
+u16 msm665xx_device::acc_r()
+{
+ return m_acc;
+}
+
+void msm665xx_device::acc_w(offs_t offset, u16 data, u16 mem_mask)
+{
+ m_acc = (m_acc & ~mem_mask) | (data & mem_mask);
+}
+
+u8 msm665xx_device::dsr_r()
+{
+ return m_dsr;
+}
+
+void msm665xx_device::dsr_w(u8 data)
+{
+ m_dsr = data & 0x0f;
+}
+
+u8 msm665xx_device::tsr_r()
+{
+ return m_tsr;
+}
+
+void msm665xx_device::tsr_w(u8 data)
+{
+ m_tsr = data & 0x0f;
+}
+
+u8 msm665xx_device::romwin_r()
+{
+ return m_romwin;
+}
+
+void msm665xx_device::romwin_w(u8 data)
+{
+ // ROMWIN is only supposed to be written once after reset
+ m_romwin = data | 0x30;
+}
+
+
+void msm665xx_device::execute_run()
+{
+ m_pc = m_program_cache.read_word(0);
+ m_ppc = m_pc;
+ debugger_instruction_hook(m_pc);
+
+ // TODO
+ m_icount = 0;
+}
+
+
+void msm665xx_device::state_string_export(const device_state_entry &entry, std::string &str) const
+{
+ switch (entry.index())
+ {
+ case STATE_GENFLAGS:
+ // TODO
+ break;
+ }
+}
diff --git a/src/devices/cpu/olms66k/msm665xx.h b/src/devices/cpu/olms66k/msm665xx.h
new file mode 100644
index 00000000000..3f3fc3ae6ab
--- /dev/null
+++ b/src/devices/cpu/olms66k/msm665xx.h
@@ -0,0 +1,98 @@
+// license:BSD-3-Clause
+// copyright-holders:AJR
+/**********************************************************************
+
+ Oki MSM665xx 16-bit microcontroller family (nX-8/500S core)
+
+**********************************************************************/
+
+#ifndef MAME_CPU_OLMS66K_MSM665XX_H
+#define MAME_CPU_OLMS66K_MSM665XX_H
+
+#pragma once
+
+
+class msm665xx_device : public cpu_device
+{
+public:
+ enum {
+ MSM665XX_ACC, MSM665XX_PC, MSM665XX_PSW, MSM665XX_LRB, MSM665XX_SSP,
+ MSM665XX_PR0, MSM665XX_X1 = MSM665XX_PR0,
+ MSM665XX_PR1, MSM665XX_X2 = MSM665XX_PR1,
+ MSM665XX_PR2, MSM665XX_DP = MSM665XX_PR2,
+ MSM665XX_PR3, MSM665XX_USP = MSM665XX_PR3,
+ MSM665XX_ER0, MSM665XX_ER1, MSM665XX_ER2, MSM665XX_ER3,
+ MSM665XX_R0, MSM665XX_R1, MSM665XX_R2, MSM665XX_R3,
+ MSM665XX_R4, MSM665XX_R5, MSM665XX_R6, MSM665XX_R7,
+ MSM665XX_CSR, MSM665XX_DSR, MSM665XX_TSR,
+ MSM665XX_ROMWIN
+ };
+
+ // TODO: port callbacks
+
+protected:
+ msm665xx_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, address_map_constructor mem_map, address_map_constructor data_map);
+
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
+
+ virtual void execute_run() override;
+
+ virtual space_config_vector memory_space_config() const override;
+
+ virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;
+
+ u16 ssp_r();
+ void ssp_w(u16 data);
+ u16 lrb_r();
+ void lrb_w(offs_t offset, u16 data, u16 mem_mask);
+ u16 psw_r();
+ void psw_w(offs_t offset, u16 data, u16 mem_mask);
+ u16 acc_r();
+ void acc_w(offs_t offset, u16 data, u16 mem_mask);
+ u8 dsr_r();
+ void dsr_w(u8 data);
+ u8 tsr_r();
+ void tsr_w(u8 data);
+ u8 romwin_r();
+ void romwin_w(u8 data);
+
+private:
+ address_space_config m_program_config;
+ address_space_config m_data_config;
+ memory_access<20, 0, 0, ENDIANNESS_LITTLE>::cache m_program_cache;
+ memory_access<20, 0, 0, ENDIANNESS_LITTLE>::specific m_program_space;
+ memory_access<20, 1, 0, ENDIANNESS_LITTLE>::cache m_data_cache;
+ memory_access<20, 1, 0, ENDIANNESS_LITTLE>::specific m_data_space;
+
+ u16 m_acc;
+ u16 m_pc;
+ u32 m_ppc;
+ u16 m_psw;
+ u16 m_lrb;
+ u16 m_ssp;
+ u8 m_csr;
+ u8 m_dsr;
+ u8 m_tsr;
+ u8 m_romwin;
+ s32 m_icount;
+};
+
+
+class msm66573_device : public msm665xx_device
+{
+public:
+ // device type constructor
+ msm66573_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+private:
+ void data_map(address_map &map);
+};
+
+
+// device type declaration
+DECLARE_DEVICE_TYPE(MSM66573, msm66573_device)
+
+#endif // MAME_CPU_OLMS66K_MSM665XX_H