mirror of
https://github.com/holub/mame
synced 2025-07-01 16:19:38 +03:00
snova: added inputs and leds
This commit is contained in:
parent
c0dee3c856
commit
cec7f7c683
@ -9,19 +9,26 @@ Hardware notes:
|
|||||||
- Hitachi HD63A03YP MCU @ 16MHz (4MHz internal)
|
- Hitachi HD63A03YP MCU @ 16MHz (4MHz internal)
|
||||||
- 32KB ROM(TC57256AD-12), 8KB RAM(CXK58648P-10L)
|
- 32KB ROM(TC57256AD-12), 8KB RAM(CXK58648P-10L)
|
||||||
- LCD with 4 digits and custom segments, no LCD chip
|
- 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
|
- buzzer, 16 LEDs, 8*8 chessboard buttons
|
||||||
|
|
||||||
TODO:
|
TODO:
|
||||||
- everything
|
- NMI on power-off switch, it sets 0x14 bit 7 for standby power (see below)
|
||||||
- if it turns out that the hardware is similar enough to supremo, merge drivers?
|
- 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 "emu.h"
|
||||||
|
|
||||||
|
#include "bus/rs232/rs232.h"
|
||||||
#include "cpu/m6800/m6801.h"
|
#include "cpu/m6800/m6801.h"
|
||||||
#include "machine/sensorboard.h"
|
#include "machine/sensorboard.h"
|
||||||
#include "sound/dac.h"
|
#include "sound/dac.h"
|
||||||
|
#include "video/pwm.h"
|
||||||
|
|
||||||
#include "speaker.h"
|
#include "speaker.h"
|
||||||
|
|
||||||
@ -35,7 +42,12 @@ public:
|
|||||||
driver_device(mconfig, type, tag),
|
driver_device(mconfig, type, tag),
|
||||||
m_maincpu(*this, "maincpu"),
|
m_maincpu(*this, "maincpu"),
|
||||||
m_board(*this, "board"),
|
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
|
// machine configs
|
||||||
@ -48,13 +60,38 @@ private:
|
|||||||
// devices/pointers
|
// devices/pointers
|
||||||
required_device<hd6303y_cpu_device> m_maincpu;
|
required_device<hd6303y_cpu_device> m_maincpu;
|
||||||
required_device<sensorboard_device> m_board;
|
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<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 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()
|
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
|
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 )
|
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
|
INPUT_PORTS_END
|
||||||
|
|
||||||
|
|
||||||
@ -99,14 +224,26 @@ void snova_state::snova(machine_config &config)
|
|||||||
/* basic machine hardware */
|
/* basic machine hardware */
|
||||||
HD6303Y(config, m_maincpu, 16_MHz_XTAL);
|
HD6303Y(config, m_maincpu, 16_MHz_XTAL);
|
||||||
m_maincpu->set_addrmap(AS_PROGRAM, &snova_state::main_map);
|
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);
|
SENSORBOARD(config, m_board).set_type(sensorboard_device::BUTTONS);
|
||||||
m_board->init_cb().set(m_board, FUNC(sensorboard_device::preset_chess));
|
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 */
|
/* sound hardware */
|
||||||
SPEAKER(config, "speaker").front_center();
|
SPEAKER(config, "speaker").front_center();
|
||||||
DAC_1BIT(config, m_dac).add_route(ALL_OUTPUTS, "speaker", 0.25);
|
DAC_1BIT(config, m_dac).add_route(ALL_OUTPUTS, "speaker", 0.25);
|
||||||
|
|
||||||
|
RS232_PORT(config, m_rs232, default_rs232_devices, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user