summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author hap <happppp@users.noreply.github.com>2024-02-10 23:36:25 +0100
committer hap <happppp@users.noreply.github.com>2024-02-10 23:36:35 +0100
commit2aee7dcc5d164297ea3fa13565c1689bd9c0c7c4 (patch)
tree1700465c35c46c8d2c37e4b1278798bc6c3104aa
parent3b5a2f9cbc8f63cf09263071d601b1b8d2b42b0c (diff)
h8: add software standby mode and optional nvram
-rw-r--r--src/devices/cpu/h8/h8.cpp87
-rw-r--r--src/devices/cpu/h8/h8.h50
-rw-r--r--src/devices/cpu/h8/h8.lst6
-rw-r--r--src/devices/cpu/h8/h8325.cpp19
-rw-r--r--src/devices/cpu/h8/h8325.h1
-rw-r--r--src/devices/cpu/h8/h8_port.cpp32
-rw-r--r--src/devices/cpu/h8/h8_port.h5
-rw-r--r--src/devices/cpu/h8/h8_sci.cpp4
-rw-r--r--src/devices/cpu/m6800/m6801.cpp14
-rw-r--r--src/mame/saitek/prisma.cpp17
10 files changed, 198 insertions, 37 deletions
diff --git a/src/devices/cpu/h8/h8.cpp b/src/devices/cpu/h8/h8.cpp
index a3aaaf9303f..ce62b41f066 100644
--- a/src/devices/cpu/h8/h8.cpp
+++ b/src/devices/cpu/h8/h8.cpp
@@ -2,10 +2,12 @@
// copyright-holders:Olivier Galibert
/***************************************************************************
- h8.h
+ h8.cpp
H8-300 base cpu emulation
+ TODO:
+ - add STBY pin (hardware standby mode)
***************************************************************************/
@@ -13,19 +15,25 @@
#include "h8.h"
#include "h8_dma.h"
#include "h8_dtc.h"
+#include "h8_port.h"
#include "h8d.h"
h8_device::h8_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor map_delegate) :
cpu_device(mconfig, type, tag, owner, clock),
+ device_nvram_interface(mconfig, *this),
m_program_config("program", ENDIANNESS_BIG, 16, 16, 0, map_delegate),
+ m_internal_ram(*this, "internal_ram"),
m_read_adc(*this, 0),
m_read_port(*this, 0),
m_write_port(*this),
m_sci(*this, "sci%u", 0),
m_sci_tx(*this),
m_sci_clk(*this),
+ m_standby_cb(*this),
m_PPC(0), m_NPC(0), m_PC(0), m_PIR(0), m_EXR(0), m_CCR(0), m_MAC(0), m_MACF(0),
- m_TMP1(0), m_TMP2(0), m_TMPR(0), m_inst_state(0), m_inst_substate(0), m_icount(0), m_bcount(0), m_irq_vector(0), m_taken_irq_vector(0), m_irq_level(0), m_taken_irq_level(0), m_irq_required(false), m_irq_nmi(false)
+ m_TMP1(0), m_TMP2(0), m_TMPR(0), m_inst_state(0), m_inst_substate(0), m_icount(0), m_bcount(0),
+ m_irq_vector(0), m_taken_irq_vector(0), m_irq_level(0), m_taken_irq_level(0), m_irq_required(false), m_irq_nmi(false),
+ m_standby_pending(false), m_nvram_defval(0), m_nvram_battery(true)
{
m_supports_advanced = false;
m_mode_advanced = false;
@@ -35,6 +43,7 @@ h8_device::h8_device(const machine_config &mconfig, device_type type, const char
m_mac_saturating = false;
m_has_trace = false;
m_has_hc = true;
+ nvram_enable_backup(false); // disable nvram by default
for(unsigned int i=0; i != m_read_adc.size(); i++)
m_read_adc[i].bind().set([this, i]() { return adc_default(i); });
@@ -146,6 +155,8 @@ void h8_device::device_start()
save_item(NAME(m_taken_irq_level));
save_item(NAME(m_irq_nmi));
save_item(NAME(m_current_dma));
+ save_item(NAME(m_standby_pending));
+ save_item(NAME(m_nvram_battery));
set_icountptr(m_icount);
@@ -182,8 +193,74 @@ void h8_device::device_reset()
m_taken_irq_level = -1;
m_current_dma = -1;
m_current_dtc = nullptr;
+
+ m_standby_pending = false;
+ m_standby_cb(0);
+}
+
+
+// nvram handling
+
+bool h8_device::nvram_write(util::write_stream &file)
+{
+ // if it's currently not battery-backed, don't save at all
+ if(!m_nvram_battery)
+ return true;
+
+ size_t actual;
+
+ // internal RAM
+ if(m_internal_ram) {
+ if(file.write(&m_internal_ram[0], m_internal_ram.bytes(), actual) || m_internal_ram.bytes() != actual)
+ return false;
+ }
+
+ // I/O ports
+ for(h8_port_device &port : h8_port_device_enumerator(*this)) {
+ if (!port.nvram_write(file))
+ return false;
+ }
+
+ return true;
}
+bool h8_device::nvram_read(util::read_stream &file)
+{
+ size_t actual;
+
+ // internal RAM
+ if(m_internal_ram) {
+ if(file.read(&m_internal_ram[0], m_internal_ram.bytes(), actual) || m_internal_ram.bytes() != actual)
+ return false;
+ }
+
+ // I/O ports
+ for(h8_port_device &port : h8_port_device_enumerator(*this)) {
+ if (!port.nvram_read(file))
+ return false;
+ }
+
+ return true;
+}
+
+void h8_device::nvram_default()
+{
+ if(!nvram_backup_enabled() || !m_internal_ram)
+ return;
+
+ // default nvram from mytag:nvram region if it exists (only the internal RAM for now)
+ memory_region *region = memregion("nvram");
+ if(region != nullptr) {
+ if(region->bytes() != m_internal_ram.bytes())
+ fatalerror("%s: Wrong region size (expected 0x%x, found 0x%x)", region->name(), m_internal_ram.bytes(), region->bytes());
+
+ std::copy_n(&region->as_u16(), m_internal_ram.length(), &m_internal_ram[0]);
+ }
+ else
+ std::fill_n(&m_internal_ram[0], m_internal_ram.length(), m_nvram_defval);
+}
+
+
bool h8_device::trigger_dma(int vector)
{
bool dma_triggered = false;
@@ -458,6 +535,12 @@ void h8_device::prefetch_done_noirq_notrace()
void h8_device::set_irq(int irq_vector, int irq_level, bool irq_nmi)
{
+ // wake up from software standby with an external interrupt
+ if(standby() && (irq_vector || irq_nmi)) {
+ resume(SUSPEND_REASON_CLOCK);
+ m_standby_cb(0);
+ }
+
m_irq_vector = irq_vector;
m_irq_level = irq_level;
m_irq_nmi = irq_nmi;
diff --git a/src/devices/cpu/h8/h8.h b/src/devices/cpu/h8/h8.h
index 6b01f781c45..6bd1289a2bb 100644
--- a/src/devices/cpu/h8/h8.h
+++ b/src/devices/cpu/h8/h8.h
@@ -6,7 +6,6 @@
H8-300 base cpu emulation
-
***************************************************************************/
#ifndef MAME_CPU_H8_H8_H
@@ -23,7 +22,7 @@ class h8_device;
#include "h8_sci.h"
-class h8_device : public cpu_device {
+class h8_device : public cpu_device, public device_nvram_interface {
public:
enum {
STATE_RESET = 0x10000,
@@ -46,6 +45,11 @@ public:
template<int Sci> void sci_rx_w(int state) { m_sci[Sci]->do_rx_w(state); }
template<int Sci> void sci_clk_w(int state) { m_sci[Sci]->do_clk_w(state); }
+ void nvram_set_battery(int state) { m_nvram_battery = bool(state); } // default is 1 (nvram_enable_backup needs to be true)
+ void nvram_set_default_value(uint8_t val) { m_nvram_defval = val; } // default is 0
+ auto standby_cb() { return m_standby_cb.bind(); } // notifier (not an output pin)
+ int standby() { return suspended(SUSPEND_REASON_CLOCK) ? 1 : 0; }
+
void internal_update();
void set_irq(int irq_vector, int irq_level, bool irq_nmi);
bool trigger_dma(int vector);
@@ -104,12 +108,12 @@ protected:
h8_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor map_delegate);
- // device-level overrides
+ // device_t implementation
virtual void device_config_complete() override;
virtual void device_start() override;
virtual void device_reset() override;
- // device_execute_interface overrides
+ // device_execute_interface implementation
virtual bool cpu_is_interruptible() const override { return true; }
virtual uint32_t execute_min_cycles() const noexcept override { return 2; }
virtual uint32_t execute_max_cycles() const noexcept override { return 12; }
@@ -117,25 +121,32 @@ protected:
virtual bool execute_input_edge_triggered(int inputnum) const noexcept override { return inputnum == INPUT_LINE_NMI; }
virtual void execute_run() override;
- // device_memory_interface overrides
+ // device_memory_interface implementation
virtual space_config_vector memory_space_config() const override;
- // device_state_interface overrides
+ // device_state_interface implementation
virtual void state_import(const device_state_entry &entry) override;
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
+ // device_disasm_interface implementation
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
+ // device_nvram_interface implementation
+ virtual void nvram_default() override;
+ virtual bool nvram_read(util::read_stream &file) override;
+ virtual bool nvram_write(util::write_stream &file) override;
+
address_space_config m_program_config;
memory_access<32, 1, 0, ENDIANNESS_BIG>::cache m_cache;
memory_access<32, 1, 0, ENDIANNESS_BIG>::specific m_program;
+ optional_shared_ptr<uint16_t> m_internal_ram; // for nvram
devcb_read16::array<8> m_read_adc;
devcb_read8::array<PORT_COUNT> m_read_port;
devcb_write8::array<PORT_COUNT> m_write_port;
optional_device_array<h8_sci_device, 3> m_sci;
devcb_write_line::array<3> m_sci_tx, m_sci_clk;
+ devcb_write_line m_standby_cb;
h8gen_dma_device *m_dma_device;
h8_dtc_device *m_dtc_device;
@@ -143,18 +154,18 @@ protected:
int m_current_dma;
h8_dtc_state *m_current_dtc;
- uint32_t m_PPC; /* previous program counter */
- uint32_t m_NPC; /* next start-of-instruction program counter */
- uint32_t m_PC; /* program counter */
- uint16_t m_PIR; /* Prefetched word */
- uint16_t m_IR[5]; /* Fetched instruction */
- uint16_t m_R[16]; /* Rn (0-7), En (8-15, h8-300h+) */
- uint8_t m_EXR; /* Interrupt/trace register (h8s/2000+) */
- uint8_t m_CCR; /* Condition-code register */
- int64_t m_MAC; /* Multiply accumulator (h8s/2600+) */
- uint8_t m_MACF; /* MAC flags (h8s/2600+) */
+ uint32_t m_PPC; // previous program counter
+ uint32_t m_NPC; // next start-of-instruction program counter
+ uint32_t m_PC; // program counter
+ uint16_t m_PIR; // Prefetched word
+ uint16_t m_IR[5]; // Fetched instruction
+ uint16_t m_R[16]; // Rn (0-7), En (8-15, h8-300h+)
+ uint8_t m_EXR; // Interrupt/trace register (h8s/2000+)
+ uint8_t m_CCR; // Condition-code register
+ int64_t m_MAC; // Multiply accumulator (h8s/2600+)
+ uint8_t m_MACF; // MAC flags (h8s/2600+)
uint32_t m_TMP1, m_TMP2;
- uint32_t m_TMPR; /* For debugger ER register import */
+ uint32_t m_TMPR; // For debugger ER register import
bool m_has_exr, m_has_mac, m_has_trace, m_supports_advanced, m_mode_advanced, m_mode_a20, m_mac_saturating;
bool m_has_hc; // GT913's CCR bit 5 is I, not H
@@ -164,6 +175,9 @@ protected:
int m_irq_vector, m_taken_irq_vector;
int m_irq_level, m_taken_irq_level;
bool m_irq_required, m_irq_nmi;
+ bool m_standby_pending;
+ uint16_t m_nvram_defval;
+ bool m_nvram_battery;
virtual void do_exec_full();
virtual void do_exec_partial();
diff --git a/src/devices/cpu/h8/h8.lst b/src/devices/cpu/h8/h8.lst
index c09caa3d904..88637e0d38a 100644
--- a/src/devices/cpu/h8/h8.lst
+++ b/src/devices/cpu/h8/h8.lst
@@ -741,7 +741,11 @@ macro jsr32 %opc %spreg
0180 ffff 0 sleep - -
prefetch_start
- while(!m_irq_vector) {
+ if(m_standby_pending) {
+ suspend(SUSPEND_REASON_CLOCK, true);
+ m_standby_cb(1);
+ }
+ else while(!m_irq_vector) {
eat-all-cycles;
}
prefetch_done();
diff --git a/src/devices/cpu/h8/h8325.cpp b/src/devices/cpu/h8/h8325.cpp
index e2cc665405d..fa45bb16985 100644
--- a/src/devices/cpu/h8/h8325.cpp
+++ b/src/devices/cpu/h8/h8325.cpp
@@ -7,10 +7,9 @@
H8/325 family emulation
TODO:
- - nvram and standby emulation, but that's a thing for more H8 types?
- serial controllers are slightly different, has 3 interrupt sources
instead of 4
- - SYSCR register (RAM disable, NMI edge invert, standby)
+ - SYSCR NMI edge invert
- HCSR register @ 0xfffe (port 3 handshake)
- FNCR register @ 0xffff (16-bit timer noise canceler)
@@ -42,6 +41,7 @@ h8325_device::h8325_device(const machine_config &mconfig, device_type type, cons
m_timer16(*this, "timer16"),
m_timer16_0(*this, "timer16:0"),
m_read_md(*this, 3),
+ m_ram_view(*this, "ram_view"),
m_syscr(0),
m_mds(0),
m_ram_start(start)
@@ -80,7 +80,8 @@ h8322_device::h8322_device(const machine_config &mconfig, const char *tag, devic
void h8325_device::map(address_map &map)
{
- map(m_ram_start, 0xff7f).ram();
+ map(m_ram_start, 0xff7f).view(m_ram_view);
+ m_ram_view[0](m_ram_start, 0xff7f).ram().share(m_internal_ram);
map(0xff90, 0xff90).rw(m_timer16_0, FUNC(h8325_timer16_channel_device::tcr_r), FUNC(h8325_timer16_channel_device::tcr_w));
map(0xff91, 0xff91).rw(m_timer16_0, FUNC(h8325_timer16_channel_device::tsr_r), FUNC(h8325_timer16_channel_device::tsr_w));
@@ -199,6 +200,9 @@ void h8325_device::device_reset()
h8_device::device_reset();
m_syscr = 0x01;
+ m_ram_view.select(0);
+
+ // MD pins are latched at reset
m_mds = m_read_md() & 3;
}
@@ -211,6 +215,15 @@ void h8325_device::syscr_w(uint8_t data)
{
logerror("syscr = %02x\n", data);
m_syscr = data;
+
+ // RAME
+ if (data & 1)
+ m_ram_view.select(0);
+ else
+ m_ram_view.disable();
+
+ // SSBY
+ m_standby_pending = bool(data & 0x80);
}
uint8_t h8325_device::mdcr_r()
diff --git a/src/devices/cpu/h8/h8325.h b/src/devices/cpu/h8/h8325.h
index 5c18b2e1cbf..fba31ce4ce7 100644
--- a/src/devices/cpu/h8/h8325.h
+++ b/src/devices/cpu/h8/h8325.h
@@ -74,6 +74,7 @@ protected:
required_device<h8325_timer16_channel_device> m_timer16_0;
devcb_read8 m_read_md;
+ memory_view m_ram_view;
uint8_t m_syscr;
uint8_t m_mds;
diff --git a/src/devices/cpu/h8/h8_port.cpp b/src/devices/cpu/h8/h8_port.cpp
index 6f65bfa6ced..4aeb446c85d 100644
--- a/src/devices/cpu/h8/h8_port.cpp
+++ b/src/devices/cpu/h8/h8_port.cpp
@@ -98,3 +98,35 @@ void h8_port_device::device_reset()
{
update_output();
}
+
+bool h8_port_device::nvram_write(util::write_stream &file)
+{
+ size_t actual;
+ u8 buf[4];
+
+ buf[0] = m_ddr;
+ buf[1] = m_dr;
+ buf[2] = m_pcr;
+ buf[3] = m_odr;
+
+ if(file.write(&buf, sizeof(buf), actual) || (sizeof(buf) != actual))
+ return false;
+
+ return true;
+}
+
+bool h8_port_device::nvram_read(util::read_stream &file)
+{
+ size_t actual;
+ u8 buf[4];
+
+ if(file.read(&buf, sizeof(buf), actual) || (sizeof(buf) != actual))
+ return false;
+
+ m_ddr = buf[0];
+ m_dr = buf[1];
+ m_pcr = buf[2];
+ m_odr = buf[3];
+
+ return true;
+}
diff --git a/src/devices/cpu/h8/h8_port.h b/src/devices/cpu/h8/h8_port.h
index cc809b633af..a9b224d2289 100644
--- a/src/devices/cpu/h8/h8_port.h
+++ b/src/devices/cpu/h8/h8_port.h
@@ -38,6 +38,9 @@ public:
void odr_w(uint8_t data);
uint8_t odr_r();
+ bool nvram_read(util::read_stream &file);
+ bool nvram_write(util::write_stream &file);
+
protected:
required_device<h8_device> m_cpu;
@@ -54,4 +57,6 @@ protected:
DECLARE_DEVICE_TYPE(H8_PORT, h8_port_device)
+typedef device_type_enumerator<h8_port_device> h8_port_device_enumerator;
+
#endif // MAME_CPU_H8_H8_PORT_H
diff --git a/src/devices/cpu/h8/h8_sci.cpp b/src/devices/cpu/h8/h8_sci.cpp
index d78eb04f83e..1bf59ee2d08 100644
--- a/src/devices/cpu/h8/h8_sci.cpp
+++ b/src/devices/cpu/h8/h8_sci.cpp
@@ -313,7 +313,7 @@ void h8_sci_device::do_rx_w(int state)
{
m_rx_value = state;
if(V>=2) logerror("rx=%d\n", state);
- if(!m_rx_value && !(m_clock_state & CLK_RX) && m_rx_state != ST_IDLE)
+ if(!m_rx_value && !(m_clock_state & CLK_RX) && m_rx_state != ST_IDLE && !m_cpu->standby())
clock_start(CLK_RX);
}
@@ -321,7 +321,7 @@ void h8_sci_device::do_clk_w(int state)
{
if(m_ext_clock_value != state) {
m_ext_clock_value = state;
- if(m_clock_state) {
+ if(m_clock_state && !m_cpu->standby()) {
switch(m_clock_mode) {
case clock_mode_t::EXTERNAL_ASYNC:
if(m_ext_clock_value) {
diff --git a/src/devices/cpu/m6800/m6801.cpp b/src/devices/cpu/m6800/m6801.cpp
index d799d737c1b..cff7f922245 100644
--- a/src/devices/cpu/m6800/m6801.cpp
+++ b/src/devices/cpu/m6800/m6801.cpp
@@ -274,7 +274,7 @@ void m6801_cpu_device::m6801_io(address_map &map)
void m6801_cpu_device::m6803_mem(address_map &map)
{
m6801_io(map);
- map(0x0080, 0x00ff).ram().share("internal");
+ map(0x0080, 0x00ff).ram().share(m_internal_ram);
}
void m6801_cpu_device::m6801_mem(address_map &map)
@@ -300,7 +300,7 @@ void m6801u4_cpu_device::m6801u4_io(address_map &map)
void m6801u4_cpu_device::m6801u4_mem(address_map &map)
{
m6801u4_io(map);
- map(0x0040, 0x00ff).ram().share("internal");
+ map(0x0040, 0x00ff).ram().share(m_internal_ram);
map(0xf000, 0xffff).rom().region(DEVICE_SELF, 0);
}
@@ -351,13 +351,13 @@ void hd6301x_cpu_device::hd6301x_io(address_map &map)
void hd6301x_cpu_device::hd6303x_mem(address_map &map)
{
hd6303x_io(map);
- map(0x0040, 0x00ff).ram().share("internal");
+ map(0x0040, 0x00ff).ram().share(m_internal_ram);
}
void hd6301x_cpu_device::hd6301x_mem(address_map &map)
{
hd6301x_io(map);
- map(0x0040, 0x00ff).ram().share("internal");
+ map(0x0040, 0x00ff).ram().share(m_internal_ram);
map(0xf000, 0xffff).rom().region(DEVICE_SELF, 0);
}
@@ -387,13 +387,13 @@ void hd6301y_cpu_device::hd6301y_io(address_map &map)
void hd6301y_cpu_device::hd6303y_mem(address_map &map)
{
hd6303y_io(map);
- map(0x0040, 0x013f).ram().share("internal");
+ map(0x0040, 0x013f).ram().share(m_internal_ram);
}
void hd6301y_cpu_device::hd6301y_mem(address_map &map)
{
hd6301y_io(map);
- map(0x0040, 0x013f).ram().share("internal");
+ map(0x0040, 0x013f).ram().share(m_internal_ram);
map(0xc000, 0xffff).rom().region(DEVICE_SELF, 0);
}
@@ -428,7 +428,7 @@ 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_internal_ram(*this, "internal")
+ , m_internal_ram(*this, "internal_ram")
, m_nvram_bytes(nvram_bytes)
, m_nvram_defval(0)
, m_nvram_battery(true)
diff --git a/src/mame/saitek/prisma.cpp b/src/mame/saitek/prisma.cpp
index d3aae90a4a3..d53720e4917 100644
--- a/src/mame/saitek/prisma.cpp
+++ b/src/mame/saitek/prisma.cpp
@@ -14,10 +14,7 @@ Hardware notes:
It was also sold by Tandy as Chess Champion 2150L, with a slower CPU (16MHz XTAL).
TODO:
-- does not work, it's unresponsive and will lock up after pressing buttons, irq
- or opcode bug? (hold S to boot it up for now, that's not how it's supposed to be)
-- add nvram, should be internal to H8, but it's missing standby emulation
-- everything else
+- finish driver
*******************************************************************************/
@@ -55,6 +52,8 @@ public:
void prisma(machine_config &config);
+ DECLARE_INPUT_CHANGED_MEMBER(go_button);
+
protected:
virtual void machine_start() override;
@@ -108,6 +107,10 @@ void prisma_state::machine_start()
I/O
*******************************************************************************/
+INPUT_CHANGED_MEMBER(prisma_state::go_button)
+{
+}
+
void prisma_state::lcd_pwm_w(offs_t offset, u8 data)
{
m_out_lcd[offset & 0x3f][offset >> 6] = data;
@@ -253,6 +256,9 @@ static INPUT_PORTS_START( prisma )
PORT_CONFNAME( 0x01, 0x01, "Battery Status" )
PORT_CONFSETTING( 0x00, "Low" )
PORT_CONFSETTING( 0x01, DEF_STR( Normal ) )
+
+ PORT_START("RESET")
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_Z) PORT_CHANGED_MEMBER(DEVICE_SELF, prisma_state, go_button, 0) PORT_NAME("Go")
INPUT_PORTS_END
@@ -265,6 +271,8 @@ void prisma_state::prisma(machine_config &config)
{
// basic machine hardware
H8325(config, m_maincpu, 20_MHz_XTAL / 2);
+ m_maincpu->nvram_enable_backup(true);
+ m_maincpu->nvram_set_default_value(~0);
m_maincpu->set_addrmap(AS_PROGRAM, &prisma_state::main_map);
m_maincpu->write_port1().set(FUNC(prisma_state::p1_w));
m_maincpu->write_port2().set(FUNC(prisma_state::p2_w));
@@ -279,6 +287,7 @@ void prisma_state::prisma(machine_config &config)
SENSORBOARD(config, m_board).set_type(sensorboard_device::BUTTONS);
m_board->init_cb().set(m_board, FUNC(sensorboard_device::preset_chess));
m_board->set_delay(attotime::from_msec(150));
+ m_board->set_nvram_enable(true);
// video hardware
SED1502(config, m_lcd, 32768).write_segs().set(FUNC(prisma_state::lcd_output_w));