summaryrefslogtreecommitdiffstatshomepage
path: root/src/mess/drivers/cnsector.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mess/drivers/cnsector.c')
-rw-r--r--src/mess/drivers/cnsector.c71
1 files changed, 69 insertions, 2 deletions
diff --git a/src/mess/drivers/cnsector.c b/src/mess/drivers/cnsector.c
index c78f19d074d..8aae3e34520 100644
--- a/src/mess/drivers/cnsector.c
+++ b/src/mess/drivers/cnsector.c
@@ -32,10 +32,17 @@ public:
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();
};
@@ -43,6 +50,60 @@ public:
/***************************************************************************
+ LEDs
+
+***************************************************************************/
+
+// Devices with TMS09x0 strobe 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 cnsector_state::leds_update()
+{
+ UINT16 active_state[0x10];
+
+ for (int i = 0; i < 0x10; i++)
+ {
+ 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])
+ output_set_digit_value(i, active_state[i]);
+
+ memcpy(m_leds_cache, active_state, sizeof(m_leds_cache));
+}
+
+TIMER_DEVICE_CALLBACK_MEMBER(cnsector_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
***************************************************************************/
@@ -61,9 +122,10 @@ READ8_MEMBER(cnsector_state::read_k)
WRITE16_MEMBER(cnsector_state::write_r)
{
- // R0-R5: select digit
+ // R0-R5: select digit (right-to-left)
for (int i = 0; i < 6; i++)
- output_set_digit_value(i, (data >> i & 1) ? m_o : 0);
+ m_leds_state[i] = (data >> i & 1) ? m_o : 0;
+ leds_update();
// R6-R9: direction leds
for (int i = 6; i < 10; i++)
@@ -127,6 +189,9 @@ INPUT_PORTS_END
void cnsector_state::machine_start()
{
+ 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_o = 0;
save_item(NAME(m_o));
@@ -141,6 +206,8 @@ static MACHINE_CONFIG_START( cnsector, cnsector_state )
MCFG_TMS1XXX_WRITE_O_CB(WRITE16(cnsector_state, write_o))
MCFG_TMS1XXX_WRITE_R_CB(WRITE16(cnsector_state, write_r))
+ MCFG_TIMER_DRIVER_ADD_PERIODIC("leds_decay", cnsector_state, leds_decay_tick, attotime::from_msec(10))
+
MCFG_DEFAULT_LAYOUT(layout_cnsector)
/* no video! */