summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author hap <happppp@users.noreply.github.com>2020-12-23 11:29:03 +0100
committer hap <happppp@users.noreply.github.com>2020-12-23 11:29:15 +0100
commitcec7f7c683c923f734ac765e6058ffb66f86b672 (patch)
tree5d573e5491db644a640180a453f1ab0db4d4ff12
parentc0dee3c85674f12183d381d75b4174b0399dfbe5 (diff)
snova: added inputs and leds
-rw-r--r--src/mame/drivers/novag_snova.cpp147
1 files changed, 142 insertions, 5 deletions
diff --git a/src/mame/drivers/novag_snova.cpp b/src/mame/drivers/novag_snova.cpp
index 28bc437972f..efb8141f7d0 100644
--- a/src/mame/drivers/novag_snova.cpp
+++ b/src/mame/drivers/novag_snova.cpp
@@ -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);
}