mirror of
https://github.com/holub/mame
synced 2025-04-22 16:31:49 +03:00
ccompan2: remove standbytimer,
hlcd0515/mattelchess: add nvram
This commit is contained in:
parent
eb1d4f8ad7
commit
7a691be059
@ -22,14 +22,14 @@ DEFINE_DEVICE_TYPE(NVRAM, nvram_device, "nvram", "NVRAM")
|
||||
// nvram_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
nvram_device::nvram_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, NVRAM, tag, owner, clock),
|
||||
device_nvram_interface(mconfig, *this),
|
||||
m_region(*this, DEVICE_SELF),
|
||||
m_default_value(DEFAULT_ALL_1),
|
||||
m_custom_handler(*this),
|
||||
m_base(nullptr),
|
||||
m_length(0)
|
||||
nvram_device::nvram_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||
device_t(mconfig, NVRAM, tag, owner, clock),
|
||||
device_nvram_interface(mconfig, *this),
|
||||
m_region(*this, DEVICE_SELF),
|
||||
m_default_value(DEFAULT_ALL_1),
|
||||
m_custom_handler(*this),
|
||||
m_base(nullptr),
|
||||
m_length(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -30,9 +30,13 @@ DEFINE_DEVICE_TYPE(HLCD0601, hlcd0601_device, "hlcd0601", "Hughes HLCD 0601 LCD
|
||||
|
||||
hlcd0515_device::hlcd0515_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 colmax) :
|
||||
device_t(mconfig, type, tag, owner, clock),
|
||||
device_nvram_interface(mconfig, *this),
|
||||
m_colmax(colmax),
|
||||
m_write_cols(*this), m_write_data(*this)
|
||||
{ }
|
||||
{
|
||||
// disable nvram by default
|
||||
nvram_enable_backup(false);
|
||||
}
|
||||
|
||||
hlcd0515_device::hlcd0515_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
|
||||
hlcd0515_device(mconfig, HLCD0515, tag, owner, clock, 25)
|
||||
@ -56,18 +60,9 @@ hlcd0601_device::hlcd0601_device(const machine_config &mconfig, const char *tag,
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void hlcd0515_device::device_start()
|
||||
void hlcd0515_device::internal_clear()
|
||||
{
|
||||
// timer
|
||||
m_lcd_timer = timer_alloc(FUNC(hlcd0515_device::scan_lcd), this);
|
||||
attotime period = attotime::from_hz(clock() / 2);
|
||||
m_lcd_timer->adjust(period, 0, period);
|
||||
|
||||
// zerofill
|
||||
m_cs = 0;
|
||||
m_clk = 0;
|
||||
m_data = 0;
|
||||
m_dataout = 0;
|
||||
// clear internal registers and RAM
|
||||
m_count = 0;
|
||||
m_control = 0;
|
||||
m_blank = false;
|
||||
@ -76,6 +71,21 @@ void hlcd0515_device::device_start()
|
||||
m_rowsel = 0;
|
||||
m_buffer = 0;
|
||||
memset(m_ram, 0, sizeof(m_ram));
|
||||
}
|
||||
|
||||
void hlcd0515_device::device_start()
|
||||
{
|
||||
// timer
|
||||
m_lcd_timer = timer_alloc(FUNC(hlcd0515_device::scan_lcd), this);
|
||||
attotime period = attotime::from_hz(clock() / 2);
|
||||
m_lcd_timer->adjust(period, 0, period);
|
||||
|
||||
// zerofill
|
||||
internal_clear();
|
||||
m_cs = 0;
|
||||
m_clk = 0;
|
||||
m_data = 0;
|
||||
m_dataout = 0;
|
||||
|
||||
// register for savestates
|
||||
save_item(NAME(m_cs));
|
||||
@ -95,7 +105,63 @@ void hlcd0515_device::device_start()
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// scan_lcd -
|
||||
// nvram (when VDD is battery-backed, rare occurence)
|
||||
//-------------------------------------------------
|
||||
|
||||
bool hlcd0515_device::nvram_write(util::write_stream &file)
|
||||
{
|
||||
size_t actual;
|
||||
|
||||
// misc internal registers
|
||||
u8 buf[6];
|
||||
buf[0] = m_count;
|
||||
buf[1] = m_control;
|
||||
buf[2] = m_blank ? 1 : 0;
|
||||
buf[3] = m_rowmax;
|
||||
buf[4] = m_rowout;
|
||||
buf[5] = m_rowsel;
|
||||
|
||||
if (file.write(&buf, sizeof(buf), actual) || (sizeof(buf) != actual))
|
||||
return false;
|
||||
|
||||
// shift register and RAM
|
||||
if (file.write(&m_buffer, sizeof(m_buffer), actual) || (sizeof(m_buffer) != actual))
|
||||
return false;
|
||||
if (file.write(&m_ram, sizeof(m_ram), actual) || (sizeof(m_ram) != actual))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool hlcd0515_device::nvram_read(util::read_stream &file)
|
||||
{
|
||||
size_t actual;
|
||||
|
||||
// misc internal registers
|
||||
u8 buf[6];
|
||||
if (file.read(&buf, sizeof(buf), actual) || (sizeof(buf) != actual))
|
||||
return false;
|
||||
|
||||
m_count = buf[0];
|
||||
m_control = buf[1];
|
||||
m_blank = bool(buf[2]);
|
||||
m_rowmax = buf[3] & 7;
|
||||
m_rowout = buf[4] & 7;
|
||||
m_rowsel = buf[5] & 7;
|
||||
|
||||
// shift register and RAM
|
||||
if (file.read(&m_buffer, sizeof(m_buffer), actual) || (sizeof(m_buffer) != actual))
|
||||
return false;
|
||||
if (file.read(&m_ram, sizeof(m_ram), actual) || (sizeof(m_ram) != actual))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// I/O handlers
|
||||
//-------------------------------------------------
|
||||
|
||||
TIMER_CALLBACK_MEMBER(hlcd0515_device::scan_lcd)
|
||||
@ -109,11 +175,6 @@ TIMER_CALLBACK_MEMBER(hlcd0515_device::scan_lcd)
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// handlers
|
||||
//-------------------------------------------------
|
||||
|
||||
void hlcd0515_device::set_control()
|
||||
{
|
||||
// clock 0,1,2: row select
|
||||
@ -178,7 +239,6 @@ void hlcd0515_device::clock_w(int state)
|
||||
if (m_count == 4)
|
||||
set_control();
|
||||
}
|
||||
|
||||
else
|
||||
clock_data(m_count - 5);
|
||||
|
||||
|
@ -41,7 +41,7 @@
|
||||
*/
|
||||
|
||||
|
||||
class hlcd0515_device : public device_t
|
||||
class hlcd0515_device : public device_t, public device_nvram_interface
|
||||
{
|
||||
public:
|
||||
hlcd0515_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||
@ -61,6 +61,12 @@ protected:
|
||||
// device-level overrides
|
||||
virtual void device_start() override;
|
||||
|
||||
// device_nvram_interface overrides
|
||||
virtual void nvram_default() override { internal_clear(); }
|
||||
virtual bool nvram_read(util::read_stream &file) override;
|
||||
virtual bool nvram_write(util::write_stream &file) override;
|
||||
|
||||
void internal_clear();
|
||||
TIMER_CALLBACK_MEMBER(scan_lcd);
|
||||
|
||||
virtual void set_control();
|
||||
@ -72,7 +78,7 @@ protected:
|
||||
int m_clk; // "
|
||||
int m_data; // "
|
||||
int m_dataout; // DATA OUT pin state
|
||||
int m_count;
|
||||
u8 m_count;
|
||||
u8 m_control;
|
||||
bool m_blank; // display blank/visible
|
||||
u8 m_rowmax; // number of rows output by lcd (max 8)
|
||||
|
@ -37,9 +37,8 @@ license:CC0-1.0
|
||||
</element>
|
||||
|
||||
<element name="text_switch" defstate="0">
|
||||
<rect><color red="0.12" green="0.03" blue="0.4" /></rect>
|
||||
<text string="POWER SWITCH: ON" align="1" state="0"><color red="0.4" green="0.4" blue="0.55" /></text>
|
||||
<text string="POWER SWITCH: SAVE" align="1" state="1"><color red="0.4" green="0.4" blue="0.55" /></text>
|
||||
<text string="SAVE: OFF" align="1" state="0"><color red="0.8" green="0.8" blue="0.8" /></text>
|
||||
<text string="SAVE: ON" align="1" state="1"><color red="0.8" green="0.8" blue="0.8" /></text>
|
||||
</element>
|
||||
|
||||
<element name="text_l0"><text string="MOVE"><color red="0.8" green="0.8" blue="0.8" /></text></element>
|
||||
@ -156,7 +155,8 @@ license:CC0-1.0
|
||||
<element ref="blackb"><bounds x="91" y="47" width="95" height="53" /></element>
|
||||
<group ref="buttons"><bounds x="93" y="48.634" width="87.8" height="45.8" /></group>
|
||||
|
||||
<element ref="text_switch" inputtag="IN.3" inputmask="0x01"><bounds x="91" y="2" width="24" height="2.7" /></element>
|
||||
<element ref="blackb"><bounds x="170" y="-1" width="20" height="4" /></element>
|
||||
<element ref="text_switch" inputtag="IN.3" inputmask="0x01"><bounds x="171" y="0" width="13" height="2.7" /></element>
|
||||
</view>
|
||||
|
||||
<view name="Internal Layout (Screen)">
|
||||
|
@ -5,6 +5,16 @@
|
||||
|
||||
Mattel Computer Chess
|
||||
|
||||
The chess engine is by Julio Kaplan, before he was working for SciSys/Saitek.
|
||||
|
||||
The power switch has a SAVE setting, this keeps the LCD chips powered on, and
|
||||
the program reads the chessboard position from LCD RAM on the next boot. To save
|
||||
a game in progress, make sure to press CLEAR before powering off. It does not
|
||||
save the level setting.
|
||||
|
||||
There is no button to start a new game. The user is meant to switch power off/on.
|
||||
In MAME, reset (or exit/restart) while the save switch is off.
|
||||
|
||||
Hardware notes:
|
||||
- INS8050 CPU @ 6MHz (4KB internal ROM, 256 bytes internal RAM)
|
||||
- 2*HLCD0569(also seen with 2*HLCD0601, functionally same?)
|
||||
@ -16,8 +26,10 @@ assumed to be an unlicensed clone.
|
||||
*******************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
#include "cpu/mcs48/mcs48.h"
|
||||
#include "video/hlcd0515.h"
|
||||
|
||||
#include "screen.h"
|
||||
|
||||
// internal artwork
|
||||
@ -39,8 +51,6 @@ public:
|
||||
|
||||
void mchess(machine_config &config);
|
||||
|
||||
DECLARE_INPUT_CHANGED_MEMBER(reset_switch) { update_reset(newval); }
|
||||
|
||||
protected:
|
||||
virtual void machine_start() override;
|
||||
virtual void machine_reset() override;
|
||||
@ -52,8 +62,6 @@ private:
|
||||
required_ioport_array<4> m_inputs;
|
||||
output_finder<2, 8, 22> m_out_x;
|
||||
|
||||
void update_reset(ioport_value state);
|
||||
|
||||
// I/O handlers
|
||||
template<int Sel> void lcd_output_w(offs_t offset, u32 data);
|
||||
void input_w(u8 data);
|
||||
@ -77,14 +85,12 @@ void mchess_state::machine_start()
|
||||
|
||||
void mchess_state::machine_reset()
|
||||
{
|
||||
update_reset(m_inputs[3]->read());
|
||||
}
|
||||
|
||||
void mchess_state::update_reset(ioport_value state)
|
||||
{
|
||||
// battery is disconnected from CPU VCC pin when power switch is in SAVE mode
|
||||
// (at reboot, the game will read the chessboard positions from LCD RAM)
|
||||
m_maincpu->set_input_line(INPUT_LINE_RESET, state ? ASSERT_LINE : CLEAR_LINE);
|
||||
// clear nvram if SAVE is off
|
||||
if (~m_inputs[3]->read() & 1)
|
||||
{
|
||||
m_lcd[0]->nvram_reset();
|
||||
m_lcd[1]->nvram_reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -96,12 +102,10 @@ void mchess_state::update_reset(ioport_value state)
|
||||
template<int Sel>
|
||||
void mchess_state::lcd_output_w(offs_t offset, u32 data)
|
||||
{
|
||||
int enabled = ~m_inputs[3]->read() & m_lcd_control & 1;
|
||||
|
||||
// output to x.y.z where x = chip, y = row, z = col
|
||||
// up to 22 columns used
|
||||
for (int i = 0; i < 22; i++)
|
||||
m_out_x[Sel][offset][i] = BIT(data, i) & enabled;
|
||||
m_out_x[Sel][offset][i] = BIT(data, i) & m_lcd_control;
|
||||
}
|
||||
|
||||
void mchess_state::input_w(u8 data)
|
||||
@ -181,7 +185,7 @@ static INPUT_PORTS_START( mchess )
|
||||
PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_B) PORT_NAME("Take Back")
|
||||
|
||||
PORT_START("IN.3")
|
||||
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_CODE(KEYCODE_F1) PORT_TOGGLE PORT_CHANGED_MEMBER(DEVICE_SELF, mchess_state, reset_switch, 0) PORT_NAME("Save Switch")
|
||||
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_CODE(KEYCODE_F1) PORT_TOGGLE PORT_NAME("Save Switch")
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
@ -202,8 +206,11 @@ void mchess_state::mchess(machine_config &config)
|
||||
// video hardware
|
||||
HLCD0569(config, m_lcd[0], 500); // C=0.01uF
|
||||
m_lcd[0]->write_cols().set(FUNC(mchess_state::lcd_output_w<0>));
|
||||
m_lcd[0]->nvram_enable_backup(true);
|
||||
|
||||
HLCD0569(config, m_lcd[1], 500); // C=0.01uF
|
||||
m_lcd[1]->write_cols().set(FUNC(mchess_state::lcd_output_w<1>));
|
||||
m_lcd[1]->nvram_enable_backup(true);
|
||||
|
||||
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
|
||||
screen.set_refresh_hz(60);
|
||||
|
@ -104,9 +104,8 @@ private:
|
||||
void led_w(u8 data);
|
||||
|
||||
void set_cpu_freq();
|
||||
TIMER_CALLBACK_MEMBER(set_pin);
|
||||
TIMER_CALLBACK_MEMBER(delayed_nmi);
|
||||
|
||||
emu_timer *m_standbytimer;
|
||||
emu_timer *m_nmitimer;
|
||||
bool m_power = false;
|
||||
u8 m_inp_mux = 0;
|
||||
@ -114,8 +113,7 @@ private:
|
||||
|
||||
void ccompan2_state::machine_start()
|
||||
{
|
||||
m_nmitimer = timer_alloc(FUNC(ccompan2_state::set_pin), this);
|
||||
m_standbytimer = timer_alloc(FUNC(ccompan2_state::set_pin), this);
|
||||
m_nmitimer = timer_alloc(FUNC(ccompan2_state::delayed_nmi), this);
|
||||
|
||||
// register for savestates
|
||||
save_item(NAME(m_power));
|
||||
@ -137,12 +135,11 @@ void ccompan2_state::set_cpu_freq()
|
||||
void ccompan2_state::machine_reset()
|
||||
{
|
||||
m_power = true;
|
||||
m_maincpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE);
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(ccompan2_state::set_pin)
|
||||
TIMER_CALLBACK_MEMBER(ccompan2_state::delayed_nmi)
|
||||
{
|
||||
m_maincpu->set_input_line(param, ASSERT_LINE);
|
||||
m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
|
||||
}
|
||||
|
||||
INPUT_CHANGED_MEMBER(ccompan2_state::power_off)
|
||||
@ -152,12 +149,8 @@ INPUT_CHANGED_MEMBER(ccompan2_state::power_off)
|
||||
m_power = false;
|
||||
|
||||
// when power switch is set to MEMORY, it triggers an NMI after a short delay
|
||||
attotime delay = attotime::from_msec(100);
|
||||
m_nmitimer->adjust(delay, INPUT_LINE_NMI);
|
||||
|
||||
// afterwards, MCU STBY pin is asserted after a short delay
|
||||
delay += attotime::from_msec(10);
|
||||
m_standbytimer->adjust(delay, INPUT_LINE_RESET);
|
||||
// (and shortly after that, MCU STBY is asserted)
|
||||
m_nmitimer->adjust(attotime::from_msec(100));
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user