diff --git a/src/mess/drivers/hh_hmcs40.c b/src/mess/drivers/hh_hmcs40.c index d4ef7cb2a47..1ea775a681b 100644 --- a/src/mess/drivers/hh_hmcs40.c +++ b/src/mess/drivers/hh_hmcs40.c @@ -89,6 +89,7 @@ public: TIMER_DEVICE_CALLBACK_MEMBER(display_decay_tick); void display_update(); + void set_display_size(int maxx, int maxy); void display_matrix(int maxx, int maxy, UINT64 setx, UINT32 sety); // game-specific handlers @@ -199,10 +200,15 @@ TIMER_DEVICE_CALLBACK_MEMBER(hh_hmcs40_state::display_decay_tick) display_update(); } -void hh_hmcs40_state::display_matrix(int maxx, int maxy, UINT64 setx, UINT32 sety) +void hh_hmcs40_state::set_display_size(int maxx, int maxy) { m_display_maxx = maxx; m_display_maxy = maxy; +} + +void hh_hmcs40_state::display_matrix(int maxx, int maxy, UINT64 setx, UINT32 sety) +{ + set_display_size(maxx, maxy); // update current state UINT64 mask = (1 << maxx) - 1; diff --git a/src/mess/drivers/hh_pic16.c b/src/mess/drivers/hh_pic16.c index 4ee9bf29385..266ebc8d9b4 100644 --- a/src/mess/drivers/hh_pic16.c +++ b/src/mess/drivers/hh_pic16.c @@ -65,6 +65,7 @@ public: TIMER_DEVICE_CALLBACK_MEMBER(display_decay_tick); void display_update(); + void set_display_size(int maxx, int maxy); void display_matrix(int maxx, int maxy, UINT32 setx, UINT32 sety); // game-specific handlers @@ -162,10 +163,15 @@ TIMER_DEVICE_CALLBACK_MEMBER(hh_pic16_state::display_decay_tick) display_update(); } -void hh_pic16_state::display_matrix(int maxx, int maxy, UINT32 setx, UINT32 sety) +void hh_pic16_state::set_display_size(int maxx, int maxy) { m_display_maxx = maxx; m_display_maxy = maxy; +} + +void hh_pic16_state::display_matrix(int maxx, int maxy, UINT32 setx, UINT32 sety) +{ + set_display_size(maxx, maxy); // update current state UINT32 mask = (1 << maxx) - 1; @@ -204,11 +210,10 @@ WRITE8_MEMBER(hh_pic16_state::maniac_output_w) m_speaker->level_w((m_b >> 7 & 1) | (m_c >> 6 & 2)); // d0-d6: 7seg - m_display_maxx = 7; - m_display_maxy = 2; - m_display_segmask[offset] = 0x7f; m_display_state[offset] = ~data & 0x7f; + + set_display_size(7, 2); display_update(); } diff --git a/src/mess/drivers/hh_tms1k.c b/src/mess/drivers/hh_tms1k.c index 57fe20903a0..b17b40e2035 100644 --- a/src/mess/drivers/hh_tms1k.c +++ b/src/mess/drivers/hh_tms1k.c @@ -194,10 +194,15 @@ TIMER_DEVICE_CALLBACK_MEMBER(hh_tms1k_state::display_decay_tick) display_update(); } -void hh_tms1k_state::display_matrix(int maxx, int maxy, UINT32 setx, UINT32 sety) +void hh_tms1k_state::set_display_size(int maxx, int maxy) { m_display_maxx = maxx; m_display_maxy = maxy; +} + +void hh_tms1k_state::display_matrix(int maxx, int maxy, UINT32 setx, UINT32 sety) +{ + set_display_size(maxx, maxy); // update current state UINT32 mask = (1 << maxx) - 1; @@ -270,9 +275,6 @@ INPUT_CHANGED_MEMBER(hh_tms1k_state::power_button) void hh_tms1k_state::mathmagi_display() { - m_display_maxx = 8; - m_display_maxy = 11; - // R0-R7: 7seg leds for (int y = 0; y < 8; y++) { @@ -286,6 +288,7 @@ void hh_tms1k_state::mathmagi_display() for (int y = 8; y < 11; y++) m_display_state[y] = (m_r >> y & 1) ? m_o : 0; + set_display_size(8, 11); display_update(); } @@ -433,9 +436,6 @@ MACHINE_CONFIG_END void hh_tms1k_state::amaztron_display() { - m_display_maxx = 8; - m_display_maxy = 3; - // R8,R9: select digit for (int y = 0; y < 2; y++) { @@ -446,6 +446,7 @@ void hh_tms1k_state::amaztron_display() // R6,R7: lamps (-> lamp20,21) m_display_state[2] = m_r >> 6 & 3; + set_display_size(8, 3); display_update(); } @@ -960,9 +961,6 @@ MACHINE_CONFIG_END void hh_tms1k_state::ebball3_display() { - m_display_maxx = 7; - m_display_maxy = 10+2; - // update current state for (int y = 0; y < 10; y++) m_display_state[y] = (m_r >> y & 1) ? m_o : 0; @@ -975,6 +973,7 @@ void hh_tms1k_state::ebball3_display() m_display_state[11] = ((m_display_state[4] & 0x10) | (m_display_state[7] & 0x01)) << 1; m_display_segmask[10] = m_display_segmask[11] = 0x22; + set_display_size(7, 10+2); display_update(); } @@ -1612,9 +1611,6 @@ MACHINE_CONFIG_END WRITE16_MEMBER(hh_tms1k_state::cnsector_write_r) { - m_display_maxx = 8; - m_display_maxy = 7; - // R0-R5: select digit (right-to-left) for (int y = 0; y < 6; y++) { @@ -1625,6 +1621,7 @@ WRITE16_MEMBER(hh_tms1k_state::cnsector_write_r) // R6-R9: direction leds (-> lamp60-63) m_display_state[6] = data >> 6 & 0xf; + set_display_size(8, 7); display_update(); } @@ -1814,17 +1811,15 @@ MACHINE_CONFIG_END WRITE16_MEMBER(hh_tms1k_state::stopthief_write_r) { - m_display_maxx = 7; - m_display_maxy = 3; - // R0-R2: select digit UINT8 o = BITSWAP8(m_o,3,5,2,1,4,0,6,7) & 0x7f; - for (int y = 0; y < m_display_maxy; y++) + for (int y = 0; y < 3; y++) { m_display_segmask[y] = 0x7f; m_display_state[y] = (data >> y & 1) ? o : 0; } + set_display_size(7, 3); display_update(); // R3-R8: speaker on diff --git a/src/mess/drivers/hh_ucom4.c b/src/mess/drivers/hh_ucom4.c index db2d2bb2887..a91ffa52340 100644 --- a/src/mess/drivers/hh_ucom4.c +++ b/src/mess/drivers/hh_ucom4.c @@ -76,6 +76,7 @@ public: TIMER_DEVICE_CALLBACK_MEMBER(display_decay_tick); void display_update(); + void set_display_size(int maxx, int maxy); void display_matrix(int maxx, int maxy, UINT32 setx, UINT32 sety); // game-specific handlers @@ -207,10 +208,15 @@ TIMER_DEVICE_CALLBACK_MEMBER(hh_ucom4_state::display_decay_tick) display_update(); } -void hh_ucom4_state::display_matrix(int maxx, int maxy, UINT32 setx, UINT32 sety) +void hh_ucom4_state::set_display_size(int maxx, int maxy) { m_display_maxx = maxx; m_display_maxy = maxy; +} + +void hh_ucom4_state::display_matrix(int maxx, int maxy, UINT32 setx, UINT32 sety) +{ + set_display_size(maxx, maxy); // update current state UINT32 mask = (1 << maxx) - 1; diff --git a/src/mess/drivers/mbdtower.c b/src/mess/drivers/mbdtower.c index e9ff39fd798..70aa569678a 100644 --- a/src/mess/drivers/mbdtower.c +++ b/src/mess/drivers/mbdtower.c @@ -61,8 +61,7 @@ protected: void mbdtower_state::mbdtower_display() { // declare display matrix size and the 2 7segs - m_display_maxx = 7; - m_display_maxy = 3; + set_display_size(7, 3); m_display_segmask[1] = m_display_segmask[2] = 0x7f; // update current state diff --git a/src/mess/drivers/ticalc1x.c b/src/mess/drivers/ticalc1x.c index 85ad5c3ecc2..1339288d536 100644 --- a/src/mess/drivers/ticalc1x.c +++ b/src/mess/drivers/ticalc1x.c @@ -2,6 +2,8 @@ // copyright-holders:hap, Sean Riddle /*************************************************************************** + ** subclass of hh_tms1k_state (includes/hh_tms1k.h, drivers/hh_tms1k.c) ** + Texas Instruments TMS1xxx/0970/0980 handheld calculators (mostly single-chip) Refer to their official manuals on how to use them. @@ -13,9 +15,7 @@ ***************************************************************************/ -#include "emu.h" -#include "cpu/tms0980/tms0980.h" -#include "sound/speaker.h" +#include "includes/hh_tms1k.h" // internal artwork #include "ti1270.lh" @@ -24,49 +24,13 @@ #include "wizatron.lh" -class ticalc1x_state : public driver_device +class ticalc1x_state : public hh_tms1k_state { public: ticalc1x_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu"), - m_inp_matrix(*this, "IN"), - m_speaker(*this, "speaker"), - m_display_wait(33), - m_display_maxy(1), - m_display_maxx(0) + : hh_tms1k_state(mconfig, type, tag) { } - // devices - required_device m_maincpu; - optional_ioport_array<11> m_inp_matrix; // max 11 - optional_device m_speaker; - - // misc common - UINT16 m_r; // MCU R-pins data - UINT16 m_o; // MCU O-pins data - UINT16 m_inp_mux; // multiplexed inputs mask - bool m_power_on; - - UINT8 read_inputs(int columns); - DECLARE_INPUT_CHANGED_MEMBER(power_button); - DECLARE_WRITE_LINE_MEMBER(auto_power_off); - - virtual void machine_reset(); - virtual void machine_start(); - - // display common - int m_display_wait; // led/lamp off-delay in microseconds (default 33ms) - int m_display_maxy; // display matrix number of rows - int m_display_maxx; // display matrix number of columns - - UINT32 m_display_state[0x20]; // display matrix rows data - UINT16 m_display_segmask[0x20]; // if not 0, display matrix row is a digit, mask indicates connected segments - UINT32 m_display_cache[0x20]; // (internal use) - UINT8 m_display_decay[0x20][0x20]; // (internal use) - - TIMER_DEVICE_CALLBACK_MEMBER(display_decay_tick); - void display_update(); void display_matrix_seg(int maxx, int maxy, UINT32 setx, UINT32 sety, UINT16 segmask); // calculator-specific handlers @@ -93,155 +57,24 @@ public: DECLARE_WRITE16_MEMBER(ti30_write_o); DECLARE_WRITE16_MEMBER(ti30_write_r); DECLARE_READ8_MEMBER(ti30_read_k); + +protected: + virtual void machine_start(); }; -// machine_start/reset - void ticalc1x_state::machine_start() { - // zerofill - memset(m_display_state, 0, sizeof(m_display_state)); - memset(m_display_cache, ~0, sizeof(m_display_cache)); - memset(m_display_decay, 0, sizeof(m_display_decay)); + hh_tms1k_state::machine_start(); memset(m_display_segmask, ~0, sizeof(m_display_segmask)); // ! - - m_o = 0; - m_r = 0; - m_inp_mux = 0; - m_power_on = false; - - // register for savestates - save_item(NAME(m_display_maxy)); - save_item(NAME(m_display_maxx)); - save_item(NAME(m_display_wait)); - - save_item(NAME(m_display_state)); - /* save_item(NAME(m_display_cache)); */ // don't save! - save_item(NAME(m_display_decay)); - save_item(NAME(m_display_segmask)); - - save_item(NAME(m_o)); - save_item(NAME(m_r)); - save_item(NAME(m_inp_mux)); - save_item(NAME(m_power_on)); -} - -void ticalc1x_state::machine_reset() -{ - m_power_on = true; -} - - - -/*************************************************************************** - - Helper Functions - -***************************************************************************/ - -// The device may strobe the outputs very fast, it is unnoticeable to the user. -// To prevent flickering here, we need to simulate a decay. - -void ticalc1x_state::display_update() -{ - UINT32 active_state[0x20]; - - for (int y = 0; y < m_display_maxy; y++) - { - active_state[y] = 0; - - for (int x = 0; x < m_display_maxx; x++) - { - // turn on powered segments - if (m_power_on && m_display_state[y] >> x & 1) - m_display_decay[y][x] = m_display_wait; - - // determine active state - int ds = (m_display_decay[y][x] != 0) ? 1 : 0; - active_state[y] |= (ds << x); - } - } - - // on difference, send to output - for (int y = 0; y < m_display_maxy; y++) - if (m_display_cache[y] != active_state[y]) - { - if (m_display_segmask[y] != 0) - output_set_digit_value(y, active_state[y] & m_display_segmask[y]); - - const int mul = (m_display_maxx <= 10) ? 10 : 100; - for (int x = 0; x < m_display_maxx; x++) - { - int state = active_state[y] >> x & 1; - output_set_lamp_value(y * mul + x, state); - - // bit coords for svg2lay - char buf[10]; - sprintf(buf, "%d.%d", y, x); - output_set_value(buf, state); - } - } - - memcpy(m_display_cache, active_state, sizeof(m_display_cache)); -} - -TIMER_DEVICE_CALLBACK_MEMBER(ticalc1x_state::display_decay_tick) -{ - // slowly turn off unpowered segments - for (int y = 0; y < m_display_maxy; y++) - for (int x = 0; x < m_display_maxx; x++) - if (m_display_decay[y][x] != 0) - m_display_decay[y][x]--; - - display_update(); } void ticalc1x_state::display_matrix_seg(int maxx, int maxy, UINT32 setx, UINT32 sety, UINT16 segmask) { - m_display_maxx = maxx; - m_display_maxy = maxy; - - // update current state - UINT32 colmask = (1 << maxx) - 1; for (int y = 0; y < maxy; y++) - { m_display_segmask[y] &= segmask; - m_display_state[y] = (sety >> y & 1) ? (setx & colmask) : 0; - } - display_update(); -} - - -UINT8 ticalc1x_state::read_inputs(int columns) -{ - UINT8 ret = 0; - - // read selected input rows - for (int i = 0; i < columns; i++) - if (m_inp_mux >> i & 1) - ret |= m_inp_matrix[i]->read(); - - return ret; -} - - -// devices with a TMS0980 can auto power-off - -WRITE_LINE_MEMBER(ticalc1x_state::auto_power_off) -{ - if (state) - { - m_power_on = false; - m_maincpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); - } -} - -INPUT_CHANGED_MEMBER(ticalc1x_state::power_button) -{ - m_power_on = (bool)(FPTR)param; - m_maincpu->set_input_line(INPUT_LINE_RESET, m_power_on ? CLEAR_LINE : ASSERT_LINE); + display_matrix(maxx, maxy, setx, sety); } @@ -269,8 +102,7 @@ void ticalc1x_state::tisr16_display() m_display_state[11] = m_display_state[10] << 5 & 0x40; m_display_state[10] &= 0x40; - m_display_maxx = 8; - m_display_maxy = 12; + set_display_size(8, 12); display_update(); } @@ -372,7 +204,7 @@ static MACHINE_CONFIG_START( tisr16, ticalc1x_state ) MCFG_TMS1XXX_WRITE_O_CB(WRITE16(ticalc1x_state, tisr16_write_o)) MCFG_TMS1XXX_WRITE_R_CB(WRITE16(ticalc1x_state, tisr16_write_r)) - MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", ticalc1x_state, display_decay_tick, attotime::from_msec(1)) + MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_tms1k_state, display_decay_tick, attotime::from_msec(1)) MCFG_DEFAULT_LAYOUT(layout_tisr16) /* no video! */ @@ -548,7 +380,7 @@ static MACHINE_CONFIG_START( ti1270, ticalc1x_state ) MCFG_TMS1XXX_WRITE_O_CB(WRITE16(ticalc1x_state, ti1270_write_o)) MCFG_TMS1XXX_WRITE_R_CB(WRITE16(ticalc1x_state, ti1270_write_r)) - MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", ticalc1x_state, display_decay_tick, attotime::from_msec(1)) + MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_tms1k_state, display_decay_tick, attotime::from_msec(1)) MCFG_DEFAULT_LAYOUT(layout_ti1270) /* no video! */ @@ -632,7 +464,7 @@ static MACHINE_CONFIG_START( wizatron, ticalc1x_state ) MCFG_TMS1XXX_WRITE_O_CB(WRITE16(ticalc1x_state, wizatron_write_o)) MCFG_TMS1XXX_WRITE_R_CB(WRITE16(ticalc1x_state, wizatron_write_r)) - MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", ticalc1x_state, display_decay_tick, attotime::from_msec(1)) + MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_tms1k_state, display_decay_tick, attotime::from_msec(1)) MCFG_DEFAULT_LAYOUT(layout_wizatron) /* no video! */ @@ -692,7 +524,7 @@ static MACHINE_CONFIG_START( lilprof, ticalc1x_state ) MCFG_TMS1XXX_WRITE_O_CB(WRITE16(ticalc1x_state, lilprof_write_o)) MCFG_TMS1XXX_WRITE_R_CB(WRITE16(ticalc1x_state, wizatron_write_r)) - MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", ticalc1x_state, display_decay_tick, attotime::from_msec(1)) + MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_tms1k_state, display_decay_tick, attotime::from_msec(1)) MCFG_DEFAULT_LAYOUT(layout_wizatron) /* no video! */ @@ -706,8 +538,11 @@ MACHINE_CONFIG_END /*************************************************************************** - TI Little Professor (1978 version, same as 1980 version) + TI Little Professor (1978 version) * TMS1990 MCU labeled TMC1993NL. die labeled 1990C-c3C + + 1978 re-release, with on/off and level select on buttons instead of + switches. The casing was slightly revised in 1980 again, but same rom. ***************************************************************************/ @@ -726,8 +561,7 @@ WRITE16_MEMBER(ticalc1x_state::lilprof78_write_r) // 6th digit is a custom 7seg for math symbols (see wizatron_write_r) m_display_state[6] = BITSWAP8(m_display_state[6],7,6,1,4,2,3,5,0); - m_display_maxx = 7; - m_display_maxy = 9; + set_display_size(7, 9); display_update(); } @@ -788,7 +622,7 @@ static MACHINE_CONFIG_START( lilprof78, ticalc1x_state ) MCFG_TMS1XXX_WRITE_O_CB(WRITE16(ticalc1x_state, lilprof78_write_o)) MCFG_TMS1XXX_WRITE_R_CB(WRITE16(ticalc1x_state, lilprof78_write_r)) - MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", ticalc1x_state, display_decay_tick, attotime::from_msec(1)) + MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_tms1k_state, display_decay_tick, attotime::from_msec(1)) MCFG_DEFAULT_LAYOUT(layout_wizatron) /* no video! */ @@ -1023,7 +857,7 @@ static MACHINE_CONFIG_START( ti30, ticalc1x_state ) MCFG_TMS1XXX_WRITE_R_CB(WRITE16(ticalc1x_state, ti30_write_r)) MCFG_TMS1XXX_POWER_OFF_CB(WRITELINE(ticalc1x_state, auto_power_off)) - MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", ticalc1x_state, display_decay_tick, attotime::from_msec(1)) + MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_tms1k_state, display_decay_tick, attotime::from_msec(1)) MCFG_DEFAULT_LAYOUT(layout_ti30) /* no video! */ diff --git a/src/mess/drivers/tispeak.c b/src/mess/drivers/tispeak.c index ed6dfa7ae78..eb59237f6ea 100644 --- a/src/mess/drivers/tispeak.c +++ b/src/mess/drivers/tispeak.c @@ -2,6 +2,8 @@ // copyright-holders:hap, Lord Nightmare /*************************************************************************** + ** subclass of hh_tms1k_state (includes/hh_tms1k.h, drivers/hh_tms1k.c) ** + Texas Instruments 1st-gen. handheld speech devices, These devices, mostly edu-toys, are based around an MCU(TMS0270/TMS1100), @@ -275,13 +277,13 @@ Other devices: ***************************************************************************/ -#include "emu.h" -#include "cpu/tms0980/tms0980.h" +#include "includes/hh_tms1k.h" #include "sound/tms5110.h" #include "machine/tms6100.h" #include "bus/generic/slot.h" #include "bus/generic/carts.h" +// internal artwork #include "lantutor.lh" #include "snspell.lh" @@ -294,47 +296,20 @@ Other devices: #define MASTER_CLOCK (640000) -class tispeak_state : public driver_device +class tispeak_state : public hh_tms1k_state { public: tispeak_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu"), + : hh_tms1k_state(mconfig, type, tag), m_tms5100(*this, "tms5100"), m_tms6100(*this, "tms6100"), - m_cart(*this, "cartslot"), - m_button_matrix(*this, "IN"), - m_display_wait(33), - m_display_maxy(1), - m_display_maxx(0) + m_cart(*this, "cartslot") { } // devices - required_device m_maincpu; required_device m_tms5100; required_device m_tms6100; optional_device m_cart; - required_ioport_array<9> m_button_matrix; - - // misc common - UINT16 m_r; // MCU R-pins data - UINT16 m_o; // MCU O-pins data - int m_power_on; - int m_filament_on; - - // display common - int m_display_wait; // led/lamp off-delay in microseconds (default 33ms) - int m_display_maxy; // display matrix number of rows - int m_display_maxx; // display matrix number of columns - - UINT32 m_display_state[0x20]; // display matrix rows data - UINT16 m_display_segmask[0x20]; // if not 0, display matrix row is a digit, mask indicates connected segments - UINT32 m_display_cache[0x20]; // (internal use) - UINT8 m_display_decay[0x20][0x20]; // (internal use) - - TIMER_DEVICE_CALLBACK_MEMBER(display_decay_tick); - void display_update(); - void display_matrix_seg(int maxx, int maxy, UINT32 setx, UINT32 sety, UINT16 segmask); // cartridge UINT32 m_cart_max_size; @@ -349,10 +324,11 @@ public: DECLARE_WRITE16_MEMBER(snspell_write_r); DECLARE_WRITE16_MEMBER(lantutor_write_r); - DECLARE_INPUT_CHANGED_MEMBER(power_button); - void power_off(); + DECLARE_INPUT_CHANGED_MEMBER(snspell_power_button); + void snspell_power_off(); + void snspell_display(); - virtual void machine_reset(); +protected: virtual void machine_start(); }; @@ -395,87 +371,6 @@ DRIVER_INIT_MEMBER(tispeak_state, lantutor) -/*************************************************************************** - - VFD Display - -***************************************************************************/ - -// The device may strobe the outputs very fast, it is unnoticeable to the user. -// To prevent flickering here, we need to simulate a decay. - -void tispeak_state::display_update() -{ - UINT32 active_state[0x20]; - - for (int y = 0; y < m_display_maxy; y++) - { - active_state[y] = 0; - - for (int x = 0; x < m_display_maxx; x++) - { - // turn on powered segments - if (m_power_on && m_filament_on && m_display_state[y] >> x & 1) - m_display_decay[y][x] = m_display_wait; - - // determine active state - int ds = (m_display_decay[y][x] != 0) ? 1 : 0; - active_state[y] |= (ds << x); - } - } - - // on difference, send to output - for (int y = 0; y < m_display_maxy; y++) - if (m_display_cache[y] != active_state[y]) - { - if (m_display_segmask[y] != 0) - output_set_digit_value(y, active_state[y] & m_display_segmask[y]); - - const int mul = (m_display_maxx <= 10) ? 10 : 100; - for (int x = 0; x < m_display_maxx; x++) - { - int state = active_state[y] >> x & 1; - output_set_lamp_value(y * mul + x, state); - - // bit coords for svg2lay - char buf[10]; - sprintf(buf, "%d.%d", y, x); - output_set_value(buf, state); - } - } - - memcpy(m_display_cache, active_state, sizeof(m_display_cache)); -} - -TIMER_DEVICE_CALLBACK_MEMBER(tispeak_state::display_decay_tick) -{ - // slowly turn off unpowered segments - for (int y = 0; y < m_display_maxy; y++) - for (int x = 0; x < m_display_maxx; x++) - if (m_display_decay[y][x] != 0) - m_display_decay[y][x]--; - - display_update(); -} - -void tispeak_state::display_matrix_seg(int maxx, int maxy, UINT32 setx, UINT32 sety, UINT16 segmask) -{ - m_display_maxx = maxx; - m_display_maxy = maxy; - - // update current state - UINT32 colmask = (1 << maxx) - 1; - for (int y = 0; y < maxy; y++) - { - m_display_segmask[y] &= segmask; - m_display_state[y] = (sety >> y & 1) ? (setx & colmask) : 0; - } - - display_update(); -} - - - /*************************************************************************** I/O @@ -484,32 +379,31 @@ void tispeak_state::display_matrix_seg(int maxx, int maxy, UINT32 setx, UINT32 s // common/snspell +void tispeak_state::snspell_display() +{ + for (int y = 0; y < 16; y++) + m_display_segmask[y] = 0x3fff; + + display_matrix(16, 16, m_o, (m_r & 0x8000) ? (m_r & 0x21ff) : 0); +} + READ8_MEMBER(tispeak_state::snspell_read_k) { - // the Vss row is always on - UINT8 k = m_button_matrix[8]->read(); - - // read selected button rows - for (int i = 0; i < 8; i++) - if (m_r >> i & 1) - k |= m_button_matrix[i]->read(); - - return k; + // note: the Vss row is always on + return m_inp_matrix[8]->read() | read_inputs(8); } WRITE16_MEMBER(tispeak_state::snspell_write_r) { - // R15: filament on - m_filament_on = data & 0x8000; - // R13: power-off request, on falling edge if ((m_r >> 13 & 1) && !(data >> 13 & 1)) - power_off(); + snspell_power_off(); // R0-R7: input mux and select digit (+R8 if the device has 9 digits) + // R15: filament on // other bits: MCU internal use - m_r = data & 0x21ff; - display_matrix_seg(16, 16, m_o, m_r, 0x3fff); + m_r = m_inp_mux = data; + snspell_display(); } WRITE16_MEMBER(tispeak_state::snspell_write_o) @@ -517,17 +411,17 @@ WRITE16_MEMBER(tispeak_state::snspell_write_o) // reorder opla to led14seg, plus DP as d14 and AP as d15: // E,D,C,G,B,A,I,M,L,K,N,J,[AP],H,F,[DP] (sidenote: TI KLMN = MAME MLNK) m_o = BITSWAP16(data,12,15,10,7,8,9,11,6,13,3,14,0,1,2,4,5); - display_matrix_seg(16, 16, m_o, m_r, 0x3fff); + snspell_display(); } -void tispeak_state::power_off() +void tispeak_state::snspell_power_off() { m_maincpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); m_tms5100->reset(); m_tms6100->reset(); - m_power_on = 0; + m_power_on = false; } @@ -538,7 +432,7 @@ WRITE16_MEMBER(tispeak_state::snmath_write_o) // reorder opla to led14seg, plus DP as d14 and AP as d15: // [DP],D,C,H,F,B,I,M,L,K,N,J,[AP],E,G,A (sidenote: TI KLMN = MAME MLNK) m_o = BITSWAP16(data,12,0,10,7,8,9,11,6,3,14,4,13,1,2,5,15); - display_matrix_seg(16, 16, m_o, m_r, 0x3fff); + snspell_display(); } @@ -547,9 +441,8 @@ WRITE16_MEMBER(tispeak_state::snmath_write_o) WRITE16_MEMBER(tispeak_state::lantutor_write_r) { // same as default, except R13 is used for an extra digit - m_filament_on = data & 0x8000; - m_r = data & 0x21ff; - display_matrix_seg(16, 16, m_o, m_r, 0x3fff); + m_r = m_inp_mux = data; + snspell_display(); } @@ -560,17 +453,17 @@ WRITE16_MEMBER(tispeak_state::lantutor_write_r) ***************************************************************************/ -INPUT_CHANGED_MEMBER(tispeak_state::power_button) +INPUT_CHANGED_MEMBER(tispeak_state::snspell_power_button) { int on = (int)(FPTR)param; if (on && !m_power_on) { - m_power_on = 1; + m_power_on = true; m_maincpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE); } else if (!on && m_power_on) - power_off(); + snspell_power_off(); } static INPUT_PORTS_START( snspell ) @@ -631,7 +524,7 @@ static INPUT_PORTS_START( snspell ) PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_NAME("Secret Code") PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_NAME("Letter") PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_NAME("Say It") - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_PGUP) PORT_NAME("Spell/On") PORT_CHANGED_MEMBER(DEVICE_SELF, tispeak_state, power_button, (void *)1) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_PGUP) PORT_NAME("Spell/On") PORT_CHANGED_MEMBER(DEVICE_SELF, tispeak_state, snspell_power_button, (void *)true) INPUT_PORTS_END @@ -683,7 +576,7 @@ static INPUT_PORTS_START( snmath ) PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_NAME("Write It") PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_NAME("Greater/Less") PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_NAME("Word Problems") - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CODE(KEYCODE_PGUP) PORT_NAME("Solve It/On") PORT_CHANGED_MEMBER(DEVICE_SELF, tispeak_state, power_button, (void *)1) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CODE(KEYCODE_PGUP) PORT_NAME("Solve It/On") PORT_CHANGED_MEMBER(DEVICE_SELF, tispeak_state, snspell_power_button, (void *)true) PORT_START("IN.7") PORT_BIT( 0x1f, IP_ACTIVE_HIGH, IPT_UNUSED ) @@ -705,7 +598,7 @@ static INPUT_PORTS_START( snread ) PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_NAME("Picture Read") PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_NAME("Letter Stumper") PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_NAME("Hear It") - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_PGUP) PORT_NAME("Word Zap/On") PORT_CHANGED_MEMBER(DEVICE_SELF, tispeak_state, power_button, (void *)1) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_PGUP) PORT_NAME("Word Zap/On") PORT_CHANGED_MEMBER(DEVICE_SELF, tispeak_state, snspell_power_button, (void *)true) INPUT_PORTS_END @@ -746,38 +639,9 @@ INPUT_PORTS_END ***************************************************************************/ -void tispeak_state::machine_reset() -{ - m_power_on = 1; -} - void tispeak_state::machine_start() { - // zerofill - memset(m_display_state, 0, sizeof(m_display_state)); - memset(m_display_cache, ~0, sizeof(m_display_cache)); - memset(m_display_decay, 0, sizeof(m_display_decay)); - memset(m_display_segmask, ~0, sizeof(m_display_segmask)); // ! - - m_r = 0; - m_o = 0; - m_power_on = 0; - m_filament_on = 0; - - // register for savestates - save_item(NAME(m_display_maxy)); - save_item(NAME(m_display_maxx)); - save_item(NAME(m_display_wait)); - - save_item(NAME(m_display_state)); - /* save_item(NAME(m_display_cache)); */ // don't save! - save_item(NAME(m_display_decay)); - save_item(NAME(m_display_segmask)); - - save_item(NAME(m_r)); - save_item(NAME(m_o)); - save_item(NAME(m_power_on)); - save_item(NAME(m_filament_on)); + hh_tms1k_state::machine_start(); // init cartridge if (m_cart != NULL && m_cart->exists()) @@ -802,7 +666,7 @@ static MACHINE_CONFIG_START( snmath, tispeak_state ) MCFG_TMS0270_WRITE_CTL_CB(DEVWRITE8("tms5100", tms5100_device, ctl_w)) MCFG_TMS0270_WRITE_PDC_CB(DEVWRITELINE("tms5100", tms5100_device, pdc_w)) - MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", tispeak_state, display_decay_tick, attotime::from_msec(1)) + MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_tms1k_state, display_decay_tick, attotime::from_msec(1)) MCFG_DEFAULT_LAYOUT(layout_snspell) // max 9 digits /* no video! */ diff --git a/src/mess/includes/hh_tms1k.h b/src/mess/includes/hh_tms1k.h index 1ab7b2cce90..f45f040609c 100644 --- a/src/mess/includes/hh_tms1k.h +++ b/src/mess/includes/hh_tms1k.h @@ -30,7 +30,7 @@ public: // devices required_device m_maincpu; - optional_ioport_array<7> m_inp_matrix; // max 7 + optional_ioport_array<11> m_inp_matrix; // max 11 optional_device m_speaker; // misc common @@ -55,6 +55,7 @@ public: TIMER_DEVICE_CALLBACK_MEMBER(display_decay_tick); void display_update(); + void set_display_size(int maxx, int maxy); void display_matrix(int maxx, int maxy, UINT32 setx, UINT32 sety); // game-specific handlers