trunk/src/mess/drivers/cnsector.c
| r242172 | r242173 | |
| 32 | 32 | |
| 33 | 33 | UINT16 m_o; |
| 34 | 34 | |
| 35 | UINT16 m_leds_state[0x10]; |
| 36 | UINT16 m_leds_cache[0x10]; |
| 37 | UINT8 m_leds_decay[0x100]; |
| 38 | |
| 35 | 39 | DECLARE_READ8_MEMBER(read_k); |
| 36 | 40 | DECLARE_WRITE16_MEMBER(write_o); |
| 37 | 41 | DECLARE_WRITE16_MEMBER(write_r); |
| 38 | 42 | |
| 43 | TIMER_DEVICE_CALLBACK_MEMBER(leds_decay_tick); |
| 44 | void leds_update(); |
| 45 | |
| 39 | 46 | virtual void machine_start(); |
| 40 | 47 | }; |
| 41 | 48 | |
| r242172 | r242173 | |
| 43 | 50 | |
| 44 | 51 | /*************************************************************************** |
| 45 | 52 | |
| 53 | LEDs |
| 54 | |
| 55 | ***************************************************************************/ |
| 56 | |
| 57 | // Devices with TMS09x0 strobe the outputs very fast, it is unnoticeable to the user. |
| 58 | // To prevent flickering here, we need to simulate a decay. |
| 59 | |
| 60 | // decay time, in steps of 10ms |
| 61 | #define LEDS_DECAY_TIME 4 |
| 62 | |
| 63 | void cnsector_state::leds_update() |
| 64 | { |
| 65 | UINT16 active_state[0x10]; |
| 66 | |
| 67 | for (int i = 0; i < 0x10; i++) |
| 68 | { |
| 69 | active_state[i] = 0; |
| 70 | |
| 71 | for (int j = 0; j < 0x10; j++) |
| 72 | { |
| 73 | int di = j << 4 | i; |
| 74 | |
| 75 | // turn on powered leds |
| 76 | if (m_leds_state[i] >> j & 1) |
| 77 | m_leds_decay[di] = LEDS_DECAY_TIME; |
| 78 | |
| 79 | // determine active state |
| 80 | int ds = (m_leds_decay[di] != 0) ? 1 : 0; |
| 81 | active_state[i] |= (ds << j); |
| 82 | } |
| 83 | } |
| 84 | |
| 85 | // on difference, send to output |
| 86 | for (int i = 0; i < 0x10; i++) |
| 87 | if (m_leds_cache[i] != active_state[i]) |
| 88 | output_set_digit_value(i, active_state[i]); |
| 89 | |
| 90 | memcpy(m_leds_cache, active_state, sizeof(m_leds_cache)); |
| 91 | } |
| 92 | |
| 93 | TIMER_DEVICE_CALLBACK_MEMBER(cnsector_state::leds_decay_tick) |
| 94 | { |
| 95 | // slowly turn off unpowered leds |
| 96 | for (int i = 0; i < 0x100; i++) |
| 97 | if (!(m_leds_state[i & 0xf] >> (i>>4) & 1) && m_leds_decay[i]) |
| 98 | m_leds_decay[i]--; |
| 99 | |
| 100 | leds_update(); |
| 101 | } |
| 102 | |
| 103 | |
| 104 | |
| 105 | /*************************************************************************** |
| 106 | |
| 46 | 107 | I/O |
| 47 | 108 | |
| 48 | 109 | ***************************************************************************/ |
| r242172 | r242173 | |
| 61 | 122 | |
| 62 | 123 | WRITE16_MEMBER(cnsector_state::write_r) |
| 63 | 124 | { |
| 64 | | // R0-R5: select digit |
| 125 | // R0-R5: select digit (right-to-left) |
| 65 | 126 | for (int i = 0; i < 6; i++) |
| 66 | | output_set_digit_value(i, (data >> i & 1) ? m_o : 0); |
| 127 | m_leds_state[i] = (data >> i & 1) ? m_o : 0; |
| 128 | leds_update(); |
| 67 | 129 | |
| 68 | 130 | // R6-R9: direction leds |
| 69 | 131 | for (int i = 6; i < 10; i++) |
| r242172 | r242173 | |
| 127 | 189 | |
| 128 | 190 | void cnsector_state::machine_start() |
| 129 | 191 | { |
| 192 | memset(m_leds_state, 0, sizeof(m_leds_state)); |
| 193 | memset(m_leds_cache, 0, sizeof(m_leds_cache)); |
| 194 | memset(m_leds_decay, 0, sizeof(m_leds_decay)); |
| 130 | 195 | m_o = 0; |
| 131 | 196 | |
| 132 | 197 | save_item(NAME(m_o)); |
| r242172 | r242173 | |
| 141 | 206 | MCFG_TMS1XXX_WRITE_O_CB(WRITE16(cnsector_state, write_o)) |
| 142 | 207 | MCFG_TMS1XXX_WRITE_R_CB(WRITE16(cnsector_state, write_r)) |
| 143 | 208 | |
| 209 | MCFG_TIMER_DRIVER_ADD_PERIODIC("leds_decay", cnsector_state, leds_decay_tick, attotime::from_msec(10)) |
| 210 | |
| 144 | 211 | MCFG_DEFAULT_LAYOUT(layout_cnsector) |
| 145 | 212 | |
| 146 | 213 | /* no video! */ |
trunk/src/mess/layout/cnsector.lay
| r242172 | r242173 | |
| 18 | 18 | <view name="Internal Layout"> |
| 19 | 19 | <bounds left="0" right="200" top="0" bottom="200" /> |
| 20 | 20 | |
| 21 | | <bezel name="digit0" element="digit"> |
| 21 | <bezel name="digit5" element="digit"> |
| 22 | 22 | <bounds x="0" y="0" width="10" height="15" /> |
| 23 | 23 | </bezel> |
| 24 | | <bezel name="digit1" element="digit"> |
| 25 | | <bounds x="10" y="0" width="10" height="15" /> |
| 26 | | </bezel> |
| 27 | | <bezel name="digit2" element="digit"> |
| 24 | <bezel name="digit4" element="digit"> |
| 28 | 25 | <bounds x="20" y="0" width="10" height="15" /> |
| 29 | 26 | </bezel> |
| 30 | 27 | <bezel name="digit3" element="digit"> |
| 31 | | <bounds x="30" y="0" width="10" height="15" /> |
| 32 | | </bezel> |
| 33 | | <bezel name="digit4" element="digit"> |
| 34 | 28 | <bounds x="40" y="0" width="10" height="15" /> |
| 35 | 29 | </bezel> |
| 36 | | <bezel name="digit5" element="digit"> |
| 30 | <bezel name="digit2" element="digit"> |
| 37 | 31 | <bounds x="50" y="0" width="10" height="15" /> |
| 38 | 32 | </bezel> |
| 33 | <bezel name="digit1" element="digit"> |
| 34 | <bounds x="60" y="0" width="10" height="15" /> |
| 35 | </bezel> |
| 36 | <bezel name="digit0" element="digit"> |
| 37 | <bounds x="70" y="0" width="10" height="15" /> |
| 38 | </bezel> |
| 39 | 39 | |
| 40 | 40 | <bezel name="lamp0" element="lamp"> |
| 41 | 41 | <bounds x="20" y="20" width="5" height="5" /> |