nsnova: add nvram

This commit is contained in:
hap 2023-11-11 15:11:37 +01:00
parent 231c47ef17
commit 92b128b1e7
5 changed files with 81 additions and 41 deletions

View File

@ -16,8 +16,11 @@ Hardware notes:
- 2KB battery-backed RAM (MSM5128-15RS), 3 sockets, only middle one used
- TTL, piezo, 8*8+4 LEDs, magnetic sensors
The hardware triggers an NMI on power-off (or power-failure). If this isn't done,
NVRAM fails at next power-on.
NOTE: The hardware triggers an NMI on power-off (or power-failure). If this isn't
done, NVRAM fails at next power-on.
TODO:
- if/when MAME supports an exit callback, hook up power-off NMI to that
*******************************************************************************/
@ -49,7 +52,7 @@ public:
m_inputs(*this, "IN.%u", 0)
{ }
DECLARE_INPUT_CHANGED_MEMBER(power) { if (newval && m_power) power_off(); }
DECLARE_INPUT_CHANGED_MEMBER(power_off);
// machine configs
void regence(machine_config &config);
@ -75,9 +78,7 @@ private:
void leds_w(u8 data);
u8 input_r();
void power_off();
bool m_power = false;
u8 m_inp_mux = 0;
u8 m_led_data = 0;
};
@ -90,11 +91,14 @@ void regence_state::machine_start()
save_item(NAME(m_led_data));
}
void regence_state::power_off()
INPUT_CHANGED_MEMBER(regence_state::power_off)
{
// NMI at power-off (it prepares nvram for next power-on)
m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
m_power = false;
if (newval && m_power)
{
m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
m_power = false;
}
}
@ -187,7 +191,7 @@ static INPUT_PORTS_START( regence )
PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_START("POWER") // needs to be triggered for nvram to work
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_CODE(KEYCODE_F1) PORT_CHANGED_MEMBER(DEVICE_SELF, regence_state, power, 0) PORT_NAME("Power Off")
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_CODE(KEYCODE_F1) PORT_CHANGED_MEMBER(DEVICE_SELF, regence_state, power_off, 0) PORT_NAME("Power Off")
INPUT_PORTS_END

View File

@ -61,6 +61,7 @@ Super Constellation also has a power-off NMI, but it doesn't do anything other
than writing 0x08 to control_w.
TODO:
- if/when MAME supports an exit callback, hook up power-off NMI to that
- is Dynamic S a program update of ssensor4 or identical?
*******************************************************************************/
@ -102,7 +103,7 @@ public:
m_inputs(*this, "IN.%u", 0)
{ }
DECLARE_INPUT_CHANGED_MEMBER(power) { if (newval && m_power) power_off(); }
DECLARE_INPUT_CHANGED_MEMBER(power_off);
// machine configs
void nconst(machine_config &config);
@ -138,9 +139,7 @@ private:
u8 input1_r();
u8 input2_r();
void power_off();
bool m_power = false;
u8 m_inp_mux = 0;
u8 m_led_select = 0;
};
@ -153,11 +152,14 @@ void const_state::machine_start()
save_item(NAME(m_led_select));
}
void const_state::power_off()
INPUT_CHANGED_MEMBER(const_state::power_off)
{
// NMI at power-off (ssensor4 prepares nvram for next power-on)
m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
m_power = false;
if (newval && m_power)
{
m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
m_power = false;
}
}
void const_state::init_const()
@ -320,7 +322,7 @@ static INPUT_PORTS_START( ssensor4 )
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_W) PORT_NAME("Hint")
PORT_START("POWER") // needs to be triggered for nvram to work
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_CODE(KEYCODE_F1) PORT_CHANGED_MEMBER(DEVICE_SELF, const_state, power, 0) PORT_NAME("Power Off")
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_CODE(KEYCODE_F1) PORT_CHANGED_MEMBER(DEVICE_SELF, const_state, power_off, 0) PORT_NAME("Power Off")
INPUT_PORTS_END
static INPUT_PORTS_START( nconstq )
@ -345,7 +347,7 @@ static INPUT_PORTS_START( sconst )
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_3) PORT_NAME("Print List / Acc. Time / Pawn")
PORT_START("POWER")
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_CODE(KEYCODE_F1) PORT_CHANGED_MEMBER(DEVICE_SELF, const_state, power, 0) PORT_NAME("Power Off")
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_CODE(KEYCODE_F1) PORT_CHANGED_MEMBER(DEVICE_SELF, const_state, power_off, 0) PORT_NAME("Power Off")
INPUT_PORTS_END

View File

