diff options
Diffstat (limited to 'src/mame/drivers/nes_vt32.cpp')
-rw-r--r-- | src/mame/drivers/nes_vt32.cpp | 362 |
1 files changed, 362 insertions, 0 deletions
diff --git a/src/mame/drivers/nes_vt32.cpp b/src/mame/drivers/nes_vt32.cpp new file mode 100644 index 00000000000..1e1f52a97ae --- /dev/null +++ b/src/mame/drivers/nes_vt32.cpp @@ -0,0 +1,362 @@ +// license:BSD-3-Clause +// copyright-holders:David Haywood +/*************************************************************************** + + nes_vt32.cpp + + VT32 + + - new 444 palette mode + - backwards compatibility with mappers other than MMC3 + + ***************************************************************************/ + +#include "emu.h" +#include "machine/nes_vt369_vtunknown_soc.h" +#include "machine/nes_vt32_soc.h" + +class nes_vt32_base_state : public driver_device +{ +public: + nes_vt32_base_state(const machine_config& mconfig, device_type type, const char* tag) : + driver_device(mconfig, type, tag), + m_io0(*this, "IO0"), + m_io1(*this, "IO1"), + m_cartsel(*this, "CARTSEL"), + m_exin(*this, "EXTRAIN%u", 0U), + m_prgrom(*this, "mainrom") + { } + +protected: + virtual void machine_start() override; + virtual void machine_reset() override; + + virtual uint8_t in0_r(); + virtual uint8_t in1_r(); + virtual void in0_w(uint8_t data); + + void nes_vt32_map(address_map& map); + + optional_ioport m_io0; + optional_ioport m_io1; + + uint8_t m_latch0; + uint8_t m_latch1; + uint8_t m_previous_port0; + + optional_ioport m_cartsel; + optional_ioport_array<4> m_exin; + + /* Misc */ + uint32_t m_ahigh; // external banking bits + uint8_t m_4242; + uint8_t m_411c; + uint8_t m_411d; + + required_region_ptr<uint8_t> m_prgrom; + + uint8_t vt_rom_r(offs_t offset); + void vtspace_w(offs_t offset, uint8_t data); + + void configure_soc(nes_vt02_vt03_soc_device* soc); + + uint8_t upper_412c_r(); + uint8_t upper_412d_r(); + void upper_412c_w(uint8_t data); + +private: + /* Extra IO */ + template <uint8_t NUM> uint8_t extrain_r(); +}; + +class nes_vt32_state : public nes_vt32_base_state +{ +public: + nes_vt32_state(const machine_config& mconfig, device_type type, const char* tag) : + nes_vt32_base_state(mconfig, type, tag), + m_soc(*this, "soc") + { } + + void vt_external_space_map_32mbyte(address_map& map); + +protected: + required_device<nes_vt02_vt03_soc_device> m_soc; +}; + +class nes_vt32_unk_state : public nes_vt32_state +{ +public: + nes_vt32_unk_state(const machine_config& mconfig, device_type type, const char* tag) : + nes_vt32_state(mconfig, type, tag) + { } + + void nes_vt32_fp(machine_config& config); + void nes_vt32_32mb(machine_config& config); + void nes_vt32_4x16mb(machine_config& config); + + void nes_vt32_pal_32mb(machine_config& config); + +private: + uint8_t vt_rom_banked_r(offs_t offset); + void vt_external_space_map_fp_2x32mbyte(address_map& map); + + uint8_t fcpocket_412d_r(); + void fcpocket_412c_w(uint8_t data); +}; + +uint8_t nes_vt32_base_state::vt_rom_r(offs_t offset) +{ + return m_prgrom[offset]; +} + +void nes_vt32_base_state::vtspace_w(offs_t offset, uint8_t data) +{ + logerror("%s: vtspace_w %08x : %02x", machine().describe_context(), offset, data); +} + +// VTxx can address 25-bit address space (32MB of ROM) so use maps with mirroring in depending on ROM size +void nes_vt32_state::vt_external_space_map_32mbyte(address_map &map) +{ + map(0x0000000, 0x1ffffff).r(FUNC(nes_vt32_state::vt_rom_r)); +} + + +uint8_t nes_vt32_unk_state::vt_rom_banked_r(offs_t offset) +{ + return m_prgrom[m_ahigh | offset]; +} + +void nes_vt32_unk_state::vt_external_space_map_fp_2x32mbyte(address_map &map) +{ + map(0x0000000, 0x1ffffff).r(FUNC(nes_vt32_unk_state::vt_rom_banked_r)); +} + + +template <uint8_t NUM> uint8_t nes_vt32_base_state::extrain_r() +{ + if (m_exin[NUM]) + return m_exin[NUM]->read(); + else + { + logerror("%s: extrain_r (port %d) (not hooked up)\n", NUM, machine().describe_context()); + } + return 0x00; +} + + +/* Standard I/O handlers (NES Controller clone) */ + +uint8_t nes_vt32_base_state::in0_r() +{ + //logerror("%s: in0_r\n", machine().describe_context()); + uint8_t ret = 0x40; + ret |= m_latch0 & 1; + m_latch0 >>= 1; + return ret; +} + +uint8_t nes_vt32_base_state::in1_r() +{ + //logerror("%s: in1_r\n", machine().describe_context()); + uint8_t ret = 0x40; + ret |= m_latch1 & 1; + m_latch1 >>= 1; + return ret; +} + +void nes_vt32_base_state::in0_w(uint8_t data) +{ + //logerror("%s: in0_w %02x\n", machine().describe_context(), data); + if ((data & 0x01) != (m_previous_port0 & 0x01)) + { + if (data & 0x01) + { + m_latch0 = m_io0->read(); + m_latch1 = m_io1->read(); + } + } + + m_previous_port0 = data; +} + + +void nes_vt32_base_state::machine_start() +{ + m_latch0 = 0; + m_latch1 = 0; + m_previous_port0 = 0; + + m_ahigh = 0; + m_4242 = 0; + m_411c = 0; + m_411d = 0; + + save_item(NAME(m_latch0)); + save_item(NAME(m_latch1)); + save_item(NAME(m_previous_port0)); + + save_item(NAME(m_ahigh)); + save_item(NAME(m_4242)); + save_item(NAME(m_411c)); + save_item(NAME(m_411d)); +} + +void nes_vt32_base_state::machine_reset() +{ + +} + +void nes_vt32_base_state::configure_soc(nes_vt02_vt03_soc_device* soc) +{ + soc->set_addrmap(AS_PROGRAM, &nes_vt32_state::vt_external_space_map_32mbyte); + soc->read_0_callback().set(FUNC(nes_vt32_base_state::in0_r)); + soc->read_1_callback().set(FUNC(nes_vt32_base_state::in1_r)); + soc->write_0_callback().set(FUNC(nes_vt32_base_state::in0_w)); + + soc->extra_read_0_callback().set(FUNC(nes_vt32_base_state::extrain_r<0>)); + soc->extra_read_1_callback().set(FUNC(nes_vt32_base_state::extrain_r<1>)); + soc->extra_read_2_callback().set(FUNC(nes_vt32_base_state::extrain_r<2>)); + soc->extra_read_3_callback().set(FUNC(nes_vt32_base_state::extrain_r<3>)); +} + +uint8_t nes_vt32_base_state::upper_412c_r() +{ + logerror("%s: upper_412c_r\n", machine().describe_context()); + return 0x00; +} + +uint8_t nes_vt32_base_state::upper_412d_r() +{ + logerror("%s: upper_412d_r\n", machine().describe_context()); + return 0x00; +} + +void nes_vt32_base_state::upper_412c_w(uint8_t data) +{ + logerror("%s: upper_412c_w %02x\n", machine().describe_context(), data); +} + + + + +static INPUT_PORTS_START( nes_vt32 ) + PORT_START("IO0") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_PLAYER(1) PORT_NAME("A") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_NAME("B") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_PLAYER(1) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_START ) PORT_PLAYER(1) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_PLAYER(1) PORT_8WAY + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1) PORT_8WAY + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1) PORT_8WAY + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1) PORT_8WAY + + PORT_START("IO1") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_PLAYER(2) PORT_NAME("A") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_NAME("B") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_PLAYER(2) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_START ) PORT_PLAYER(2) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_PLAYER(2) PORT_8WAY + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2) PORT_8WAY + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2) PORT_8WAY + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2) PORT_8WAY +INPUT_PORTS_END + +uint8_t nes_vt32_unk_state::fcpocket_412d_r() +{ + if (m_cartsel) + return m_cartsel->read(); + else + return 0; +} + +void nes_vt32_unk_state::fcpocket_412c_w(uint8_t data) +{ + // fcpocket + logerror("%s: vtfp_412c_extbank_w %02x\n", machine().describe_context(), data); + m_ahigh = (data & 0x01) ? (1 << 25) : 0x0; +} + +void nes_vt32_unk_state::nes_vt32_fp(machine_config &config) +{ + /* basic machine hardware */ + NES_VT32_SOC(config, m_soc, NTSC_APU_CLOCK); + configure_soc(m_soc); + + dynamic_cast<nes_vt09_soc_device&>(*m_soc).upper_read_412c_callback().set(FUNC(nes_vt32_unk_state::upper_412c_r)); + dynamic_cast<nes_vt09_soc_device&>(*m_soc).upper_read_412d_callback().set(FUNC(nes_vt32_unk_state::upper_412d_r)); + dynamic_cast<nes_vt09_soc_device&>(*m_soc).upper_write_412c_callback().set(FUNC(nes_vt32_unk_state::upper_412c_w)); + + m_soc->set_default_palette_mode(PAL_MODE_NEW_RGB12); + m_soc->force_bad_dma(); +} + +void nes_vt32_unk_state::nes_vt32_pal_32mb(machine_config& config) +{ + /* basic machine hardware */ + NES_VT32_SOC_PAL(config, m_soc, NTSC_APU_CLOCK); // TODO, proper clocks etc. for PAL + configure_soc(m_soc); + + dynamic_cast<nes_vt09_soc_device&>(*m_soc).upper_read_412c_callback().set(FUNC(nes_vt32_unk_state::upper_412c_r)); + dynamic_cast<nes_vt09_soc_device&>(*m_soc).upper_read_412d_callback().set(FUNC(nes_vt32_unk_state::upper_412d_r)); + dynamic_cast<nes_vt09_soc_device&>(*m_soc).upper_write_412c_callback().set(FUNC(nes_vt32_unk_state::upper_412c_w)); + + m_soc->set_default_palette_mode(PAL_MODE_NEW_RGB12); + m_soc->force_bad_dma(); + + m_soc->set_addrmap(AS_PROGRAM, &nes_vt32_unk_state::vt_external_space_map_32mbyte); +} + +void nes_vt32_unk_state::nes_vt32_4x16mb(machine_config& config) +{ + nes_vt32_fp(config); + m_soc->set_addrmap(AS_PROGRAM, &nes_vt32_unk_state::vt_external_space_map_fp_2x32mbyte); + + dynamic_cast<nes_vt09_soc_device&>(*m_soc).upper_write_412c_callback().set(FUNC(nes_vt32_unk_state::fcpocket_412c_w)); + dynamic_cast<nes_vt09_soc_device&>(*m_soc).upper_read_412d_callback().set(FUNC(nes_vt32_unk_state::fcpocket_412d_r)); +} + +void nes_vt32_unk_state::nes_vt32_32mb(machine_config& config) +{ + nes_vt32_fp(config); + m_soc->set_addrmap(AS_PROGRAM, &nes_vt32_unk_state::vt_external_space_map_32mbyte); +} + + +static INPUT_PORTS_START( nes_vt32_fp ) + PORT_INCLUDE(nes_vt32) + + PORT_START("CARTSEL") + PORT_DIPNAME( 0x06, 0x00, "Cartridge Select" ) PORT_CODE(KEYCODE_3) PORT_TOGGLE + PORT_DIPSETTING( 0x00, "472-in-1" ) + PORT_DIPSETTING( 0x06, "128-in-1" ) +INPUT_PORTS_END + + +ROM_START( dgun2573 ) // this one lacked a DreamGear logo but was otherwise physically identical, is it a clone product or did DreamGear drop the logo in favor of just using the 'My Arcade' brand? + ROM_REGION( 0x2000000, "mainrom", 0 ) + ROM_LOAD( "myarcadegamerportable_s29gl256p10tfi01_0001227e.bin", 0x00000, 0x2000000, CRC(8f8c8da7) SHA1(76a18458922e39abe1982f05f184babb5e65acf2) ) +ROM_END + +ROM_START( dgun2573a ) + ROM_REGION( 0x2000000, "mainrom", 0 ) + ROM_LOAD( "myarcadegamerportabledreamgear_s29gl256p10tfi01_0001227e.bin", 0x00000, 0x2000000, CRC(928c41ad) SHA1(c0119a13a47a5b784d0b834d1451973ff0b4a84f) ) +ROM_END + +ROM_START( rminitv ) + ROM_REGION( 0x2000000, "mainrom", 0 ) + ROM_LOAD( "29gl256.bin", 0x00000, 0x2000000, CRC(cb4048d4) SHA1(9877ce5716d13f8498abfc1cbfaefa9426205d3e) ) +ROM_END + +ROM_START( fcpocket ) + ROM_REGION( 0x8000000, "mainrom", 0 ) + ROM_LOAD( "s29gl01gp.bin", 0x00000, 0x8000000, CRC(8703b18a) SHA1(07943443294e80ca93f83181c8bdbf950b87c52f) ) // 2nd half = 0x00 (so 64MByte of content) +ROM_END + + +CONS( 2015, dgun2573, 0, 0, nes_vt32_32mb, nes_vt32, nes_vt32_unk_state, empty_init, "dreamGEAR", "My Arcade Gamer V Portable Gaming System (DGUN-2573) (set 1, newer)", MACHINE_WRONG_COLORS | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) +CONS( 2015, dgun2573a, dgun2573, 0, nes_vt32_32mb, nes_vt32, nes_vt32_unk_state, empty_init, "dreamGEAR", "My Arcade Gamer V Portable Gaming System (DGUN-2573) (set 2, older)", MACHINE_WRONG_COLORS | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) // some menu graphics haven't been updated to reflect 'Panda' theme to the sports games + +CONS( 2015, rminitv, 0, 0, nes_vt32_pal_32mb, nes_vt32, nes_vt32_unk_state, empty_init, "Orb Gaming", "Retro 'Mini TV' Console 300-in-1", MACHINE_IMPERFECT_GRAPHICS ) // single 32Mbyte bank! + +// Use DIP switch to select console or cartridge, as cartridge is fake and just toggles a GPIO +CONS( 2016, fcpocket, 0, 0, nes_vt32_4x16mb, nes_vt32_fp, nes_vt32_unk_state, empty_init, "<unknown>", "FC Pocket 600 in 1", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) // has external banking (2x 32mbyte banks) |