From 27b34159d23e714c95f8fc837a6f0c0f97437855 Mon Sep 17 00:00:00 2001 From: hap Date: Sun, 18 Jan 2015 00:07:48 +0100 Subject: added led decay simulation as usual --- src/mess/drivers/splitsec.c | 113 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 110 insertions(+), 3 deletions(-) diff --git a/src/mess/drivers/splitsec.c b/src/mess/drivers/splitsec.c index 2aae2430d3e..30ed07f08cf 100644 --- a/src/mess/drivers/splitsec.c +++ b/src/mess/drivers/splitsec.c @@ -25,26 +25,94 @@ public: splitsec_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), m_maincpu(*this, "maincpu"), -// m_button_matrix(*this, "IN"), + m_button_matrix(*this, "IN"), m_speaker(*this, "speaker") { } required_device m_maincpu; -// required_ioport_array<4> m_button_matrix; + required_ioport_array<2> m_button_matrix; required_device m_speaker; UINT16 m_r; UINT16 m_o; + UINT16 m_leds_state[0x10]; + UINT16 m_leds_cache[0x10]; + UINT8 m_leds_decay[0x100]; + DECLARE_READ8_MEMBER(read_k); DECLARE_WRITE16_MEMBER(write_o); DECLARE_WRITE16_MEMBER(write_r); + TIMER_DEVICE_CALLBACK_MEMBER(leds_decay_tick); + void leds_update(); + virtual void machine_start(); }; +/*************************************************************************** + + LEDs + +***************************************************************************/ + +// The device strobes the outputs very fast, it is unnoticeable to the user. +// To prevent flickering here, we need to simulate a decay. + +// decay time, in steps of 10ms +#define LEDS_DECAY_TIME 4 + +void splitsec_state::leds_update() +{ + UINT16 active_state[0x10]; + + for (int i = 0; i < 0x10; i++) + { + // update current state + if (m_r >> i & 1) + m_leds_state[i] = m_o; + + active_state[i] = 0; + + for (int j = 0; j < 0x10; j++) + { + int di = j << 4 | i; + + // turn on powered leds + if (m_leds_state[i] >> j & 1) + m_leds_decay[di] = LEDS_DECAY_TIME; + + // determine active state + int ds = (m_leds_decay[di] != 0) ? 1 : 0; + active_state[i] |= (ds << j); + } + } + + // on difference, send to output + for (int i = 0; i < 0x10; i++) + if (m_leds_cache[i] != active_state[i]) + { + for (int j = 0; j < 8; j++) + output_set_lamp_value(i*10 + j, active_state[i] >> j & 1); + } + + memcpy(m_leds_cache, active_state, sizeof(m_leds_cache)); +} + +TIMER_DEVICE_CALLBACK_MEMBER(splitsec_state::leds_decay_tick) +{ + // slowly turn off unpowered leds + for (int i = 0; i < 0x100; i++) + if (!(m_leds_state[i & 0xf] >> (i>>4) & 1) && m_leds_decay[i]) + m_leds_decay[i]--; + + leds_update(); +} + + + /*************************************************************************** I/O @@ -53,17 +121,33 @@ public: READ8_MEMBER(splitsec_state::read_k) { - return 0; + UINT8 k = 0; + + // read selected button rows + for (int i = 0; i < 2; i++) + if (m_r >> (i+9) & 1) + k |= m_button_matrix[i]->read(); + + return k; } WRITE16_MEMBER(splitsec_state::write_r) { + // R8: speaker out + m_speaker->level_w(data >> 8 & 1); + + // R9,R10: input mux + // R0-R7: led columns m_r = data; + leds_update(); } WRITE16_MEMBER(splitsec_state::write_o) { + // O0-O6: led rows + // O7: N/C m_o = data; + leds_update(); } @@ -75,6 +159,17 @@ WRITE16_MEMBER(splitsec_state::write_o) ***************************************************************************/ static INPUT_PORTS_START( splitsec ) + PORT_START("IN.0") // R9 + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("IN.1") // R10 + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Select") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("Start") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) INPUT_PORTS_END @@ -87,9 +182,19 @@ INPUT_PORTS_END void splitsec_state::machine_start() { + // zerofill + memset(m_leds_state, 0, sizeof(m_leds_state)); + memset(m_leds_cache, 0, sizeof(m_leds_cache)); + memset(m_leds_decay, 0, sizeof(m_leds_decay)); + m_r = 0; m_o = 0; + // register for savestates + save_item(NAME(m_leds_state)); + save_item(NAME(m_leds_cache)); + save_item(NAME(m_leds_decay)); + save_item(NAME(m_r)); save_item(NAME(m_o)); } @@ -103,6 +208,8 @@ static MACHINE_CONFIG_START( splitsec, splitsec_state ) MCFG_TMS1XXX_WRITE_O_CB(WRITE16(splitsec_state, write_o)) MCFG_TMS1XXX_WRITE_R_CB(WRITE16(splitsec_state, write_r)) + MCFG_TIMER_DRIVER_ADD_PERIODIC("leds_decay", splitsec_state, leds_decay_tick, attotime::from_msec(10)) + MCFG_DEFAULT_LAYOUT(layout_splitsec) /* no video! */ -- cgit v1.2.3