@ -6,9 +6,11 @@
Novag Super Nova & related chess computers. I believe the series started with
Primo. The chess engine is by David Kittinger.
NOTE: nsnova does an NMI at power-off (or power-failure). If this isn't done,
NVRAM won't work properly (supremo doesn't have NVRAM).
TODO:
- NMI on power-off switch, it sets 0x14 bit 7 for standby power (see below)
- add nvram, MCU is missing standby power emulation
- if/when MAME supports an exit callback, hook up power-off NMI to that
- beeps are glitchy, as if interrupted for too long
- nsnova serial port isn't working, MCU emulation problem?
- nsnova unmapped reads from 0x33/0x34
@ -50,6 +52,7 @@ The model number is still 881, ROM is the same as the standard fake-wood version
#include "bus/rs232/rs232.h"
#include "cpu/m6800/m6801.h"
#include "machine/nvram.h"
#include "machine/sensorboard.h"
#include "sound/dac.h"
#include "video/pwm.h"
@ -79,6 +82,8 @@ public:
m_out_lcd(*this, "s%u.%u", 0U, 0U)
{ }
DECLARE_INPUT_CHANGED_MEMBER(power_off);
// machine configs
void snova(machine_config &config);
void supremo(machine_config &config);
@ -100,6 +105,7 @@ private:
void snova_map(address_map &map);
void supremo_map(address_map &map);
void standby(int state);
void lcd_pwm_w(offs_t offset, u8 data);
void update_leds();
@ -131,6 +137,26 @@ void snova_state::machine_start()
I/O
*******************************************************************************/
// power
void snova_state::standby(int state)
{
// clear display
if (state)
{
m_lcd_pwm->clear();
m_led_pwm->clear();
}
}
INPUT_CHANGED_MEMBER(snova_state::power_off)
{
// NMI at power-off, which will trigger standby mode
if (newval && !m_maincpu->standby())
m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
}
// misc
void snova_state::lcd_pwm_w(offs_t offset, u8 data)
@ -223,7 +249,8 @@ void snova_state::supremo_map(address_map &map)
void snova_state::snova_map(address_map &map)
{
supremo_map(map);
map(0x4000, 0x5fff).ram();
map(0x0040, 0x013f).ram().share("internal"); // internal
map(0x4000, 0x5fff).ram().share("nvram");
}
@ -252,6 +279,9 @@ static INPUT_PORTS_START( snova )
PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_E) PORT_NAME("Set Up / Verify")
PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_W) PORT_NAME("Random / Auto Clock")
PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_Q) PORT_NAME("New Game")
PORT_START("POWER") // needs to be triggered for nvram to work
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_CODE(KEYCODE_F1) PORT_CHANGED_MEMBER(DEVICE_SELF, snova_state, power_off, 0) PORT_NAME("Power Off")
INPUT_PORTS_END
static INPUT_PORTS_START( supremo )
@ -282,11 +312,11 @@ INPUT_PORTS_END
Machine Configs
*******************************************************************************/
void snova_state::snova(machine_config &config)
void snova_state::supremo(machine_config &config)
{
// basic machine hardware
HD6303Y(config, m_maincpu, 16_MHz_XTAL);
m_maincpu->set_addrmap(AS_PROGRAM, &snova_state::snova_map);
HD6303Y(config, m_maincpu, 8_MHz_XTAL);
m_maincpu->set_addrmap(AS_PROGRAM, &snova_state::supremo_map);
m_maincpu->in_p2_cb().set(FUNC(snova_state::p2_r));
m_maincpu->out_p2_cb().set(FUNC(snova_state::p2_w));
m_maincpu->out_p5_cb().set(FUNC(snova_state::p5_w));
@ -306,29 +336,33 @@ void snova_state::snova(machine_config &config)
screen.set_visarea_full();
PWM_DISPLAY(config, m_led_pwm).set_size(2, 8);
config.set_default_layout(layout_novag_snova);
config.set_default_layout(layout_novag_supremo);
// sound hardware
SPEAKER(config, "speaker").front_center();
DAC_1BIT(config, m_dac).add_route(ALL_OUTPUTS, "speaker", 0.25);
}
void snova_state::snova(machine_config &config)
{
supremo(config);
// basic machine hardware
m_maincpu->set_clock(16_MHz_XTAL);
m_maincpu->set_addrmap(AS_PROGRAM, &snova_state::snova_map);
m_maincpu->nvram_enable_backup(true);
m_maincpu->standby_cb().set(FUNC(snova_state::standby));
NVRAM(config, "internal", nvram_device::DEFAULT_ALL_0);
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
m_board->set_nvram_enable(true);
config.set_default_layout(layout_novag_snova);
// rs232 (configure after video)
RS232_PORT(config, m_rs232, default_rs232_devices, nullptr);
}
void snova_state::supremo(machine_config &config)
{
snova(config);
// basic machine hardware
m_maincpu->set_clock(8_MHz_XTAL);
m_maincpu->set_addrmap(AS_PROGRAM, &snova_state::supremo_map);
config.set_default_layout(layout_novag_supremo);
config.device_remove("rs232");
}
/*******************************************************************************

View File

@ -14,10 +14,10 @@ The expansion modules are basically entire chesscomputers, making the whole
thing combined a 'dual brain' chesscomputer. The embedded chess engine is by
Julio Kaplan and Craig Barnes, same as the one in SciSys Turbo S-24K.
NOTE: In order for nvram to work properly, press the STOP button to turn off
NOTE: In order for NVRAM to work properly, press the STOP button to turn off
the chesscomputer before exiting MAME. Other than ACL (which is an unemulated
hardware button that disconnects the battery), there is no known method to
force a cold boot. So if nvram somehow becomes broken, remove the nvram files.
force a cold boot. So if NVRAM somehow becomes broken, remove the NVRAM files.
Hardware notes:
@ -55,7 +55,7 @@ to be upgraded with an EMI PCB (power supply related, meaningless for emulation)
TODO:
- OSA PC link, uses MCU serial interface
- MCU internal nvram belongs in m6801.cpp
- MCU internal NVRAM belongs in m6801.cpp
*******************************************************************************/

View File

@ -8,7 +8,7 @@ Saitek Kasparov Renaissance
Saitek's 2nd version modular chesscomputer. It accepts the same modules as
Leonardo/Galileo. "OSA" version for Renaissance is 1.5.
NOTE: In order for nvram to work properly, press the STOP button to turn off
NOTE: In order for NVRAM to work properly, press the STOP button to turn off
the chesscomputer before exiting MAME. Unlike Leonardo/Galileo, it looks like
it will always do a cold boot if you reset without having pressed STOP.