From 632f0a0e09b4d24e358affe6caf7637a34618130 Mon Sep 17 00:00:00 2001 From: hap Date: Sun, 12 Nov 2023 10:37:03 +0100 Subject: [PATCH] m6801: add support for canned nvram --- src/devices/cpu/m6800/m6801.cpp | 50 +++++++++++++++++++++++---------- src/devices/cpu/m6800/m6801.h | 17 +++++------ 2 files changed, 44 insertions(+), 23 deletions(-) diff --git a/src/devices/cpu/m6800/m6801.cpp b/src/devices/cpu/m6800/m6801.cpp index 35a84ff4105..4ff7398e3e7 100644 --- a/src/devices/cpu/m6800/m6801.cpp +++ b/src/devices/cpu/m6800/m6801.cpp @@ -379,7 +379,7 @@ m6801_cpu_device::m6801_cpu_device(const machine_config &mconfig, const char *ta { } -m6801_cpu_device::m6801_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, const op_func *insn, const uint8_t *cycles, address_map_constructor internal, int standby_bytes) +m6801_cpu_device::m6801_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, const op_func *insn, const uint8_t *cycles, address_map_constructor internal, int nvram_bytes) : m6800_cpu_device(mconfig, type, tag, owner, clock, insn, cycles, internal) , device_nvram_interface(mconfig, *this) , m_in_port_func(*this, 0xff) @@ -387,9 +387,10 @@ m6801_cpu_device::m6801_cpu_device(const machine_config &mconfig, device_type ty , m_out_sc2_func(*this) , m_out_sertx_func(*this) , m_standby_func(*this) - , m_sclk_divider(8) , m_internal_ram(*this, "internal") - , m_standby_bytes(standby_bytes) + , m_nvram_bytes(nvram_bytes) + , m_nvram_defval(0) + , m_sclk_divider(8) { // disable nvram by default (set to true if MCU is battery-backed when in standby mode) nvram_enable_backup(false); @@ -430,8 +431,8 @@ mc68121_device::mc68121_device(const machine_config &mconfig, const char *tag, d { } -hd6301_cpu_device::hd6301_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, const m6800_cpu_device::op_func *insn, const uint8_t *cycles, address_map_constructor internal, int standby_bytes) - : m6801_cpu_device(mconfig, type, tag, owner, clock, hd63701_insn, cycles_63701, internal, standby_bytes) +hd6301_cpu_device::hd6301_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, const m6800_cpu_device::op_func *insn, const uint8_t *cycles, address_map_constructor internal, int nvram_bytes) + : m6801_cpu_device(mconfig, type, tag, owner, clock, hd63701_insn, cycles_63701, internal, nvram_bytes) { } @@ -450,8 +451,8 @@ hd6303r_cpu_device::hd6303r_cpu_device(const machine_config &mconfig, const char { } -hd6301x_cpu_device::hd6301x_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor internal, int standby_bytes) - : hd6301_cpu_device(mconfig, type, tag, owner, clock, hd63701_insn, cycles_63701, internal, standby_bytes) +hd6301x_cpu_device::hd6301x_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor internal, int nvram_bytes) + : hd6301_cpu_device(mconfig, type, tag, owner, clock, hd63701_insn, cycles_63701, internal, nvram_bytes) , m_in_portx_func(*this, 0xff) , m_out_portx_func(*this) { @@ -473,8 +474,8 @@ hd6303x_cpu_device::hd6303x_cpu_device(const machine_config &mconfig, const char { } -hd6301y_cpu_device::hd6301y_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor internal, int standby_bytes) - : hd6301x_cpu_device(mconfig, type, tag, owner, clock, internal, standby_bytes) +hd6301y_cpu_device::hd6301y_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor internal, int nvram_bytes) + : hd6301x_cpu_device(mconfig, type, tag, owner, clock, internal, nvram_bytes) { } @@ -1322,12 +1323,12 @@ bool m6801_cpu_device::nvram_write(util::write_stream &file) { size_t actual; - if (file.write(&m_internal_ram[0], m_standby_bytes, actual) || m_standby_bytes != actual) + if (file.write(&m_internal_ram[0], m_nvram_bytes, actual) || m_nvram_bytes != actual) return false; // upper bits of RAM control register - u8 ram_ctrl = m_ram_ctrl & 0xc0; - if (file.write(&ram_ctrl, sizeof(ram_ctrl), actual) || (sizeof(ram_ctrl) != actual)) + uint8_t ram_ctrl = m_ram_ctrl & 0xc0; + if (file.write(&ram_ctrl, 1, actual) || actual != 1) return false; return true; @@ -1337,18 +1338,37 @@ bool m6801_cpu_device::nvram_read(util::read_stream &file) { size_t actual; - if (file.read(&m_internal_ram[0], m_standby_bytes, actual) || m_standby_bytes != actual) + if (file.read(&m_internal_ram[0], m_nvram_bytes, actual) || m_nvram_bytes != actual) return false; // upper bits of RAM control register - u8 ram_ctrl = 0; - if (file.read(&ram_ctrl, sizeof(ram_ctrl), actual) || (sizeof(ram_ctrl) != actual)) + uint8_t ram_ctrl = 0; + if (file.read(&ram_ctrl, 1, actual) || actual != 1) return false; m_ram_ctrl |= ram_ctrl & 0xc0; return true; } +void m6801_cpu_device::nvram_default() +{ + if (!nvram_backup_enabled() || m_nvram_bytes == 0) + return; + + std::fill_n(&m_internal_ram[0], m_nvram_bytes, m_nvram_defval); + + // default nvram from mytag:nvram region if it exists + memory_region *region = memregion("nvram"); + if (region != nullptr) + { + if (region->bytes() != m_nvram_bytes) + fatalerror("%s: Wrong region size (expected 0x%x, found 0x%x)", region->name(), m_nvram_bytes, region->bytes()); + + std::copy_n(®ion->as_u8(), m_nvram_bytes, &m_internal_ram[0]); + m_ram_ctrl |= 0x80; + } +} + void m6801_cpu_device::write_port2() diff --git a/src/devices/cpu/m6800/m6801.h b/src/devices/cpu/m6800/m6801.h index c24d9b2af6c..7edb31a844d 100644 --- a/src/devices/cpu/m6800/m6801.h +++ b/src/devices/cpu/m6800/m6801.h @@ -58,20 +58,21 @@ public: auto out_sc2_cb() { return m_out_sc2_func.bind(); } auto out_ser_tx_cb() { return m_out_sertx_func.bind(); } + void nvram_set_default_value(uint8_t val) { m_nvram_defval = val; } // default is 0 auto standby_cb() { return m_standby_func.bind(); } // notifier (not an output pin) bool standby() { return suspended(SUSPEND_REASON_CLOCK); } void m6801_clock_serial(); protected: - m6801_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, const m6800_cpu_device::op_func *insn, const uint8_t *cycles, address_map_constructor internal, int standby_bytes); + m6801_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, const m6800_cpu_device::op_func *insn, const uint8_t *cycles, address_map_constructor internal, int nvram_bytes); // device_t implementation virtual void device_start() override; virtual void device_reset() override; // device_nvram_interface implementation - virtual void nvram_default() override { ; } + virtual void nvram_default() override; virtual bool nvram_read(util::read_stream &file) override; virtual bool nvram_write(util::write_stream &file) override; @@ -137,10 +138,10 @@ protected: devcb_write_line m_out_sertx_func; devcb_write_line m_standby_func; - int m_sclk_divider; - required_shared_ptr m_internal_ram; - const int m_standby_bytes; + const int m_nvram_bytes; + uint8_t m_nvram_defval; + int m_sclk_divider; /* internal registers */ uint8_t m_port_ddr[4]; @@ -253,7 +254,7 @@ public: class hd6301_cpu_device : public m6801_cpu_device { protected: - hd6301_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, const m6800_cpu_device::op_func *insn, const uint8_t *cycles, address_map_constructor internal, int standby_bytes); + hd6301_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, const m6800_cpu_device::op_func *insn, const uint8_t *cycles, address_map_constructor internal, int nvram_bytes); virtual std::unique_ptr create_disassembler() override; @@ -305,7 +306,7 @@ public: auto out_p7_cb() { return m_out_portx_func[2].bind(); } protected: - hd6301x_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor internal, int standby_bytes); + hd6301x_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor internal, int nvram_bytes); void hd6301x_io(address_map &map); void hd6303x_io(address_map &map); @@ -403,7 +404,7 @@ public: class hd6301y_cpu_device : public hd6301x_cpu_device { protected: - hd6301y_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor internal, int standby_bytes); + hd6301y_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor internal, int nvram_bytes); void hd6301y_io(address_map &map); void hd6303y_io(address_map &map);