summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/drivers/spg2xx_wiwi.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/drivers/spg2xx_wiwi.cpp')
-rw-r--r--src/mame/drivers/spg2xx_wiwi.cpp293
1 files changed, 290 insertions, 3 deletions
diff --git a/src/mame/drivers/spg2xx_wiwi.cpp b/src/mame/drivers/spg2xx_wiwi.cpp
index 69c852ecfdb..ceeec61c580 100644
--- a/src/mame/drivers/spg2xx_wiwi.cpp
+++ b/src/mame/drivers/spg2xx_wiwi.cpp
@@ -18,10 +18,50 @@ public:
void init_wiwi18();
+protected:
+
+private:
+ void portb_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0) override;
+};
+
+class spg2xx_game_marc101_state : public spg2xx_game_state
+{
+public:
+ spg2xx_game_marc101_state(const machine_config &mconfig, device_type type, const char *tag) :
+ spg2xx_game_state(mconfig, type, tag)
+ { }
+
+ void init_m489();
+
+protected:
+
+private:
+ void portb_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0) override;
+};
+
+class spg2xx_game_marc250_state : public spg2xx_game_state
+{
+public:
+ spg2xx_game_marc250_state(const machine_config &mconfig, device_type type, const char *tag) :
+ spg2xx_game_state(mconfig, type, tag)
+ { }
+
+ void init_m527();
+
+protected:
+ void machine_reset() override
+ {
+ spg2xx_game_state::machine_reset();
+ switch_bank(31);
+ m_maincpu->reset();
+ }
+
private:
void portb_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0) override;
};
+
+
static INPUT_PORTS_START( wiwi18 )
PORT_START("P1")
PORT_DIPNAME( 0x0001, 0x0001, "IN0" )
@@ -228,6 +268,26 @@ static INPUT_PORTS_START( lexifit )
PORT_BIT( 0xffff, IP_ACTIVE_LOW, IPT_CUSTOM )
INPUT_PORTS_END
+static INPUT_PORTS_START( m489 )
+ PORT_START("P1")
+ PORT_BIT( 0xffff, IP_ACTIVE_LOW, IPT_UNUSED )
+
+ PORT_START("P2")
+ PORT_BIT( 0x0003, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_UP )
+ PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN )
+ PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT )
+ PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT )
+ PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON1 )
+ PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_BUTTON2 )
+ PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED )
+
+ PORT_START("P3")
+ PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_START1 )
+ PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_UNUSED ) // acts as Button 1 autofire (not connected on unit?)
+ PORT_BIT( 0xfffc, IP_ACTIVE_LOW, IPT_UNUSED )
+INPUT_PORTS_END
+
void spg2xx_game_wiwi18_state::init_wiwi18()
{
@@ -242,9 +302,7 @@ void spg2xx_game_wiwi18_state::init_wiwi18()
}
-
-
-void spg2xx_game_wiwi18_state::portb_w(offs_t offset, uint16_t data, uint16_t mem_mask)
+ void spg2xx_game_wiwi18_state::portb_w(offs_t offset, uint16_t data, uint16_t mem_mask)
{
logerror("%s: portb_w %04x (%04x) %c %c %c %c | %c %c %c %c | %c %c %c %c | %c %c %c %c \n", machine().describe_context(), data, mem_mask,
(mem_mask & 0x8000) ? ((data & 0x8000) ? '1' : '0') : 'x',
@@ -274,6 +332,220 @@ void spg2xx_game_wiwi18_state::portb_w(offs_t offset, uint16_t data, uint16_t me
}
+void spg2xx_game_marc101_state::init_m489()
+{
+ uint16_t* rom = (uint16_t*)memregion("maincpu")->base();
+
+ // bypass a call that turns unit off after about 2 seconds, maybe it's a battery check?
+ if (rom[0x6460]==0x4240) rom[0x6460] = 0x4241;
+}
+
+void spg2xx_game_marc101_state::portb_w(offs_t offset, uint16_t data, uint16_t mem_mask)
+{
+ if (m_maincpu->pc() < 0x2000)
+ {
+ logerror("%s: portb_w %04x (%04x) %c %c %c %c | %c %c %c %c | %c %c %c %c | %c %c %c %c \n", machine().describe_context(), data, mem_mask,
+ (mem_mask & 0x8000) ? ((data & 0x8000) ? '1' : '0') : 'x',
+ (mem_mask & 0x4000) ? ((data & 0x4000) ? '1' : '0') : 'x',
+ (mem_mask & 0x2000) ? ((data & 0x2000) ? '1' : '0') : 'x',
+ (mem_mask & 0x1000) ? ((data & 0x1000) ? '1' : '0') : 'x',
+ (mem_mask & 0x0800) ? ((data & 0x0800) ? '1' : '0') : 'x',
+ (mem_mask & 0x0400) ? ((data & 0x0400) ? '1' : '0') : 'x',
+ (mem_mask & 0x0200) ? ((data & 0x0200) ? '1' : '0') : 'x',
+ (mem_mask & 0x0100) ? ((data & 0x0100) ? '1' : '0') : 'x',
+ (mem_mask & 0x0080) ? ((data & 0x0080) ? '1' : '0') : 'x',
+ (mem_mask & 0x0040) ? ((data & 0x0040) ? '1' : '0') : 'x',
+ (mem_mask & 0x0020) ? ((data & 0x0020) ? '1' : '0') : 'x',
+ (mem_mask & 0x0010) ? ((data & 0x0010) ? '1' : '0') : 'x',
+ (mem_mask & 0x0008) ? ((data & 0x0008) ? '1' : '0') : 'x',
+ (mem_mask & 0x0004) ? ((data & 0x0004) ? '1' : '0') : 'x',
+ (mem_mask & 0x0002) ? ((data & 0x0002) ? '1' : '0') : 'x',
+ (mem_mask & 0x0001) ? ((data & 0x0001) ? '1' : '0') : 'x');
+ }
+
+
+ if (m_maincpu->pc() < 0x2000)
+ {
+ // bit 0x1000 isn't set as an output, but clearly needs to be treated as one
+ switch (data & 0x1003)
+ {
+ case 0x0000: switch_bank(7); break;
+ case 0x0001: switch_bank(6); break; // good - heroic pilot
+ case 0x0002: switch_bank(5); break; // good - horrific collapser
+ case 0x0003: switch_bank(4); break; // good - under sea war
+ case 0x1000: switch_bank(3); break; // good - roadman etc.
+ case 0x1001: switch_bank(2); break; // good - santa etc
+ case 0x1002: switch_bank(1); break;
+ case 0x1003: switch_bank(0); break;
+ }
+ }
+}
+
+void spg2xx_game_marc250_state::init_m527()
+{
+ uint16_t* rom = (uint16_t*)memregion("maincpu")->base();
+
+ // bypass a call that turns unit off after about 10 seconds, maybe it's a battery check?
+ rom[((31 * 0x800000) / 2) | 0x004ea5] = 0x4241;
+
+ // same for xracing 3
+ rom[((22 * 0x800000) / 2) | 0x00eb2a] = 0x4241;
+
+ uint16_t ident2[6] = { 0x9512, 0x2862, 0xa70a, 0x0002, 0xd71b, 0x2862 };
+
+ for (int i = 0; i < (0x10000000 / 2) - 6; i++)
+ {
+ bool found = true;
+ for (int j = 0; j < 6; j++)
+ {
+ uint16_t cmp1 = ident2[j];
+ uint16_t cmp2 = rom[i + j];
+
+ if (cmp1 != cmp2)
+ found = false;
+ }
+
+ if (found)
+ {
+ printf("found at %08x\n", i + 3);
+ rom[i + 3] = 0x0003;
+ }
+ }
+
+ // this turns the IRQ off, code looks a bit like smarttv code.. is SoC IRQ handling wrong?
+
+ // pass maze road
+ //rom[((12 * 0x800000) / 2) | 0x0284b5] = 0x0003;
+ // learn numbers
+ //rom[((13 * 0x800000) / 2) | 0x00c055] = 0x0003;
+ // bowling
+ //rom[((17 * 0x800000) / 2) | 0x015e58] = 0x0003;
+ // cliff overhang / gym dancing
+ //rom[((18 * 0x800000) / 2) | 0x01cab4] = 0x0003;
+ rom[((18 * 0x800000) / 2) | 0x021e25] = 0xffff;
+ // jump chess
+ //rom[((19 * 0x800000) / 2) | 0x012c3a] = 0x0003;
+ // boxing, basketball etc.
+ //rom[((23 * 0x800000) / 2) | 0x00c1bd] = 0x0003;
+ // dash motor
+ //rom[((24 * 0x800000) / 2) | 0x00d62c] = 0x0003;
+ // same for curling
+ //rom[((25 * 0x800000) / 2) | 0x0103c5] = 0x0003;
+ // balloon puyo
+ //rom[((26 * 0x800000) / 2) | 0x0084dd] = 0x0003;
+ // 4 score
+ //rom[((27 * 0x800000) / 2) | 0x145cdd] = 0x0003;
+}
+
+void spg2xx_game_marc250_state::portb_w(offs_t offset, uint16_t data, uint16_t mem_mask)
+{
+ if (m_maincpu->pc() == 0x18)
+ {
+ printf("%s: portb_w %04x (%04x) %c %c %c %c | %c %c %c %c | %c %c %c %c | %c %c %c %c \n", machine().describe_context().c_str(), data, mem_mask,
+ (mem_mask & 0x8000) ? ((data & 0x8000) ? '1' : '0') : 'x',
+ (mem_mask & 0x4000) ? ((data & 0x4000) ? '1' : '0') : 'x',
+ (mem_mask & 0x2000) ? ((data & 0x2000) ? '1' : '0') : 'x',
+ (mem_mask & 0x1000) ? ((data & 0x1000) ? '1' : '0') : 'x',
+ (mem_mask & 0x0800) ? ((data & 0x0800) ? '1' : '0') : 'x',
+ (mem_mask & 0x0400) ? ((data & 0x0400) ? '1' : '0') : 'x',
+ (mem_mask & 0x0200) ? ((data & 0x0200) ? '1' : '0') : 'x',
+ (mem_mask & 0x0100) ? ((data & 0x0100) ? '1' : '0') : 'x',
+ (mem_mask & 0x0080) ? ((data & 0x0080) ? '1' : '0') : 'x',
+ (mem_mask & 0x0040) ? ((data & 0x0040) ? '1' : '0') : 'x',
+ (mem_mask & 0x0020) ? ((data & 0x0020) ? '1' : '0') : 'x',
+ (mem_mask & 0x0010) ? ((data & 0x0010) ? '1' : '0') : 'x',
+ (mem_mask & 0x0008) ? ((data & 0x0008) ? '1' : '0') : 'x',
+ (mem_mask & 0x0004) ? ((data & 0x0004) ? '1' : '0') : 'x',
+ (mem_mask & 0x0002) ? ((data & 0x0002) ? '1' : '0') : 'x',
+ (mem_mask & 0x0001) ? ((data & 0x0001) ? '1' : '0') : 'x');
+ }
+
+ // bank 0 = (unused) 'ROM 18 64M' (dupe)
+ // bank 1 = (unused) 'ROM 18 64M' (dupe)
+ // bank 2 = (unused) 'ROM 18 64M' (dupe)
+ // bank 3 = (unused) 'ROM 18 64M' (dupe)
+ // bank 4 = (unused) 'ROM 18 64M' (dupe)
+ // bank 5 = (unused) 'ROM 18 64M' (dupe)
+ // bank 6 = (used) boots 'kung fu high style' (no bank number check)
+ // bank 7 = (unused) 'ROM 18 64M' (dupe)
+
+ // bank 8 = (used) 'ROM 24 64M'
+ // bank 9 = (used) 'ROM 23 64M'
+ // bank 10 = (unused) 'ROM 18 64M' (dupe)
+ // bank 11 = (unused) 'ROM 18 64M' (dupe)
+ // bank 12 = (used) (doesn't boot)
+ // bank 13 = (used) (doesn't boot)
+ // bank 14 = (used) 'ROM 18 64M'
+ // bank 15 = (unused) 'ROM 18 64M' (dupe)
+
+ // bank 16 = (used) 'ROM 16 64M' (error)
+ // bank 17 = (used) (plays music)
+ // bank 18 = (used) (doesn't boot)
+ // bank 19 = (used)
+ // bank 20 = (used)
+ // bank 21 = (used)
+ // bank 22 = (used)
+ // bank 23 = (used)
+
+ // bank 24 = (used)
+ // bank 25 = (used)
+ // bank 26 = (used)
+ // bank 27 = (used)
+ // bank 28 = (used)
+ // bank 29 = (used)
+ // bank 30 = (used) 'ROM 2 64M'
+ // bank 31 = (used) menu (no bank number check)
+
+ if ((m_maincpu->pc() == 0x18) && (data != 0x00ff))
+ {
+ // bits 0x1804 aren't set as an output, but clearly need to be treated as output
+ switch (data & 0x1807)
+ {
+ case 0x0000: switch_bank(0); break; // unused
+ case 0x0001: switch_bank(1); break; // unused
+ case 0x0002: switch_bank(2); break; // unused
+ case 0x0003: switch_bank(3); break; // unused
+
+ case 0x1000: switch_bank(4); break; // unused
+ case 0x1001: switch_bank(5); break; // unused
+ case 0x1002: switch_bank(6); break; // kung fu (ok)
+ case 0x1003: switch_bank(7); break; // unused
+
+ case 0x0800: switch_bank(8); break; // jogging (ok)
+ case 0x0801: switch_bank(9); break; // power kick (ok)
+ case 0x0802: switch_bank(10); break; // unused
+ case 0x0803: switch_bank(11); break; // unused
+
+ case 0x1800: switch_bank(12); break; // pass maze road
+ case 0x1801: switch_bank(13); break; // learn number
+ case 0x1802: switch_bank(14); break; // final race, motor race
+ case 0x1803: switch_bank(15); break; // unused
+
+ case 0x0004: switch_bank(16); break; // thunder race, speed race, night shooter
+ case 0x0005: switch_bank(17); break; // rescue bees
+ case 0x0006: switch_bank(18); break; // cliff overhang
+ case 0x0007: switch_bank(19); break; // jump chess
+
+ case 0x1004: switch_bank(20); break; // mind link, mystery cave
+ case 0x1005: switch_bank(21); break; // bumper cars, stone age, dance party (need hack)
+ case 0x1006: switch_bank(22); break; // xracer (need hack)
+ case 0x1007: switch_bank(23); break; // basketball (but irq gets turned off?)
+
+ case 0x0804: switch_bank(24); break; // button jumper dash motor
+ case 0x0805: switch_bank(25); break; // cross river
+ case 0x0806: switch_bank(26); break; // balloon puyu
+ case 0x0807: switch_bank(27); break; // 4 Score
+
+ case 0x1804: switch_bank(28); break; // bubble, malibu
+ case 0x1805: switch_bank(29); break; // goalkeeper
+ case 0x1806: switch_bank(30); break; // fish journey, brick, happy zoo, crazy tramcar
+ case 0x1807: switch_bank(31); break; // menu
+
+ }
+ }
+}
+
+
ROM_START( foxsport )
ROM_REGION( 0x1000000, "maincpu", ROMREGION_ERASE00 )
ROM_LOAD16_WORD_SWAP( "foxsports.bin", 0x000000, 0x1000000, CRC(a5092f49) SHA1(feb4d432486b17d6cd2aed8cefd3d084f77c1733) ) // only a tiny amount of data in the 2nd half, what's it used for (if anything)
@@ -289,6 +561,17 @@ ROM_START( lexifit )
ROM_LOAD16_WORD_SWAP( "lexibook_tv_fitness_center.bin", 0x000000, 0x1000000, CRC(38021230) SHA1(2b949d723a475bfac23d9da4d1a30ea71b332ccb) )
ROM_END
+ROM_START( marc101 )
+ ROM_REGION( 0x4000000, "maincpu", ROMREGION_ERASE00 )
+ ROM_LOAD16_WORD_SWAP( "m489.u6", 0x0000000, 0x4000000, CRC(0a01695f) SHA1(1a13c5eb9dffdc91fc68a98e8f35bd8a019a8373) )
+ ROM_IGNORE(0x4000000) // 2nd half is just random fill unrelated to the game, ROM was twice needed capacity
+ROM_END
+
+ROM_START( marc250 )
+ ROM_REGION( 0x10000000, "maincpu", ROMREGION_ERASE00 )
+ ROM_LOAD16_WORD_SWAP( "m527.u6", 0x0000000, 0x10000000, CRC(4b856cab) SHA1(41c66bbdb0bb1442d7e11da18e9e6b20048445ba) )
+ROM_END
+
// box marked 'Wireless game console' 'Drahtlose Spielekonsole' 87 Sports games included : 18 hyper sports games, 69 arcade games.
// Unit marked 'Hamy System' 'WiWi'
// actually a cartridge, but all hardware is in the cart, overriding any internal hardware entirely. see nes_vt.cp 'mc_sp69' for the '69 arcade game' part
@@ -299,3 +582,7 @@ CONS( 2009, lexifit, 0, 0, rad_skat, lexifit, spg2xx_game_wiwi18_state,
CONS( 200?, foxsport, 0, 0, rad_skat, wiwi18, spg2xx_game_wiwi18_state, init_wiwi18, "Excalibur Electronics", "Fox Sports 7 in 1 Sports Games Plug n' Play", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS )
// thtere is another 'Drahtlose Spielekonsole 48-in-1' with '11 hyper sports games' (including Running) which are clearly SunPlus and would fit here, with the 37 non-hyper sports games presumably again being a NES/Famiclone cart
+
+CONS( 200?, marc101, 0, 0, spg2xx, m489, spg2xx_game_marc101_state, init_m489, "Millennium 2000 GmbH", "Millennium Arcade 101 (M489) (Game Station 2 101-in-1)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS )
+
+CONS( 200?, marc250, 0, 0, spg2xx, m489, spg2xx_game_marc250_state, init_m527, "Millennium 2000 GmbH", "Millennium Arcade 250 (M527)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS )