From e6b5b5d536e6168e99b8dd79df219cc92f561301 Mon Sep 17 00:00:00 2001 From: David Haywood <28625134+DavidHaywood@users.noreply.github.com> Date: Mon, 23 Mar 2020 15:33:56 +0000 Subject: Plug and Play work (#6481) * trkfldch.cpp: support sprite pixel doubling (nw) * new WORKING machine ----- Dance 2000 / Hot 2000 (Jin Bao TV Dancing Carpet, SY-2000-04) [Sean Riddle, David Haywood] * use correct PPU type (nw) * new NOT WORKING ----- Carol Vorderman's Sudoku Plug & Play TV Game (All in 1 / Play Vision) [Sean Riddle, David Haywood] --- src/mame/drivers/elan_eu3a05.cpp | 45 ++++++++- src/mame/drivers/nes_clone.cpp | 204 +++++++++++++++++++++++++++++++++++++-- src/mame/drivers/trkfldch.cpp | 10 +- src/mame/mame.lst | 4 +- 4 files changed, 247 insertions(+), 16 deletions(-) diff --git a/src/mame/drivers/elan_eu3a05.cpp b/src/mame/drivers/elan_eu3a05.cpp index 8ffce8019a6..a23e03f4940 100644 --- a/src/mame/drivers/elan_eu3a05.cpp +++ b/src/mame/drivers/elan_eu3a05.cpp @@ -242,8 +242,11 @@ public: void airblsjs(machine_config& config); void elan_sudoku(machine_config &config); + void elan_sudoku_pal(machine_config &config); void elan_pvmilfin(machine_config &config); + void init_sudelan(); + void init_sudelan3(); protected: // driver_device overrides @@ -775,6 +778,13 @@ void elan_eu3a05_state::elan_sudoku(machine_config& config) m_sys->set_alt_timer(); // for Carl Edwards' } +void elan_eu3a05_state::elan_sudoku_pal(machine_config& config) +{ + elan_sudoku(config); + m_sys->set_pal(); // TODO: also set PAL clocks + m_screen->set_refresh_hz(50); +} + void elan_eu3a05_state::elan_pvmilfin(machine_config& config) { elan_eu3a05(config); @@ -792,6 +802,9 @@ void elan_eu3a05_state::airblsjs(machine_config& config) m_sys->set_pal(); // TODO: also set PAL clocks } + + + ROM_START( rad_tetr ) ROM_REGION( 0x400000, "maincpu", ROMREGION_ERASE00 ) ROM_LOAD( "tetrisrom.bin", 0x000000, 0x100000, CRC(40538e08) SHA1(1aef9a2c678e39243eab8d910bb7f9f47bae0aee) ) @@ -813,7 +826,7 @@ ROM_START( airblsjs ) ROM_LOAD( "airblsjs.bin", 0x000000, 0x400000, BAD_DUMP CRC(d10a6a84) SHA1(fa65f06e7da229006ddaffb245eef2cc4f90a66d) ) // ROM probably ok, but needs verification pass ROM_END -ROM_START( sudoelan ) +ROM_START( sudelan3 ) ROM_REGION( 0x400000, "maincpu", ROMREGION_ERASE00 ) ROM_LOAD( "sudoku.bin", 0x00000, 0x100000, CRC(c2596173) SHA1(cc74932648b577b735151014e8c04ed778e11704) ) ROM_RELOAD(0x100000,0x100000) @@ -821,6 +834,14 @@ ROM_START( sudoelan ) ROM_RELOAD(0x300000,0x100000) ROM_END +ROM_START( sudelan ) + ROM_REGION( 0x400000, "maincpu", ROMREGION_ERASE00 ) + ROM_LOAD( "klaussudoku.bin", 0x00000, 0x200000, CRC(afd2b06a) SHA1(21db956fb40b2e3d61fc2bac89000cf7f61fe99e) ) + ROM_RELOAD(0x200000,0x200000) +ROM_END + + + ROM_START( carlecfg ) ROM_REGION( 0x400000, "maincpu", ROMREGION_ERASE00 ) ROM_LOAD( "carledwardsracing.bin", 0x00000, 0x100000, CRC(920f633e) SHA1(8460b77b9635a2484edab1111f35bbda74eb68e4) ) @@ -845,6 +866,24 @@ ROM_START( buzztime ) ROM_END +void elan_eu3a05_state::init_sudelan3() +{ + // skip infinite loop (why is this needed? does it think we've soft shutdown?) + uint8_t* ROM = memregion("maincpu")->base(); + ROM[0x0fcc] = 0xea; + ROM[0x0fcd] = 0xea; + ROM[0x0fce] = 0xea; +} + +void elan_eu3a05_state::init_sudelan() +{ + // avoid jump to infinite loop (why is this needed? does it think we've soft shutdown?) + uint8_t* ROM = memregion("maincpu")->base(); + ROM[0xd0f] = 0xea; + ROM[0xd10] = 0xea; + ROM[0xd11] = 0xea; +} + CONS( 2004, rad_sinv, 0, 0, elan_eu3a05, rad_sinv, elan_eu3a05_state, empty_init, "Radica (licensed from Taito)", "Space Invaders [Lunar Rescue, Colony 7, Qix, Phoenix] (Radica, Arcade Legends TV Game)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) // "5 Taito games in 1" CONS( 2004, rad_tetr, 0, 0, elan_eu3a05, rad_tetr, elan_eu3a05_state, empty_init, "Radica (licensed from Elorg / The Tetris Company)", "Tetris (Radica, Arcade Legends TV Game)", MACHINE_NOT_WORKING ) // "5 Tetris games in 1" @@ -856,7 +895,9 @@ CONS( 2004, buzztime, 0, 0, elan_buzztime, sudoku, elan_eu3a05_buzztime_state, e // Below are probably not EU3A05 but use similar modes (possibly EU3A13?) -CONS( 2006, sudoelan, 0, 0, elan_sudoku, sudoku, elan_eu3a05_state, empty_init, "Senario / All in 1 Products Ltd", "Ultimate Sudoku TV Edition 3-in-1", MACHINE_NOT_WORKING ) +CONS( 2006, sudelan3, 0, 0, elan_sudoku, sudoku, elan_eu3a05_state, init_sudelan3, "All in 1 Products Ltd / Senario", "Ultimate Sudoku TV Edition 3-in-1 (All in 1 / Senario)", MACHINE_NOT_WORKING ) +// Senario also distributed this version in the US without the '3 in 1' text on the box, ROM has not been verified to match +CONS( 2005, sudelan, 0, 0, elan_sudoku_pal, sudoku, elan_eu3a05_state, init_sudelan, "All in 1 Products Ltd / Play Vision", "Carol Vorderman's Sudoku Plug & Play TV Game (All in 1 / Play Vision)", MACHINE_NOT_WORKING ) CONS( 200?, carlecfg, 0, 0, elan_sudoku, carlecfg, elan_eu3a05_state, empty_init, "Excalibur Electronics Inc", "Carl Edwards' Chase For Glory", MACHINE_NOT_WORKING ) diff --git a/src/mame/drivers/nes_clone.cpp b/src/mame/drivers/nes_clone.cpp index 4a03b5b95d9..ae21b8647e1 100644 --- a/src/mame/drivers/nes_clone.cpp +++ b/src/mame/drivers/nes_clone.cpp @@ -18,10 +18,14 @@ public: nes_clone_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), m_maincpu(*this, "maincpu"), + m_screen(*this, "screen"), + m_io0(*this, "IO0"), + m_io1(*this, "IO1"), m_ppu(*this, "ppu") { } void nes_clone(machine_config &config); + void nes_clone_pal(machine_config &config); void init_nes_clone(); @@ -30,15 +34,47 @@ protected: virtual void machine_reset() override; virtual void video_start() override; - WRITE8_MEMBER(sprite_dma_w); + DECLARE_WRITE8_MEMBER(sprite_dma_w); + + virtual DECLARE_READ8_MEMBER(in0_r); + virtual DECLARE_READ8_MEMBER(in1_r); + virtual DECLARE_WRITE8_MEMBER(in0_w); + + void nes_clone_basemap(address_map &map); + + uint8_t* m_mainrom; + int m_mainromsize; -private: required_device m_maincpu; + required_device m_screen; + optional_ioport m_io0; + optional_ioport m_io1; + uint8_t m_latch0; + uint8_t m_latch1; + +private: required_device m_ppu; void nes_clone_map(address_map &map); }; +class nes_clone_dnce2000_state : public nes_clone_state +{ +public: + nes_clone_dnce2000_state(const machine_config& mconfig, device_type type, const char* tag) : + nes_clone_state(mconfig, type, tag) + { } + void nes_clone_dnce2000(machine_config& config); + +private: + void nes_clone_dnce2000_map(address_map& map); + virtual void machine_start() override; + virtual void machine_reset() override; + DECLARE_READ8_MEMBER(rom_r); + DECLARE_WRITE8_MEMBER(bank_w); + int m_rombase; +}; + WRITE8_MEMBER(nes_clone_state::sprite_dma_w) { @@ -46,15 +82,89 @@ WRITE8_MEMBER(nes_clone_state::sprite_dma_w) m_ppu->spriteram_dma(space, source); } -void nes_clone_state::nes_clone_map(address_map &map) +// Standard NES style inputs (not using bus device as there are no real NES controller ports etc. these are all-in-one units and can be custom +READ8_MEMBER(nes_clone_state::in0_r) +{ + //logerror("%s: in0_r\n", machine().describe_context()); + uint8_t ret = 0x40; + ret |= m_latch0 & 1; + m_latch0 >>= 1; + return ret; +} + +READ8_MEMBER(nes_clone_state::in1_r) +{ + //logerror("%s: in1_r\n", machine().describe_context()); + uint8_t ret = 0x40; + ret |= m_latch1 & 1; + m_latch1 >>= 1; + return ret; +} + +WRITE8_MEMBER(nes_clone_state::in0_w) +{ + //logerror("%s: in0_w %02x\n", machine().describe_context(), data); + if (data & 0x01) + return; + + m_latch0 = m_io0->read(); + m_latch1 = m_io1->read(); +} + + +void nes_clone_state::nes_clone_basemap(address_map& map) { map(0x0000, 0x07ff).ram(); map(0x2000, 0x3fff).rw(m_ppu, FUNC(ppu2c0x_device::read), FUNC(ppu2c0x_device::write)); + + map(0x4016, 0x4016).rw(FUNC(nes_clone_state::in0_r), FUNC(nes_clone_state::in0_w)); + map(0x4017, 0x4017).r(FUNC(nes_clone_state::in1_r)); + map(0x4014, 0x4014).w(FUNC(nes_clone_state::sprite_dma_w)); +} + +void nes_clone_state::nes_clone_map(address_map& map) +{ + nes_clone_basemap(map); map(0x8000, 0xffff).rom(); } static INPUT_PORTS_START( nes_clone ) + 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 + + +static INPUT_PORTS_START( dnce2000 ) + PORT_START("IO0") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_PLAYER(1) PORT_NAME("Down-Left") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_NAME("Down-Right") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_PLAYER(1) PORT_NAME("Up-Left / Select") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_START ) PORT_PLAYER(1) PORT_NAME("Up-Right / Start") + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_PLAYER(1) PORT_16WAY // NOT A JOYSTICK!! + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1) PORT_16WAY + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1) PORT_16WAY + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1) PORT_16WAY + + PORT_START("IO1") + PORT_BIT( 0xff, IP_ACTIVE_HIGH, IPT_UNUSED ) INPUT_PORTS_END void nes_clone_state::video_start() @@ -63,11 +173,20 @@ void nes_clone_state::video_start() void nes_clone_state::machine_reset() { + m_latch0 = 0; + m_latch1 = 0; } void nes_clone_state::machine_start() { + m_mainrom = memregion("maincpu")->base(); + m_mainromsize = memregion("maincpu")->bytes(); + + save_item(NAME(m_latch0)); + save_item(NAME(m_latch1)); +} + // m_nt_ram = std::make_unique(0x1000); // m_nt_page[0] = m_nt_ram.get(); // m_nt_page[1] = m_nt_ram.get() + 0x400; @@ -77,7 +196,6 @@ void nes_clone_state::machine_start() // m_ppu->space(AS_PROGRAM).install_readwrite_handler(0x2000, 0x3eff, read8_delegate(*this, FUNC(nes_clone_state::nes_clone_nt_r)), write8_delegate(*this, FUNC(nes_clone_state::nes_clone_nt_w))); // m_ppu->space(AS_PROGRAM).install_read_bank(0x0000, 0x1fff, "bank1"); // membank("bank1")->set_base(memregion("gfx1")->base()); -} void nes_clone_state::nes_clone(machine_config &config) { @@ -86,11 +204,12 @@ void nes_clone_state::nes_clone(machine_config &config) m_maincpu->set_addrmap(AS_PROGRAM, &nes_clone_state::nes_clone_map); /* video hardware */ - screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); - screen.set_refresh_hz(60); - screen.set_size(32*8, 262); - screen.set_visarea(0*8, 32*8-1, 0*8, 30*8-1); - screen.set_screen_update("ppu", FUNC(ppu2c0x_device::screen_update)); + SCREEN(config, m_screen, SCREEN_TYPE_RASTER); + m_screen->set_refresh_hz(60.0988); + m_screen->set_vblank_time(ATTOSECONDS_IN_USEC((113.66/(NTSC_APU_CLOCK.dvalue()/1000000)) * (ppu2c0x_device::VBLANK_LAST_SCANLINE_NTSC-ppu2c0x_device::VBLANK_FIRST_SCANLINE+1+2))); + m_screen->set_size(32*8, 262); + m_screen->set_visarea(0*8, 32*8-1, 0*8, 30*8-1); + m_screen->set_screen_update(m_ppu, FUNC(ppu2c0x_device::screen_update)); PPU_2C02(config, m_ppu); m_ppu->set_cpu_tag("maincpu"); @@ -101,6 +220,66 @@ void nes_clone_state::nes_clone(machine_config &config) m_maincpu->add_route(ALL_OUTPUTS, "mono", 0.50); } +void nes_clone_state::nes_clone_pal(machine_config &config) +{ + /* basic machine hardware */ + N2A03(config, m_maincpu, PALC_APU_CLOCK); + m_maincpu->set_addrmap(AS_PROGRAM, &nes_clone_state::nes_clone_map); + + /* video hardware */ + SCREEN(config, m_screen, SCREEN_TYPE_RASTER); + m_screen->set_refresh_hz(50.0070); + m_screen->set_vblank_time(ATTOSECONDS_IN_USEC((113.66 / (PALC_APU_CLOCK.dvalue() / 1000000)) * (ppu2c0x_device::VBLANK_LAST_SCANLINE_PAL - ppu2c0x_device::VBLANK_FIRST_SCANLINE_PALC + 1 + 2))); + m_screen->set_size(32 * 8, 312); + m_screen->set_visarea(0 * 8, 32 * 8 - 1, 0 * 8, 30 * 8 - 1); + m_screen->set_screen_update(m_ppu, FUNC(ppu2c0x_device::screen_update)); + + PPU_PALC(config, m_ppu); + m_ppu->set_cpu_tag("maincpu"); + m_ppu->int_callback().set_inputline(m_maincpu, INPUT_LINE_NMI); + + /* sound hardware */ + SPEAKER(config, "mono").front_center(); + m_maincpu->add_route(ALL_OUTPUTS, "mono", 0.50); +} + +void nes_clone_dnce2000_state::nes_clone_dnce2000(machine_config& config) +{ + nes_clone_pal(config); + m_maincpu->set_addrmap(AS_PROGRAM, &nes_clone_dnce2000_state::nes_clone_dnce2000_map); +} + + + +void nes_clone_dnce2000_state::nes_clone_dnce2000_map(address_map& map) +{ + nes_clone_basemap(map); + map(0x8000, 0xffff).rw(FUNC(nes_clone_dnce2000_state::rom_r), FUNC(nes_clone_dnce2000_state::bank_w)); +} + + +void nes_clone_dnce2000_state::machine_reset() +{ + nes_clone_state::machine_reset(); + m_rombase = 0; +} + +void nes_clone_dnce2000_state::machine_start() +{ + nes_clone_state::machine_start(); + save_item(NAME(m_rombase)); +} + +READ8_MEMBER(nes_clone_dnce2000_state::rom_r) +{ + return m_mainrom[(offset + (m_rombase * 0x8000)) & (m_mainromsize - 1)]; +} + +WRITE8_MEMBER(nes_clone_dnce2000_state::bank_w) +{ + m_rombase = data; +} + ROM_START( pjoypj001 ) ROM_REGION( 0x100000, "maincpu", ROMREGION_ERASE00 ) ROM_LOAD( "powerjoy_pj001_lh28f008sc_89a6.bin", 0x00000, 0x100000, CRC(e655e0aa) SHA1(c96d3422e26451c366fee2151fedccb95014cbc7) ) @@ -114,6 +293,11 @@ ROM_START( afbm7800 ) ROM_LOAD( "atariflashbackmini7800.bin", 0x00000, 0x100000, CRC(da4d9483) SHA1(c04465ff5bd5ca7abf088fe771b8e71c157afb89) ) ROM_END +ROM_START( dnce2000 ) // use Mapper 241 if you want to run this in a NES emulator + ROM_REGION( 0x40000, "maincpu", 0 ) + ROM_LOAD( "dance.bin", 0x00000, 0x40000, CRC(0982bb50) SHA1(bd608159d7e624ea345f2a188de51cb1aa116421) ) +ROM_END + void nes_clone_state::init_nes_clone() { @@ -123,3 +307,5 @@ CONS( 200?, pjoypj001, 0, 0, nes_clone, nes_clone, nes_clone_state, init_nes_clo // "Flashback Mini 7800 uses normal NES-style hardware, together with a mapper chipset similar to the Waixing kk33xx cartridges (NES 2.0 Mapper 534)" CONS( 2004, afbm7800, 0, 0, nes_clone, nes_clone, nes_clone_state, init_nes_clone, "Atari", "Atari Flashback Mini 7800", MACHINE_NOT_WORKING ) + +CONS( 200?, dnce2000, 0, 0, nes_clone_dnce2000, dnce2000, nes_clone_dnce2000_state, init_nes_clone, "Shenzhen Soyin Electric Appliance Ind. Co., Ltd.", "Dance 2000 / Hot 2000 (Jin Bao TV Dancing Carpet, SY-2000-04)", 0 ) diff --git a/src/mame/drivers/trkfldch.cpp b/src/mame/drivers/trkfldch.cpp index 35b414516f0..f5b771af04e 100644 --- a/src/mame/drivers/trkfldch.cpp +++ b/src/mame/drivers/trkfldch.cpp @@ -303,20 +303,23 @@ void trkfldch_state::draw_sprites(screen_device& screen, bitmap_ind16& bitmap, c m_spriteram[i + 1] yyyy yyyy m_spriteram[i + 2] tttt tttt m_spriteram[i + 3] xxxx xxxx - m_spriteram[i + 4] --zfF-t-x + m_spriteram[i + 4] --zfF-tdx p = palette bits - t = tile bites + t = tile bits y = y pos bits x = x pos bits z = priority fF = x/y flip + d = pixel double */ int y = m_spriteram[i + 1]; int x = m_spriteram[i + 3]; int tile = m_spriteram[i + 2]; + int doublesize = m_spriteram[i + 4] & 0x02; + int tilehigh = m_spriteram[i + 4] & 0x04; int tilehigh2 = m_spriteram[i + 0] & 0x04; int tilehigh3 = m_spriteram[i + 0] & 0x08; @@ -361,8 +364,7 @@ void trkfldch_state::draw_sprites(screen_device& screen, bitmap_ind16& bitmap, c } - - gfx->transpen(bitmap, cliprect, tile + tilegfxbase, pal, flipx, flipy, x, y, 0); + gfx->zoom_transpen(bitmap, cliprect, tile + tilegfxbase, pal, flipx, flipy, x, y, doublesize ? 0x20000 : 0x10000, doublesize ? 0x20000 : 0x10000, 0); } } diff --git a/src/mame/mame.lst b/src/mame/mame.lst index ecc6856d775..f36ea815067 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -12927,7 +12927,8 @@ rad_sinv rad_tetr airblsjs buzztime -sudoelan +sudelan3 +sudelan carlecfg pvmilfin @@ -31435,6 +31436,7 @@ nespal // Nintendo Entertainment System PAL @source:nes_clone.cpp pjoypj001 afbm7800 +dnce2000 @source:nes_sh6578.cpp bandgpad -- cgit v1.2.3