From 7603db3379772463f14c55525ce48b3c863917fb Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Thu, 22 Dec 2022 01:11:05 +1100 Subject: sega/sg1000.cpp: Converted Othello Multivision FG-2000 second controller to 9-pin port, and restructured code for fewer optional object finders. --- src/mame/sega/sg1000.cpp | 165 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 117 insertions(+), 48 deletions(-) diff --git a/src/mame/sega/sg1000.cpp b/src/mame/sega/sg1000.cpp index 75fa7444dd0..bd937a4adca 100644 --- a/src/mame/sega/sg1000.cpp +++ b/src/mame/sega/sg1000.cpp @@ -99,48 +99,87 @@ namespace { #define TMS9918A_TAG "tms9918a" #define RS232_TAG "rs232" -class sg1000_state : public driver_device +class sg1000_state_base : public driver_device { public: - sg1000_state(const machine_config &mconfig, device_type type, const char *tag) : + sg1000_state_base(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), m_maincpu(*this, Z80_TAG), m_ram(*this, RAM_TAG), m_rom(*this, Z80_TAG), m_cart(*this, "slot"), - m_sgexpslot(*this, "sgexp"), + m_sgexpslot(*this, "sgexp") + { } + +protected: + required_device m_maincpu; + required_device m_ram; + required_memory_region m_rom; + optional_device m_cart; + required_device m_sgexpslot; + + void sg1000_base(machine_config &config); +}; + +class sg1000_state : public sg1000_state_base +{ +public: + sg1000_state(const machine_config &mconfig, device_type type, const char *tag) : + sg1000_state_base(mconfig, type, tag), m_ctrlports(*this, "ctrl%u", 1U) { } void sg1000(machine_config &config); - void omv(machine_config &config); DECLARE_INPUT_CHANGED_MEMBER( trigger_nmi ); protected: - required_device m_maincpu; - required_device m_ram; - required_memory_region m_rom; - optional_device m_cart; - optional_device m_sgexpslot; - optional_device_array m_ctrlports; + required_device_array m_ctrlports; virtual void machine_start() override; uint8_t peripheral_r(offs_t offset); void peripheral_w(offs_t offset, uint8_t data); + void sg1000_map(address_map &map); + void sg1000_io_map(address_map &map); + void sc3000_map(address_map &map); + void sc3000_io_map(address_map &map); +}; + +class omv_state : public sg1000_state_base +{ +public: + omv_state(const machine_config &mconfig, device_type type, const char *tag) : + sg1000_state_base(mconfig, type, tag) + { } + + void omv1000(machine_config &config); + +private: uint8_t omv_r(offs_t offset); void omv_w(offs_t offset, uint8_t data); - void sg1000_base(machine_config &config); - - void omv_io_map(address_map &map); void omv_map(address_map &map); - void sc3000_io_map(address_map &map); - void sc3000_map(address_map &map); - void sg1000_io_map(address_map &map); - void sg1000_map(address_map &map); + void omv_io_map(address_map &map); +}; + +class omv2000_state : public omv_state +{ +public: + omv2000_state(const machine_config &mconfig, device_type type, const char *tag) : + omv_state(mconfig, type, tag), + m_ctrl2(*this, "ctrl2") + { } + + void omv2000(machine_config &config); + + template ioport_value ctrl2_r(); + +private: + required_device m_ctrl2; + + virtual void machine_start() override; }; class sc3000_state : public sg1000_state @@ -195,9 +234,9 @@ private: ***************************************************************************/ // TODO: not sure if the OMV bios actually detects the presence of a cart, -// or if the cart data simply overwrites the internal bios... +// or if the cart data simply overwrites the internal BIOS... // for the moment let assume the latter! -uint8_t sg1000_state::omv_r(offs_t offset) +uint8_t omv_state::omv_r(offs_t offset) { if (m_cart && m_cart->exists()) return m_cart->read_cart(offset); @@ -205,7 +244,7 @@ uint8_t sg1000_state::omv_r(offs_t offset) return m_rom->base()[offset]; } -void sg1000_state::omv_w(offs_t offset, uint8_t data) +void omv_state::omv_w(offs_t offset, uint8_t data) { if (m_cart && m_cart->exists()) m_cart->write_cart(offset, data); @@ -259,9 +298,9 @@ void sg1000_state::sg1000_io_map(address_map &map) ADDRESS_MAP( omv_map ) -------------------------------------------------*/ -void sg1000_state::omv_map(address_map &map) +void omv_state::omv_map(address_map &map) { - map(0x0000, 0xbfff).rw(FUNC(sg1000_state::omv_r), FUNC(sg1000_state::omv_w)); + map(0x0000, 0xbfff).rw(FUNC(omv_state::omv_r), FUNC(omv_state::omv_w)); map(0xc000, 0xc7ff).mirror(0x3800).ram(); } @@ -269,7 +308,7 @@ void sg1000_state::omv_map(address_map &map) ADDRESS_MAP( omv_io_map ) -------------------------------------------------*/ -void sg1000_state::omv_io_map(address_map &map) +void omv_state::omv_io_map(address_map &map) { map.global_mask(0xff); map(0x40, 0x40).mirror(0x3f).w(SN76489AN_TAG, FUNC(sn76489a_device::write)); @@ -354,6 +393,16 @@ INPUT_CHANGED_MEMBER( sg1000_state::trigger_nmi ) m_maincpu->set_input_line(INPUT_LINE_NMI, newval ? CLEAR_LINE : ASSERT_LINE); } +/*------------------------------------------------- + CUSTOM_INPUT_MEMBER( ctrl2_r ) +-------------------------------------------------*/ + +template +ioport_value omv2000_state::ctrl2_r() +{ + return m_ctrl2->in_r() >> Shift; +} + /*------------------------------------------------- INPUT_PORTS( sg1000 ) -------------------------------------------------*/ @@ -412,19 +461,13 @@ static INPUT_PORTS_START( omv1000 ) INPUT_PORTS_END static INPUT_PORTS_START( omv2000 ) - // FIXME: second controller attaches to a 9-pin port and should be a slot - PORT_INCLUDE( omv1000 ) PORT_MODIFY("C4") - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2) + PORT_BIT( 0xc0, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(omv2000_state, ctrl2_r<0>); PORT_MODIFY("C5") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) + PORT_BIT( 0x0f, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(omv2000_state, ctrl2_r<2>); PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNUSED ) INPUT_PORTS_END @@ -557,6 +600,8 @@ static void sf7000_floppies(device_slot_interface &device) void sg1000_state::machine_start() { + sg1000_state_base::machine_start(); + if (m_cart->get_type() == SEGA8_DAHJEE_TYPEA || m_cart->get_type() == SEGA8_DAHJEE_TYPEB) { m_maincpu->space(AS_PROGRAM).install_read_handler(0xc000, 0xffff, read8sm_delegate(*m_cart, FUNC(sega8_cart_slot_device::read_ram))); @@ -566,10 +611,20 @@ void sg1000_state::machine_start() if (m_cart) m_cart->save_ram(); - if (m_ctrlports[0]) - m_ctrlports[0]->out_w(0x3f, 0x40); - if (m_ctrlports[1]) - m_ctrlports[1]->out_w(0x3f, 0x40); + m_ctrlports[0]->out_w(0x3f, 0x40); + m_ctrlports[1]->out_w(0x3f, 0x40); +} + +/*------------------------------------------------- + MACHINE_START( omv2000 ) +-------------------------------------------------*/ + +void omv2000_state::machine_start() +{ + omv_state::machine_start(); + + // TODO: confirm wiring of pin 7 + m_ctrl2->out_w(0x3f, 0x40); } /*------------------------------------------------- @@ -578,6 +633,8 @@ void sg1000_state::machine_start() void sc3000_state::machine_start() { + sg1000_state_base::machine_start(); + if (m_cart && m_cart->exists() && (m_cart->get_type() == SEGA8_BASIC_L3 || m_cart->get_type() == SEGA8_MUSIC_EDITOR || m_cart->get_type() == SEGA8_DAHJEE_TYPEA || m_cart->get_type() == SEGA8_DAHJEE_TYPEB || m_cart->get_type() == SEGA8_MULTICART || m_cart->get_type() == SEGA8_MEGACART)) @@ -620,7 +677,7 @@ void sf7000_state::machine_reset() MACHINE DRIVERS ***************************************************************************/ -void sg1000_state::sg1000_base(machine_config &config) +void sg1000_state_base::sg1000_base(machine_config &config) { /* basic machine hardware */ Z80(config, m_maincpu, XTAL(10'738'635) / 3); // LH0080A @@ -682,15 +739,15 @@ void sg1000_state::sg1000(machine_config &config) } /*------------------------------------------------- - machine_config( omv ) + machine_config( omv1000 ) -------------------------------------------------*/ -void sg1000_state::omv(machine_config &config) +void omv_state::omv1000(machine_config &config) { sg1000_base(config); - m_maincpu->set_addrmap(AS_PROGRAM, &sg1000_state::omv_map); - m_maincpu->set_addrmap(AS_IO, &sg1000_state::omv_io_map); + m_maincpu->set_addrmap(AS_PROGRAM, &omv_state::omv_map); + m_maincpu->set_addrmap(AS_IO, &omv_state::omv_io_map); /* expansion slot */ SG1000_EXPANSION_SLOT(config, m_sgexpslot, sg1000_expansion_devices, nullptr, false); @@ -702,6 +759,18 @@ void sg1000_state::omv(machine_config &config) RAM(config, m_ram).set_default_size("2K"); } +/*------------------------------------------------- + machine_config( omv2000 ) +-------------------------------------------------*/ + +void omv2000_state::omv2000(machine_config &config) +{ + omv1000(config); + + /* controller ports */ + SMS_CONTROL_PORT(config, m_ctrl2, sms_control_port_passive_devices, SMS_CTRL_OPTION_JOYPAD); +} + /*------------------------------------------------- machine_config( sc3000 ) -------------------------------------------------*/ @@ -800,11 +869,11 @@ ROM_END SYSTEM DRIVERS ***************************************************************************/ -// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS -CONS( 1983, sg1000, 0, 0, sg1000, sg1000, sg1000_state, empty_init, "Sega", "SG-1000", MACHINE_SUPPORTS_SAVE ) -CONS( 1984, sg1000m2, sg1000, 0, sc3000, sc3000, sc3000_state, empty_init, "Sega", "SG-1000 II", MACHINE_SUPPORTS_SAVE ) -COMP( 1983, sc3000, 0, sg1000, sc3000, sc3000, sc3000_state, empty_init, "Sega", "SC-3000", MACHINE_SUPPORTS_SAVE ) -COMP( 1983, sc3000h, sc3000, 0, sc3000, sc3000, sc3000_state, empty_init, "Sega", "SC-3000H", MACHINE_SUPPORTS_SAVE ) -COMP( 1983, sf7000, sc3000, 0, sf7000, sf7000, sf7000_state, empty_init, "Sega", "SC-3000/Super Control Station SF-7000", MACHINE_SUPPORTS_SAVE ) -CONS( 1984, omv1000, sg1000, 0, omv, omv1000, sg1000_state, empty_init, "Tsukuda Original", "Othello Multivision FG-1000", MACHINE_SUPPORTS_SAVE ) -CONS( 1984, omv2000, sg1000, 0, omv, omv2000, sg1000_state, empty_init, "Tsukuda Original", "Othello Multivision FG-2000", MACHINE_SUPPORTS_SAVE ) +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +CONS( 1983, sg1000, 0, 0, sg1000, sg1000, sg1000_state, empty_init, "Sega", "SG-1000", MACHINE_SUPPORTS_SAVE ) +CONS( 1984, sg1000m2, sg1000, 0, sc3000, sc3000, sc3000_state, empty_init, "Sega", "SG-1000 II", MACHINE_SUPPORTS_SAVE ) +COMP( 1983, sc3000, 0, sg1000, sc3000, sc3000, sc3000_state, empty_init, "Sega", "SC-3000", MACHINE_SUPPORTS_SAVE ) +COMP( 1983, sc3000h, sc3000, 0, sc3000, sc3000, sc3000_state, empty_init, "Sega", "SC-3000H", MACHINE_SUPPORTS_SAVE ) +COMP( 1983, sf7000, sc3000, 0, sf7000, sf7000, sf7000_state, empty_init, "Sega", "SC-3000/Super Control Station SF-7000", MACHINE_SUPPORTS_SAVE ) +CONS( 1984, omv1000, sg1000, 0, omv1000, omv1000, omv_state, empty_init, "Tsukuda Original", "Othello Multivision FG-1000", MACHINE_SUPPORTS_SAVE ) +CONS( 1984, omv2000, sg1000, 0, omv2000, omv2000, omv2000_state, empty_init, "Tsukuda Original", "Othello Multivision FG-2000", MACHINE_SUPPORTS_SAVE ) -- cgit v1.2.3