snova: added inputs and leds

This commit is contained in:
hap 2020-12-23 11:29:03 +01:00
parent c0dee3c856
commit cec7f7c683

View File

@ -9,19 +9,26 @@ Hardware notes:
- Hitachi HD63A03YP MCU @ 16MHz (4MHz internal)
- 32KB ROM(TC57256AD-12), 8KB RAM(CXK58648P-10L)
- LCD with 4 digits and custom segments, no LCD chip
- RS232 port for Novag Super System (like the one in sexpertc)
- buzzer, 16 LEDs, 8*8 chessboard buttons
TODO:
- everything
- if it turns out that the hardware is similar enough to supremo, merge drivers?
- NMI on power-off switch, it sets 0x14 bit 7 for standby power (see below)
- add nvram, MCU is missing standby power emulation
- add lcd screen
- internal artwork
- rs232 port isn't working?
- unmapped reads from 0x33/0x34
******************************************************************************/
#include "emu.h"
#include "bus/rs232/rs232.h"
#include "cpu/m6800/m6801.h"
#include "machine/sensorboard.h"
#include "sound/dac.h"
#include "video/pwm.h"
#include "speaker.h"
@ -35,7 +42,12 @@ public:
driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_board(*this, "board"),
m_dac(*this, "dac")
m_lcd_pwm(*this, "lcd_pwm"),
m_led_pwm(*this, "led_pwm"),
m_dac(*this, "dac"),
m_rs232(*this, "rs232"),
m_inputs(*this, "IN.%u", 0),
m_out_lcd(*this, "s%u.%u", 0U, 0U)
{ }
// machine configs
@ -48,13 +60,38 @@ private:
// devices/pointers
required_device<hd6303y_cpu_device> m_maincpu;
required_device<sensorboard_device> m_board;
required_device<pwm_display_device> m_lcd_pwm;
required_device<pwm_display_device> m_led_pwm;
required_device<dac_bit_interface> m_dac;
required_device<rs232_port_device> m_rs232;
required_ioport_array<2> m_inputs;
output_finder<4, 10> m_out_lcd;
void main_map(address_map &map);
void lcd_pwm_w(offs_t offset, u8 data);
void update_leds();
u8 p2_r();
void p2_w(u8 data);
void p5_w(u8 data);
void p6_w(u8 data);
bool m_lcd_strobe = false;
u8 m_inp_mux = 0;
u8 m_select = 0;
u8 m_led_data = 0;
};
void snova_state::machine_start()
{
m_out_lcd.resolve();
// register for savestates
save_item(NAME(m_lcd_strobe));
save_item(NAME(m_inp_mux));
save_item(NAME(m_select));
save_item(NAME(m_led_data));
}
@ -63,7 +100,76 @@ void snova_state::machine_start()
I/O
******************************************************************************/
// ...
// misc
void snova_state::lcd_pwm_w(offs_t offset, u8 data)
{
m_out_lcd[offset & 0x3f][offset >> 6] = data;
}
void snova_state::update_leds()
{
m_led_pwm->matrix(m_select >> 4 & 3, m_led_data);
}
// MCU ports
u8 snova_state::p2_r()
{
// P20: 4051 Z
u8 data = 0;
// read chessboard buttons
for (int i = 0; i < 8; i++)
if (BIT(m_led_data, i))
data |= BIT(m_board->read_file(i), m_inp_mux);
// read keypad buttons
for (int i = 0; i < 2; i++)
if (BIT(m_select, i + 6))
data |= BIT(m_inputs[i]->read(), m_inp_mux);
// P23: serial rx
return (data ^ 1) | (m_rs232->rxd_r() << 3);
}
void snova_state::p2_w(u8 data)
{
// P21: 4066 in/out to LCD
if (m_lcd_strobe && ~data & 2)
{
u16 lcd_data = (m_select << 2 & 0x300) | m_led_data;
m_lcd_pwm->matrix(m_select & 0xf, lcd_data);
}
m_lcd_strobe = bool(data & 2);
// P22: speaker out
m_dac->write(BIT(data, 2));
// P24: serial tx
m_rs232->write_txd(BIT(data, 4));
// P25-P27: 4051 S1-S2
// 4051 Y0-Y7: multiplexed inputs
m_inp_mux = data >> 5 & 7;
}
void snova_state::p5_w(u8 data)
{
// P50-P53: 4066 control to LCD
// P54,P55: led select
// P56,P57: keypad mux, lcd data
m_select = data ^ 0xf0;
update_leds();
}
void snova_state::p6_w(u8 data)
{
// P60-P67: led data, lcd data, chessboard mux
m_led_data = ~data;
update_leds();
}
@ -86,6 +192,25 @@ void snova_state::main_map(address_map &map)
******************************************************************************/
static INPUT_PORTS_START( snova )
PORT_START("IN.0")
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_1)
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_2)
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_3) // pawn
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_4) // knight
PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_5) // bishop
PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_6) // rook
PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_7) // queen
PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_8) // king
PORT_START("IN.1")
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_Q)
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_W)
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_E)
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_R)
PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_T)
PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_Y) // verify
PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_U)
PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_I)
INPUT_PORTS_END
@ -99,14 +224,26 @@ void snova_state::snova(machine_config &config)
/* basic machine hardware */
HD6303Y(config, m_maincpu, 16_MHz_XTAL);
m_maincpu->set_addrmap(AS_PROGRAM, &snova_state::main_map);
m_maincpu->in_p2_cb().set(FUNC(snova_state::p2_r));
m_maincpu->out_p2_cb().set(FUNC(snova_state::p2_w));
m_maincpu->out_p5_cb().set(FUNC(snova_state::p5_w));
m_maincpu->out_p6_cb().set(FUNC(snova_state::p6_w));
SENSORBOARD(config, m_board).set_type(sensorboard_device::BUTTONS);
m_board->init_cb().set(m_board, FUNC(sensorboard_device::preset_chess));
m_board->set_delay(attotime::from_msec(150));
m_board->set_delay(attotime::from_msec(350));
/* video hardware */
PWM_DISPLAY(config, m_lcd_pwm).set_size(4, 10);
m_lcd_pwm->output_x().set(FUNC(snova_state::lcd_pwm_w));
PWM_DISPLAY(config, m_led_pwm).set_size(2, 8);
/* sound hardware */
SPEAKER(config, "speaker").front_center();
DAC_1BIT(config, m_dac).add_route(ALL_OUTPUTS, "speaker", 0.25);
RS232_PORT(config, m_rs232, default_rs232_devices, nullptr);
}