update tispeak.c display_update

This commit is contained in:
hap 2015-03-15 17:46:47 +01:00
parent 3790a735eb
commit 02590ff263
6 changed files with 117 additions and 88 deletions

View File

@ -83,7 +83,7 @@ public:
UINT64 m_plate; // VFD current column data
UINT64 m_display_state[0x20]; // display matrix rows data
UINT16 m_7seg_mask[0x20]; // if not 0, display matrix row is a 7seg, mask indicates connected segments
UINT16 m_display_segmask[0x20]; // if not 0, display matrix row is a digit, mask indicates connected segments
UINT64 m_display_cache[0x20]; // (internal use)
UINT8 m_display_decay[0x20][0x40]; // (internal use)
@ -104,7 +104,7 @@ void hh_hmcs40_state::machine_start()
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_7seg_mask, 0, sizeof(m_7seg_mask));
memset(m_display_segmask, 0, sizeof(m_display_segmask));
m_inp_mux = 0;
m_grid = 0;
@ -118,7 +118,7 @@ void hh_hmcs40_state::machine_start()
save_item(NAME(m_display_state));
save_item(NAME(m_display_cache));
save_item(NAME(m_display_decay));
save_item(NAME(m_7seg_mask));
save_item(NAME(m_display_segmask));
save_item(NAME(m_inp_mux));
save_item(NAME(m_grid));
@ -160,8 +160,8 @@ void hh_hmcs40_state::display_update()
for (int y = 0; y < m_display_maxy; y++)
if (m_display_cache[y] != active_state[y])
{
if (m_7seg_mask[y] != 0)
output_set_digit_value(y, active_state[y] & m_7seg_mask[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++)

View File

@ -59,7 +59,7 @@ public:
int m_display_maxx; // display matrix number of columns
UINT32 m_display_state[0x20]; // display matrix rows data
UINT16 m_7seg_mask[0x20]; // if not 0, display matrix row is a 7seg, mask indicates connected segments
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)
@ -78,7 +78,7 @@ void hh_pic16_state::machine_start()
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_7seg_mask, 0, sizeof(m_7seg_mask));
memset(m_display_segmask, 0, sizeof(m_display_segmask));
m_b = 0;
m_c = 0;
@ -91,7 +91,7 @@ void hh_pic16_state::machine_start()
save_item(NAME(m_display_state));
save_item(NAME(m_display_cache));
save_item(NAME(m_display_decay));
save_item(NAME(m_7seg_mask));
save_item(NAME(m_display_segmask));
save_item(NAME(m_b));
save_item(NAME(m_c));
@ -132,8 +132,8 @@ void hh_pic16_state::display_update()
for (int y = 0; y < m_display_maxy; y++)
if (m_display_cache[y] != active_state[y])
{
if (m_7seg_mask[y] != 0)
output_set_digit_value(y, active_state[y] & m_7seg_mask[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++)
@ -199,7 +199,7 @@ WRITE8_MEMBER(hh_pic16_state::maniac_output_w)
m_display_maxx = 7;
m_display_maxy = 2;
m_7seg_mask[offset] = 0x7f;
m_display_segmask[offset] = 0x7f;
m_display_state[offset] = ~data & 0x7f;
display_update();
}

View File

@ -126,7 +126,7 @@ public:
int m_display_maxx; // display matrix number of columns
UINT32 m_display_state[0x20]; // display matrix rows data
UINT16 m_7seg_mask[0x20]; // if not 0, display matrix row is a 7seg, mask indicates connected segments
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)
@ -215,7 +215,7 @@ void hh_tms1k_state::machine_start()
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_7seg_mask, 0, sizeof(m_7seg_mask));
memset(m_display_segmask, 0, sizeof(m_display_segmask));
m_o = 0;
m_r = 0;
@ -230,7 +230,7 @@ void hh_tms1k_state::machine_start()
save_item(NAME(m_display_state));
save_item(NAME(m_display_cache));
save_item(NAME(m_display_decay));
save_item(NAME(m_7seg_mask));
save_item(NAME(m_display_segmask));
save_item(NAME(m_o));
save_item(NAME(m_r));
@ -291,8 +291,8 @@ void hh_tms1k_state::display_update()
for (int y = 0; y < m_display_maxy; y++)
if (m_display_cache[y] != active_state[y])
{
if (m_7seg_mask[y] != 0)
output_set_digit_value(y, active_state[y] & m_7seg_mask[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++)
@ -395,7 +395,7 @@ void hh_tms1k_state::mathmagi_display()
// R0-R7: 7seg leds
for (int y = 0; y < 8; y++)
{
m_7seg_mask[y] = 0x7f;
m_display_segmask[y] = 0x7f;
m_display_state[y] = (m_r >> y & 1) ? (m_o >> 1) : 0;
}
@ -558,7 +558,7 @@ void hh_tms1k_state::amaztron_display()
// R8,R9: select digit
for (int y = 0; y < 2; y++)
{
m_7seg_mask[y] = 0x7f;
m_display_segmask[y] = 0x7f;
m_display_state[y] = (m_r >> (y + 8) & 1) ? m_o : 0;
}
@ -705,7 +705,7 @@ void hh_tms1k_state::tc4_display()
// R5,7,8,9 are 7segs
for (int y = 0; y < 10; y++)
if (y >= 5 && y <= 9 && y != 6)
m_7seg_mask[y] = 0x7f;
m_display_segmask[y] = 0x7f;
// update current state (note: R6 as extra column!)
display_matrix(9, 10, (m_o | (m_r << 2 & 0x100)), m_r);
@ -848,7 +848,7 @@ MACHINE_CONFIG_END
void hh_tms1k_state::ebball_display()
{
// R8 is a 7seg
m_7seg_mask[8] = 0x7f;
m_display_segmask[8] = 0x7f;
display_matrix(7, 9, ~m_o, m_r);
}
@ -979,12 +979,12 @@ void hh_tms1k_state::ebball3_display()
m_display_state[y] = (m_r >> y & 1) ? m_o : 0;
// R0,R1 are normal 7segs
m_7seg_mask[0] = m_7seg_mask[1] = 0x7f;
m_display_segmask[0] = m_display_segmask[1] = 0x7f;
// R4,R7 contain segments(only F and B) for the two other digits
m_display_state[10] = (m_display_state[4] & 0x20) | (m_display_state[7] & 0x02);
m_display_state[11] = ((m_display_state[4] & 0x10) | (m_display_state[7] & 0x01)) << 1;
m_7seg_mask[10] = m_7seg_mask[11] = 0x22;
m_display_segmask[10] = m_display_segmask[11] = 0x22;
display_update();
}
@ -1126,7 +1126,7 @@ WRITE16_MEMBER(hh_tms1k_state::elecdet_write_r)
// R0-R6: select digit
for (int y = 0; y < 7; y++)
m_7seg_mask[y] = 0x7f;
m_display_segmask[y] = 0x7f;
display_matrix(7, 7, BITSWAP8(m_o,7,5,2,1,4,0,6,3), data);
}
@ -1228,7 +1228,7 @@ MACHINE_CONFIG_END
void hh_tms1k_state::starwbc_display()
{
// R6,R8 are 7segs
m_7seg_mask[6] = m_7seg_mask[8] = 0x7f;
m_display_segmask[6] = m_display_segmask[8] = 0x7f;
display_matrix(8, 10, m_o, m_r);
}
@ -1527,7 +1527,7 @@ WRITE16_MEMBER(hh_tms1k_state::cnsector_write_r)
// R0-R5: select digit (right-to-left)
for (int y = 0; y < 6; y++)
{
m_7seg_mask[y] = 0xff;
m_display_segmask[y] = 0xff;
m_display_state[y] = (data >> y & 1) ? m_o : 0;
}
@ -1731,7 +1731,7 @@ WRITE16_MEMBER(hh_tms1k_state::stopthief_write_r)
UINT8 o = BITSWAP8(m_o,3,5,2,1,4,0,6,7) & 0x7f;
for (int y = 0; y < m_display_maxy; y++)
{
m_7seg_mask[y] = 0x7f;
m_display_segmask[y] = 0x7f;
m_display_state[y] = (data >> y & 1) ? o : 0;
}

