ecbackg: preliminary board read and lcd outputs

This commit is contained in:
hap 2024-01-14 13:30:22 +01:00
parent 31639173da
commit 1ecd686c6f
2 changed files with 130 additions and 58 deletions

View File

@ -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);
}

View File

@ -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<hd6301y0_cpu_device> m_maincpu;
required_device<sensorboard_device> m_board;
required_device<pwm_display_device> m_display;
required_device<pwm_display_device> m_lcd_pwm;
required_device<pwm_display_device> m_led_pwm;
required_device<dac_bit_interface> m_dac;
required_ioport_array<5> m_inputs;
output_finder<2, 24> m_out_lcd;
bool m_power = false;
u8 m_inp_mux = 0;
void init_board(int state);
u32 m_lcd_segs = 0;
u8 m_lcd_com[2] = { };
// I/O handlers
void p1_w(u8 data);
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 <int N> void lcd_segs_w(u8 data);
void lcd_com_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)
{
}
u8 ecbackg_state::board_r(u8 row)
{
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
*******************************************************************************/
// power
INPUT_CHANGED_MEMBER(ecbackg_state::power_off)
{
if (newval)
m_power = false;
}
/*******************************************************************************
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
void ecbackg_state::p1_w(u8 data)
void ecbackg_state::standby(int state)
{
//printf("w1_%X ",data);
// 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()
{
}
template <int N>
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()
{
//printf("r2 ");
// 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