mirror of
https://github.com/holub/mame
synced 2025-04-20 23:42:22 +03:00
Merge branch 'master' of https://github.com/mamedev/mame
This commit is contained in:
commit
0d375f3312
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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<cpu_device> m_maincpu;
|
||||
optional_ioport_array<11> m_inp_matrix; // max 11
|
||||
optional_device<speaker_sound_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! */
|
||||
|
@ -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<tms0270_cpu_device> m_maincpu;
|
||||
required_device<tms5100_device> m_tms5100;
|
||||
required_device<tms6100_device> m_tms6100;
|
||||
optional_device<generic_slot_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! */
|
||||
|
@ -30,7 +30,7 @@ public:
|
||||
|
||||
// devices
|
||||
required_device<cpu_device> m_maincpu;
|
||||
optional_ioport_array<7> m_inp_matrix; // max 7
|
||||
optional_ioport_array<11> m_inp_matrix; // max 11
|
||||
optional_device<speaker_sound_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
|
||||
|
Loading…
Reference in New Issue
Block a user