View File

@ -69,7 +69,7 @@ public:
UINT32 m_plate; // VFD current column data
UINT32 m_display_state[0x20]; // display matrix rows data
UINT16 m_7seg_mask[0x20]; // if not 0, display matrix row is a 7seg, mask indicates connected segments
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)
@ -118,7 +118,7 @@ void hh_ucom4_state::machine_start()
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_7seg_mask, 0, sizeof(m_7seg_mask));
memset(m_display_segmask, 0, sizeof(m_display_segmask));
memset(m_port, 0, sizeof(m_port));
m_inp_mux = 0;
@ -133,7 +133,7 @@ void hh_ucom4_state::machine_start()
save_item(NAME(m_display_state));
save_item(NAME(m_display_cache));
save_item(NAME(m_display_decay));
save_item(NAME(m_7seg_mask));
save_item(NAME(m_display_segmask));
save_item(NAME(m_port));
save_item(NAME(m_inp_mux));
@ -176,8 +176,8 @@ void hh_ucom4_state::display_update()
for (int y = 0; y < m_display_maxy; y++)
if (m_display_cache[y] != active_state[y])
{
if (m_7seg_mask[y] != 0)
output_set_digit_value(y, active_state[y] & m_7seg_mask[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++)

View File

@ -61,13 +61,13 @@ public:
int m_display_maxx; // display matrix number of columns
UINT32 m_display_state[0x20]; // display matrix rows data
UINT16 m_7seg_mask[0x20]; // if not 0, display matrix row is a 7seg, mask indicates connected segments
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_7seg(int maxx, int maxy, UINT32 setx, UINT32 sety, UINT16 _7segmask);
void display_matrix_seg(int maxx, int maxy, UINT32 setx, UINT32 sety, UINT16 segmask);
// calculator-specific handlers
DECLARE_READ8_MEMBER(tisr16_read_k);
@ -101,7 +101,7 @@ void ticalc1x_state::machine_start()
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_7seg_mask, ~0, sizeof(m_7seg_mask)); // !
memset(m_display_segmask, ~0, sizeof(m_display_segmask)); // !
m_o = 0;
m_r = 0;
@ -116,7 +116,7 @@ void ticalc1x_state::machine_start()
save_item(NAME(m_display_state));
save_item(NAME(m_display_cache));
save_item(NAME(m_display_decay));
save_item(NAME(m_7seg_mask));
save_item(NAME(m_display_segmask));
save_item(NAME(m_o));
save_item(NAME(m_r));
@ -164,8 +164,8 @@ void ticalc1x_state::display_update()
for (int y = 0; y < m_display_maxy; y++)
if (m_display_cache[y] != active_state[y])
{
if (m_7seg_mask[y] != 0)
output_set_digit_value(y, active_state[y] & m_7seg_mask[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++)
@ -186,7 +186,7 @@ TIMER_DEVICE_CALLBACK_MEMBER(ticalc1x_state::display_decay_tick)
display_update();
}
void ticalc1x_state::display_matrix_7seg(int maxx, int maxy, UINT32 setx, UINT32 sety, UINT16 _7segmask)
void ticalc1x_state::display_matrix_seg(int maxx, int maxy, UINT32 setx, UINT32 sety, UINT16 segmask)
{
m_display_maxx = maxx;
m_display_maxy = maxy;
@ -195,7 +195,7 @@ void ticalc1x_state::display_matrix_7seg(int maxx, int maxy, UINT32 setx, UINT32
UINT32 colmask = (1 << maxx) - 1;
for (int y = 0; y < maxy; y++)
{
m_7seg_mask[y] &= _7segmask;
m_display_segmask[y] &= segmask;
m_display_state[y] = (sety >> y & 1) ? (setx & colmask) : 0;
}
@ -387,7 +387,7 @@ READ8_MEMBER(ticalc1x_state::ti1270_read_k)
WRITE16_MEMBER(ticalc1x_state::ti1270_write_r)
{
// R0-R7: select digit (right-to-left)
display_matrix_7seg(8, 8, m_o, data, 0xff);
display_matrix_seg(8, 8, m_o, data, 0xff);
}
WRITE16_MEMBER(ticalc1x_state::ti1270_write_o)
@ -474,10 +474,10 @@ WRITE16_MEMBER(ticalc1x_state::wizatron_write_r)
{
// note: 6th digit is custom(not 7seg), for math symbols, and 3rd digit
// only has A and G for =, though some newer revisions use a custom digit too.
m_7seg_mask[3] = 0x41;
m_display_segmask[3] = 0x41;
// R0-R8: select digit (right-to-left)
display_matrix_7seg(8, 9, m_o, data, 0x7f);
display_matrix_seg(8, 9, m_o, data, 0x7f);
}
WRITE16_MEMBER(ticalc1x_state::wizatron_write_o)
@ -651,10 +651,10 @@ READ8_MEMBER(ticalc1x_state::ti30_read_k)
WRITE16_MEMBER(ticalc1x_state::ti30_write_r)
{
// note: 1st digit only has segments B,F,G,DP
m_7seg_mask[0] = 0xe2;
m_display_segmask[0] = 0xe2;
// R0-R8: select digit
display_matrix_7seg(8, 9, BITSWAP8(m_o,7,5,2,1,4,0,6,3), data, 0xff);
display_matrix_seg(8, 9, BITSWAP8(m_o,7,5,2,1,4,0,6,3), data, 0xff);
}
WRITE16_MEMBER(ticalc1x_state::ti30_write_o)

View File

@ -303,25 +303,40 @@ public:
m_tms5100(*this, "tms5100"),
m_tms6100(*this, "tms6100"),
m_cart(*this, "cartslot"),
m_button_matrix(*this, "IN")
m_button_matrix(*this, "IN"),
m_display_wait(33),
m_display_maxy(1),
m_display_maxx(0)
{ }
// 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;
UINT16 m_r;
UINT16 m_o;
// 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)
UINT16 m_display_state[0x10];
UINT16 m_display_cache[0x10];
UINT8 m_display_decay[0x100];
void display_update();
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;
UINT8* m_cart_base;
DECLARE_DEVICE_IMAGE_LOAD_MEMBER(tispeak_cartridge);
@ -386,47 +401,39 @@ DRIVER_INIT_MEMBER(tispeak_state, lantutor)
***************************************************************************/
// The device strobes the filament-enable very fast, it is unnoticeable to the user.
// The device may 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 1ms
#define DISPLAY_DECAY_TIME 40
void tispeak_state::display_update()
{
int filament_on = (m_r & 0x8000) ? 1 : 0;
UINT16 active_state[0x10];
UINT32 active_state[0x20];
for (int i = 0; i < 0x10; i++)
for (int y = 0; y < m_display_maxy; y++)
{
// update current state
m_display_state[i] = (m_r >> i & 1) ? m_o : 0;
active_state[y] = 0;
active_state[i] = 0;
for (int j = 0; j < 0x10; j++)
for (int x = 0; x < m_display_maxx; x++)
{
int di = j << 4 | i;
// turn on powered segments
if (m_power_on && filament_on && m_display_state[i] >> j & 1)
m_display_decay[di] = DISPLAY_DECAY_TIME;
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[di] != 0) ? 1 : 0;
active_state[i] |= (ds << j);
int ds = (m_display_decay[y][x] != 0) ? 1 : 0;
active_state[y] |= (ds << x);
}
}
// on difference, send to output
for (int i = 0; i < 0x10; i++)
if (m_display_cache[i] != active_state[i])
for (int y = 0; y < m_display_maxy; y++)
if (m_display_cache[y] != active_state[y])
{
output_set_digit_value(i, active_state[i] & 0x3fff);
if (m_display_segmask[y] != 0)
output_set_digit_value(y, active_state[y] & m_display_segmask[y]);
// lampxyy where x=digit, y=segment
for (int j = 0; j < 0x10; j++)
output_set_lamp_value(i*100 + j, active_state[i] >> j & 1);
const int mul = (m_display_maxx <= 10) ? 10 : 100;
for (int x = 0; x < m_display_maxx; x++)
output_set_lamp_value(y * mul + x, active_state[y] >> x & 1);
}
memcpy(m_display_cache, active_state, sizeof(m_display_cache));
@ -435,10 +442,27 @@ void tispeak_state::display_update()
TIMER_DEVICE_CALLBACK_MEMBER(tispeak_state::display_decay_tick)
{
// slowly turn off unpowered segments
for (int i = 0; i < 0x100; i++)
if (!(m_display_state[i & 0xf] >> (i>>4) & 1) && m_display_decay[i])
m_display_decay[i]--;
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();
}
@ -467,15 +491,17 @@ READ8_MEMBER(tispeak_state::snspell_read_k)
WRITE16_MEMBER(tispeak_state::snspell_write_r)
{
// R0-R7: input mux and select digit (+R8 if the device has 9 digits)
// R15: filament on (handled in leds_update)
// 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();
// R0-R7: input mux and select digit (+R8 if the device has 9 digits)
// other bits: MCU internal use
m_r = data;
display_update();
m_r = data & 0x21ff;
display_matrix_seg(16, 16, m_o, m_r, 0x3fff);
}
WRITE16_MEMBER(tispeak_state::snspell_write_o)
@ -483,8 +509,7 @@ 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_update();
display_matrix_seg(16, 16, m_o, m_r, 0x3fff);
}
@ -505,8 +530,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_update();
display_matrix_seg(16, 16, m_o, m_r, 0x3fff);
}
@ -515,8 +539,9 @@ 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_r = data;
display_update();
m_filament_on = data & 0x8000;
m_r = data & 0x21ff;
display_matrix_seg(16, 16, m_o, m_r, 0x3fff);
}
@ -708,19 +733,23 @@ void tispeak_state::machine_start()
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_state));
save_item(NAME(m_display_cache));
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));
// init cartridge
if (m_cart != NULL && m_cart->exists())