diff --git a/hash/bbc_rom.xml b/hash/bbc_rom.xml
index e50cfa8a2eb..8fc4234b000 100644
--- a/hash/bbc_rom.xml
+++ b/hash/bbc_rom.xml
@@ -5282,8 +5282,6 @@ license:CC0-1.0
-
-
@@ -5300,8 +5298,6 @@ license:CC0-1.0
-
-
diff --git a/src/devices/bus/bbc/rom/genie.cpp b/src/devices/bus/bbc/rom/genie.cpp
index 28b9b42644a..6515bfe4030 100644
--- a/src/devices/bus/bbc/rom/genie.cpp
+++ b/src/devices/bus/bbc/rom/genie.cpp
@@ -3,7 +3,7 @@
// thanks-to:Derek Mathieson (original author of Genie)
/***************************************************************************
- PMS Genie
+ PMS Genie ROM Board
***************************************************************************/
@@ -11,28 +11,45 @@
#include "genie.h"
-//**************************************************************************
-// DEVICE DEFINITIONS
-//**************************************************************************
+namespace {
-DEFINE_DEVICE_TYPE(BBC_PMSGENIE, bbc_pmsgenie_device, "bbc_pmsgenie", "PMS Genie ROM Board")
-
-
-//**************************************************************************
-// LIVE DEVICE
-//**************************************************************************
-
-//-------------------------------------------------
-// bbc_palprom_device - constructor
-//-------------------------------------------------
-
-bbc_pmsgenie_device::bbc_pmsgenie_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : device_t(mconfig, BBC_PMSGENIE, tag, owner, clock)
- , device_bbc_rom_interface(mconfig, *this)
- , m_write_latch(0)
- , m_bank_latch(0)
+class bbc_pmsgenie_device
+ : public device_t
+ , public device_bbc_rom_interface
+ , public device_nvram_interface
{
-}
+public:
+ bbc_pmsgenie_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, BBC_PMSGENIE, tag, owner, clock)
+ , device_bbc_rom_interface(mconfig, *this)
+ , device_nvram_interface(mconfig, *this)
+ , m_nvram(*this, "nvram", 0x8000, ENDIANNESS_LITTLE)
+ , m_ram(*this, "ram", 0x8000, ENDIANNESS_LITTLE)
+ , m_write_latch(0)
+ , m_bank_latch(0)
+ {
+ }
+
+protected:
+ // device_t overrides
+ virtual void device_start() override ATTR_COLD;
+
+ // device_nvram_interface overrides
+ virtual void nvram_default() override;
+ virtual bool nvram_read(util::read_stream &file) override;
+ virtual bool nvram_write(util::write_stream &file) override;
+
+ // device_bbc_rom_interface overrides
+ virtual uint8_t read(offs_t offset) override;
+ virtual uint32_t get_rom_size() override { return 0x4000; }
+
+private:
+ memory_share_creator m_nvram;
+ memory_share_creator m_ram;
+
+ uint8_t m_write_latch;
+ uint8_t m_bank_latch;
+};
//-------------------------------------------------
@@ -45,6 +62,65 @@ void bbc_pmsgenie_device::device_start()
save_item(NAME(m_bank_latch));
}
+
+//-------------------------------------------------
+// nvram_default - called to initialize NVRAM to
+// its default state
+//-------------------------------------------------
+
+void bbc_pmsgenie_device::nvram_default()
+{
+ // initial data from Genie formatter
+ static const uint8_t format[256] =
+ {
+ 0x37, 0x1b, 0x36, 0x1e, 0x1e, 0x35, 0x12, 0x10, 0x36, 0x34, 0x00, 0x00, 0x03, 0x01, 0x01, 0x01,
+ 0xff, 0x01, 0x01, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x44, 0x65, 0x72, 0x65, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+
+ // clear the Genie
+ memset(&m_nvram[0], 0x00, sizeof(m_nvram));
+
+ // set password to "GENIE", and initialise structures
+ memcpy(&m_nvram[0], format, sizeof(format));
+}
+
+//-------------------------------------------------
+// nvram_read - called to read NVRAM from the
+// specified file
+//-------------------------------------------------
+
+bool bbc_pmsgenie_device::nvram_read(util::read_stream &file)
+{
+ auto const [err, actual] = util::read(file, m_nvram, m_nvram.bytes());
+ return !err && (actual == m_nvram.bytes());
+}
+
+//-------------------------------------------------
+// nvram_write - called to write NVRAM to the
+// specified file
+//-------------------------------------------------
+
+bool bbc_pmsgenie_device::nvram_write(util::write_stream &file)
+{
+ auto const [err, actual] = util::write(file, m_nvram, m_nvram.bytes());
+ return !err;
+}
+
+
//-------------------------------------------------
// read
//-------------------------------------------------
@@ -58,17 +134,18 @@ uint8_t bbc_pmsgenie_device::read(offs_t offset)
switch (offset >> 8)
{
case 0x1e:
- /* &9E00-&9EFF - Write value latch */
+ // &9E00-&9EFF - Write value latch
m_write_latch = offset & 0xff;
break;
+
case 0x1f:
- /* &9F00-&9FFF - Bank select latch
- Bit
- 0-2: RAM bank select
- 3: Not used
- 4-5: ROM bank select
- 6: Not used
- 7: Read / NOT Write for internal RAM */
+ // &9F00-&9FFF - Bank select latch
+ // Bit
+ // 0-2: RAM bank select
+ // 3: Not used
+ // 4-5: ROM bank select
+ // 6: Not used
+ // 7: Read / NOT Write for internal RAM
m_bank_latch = offset & 0xff;
break;
}
@@ -77,35 +154,28 @@ uint8_t bbc_pmsgenie_device::read(offs_t offset)
switch (offset & 0x2000)
{
case 0x0000:
- /* &8000-&9FFF - 4 Pages of 8K ROM (32K in total) */
+ // &8000-&9FFF - 4 Pages of 8K ROM (32K in total)
data = get_rom_base()[(offset & 0x1fff) | (m_bank_latch & 0x30) << 9];
break;
case 0x2000:
- /* &A000-&BFFF - 8 Pages of 8K RAM (64K in total) */
+ // &A000-&BFFF - 8 Pages of 8K RAM (64K in total)
if (m_bank_latch & 0x80)
{
- /* RAM read */
+ // RAM read
if (m_bank_latch & 0x04)
- {
- data = get_nvram_base()[(offset & 0x1fff) | (m_bank_latch & 0x03) << 13];
- }
+ data = m_nvram[(offset & 0x1fff) | (m_bank_latch & 0x03) << 13];
else
- {
- data = get_ram_base()[(offset & 0x1fff) | (m_bank_latch & 0x03) << 13];
- }
+ data = m_ram[(offset & 0x1fff) | (m_bank_latch & 0x03) << 13];
}
else
{
- /* RAM write */
+ // RAM write
if (m_bank_latch & 0x04)
- {
- get_nvram_base()[(offset & 0x1fff) | (m_bank_latch & 0x03) << 13] = m_write_latch;
- }
+ m_nvram[(offset & 0x1fff) | (m_bank_latch & 0x03) << 13] = m_write_latch;
else
- {
- get_ram_base()[(offset & 0x1fff) | (m_bank_latch & 0x03) << 13] = m_write_latch;
- }
+ m_ram[(offset & 0x1fff) | (m_bank_latch & 0x03) << 13] = m_write_latch;
+
data = m_write_latch;
}
break;
@@ -113,3 +183,8 @@ uint8_t bbc_pmsgenie_device::read(offs_t offset)
return data;
}
+
+} // anonymous namespace
+
+
+DEFINE_DEVICE_TYPE_PRIVATE(BBC_PMSGENIE, device_bbc_rom_interface, bbc_pmsgenie_device, "bbc_pmsgenie", "PMS Genie ROM Board")
diff --git a/src/devices/bus/bbc/rom/genie.h b/src/devices/bus/bbc/rom/genie.h
index 8dec5ce6f53..ec57e4a0492 100644
--- a/src/devices/bus/bbc/rom/genie.h
+++ b/src/devices/bus/bbc/rom/genie.h
@@ -1,11 +1,5 @@
// license:BSD-3-Clause
// copyright-holders:Nigel Barnes
-/***************************************************************************
-
- BBC Micro ROM carrier boards
-
-***************************************************************************/
-
#ifndef MAME_BUS_BBC_ROM_GENIE_H
#define MAME_BUS_BBC_ROM_GENIE_H
@@ -14,35 +8,6 @@
#include "slot.h"
-//**************************************************************************
-// TYPE DEFINITIONS
-//**************************************************************************
-
-// ======================> bbc_genie_device
-
-class bbc_pmsgenie_device : public device_t,
- public device_bbc_rom_interface
-{
-public:
- // construction/destruction
- bbc_pmsgenie_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-
-protected:
- // device-level overrides
- virtual void device_start() override ATTR_COLD;
-
- // device_bbc_rom_interface overrides
- virtual uint8_t read(offs_t offset) override;
- virtual uint32_t get_rom_size() override { return 0x4000; }
-
-private:
- uint8_t m_write_latch;
- uint8_t m_bank_latch;
-};
-
-
-// device type definition
-DECLARE_DEVICE_TYPE(BBC_PMSGENIE, bbc_pmsgenie_device)
-
+DECLARE_DEVICE_TYPE(BBC_PMSGENIE, device_bbc_rom_interface)
#endif // MAME_BUS_BBC_ROM_GENIE_H