From 8d82bf8896aa59c027a1cdfc9dd352d8348a1163 Mon Sep 17 00:00:00 2001 From: hap Date: Sun, 25 Jun 2017 17:32:50 +0200 Subject: hh_sm510: added lcd deflicker (nw) --- src/devices/cpu/sm510/sm500.h | 2 +- src/devices/cpu/sm510/sm500core.cpp | 2 +- src/mame/drivers/cxgz80.cpp | 2 +- src/mame/drivers/hh_cop400.cpp | 2 +- src/mame/drivers/hh_hmcs40.cpp | 2 +- src/mame/drivers/hh_melps4.cpp | 2 +- src/mame/drivers/hh_pic16.cpp | 2 +- src/mame/drivers/hh_sm510.cpp | 149 +++++++++++++++++++++++++----------- src/mame/drivers/k28.cpp | 2 +- src/mame/includes/fidelbase.h | 2 +- src/mame/includes/hh_tms1k.h | 2 +- src/mame/includes/hh_ucom4.h | 2 +- src/mame/includes/novagbase.h | 2 +- 13 files changed, 115 insertions(+), 58 deletions(-) diff --git a/src/devices/cpu/sm510/sm500.h b/src/devices/cpu/sm510/sm500.h index 6c6e7e7cecd..7c11f21e1f3 100644 --- a/src/devices/cpu/sm510/sm500.h +++ b/src/devices/cpu/sm510/sm500.h @@ -16,7 +16,7 @@ // I/O ports setup -// LCD segment outputs: H1/2 as a4, O group as a0-a3, O data as d0-d3 +// LCD segment outputs: H1/2 as a0, O group as a1-a4, O data as d0-d3 #define MCFG_SM500_WRITE_O_CB(_devcb) \ devcb = &sm500_device::set_write_o_callback(*device, DEVCB_##_devcb); diff --git a/src/devices/cpu/sm510/sm500core.cpp b/src/devices/cpu/sm510/sm500core.cpp index fb9206aa6d3..2b9211a15dd 100644 --- a/src/devices/cpu/sm510/sm500core.cpp +++ b/src/devices/cpu/sm510/sm500core.cpp @@ -122,7 +122,7 @@ void sm500_device::lcd_update() { // 4 segments per group u8 seg = h ? m_o[o] : m_ox[o]; - m_write_o(h << 4 | o, m_bp ? seg : 0, 0xff); + m_write_o(o << 1 | h, m_bp ? seg : 0, 0xff); } } } diff --git a/src/mame/drivers/cxgz80.cpp b/src/mame/drivers/cxgz80.cpp index 0a34c800ff3..96af9b69426 100644 --- a/src/mame/drivers/cxgz80.cpp +++ b/src/mame/drivers/cxgz80.cpp @@ -64,7 +64,7 @@ public: u16 read_inputs(int columns); // display common - int m_display_wait; // led/lamp off-delay in microseconds (default 33ms) + int m_display_wait; // led/lamp off-delay in milliseconds (default 33ms) int m_display_maxy; // display matrix number of rows int m_display_maxx; // display matrix number of columns (max 31 for now) diff --git a/src/mame/drivers/hh_cop400.cpp b/src/mame/drivers/hh_cop400.cpp index 6a8de5d67a1..d0bcc8cb722 100644 --- a/src/mame/drivers/hh_cop400.cpp +++ b/src/mame/drivers/hh_cop400.cpp @@ -65,7 +65,7 @@ public: u16 read_inputs(int columns); // display common - int m_display_wait; // led/lamp off-delay in microseconds (default 33ms) + int m_display_wait; // led/lamp off-delay in milliseconds (default 33ms) int m_display_maxy; // display matrix number of rows int m_display_maxx; // display matrix number of columns (max 31 for now) diff --git a/src/mame/drivers/hh_hmcs40.cpp b/src/mame/drivers/hh_hmcs40.cpp index e994e16d307..fa5e9133f36 100644 --- a/src/mame/drivers/hh_hmcs40.cpp +++ b/src/mame/drivers/hh_hmcs40.cpp @@ -141,7 +141,7 @@ public: DECLARE_INPUT_CHANGED_MEMBER(single_interrupt_line); // display common - int m_display_wait; // led/lamp off-delay in microseconds (default 33ms) + int m_display_wait; // led/lamp off-delay in milliseconds (default 33ms) int m_display_maxy; // display matrix number of rows int m_display_maxx; // display matrix number of columns (max 47 for now) diff --git a/src/mame/drivers/hh_melps4.cpp b/src/mame/drivers/hh_melps4.cpp index 0fd011ca554..57f6437ed6f 100644 --- a/src/mame/drivers/hh_melps4.cpp +++ b/src/mame/drivers/hh_melps4.cpp @@ -44,7 +44,7 @@ public: DECLARE_INPUT_CHANGED_MEMBER(reset_button); // display common - int m_display_wait; // led/lamp off-delay in microseconds (default 33ms) + int m_display_wait; // led/lamp off-delay in milliseconds (default 33ms) int m_display_maxy; // display matrix number of rows int m_display_maxx; // display matrix number of columns (max 31 for now) diff --git a/src/mame/drivers/hh_pic16.cpp b/src/mame/drivers/hh_pic16.cpp index 98f8247d90a..d5ee4f39b04 100644 --- a/src/mame/drivers/hh_pic16.cpp +++ b/src/mame/drivers/hh_pic16.cpp @@ -91,7 +91,7 @@ public: u16 read_inputs(int columns); // display common - int m_display_wait; // led/lamp off-delay in microseconds (default 33ms) + int m_display_wait; // led/lamp off-delay in milliseconds (default 33ms) int m_display_maxy; // display matrix number of rows int m_display_maxx; // display matrix number of columns (max 31 for now) diff --git a/src/mame/drivers/hh_sm510.cpp b/src/mame/drivers/hh_sm510.cpp index 9b7457c0b0f..9a0d6d3e26d 100644 --- a/src/mame/drivers/hh_sm510.cpp +++ b/src/mame/drivers/hh_sm510.cpp @@ -6,15 +6,11 @@ Sharp SM5xx family handhelds. TODO: - - gnw_mc25 emulation is preliminary - - confirm gnw_mc25 romdump + - add svg layout for gnw_mc25 - improve svg layout for gnw_jr55, gnw_mw56 + - confirm gnw_mc25 romdump - svg lcd screen background/foreground (not supported in core), or should it be for external artwork only? - - flickering segments, lcd physics? or screen update timing? - * ktmnt: "LIMIT" segment when going underwater on level 1 - * gnw_dj101: cage and clock before you start the game - * gnw_mw56: truck boxes while playing ***************************************************************************/ @@ -41,7 +37,8 @@ public: m_maincpu(*this, "maincpu"), m_inp_matrix(*this, "IN.%u", 0), m_speaker(*this, "speaker"), - m_inp_lines(0) + m_inp_lines(0), + m_display_wait(17) { } // devices @@ -50,10 +47,9 @@ public: optional_device m_speaker; // misc common - u16 m_inp_mux; // multiplexed inputs mask - int m_inp_lines; // number of input mux columns - u8 m_lcd_output_cache[0x100]; - + u16 m_inp_mux; // multiplexed inputs mask + int m_inp_lines; // number of input mux columns + u8 read_inputs(int columns); virtual void update_k_line(); @@ -67,6 +63,18 @@ public: virtual DECLARE_WRITE8_MEMBER(piezo_r2_w); virtual DECLARE_WRITE8_MEMBER(piezo_input_w); + // display common + int m_display_wait; // lcd segment on/off-delay in milliseconds (default 17ms) + u8 m_display_x_len; // lcd number of groups + u8 m_display_y_len; // lcd number of segments + u8 m_display_z_len; // lcd number of commons + u32 m_display_state[0x20]; // lcd segment data + u8 m_display_decay[0x20][0x20]; // (internal use) + u8 m_display_cache[0x20][0x20]; // (internal use) + + void set_display_size(u8 x, u8 y, u8 z); + TIMER_DEVICE_CALLBACK_MEMBER(display_decay_tick); + protected: virtual void machine_start() override; virtual void machine_reset() override; @@ -80,12 +88,22 @@ void hh_sm510_state::machine_start() // zerofill m_inp_mux = 0; /* m_inp_lines = 0; */ // not here - memset(m_lcd_output_cache, ~0, sizeof(m_lcd_output_cache)); + m_display_x_len = 0; + m_display_y_len = 0; + m_display_z_len = 0; + memset(m_display_state, 0, sizeof(m_display_state)); + memset(m_display_decay, 0, sizeof(m_display_decay)); + memset(m_display_cache, ~0, sizeof(m_display_cache)); // register for savestates save_item(NAME(m_inp_mux)); save_item(NAME(m_inp_lines)); - /* save_item(NAME(m_lcd_output_cache)); */ // don't save! + save_item(NAME(m_display_x_len)); + save_item(NAME(m_display_y_len)); + save_item(NAME(m_display_z_len)); + save_item(NAME(m_display_state)); + save_item(NAME(m_display_decay)); + /* save_item(NAME(m_display_cache)); */ // don't save! } void hh_sm510_state::machine_reset() @@ -101,49 +119,68 @@ void hh_sm510_state::machine_reset() ***************************************************************************/ // lcd panel - on lcd handhelds, usually not a generic x/y screen device +// deflicker here, especially needed for SM500/SM5A with the active shift register -WRITE16_MEMBER(hh_sm510_state::sm510_lcd_segment_w) +TIMER_DEVICE_CALLBACK_MEMBER(hh_sm510_state::display_decay_tick) { - for (int seg = 0; seg < 0x10; seg++) + u8 z_mask = (1 << m_display_z_len) - 1; + u8 zx_len = 1 << (m_display_x_len + m_display_z_len); + + for (int zx = 0; zx < zx_len; zx++) { - int index = offset << 4 | seg; - u8 state = data >> seg & 1; - - if (state != m_lcd_output_cache[index]) + for (int y = 0; y < m_display_y_len; y++) { - // output to row.seg.H, where: - // row = row a/b/bs/c (0/1/2/3) - // seg = seg 1-16 (0-15) - // H = H1-H4 (0-3) - char buf[0x10]; - sprintf(buf, "%d.%d.%d", offset >> 2, seg, offset & 3); - output().set_value(buf, state); - - m_lcd_output_cache[index] = state; + // delay lcd segment on/off state + if (m_display_state[zx] >> y & 1) + { + if (m_display_decay[y][zx] < (2 * m_display_wait - 1)) + m_display_decay[y][zx]++; + } + else if (m_display_decay[y][zx] > 0) + m_display_decay[y][zx]--; + u8 active_state = (m_display_decay[y][zx] < m_display_wait) ? 0 : 1; + + if (active_state != m_display_cache[y][zx]) + { + // SM510 series: output to x.y.z, where: + // x = group a/b/bs/c (0/1/2/3) + // y = segment 1-16 (0-15) + // z = common H1-H4 (0-3) + + // SM500 series: output to x.y.z, where: + // x = O group (0-*) + // y = O segment (0-3) + // z = common H1/H2 (0/1) + char buf[0x10]; + sprintf(buf, "%d.%d.%d", zx >> m_display_z_len, y, zx & z_mask); + output().set_value(buf, active_state); + + m_display_cache[y][zx] = active_state; + } } } } -WRITE8_MEMBER(hh_sm510_state::sm500_lcd_segment_w) +void hh_sm510_state::set_display_size(u8 x, u8 y, u8 z) { - for (int seg = 0; seg < 4; seg++) - { - int index = offset << 2 | seg; - u8 state = data >> seg & 1; + // x = groups(in bits) + // y = number of segments per group + // z = commons(in bits) + m_display_x_len = x; + m_display_y_len = y; + m_display_z_len = z; +} - if (state != m_lcd_output_cache[index]) - { - // output to row.seg.H, where: - // row = O group (0-*) - // seg = O data (0-3) - // H = H1/H2 (0/1) - char buf[0x10]; - sprintf(buf, "%d.%d.%d", offset & 0xf, seg, offset >> 4); - output().set_value(buf, state); - - m_lcd_output_cache[index] = state; - } - } +WRITE16_MEMBER(hh_sm510_state::sm510_lcd_segment_w) +{ + set_display_size(2, 16, 2); + m_display_state[offset] = data; +} + +WRITE8_MEMBER(hh_sm510_state::sm500_lcd_segment_w) +{ + set_display_size(4, 4, 1); + m_display_state[offset] = data; } @@ -276,6 +313,8 @@ static MACHINE_CONFIG_START( ktopgun ) MCFG_SCREEN_REFRESH_RATE(50) MCFG_SCREEN_SIZE(1611, 1080) MCFG_SCREEN_VISIBLE_AREA(0, 1611-1, 0, 1080-1) + + MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_sm510_state, display_decay_tick, attotime::from_msec(1)) MCFG_DEFAULT_LAYOUT(layout_svg) /* sound hardware */ @@ -345,6 +384,8 @@ static MACHINE_CONFIG_START( kcontra ) MCFG_SCREEN_REFRESH_RATE(50) MCFG_SCREEN_SIZE(1501, 1080) MCFG_SCREEN_VISIBLE_AREA(0, 1501-1, 0, 1080-1) + + MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_sm510_state, display_decay_tick, attotime::from_msec(1)) MCFG_DEFAULT_LAYOUT(layout_svg) /* sound hardware */ @@ -413,6 +454,8 @@ static MACHINE_CONFIG_START( ktmnt ) MCFG_SCREEN_REFRESH_RATE(50) MCFG_SCREEN_SIZE(1380, 1080) MCFG_SCREEN_VISIBLE_AREA(0, 1380-1, 0, 1080-1) + + MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_sm510_state, display_decay_tick, attotime::from_msec(1)) MCFG_DEFAULT_LAYOUT(layout_svg) /* sound hardware */ @@ -478,6 +521,8 @@ static MACHINE_CONFIG_START( kgradius ) MCFG_SCREEN_REFRESH_RATE(50) MCFG_SCREEN_SIZE(1435, 1080) MCFG_SCREEN_VISIBLE_AREA(0, 1435-1, 0, 1080-1) + + MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_sm510_state, display_decay_tick, attotime::from_msec(1)) MCFG_DEFAULT_LAYOUT(layout_svg) /* sound hardware */ @@ -541,6 +586,8 @@ static MACHINE_CONFIG_START( kloneran ) MCFG_SCREEN_REFRESH_RATE(50) MCFG_SCREEN_SIZE(1495, 1080) MCFG_SCREEN_VISIBLE_AREA(0, 1495-1, 0, 1080-1) + + MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_sm510_state, display_decay_tick, attotime::from_msec(1)) MCFG_DEFAULT_LAYOUT(layout_svg) /* sound hardware */ @@ -611,6 +658,7 @@ static MACHINE_CONFIG_START( mc25 ) MCFG_SM510_WRITE_R_CB(WRITE8(hh_sm510_state, piezo_input_w)) /* video hardware */ + MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_sm510_state, display_decay_tick, attotime::from_msec(1)) MCFG_DEFAULT_LAYOUT(layout_hh_sm500_test) /* sound hardware */ @@ -680,6 +728,7 @@ static MACHINE_CONFIG_START( dm53 ) MCFG_SCREEN_SIZE(1920/2, 1219/2) MCFG_SCREEN_VISIBLE_AREA(0, 1920/2-1, 0, 1219/2-1) + MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_sm510_state, display_decay_tick, attotime::from_msec(1)) MCFG_DEFAULT_LAYOUT(layout_gnw_dualv) /* sound hardware */ @@ -753,6 +802,7 @@ static MACHINE_CONFIG_START( jr55 ) MCFG_SCREEN_SIZE(1920/2, 1261/2) MCFG_SCREEN_VISIBLE_AREA(0, 1920/2-1, 0, 1261/2-1) + MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_sm510_state, display_decay_tick, attotime::from_msec(1)) MCFG_DEFAULT_LAYOUT(layout_gnw_dualv) /* sound hardware */ @@ -822,6 +872,7 @@ static MACHINE_CONFIG_START( mw56 ) MCFG_SCREEN_SIZE(2079/2, 1440/2) MCFG_SCREEN_VISIBLE_AREA(0, 2079/2-1, 0, 1440/2-1) + MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_sm510_state, display_decay_tick, attotime::from_msec(1)) MCFG_DEFAULT_LAYOUT(layout_gnw_dualh) /* sound hardware */ @@ -891,6 +942,8 @@ static MACHINE_CONFIG_START( dj101 ) MCFG_SCREEN_REFRESH_RATE(50) MCFG_SCREEN_SIZE(1665, 1080) MCFG_SCREEN_VISIBLE_AREA(0, 1665-1, 0, 1080-1) + + MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_sm510_state, display_decay_tick, attotime::from_msec(1)) MCFG_DEFAULT_LAYOUT(layout_svg) /* sound hardware */ @@ -955,6 +1008,8 @@ static MACHINE_CONFIG_START( ml102 ) MCFG_SCREEN_REFRESH_RATE(50) MCFG_SCREEN_SIZE(1759, 1080) MCFG_SCREEN_VISIBLE_AREA(0, 1759-1, 0, 1080-1) + + MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_sm510_state, display_decay_tick, attotime::from_msec(1)) MCFG_DEFAULT_LAYOUT(layout_svg) /* sound hardware */ @@ -1041,6 +1096,8 @@ static MACHINE_CONFIG_START( bx301 ) MCFG_SCREEN_REFRESH_RATE(50) MCFG_SCREEN_SIZE(1920, 529) MCFG_SCREEN_VISIBLE_AREA(0, 1920-1, 0, 529-1) + + MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_sm510_state, display_decay_tick, attotime::from_msec(1)) MCFG_DEFAULT_LAYOUT(layout_svg) /* sound hardware */ diff --git a/src/mame/drivers/k28.cpp b/src/mame/drivers/k28.cpp index 29c5ba93168..53316895754 100644 --- a/src/mame/drivers/k28.cpp +++ b/src/mame/drivers/k28.cpp @@ -51,7 +51,7 @@ public: required_ioport_array<7> m_inp_matrix; // display common - int m_display_wait; // led/lamp off-delay in microseconds (default 33ms) + int m_display_wait; // led/lamp off-delay in milliseconds (default 33ms) int m_display_maxy; // display matrix number of rows int m_display_maxx; // display matrix number of columns (max 31 for now) diff --git a/src/mame/includes/fidelbase.h b/src/mame/includes/fidelbase.h index cfadc5ed056..7d899b1ab76 100644 --- a/src/mame/includes/fidelbase.h +++ b/src/mame/includes/fidelbase.h @@ -54,7 +54,7 @@ public: DECLARE_DEVICE_IMAGE_LOAD_MEMBER(scc_cartridge); // display common - int m_display_wait; // led/lamp off-delay in microseconds (default 33ms) + int m_display_wait; // led/lamp off-delay in milliseconds (default 33ms) int m_display_maxy; // display matrix number of rows int m_display_maxx; // display matrix number of columns (max 31 for now) diff --git a/src/mame/includes/hh_tms1k.h b/src/mame/includes/hh_tms1k.h index 8b680278876..5ef40435f63 100644 --- a/src/mame/includes/hh_tms1k.h +++ b/src/mame/includes/hh_tms1k.h @@ -52,7 +52,7 @@ public: virtual DECLARE_WRITE_LINE_MEMBER(auto_power_off); // display common - int m_display_wait; // led/lamp off-delay in microseconds (default 33ms) + int m_display_wait; // led/lamp off-delay in milliseconds (default 33ms) int m_display_maxy; // display matrix number of rows int m_display_maxx; // display matrix number of columns (max 31 for now) diff --git a/src/mame/includes/hh_ucom4.h b/src/mame/includes/hh_ucom4.h index 3fbbdc3d63d..83fcaf0228c 100644 --- a/src/mame/includes/hh_ucom4.h +++ b/src/mame/includes/hh_ucom4.h @@ -44,7 +44,7 @@ public: DECLARE_INPUT_CHANGED_MEMBER(single_interrupt_line); // display common - int m_display_wait; // led/lamp off-delay in microseconds (default 33ms) + int m_display_wait; // led/lamp off-delay in milliseconds (default 33ms) int m_display_maxy; // display matrix number of rows int m_display_maxx; // display matrix number of columns (max 31 for now) diff --git a/src/mame/includes/novagbase.h b/src/mame/includes/novagbase.h index 18b6870e920..728066a9b96 100644 --- a/src/mame/includes/novagbase.h +++ b/src/mame/includes/novagbase.h @@ -47,7 +47,7 @@ public: u16 read_inputs(int columns); // display common - int m_display_wait; // led/lamp off-delay in microseconds (default 33ms) + int m_display_wait; // led/lamp off-delay in milliseconds (default 33ms) int m_display_maxy; // display matrix number of rows int m_display_maxx; // display matrix number of columns (max 31 for now) -- cgit v1.2.3