Plug and Play work (#6357)

* start cleaning up banking for some of the SunPlus games (helps when you remember that the port wrirtes supply a mem_mask)

* banking improvements (nw)

* further improvements (nw)

* (nw)

* make more DRC friendly (nw)

* cleaner banking for some in here, although mysprtcp doesn't want to behave, the port dirtection bits we need to output to aren't set to output?!

* new NOT WORKING software list entries
-----
mobigo_cart.xml [TeamEurope]
Tinkerbell - Tal der Feen (Germany) (80-250904)
Dino-Zug - Erforsche die Welt (Germany) (80-252304)
Planes (Germany) (80-253004)
Sofia die Erste (Germany) (80-253204)
Doc McStuffins - Spielzeugarztin (Germany) (80-253304)
Ultimate Spider-Man (Germany) (80-253604)
This commit is contained in:
David Haywood 2020-02-25 13:18:57 +00:00 committed by GitHub
parent 5d1ebeb648
commit 4bb92d091a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 406 additions and 245 deletions

View File

@ -147,7 +147,72 @@
</part>
</software>
<software name="tbellger" supported="no">
<description>Tinkerbell - Tal der Feen (Germany) (80-250904)</description>
<year>201?</year>
<publisher>VTech</publisher>
<part name="cart" interface="mobigo_cart">
<dataarea name="rom" size="0x1000000">
<rom name="80-250904 - tinkerbell - tal der feen (ger).bin" size="0x1000000" crc="f711f920" sha1="0fc8890d604ec89e061a35a0d577864e937920ce"/>
</dataarea>
</part>
</software>
<software name="dzugger" supported="no">
<description>Dino-Zug - Erforsche die Welt (Germany) (80-252304)</description>
<year>201?</year>
<publisher>VTech</publisher>
<part name="cart" interface="mobigo_cart">
<dataarea name="rom" size="0x1000000">
<rom name="80-252304 - dino-zug - erforsche die welt (ger).bin" size="0x1000000" crc="7019a906" sha1="a9b0caa59cd7119d8fac305729b75b4da0702dc1"/>
</dataarea>
</part>
</software>
<software name="planeger" supported="no">
<description>Planes (Germany) (80-253004)</description>
<year>201?</year>
<publisher>VTech</publisher>
<part name="cart" interface="mobigo_cart">
<dataarea name="rom" size="0x1000000">
<rom name="80-253004 - planes (ger).bin" size="0x1000000" crc="f945b3cd" sha1="4b7f17f3d7b7edc1626b4e84e26e01ae67bb4f5a"/>
</dataarea>
</part>
</software>
<software name="sofiager" supported="no">
<description>Sofia die Erste (Germany) (80-253204)</description>
<year>201?</year>
<publisher>VTech</publisher>
<part name="cart" interface="mobigo_cart">
<dataarea name="rom" size="0x1000000">
<rom name="80-253204 - sofia die erste (ger).bin" size="0x1000000" crc="8559a363" sha1="2892e33c48ef25ecaf3753a6d3f0bff7afb826d7"/>
</dataarea>
</part>
</software>
<software name="docmcger" supported="no">
<description>Doc McStuffins - Spielzeugarztin (Germany) (80-253304)</description>
<year>201?</year>
<publisher>VTech</publisher>
<part name="cart" interface="mobigo_cart">
<dataarea name="rom" size="0x1000000">
<rom name="80-253304 - doc mcstuffins - spielzeugarztin (ger).bin" size="0x1000000" crc="53100cbe" sha1="6d47ff9d2623c8012fa394154cd5a39bb99bc805"/>
</dataarea>
</part>
</software>
<software name="uspidger" supported="no">
<description>Ultimate Spider-Man (Germany) (80-253604)</description>
<year>201?</year>
<publisher>VTech</publisher>
<part name="cart" interface="mobigo_cart">
<dataarea name="rom" size="0x1000000">
<rom name="80-253604 - ultimate spider-man (ger).bin" size="0x1000000" crc="953d470c" sha1="e74fb15fcb92aadd0d36ec1f5bf6799c46ca5425"/>
</dataarea>
</part>
</software>
<software name="tstory3a" supported="no"> <!-- part #? full title? region? -->
<description>Toy Story 3</description>
<year>201?</year>

View File

@ -168,17 +168,65 @@ void spg2xx_game_state::switch_bank(uint32_t bank)
WRITE16_MEMBER(spg2xx_game_state::porta_w)
{
logerror("%s: porta_w %04x\n", machine().describe_context(), data);
logerror("%s: porta_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');
}
WRITE16_MEMBER(spg2xx_game_state::portb_w)
{
logerror("%s: portb_w %04x\n", machine().describe_context(), data);
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');
}
WRITE16_MEMBER(spg2xx_game_state::portc_w)
{
logerror("%s: portc_w %04x\n", machine().describe_context(), data);
logerror("%s: portc_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');
}
WRITE8_MEMBER(spg2xx_game_state::i2c_w)
@ -195,21 +243,21 @@ READ8_MEMBER(spg2xx_game_state::i2c_r)
READ16_MEMBER(spg2xx_game_state::base_porta_r)
{
uint16_t data = m_io_p1->read();
logerror("%s: Port A Read: %04x\n", machine().describe_context(), data);
logerror("%s: Port A Read: %04x (%04x)\n", machine().describe_context(), data, mem_mask);
return data;
}
READ16_MEMBER(spg2xx_game_state::base_portb_r)
{
uint16_t data = m_io_p2->read();
logerror("%s: Port B Read: %04x\n", machine().describe_context(), data);
logerror("%s: Port B Read: %04x (%04x)\n", machine().describe_context(), data, mem_mask);
return data;
}
READ16_MEMBER(spg2xx_game_state::base_portc_r)
{
uint16_t data = m_io_p3->read();
logerror("%s: Port C Read: %04x\n", machine().describe_context(), data);
logerror("%s: Port C Read: %04x (%04x)\n", machine().describe_context(), data, mem_mask);
return data;
}

View File

@ -6,10 +6,10 @@
#include "includes/spg2xx.h"
class spg2xx_game_mysprtch_state : public spg2xx_game_state
class spg2xx_game_mysprt_plus_state : public spg2xx_game_state
{
public:
spg2xx_game_mysprtch_state(const machine_config& mconfig, device_type type, const char* tag) :
spg2xx_game_mysprt_plus_state(const machine_config& mconfig, device_type type, const char* tag) :
spg2xx_game_state(mconfig, type, tag),
m_romregion(*this, "maincpu")
{ }
@ -23,6 +23,7 @@ public:
protected:
virtual void machine_start() override;
virtual void machine_reset() override;
virtual void device_post_load() override;
void mem_map_mysprtch(address_map& map);
@ -39,11 +40,11 @@ private:
required_region_ptr<uint16_t> m_romregion;
};
class spg2xx_game_mysprtch24_state : public spg2xx_game_mysprtch_state
class spg2xx_game_mysprt_orig_state : public spg2xx_game_mysprt_plus_state
{
public:
spg2xx_game_mysprtch24_state(const machine_config& mconfig, device_type type, const char* tag) :
spg2xx_game_mysprtch_state(mconfig, type, tag)
spg2xx_game_mysprt_orig_state(const machine_config& mconfig, device_type type, const char* tag) :
spg2xx_game_mysprt_plus_state(mconfig, type, tag)
{ }
protected:
@ -53,20 +54,25 @@ protected:
private:
};
void spg2xx_game_mysprt_plus_state::device_post_load()
{
// load state can change the bank, so we must invalide cache
m_maincpu->invalidate_cache();
}
READ16_MEMBER(spg2xx_game_mysprtch_state::mysprtch_rom_r)
READ16_MEMBER(spg2xx_game_mysprt_plus_state::mysprtch_rom_r)
{
// due to granularity of rom bank this manual method is safer
return m_romregion[(offset + (m_mysprtch_rombase * 0x200000)) & (m_romsize-1)];
}
void spg2xx_game_mysprtch_state::mem_map_mysprtch(address_map &map)
void spg2xx_game_mysprt_plus_state::mem_map_mysprtch(address_map &map)
{
map(0x000000, 0x3fffff).r(FUNC(spg2xx_game_mysprtch_state::mysprtch_rom_r));
map(0x000000, 0x3fffff).r(FUNC(spg2xx_game_mysprt_plus_state::mysprtch_rom_r));
}
void spg2xx_game_mysprtch_state::machine_start()
void spg2xx_game_mysprt_plus_state::machine_start()
{
spg2xx_game_state::machine_start();
@ -77,7 +83,7 @@ void spg2xx_game_mysprtch_state::machine_start()
save_item(NAME(m_bank_enabled));
}
void spg2xx_game_mysprtch_state::machine_reset()
void spg2xx_game_mysprt_plus_state::machine_reset()
{
spg2xx_game_state::machine_reset();
@ -89,7 +95,7 @@ void spg2xx_game_mysprtch_state::machine_reset()
m_maincpu->reset();
}
void spg2xx_game_mysprtch24_state::machine_reset()
void spg2xx_game_mysprt_orig_state::machine_reset()
{
spg2xx_game_state::machine_reset();
@ -237,11 +243,89 @@ static INPUT_PORTS_START( mgt20in1 ) // this seems to expect rotated controls by
INPUT_PORTS_END
WRITE16_MEMBER(spg2xx_game_mysprtch_state::porta_w)
WRITE16_MEMBER(spg2xx_game_mysprt_orig_state::porta_w)
{
logerror("%s: porta_w %04x\n", machine().describe_context(), data);
// this seems like nice clean logic, based on writes and how the port direction is set,
// mysprtch and mysptqvc work fine with this logic, but mysprtcp is more problematic, especially in test mode, see other function
// this is rather ugly guesswork based on use and testmode
logerror("%s: porta_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');
int oldrombank = m_mysprtch_rombase;
if (mem_mask & 0x0400)
{
if (data & 0x0400)
m_mysprtch_rombase |= 1;
else
m_mysprtch_rombase &= ~1;
}
if (mem_mask & 0x0800)
{
if (data & 0x0800)
m_mysprtch_rombase |= 2;
else
m_mysprtch_rombase &= ~2;
}
if (mem_mask & 0x0200)
{
if (data & 0x0200)
m_mysprtch_rombase &= ~4; // inverted
else
m_mysprtch_rombase |= 4;
}
if (oldrombank != m_mysprtch_rombase)
m_maincpu->invalidate_cache();
m_prev_porta = data;
}
WRITE16_MEMBER(spg2xx_game_mysprt_plus_state::porta_w)
{
// this is very ugly guesswork based on use and testmode
// what is even more problematic here is that mysprtcp has mem_mask as 0x0000, ie all ports are set to INPUT mode?! so we can't use mem_mask to
// see if a port is active. Using mem_mask works fine for the other sets, as port direction gets set as expected by the spg2xx_io core
logerror("%s: porta_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');
int oldrombank = m_mysprtch_rombase;
if ((m_prev_porta & 0x00ff) != (data & 0x00ff))
{
@ -275,51 +359,29 @@ WRITE16_MEMBER(spg2xx_game_mysprtch_state::porta_w)
m_mysprtch_rombase = bank;
}
m_prev_porta = data;
}
WRITE16_MEMBER(spg2xx_game_mysprtch24_state::porta_w)
{
logerror("%s: porta_w %04x\n", machine().describe_context(), data);
// this is rather ugly guesswork based on use and testmode
// the game writes 0x0000 to the ports during startup, which would cause an incorrect bank
// but this value can't just be ignored when we want to bank there
// so only bank if running from RAM
// probably should be the same logic for both games, as the test mode on this one proves
// that the logic in spg2xx_game_mysprtch_state::porta_w is incorrect
if (m_maincpu->pc() < 0x4000)
{
int bank = 0;
bank |= (data & 0x0400) ? 1 : 0;
bank |= (data & 0x0800) ? 2 : 0;
bank |= (data & 0x0200) ? 0 : 4; // inverted
m_mysprtch_rombase = bank;
}
if (oldrombank != m_mysprtch_rombase)
m_maincpu->invalidate_cache();
m_prev_porta = data;
}
void spg2xx_game_mysprtch_state::mysprtch(machine_config& config)
void spg2xx_game_mysprt_plus_state::mysprtch(machine_config& config)
{
SPG24X(config, m_maincpu, XTAL(27'000'000), m_screen);
m_maincpu->set_addrmap(AS_PROGRAM, &spg2xx_game_mysprtch_state::mem_map_mysprtch);
m_maincpu->set_addrmap(AS_PROGRAM, &spg2xx_game_mysprt_plus_state::mem_map_mysprtch);
m_maincpu->set_force_no_drc(true); // uses JVS opcode, not implemented in recompiler
spg2xx_base(config);
m_maincpu->porta_in().set(FUNC(spg2xx_game_mysprtch_state::base_porta_r));
m_maincpu->portb_in().set(FUNC(spg2xx_game_mysprtch_state::base_portb_r));
m_maincpu->portc_in().set(FUNC(spg2xx_game_mysprtch_state::base_portc_r));
m_maincpu->porta_in().set(FUNC(spg2xx_game_mysprt_plus_state::base_porta_r));
m_maincpu->portb_in().set(FUNC(spg2xx_game_mysprt_plus_state::base_portb_r));
m_maincpu->portc_in().set(FUNC(spg2xx_game_mysprt_plus_state::base_portc_r));
m_maincpu->porta_out().set(FUNC(spg2xx_game_mysprtch_state::porta_w));
m_maincpu->porta_out().set(FUNC(spg2xx_game_mysprt_plus_state::porta_w));
}
void spg2xx_game_mysprtch_state::mgt20in1(machine_config& config)
void spg2xx_game_mysprt_plus_state::mgt20in1(machine_config& config)
{
mysprtch(config);
@ -327,7 +389,7 @@ void spg2xx_game_mysprtch_state::mgt20in1(machine_config& config)
m_screen->set_refresh_hz(50);
}
void spg2xx_game_mysprtch_state::init_mysprtcp()
void spg2xx_game_mysprt_plus_state::init_mysprtcp()
{
uint16_t *ROM = (uint16_t*)memregion("maincpu")->base();
int size = memregion("maincpu")->bytes();
@ -345,7 +407,7 @@ void spg2xx_game_mysprtch_state::init_mysprtcp()
void spg2xx_game_mysprtch_state::init_mgt20in1()
void spg2xx_game_mysprt_plus_state::init_mgt20in1()
{
uint16_t *ROM = (uint16_t*)memregion("maincpu")->base();
int size = memregion("maincpu")->bytes();
@ -380,10 +442,10 @@ void spg2xx_game_mysprtch_state::init_mgt20in1()
}
}
ROM_START( mysprtcp )
ROM_REGION( 0x2000000, "maincpu", ROMREGION_ERASE00 )
ROM_LOAD16_WORD_SWAP( "mysportschallengeplus.bin", 0x0000, 0x2000000, CRC(6911d19c) SHA1(c71bc38595e5505434395b6d59320caabfc7bce3) )
ROM_START( mysprtch )
ROM_REGION( 0x2000000, "maincpu", ROMREGION_ERASE00 ) // SOP64 M6MLT947, has two /CE lines so internally this '24MByte / 192Mbit' chip is likely 2 ROM dies in a single package
ROM_LOAD16_WORD_SWAP( "senariomysportschallengesop64h.bin", 0x0000000, 0x1000000, CRC(3714df21) SHA1(f725dad48b9dfeba188879a6fd28652a7330d3e5) )
ROM_LOAD16_WORD_SWAP( "senariomysportschallengesop64l.bin", 0x1000000, 0x0800000, CRC(0f71099f) SHA1(6e4b9ce329edbb6f0b962cb5669e04c6bd209596) )
ROM_END
ROM_START( mysptqvc )
@ -391,26 +453,21 @@ ROM_START( mysptqvc )
ROM_LOAD16_WORD_SWAP( "qvcmysportschallenge.bin", 0x0000000, 0x2000000, CRC(04783adc) SHA1(a173145ec307fc12f231d3e3f6efa60f8c2f0c89) ) // last 8MB is unused
ROM_END
ROM_START( mysprtch )
ROM_REGION( 0x2000000, "maincpu", ROMREGION_ERASE00 ) // SOP64 M6MLT947, has two /CE lines so internally this '24MByte / 192Mbit' chip is likely 2 ROM dies in a single package
ROM_LOAD16_WORD_SWAP( "senariomysportschallengesop64h.bin", 0x0000000, 0x1000000, CRC(3714df21) SHA1(f725dad48b9dfeba188879a6fd28652a7330d3e5) )
ROM_LOAD16_WORD_SWAP( "senariomysportschallengesop64l.bin", 0x1000000, 0x0800000, CRC(0f71099f) SHA1(6e4b9ce329edbb6f0b962cb5669e04c6bd209596) )
ROM_START( mysprtcp )
ROM_REGION( 0x2000000, "maincpu", ROMREGION_ERASE00 )
ROM_LOAD16_WORD_SWAP( "mysportschallengeplus.bin", 0x0000, 0x2000000, CRC(6911d19c) SHA1(c71bc38595e5505434395b6d59320caabfc7bce3) )
ROM_END
ROM_START( mgt20in1 )
ROM_REGION( 0x1000000, "maincpu", ROMREGION_ERASE00 )
ROM_LOAD16_WORD_SWAP( "m29gl128.u2", 0x000000, 0x1000000, CRC(41d594e3) SHA1(351890455bed28bcaf173d8fd9a4cc997c404d94) )
ROM_END
// Unit with Blue surround to power button. Box shows 'Wireless Sports Plus' but title screen shots "My Sports Challenge Plus" Appears to be V-Tac developed as it has the common V-Tac test mode.
CONS( 200?, mysprtcp, 0, 0, mysprtch, mysprtch, spg2xx_game_mysprtch_state, init_mysprtcp, "Senario / V-Tac Technology Co Ltd.", "My Sports Challenge Plus / Wireless Sports Plus", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS )
// Original release, with 24MB ROM package, Unit has Black surround to power button
CONS( 200?, mysprtch, 0, 0, mysprtch, mysprtch, spg2xx_game_mysprt_orig_state, init_mysprtcp, "Senario / V-Tac Technology Co Ltd.", "My Sports Challenge (5-in-1 version)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS )
// from a QVC licensed unit with a different physical shape etc. uses a 32MByte rom with only 24MByte used
CONS( 200?, mysptqvc, 0, 0, mysprtch, mysprtch, spg2xx_game_mysprtch24_state, init_mysprtcp, "Senario / V-Tac Technology Co Ltd. (QVC license)", "My Sports Challenge (6-in-1 version, QVC license)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS )
CONS( 200?, mysprtch, 0, 0, mysprtch, mysprtch, spg2xx_game_mysprtch24_state, init_mysprtcp, "Senario / V-Tac Technology Co Ltd.", "My Sports Challenge (5-in-1 version)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS )
CONS( 200?, mysptqvc, 0, 0, mysprtch, mysprtch, spg2xx_game_mysprt_orig_state, init_mysprtcp, "Senario / V-Tac Technology Co Ltd. (QVC license)", "My Sports Challenge (6-in-1 version, QVC license)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS )
// Unit is same shape as regular (non-QVC release) but with Blue surround to power button. Box shows 'Wireless Sports Plus' but title screen shots "My Sports Challenge Plus" Appears to be V-Tac developed as it has the common V-Tac test mode.
CONS( 200?, mysprtcp, 0, 0, mysprtch, mysprtch, spg2xx_game_mysprt_plus_state, init_mysprtcp, "Senario / V-Tac Technology Co Ltd.", "My Sports Challenge Plus / Wireless Sports Plus", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS )
// 2009 date on PCB, not actually in German, so maybe sold under different brands?
CONS( 2009, mgt20in1, 0, 0, mgt20in1, mgt20in1, spg2xx_game_mysprtch_state, init_mgt20in1, "MGT", "MGT 20-in-1 TV-Spielekonsole (Germany)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS )
CONS( 2009, mgt20in1, 0, 0, mgt20in1, mgt20in1, spg2xx_game_mysprt_plus_state, init_mgt20in1, "MGT", "MGT 20-in-1 TV-Spielekonsole (Germany)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS )

View File

@ -19,12 +19,10 @@ public:
void mem_map_zon32bit(address_map &map);
void init_zon32bit() { m_game = 0; };
void init_mywicodx() { m_game = 1; };
protected:
virtual void machine_start() override;
virtual void machine_reset() override;
virtual void device_post_load() override;
DECLARE_READ16_MEMBER(z32_rom_r);
@ -38,17 +36,35 @@ protected:
virtual DECLARE_WRITE16_MEMBER(portb_w) override;
virtual DECLARE_WRITE16_MEMBER(portc_w) override;
private:
int m_porta_dat;
int m_portb_dat;
int m_portc_dat;
int m_porta_mask;
int m_upperbank;
int m_hackbank;
int m_game;
int m_basebank;
};
class mywicodx_state : public zon32bit_state
{
public:
mywicodx_state(const machine_config& mconfig, device_type type, const char* tag) :
zon32bit_state(mconfig, type, tag)
{ }
protected:
virtual DECLARE_WRITE16_MEMBER(porta_w) override;
virtual void machine_reset() override;
};
void zon32bit_state::device_post_load()
{
// load state can change the bank, so we must invalide cache
m_maincpu->invalidate_cache();
}
READ16_MEMBER(zon32bit_state::porta_r)
{
return m_porta_dat;
@ -57,33 +73,84 @@ READ16_MEMBER(zon32bit_state::porta_r)
WRITE16_MEMBER(zon32bit_state::porta_w)
{
//if (data != 0x0101)
// logerror("%s: porta_w (%04x)\n", machine().describe_context(), data);
if (0)
logerror("%s: porta_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');
m_porta_dat = data;
// where is the banking?! this gets written from the RAM-based code when the lower bank needs to change, but the upper bank needs to change in places too
// (and all these bits get unset again after this write, so this probably isn't the bank)
// The banking on zon32bit doesn't seem the same as mywicodx.
// The same values get written here both in the case of switching to upper bank and switching to lower bank, so presumably it must be some kind of toggle
if (data == 0x0e01)
{
m_hackbank ^= 1;
m_basebank ^= 1;
logerror("bank is now %d\n", m_basebank);
m_maincpu->invalidate_cache();
}
if (data == 0x0301)
{
m_hackbank = 2;
}
/*
if (data == 0x0335)
{
logerror("%s: port a write 0x0355, port c is %04x %04X\n", machine().describe_context(), data, data & 0x1800);
m_upperbank = (m_portc_dat & 0x1800);
}
*/
}
WRITE16_MEMBER(mywicodx_state::porta_w)
{
if (0)
logerror("%s: porta_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');
m_porta_dat = data;
int oldbank = m_basebank;
if (mem_mask & 0x0400)
{
if (data & 0x0400)
m_basebank |= 1;
else
m_basebank &= ~1;
}
if (mem_mask & 0x0800)
{
if (data & 0x0800)
m_basebank |= 2;
else
m_basebank &= ~2;
}
if (oldbank != m_basebank)
m_maincpu->invalidate_cache();
}
READ16_MEMBER(zon32bit_state::portc_r)
{
// 0x03ff seem to be inputs for buttons (and some kind of output?)
@ -107,7 +174,7 @@ READ16_MEMBER(zon32bit_state::portb_r)
WRITE16_MEMBER(zon32bit_state::portb_w)
{
if (data != 0x0001)
logerror("%s: portb_w (%04x)\n", machine().describe_context(), data);
logerror("%s: portb_w %04x (%04x)\n", machine().describe_context(), data, mem_mask);
m_portb_dat = data;
}
@ -116,82 +183,47 @@ WRITE16_MEMBER(zon32bit_state::portc_w)
{
// very noisy
// is the code actually sending the sound to the remotes?
if (0)
logerror("%s: portc_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');
//logerror("%s: portc_w (%04x)\n", machine().describe_context(), data);
int oldbank = m_upperbank;
//if ((pc >= 0x77261) && (pc <= 0x77268))
// logerror("%s: port c %04x %04X-- BANK STUFF\n", machine().describe_context(), data, data & 0x1800);
//logerror("%s: port c %04x %04x\n", machine().describe_context(), data, data & 0x1800);
/*
this logic seems to apply for some of the mini-games, but cases where the lower bank doesn't change, this sequence doesn't happen either...
we can only trigger bank on 0335 writes, because it gets lost shortly after (unless that's an issue with the io code in spg2xx_io.cpp)
':maincpu' (077250): port c 0000 0000
':maincpu' (077263): port c fe00 1800-- BANK STUFF
':maincpu' (0677DC): porta_w (0311)
':maincpu' (0677E9): porta_w (0301)
':maincpu' (0677F6): porta_w (0335) // bank take effect?
':maincpu' (067803): port c fc00 1800
':maincpu' (067810): port c fe00 1800
':maincpu' (06781B): port c f800 1800
*/
// bits 0x0600 are explicitly set when changing bank, but this logic doesn't work for all cases, causes bad bank changes after boot in some games
#if 0
if ((data & 0x0600) == (0x0600))
if (mem_mask & 0x1000)
{
if ((m_portc_dat & 0x0600) != 0x0600)
m_upperbank = data & 0x1800;
if (data & 0x1000)
m_upperbank |= 0x1000;
else
m_upperbank &= ~0x1000;
}
#else // ugly PC based hacked to ensure we always have the correct bank
int pc = m_maincpu->pc();
if (m_game == 0)
if (mem_mask & 0x0800)
{
if ((pc == 0x077263) && m_hackbank == 1) // when using upper code bank
{
//printf("zon32bit change upper bank from upper code bank %04x\n", data & 0x1800);
m_upperbank = data & 0x1800;
}
if ((pc == 0x05ff63) && m_hackbank == 0) // when using lower code bank
{
//printf("zon32bit change upper bank from lower code bank %04x\n", data & 0x1800);
m_upperbank = data & 0x1800;
}
if (data & 0x0800)
m_upperbank |= 0x0800;
else
m_upperbank &= ~0x0800;
}
else if (m_game == 1)
{
if ((pc == 0x09369c) && m_hackbank == 0) // when using lower code bank
{
printf("mywicodx change upper bank from main menu code bank %04x\n", data & 0x1800);
m_upperbank = data & 0x1800;
}
if ((pc == 0x530) && m_hackbank == 1)
{
printf("mywicodx change upper bank from other menu code bank %04x\n", data & 0x1800);
m_upperbank = data & 0x1800;
}
if ((pc == 0x159E2) && m_hackbank == 2)
{
printf("mywicodx change guitar music bank %04x\n", data & 0x1800);
m_upperbank = data & 0x1800;
}
}
#endif
if (oldbank != m_basebank)
m_maincpu->invalidate_cache();
m_portc_dat = data;
//077261: r4 = r2
//077262: [r4] = r3 // writes to 3d0b (port c?)
//077263: sp += 04
}
@ -203,86 +235,28 @@ void zon32bit_state::mem_map_zon32bit(address_map &map)
READ16_MEMBER(zon32bit_state::z32_rom_r)
{
/*
This has upper and lower bank, which can be changed independently.
Banking hookup is currently very hacky as bank values are written
to ports then erased at the moment, maybe they latch somehow?
This has upper and lower bank, which can be changed independently.
Banking hookup is currently very hacky as bank values are written
to ports then erased at the moment, maybe they latch somehow?
*/
if (m_game == 0) // zon32bit
{
if (offset < 0x200000)
{
if (m_hackbank == 0) // if lower bank is 0
return m_romregion[offset + 0x000000];
else
{ // if lower bank is 1
return m_romregion[offset + 0x400000];
}
}
else
{
offset &= 0x1fffff;
int base = 0x0000000;
if (m_hackbank == 0) // if lower bank is 0
{
if ((m_upperbank & 0x1800) == 0x1000) return m_romregion[offset + (0x0400000 / 2)]; // this upper bank is needed to boot to the menu
else if ((m_upperbank & 0x1800) == 0x0800) return m_romregion[offset + (0x1000000 / 2)]; // golf, tennis, several mini games
else if ((m_upperbank & 0x1800) == 0x1800) return m_romregion[offset + (0x1400000 / 2)]; // baseball, more minigames
else if ((m_upperbank & 0x1800) == 0x0000) return m_romregion[offset + (0x0400000 / 2)]; // ? (not used?)
}
else // if lower bank is 1
{
// these banks are used for different 'mini' games (and boxing) with the 2nd lower bank enabled
if ((m_upperbank & 0x1800) == 0x1000) return m_romregion[offset + (0x0c00000 / 2)]; // 31-44 some mini games
else if ((m_upperbank & 0x1800) == 0x0800) return m_romregion[offset + (0x1800000 / 2)]; // 45-49 some mini games + boxing
else if ((m_upperbank & 0x1800) == 0x1800) return m_romregion[offset + (0x1c00000 / 2)]; // 50-59 some mini games
else if ((m_upperbank & 0x1800) == 0x0000) return m_romregion[offset + (0x0400000 / 2)]; // ? (not used?)
}
}
if (m_basebank & 2) base |= 0x2000000;
if (m_basebank & 1) base |= 0x1000000;
if (offset < 0x200000)
{
return m_romregion[offset + (base / 2)];
}
else if (m_game == 1) // mywicodx
else
{
if (offset < 0x200000)
{
if (m_hackbank == 0) // if lower bank is 0 (main menu)
{
return m_romregion[offset + (0x2000000 / 2)];
}
else if (m_hackbank == 1) // if lower bank is 0 (debug menu code / extra cames)
{
return m_romregion[offset + (0x3000000 / 2)];
}
else // Mi Guitar
{
return m_romregion[offset + (0x0000000 / 2)];
}
}
else
{
offset &= 0x1fffff;
offset &= 0x1fffff;
if (m_hackbank == 0)
{
if ((m_upperbank & 0x1800) == 0x1000) return m_romregion[offset + (0x2400000 / 2)]; // this upper bank is needed to boot to the menu, boxing
else if ((m_upperbank & 0x1800) == 0x0800) return m_romregion[offset + (0x2800000 / 2)]; // ? tennis, golf
else if ((m_upperbank & 0x1800) == 0x1800) return m_romregion[offset + (0x2c00000 / 2)]; // ? table tennis, bowling, basketball, baseball
else if ((m_upperbank & 0x1800) == 0x0000) return m_romregion[offset + (0x2400000 / 2)]; // ? (not used?)
}
else if (m_hackbank == 1)
{
if ((m_upperbank & 0x1800) == 0x1000) return m_romregion[offset + (0x3400000 / 2)]; // base code for other bank
else if ((m_upperbank & 0x1800) == 0x0800) return m_romregion[offset + (0x3800000 / 2)]; //
else if ((m_upperbank & 0x1800) == 0x1800) return m_romregion[offset + (0x3c00000 / 2)]; //
else if ((m_upperbank & 0x1800) == 0x0000) return m_romregion[offset + (0x3400000 / 2)]; //
}
else
{
if ((m_upperbank & 0x1800) == 0x1000) return m_romregion[offset + (0x0400000 / 2)]; // song data 1
else if ((m_upperbank & 0x1800) == 0x0800) return m_romregion[offset + (0x0800000 / 2)]; // song data 2
else if ((m_upperbank & 0x1800) == 0x1800) return m_romregion[offset + (0x0c00000 / 2)]; // song data 3
else if ((m_upperbank & 0x1800) == 0x0000) return m_romregion[offset + (0x0400000 / 2)]; //
}
}
if (m_upperbank & 0x1000) base |= 0x0400000;
if (m_upperbank & 0x0800) base |= 0x0800000;
return m_romregion[offset + (base / 2)];
}
return 0x0000;// m_romregion[offset];
@ -291,6 +265,13 @@ READ16_MEMBER(zon32bit_state::z32_rom_r)
void zon32bit_state::machine_start()
{
spg2xx_game_state::machine_start();
save_item(NAME(m_porta_dat));
save_item(NAME(m_portb_dat));
save_item(NAME(m_portc_dat));
save_item(NAME(m_porta_mask));
save_item(NAME(m_upperbank));
save_item(NAME(m_basebank));
}
@ -298,10 +279,18 @@ void zon32bit_state::machine_reset()
{
spg2xx_game_state::machine_reset();
m_porta_dat = 0x0000;
m_porta_dat = 0xffff;
m_portb_dat = 0x0000;
m_hackbank = 0;
m_basebank = 0;
m_maincpu->invalidate_cache();
}
void mywicodx_state::machine_reset()
{
zon32bit_state::machine_reset();
m_basebank = 3;
m_maincpu->invalidate_cache();
}
@ -443,7 +432,6 @@ void zon32bit_state::zon32bit(machine_config &config)
{
SPG24X(config, m_maincpu, XTAL(27'000'000), m_screen);
m_maincpu->set_addrmap(AS_PROGRAM, &zon32bit_state::mem_map_zon32bit);
m_maincpu->set_force_no_drc(true); // uses JVS opcode, not implemented in recompiler
spg2xx_base(config);
@ -464,15 +452,18 @@ ROM_END
ROM_START( zon32bit )
ROM_REGION( 0x2000000, "maincpu", ROMREGION_ERASE00 )
ROM_LOAD16_WORD_SWAP( "41sports.bin", 0x0000, 0x2000000, CRC(86eee6e0) SHA1(3f6cab6649aebf596de5a8af21658bb1a27edb10) )
ROM_REGION( 0x2000000, "maincpu", ROMREGION_ERASE00 ) // probably should just swap upper 2 line of ROM, as pinout was unknown
ROM_LOAD16_WORD_SWAP( "41sports.bin", 0x0000000, 0x0800000, CRC(86eee6e0) SHA1(3f6cab6649aebf596de5a8af21658bb1a27edb10) )
ROM_CONTINUE(0x1000000, 0x0800000)
ROM_CONTINUE(0x0800000, 0x0800000)
ROM_CONTINUE(0x1800000, 0x0800000)
ROM_END
// Box advertises this as '40 Games Included' but the cartridge, which was glued directly to the PCB, not removable, is a 41-in-1. Maybe some versions exist with a 40 game selection.
CONS( 200?, zon32bit, 0, 0, zon32bit, zon32bit, zon32bit_state, init_zon32bit, "Jungle Soft / Ultimate Products (HK) Ltd", "Zone 32-bit Gaming Console System (Family Sport 41-in-1)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS )
CONS( 200?, zon32bit, 0, 0, zon32bit, zon32bit, zon32bit_state, empty_init, "Jungle Soft / Ultimate Products (HK) Ltd", "Zone 32-bit Gaming Console System (Family Sport 41-in-1)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS )
// My Wico Deluxe was also available under the MiWi brand (exact model unknown, but it was a cart there instead of built in)
// Box claimed 53 Arcade Games + 8 Sports games + 24 Music games, although it's unclear where 24 Music Games comes from, there are 3, which are identical aside from the title screen.
// The Mi Guitar menu contains 24 games, but they're dupes, and just counting those would exclude the other Mi Fit and Mi Papacon menus (which also contain dupes)
CONS( 200?, mywicodx, 0, 0, zon32bit, zon32bit, zon32bit_state, init_mywicodx, "<unknown>", "My Wico Deluxe (Family Sport 85-in-1)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS )
CONS( 200?, mywicodx, 0, 0, zon32bit, zon32bit, mywicodx_state, empty_init, "<unknown>", "My Wico Deluxe (Family Sport 85-in-1)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS )