From 1ecd686c6fef73b53bdc81f9cdf764e57589c9b1 Mon Sep 17 00:00:00 2001 From: hap Date: Sun, 14 Jan 2024 13:30:22 +0100 Subject: ecbackg: preliminary board read and lcd outputs --- src/mame/fidelity/dames.cpp | 6 +- src/mame/saitek/ecbackg.cpp | 174 +++++++++++++++++++++++++++++++------------- 2 files changed, 126 insertions(+), 54 deletions(-) diff --git a/src/mame/fidelity/dames.cpp b/src/mame/fidelity/dames.cpp index 743461d808e..e69d859746b 100644 --- a/src/mame/fidelity/dames.cpp +++ b/src/mame/fidelity/dames.cpp @@ -104,8 +104,8 @@ u8 dsc_state::read_board_row(u8 row) { u8 data = 0; - // inputs to sensorboard translation table - static const u8 lut_i2sb[64] = + // inputs to sensorboard translation table (0xff is invalid) + static const u8 lut_board[64] = { 0x00, 0x50, 0x60, 0x70, 0x40, 0x30, 0x20, 0x10, 0x01, 0x51, 0x61, 0x71, 0x41, 0x31, 0x21, 0x11, @@ -119,7 +119,7 @@ u8 dsc_state::read_board_row(u8 row) for (int i = 0; i < 8; i++) { - u8 pos = lut_i2sb[row * 8 + i]; + u8 pos = lut_board[row * 8 + i]; data = data << 1 | m_board->read_sensor(pos & 0xf, pos >> 4); } diff --git a/src/mame/saitek/ecbackg.cpp b/src/mame/saitek/ecbackg.cpp index 1067b7166c1..4c0d3a0b054 100644 --- a/src/mame/saitek/ecbackg.cpp +++ b/src/mame/saitek/ecbackg.cpp @@ -16,7 +16,7 @@ Hardware notes: TODO: - if/when MAME supports an exit callback, hook up power-off switch to that -- sensorboard, lcd, internal artwork +- finish sensorboard handling, finish lcd(svg), internal artwork *******************************************************************************/ @@ -41,9 +41,11 @@ public: driver_device(mconfig, type, tag), m_maincpu(*this, "maincpu"), m_board(*this, "board"), - m_display(*this, "display"), + m_lcd_pwm(*this, "lcd_pwm"), + m_led_pwm(*this, "led_pwm"), m_dac(*this, "dac"), - m_inputs(*this, "IN.%u", 0) + m_inputs(*this, "IN.%u", 0), + m_out_lcd(*this, "s%u.%u", 0U, 0U) { } void ecbackg(machine_config &config); @@ -58,95 +60,164 @@ private: // devices/pointers required_device m_maincpu; required_device m_board; - required_device m_display; + required_device m_lcd_pwm; + required_device m_led_pwm; required_device m_dac; required_ioport_array<5> m_inputs; + output_finder<2, 24> m_out_lcd; bool m_power = false; u8 m_inp_mux = 0; + u32 m_lcd_segs = 0; + u8 m_lcd_com[2] = { }; + // I/O handlers void init_board(int state); + u8 board_r(u8 row); + + void standby(int state); + + void lcd_pwm_w(offs_t offset, u8 data); + void update_lcd(); + template void lcd_segs_w(u8 data); + void lcd_com_w(u8 data); - // I/O handlers - void p1_w(u8 data); u8 p2_r(); void p2_w(u8 data); - void p3_w(u8 data); - void p4_w(u8 data); u8 p5_r(); void p6_w(u8 data); - void p7_w(u8 data); }; void ecbackg_state::machine_start() { + m_out_lcd.resolve(); + // register for savestates + save_item(NAME(m_power)); save_item(NAME(m_inp_mux)); + save_item(NAME(m_lcd_segs)); + save_item(NAME(m_lcd_com)); } + + +/******************************************************************************* + Sensorboard +*******************************************************************************/ + void ecbackg_state::init_board(int state) { } -INPUT_CHANGED_MEMBER(ecbackg_state::power_off) +u8 ecbackg_state::board_r(u8 row) { - if (newval) - m_power = false; + u8 data = 0; + + // inputs to sensorboard translation table (0xff is invalid) + static const u8 lut_board[4*7] = + { + 0xff, 0x1b, 0x19, 0x17, 0x07, 0x09, 0x0b, + 0x0c, 0x1a, 0x18, 0x16, 0x06, 0x08, 0x0a, + 0x1c, 0x15, 0x13, 0x11, 0x01, 0x03, 0x05, + 0xff, 0x14, 0x12, 0x10, 0x00, 0x02, 0x04 + }; + + for (int i = 0; i < 7; i++) + { + const u8 pos = lut_board[row * 7 + i]; + const u8 x = pos & 0xf; + const u8 y = pos >> 4; + + // 5 rows per button + int state = 0; + for (int j = 0; j < 5; j++) + state |= m_board->read_sensor(x, y * 5 + j); + + data = data << 1 | state; + } + + return data; } + /******************************************************************************* I/O *******************************************************************************/ -//[:maincpu] Port 5 Data Direction Register: 00 -//[:maincpu] Port 6 Data Direction Register: ff -//[:maincpu] Port 2 Data Direction Register: 2f -//[:maincpu] Port 1 Data Direction Register: ff -//[:maincpu] Port 3 Data Direction Register: ff -//[:maincpu] Port 4 Data Direction Register: ff +// power -void ecbackg_state::p1_w(u8 data) +INPUT_CHANGED_MEMBER(ecbackg_state::power_off) { - //printf("w1_%X ",data); + if (newval) + m_power = false; } -u8 ecbackg_state::p2_r() +void ecbackg_state::standby(int state) +{ + // clear display + if (state) + { + m_lcd_pwm->clear(); + m_led_pwm->clear(); + } +} + + +// LCD + +void ecbackg_state::lcd_pwm_w(offs_t offset, u8 data) +{ + m_out_lcd[offset & 0x3f][offset >> 6] = data; +} + +void ecbackg_state::update_lcd() { - //printf("r2 "); +} +template +void ecbackg_state::lcd_segs_w(u8 data) +{ + // P1x, P3x, P4x: LCD segments + const u8 shift = 8 * N; + const u32 mask = 0xff << shift; + m_lcd_segs = (m_lcd_segs & ~mask) | (data << shift); + update_lcd(); +} + +void ecbackg_state::lcd_com_w(u8 data) +{ + // P70/P71,P72/P73: LCD common (voltage level) + m_lcd_com[0] = population_count_32(data & 3); + m_lcd_com[1] = population_count_32(data & 0xc); + update_lcd(); +} + + +// misc + +u8 ecbackg_state::p2_r() +{ // P27: power switch state u8 data = m_power ? 0 : 0x80; - // P24: P57 + // P24: P57 (unused) data |= ~p5_r() >> 3 & 0x10; return ~data; } void ecbackg_state::p2_w(u8 data) { - //printf("w2_%X ",data); - // P20-P22: led select - m_display->write_my(~data & 7); + m_led_pwm->write_my(data & 7); // P23: speaker out m_dac->write(BIT(data, 3)); } -void ecbackg_state::p3_w(u8 data) -{ - //printf("w3_%X ",data); -} - -void ecbackg_state::p4_w(u8 data) -{ - //printf("w4_%X ",data); -} - u8 ecbackg_state::p5_r() { - // P50-P57: multiplexed inputs + // P50-P56: multiplexed inputs u8 data = 0; // read buttons @@ -154,6 +225,11 @@ u8 ecbackg_state::p5_r() if (BIT(bitswap<5>(m_inp_mux,6,5,4,3,0), i)) data |= m_inputs[i]->read(); + // read board + for (int i = 0; i < 4; i++) + if (BIT(m_inp_mux, i)) + data |= board_r(i); + return ~data; } @@ -161,14 +237,7 @@ void ecbackg_state::p6_w(u8 data) { // P60-P67: input mux, led data m_inp_mux = ~data; - m_display->write_mx(~data); - - //printf("w6_%X ",data); -} - -void ecbackg_state::p7_w(u8 data) -{ - //printf("w7_%X ",data); + m_led_pwm->write_mx(~data); } @@ -221,15 +290,15 @@ void ecbackg_state::ecbackg(machine_config &config) HD6301Y0(config, m_maincpu, 4'000'000); // approximation m_maincpu->nvram_enable_backup(true); m_maincpu->standby_cb().set(m_maincpu, FUNC(hd6301y0_cpu_device::nvram_set_battery)); - m_maincpu->standby_cb().append([this](int state) { if (state) m_display->clear(); }); - m_maincpu->out_p1_cb().set(FUNC(ecbackg_state::p1_w)); + m_maincpu->standby_cb().append(FUNC(ecbackg_state::standby)); + m_maincpu->out_p1_cb().set(FUNC(ecbackg_state::lcd_segs_w<0>)); m_maincpu->in_p2_cb().set(FUNC(ecbackg_state::p2_r)); m_maincpu->out_p2_cb().set(FUNC(ecbackg_state::p2_w)); - m_maincpu->out_p3_cb().set(FUNC(ecbackg_state::p3_w)); - m_maincpu->out_p4_cb().set(FUNC(ecbackg_state::p4_w)); + m_maincpu->out_p3_cb().set(FUNC(ecbackg_state::lcd_segs_w<1>)); + m_maincpu->out_p4_cb().set(FUNC(ecbackg_state::lcd_segs_w<2>)); m_maincpu->in_p5_cb().set(FUNC(ecbackg_state::p5_r)); m_maincpu->out_p6_cb().set(FUNC(ecbackg_state::p6_w)); - m_maincpu->out_p7_cb().set(FUNC(ecbackg_state::p7_w)); + m_maincpu->out_p7_cb().set(FUNC(ecbackg_state::lcd_com_w)); SENSORBOARD(config, m_board).set_type(sensorboard_device::BUTTONS); m_board->init_cb().set(FUNC(ecbackg_state::init_board)); @@ -239,7 +308,10 @@ void ecbackg_state::ecbackg(machine_config &config) m_board->set_nvram_enable(true); // video hardware - PWM_DISPLAY(config, m_display).set_size(3, 8); + PWM_DISPLAY(config, m_lcd_pwm).set_size(2, 24); + m_lcd_pwm->output_x().set(FUNC(ecbackg_state::lcd_pwm_w)); + + PWM_DISPLAY(config, m_led_pwm).set_size(3, 8); //config.set_default_layout(layout_saitek_ecbackg); // sound hardware -- cgit v1.2.3