mirror of
https://github.com/holub/mame
synced 2025-06-06 21:03:47 +03:00
(MESS) megadriv.c: many updates to cart handling [Fabio Priuli]
- updated carts to be slot devices - simplified loading and bankswitch mechanism - added support for real Sonic & Knuckles lock-on emulation (you can combine it freely with other carts, through the -cart2 slot which gets added automatically) - remove need for "pcb_type" feature from xml softlist, since the new "slot" feature is enough - moved SVP emulation to src/mess/ in view of conversion to a slot device as well
This commit is contained in:
parent
7c37d1945e
commit
6d7b97aca4
16
.gitattributes
vendored
16
.gitattributes
vendored
@ -4852,7 +4852,6 @@ src/mame/machine/mc8123.c svneol=native#text/plain
|
|||||||
src/mame/machine/mc8123.h svneol=native#text/plain
|
src/mame/machine/mc8123.h svneol=native#text/plain
|
||||||
src/mame/machine/mcr.c svneol=native#text/plain
|
src/mame/machine/mcr.c svneol=native#text/plain
|
||||||
src/mame/machine/mcr68.c svneol=native#text/plain
|
src/mame/machine/mcr68.c svneol=native#text/plain
|
||||||
src/mame/machine/md_cart.c svneol=native#text/plain
|
|
||||||
src/mame/machine/mega32x.c svneol=native#text/plain
|
src/mame/machine/mega32x.c svneol=native#text/plain
|
||||||
src/mame/machine/mega32x.h svneol=native#text/plain
|
src/mame/machine/mega32x.h svneol=native#text/plain
|
||||||
src/mame/machine/megacd.c svneol=native#text/plain
|
src/mame/machine/megacd.c svneol=native#text/plain
|
||||||
@ -4860,7 +4859,6 @@ src/mame/machine/megacd.h svneol=native#text/plain
|
|||||||
src/mame/machine/megacdcd.c svneol=native#text/plain
|
src/mame/machine/megacdcd.c svneol=native#text/plain
|
||||||
src/mame/machine/megacdcd.h svneol=native#text/plain
|
src/mame/machine/megacdcd.h svneol=native#text/plain
|
||||||
src/mame/machine/megadriv.c svneol=native#text/plain
|
src/mame/machine/megadriv.c svneol=native#text/plain
|
||||||
src/mame/machine/megasvp.c svneol=native#text/plain
|
|
||||||
src/mame/machine/megavdp.c svneol=native#text/plain
|
src/mame/machine/megavdp.c svneol=native#text/plain
|
||||||
src/mame/machine/megavdp.h svneol=native#text/plain
|
src/mame/machine/megavdp.h svneol=native#text/plain
|
||||||
src/mame/machine/meters.c svneol=native#text/plain
|
src/mame/machine/meters.c svneol=native#text/plain
|
||||||
@ -6453,6 +6451,7 @@ src/mess/includes/mboard.h svneol=native#text/plain
|
|||||||
src/mess/includes/mc1000.h svneol=native#text/plain
|
src/mess/includes/mc1000.h svneol=native#text/plain
|
||||||
src/mess/includes/mc68328.h svneol=native#text/plain
|
src/mess/includes/mc68328.h svneol=native#text/plain
|
||||||
src/mess/includes/mc80.h svneol=native#text/plain
|
src/mess/includes/mc80.h svneol=native#text/plain
|
||||||
|
src/mess/includes/md.h svneol=native#text/plain
|
||||||
src/mess/includes/micronic.h svneol=native#text/plain
|
src/mess/includes/micronic.h svneol=native#text/plain
|
||||||
src/mess/includes/microtan.h svneol=native#text/plain
|
src/mess/includes/microtan.h svneol=native#text/plain
|
||||||
src/mess/includes/mikro80.h svneol=native#text/plain
|
src/mess/includes/mikro80.h svneol=native#text/plain
|
||||||
@ -7239,6 +7238,19 @@ src/mess/machine/mc6846.h svneol=native#text/plain
|
|||||||
src/mess/machine/mc6854.c svneol=native#text/plain
|
src/mess/machine/mc6854.c svneol=native#text/plain
|
||||||
src/mess/machine/mc6854.h svneol=native#text/plain
|
src/mess/machine/mc6854.h svneol=native#text/plain
|
||||||
src/mess/machine/mc80.c svneol=native#text/plain
|
src/mess/machine/mc80.c svneol=native#text/plain
|
||||||
|
src/mess/machine/md_eeprom.c svneol=native#text/plain
|
||||||
|
src/mess/machine/md_eeprom.h svneol=native#text/plain
|
||||||
|
src/mess/machine/md_jcart.c svneol=native#text/plain
|
||||||
|
src/mess/machine/md_jcart.h svneol=native#text/plain
|
||||||
|
src/mess/machine/md_rom.c svneol=native#text/plain
|
||||||
|
src/mess/machine/md_rom.h svneol=native#text/plain
|
||||||
|
src/mess/machine/md_sk.c svneol=native#text/plain
|
||||||
|
src/mess/machine/md_sk.h svneol=native#text/plain
|
||||||
|
src/mess/machine/md_slot.c svneol=native#text/plain
|
||||||
|
src/mess/machine/md_slot.h svneol=native#text/plain
|
||||||
|
src/mess/machine/md_stm95.c svneol=native#text/plain
|
||||||
|
src/mess/machine/md_stm95.h svneol=native#text/plain
|
||||||
|
src/mess/machine/megasvp.c svneol=native#text/plain
|
||||||
src/mess/machine/mface2.c svneol=native#text/plain
|
src/mess/machine/mface2.c svneol=native#text/plain
|
||||||
src/mess/machine/mface2.h svneol=native#text/plain
|
src/mess/machine/mface2.h svneol=native#text/plain
|
||||||
src/mess/machine/micropolis.c svneol=native#text/plain
|
src/mess/machine/micropolis.c svneol=native#text/plain
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -115,7 +115,7 @@ ROM_END
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DRIVER_INIT_MEMBER(md_cons_state,hshavoc)
|
DRIVER_INIT_MEMBER(md_havoc_state,hshavoc)
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
UINT16 *src = (UINT16 *)machine().root_device().memregion("maincpu")->base();
|
UINT16 *src = (UINT16 *)machine().root_device().memregion("maincpu")->base();
|
||||||
@ -227,5 +227,5 @@ DRIVER_INIT_MEMBER(md_cons_state,hshavoc)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
GAME( 1993, hshavoc, 0, md_bootleg, hshavoc, md_cons_state, hshavoc, ROT0, "Data East", "High Seas Havoc",GAME_NOT_WORKING )
|
GAME( 1993, hshavoc, 0, md_bootleg, hshavoc, md_havoc_state, hshavoc, ROT0, "Data East", "High Seas Havoc",GAME_NOT_WORKING )
|
||||||
//GAME( 1993, hshavoc2, hshavoc, md_bootleg, hshavoc, md_cons_state, genesis, ROT0, "Data East", "High Seas Havoc (Genesis ROM)",GAME_NOT_WORKING )
|
//GAME( 1993, hshavoc2, hshavoc, md_bootleg, hshavoc, md_havoc_state, genesis, ROT0, "Data East", "High Seas Havoc (Genesis ROM)",GAME_NOT_WORKING )
|
||||||
|
@ -763,7 +763,7 @@ DRIVER_INIT_MEMBER(md_boot_state,srmdb)
|
|||||||
DRIVER_INIT_CALL(megadriv);
|
DRIVER_INIT_CALL(megadriv);
|
||||||
}
|
}
|
||||||
|
|
||||||
DRIVER_INIT_MEMBER(md_cons_state,topshoot)
|
DRIVER_INIT_MEMBER(md_boot_state,topshoot)
|
||||||
{
|
{
|
||||||
machine().device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x200050, 0x200051, FUNC(topshoot_200051_r) );
|
machine().device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x200050, 0x200051, FUNC(topshoot_200051_r) );
|
||||||
machine().device("maincpu")->memory().space(AS_PROGRAM).install_read_port(0x200042, 0x200043, "IN0");
|
machine().device("maincpu")->memory().space(AS_PROGRAM).install_read_port(0x200042, 0x200043, "IN0");
|
||||||
@ -785,4 +785,4 @@ GAME( 1993, aladmdb, 0, megadrvb, aladmdb, md_boot_state, aladmdb, ROT0, "b
|
|||||||
GAME( 1996, mk3mdb, 0, megadrvb, mk3mdb, md_boot_state, mk3mdb, ROT0, "bootleg / Midway", "Mortal Kombat 3 (bootleg of Megadrive version)", 0)
|
GAME( 1996, mk3mdb, 0, megadrvb, mk3mdb, md_boot_state, mk3mdb, ROT0, "bootleg / Midway", "Mortal Kombat 3 (bootleg of Megadrive version)", 0)
|
||||||
GAME( 1994, ssf2mdb, 0, megadrvb, ssf2mdb, md_boot_state, ssf2mdb, ROT0, "bootleg / Capcom", "Super Street Fighter II - The New Challengers (bootleg of Japanese MegaDrive version)", 0)
|
GAME( 1994, ssf2mdb, 0, megadrvb, ssf2mdb, md_boot_state, ssf2mdb, ROT0, "bootleg / Capcom", "Super Street Fighter II - The New Challengers (bootleg of Japanese MegaDrive version)", 0)
|
||||||
GAME( 1993, srmdb, 0, megadrvb, srmdb, md_boot_state, srmdb, ROT0, "bootleg / Konami", "Sunset Riders (bootleg of Megadrive version)", 0)
|
GAME( 1993, srmdb, 0, megadrvb, srmdb, md_boot_state, srmdb, ROT0, "bootleg / Konami", "Sunset Riders (bootleg of Megadrive version)", 0)
|
||||||
GAME( 1995, topshoot, 0, md_bootleg, topshoot, md_cons_state, topshoot, ROT0, "Sun Mixing", "Top Shooter", 0)
|
GAME( 1995, topshoot, 0, md_bootleg, topshoot, md_boot_state, topshoot, ROT0, "Sun Mixing", "Top Shooter", 0)
|
||||||
|
@ -599,17 +599,17 @@ static DEVICE_IMAGE_LOAD( megatech_cart )
|
|||||||
{
|
{
|
||||||
if (!mame_stricmp("genesis", pcb_name))
|
if (!mame_stricmp("genesis", pcb_name))
|
||||||
{
|
{
|
||||||
printf("%s is genesis\n", mt_cart->tag);
|
mame_printf_debug("%s is genesis\n", mt_cart->tag);
|
||||||
state->m_cart_is_genesis[this_cart->slot] = 1;
|
state->m_cart_is_genesis[this_cart->slot] = 1;
|
||||||
}
|
}
|
||||||
else if (!mame_stricmp("sms", pcb_name))
|
else if (!mame_stricmp("sms", pcb_name))
|
||||||
{
|
{
|
||||||
printf("%s is sms\n", mt_cart->tag);
|
mame_printf_debug("%s is sms\n", mt_cart->tag);
|
||||||
state->m_cart_is_genesis[this_cart->slot] = 0;
|
state->m_cart_is_genesis[this_cart->slot] = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf("%s is invalid\n", mt_cart->tag);
|
mame_printf_debug("%s is invalid\n", mt_cart->tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -23,13 +23,7 @@
|
|||||||
#define MASTER_CLOCK_PAL 53203424
|
#define MASTER_CLOCK_PAL 53203424
|
||||||
#define SEGACD_CLOCK 12500000
|
#define SEGACD_CLOCK 12500000
|
||||||
|
|
||||||
|
#define MD_CPU_REGION_SIZE 0x800000
|
||||||
#define MAX_MD_CART_SIZE 0x800000
|
|
||||||
|
|
||||||
/* where a fresh copy of rom is stashed for reset and banking setup */
|
|
||||||
#define VIRGIN_COPY_GEN 0xd00000
|
|
||||||
|
|
||||||
#define MD_CPU_REGION_SIZE (MAX_MD_CART_SIZE + VIRGIN_COPY_GEN)
|
|
||||||
|
|
||||||
extern int sega_cd_connected;
|
extern int sega_cd_connected;
|
||||||
|
|
||||||
@ -41,17 +35,12 @@ INPUT_PORTS_EXTERN( megadriv );
|
|||||||
INPUT_PORTS_EXTERN( megadri6 );
|
INPUT_PORTS_EXTERN( megadri6 );
|
||||||
INPUT_PORTS_EXTERN( ssf2mdb );
|
INPUT_PORTS_EXTERN( ssf2mdb );
|
||||||
INPUT_PORTS_EXTERN( mk3mdb );
|
INPUT_PORTS_EXTERN( mk3mdb );
|
||||||
INPUT_PORTS_EXTERN( megdsvp );
|
|
||||||
|
|
||||||
MACHINE_CONFIG_EXTERN( megadriv_timers );
|
MACHINE_CONFIG_EXTERN( megadriv_timers );
|
||||||
MACHINE_CONFIG_EXTERN( md_ntsc );
|
MACHINE_CONFIG_EXTERN( md_ntsc );
|
||||||
MACHINE_CONFIG_EXTERN( md_pal );
|
MACHINE_CONFIG_EXTERN( md_pal );
|
||||||
MACHINE_CONFIG_EXTERN( md_svp );
|
MACHINE_CONFIG_EXTERN( md_svp );
|
||||||
|
|
||||||
MACHINE_CONFIG_EXTERN( megdsvppal );
|
|
||||||
MACHINE_CONFIG_EXTERN( megadriv );
|
|
||||||
MACHINE_CONFIG_EXTERN( megadpal );
|
|
||||||
MACHINE_CONFIG_EXTERN( megdsvp );
|
|
||||||
MACHINE_CONFIG_EXTERN( genesis_32x );
|
MACHINE_CONFIG_EXTERN( genesis_32x );
|
||||||
MACHINE_CONFIG_EXTERN( genesis_32x_pal );
|
MACHINE_CONFIG_EXTERN( genesis_32x_pal );
|
||||||
MACHINE_CONFIG_EXTERN( genesis_scd );
|
MACHINE_CONFIG_EXTERN( genesis_scd );
|
||||||
@ -61,8 +50,7 @@ MACHINE_CONFIG_EXTERN( genesis_scd_mcdj );
|
|||||||
MACHINE_CONFIG_EXTERN( genesis_32x_scd );
|
MACHINE_CONFIG_EXTERN( genesis_32x_scd );
|
||||||
MACHINE_CONFIG_EXTERN( md_bootleg ); // for topshoot.c & hshavoc.c
|
MACHINE_CONFIG_EXTERN( md_bootleg ); // for topshoot.c & hshavoc.c
|
||||||
|
|
||||||
extern UINT16* megadriv_backupram;
|
extern cpu_device *_svp_cpu;
|
||||||
extern int megadriv_backupram_length;
|
|
||||||
|
|
||||||
extern UINT8 megatech_bios_port_cc_dc_r(running_machine &machine, int offset, int ctrl);
|
extern UINT8 megatech_bios_port_cc_dc_r(running_machine &machine, int offset, int ctrl);
|
||||||
extern void megadriv_stop_scanline_timer(running_machine &machine);
|
extern void megadriv_stop_scanline_timer(running_machine &machine);
|
||||||
@ -384,52 +372,16 @@ struct megadriv_cart
|
|||||||
int ssf2_lastoff, ssf2_lastdata;
|
int ssf2_lastoff, ssf2_lastdata;
|
||||||
};
|
};
|
||||||
|
|
||||||
class md_cons_state : public md_base_state
|
class md_havoc_state : public md_base_state
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
md_cons_state(const machine_config &mconfig, device_type type, const char *tag)
|
md_havoc_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||||
: md_base_state(mconfig, type, tag) { }
|
: md_base_state(mconfig, type, tag) { }
|
||||||
|
|
||||||
emu_timer *m_mess_io_timeout[3];
|
|
||||||
int m_mess_io_stage[3];
|
|
||||||
UINT8 m_jcart_io_data[2];
|
|
||||||
|
|
||||||
megadriv_cart m_md_cart;
|
|
||||||
|
|
||||||
DECLARE_DRIVER_INIT(hshavoc);
|
DECLARE_DRIVER_INIT(hshavoc);
|
||||||
DECLARE_DRIVER_INIT(topshoot);
|
|
||||||
|
|
||||||
DECLARE_DRIVER_INIT(genesis);
|
|
||||||
DECLARE_DRIVER_INIT(mess_md_common);
|
|
||||||
DECLARE_DRIVER_INIT(md_eur);
|
|
||||||
DECLARE_DRIVER_INIT(md_jpn);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class mdsvp_state : public md_cons_state
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
mdsvp_state(const machine_config &mconfig, device_type type, const char *tag)
|
|
||||||
: md_cons_state(mconfig, type, tag) { }
|
|
||||||
|
|
||||||
UINT8 *m_iram; // IRAM (0-0x7ff)
|
|
||||||
UINT8 *m_dram; // [0x20000];
|
|
||||||
UINT32 m_pmac_read[6]; // read modes/addrs for PM0-PM5
|
|
||||||
UINT32 m_pmac_write[6]; // write ...
|
|
||||||
PAIR m_pmc;
|
|
||||||
UINT32 m_emu_status;
|
|
||||||
UINT16 m_XST; // external status, mapped at a15000 and a15002 on 68k side.
|
|
||||||
UINT16 m_XST2; // status of XST (bit1 set when 68k writes to XST)
|
|
||||||
};
|
|
||||||
|
|
||||||
ADDRESS_MAP_EXTERN( svp_ssp_map, driver_device );
|
|
||||||
ADDRESS_MAP_EXTERN( svp_ext_map, driver_device );
|
|
||||||
extern void svp_init(running_machine &machine);
|
|
||||||
extern cpu_device *_svp_cpu;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
UINT8 megadrive_io_read_data_port_3button(running_machine &machine, int portnum);
|
UINT8 megadrive_io_read_data_port_3button(running_machine &machine, int portnum);
|
||||||
|
|
||||||
class _32x_state : public md_base_state
|
class _32x_state : public md_base_state
|
||||||
@ -459,13 +411,8 @@ public:
|
|||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*----------- defined in machine/md_cart.c -----------*/
|
|
||||||
|
|
||||||
MACHINE_CONFIG_EXTERN( genesis_cartslot );
|
|
||||||
MACHINE_CONFIG_EXTERN( _32x_cartslot );
|
MACHINE_CONFIG_EXTERN( _32x_cartslot );
|
||||||
MACHINE_CONFIG_EXTERN( pico_cartslot );
|
|
||||||
MACHINE_START( md_sram );
|
|
||||||
|
|
||||||
/*----------- defined in drivers/megadriv.c -----------*/
|
/*----------- defined in drivers/megadriv.c -----------*/
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -30,9 +30,12 @@ Known Non-Issues (confirmed on Real Genesis)
|
|||||||
#include "sound/2612intf.h"
|
#include "sound/2612intf.h"
|
||||||
|
|
||||||
#include "sound/dac.h"
|
#include "sound/dac.h"
|
||||||
|
|
||||||
#include "sound/sn76496.h"
|
#include "sound/sn76496.h"
|
||||||
|
|
||||||
#include "imagedev/chd_cd.h"
|
#include "imagedev/chd_cd.h"
|
||||||
|
#include "imagedev/cartslot.h"
|
||||||
|
#include "formats/imageutl.h"
|
||||||
|
|
||||||
#include "includes/megadriv.h"
|
#include "includes/megadriv.h"
|
||||||
#include "machine/nvram.h"
|
#include "machine/nvram.h"
|
||||||
#include "cpu/ssp1601/ssp1601.h"
|
#include "cpu/ssp1601/ssp1601.h"
|
||||||
@ -40,12 +43,14 @@ Known Non-Issues (confirmed on Real Genesis)
|
|||||||
#include "machine/megavdp.h"
|
#include "machine/megavdp.h"
|
||||||
|
|
||||||
|
|
||||||
|
MACHINE_CONFIG_EXTERN( megadriv );
|
||||||
|
|
||||||
|
|
||||||
static cpu_device *_genesis_snd_z80_cpu;
|
static cpu_device *_genesis_snd_z80_cpu;
|
||||||
int genesis_other_hacks = 0; // misc hacks
|
int genesis_other_hacks = 0; // misc hacks
|
||||||
|
|
||||||
timer_device* megadriv_scanline_timer;
|
timer_device* megadriv_scanline_timer;
|
||||||
|
cpu_device *_svp_cpu;
|
||||||
|
|
||||||
struct genesis_z80_vars
|
struct genesis_z80_vars
|
||||||
{
|
{
|
||||||
@ -318,7 +323,7 @@ UINT8 megadrive_io_read_data_port_3button(running_machine &machine, int portnum)
|
|||||||
{
|
{
|
||||||
UINT8 retdata, helper = (megadrive_io_ctrl_regs[portnum] & 0x7f) | 0x80; // bit 7 always comes from megadrive_io_data_regs
|
UINT8 retdata, helper = (megadrive_io_ctrl_regs[portnum] & 0x7f) | 0x80; // bit 7 always comes from megadrive_io_data_regs
|
||||||
static const char *const pad3names[] = { "PAD1", "PAD2", "IN0", "UNK" };
|
static const char *const pad3names[] = { "PAD1", "PAD2", "IN0", "UNK" };
|
||||||
|
|
||||||
if (megadrive_io_data_regs[portnum] & 0x40)
|
if (megadrive_io_data_regs[portnum] & 0x40)
|
||||||
{
|
{
|
||||||
/* here we read B, C & the directional buttons */
|
/* here we read B, C & the directional buttons */
|
||||||
@ -885,41 +890,6 @@ MACHINE_CONFIG_END
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
INPUT_PORTS_START( megdsvp )
|
|
||||||
PORT_INCLUDE( megadriv )
|
|
||||||
|
|
||||||
PORT_START("MEMORY_TEST") /* special memtest mode */
|
|
||||||
/* Region setting for Console */
|
|
||||||
PORT_DIPNAME( 0x01, 0x00, DEF_STR( Test ) )
|
|
||||||
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
|
|
||||||
PORT_DIPSETTING( 0x01, DEF_STR( On ) )
|
|
||||||
INPUT_PORTS_END
|
|
||||||
|
|
||||||
MACHINE_CONFIG_FRAGMENT( md_svp )
|
|
||||||
MCFG_CPU_ADD("svp", SSP1601, MASTER_CLOCK_NTSC / 7 * 3) /* ~23 MHz (guessed) */
|
|
||||||
MCFG_CPU_PROGRAM_MAP(svp_ssp_map)
|
|
||||||
MCFG_CPU_IO_MAP(svp_ext_map)
|
|
||||||
MACHINE_CONFIG_END
|
|
||||||
|
|
||||||
MACHINE_CONFIG_DERIVED( megdsvp, megadriv )
|
|
||||||
|
|
||||||
MCFG_CPU_ADD("svp", SSP1601, MASTER_CLOCK_NTSC / 7 * 3) /* ~23 MHz (guessed) */
|
|
||||||
MCFG_CPU_PROGRAM_MAP(svp_ssp_map)
|
|
||||||
MCFG_CPU_IO_MAP(svp_ext_map)
|
|
||||||
/* IRQs are not used by this CPU */
|
|
||||||
MACHINE_CONFIG_END
|
|
||||||
|
|
||||||
MACHINE_CONFIG_DERIVED( megdsvppal, megadpal )
|
|
||||||
|
|
||||||
MCFG_CPU_ADD("svp", SSP1601, MASTER_CLOCK_PAL / 7 * 3) /* ~23 MHz (guessed) */
|
|
||||||
MCFG_CPU_PROGRAM_MAP(svp_ssp_map)
|
|
||||||
MCFG_CPU_IO_MAP(svp_ext_map)
|
|
||||||
/* IRQs are not used by this CPU */
|
|
||||||
MACHINE_CONFIG_END
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SCREEN_UPDATE_RGB32(megadriv)
|
SCREEN_UPDATE_RGB32(megadriv)
|
||||||
{
|
{
|
||||||
@ -1030,8 +1000,8 @@ void megadriv_stop_scanline_timer(running_machine &machine)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
UINT16* megadriv_backupram;
|
static UINT16* megadriv_backupram;
|
||||||
int megadriv_backupram_length;
|
static int megadriv_backupram_length;
|
||||||
|
|
||||||
static NVRAM_HANDLER( megadriv )
|
static NVRAM_HANDLER( megadriv )
|
||||||
{
|
{
|
||||||
@ -1190,7 +1160,7 @@ MACHINE_CONFIG_FRAGMENT( md_ntsc )
|
|||||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker",0.25) /* 3.58 MHz */
|
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker",0.25) /* 3.58 MHz */
|
||||||
MACHINE_CONFIG_END
|
MACHINE_CONFIG_END
|
||||||
|
|
||||||
MACHINE_CONFIG_START( megadriv, md_cons_state )
|
MACHINE_CONFIG_START( megadriv, md_base_state )
|
||||||
MCFG_FRAGMENT_ADD(md_ntsc)
|
MCFG_FRAGMENT_ADD(md_ntsc)
|
||||||
MACHINE_CONFIG_END
|
MACHINE_CONFIG_END
|
||||||
|
|
||||||
@ -1245,7 +1215,7 @@ MACHINE_CONFIG_FRAGMENT( md_pal )
|
|||||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker",0.25) /* 3.58 MHz */
|
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker",0.25) /* 3.58 MHz */
|
||||||
MACHINE_CONFIG_END
|
MACHINE_CONFIG_END
|
||||||
|
|
||||||
MACHINE_CONFIG_START( megadpal, md_cons_state )
|
MACHINE_CONFIG_START( megadpal, md_base_state )
|
||||||
MCFG_FRAGMENT_ADD(md_pal)
|
MCFG_FRAGMENT_ADD(md_pal)
|
||||||
MACHINE_CONFIG_END
|
MACHINE_CONFIG_END
|
||||||
|
|
||||||
@ -1295,6 +1265,64 @@ MACHINE_CONFIG_DERIVED( genesis_32x_pal, megadpal )
|
|||||||
|
|
||||||
MACHINE_CONFIG_END
|
MACHINE_CONFIG_END
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******* 32X image loading *******/
|
||||||
|
|
||||||
|
// FIXME: non-softlist loading should keep using ROM_CART_LOAD in the ROM definitions,
|
||||||
|
// once we better integrate softlist with the old loading procedures
|
||||||
|
static DEVICE_IMAGE_LOAD( _32x_cart )
|
||||||
|
{
|
||||||
|
UINT32 length;
|
||||||
|
UINT8 *temp_copy;
|
||||||
|
UINT16 *ROM16;
|
||||||
|
UINT32 *ROM32;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (image.software_entry() == NULL)
|
||||||
|
{
|
||||||
|
length = image.length();
|
||||||
|
temp_copy = auto_alloc_array(image.device().machine(), UINT8, length);
|
||||||
|
image.fread(temp_copy, length);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
length = image.get_software_region_length("rom");
|
||||||
|
temp_copy = auto_alloc_array(image.device().machine(), UINT8, length);
|
||||||
|
memcpy(temp_copy, image.get_software_region("rom"), length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the cart image in the locations the driver expects */
|
||||||
|
// Notice that, by using pick_integer, we are sure the code works on both LE and BE machines
|
||||||
|
ROM16 = (UINT16 *) image.device().machine().root_device().memregion("gamecart")->base();
|
||||||
|
for (i = 0; i < length; i += 2)
|
||||||
|
ROM16[i / 2] = pick_integer_be(temp_copy, i, 2);
|
||||||
|
|
||||||
|
ROM32 = (UINT32 *) image.device().machine().root_device().memregion("gamecart_sh2")->base();
|
||||||
|
for (i = 0; i < length; i += 4)
|
||||||
|
ROM32[i / 4] = pick_integer_be(temp_copy, i, 4);
|
||||||
|
|
||||||
|
ROM16 = (UINT16 *) image.device().machine().root_device().memregion("maincpu")->base();
|
||||||
|
for (i = 0x00; i < length; i += 2)
|
||||||
|
ROM16[i / 2] = pick_integer_be(temp_copy, i, 2);
|
||||||
|
|
||||||
|
auto_free(image.device().machine(), temp_copy);
|
||||||
|
|
||||||
|
return IMAGE_INIT_PASS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MACHINE_CONFIG_FRAGMENT( _32x_cartslot )
|
||||||
|
MCFG_CARTSLOT_ADD("cart")
|
||||||
|
MCFG_CARTSLOT_EXTENSION_LIST("32x,bin")
|
||||||
|
MCFG_CARTSLOT_MANDATORY
|
||||||
|
MCFG_CARTSLOT_INTERFACE("_32x_cart")
|
||||||
|
MCFG_CARTSLOT_LOAD(_32x_cart)
|
||||||
|
MCFG_SOFTWARE_LIST_ADD("cart_list","32x")
|
||||||
|
MACHINE_CONFIG_END
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct cdrom_interface scd_cdrom =
|
struct cdrom_interface scd_cdrom =
|
||||||
{
|
{
|
||||||
"scd_cdrom",
|
"scd_cdrom",
|
||||||
@ -1362,7 +1390,7 @@ void md_base_state::megadriv_init_common()
|
|||||||
_svp_cpu = machine().device<cpu_device>("svp");
|
_svp_cpu = machine().device<cpu_device>("svp");
|
||||||
if (_svp_cpu != NULL)
|
if (_svp_cpu != NULL)
|
||||||
{
|
{
|
||||||
printf("SVP (cpu) found '%s'\n", _svp_cpu->tag() );
|
printf("SVP (cpu) found '%s'\n", _svp_cpu->tag());
|
||||||
}
|
}
|
||||||
|
|
||||||
machine().device("maincpu")->execute().set_irq_acknowledge_callback(device_irq_acknowledge_delegate(FUNC(md_base_state::genesis_int_callback),this));
|
machine().device("maincpu")->execute().set_irq_acknowledge_callback(device_irq_acknowledge_delegate(FUNC(md_base_state::genesis_int_callback),this));
|
||||||
@ -1405,14 +1433,6 @@ void md_base_state::megadriv_init_common()
|
|||||||
}
|
}
|
||||||
mame_printf_debug("\n");
|
mame_printf_debug("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if we have an SVP cpu then do some extra initilization for it */
|
|
||||||
if (_svp_cpu != NULL)
|
|
||||||
{
|
|
||||||
svp_init(machine());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DRIVER_INIT_MEMBER(md_base_state,megadriv_c2)
|
DRIVER_INIT_MEMBER(md_base_state,megadriv_c2)
|
||||||
|
@ -1257,9 +1257,7 @@ $(MAMEOBJ)/sega.a: \
|
|||||||
$(MACHINE)/megacd.o \
|
$(MACHINE)/megacd.o \
|
||||||
$(MACHINE)/megacdcd.o \
|
$(MACHINE)/megacdcd.o \
|
||||||
$(MACHINE)/mega32x.o \
|
$(MACHINE)/mega32x.o \
|
||||||
$(MACHINE)/megasvp.o \
|
|
||||||
$(MACHINE)/megavdp.o \
|
$(MACHINE)/megavdp.o \
|
||||||
$(MACHINE)/md_cart.o \
|
|
||||||
$(DRIVERS)/megadrvb.o \
|
$(DRIVERS)/megadrvb.o \
|
||||||
$(DRIVERS)/megaplay.o \
|
$(DRIVERS)/megaplay.o \
|
||||||
$(DRIVERS)/megatech.o \
|
$(DRIVERS)/megatech.o \
|
||||||
|
@ -1,15 +1,14 @@
|
|||||||
|
|
||||||
#include "emu.h"
|
#include "emu.h"
|
||||||
#include "includes/megadriv.h"
|
#include "includes/md.h"
|
||||||
|
#include "machine/md_slot.h"
|
||||||
|
#include "machine/md_rom.h"
|
||||||
|
//#include "machine/md_svp.h"
|
||||||
|
#include "machine/md_sk.h"
|
||||||
|
#include "machine/md_eeprom.h"
|
||||||
|
#include "machine/md_jcart.h"
|
||||||
|
#include "machine/md_stm95.h"
|
||||||
|
|
||||||
class pico_state : public md_cons_state
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
pico_state(const machine_config &mconfig, device_type type, const char *tag)
|
|
||||||
: md_cons_state(mconfig, type, tag) { }
|
|
||||||
|
|
||||||
UINT8 m_page_register;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*************************************
|
/*************************************
|
||||||
*
|
*
|
||||||
@ -24,37 +23,6 @@ static TIMER_CALLBACK( mess_io_timeout_timer_callback )
|
|||||||
state->m_mess_io_stage[(int)(FPTR)ptr] = -1;
|
state->m_mess_io_stage[(int)(FPTR)ptr] = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* J-Cart controller port */
|
|
||||||
WRITE16_HANDLER( jcart_ctrl_w )
|
|
||||||
{
|
|
||||||
md_cons_state *state = space.machine().driver_data<md_cons_state>();
|
|
||||||
state->m_jcart_io_data[0] = (data & 1) << 6;
|
|
||||||
state->m_jcart_io_data[1] = (data & 1) << 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
READ16_HANDLER( jcart_ctrl_r )
|
|
||||||
{
|
|
||||||
md_cons_state *state = space.machine().driver_data<md_cons_state>();
|
|
||||||
UINT16 retdata = 0;
|
|
||||||
UINT8 joy[2];
|
|
||||||
|
|
||||||
if (state->m_jcart_io_data[0] & 0x40)
|
|
||||||
{
|
|
||||||
joy[0] = state->ioport("JCART3_3B")->read_safe(0);
|
|
||||||
joy[1] = state->ioport("JCART4_3B")->read_safe(0);
|
|
||||||
retdata = (state->m_jcart_io_data[0] & 0x40) | joy[0] | (joy[1] << 8);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
joy[0] = ((state->ioport("JCART3_3B")->read_safe(0) & 0xc0) >> 2) |
|
|
||||||
(state->ioport("JCART3_3B")->read_safe(0) & 0x03);
|
|
||||||
joy[1] = ((state->ioport("JCART4_3B")->read_safe(0) & 0xc0) >> 2) |
|
|
||||||
(state->ioport("JCART4_3B")->read_safe(0) & 0x03);
|
|
||||||
retdata = (state->m_jcart_io_data[0] & 0x40) | joy[0] | (joy[1] << 8);
|
|
||||||
}
|
|
||||||
return retdata;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mess_init_6buttons_pad(running_machine &machine)
|
static void mess_init_6buttons_pad(running_machine &machine)
|
||||||
{
|
{
|
||||||
md_cons_state *state = machine.driver_data<md_cons_state>();
|
md_cons_state *state = machine.driver_data<md_cons_state>();
|
||||||
@ -147,7 +115,12 @@ static UINT8 mess_md_io_read_data_port(running_machine &machine, int portnum)
|
|||||||
/* Otherwise it's a 3 buttons Joypad */
|
/* Otherwise it's a 3 buttons Joypad */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (megadrive_io_data_regs[portnum] & 0x40)
|
// handle test input for SVP test
|
||||||
|
if (portnum == 0 && machine.root_device().ioport("MEMORY_TEST")->read_safe(0x00))
|
||||||
|
{
|
||||||
|
retdata = (megadrive_io_data_regs[0] & 0xc0);
|
||||||
|
}
|
||||||
|
else if (megadrive_io_data_regs[portnum] & 0x40)
|
||||||
{
|
{
|
||||||
/* here we read B, C & the directional buttons */
|
/* here we read B, C & the directional buttons */
|
||||||
retdata = (megadrive_io_data_regs[portnum] & helper_3b) |
|
retdata = (megadrive_io_data_regs[portnum] & helper_3b) |
|
||||||
@ -226,10 +199,6 @@ static INPUT_PORTS_START( md )
|
|||||||
PORT_CONFNAME( 0xf0, 0x00, "Player 2 Controller" )
|
PORT_CONFNAME( 0xf0, 0x00, "Player 2 Controller" )
|
||||||
PORT_CONFSETTING( 0x00, "Joystick 3 Buttons" )
|
PORT_CONFSETTING( 0x00, "Joystick 3 Buttons" )
|
||||||
PORT_CONFSETTING( 0x10, "Joystick 6 Buttons" )
|
PORT_CONFSETTING( 0x10, "Joystick 6 Buttons" )
|
||||||
PORT_CONFNAME( 0xf00, 0x00, "Player 3 Controller (J-Cart)" )
|
|
||||||
PORT_CONFSETTING( 0x00, "Joystick 3 Buttons" )
|
|
||||||
PORT_CONFNAME( 0xf000, 0x00, "Player 4 Controller (J-Cart)" )
|
|
||||||
PORT_CONFSETTING( 0x00, "Joystick 3 Buttons" )
|
|
||||||
|
|
||||||
PORT_START("PAD1_3B") /* Joypad 1 (3 button + start) NOT READ DIRECTLY */
|
PORT_START("PAD1_3B") /* Joypad 1 (3 button + start) NOT READ DIRECTLY */
|
||||||
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x00)
|
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x00)
|
||||||
@ -251,26 +220,6 @@ static INPUT_PORTS_START( md )
|
|||||||
PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_NAME("P2 A") PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x00)
|
PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_NAME("P2 A") PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x00)
|
||||||
PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_START ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x00)
|
PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_START ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x00)
|
||||||
|
|
||||||
PORT_START("JCART3_3B") /* Joypad 3 on J-Cart (3 button + start) */
|
|
||||||
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0xf00, EQUALS, 0x00)
|
|
||||||
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0xf00, EQUALS, 0x00)
|
|
||||||
PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0xf00, EQUALS, 0x00)
|
|
||||||
PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0xf00, EQUALS, 0x00)
|
|
||||||
PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(3) PORT_NAME("P3 B") PORT_CONDITION("CTRLSEL", 0xf00, EQUALS, 0x00)
|
|
||||||
PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(3) PORT_NAME("P3 C") PORT_CONDITION("CTRLSEL", 0xf00, EQUALS, 0x00)
|
|
||||||
PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(3) PORT_NAME("P3 A") PORT_CONDITION("CTRLSEL", 0xf00, EQUALS, 0x00)
|
|
||||||
PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_START ) PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0xf00, EQUALS, 0x00)
|
|
||||||
|
|
||||||
PORT_START("JCART4_3B") /* Joypad 4 on J-Cart (3 button + start) */
|
|
||||||
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf000, EQUALS, 0x00)
|
|
||||||
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf000, EQUALS, 0x00)
|
|
||||||
PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf000, EQUALS, 0x00)
|
|
||||||
PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf000, EQUALS, 0x00)
|
|
||||||
PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(4) PORT_NAME("P4 B") PORT_CONDITION("CTRLSEL", 0xf000, EQUALS, 0x00)
|
|
||||||
PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(4) PORT_NAME("P4 C") PORT_CONDITION("CTRLSEL", 0xf000, EQUALS, 0x00)
|
|
||||||
PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(4) PORT_NAME("P4 A") PORT_CONDITION("CTRLSEL", 0xf000, EQUALS, 0x00)
|
|
||||||
PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_START ) PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf000, EQUALS, 0x00)
|
|
||||||
|
|
||||||
PORT_START("PAD1_6B") /* Joypad 1 (6 button + start + mode) NOT READ DIRECTLY */
|
PORT_START("PAD1_6B") /* Joypad 1 (6 button + start + mode) NOT READ DIRECTLY */
|
||||||
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x01)
|
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x01)
|
||||||
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x01)
|
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x01)
|
||||||
@ -317,8 +266,20 @@ INPUT_PORTS_END
|
|||||||
|
|
||||||
static MACHINE_START( ms_megadriv )
|
static MACHINE_START( ms_megadriv )
|
||||||
{
|
{
|
||||||
|
md_cons_state *state = machine.driver_data<md_cons_state>();
|
||||||
|
|
||||||
mess_init_6buttons_pad(machine);
|
mess_init_6buttons_pad(machine);
|
||||||
MACHINE_START_CALL( md_sram );
|
|
||||||
|
// small hack, until SVP is converted to be a slot device
|
||||||
|
if (machine.device<cpu_device>("svp") != NULL)
|
||||||
|
svp_init(machine);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
machine.device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler(0x000000, 0x7fffff, read16_delegate(FUNC(device_md_cart_interface::read),state->m_slotcart->m_cart), write16_delegate(FUNC(device_md_cart_interface::write),state->m_slotcart->m_cart));
|
||||||
|
machine.device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler(0xa13000, 0xa130ff, read16_delegate(FUNC(device_md_cart_interface::read_a13),state->m_slotcart->m_cart), write16_delegate(FUNC(device_md_cart_interface::write_a13),state->m_slotcart->m_cart));
|
||||||
|
machine.device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler(0xa15000, 0xa150ff, read16_delegate(FUNC(device_md_cart_interface::read_a15),state->m_slotcart->m_cart), write16_delegate(FUNC(device_md_cart_interface::write_a15),state->m_slotcart->m_cart));
|
||||||
|
machine.device("maincpu")->memory().space(AS_PROGRAM).install_write_handler(0xa14000, 0xa14003, write16_delegate(FUNC(device_md_cart_interface::write_tmss_bank),state->m_slotcart->m_cart));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static MACHINE_RESET( ms_megadriv )
|
static MACHINE_RESET( ms_megadriv )
|
||||||
@ -326,6 +287,61 @@ static MACHINE_RESET( ms_megadriv )
|
|||||||
MACHINE_RESET_CALL( megadriv );
|
MACHINE_RESET_CALL( megadriv );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SLOT_INTERFACE_START(md_cart)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom", MD_STD_ROM)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_svp", MD_STD_ROM)
|
||||||
|
// SLOT_INTERFACE_INTERNAL("rom_svp", MD_ROM_SVP) // not ready yet...
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_sk", MD_ROM_SK)
|
||||||
|
// NVRAM handling
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_sram", MD_ROM_SRAM)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_sramsafe", MD_ROM_SRAM)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_fram", MD_ROM_FRAM)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_beggar", MD_ROM_BEGGAR)
|
||||||
|
// EEPROM handling (not supported fully yet)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_eeprom", MD_STD_EEPROM)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_nbajam", MD_EEPROM_NBAJAM)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_nbajamte", MD_EEPROM_NBAJAMTE)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_nflqb", MD_EEPROM_NFLQB)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_cslam", MD_EEPROM_CSLAM)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_nhlpa", MD_EEPROM_NHLPA)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_blara", MD_EEPROM_BLARA)
|
||||||
|
// J-Cart controller (Sampras Tennis)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_jcart", MD_JCART)
|
||||||
|
// J-Cart controller + EEPROM handling (not supported fully yet)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_codemast", MD_SEPROM_CODEMAST)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_mm96", MD_SEPROM_MM96)
|
||||||
|
// STM95 EEPROM
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_stm95", MD_EEPROM_STM95)
|
||||||
|
// unique bankswitch
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_ssf2", MD_ROM_SSF2)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_radica", MD_ROM_RADICA)
|
||||||
|
// pirate mappers (protection and/or bankswitch)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_bugs", MD_ROM_BUGSLIFE)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_chinf3", MD_ROM_CHINF3)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_elfwor", MD_ROM_ELFWOR)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_kof98", MD_ROM_KOF98)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_kof99", MD_ROM_KOF99)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_lion2", MD_ROM_LION2)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_lion3", MD_ROM_LION3)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_mcpir", MD_ROM_MCPIR)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_mjlov", MD_ROM_MJLOV)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_pokestad", MD_ROM_POKESTAD)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_realtec", MD_ROM_REALTEC)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_redcl", MD_ROM_REDCL)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_rx3", MD_ROM_RX3)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_sbubl", MD_ROM_SBUBL)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_smb", MD_ROM_SMB)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_smb2", MD_ROM_SMB2)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_smouse", MD_ROM_SMOUSE)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_soulb", MD_ROM_SOULB)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_squir", MD_ROM_SQUIR)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_topf", MD_ROM_TOPF)
|
||||||
|
// these have protection patched out, instead of emulated!
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_mulan", MD_STD_ROM)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_poke", MD_STD_ROM)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_poke2", MD_STD_ROM)
|
||||||
|
SLOT_INTERFACE_END
|
||||||
|
|
||||||
static MACHINE_CONFIG_START( ms_megadriv, md_cons_state )
|
static MACHINE_CONFIG_START( ms_megadriv, md_cons_state )
|
||||||
MCFG_FRAGMENT_ADD( md_ntsc )
|
MCFG_FRAGMENT_ADD( md_ntsc )
|
||||||
MCFG_NVRAM_HANDLER_CLEAR()
|
MCFG_NVRAM_HANDLER_CLEAR()
|
||||||
@ -333,7 +349,8 @@ static MACHINE_CONFIG_START( ms_megadriv, md_cons_state )
|
|||||||
MCFG_MACHINE_START( ms_megadriv )
|
MCFG_MACHINE_START( ms_megadriv )
|
||||||
MCFG_MACHINE_RESET( ms_megadriv )
|
MCFG_MACHINE_RESET( ms_megadriv )
|
||||||
|
|
||||||
MCFG_FRAGMENT_ADD( genesis_cartslot )
|
MCFG_MD_CARTRIDGE_ADD("mdslot", md_cart, NULL, NULL)
|
||||||
|
MCFG_SOFTWARE_LIST_ADD("cart_list","megadriv")
|
||||||
MACHINE_CONFIG_END
|
MACHINE_CONFIG_END
|
||||||
|
|
||||||
static MACHINE_CONFIG_START( ms_megadpal, md_cons_state )
|
static MACHINE_CONFIG_START( ms_megadpal, md_cons_state )
|
||||||
@ -343,29 +360,8 @@ static MACHINE_CONFIG_START( ms_megadpal, md_cons_state )
|
|||||||
MCFG_MACHINE_START( ms_megadriv )
|
MCFG_MACHINE_START( ms_megadriv )
|
||||||
MCFG_MACHINE_RESET( ms_megadriv )
|
MCFG_MACHINE_RESET( ms_megadriv )
|
||||||
|
|
||||||
MCFG_FRAGMENT_ADD( genesis_cartslot )
|
MCFG_MD_CARTRIDGE_ADD("mdslot", md_cart, NULL, NULL)
|
||||||
MACHINE_CONFIG_END
|
MCFG_SOFTWARE_LIST_ADD("cart_list","megadriv")
|
||||||
|
|
||||||
static MACHINE_CONFIG_START( ms_megdsvp, mdsvp_state )
|
|
||||||
MCFG_FRAGMENT_ADD( md_ntsc )
|
|
||||||
MCFG_FRAGMENT_ADD( md_svp )
|
|
||||||
MCFG_NVRAM_HANDLER_CLEAR()
|
|
||||||
|
|
||||||
MCFG_MACHINE_START( ms_megadriv )
|
|
||||||
MCFG_MACHINE_RESET( ms_megadriv )
|
|
||||||
|
|
||||||
MCFG_FRAGMENT_ADD( genesis_cartslot )
|
|
||||||
MACHINE_CONFIG_END
|
|
||||||
|
|
||||||
static MACHINE_CONFIG_START( ms_megdsvppal, mdsvp_state )
|
|
||||||
MCFG_FRAGMENT_ADD( md_pal )
|
|
||||||
MCFG_FRAGMENT_ADD( md_svp )
|
|
||||||
MCFG_NVRAM_HANDLER_CLEAR()
|
|
||||||
|
|
||||||
MCFG_MACHINE_START( ms_megadriv )
|
|
||||||
MCFG_MACHINE_RESET( ms_megadriv )
|
|
||||||
|
|
||||||
MCFG_FRAGMENT_ADD( genesis_cartslot )
|
|
||||||
MACHINE_CONFIG_END
|
MACHINE_CONFIG_END
|
||||||
|
|
||||||
|
|
||||||
@ -640,6 +636,51 @@ ROM_START( 32x_scd )
|
|||||||
ROM_LOAD( "32x_s_bios.bin", 0x000000, 0x000400, CRC(bfda1fe5) SHA1(4103668c1bbd66c5e24558e73d4f3f92061a109a) )
|
ROM_LOAD( "32x_s_bios.bin", 0x000000, 0x000400, CRC(bfda1fe5) SHA1(4103668c1bbd66c5e24558e73d4f3f92061a109a) )
|
||||||
ROM_END
|
ROM_END
|
||||||
|
|
||||||
|
/****************************************** SVP emulation *****************************************/
|
||||||
|
|
||||||
|
INPUT_PORTS_START( megdsvp )
|
||||||
|
PORT_INCLUDE( megadriv )
|
||||||
|
|
||||||
|
PORT_START("MEMORY_TEST") /* special memtest mode */
|
||||||
|
/* Region setting for Console */
|
||||||
|
PORT_DIPNAME( 0x01, 0x00, DEF_STR( Test ) )
|
||||||
|
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
|
||||||
|
PORT_DIPSETTING( 0x01, DEF_STR( On ) )
|
||||||
|
INPUT_PORTS_END
|
||||||
|
|
||||||
|
|
||||||
|
static MACHINE_CONFIG_START( megdsvp, mdsvp_state )
|
||||||
|
MCFG_FRAGMENT_ADD( md_ntsc )
|
||||||
|
MCFG_NVRAM_HANDLER_CLEAR()
|
||||||
|
|
||||||
|
MCFG_CPU_ADD("svp", SSP1601, MASTER_CLOCK_NTSC / 7 * 3) /* ~23 MHz (guessed) */
|
||||||
|
MCFG_CPU_PROGRAM_MAP(svp_ssp_map)
|
||||||
|
MCFG_CPU_IO_MAP(svp_ext_map)
|
||||||
|
/* IRQs are not used by this CPU */
|
||||||
|
|
||||||
|
MCFG_MACHINE_START( ms_megadriv )
|
||||||
|
MCFG_MACHINE_RESET( ms_megadriv )
|
||||||
|
|
||||||
|
MCFG_MD_CARTRIDGE_ADD("mdslot", md_cart, NULL, NULL)
|
||||||
|
MCFG_SOFTWARE_LIST_ADD("cart_list","megadriv")
|
||||||
|
MACHINE_CONFIG_END
|
||||||
|
|
||||||
|
static MACHINE_CONFIG_START( megdsvp_pal, mdsvp_state )
|
||||||
|
MCFG_FRAGMENT_ADD( md_pal )
|
||||||
|
MCFG_NVRAM_HANDLER_CLEAR()
|
||||||
|
|
||||||
|
MCFG_CPU_ADD("svp", SSP1601, MASTER_CLOCK_PAL / 7 * 3) /* ~23 MHz (guessed) */
|
||||||
|
MCFG_CPU_PROGRAM_MAP(svp_ssp_map)
|
||||||
|
MCFG_CPU_IO_MAP(svp_ext_map)
|
||||||
|
/* IRQs are not used by this CPU */
|
||||||
|
|
||||||
|
MCFG_MACHINE_START( ms_megadriv )
|
||||||
|
MCFG_MACHINE_RESET( ms_megadriv )
|
||||||
|
|
||||||
|
MCFG_MD_CARTRIDGE_ADD("mdslot", md_cart, NULL, NULL)
|
||||||
|
MCFG_SOFTWARE_LIST_ADD("cart_list","megadriv")
|
||||||
|
MACHINE_CONFIG_END
|
||||||
|
|
||||||
|
|
||||||
/****************************************** PICO emulation ****************************************/
|
/****************************************** PICO emulation ****************************************/
|
||||||
|
|
||||||
@ -828,6 +869,19 @@ static INPUT_PORTS_START( pico )
|
|||||||
INPUT_PORTS_END
|
INPUT_PORTS_END
|
||||||
|
|
||||||
|
|
||||||
|
static SLOT_INTERFACE_START(pico_cart)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom", MD_STD_ROM)
|
||||||
|
SLOT_INTERFACE_END
|
||||||
|
|
||||||
|
static MACHINE_START(pico)
|
||||||
|
{
|
||||||
|
pico_state *state = machine.driver_data<pico_state>();
|
||||||
|
machine.device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler(0x000000, 0x7fffff, read16_delegate(FUNC(device_md_cart_interface::read),state->m_picocart->m_cart), write16_delegate(FUNC(device_md_cart_interface::write),state->m_picocart->m_cart));
|
||||||
|
machine.device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler(0xa13000, 0xa130ff, read16_delegate(FUNC(device_md_cart_interface::read_a13),state->m_picocart->m_cart), write16_delegate(FUNC(device_md_cart_interface::write_a13),state->m_picocart->m_cart));
|
||||||
|
machine.device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler(0xa15000, 0xa150ff, read16_delegate(FUNC(device_md_cart_interface::read_a15),state->m_picocart->m_cart), write16_delegate(FUNC(device_md_cart_interface::write_a15),state->m_picocart->m_cart));
|
||||||
|
machine.device("maincpu")->memory().space(AS_PROGRAM).install_write_handler(0xa14000, 0xa14003, write16_delegate(FUNC(device_md_cart_interface::write_tmss_bank),state->m_picocart->m_cart));
|
||||||
|
}
|
||||||
|
|
||||||
static MACHINE_CONFIG_START( pico, pico_state )
|
static MACHINE_CONFIG_START( pico, pico_state )
|
||||||
MCFG_FRAGMENT_ADD( md_ntsc )
|
MCFG_FRAGMENT_ADD( md_ntsc )
|
||||||
MCFG_NVRAM_HANDLER_CLEAR()
|
MCFG_NVRAM_HANDLER_CLEAR()
|
||||||
@ -837,9 +891,11 @@ static MACHINE_CONFIG_START( pico, pico_state )
|
|||||||
|
|
||||||
MCFG_DEVICE_REMOVE("genesis_snd_z80")
|
MCFG_DEVICE_REMOVE("genesis_snd_z80")
|
||||||
|
|
||||||
|
MCFG_MACHINE_START( pico )
|
||||||
MCFG_MACHINE_RESET( ms_megadriv )
|
MCFG_MACHINE_RESET( ms_megadriv )
|
||||||
|
|
||||||
MCFG_FRAGMENT_ADD( pico_cartslot )
|
MCFG_PICO_CARTRIDGE_ADD("picoslot", pico_cart, NULL, NULL)
|
||||||
|
MCFG_SOFTWARE_LIST_ADD("cart_list","pico")
|
||||||
MACHINE_CONFIG_END
|
MACHINE_CONFIG_END
|
||||||
|
|
||||||
static MACHINE_CONFIG_START( picopal, pico_state )
|
static MACHINE_CONFIG_START( picopal, pico_state )
|
||||||
@ -851,9 +907,11 @@ static MACHINE_CONFIG_START( picopal, pico_state )
|
|||||||
|
|
||||||
MCFG_DEVICE_REMOVE("genesis_snd_z80")
|
MCFG_DEVICE_REMOVE("genesis_snd_z80")
|
||||||
|
|
||||||
|
MCFG_MACHINE_START( pico )
|
||||||
MCFG_MACHINE_RESET( ms_megadriv )
|
MCFG_MACHINE_RESET( ms_megadriv )
|
||||||
|
|
||||||
MCFG_FRAGMENT_ADD( pico_cartslot )
|
MCFG_PICO_CARTRIDGE_ADD("picoslot", pico_cart, NULL, NULL)
|
||||||
|
MCFG_SOFTWARE_LIST_ADD("cart_list","pico")
|
||||||
MACHINE_CONFIG_END
|
MACHINE_CONFIG_END
|
||||||
|
|
||||||
|
|
||||||
@ -886,9 +944,9 @@ CONS( 1988, megadrij, genesis, 0, ms_megadriv, md, md_cons_state,
|
|||||||
|
|
||||||
// these should not exist, the SVP hardware is in the cart and should be installed dynamically when selected from the Software List
|
// these should not exist, the SVP hardware is in the cart and should be installed dynamically when selected from the Software List
|
||||||
// this however involves installing entire CPUs at run/load time and I don't think we can do that.
|
// this however involves installing entire CPUs at run/load time and I don't think we can do that.
|
||||||
CONS( 1993, gensvp, genesis, 0, ms_megdsvp, md, md_cons_state, genesis, "Sega", "Genesis (USA, NTSC, for SVP cart)", 0)
|
CONS( 1993, gensvp, genesis, 0, megdsvp, md, md_cons_state, genesis, "Sega", "Genesis (USA, NTSC, for SVP cart)", 0)
|
||||||
CONS( 1990, mdsvp, genesis, 0, ms_megdsvppal, md, md_cons_state, md_eur, "Sega", "Mega Drive (Europe, PAL, for SVP cart)", 0)
|
CONS( 1990, mdsvp, genesis, 0, megdsvp_pal, md, md_cons_state, md_eur, "Sega", "Mega Drive (Europe, PAL, for SVP cart)", 0)
|
||||||
CONS( 1988, mdsvpj, genesis, 0, ms_megdsvp, md, md_cons_state, md_jpn, "Sega", "Mega Drive (Japan, NTSC, for SVP cart)", 0)
|
CONS( 1988, mdsvpj, genesis, 0, megdsvp, md, md_cons_state, md_jpn, "Sega", "Mega Drive (Japan, NTSC, for SVP cart)", 0)
|
||||||
|
|
||||||
// the 32X plugged in the cart slot, games plugged into the 32x. Maybe it should be handled as an expansion device?
|
// the 32X plugged in the cart slot, games plugged into the 32x. Maybe it should be handled as an expansion device?
|
||||||
CONS( 1994, 32x, 0, 0, ms_32x, md, md_cons_state, genesis, "Sega", "Genesis with 32X (USA, NTSC)", GAME_NOT_WORKING )
|
CONS( 1994, 32x, 0, 0, ms_32x, md, md_cons_state, genesis, "Sega", "Genesis with 32X (USA, NTSC)", GAME_NOT_WORKING )
|
||||||
|
64
src/mess/includes/md.h
Normal file
64
src/mess/includes/md.h
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
#ifndef __MD__
|
||||||
|
#define __MD__
|
||||||
|
|
||||||
|
// Temporary include file to handle SVP add-on, until converted to a proper slot device
|
||||||
|
// Afterwards, these classes can be moved back to mess/drivers/megadriv.c!
|
||||||
|
|
||||||
|
#include "includes/megadriv.h"
|
||||||
|
#include "machine/md_slot.h"
|
||||||
|
|
||||||
|
class md_cons_state : public md_base_state
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
md_cons_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||||
|
: md_base_state(mconfig, type, tag),
|
||||||
|
m_slotcart(*this, "mdslot")
|
||||||
|
{ }
|
||||||
|
|
||||||
|
emu_timer *m_mess_io_timeout[3];
|
||||||
|
int m_mess_io_stage[3];
|
||||||
|
|
||||||
|
optional_device<md_cart_slot_device> m_slotcart;
|
||||||
|
|
||||||
|
DECLARE_DRIVER_INIT(mess_md_common);
|
||||||
|
DECLARE_DRIVER_INIT(genesis);
|
||||||
|
DECLARE_DRIVER_INIT(md_eur);
|
||||||
|
DECLARE_DRIVER_INIT(md_jpn);
|
||||||
|
};
|
||||||
|
|
||||||
|
class mdsvp_state : public md_cons_state
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
mdsvp_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||||
|
: md_cons_state(mconfig, type, tag) { }
|
||||||
|
|
||||||
|
UINT8 *m_iram; // IRAM (0-0x7ff)
|
||||||
|
UINT8 *m_dram; // [0x20000];
|
||||||
|
UINT32 m_pmac_read[6]; // read modes/addrs for PM0-PM5
|
||||||
|
UINT32 m_pmac_write[6]; // write ...
|
||||||
|
PAIR m_pmc;
|
||||||
|
UINT32 m_emu_status;
|
||||||
|
UINT16 m_XST; // external status, mapped at a15000 and a15002 on 68k side.
|
||||||
|
UINT16 m_XST2; // status of XST (bit1 set when 68k writes to XST)
|
||||||
|
};
|
||||||
|
|
||||||
|
class pico_state : public md_cons_state
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
pico_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||||
|
: md_cons_state(mconfig, type, tag),
|
||||||
|
m_picocart(*this, "picoslot") { }
|
||||||
|
|
||||||
|
optional_device<pico_cart_slot_device> m_picocart;
|
||||||
|
UINT8 m_page_register;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ADDRESS_MAP_EXTERN( svp_ssp_map, driver_device );
|
||||||
|
ADDRESS_MAP_EXTERN( svp_ext_map, driver_device );
|
||||||
|
extern void svp_init(running_machine &machine);
|
||||||
|
extern cpu_device *_svp_cpu;
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
360
src/mess/machine/md_eeprom.c
Normal file
360
src/mess/machine/md_eeprom.c
Normal file
@ -0,0 +1,360 @@
|
|||||||
|
/***********************************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
MegaDrive / Genesis cart+EEPROM emulation
|
||||||
|
|
||||||
|
|
||||||
|
TODO: proper EEPROM emulation, still not worked on (just hooked up the I2C device)
|
||||||
|
|
||||||
|
|
||||||
|
i2c games mapping table:
|
||||||
|
|
||||||
|
game name | SDA_IN | SDA_OUT | SCL | SIZE_MASK | PAGE_MASK |
|
||||||
|
----------------------------------|------------|------------|------------|----------------|-----------|
|
||||||
|
NBA Jam | 0x200001-0 | 0x200001-0 | 0x200001-1 | 0x00ff (24C02) | 0x03 | xx
|
||||||
|
NBA Jam TE | 0x200001-0 | 0x200001-0 | 0x200000-0 | 0x00ff (24C02) | 0x03 | xx
|
||||||
|
NBA Jam TE (32x) | 0x200001-0 | 0x200001-0 | 0x200000-0 | 0x00ff (24C02) | 0x03 |
|
||||||
|
NFL Quarterback Club | 0x200001-0 | 0x200001-0 | 0x200000-0 | 0x00ff (24C02) | 0x03 | xx
|
||||||
|
NFL Quarterback Club 96 | 0x200001-0 | 0x200001-0 | 0x200000-0 | 0x07ff (24C16) | 0x07 | xx
|
||||||
|
College Slam | 0x200001-0 | 0x200001-0 | 0x200000-0 | 0x1fff (24C64) | 0x07 | xx
|
||||||
|
Frank Thomas Big Hurt Baseball | 0x200001-0 | 0x200001-0 | 0x200000-0 | 0x1fff (24C64) | 0x07 | xx
|
||||||
|
NHLPA Hockey 93 | 0x200001-7 | 0x200001-7 | 0x200001-6 | 0x007f (24C01) | 0x03 | xx
|
||||||
|
Rings of Power | 0x200001-7 | 0x200001-7 | 0x200001-6 | 0x007f (24C01) | 0x03 | xx
|
||||||
|
Evander Holyfield's Boxing | 0x200001-0 | 0x200001-0 | 0x200001-1 | 0x007f (24C01) | 0x03 | xx
|
||||||
|
Greatest Heavyweights of the Ring | 0x200001-0 | 0x200001-0 | 0x200001-1 | 0x007f (24C01) | 0x03 | xx
|
||||||
|
Wonder Boy V | 0x200001-0 | 0x200001-0 | 0x200001-1 | 0x007f (24C01) | 0x03 | xx
|
||||||
|
Sports Talk Baseball | 0x200001-0 | 0x200001-0 | 0x200001-1 | 0x007f (24C01) | 0x03 | xx
|
||||||
|
Megaman - the Wily Wars | 0x200001-0 | 0x200001-0 | 0x200001-1 | 0x007f (24C01) | 0x03 | xx **
|
||||||
|
Micro Machines 2 | 0x380001-7 | 0x300000-0*| 0x300000-1*| 0x03ff (24C08) | 0x0f |
|
||||||
|
Micro Machines Military | 0x380001-7 | 0x300000-0*| 0x300000-1*| 0x03ff (24C08) | 0x0f |
|
||||||
|
Micro Machines 96 | 0x380001-7 | 0x300000-0*| 0x300000-1*| 0x07ff (24C16) | 0x0f |
|
||||||
|
Brian Lara Cricket 96 | 0x380001-7 | 0x300000-0*| 0x300000-1*| 0x1fff (24C64) | 0x??* |
|
||||||
|
----------------------------------|------------|------------|------------|----------------|-----------|
|
||||||
|
|
||||||
|
* Notes: check these
|
||||||
|
** original Rockman Mega World (J) set uses normal backup RAM
|
||||||
|
|
||||||
|
|
||||||
|
Micro Machines 2, Micro Machines Military, Micro Machines 96 are emulated in md_jcart
|
||||||
|
|
||||||
|
***********************************************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "emu.h"
|
||||||
|
#include "machine/md_eeprom.h"
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// md_rom_device - constructor
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
const device_type MD_STD_EEPROM = &device_creator<md_std_eeprom_device>;
|
||||||
|
const device_type MD_EEPROM_NBAJAM = &device_creator<md_eeprom_nbajam_device>;
|
||||||
|
const device_type MD_EEPROM_NBAJAMTE = &device_creator<md_eeprom_nbajamte_device>;
|
||||||
|
const device_type MD_EEPROM_NFLQB = &device_creator<md_eeprom_nflqb_device>;
|
||||||
|
const device_type MD_EEPROM_CSLAM = &device_creator<md_eeprom_cslam_device>;
|
||||||
|
const device_type MD_EEPROM_NHLPA = &device_creator<md_eeprom_nhlpa_device>;
|
||||||
|
const device_type MD_EEPROM_BLARA = &device_creator<md_eeprom_blara_device>;
|
||||||
|
|
||||||
|
|
||||||
|
md_std_eeprom_device::md_std_eeprom_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: device_t(mconfig, type, name, tag, owner, clock),
|
||||||
|
device_md_cart_interface( mconfig, *this ),
|
||||||
|
m_i2cmem(*this, "i2cmem")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
md_std_eeprom_device::md_std_eeprom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: device_t(mconfig, MD_STD_EEPROM, "MD Standard cart + EEPROM", tag, owner, clock),
|
||||||
|
device_md_cart_interface( mconfig, *this ),
|
||||||
|
m_i2cmem(*this, "i2cmem")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
md_eeprom_nbajam_device::md_eeprom_nbajam_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: md_std_eeprom_device(mconfig, MD_EEPROM_NBAJAM, "MD NBA Jam", tag, owner, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
md_eeprom_nbajamte_device::md_eeprom_nbajamte_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: md_std_eeprom_device(mconfig, MD_EEPROM_NBAJAMTE, "MD NBA Jam TE (and a few more)", tag, owner, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
md_eeprom_cslam_device::md_eeprom_cslam_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: md_std_eeprom_device(mconfig, MD_EEPROM_CSLAM, "MD College Slam", tag, owner, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
md_eeprom_nflqb_device::md_eeprom_nflqb_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: md_std_eeprom_device(mconfig, MD_EEPROM_NFLQB, "MD NFL Quarterback 96", tag, owner, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
md_eeprom_nhlpa_device::md_eeprom_nhlpa_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: md_std_eeprom_device(mconfig, MD_EEPROM_NHLPA, "MD NHLPA 93", tag, owner, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
md_eeprom_blara_device::md_eeprom_blara_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: md_std_eeprom_device(mconfig, MD_EEPROM_BLARA, "MD Brian Lara", tag, owner, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// SERIAL I2C DEVICE
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
static const i2cmem_interface md_24c01_i2cmem_interface =
|
||||||
|
{
|
||||||
|
I2CMEM_SLAVE_ADDRESS, 0, 0x80
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static const i2cmem_interface md_24c02_i2cmem_interface =
|
||||||
|
{
|
||||||
|
I2CMEM_SLAVE_ADDRESS, 0, 0x100
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static const i2cmem_interface md_24c16_i2cmem_interface =
|
||||||
|
{
|
||||||
|
I2CMEM_SLAVE_ADDRESS, 0, 0x800
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static const i2cmem_interface md_24c64_i2cmem_interface =
|
||||||
|
{
|
||||||
|
I2CMEM_SLAVE_ADDRESS, 0, 0x2000
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// MD_STD_EEPROM & MD_EEPROM_NHLPA
|
||||||
|
MACHINE_CONFIG_FRAGMENT( md_i2c_24c01 )
|
||||||
|
MCFG_I2CMEM_ADD("i2cmem", md_24c01_i2cmem_interface)
|
||||||
|
MACHINE_CONFIG_END
|
||||||
|
|
||||||
|
// MD_EEPROM_NBAJAM & MD_EEPROM_NBAJAMTE
|
||||||
|
MACHINE_CONFIG_FRAGMENT( md_i2c_24c02 )
|
||||||
|
MCFG_I2CMEM_ADD("i2cmem", md_24c02_i2cmem_interface)
|
||||||
|
MACHINE_CONFIG_END
|
||||||
|
|
||||||
|
// MD_EEPROM_NFLQB
|
||||||
|
MACHINE_CONFIG_FRAGMENT( md_i2c_24c16 )
|
||||||
|
MCFG_I2CMEM_ADD("i2cmem", md_24c16_i2cmem_interface)
|
||||||
|
MACHINE_CONFIG_END
|
||||||
|
|
||||||
|
// MD_EEPROM_CSLAM & MD_EEPROM_BLARA
|
||||||
|
MACHINE_CONFIG_FRAGMENT( md_i2c_24c64 )
|
||||||
|
MCFG_I2CMEM_ADD("i2cmem", md_24c64_i2cmem_interface)
|
||||||
|
MACHINE_CONFIG_END
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// machine_config_additions - device-specific
|
||||||
|
// machine configurations
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
machine_config_constructor md_std_eeprom_device::device_mconfig_additions() const
|
||||||
|
{
|
||||||
|
return MACHINE_CONFIG_NAME( md_i2c_24c01 );
|
||||||
|
}
|
||||||
|
|
||||||
|
machine_config_constructor md_eeprom_nbajam_device::device_mconfig_additions() const
|
||||||
|
{
|
||||||
|
return MACHINE_CONFIG_NAME( md_i2c_24c02 );
|
||||||
|
}
|
||||||
|
|
||||||
|
machine_config_constructor md_eeprom_nbajamte_device::device_mconfig_additions() const
|
||||||
|
{
|
||||||
|
return MACHINE_CONFIG_NAME( md_i2c_24c02 );
|
||||||
|
}
|
||||||
|
|
||||||
|
machine_config_constructor md_eeprom_cslam_device::device_mconfig_additions() const
|
||||||
|
{
|
||||||
|
return MACHINE_CONFIG_NAME( md_i2c_24c64 );
|
||||||
|
}
|
||||||
|
|
||||||
|
machine_config_constructor md_eeprom_nflqb_device::device_mconfig_additions() const
|
||||||
|
{
|
||||||
|
return MACHINE_CONFIG_NAME( md_i2c_24c16 );
|
||||||
|
}
|
||||||
|
|
||||||
|
machine_config_constructor md_eeprom_nhlpa_device::device_mconfig_additions() const
|
||||||
|
{
|
||||||
|
return MACHINE_CONFIG_NAME( md_i2c_24c01 );
|
||||||
|
}
|
||||||
|
|
||||||
|
machine_config_constructor md_eeprom_blara_device::device_mconfig_additions() const
|
||||||
|
{
|
||||||
|
return MACHINE_CONFIG_NAME( md_i2c_24c64 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void md_std_eeprom_device::device_start()
|
||||||
|
{
|
||||||
|
m_i2c_mem = 0;
|
||||||
|
m_i2c_clk = 0;
|
||||||
|
save_item(NAME(m_i2c_mem));
|
||||||
|
save_item(NAME(m_i2c_clk));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
mapper specific handlers
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
CART + EEPROM
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
READ16_MEMBER(md_std_eeprom_device::read)
|
||||||
|
{
|
||||||
|
if (offset == 0x200000/2)
|
||||||
|
{
|
||||||
|
m_i2c_mem = i2cmem_sda_read(m_i2cmem);
|
||||||
|
return ~m_i2c_mem & 1;
|
||||||
|
}
|
||||||
|
return m_rom[offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE16_MEMBER(md_std_eeprom_device::write)
|
||||||
|
{
|
||||||
|
if (offset == 0x200000/2)
|
||||||
|
{
|
||||||
|
m_i2c_clk = BIT(data, 1);
|
||||||
|
m_i2c_mem = BIT(data, 0);
|
||||||
|
i2cmem_scl_write(m_i2cmem, m_i2c_clk);
|
||||||
|
i2cmem_sda_write(m_i2cmem, m_i2c_mem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
READ16_MEMBER(md_eeprom_nbajam_device::read)
|
||||||
|
{
|
||||||
|
if (offset == 0x200000/2)
|
||||||
|
{
|
||||||
|
m_i2c_mem = i2cmem_sda_read(m_i2cmem);
|
||||||
|
return m_i2c_mem & 1;
|
||||||
|
}
|
||||||
|
return m_rom[offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE16_MEMBER(md_eeprom_nbajam_device::write)
|
||||||
|
{
|
||||||
|
if (offset == 0x200000/2)
|
||||||
|
{
|
||||||
|
m_i2c_clk = BIT(data, 1);
|
||||||
|
m_i2c_mem = BIT(data, 0);
|
||||||
|
i2cmem_scl_write(m_i2cmem, m_i2c_clk);
|
||||||
|
i2cmem_sda_write(m_i2cmem, m_i2c_mem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
READ16_MEMBER(md_eeprom_nbajamte_device::read)
|
||||||
|
{
|
||||||
|
if (offset == 0x200000/2)
|
||||||
|
{
|
||||||
|
m_i2c_mem = i2cmem_sda_read(m_i2cmem);
|
||||||
|
return m_i2c_mem & 1;
|
||||||
|
}
|
||||||
|
return m_rom[offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE16_MEMBER(md_eeprom_nbajamte_device::write)
|
||||||
|
{
|
||||||
|
if (offset == 0x200000/2)
|
||||||
|
{
|
||||||
|
m_i2c_clk = BIT(data, 8);
|
||||||
|
m_i2c_mem = BIT(data, 0);
|
||||||
|
i2cmem_scl_write(m_i2cmem, m_i2c_clk);
|
||||||
|
i2cmem_sda_write(m_i2cmem, m_i2c_mem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// same as NBAJAMTE above... derived class?
|
||||||
|
READ16_MEMBER(md_eeprom_cslam_device::read)
|
||||||
|
{
|
||||||
|
if (offset == 0x200000/2)
|
||||||
|
{
|
||||||
|
m_i2c_mem = i2cmem_sda_read(m_i2cmem);
|
||||||
|
return m_i2c_mem & 1;
|
||||||
|
}
|
||||||
|
return m_rom[offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE16_MEMBER(md_eeprom_cslam_device::write)
|
||||||
|
{
|
||||||
|
if (offset == 0x200000/2)
|
||||||
|
{
|
||||||
|
m_i2c_clk = BIT(data, 8);
|
||||||
|
m_i2c_mem = BIT(data, 0);
|
||||||
|
i2cmem_scl_write(m_i2cmem, m_i2c_clk);
|
||||||
|
i2cmem_sda_write(m_i2cmem, m_i2c_mem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// same as NBAJAMTE above... derived class?
|
||||||
|
READ16_MEMBER(md_eeprom_nflqb_device::read)
|
||||||
|
{
|
||||||
|
if (offset == 0x200000/2)
|
||||||
|
{
|
||||||
|
m_i2c_mem = i2cmem_sda_read(m_i2cmem);
|
||||||
|
return m_i2c_mem & 1;
|
||||||
|
}
|
||||||
|
return m_rom[offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE16_MEMBER(md_eeprom_nflqb_device::write)
|
||||||
|
{
|
||||||
|
if (offset == 0x200000/2)
|
||||||
|
{
|
||||||
|
m_i2c_clk = BIT(data, 8);
|
||||||
|
m_i2c_mem = BIT(data, 0);
|
||||||
|
i2cmem_scl_write(m_i2cmem, m_i2c_clk);
|
||||||
|
i2cmem_sda_write(m_i2cmem, m_i2c_mem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
READ16_MEMBER(md_eeprom_nhlpa_device::read)
|
||||||
|
{
|
||||||
|
if (offset == 0x200000/2)
|
||||||
|
{
|
||||||
|
m_i2c_mem = i2cmem_sda_read(m_i2cmem);
|
||||||
|
return (m_i2c_mem & 1) << 7;
|
||||||
|
}
|
||||||
|
return m_rom[offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE16_MEMBER(md_eeprom_nhlpa_device::write)
|
||||||
|
{
|
||||||
|
if (offset == 0x200000/2)
|
||||||
|
{
|
||||||
|
m_i2c_clk = BIT(data, 6);
|
||||||
|
m_i2c_mem = BIT(data, 7);
|
||||||
|
i2cmem_scl_write(m_i2cmem, m_i2c_clk);
|
||||||
|
i2cmem_sda_write(m_i2cmem, m_i2c_mem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
READ16_MEMBER(md_eeprom_blara_device::read)
|
||||||
|
{
|
||||||
|
if (offset == 0x380000/2)
|
||||||
|
{
|
||||||
|
m_i2c_mem = i2cmem_sda_read(m_i2cmem);
|
||||||
|
return (m_i2c_mem & 1) << 7;
|
||||||
|
}
|
||||||
|
return m_rom[offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE16_MEMBER(md_eeprom_blara_device::write)
|
||||||
|
{
|
||||||
|
if (offset == 0x380000/2)
|
||||||
|
{
|
||||||
|
m_i2c_clk = BIT(data, 9);
|
||||||
|
m_i2c_mem = BIT(data, 8);
|
||||||
|
i2cmem_scl_write(m_i2cmem, m_i2c_clk);
|
||||||
|
i2cmem_sda_write(m_i2cmem, m_i2c_mem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
147
src/mess/machine/md_eeprom.h
Normal file
147
src/mess/machine/md_eeprom.h
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
#ifndef __MD_EEPROM_H
|
||||||
|
#define __MD_EEPROM_H
|
||||||
|
|
||||||
|
#include "machine/md_slot.h"
|
||||||
|
#include "machine/i2cmem.h"
|
||||||
|
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// TYPE DEFINITIONS
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
// ======================> md_std_eeprom_device
|
||||||
|
|
||||||
|
class md_std_eeprom_device : public device_t,
|
||||||
|
public device_md_cart_interface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
md_std_eeprom_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
md_std_eeprom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_start();
|
||||||
|
virtual void device_config_complete() { m_shortname = "md_std_eeprom"; }
|
||||||
|
virtual machine_config_constructor device_mconfig_additions() const;
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ16_MEMBER(read);
|
||||||
|
virtual DECLARE_WRITE16_MEMBER(write);
|
||||||
|
|
||||||
|
required_device<i2cmem_device> m_i2cmem;
|
||||||
|
UINT8 m_i2c_mem, m_i2c_clk;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================> md_eeprom_nbajam_device
|
||||||
|
|
||||||
|
class md_eeprom_nbajam_device : public md_std_eeprom_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
md_eeprom_nbajam_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_config_complete() { m_shortname = "md_eeprom_nbajam"; }
|
||||||
|
virtual machine_config_constructor device_mconfig_additions() const;
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ16_MEMBER(read);
|
||||||
|
virtual DECLARE_WRITE16_MEMBER(write);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================> md_eeprom_nbajamte_device
|
||||||
|
|
||||||
|
class md_eeprom_nbajamte_device : public md_std_eeprom_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
md_eeprom_nbajamte_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_config_complete() { m_shortname = "md_eeprom_nbajamte"; }
|
||||||
|
virtual machine_config_constructor device_mconfig_additions() const;
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ16_MEMBER(read);
|
||||||
|
virtual DECLARE_WRITE16_MEMBER(write);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================> md_eeprom_cslam_device (same read/write as nbajamte, but different I2C type)
|
||||||
|
|
||||||
|
class md_eeprom_cslam_device : public md_std_eeprom_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
md_eeprom_cslam_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_config_complete() { m_shortname = "md_eeprom_cslam"; }
|
||||||
|
virtual machine_config_constructor device_mconfig_additions() const;
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ16_MEMBER(read);
|
||||||
|
virtual DECLARE_WRITE16_MEMBER(write);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================> md_eeprom_nflqb_device (same read/write as nbajamte, but different I2C type)
|
||||||
|
|
||||||
|
class md_eeprom_nflqb_device : public md_std_eeprom_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
md_eeprom_nflqb_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_config_complete() { m_shortname = "md_eeprom_nflqb"; }
|
||||||
|
virtual machine_config_constructor device_mconfig_additions() const;
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ16_MEMBER(read);
|
||||||
|
virtual DECLARE_WRITE16_MEMBER(write);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================> md_eeprom_nhlpa_device
|
||||||
|
|
||||||
|
class md_eeprom_nhlpa_device : public md_std_eeprom_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
md_eeprom_nhlpa_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_config_complete() { m_shortname = "md_eeprom_nhlpa"; }
|
||||||
|
virtual machine_config_constructor device_mconfig_additions() const;
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ16_MEMBER(read);
|
||||||
|
virtual DECLARE_WRITE16_MEMBER(write);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================> md_eeprom_blara_device (same read/write as codemast, but different I2C type)
|
||||||
|
|
||||||
|
class md_eeprom_blara_device : public md_std_eeprom_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
md_eeprom_blara_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_config_complete() { m_shortname = "md_eeprom_blara"; }
|
||||||
|
virtual machine_config_constructor device_mconfig_additions() const;
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ16_MEMBER(read);
|
||||||
|
virtual DECLARE_WRITE16_MEMBER(write);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// device type definition
|
||||||
|
extern const device_type MD_STD_EEPROM;
|
||||||
|
extern const device_type MD_EEPROM_NBAJAM;
|
||||||
|
extern const device_type MD_EEPROM_NBAJAMTE;
|
||||||
|
extern const device_type MD_EEPROM_CSLAM;
|
||||||
|
extern const device_type MD_EEPROM_NFLQB;
|
||||||
|
extern const device_type MD_EEPROM_NHLPA;
|
||||||
|
extern const device_type MD_EEPROM_BLARA;
|
||||||
|
|
||||||
|
#endif
|
249
src/mess/machine/md_jcart.c
Normal file
249
src/mess/machine/md_jcart.c
Normal file
@ -0,0 +1,249 @@
|
|||||||
|
/***********************************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
MegaDrive / Genesis J-Cart (+SEPROM) emulation
|
||||||
|
|
||||||
|
|
||||||
|
i2c games mapping table:
|
||||||
|
|
||||||
|
game name | SDA_IN | SDA_OUT | SCL | SIZE_MASK | PAGE_MASK |
|
||||||
|
----------------------------------|------------|------------|------------|----------------|-----------|
|
||||||
|
Micro Machines 2 | 0x380001-7 | 0x300000-0*| 0x300000-1*| 0x03ff (24C08) | 0x0f |
|
||||||
|
Micro Machines Military | 0x380001-7 | 0x300000-0*| 0x300000-1*| 0x03ff (24C08) | 0x0f |
|
||||||
|
Micro Machines 96 | 0x380001-7 | 0x300000-0*| 0x300000-1*| 0x07ff (24C16) | 0x0f |
|
||||||
|
----------------------------------|------------|------------|------------|----------------|-----------|
|
||||||
|
|
||||||
|
* Notes: check these
|
||||||
|
|
||||||
|
|
||||||
|
TODO: proper SEPROM emulation, still not worked on (just hooked up the I2C device)
|
||||||
|
|
||||||
|
***********************************************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "emu.h"
|
||||||
|
#include "machine/md_jcart.h"
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// md_rom_device - constructor
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
const device_type MD_JCART = &device_creator<md_jcart_device>;
|
||||||
|
const device_type MD_SEPROM_CODEMAST = &device_creator<md_seprom_codemast_device>;
|
||||||
|
const device_type MD_SEPROM_MM96 = &device_creator<md_seprom_mm96_device>;
|
||||||
|
|
||||||
|
// Sampras, Super Skidmarks?
|
||||||
|
md_jcart_device::md_jcart_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: device_t(mconfig, type, name, tag, owner, clock),
|
||||||
|
device_md_cart_interface( mconfig, *this ),
|
||||||
|
m_jcart3(*this, "JCART3"),
|
||||||
|
m_jcart4(*this, "JCART4")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
md_jcart_device::md_jcart_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: device_t(mconfig, MD_JCART, "MD J-Cart games", tag, owner, clock),
|
||||||
|
device_md_cart_interface( mconfig, *this ),
|
||||||
|
m_jcart3(*this, "JCART3"),
|
||||||
|
m_jcart4(*this, "JCART4")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// Micro Machines 2, Micro Machines Military
|
||||||
|
md_seprom_codemast_device::md_seprom_codemast_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: md_jcart_device(mconfig, type, name, tag, owner, clock),
|
||||||
|
m_i2cmem(*this, "i2cmem")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
md_seprom_codemast_device::md_seprom_codemast_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: md_jcart_device(mconfig, MD_SEPROM_CODEMAST, "MD J-Cart games + SEPROM", tag, owner, clock),
|
||||||
|
m_i2cmem(*this, "i2cmem")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// Micro Machines 96
|
||||||
|
md_seprom_mm96_device::md_seprom_mm96_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: md_seprom_codemast_device(mconfig, MD_SEPROM_MM96, "MD Micro Machine 96", tag, owner, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// SERIAL I2C DEVICE
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
static const i2cmem_interface md_24c08_i2cmem_interface =
|
||||||
|
{
|
||||||
|
I2CMEM_SLAVE_ADDRESS, 0, 0x400
|
||||||
|
};
|
||||||
|
|
||||||
|
static const i2cmem_interface md_24c16a_i2cmem_interface =
|
||||||
|
{
|
||||||
|
I2CMEM_SLAVE_ADDRESS, 0, 0x800
|
||||||
|
};
|
||||||
|
|
||||||
|
// MD_SEPROM_CODEMAST
|
||||||
|
MACHINE_CONFIG_FRAGMENT( md_i2c_24c08 )
|
||||||
|
MCFG_I2CMEM_ADD("i2cmem", md_24c08_i2cmem_interface)
|
||||||
|
MACHINE_CONFIG_END
|
||||||
|
|
||||||
|
// MD_SEPROM_MM96
|
||||||
|
MACHINE_CONFIG_FRAGMENT( md_i2c_24c16a )
|
||||||
|
MCFG_I2CMEM_ADD("i2cmem", md_24c16a_i2cmem_interface)
|
||||||
|
MACHINE_CONFIG_END
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// machine_config_additions - device-specific
|
||||||
|
// machine configurations
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
machine_config_constructor md_seprom_codemast_device::device_mconfig_additions() const
|
||||||
|
{
|
||||||
|
return MACHINE_CONFIG_NAME( md_i2c_24c08 );
|
||||||
|
}
|
||||||
|
|
||||||
|
machine_config_constructor md_seprom_mm96_device::device_mconfig_additions() const
|
||||||
|
{
|
||||||
|
return MACHINE_CONFIG_NAME( md_i2c_24c16a );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static INPUT_PORTS_START( jcart_ipt )
|
||||||
|
|
||||||
|
PORT_START("JCART3") /* Joypad 3 on J-Cart (3 button + start) */
|
||||||
|
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(3)
|
||||||
|
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(3)
|
||||||
|
PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(3)
|
||||||
|
PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(3)
|
||||||
|
PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(3) PORT_NAME("P3 B")
|
||||||
|
PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(3) PORT_NAME("P3 C")
|
||||||
|
PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(3) PORT_NAME("P3 A")
|
||||||
|
PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_START ) PORT_PLAYER(3)
|
||||||
|
|
||||||
|
PORT_START("JCART4") /* Joypad 4 on J-Cart (3 button + start) */
|
||||||
|
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(4)
|
||||||
|
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(4)
|
||||||
|
PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(4)
|
||||||
|
PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(4)
|
||||||
|
PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(4) PORT_NAME("P4 B")
|
||||||
|
PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(4) PORT_NAME("P4 C")
|
||||||
|
PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(4) PORT_NAME("P4 A")
|
||||||
|
PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_START ) PORT_PLAYER(4)
|
||||||
|
|
||||||
|
INPUT_PORTS_END
|
||||||
|
|
||||||
|
ioport_constructor md_jcart_device::device_input_ports() const
|
||||||
|
{
|
||||||
|
return INPUT_PORTS_NAME( jcart_ipt );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void md_jcart_device::device_start()
|
||||||
|
{
|
||||||
|
m_jcart_io_data[0] = 0;
|
||||||
|
m_jcart_io_data[1] = 0;
|
||||||
|
save_item(NAME(m_jcart_io_data));
|
||||||
|
}
|
||||||
|
|
||||||
|
void md_seprom_codemast_device::device_start()
|
||||||
|
{
|
||||||
|
m_i2c_mem = 0;
|
||||||
|
m_i2c_clk = 0;
|
||||||
|
m_jcart_io_data[0] = 0;
|
||||||
|
m_jcart_io_data[1] = 0;
|
||||||
|
save_item(NAME(m_i2c_mem));
|
||||||
|
save_item(NAME(m_i2c_clk));
|
||||||
|
save_item(NAME(m_jcart_io_data));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
mapper specific handlers
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
J-CART ONLY (Pete Sampras Tennis)
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
READ16_MEMBER(md_jcart_device::read)
|
||||||
|
{
|
||||||
|
if (offset == 0x38fffe/2)
|
||||||
|
{
|
||||||
|
UINT8 joy[2];
|
||||||
|
|
||||||
|
if (m_jcart_io_data[0] & 0x40)
|
||||||
|
{
|
||||||
|
joy[0] = m_jcart3->read_safe(0);
|
||||||
|
joy[1] = m_jcart4->read_safe(0);
|
||||||
|
return (m_jcart_io_data[0] & 0x40) | joy[0] | (joy[1] << 8);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
joy[0] = ((m_jcart3->read_safe(0) & 0xc0) >> 2) | (m_jcart3->read_safe(0) & 0x03);
|
||||||
|
joy[1] = ((m_jcart4->read_safe(0) & 0xc0) >> 2) | (m_jcart4->read_safe(0) & 0x03);
|
||||||
|
return (m_jcart_io_data[0] & 0x40) | joy[0] | (joy[1] << 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return m_rom[offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE16_MEMBER(md_jcart_device::write)
|
||||||
|
{
|
||||||
|
if (offset == 0x38fffe/2)
|
||||||
|
{
|
||||||
|
m_jcart_io_data[0] = (data & 1) << 6;
|
||||||
|
m_jcart_io_data[1] = (data & 1) << 6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
J-CART + SEPROM
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
READ16_MEMBER(md_seprom_codemast_device::read)
|
||||||
|
{
|
||||||
|
if (offset == 0x380000/2)
|
||||||
|
{
|
||||||
|
m_i2c_mem = i2cmem_sda_read(m_i2cmem);
|
||||||
|
return (m_i2c_mem & 1) << 7;
|
||||||
|
}
|
||||||
|
if (offset == 0x38fffe/2)
|
||||||
|
{
|
||||||
|
UINT8 joy[2];
|
||||||
|
|
||||||
|
if (m_jcart_io_data[0] & 0x40)
|
||||||
|
{
|
||||||
|
joy[0] = m_jcart3->read_safe(0);
|
||||||
|
joy[1] = m_jcart4->read_safe(0);
|
||||||
|
return (m_jcart_io_data[0] & 0x40) | joy[0] | (joy[1] << 8);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
joy[0] = ((m_jcart3->read_safe(0) & 0xc0) >> 2) | (m_jcart3->read_safe(0) & 0x03);
|
||||||
|
joy[1] = ((m_jcart4->read_safe(0) & 0xc0) >> 2) | (m_jcart4->read_safe(0) & 0x03);
|
||||||
|
return (m_jcart_io_data[0] & 0x40) | joy[0] | (joy[1] << 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return m_rom[offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE16_MEMBER(md_seprom_codemast_device::write)
|
||||||
|
{
|
||||||
|
if (offset == 0x380000/2)
|
||||||
|
{
|
||||||
|
m_i2c_clk = BIT(data, 9);
|
||||||
|
m_i2c_mem = BIT(data, 8);
|
||||||
|
i2cmem_scl_write(m_i2cmem, m_i2c_clk);
|
||||||
|
i2cmem_sda_write(m_i2cmem, m_i2c_mem);
|
||||||
|
}
|
||||||
|
if (offset == 0x38fffe/2)
|
||||||
|
{
|
||||||
|
m_jcart_io_data[0] = (data & 1) << 6;
|
||||||
|
m_jcart_io_data[1] = (data & 1) << 6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
83
src/mess/machine/md_jcart.h
Normal file
83
src/mess/machine/md_jcart.h
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
#ifndef __MD_JCART_H
|
||||||
|
#define __MD_JCART_H
|
||||||
|
|
||||||
|
#include "machine/md_slot.h"
|
||||||
|
#include "machine/i2cmem.h"
|
||||||
|
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// TYPE DEFINITIONS
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
// ======================> md_jcart_device
|
||||||
|
|
||||||
|
class md_jcart_device : public device_t,
|
||||||
|
public device_md_cart_interface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
md_jcart_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
md_jcart_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_start();
|
||||||
|
virtual void device_config_complete() { m_shortname = "md_jcart"; }
|
||||||
|
virtual ioport_constructor device_input_ports() const;
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ16_MEMBER(read);
|
||||||
|
virtual DECLARE_WRITE16_MEMBER(write);
|
||||||
|
|
||||||
|
required_ioport m_jcart3;
|
||||||
|
required_ioport m_jcart4;
|
||||||
|
|
||||||
|
private:
|
||||||
|
UINT8 m_jcart_io_data[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================> md_seprom_codemast_device
|
||||||
|
|
||||||
|
class md_seprom_codemast_device : public md_jcart_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
md_seprom_codemast_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
md_seprom_codemast_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_start();
|
||||||
|
virtual void device_config_complete() { m_shortname = "md_seprom_codemast"; }
|
||||||
|
virtual machine_config_constructor device_mconfig_additions() const;
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ16_MEMBER(read);
|
||||||
|
virtual DECLARE_WRITE16_MEMBER(write);
|
||||||
|
|
||||||
|
required_device<i2cmem_device> m_i2cmem;
|
||||||
|
|
||||||
|
private:
|
||||||
|
UINT8 m_jcart_io_data[2];
|
||||||
|
UINT8 m_i2c_mem, m_i2c_clk;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================> md_seprom_mm96_device (same read/write as codemast, but different I2C type)
|
||||||
|
|
||||||
|
class md_seprom_mm96_device : public md_seprom_codemast_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
md_seprom_mm96_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_config_complete() { m_shortname = "md_seprom_mm96"; }
|
||||||
|
virtual machine_config_constructor device_mconfig_additions() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// device type definition
|
||||||
|
extern const device_type MD_JCART;
|
||||||
|
extern const device_type MD_SEPROM_CODEMAST;
|
||||||
|
extern const device_type MD_SEPROM_MM96;
|
||||||
|
|
||||||
|
#endif
|
924
src/mess/machine/md_rom.c
Normal file
924
src/mess/machine/md_rom.c
Normal file
@ -0,0 +1,924 @@
|
|||||||
|
/***********************************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
MegaDrive / Genesis cart emulation
|
||||||
|
|
||||||
|
|
||||||
|
Here we emulate bankswitch / protection / NVRAM found on generic carts with no additional hardware
|
||||||
|
|
||||||
|
|
||||||
|
***********************************************************************************************************/
|
||||||
|
|
||||||
|
#include "emu.h"
|
||||||
|
#include "machine/md_rom.h"
|
||||||
|
#include "cpu/m68000/m68000.h"
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// md_rom_device - constructor
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
// BASE CARTS + NVRAM
|
||||||
|
const device_type MD_STD_ROM = &device_creator<md_std_rom_device>;
|
||||||
|
const device_type MD_ROM_SRAM = &device_creator<md_rom_sram_device>;
|
||||||
|
const device_type MD_ROM_FRAM = &device_creator<md_rom_fram_device>;
|
||||||
|
|
||||||
|
// BASE CARTS + PROTECTION / BANKSWITCH
|
||||||
|
const device_type MD_ROM_SSF2 = &device_creator<md_rom_ssf2_device>;
|
||||||
|
const device_type MD_ROM_BUGSLIFE = &device_creator<md_rom_bugslife_device>;
|
||||||
|
const device_type MD_ROM_SMOUSE = &device_creator<md_rom_smouse_device>;
|
||||||
|
const device_type MD_ROM_SMB = &device_creator<md_rom_smb_device>;
|
||||||
|
const device_type MD_ROM_SMB2 = &device_creator<md_rom_smb2_device>;
|
||||||
|
const device_type MD_ROM_SBUBL = &device_creator<md_rom_sbubl_device>;
|
||||||
|
const device_type MD_ROM_RX3 = &device_creator<md_rom_rx3_device>;
|
||||||
|
const device_type MD_ROM_MJLOV = &device_creator<md_rom_mjlov_device>;
|
||||||
|
const device_type MD_ROM_KOF98 = &device_creator<md_rom_kof98_device>;
|
||||||
|
const device_type MD_ROM_KOF99 = &device_creator<md_rom_kof99_device>;
|
||||||
|
const device_type MD_ROM_SOULB = &device_creator<md_rom_soulb_device>;
|
||||||
|
const device_type MD_ROM_CHINF3 = &device_creator<md_rom_chinf3_device>;
|
||||||
|
const device_type MD_ROM_ELFWOR = &device_creator<md_rom_elfwor_device>;
|
||||||
|
const device_type MD_ROM_LION2 = &device_creator<md_rom_lion2_device>;
|
||||||
|
const device_type MD_ROM_LION3 = &device_creator<md_rom_lion3_device>;
|
||||||
|
const device_type MD_ROM_MCPIR = &device_creator<md_rom_mcpirate_device>;
|
||||||
|
const device_type MD_ROM_POKESTAD = &device_creator<md_rom_pokestad_device>;
|
||||||
|
const device_type MD_ROM_REALTEC = &device_creator<md_rom_realtec_device>;
|
||||||
|
const device_type MD_ROM_REDCL = &device_creator<md_rom_redcl_device>;
|
||||||
|
const device_type MD_ROM_SQUIR = &device_creator<md_rom_squir_device>;
|
||||||
|
const device_type MD_ROM_TOPF = &device_creator<md_rom_topf_device>;
|
||||||
|
const device_type MD_ROM_RADICA = &device_creator<md_rom_radica_device>;
|
||||||
|
const device_type MD_ROM_BEGGAR = &device_creator<md_rom_beggar_device>;
|
||||||
|
|
||||||
|
// below ones are currently unused, because the protection is patched out
|
||||||
|
const device_type MD_ROM_MULAN = &device_creator<md_std_rom_device>;
|
||||||
|
const device_type MD_ROM_POKE = &device_creator<md_std_rom_device>;
|
||||||
|
const device_type MD_ROM_POKE2 = &device_creator<md_std_rom_device>;
|
||||||
|
|
||||||
|
|
||||||
|
md_std_rom_device::md_std_rom_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: device_t(mconfig, type, name, tag, owner, clock),
|
||||||
|
device_md_cart_interface( mconfig, *this )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
md_std_rom_device::md_std_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: device_t(mconfig, MD_STD_ROM, "MD Standard cart", tag, owner, clock),
|
||||||
|
device_md_cart_interface( mconfig, *this )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
md_rom_sram_device::md_rom_sram_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: md_std_rom_device(mconfig, MD_ROM_SRAM, "MD Standard cart + SRAM", tag, owner, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
md_rom_beggar_device::md_rom_beggar_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: md_std_rom_device(mconfig, MD_ROM_BEGGAR, "MD Xin Qigai Wangzi", tag, owner, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
md_rom_fram_device::md_rom_fram_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: md_std_rom_device(mconfig, MD_ROM_FRAM, "MD Standard cart + FRAM", tag, owner, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
md_rom_ssf2_device::md_rom_ssf2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: md_std_rom_device(mconfig, MD_ROM_SSF2, "MD Super SF2", tag, owner, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
md_rom_mcpirate_device::md_rom_mcpirate_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: md_std_rom_device(mconfig, MD_ROM_MCPIR, "MD Pirate Multicarts (Various)", tag, owner, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
md_rom_bugslife_device::md_rom_bugslife_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: md_std_rom_device(mconfig, MD_ROM_BUGSLIFE, "MD A Bug's Life", tag, owner, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
md_rom_smouse_device::md_rom_smouse_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: md_std_rom_device(mconfig, MD_ROM_SMOUSE, "MD Huan Le Tao Qi Shu / Smart Mouse", tag, owner, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
md_rom_smb_device::md_rom_smb_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: md_std_rom_device(mconfig, MD_ROM_SMB, "MD Super Mario Bros.", tag, owner, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
md_rom_smb2_device::md_rom_smb2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: md_std_rom_device(mconfig, MD_ROM_SMB2, "MD Super Mario Bros. 2", tag, owner, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
md_rom_sbubl_device::md_rom_sbubl_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: md_std_rom_device(mconfig, MD_ROM_SBUBL, "MD Super Bubble Bobble", tag, owner, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
md_rom_rx3_device::md_rom_rx3_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: md_std_rom_device(mconfig, MD_ROM_SMB2, "MD Rockman X3", tag, owner, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
md_rom_mjlov_device::md_rom_mjlov_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: md_std_rom_device(mconfig, MD_ROM_MJLOV, "MD Ma Jiang Qing Ren / Mahjong Lover", tag, owner, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
md_rom_kof98_device::md_rom_kof98_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: md_std_rom_device(mconfig, MD_ROM_KOF98, "MD KOF 98", tag, owner, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
md_rom_kof99_device::md_rom_kof99_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: md_std_rom_device(mconfig, MD_ROM_KOF99, "MD KOF 99", tag, owner, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
md_rom_soulb_device::md_rom_soulb_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: md_std_rom_device(mconfig, MD_ROM_SOULB, "MD Soul Blade", tag, owner, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
md_rom_chinf3_device::md_rom_chinf3_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: md_std_rom_device(mconfig, MD_ROM_CHINF3, "MD Chinese Fighter 3", tag, owner, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
md_rom_elfwor_device::md_rom_elfwor_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: md_std_rom_device(mconfig, MD_ROM_ELFWOR, "MD Linghuan Daoshi Super Magician / Elf Wor", tag, owner, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
md_rom_lion2_device::md_rom_lion2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: md_std_rom_device(mconfig, MD_ROM_LION2, "MD Lion King 2", tag, owner, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
md_rom_lion3_device::md_rom_lion3_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: md_std_rom_device(mconfig, MD_ROM_LION3, "MD Lion King 3", tag, owner, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
md_rom_pokestad_device::md_rom_pokestad_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: md_std_rom_device(mconfig, MD_ROM_POKESTAD, "MD Pokemon Stadium", tag, owner, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
md_rom_realtec_device::md_rom_realtec_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: md_std_rom_device(mconfig, MD_ROM_REALTEC, "MD Realtec", tag, owner, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
md_rom_redcl_device::md_rom_redcl_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: md_std_rom_device(mconfig, MD_ROM_REDCL, "MD Redcliff", tag, owner, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
md_rom_squir_device::md_rom_squir_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: md_std_rom_device(mconfig, MD_ROM_SQUIR, "MD Squirrel King", tag, owner, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
md_rom_topf_device::md_rom_topf_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: md_std_rom_device(mconfig, MD_ROM_TOPF, "MD Top Fighter", tag, owner, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
md_rom_radica_device::md_rom_radica_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: md_std_rom_device(mconfig, MD_ROM_RADICA, "MD Radica TV games", tag, owner, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// device_start - device-specific startup
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void md_rom_ssf2_device::device_start()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 7; i++)
|
||||||
|
m_bank[i] = i;
|
||||||
|
m_lastoff = -1;
|
||||||
|
m_lastdata = -1;
|
||||||
|
save_item(NAME(m_bank));
|
||||||
|
save_item(NAME(m_lastoff));
|
||||||
|
save_item(NAME(m_lastdata));
|
||||||
|
}
|
||||||
|
|
||||||
|
void md_rom_mcpirate_device::device_start()
|
||||||
|
{
|
||||||
|
m_bank = 0;
|
||||||
|
save_item(NAME(m_bank));
|
||||||
|
}
|
||||||
|
|
||||||
|
void md_rom_chinf3_device::device_start()
|
||||||
|
{
|
||||||
|
m_bank = 0;
|
||||||
|
save_item(NAME(m_bank));
|
||||||
|
}
|
||||||
|
|
||||||
|
void md_rom_lion2_device::device_start()
|
||||||
|
{
|
||||||
|
m_prot1_data = 0;
|
||||||
|
m_prot2_data = 0;
|
||||||
|
save_item(NAME(m_prot1_data));
|
||||||
|
save_item(NAME(m_prot2_data));
|
||||||
|
}
|
||||||
|
|
||||||
|
void md_rom_lion3_device::device_start()
|
||||||
|
{
|
||||||
|
m_prot_data = 0;
|
||||||
|
m_prot_cmd = 0;
|
||||||
|
m_bank = 0;
|
||||||
|
save_item(NAME(m_prot_data));
|
||||||
|
save_item(NAME(m_prot_cmd));
|
||||||
|
save_item(NAME(m_bank));
|
||||||
|
}
|
||||||
|
|
||||||
|
void md_rom_pokestad_device::device_start()
|
||||||
|
{
|
||||||
|
m_bank = 0;
|
||||||
|
save_item(NAME(m_bank));
|
||||||
|
}
|
||||||
|
|
||||||
|
void md_rom_realtec_device::device_start()
|
||||||
|
{
|
||||||
|
m_bank_addr = 0;
|
||||||
|
m_bank_size = 0;
|
||||||
|
m_old_bank_addr = -1;
|
||||||
|
save_item(NAME(m_bank_addr));
|
||||||
|
save_item(NAME(m_bank_size));
|
||||||
|
save_item(NAME(m_old_bank_addr));
|
||||||
|
}
|
||||||
|
|
||||||
|
void md_rom_squir_device::device_start()
|
||||||
|
{
|
||||||
|
m_latch = 0;
|
||||||
|
save_item(NAME(m_latch));
|
||||||
|
}
|
||||||
|
|
||||||
|
void md_rom_topf_device::device_start()
|
||||||
|
{
|
||||||
|
m_latch = 0;
|
||||||
|
m_bank[0] = m_bank[1] = m_bank[2] = 0;
|
||||||
|
save_item(NAME(m_latch));
|
||||||
|
save_item(NAME(m_bank));
|
||||||
|
}
|
||||||
|
|
||||||
|
void md_rom_radica_device::device_start()
|
||||||
|
{
|
||||||
|
m_bank = 0;
|
||||||
|
save_item(NAME(m_bank));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
mapper specific handlers
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
CART + SRAM
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
READ16_MEMBER(md_rom_sram_device::read)
|
||||||
|
{
|
||||||
|
offset <<= 1;
|
||||||
|
// since a lot of generic carts ends up here if loaded from fullpath
|
||||||
|
// we access nvram only if m_nvram_handlers_installed has been turned on
|
||||||
|
if (m_nvram_handlers_installed)
|
||||||
|
{
|
||||||
|
if (offset >= m_nvram_start && offset < m_nvram_end && m_nvram_active)
|
||||||
|
return m_nvram[(offset - m_nvram_start)/2];
|
||||||
|
}
|
||||||
|
return m_rom[offset/2];
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE16_MEMBER(md_rom_sram_device::write)
|
||||||
|
{
|
||||||
|
// since a lot of generic carts ends up here if loaded from fullpath
|
||||||
|
// we access nvram only if m_nvram_handlers_installed has been turned on
|
||||||
|
if (m_nvram_handlers_installed)
|
||||||
|
{
|
||||||
|
offset <<= 1;
|
||||||
|
if (offset >= m_nvram_start && offset <= m_nvram_end && m_nvram_active && !m_nvram_readonly)
|
||||||
|
m_nvram[(offset - m_nvram_start)/2] = data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE16_MEMBER(md_rom_sram_device::write_a13)
|
||||||
|
{
|
||||||
|
offset <<= 1;
|
||||||
|
if (offset == 0xf)
|
||||||
|
{
|
||||||
|
/* unsure if this is actually supposed to toggle or just switch on? yet to encounter game that uses this */
|
||||||
|
m_nvram_active = BIT(data, 0);
|
||||||
|
m_nvram_readonly = BIT(data, 1);
|
||||||
|
|
||||||
|
// since a lot of generic carts ends up here if loaded from fullpath
|
||||||
|
// we turn on nvram (with m_nvram_handlers_installed) only if they toggle it on by writing here!
|
||||||
|
if (m_nvram_active && !m_nvram_handlers_installed)
|
||||||
|
m_nvram_handlers_installed = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
BEGGAR PRINCE / XIN QIGAI WANGZI [same as above, but diff start/end... merge?]
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
READ16_MEMBER(md_rom_beggar_device::read)
|
||||||
|
{
|
||||||
|
offset <<= 1;
|
||||||
|
if (offset >= m_nvram_start && offset < m_nvram_end && m_nvram_active)
|
||||||
|
return m_nvram[(offset - m_nvram_start)/2];
|
||||||
|
return m_rom[offset/2];
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE16_MEMBER(md_rom_beggar_device::write)
|
||||||
|
{
|
||||||
|
offset <<= 1;
|
||||||
|
if (offset >= m_nvram_start && offset <= m_nvram_end && m_nvram_active && !m_nvram_readonly)
|
||||||
|
m_nvram[(offset - m_nvram_start)/2] = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE16_MEMBER(md_rom_beggar_device::write_a13)
|
||||||
|
{
|
||||||
|
offset <<= 1;
|
||||||
|
if (offset == 0xf)
|
||||||
|
{
|
||||||
|
/* unsure if this is actually supposed to toggle or just switch on? yet to encounter game that uses this */
|
||||||
|
m_nvram_active = BIT(data, 0);
|
||||||
|
m_nvram_readonly = BIT(data, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
CART + FRAM [almost same as SRAM... merge common parts?]
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
READ16_MEMBER(md_rom_fram_device::read)
|
||||||
|
{
|
||||||
|
offset <<= 1;
|
||||||
|
if (offset >= m_nvram_start && offset < m_nvram_end && m_nvram_active)
|
||||||
|
return m_nvram[(offset - m_nvram_start)/2];
|
||||||
|
return m_rom[offset/2];
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE16_MEMBER(md_rom_fram_device::write_a13)
|
||||||
|
{
|
||||||
|
offset <<= 1;
|
||||||
|
if (offset == 0xf)
|
||||||
|
m_nvram_active = BIT(data, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
READ16_MEMBER(md_rom_fram_device::read_a13)
|
||||||
|
{
|
||||||
|
if (offset == 0xf)
|
||||||
|
return m_nvram_active;
|
||||||
|
else
|
||||||
|
return 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
SUPER STREET FIGHTERS 2
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
READ16_MEMBER(md_rom_ssf2_device::read)
|
||||||
|
{
|
||||||
|
if (offset < 0x400000/2)
|
||||||
|
return m_rom[offset];
|
||||||
|
else
|
||||||
|
return 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
// I'm not very fond of the code below...
|
||||||
|
WRITE16_MEMBER(md_rom_ssf2_device::write_a13)
|
||||||
|
{
|
||||||
|
if (offset >= 0xf0/2)
|
||||||
|
{
|
||||||
|
offset -= 0xf0/2;
|
||||||
|
if ((m_lastoff != offset) || (m_lastdata != data))
|
||||||
|
{
|
||||||
|
m_lastoff = offset;
|
||||||
|
m_lastdata = data;
|
||||||
|
if (offset) // bank 0 is not modified
|
||||||
|
{
|
||||||
|
UINT16 *ROM = get_rom_base();
|
||||||
|
m_bank[offset] = data & 0xf;
|
||||||
|
memcpy(ROM + offset * 0x080000/2, ROM + 0x400000/2 + (m_bank[offset] * 0x080000)/2, 0x080000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
PIRATE MULTICARTS
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
READ16_MEMBER(md_rom_mcpirate_device::read)
|
||||||
|
{
|
||||||
|
if (offset < 0x400000/2)
|
||||||
|
{
|
||||||
|
return m_rom[offset + (m_bank * 0x10000)/2];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return read(space, offset - 0x400000/2, 0xffff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE16_MEMBER(md_rom_mcpirate_device::write_a13)
|
||||||
|
{
|
||||||
|
offset <<= 1;
|
||||||
|
if (offset < 0x40)
|
||||||
|
m_bank = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
A BUG'S LIFE
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
READ16_MEMBER(md_rom_bugslife_device::read_a13)
|
||||||
|
{
|
||||||
|
if (offset == 0)
|
||||||
|
return 0x28;
|
||||||
|
else
|
||||||
|
return 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
CHINESE FIGHTER 3
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
READ16_MEMBER(md_rom_chinf3_device::read)
|
||||||
|
{
|
||||||
|
if (offset < 0x100000/2)
|
||||||
|
{
|
||||||
|
if (!m_bank)
|
||||||
|
return m_rom[offset & 0xfffff/2];
|
||||||
|
else
|
||||||
|
return m_rom[(offset & 0xffff/2) + (m_bank * 0x10000)/2];
|
||||||
|
}
|
||||||
|
|
||||||
|
// PROTECTION in 0x400000 - 0x4fffff
|
||||||
|
/* not 100% correct, there may be some relationship between the reads here
|
||||||
|
and the writes made at the start of the game.. */
|
||||||
|
if (offset >= 0x400000/2 && offset < 0x500000/2)
|
||||||
|
{
|
||||||
|
UINT32 retdat = 0;
|
||||||
|
/*
|
||||||
|
04dc10 chifi3, prot_r? 2800
|
||||||
|
04cefa chifi3, prot_r? 65262
|
||||||
|
*/
|
||||||
|
if (space.machine().device("maincpu")->safe_pc() == 0x01782) // makes 'VS' screen appear
|
||||||
|
{
|
||||||
|
retdat = space.machine().device("maincpu")->state().state_int(M68K_D3) & 0xff;
|
||||||
|
retdat <<= 8;
|
||||||
|
return retdat;
|
||||||
|
}
|
||||||
|
else if (space.machine().device("maincpu")->safe_pc() == 0x1c24) // background gfx etc.
|
||||||
|
{
|
||||||
|
retdat = space.machine().device("maincpu")->state().state_int(M68K_D3) & 0xff;
|
||||||
|
retdat <<= 8;
|
||||||
|
return retdat;
|
||||||
|
}
|
||||||
|
else if (space.machine().device("maincpu")->safe_pc() == 0x10c4a) // unknown
|
||||||
|
{
|
||||||
|
return space.machine().rand();
|
||||||
|
}
|
||||||
|
else if (space.machine().device("maincpu")->safe_pc() == 0x10c50) // unknown
|
||||||
|
{
|
||||||
|
return space.machine().rand();
|
||||||
|
}
|
||||||
|
else if (space.machine().device("maincpu")->safe_pc() == 0x10c52) // relates to the game speed..
|
||||||
|
{
|
||||||
|
retdat = space.machine().device("maincpu")->state().state_int(M68K_D4) & 0xff;
|
||||||
|
retdat <<= 8;
|
||||||
|
return retdat;
|
||||||
|
}
|
||||||
|
else if (space.machine().device("maincpu")->safe_pc() == 0x061ae)
|
||||||
|
{
|
||||||
|
retdat = space.machine().device("maincpu")->state().state_int(M68K_D3) & 0xff;
|
||||||
|
retdat <<= 8;
|
||||||
|
return retdat;
|
||||||
|
}
|
||||||
|
else if (space.machine().device("maincpu")->safe_pc() == 0x061b0)
|
||||||
|
{
|
||||||
|
retdat = space.machine().device("maincpu")->state().state_int(M68K_D3) & 0xff;
|
||||||
|
retdat <<= 8;
|
||||||
|
return retdat;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logerror("%06x chifi3, prot_r? %04x\n", space.machine().device("maincpu")->safe_pc(), offset);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_rom[offset & 0x1fffff/2];
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE16_MEMBER(md_rom_chinf3_device::write)
|
||||||
|
{
|
||||||
|
if (offset >= 0x600000/2 && offset < 0x700000/2)
|
||||||
|
{
|
||||||
|
if (data == 0xf100) // *hit player
|
||||||
|
m_bank = 1;
|
||||||
|
else if (data == 0xd700) // title screen..
|
||||||
|
m_bank = 7;
|
||||||
|
else if (data == 0xd300) // character hits floor
|
||||||
|
m_bank = 3;
|
||||||
|
else if (data == 0x0000)
|
||||||
|
m_bank = 0;
|
||||||
|
else
|
||||||
|
logerror("%06x chifi3, bankw? %04x %04x\n", space.device().safe_pc(), offset, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
LINGHUAN DAOSHI SUPER MAGICIAN / ELF WOR
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
READ16_MEMBER(md_rom_elfwor_device::read)
|
||||||
|
{
|
||||||
|
/* It returns (0x55 @ 0x400000 OR 0xc9 @ 0x400004) AND (0x0f @ 0x400002 OR 0x18 @ 0x400006).
|
||||||
|
It is probably best to add handlers for all 4 addresses. */
|
||||||
|
if (offset == 0x400000/2) return 0x5500;
|
||||||
|
if (offset == 0x400002/2) return 0x0f00;
|
||||||
|
if (offset == 0x400004/2) return 0xc900;
|
||||||
|
if (offset == 0x400006/2) return 0x1800;
|
||||||
|
return m_rom[offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
HUAN LE TAO QI SHU / SMART MOUSE
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
READ16_MEMBER(md_rom_smouse_device::read)
|
||||||
|
{
|
||||||
|
if (offset == 0x400000/2) return 0x5500;
|
||||||
|
if (offset == 0x400002/2) return 0x0f00;
|
||||||
|
if (offset == 0x400004/2) return 0xaa00;
|
||||||
|
if (offset == 0x400006/2) return 0xf000;
|
||||||
|
return m_rom[offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
KOF98
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
READ16_MEMBER(md_rom_kof98_device::read)
|
||||||
|
{
|
||||||
|
if (offset == 0x480000/2) return 0xaa00;
|
||||||
|
if (offset == 0x4800e0/2) return 0xaa00;
|
||||||
|
if (offset == 0x4824a0/2) return 0xaa00;
|
||||||
|
if (offset == 0x488880/2) return 0xaa00;
|
||||||
|
if (offset == 0x4a8820/2) return 0x0a00;
|
||||||
|
if (offset == 0x4f8820/2) return 0x0000;
|
||||||
|
return m_rom[offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
KOF 99
|
||||||
|
-------------------------------------------------*/
|
||||||
|
// gfx glitch with the new code... uninitialized ram somewhere?
|
||||||
|
READ16_MEMBER(md_rom_kof99_device::read_a13)
|
||||||
|
{
|
||||||
|
if (offset == 0x00/2) return 0x00; // startup protection check, chinese message if != 0
|
||||||
|
if (offset == 0x02/2) return 0x01; // write 02 to a13002.. shift right 1?
|
||||||
|
if (offset == 0x3e/2) return 0x1f; // write 3e to a1303e.. shift right 1?
|
||||||
|
else return 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
LION KING 2
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
READ16_MEMBER(md_rom_lion2_device::read)
|
||||||
|
{
|
||||||
|
if (offset == 0x400002/2) return m_prot1_data;
|
||||||
|
if (offset == 0x400006/2) return m_prot2_data;
|
||||||
|
return m_rom[offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE16_MEMBER(md_rom_lion2_device::write)
|
||||||
|
{
|
||||||
|
if (offset == 0x400000/2) m_prot1_data = data;
|
||||||
|
if (offset == 0x400004/2) m_prot2_data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
LION KING 3
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
READ16_MEMBER(md_rom_lion3_device::read)
|
||||||
|
{
|
||||||
|
if (offset < 0x8000/2)
|
||||||
|
return m_rom[offset + (m_bank * 0x8000)/2];
|
||||||
|
else if (offset >= 0x600000/2 && offset < 0x700000/2)
|
||||||
|
{
|
||||||
|
UINT16 retdata = 0;
|
||||||
|
switch (offset & 0x7)
|
||||||
|
{
|
||||||
|
case 2:
|
||||||
|
if (m_prot_cmd == 0)
|
||||||
|
retdata = (m_prot_data << 1);
|
||||||
|
else if (m_prot_cmd == 1)
|
||||||
|
retdata = (m_prot_data >> 1);
|
||||||
|
else if (m_prot_cmd == 2)
|
||||||
|
{
|
||||||
|
retdata = m_prot_data >> 4;
|
||||||
|
retdata |= (m_prot_data & 0x0f) << 4;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* printf("unk prot case %d\n", m_prot_cmd); */
|
||||||
|
retdata = (BIT(m_prot_data, 7) << 0);
|
||||||
|
retdata |= (BIT(m_prot_data, 6) << 1);
|
||||||
|
retdata |= (BIT(m_prot_data, 5) << 2);
|
||||||
|
retdata |= (BIT(m_prot_data, 4) << 3);
|
||||||
|
retdata |= (BIT(m_prot_data, 3) << 4);
|
||||||
|
retdata |= (BIT(m_prot_data, 2) << 5);
|
||||||
|
retdata |= (BIT(m_prot_data, 1) << 6);
|
||||||
|
retdata |= (BIT(m_prot_data, 0) << 7);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
logerror("protection read, unknown offset %x\n", offset & 0x7);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return retdata;
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_rom[offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE16_MEMBER(md_rom_lion3_device::write)
|
||||||
|
{
|
||||||
|
if (offset >= 0x600000/2 && offset < 0x700000/2)
|
||||||
|
{
|
||||||
|
switch (offset & 0x7)
|
||||||
|
{
|
||||||
|
case 0x0:
|
||||||
|
m_prot_data = data;
|
||||||
|
break;
|
||||||
|
case 0x1:
|
||||||
|
m_prot_cmd = data;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
logerror("protection write, unknown offset %d\n", offset & 0x7);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (offset >= 0x700000/2 && offset < 0x800000/2)
|
||||||
|
{
|
||||||
|
switch (offset & 0x7)
|
||||||
|
{
|
||||||
|
case 0x0:
|
||||||
|
m_bank = data & 0xffff;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
logerror("bank write, unknown offset %d\n", offset & 0x7);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
MA JIANG QING REN / MAHJONG LOVER
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
READ16_MEMBER(md_rom_mjlov_device::read)
|
||||||
|
{
|
||||||
|
if (offset == 0x400000/2) return 0x9000;
|
||||||
|
if (offset == 0x401000/2) return 0xd300;
|
||||||
|
return m_rom[offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
SUPER BUBBLE BOBBLE MD
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
READ16_MEMBER(md_rom_sbubl_device::read)
|
||||||
|
{
|
||||||
|
if (offset == 0x400000/2) return 0x5500;
|
||||||
|
if (offset == 0x400002/2) return 0x0f00;
|
||||||
|
return m_rom[offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
SOUL BLADE
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
READ16_MEMBER(md_rom_soulb_device::read)
|
||||||
|
{
|
||||||
|
if (offset == 0x400002/2) return 0x9800;
|
||||||
|
if (offset == 0x400004/2) return 0xc900;
|
||||||
|
if (offset == 0x400006/2) return 0xf000;
|
||||||
|
return m_rom[offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
POKEMON STADIUM / KAIJU
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
READ16_MEMBER(md_rom_pokestad_device::read)
|
||||||
|
{
|
||||||
|
if (offset < 0x8000/2)
|
||||||
|
return m_rom[offset + (m_bank * 0x8000)/2];
|
||||||
|
return m_rom[offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE16_MEMBER(md_rom_pokestad_device::write)
|
||||||
|
{
|
||||||
|
if (offset >= 0x700000/2 && offset < 0x800000/2)
|
||||||
|
m_bank = data & 0x7f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
REALTEC
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
READ16_MEMBER(md_rom_realtec_device::read)
|
||||||
|
{
|
||||||
|
if (offset < (m_bank_size * 0x20000)) // two banks of same (variable) size at the bottom of the rom
|
||||||
|
return m_rom[offset + (m_bank_addr * 0x20000)/2];
|
||||||
|
return m_rom[(offset & 0x1fff/2) + 0x7e000/2]; // otherwise it accesses the final 8k of the image
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE16_MEMBER(md_rom_realtec_device::write)
|
||||||
|
{
|
||||||
|
if (offset == 0x400000/2)
|
||||||
|
{
|
||||||
|
m_old_bank_addr = m_bank_addr;
|
||||||
|
m_bank_addr = (m_bank_addr & 0x7) | ((data >> 9) & 0x7) << 3;
|
||||||
|
}
|
||||||
|
if (offset == 0x402000/2)
|
||||||
|
{
|
||||||
|
m_bank_addr = 0;
|
||||||
|
m_bank_size = (data >> 8) & 0x1f;
|
||||||
|
}
|
||||||
|
if (offset == 0x404000/2)
|
||||||
|
{
|
||||||
|
m_old_bank_addr = m_bank_addr;
|
||||||
|
m_bank_addr = (m_bank_addr & 0xf8) | ((data >> 8) & 0x3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
RED CLIFF
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
READ16_MEMBER(md_rom_redcl_device::read)
|
||||||
|
{
|
||||||
|
if (offset == 0x400000/2) return 0x55 << 8;
|
||||||
|
if (offset == 0x400004/2) return -0x56 << 8;
|
||||||
|
return m_rom[offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
ROCKMAN X3
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
READ16_MEMBER(md_rom_rx3_device::read_a13)
|
||||||
|
{
|
||||||
|
if (offset == 0)
|
||||||
|
return 0x0c;
|
||||||
|
else
|
||||||
|
return 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
SQUIRREL KING
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
READ16_MEMBER(md_rom_squir_device::read)
|
||||||
|
{
|
||||||
|
if ((offset >= 0x400000/2) && (offset < 0x400008/2))
|
||||||
|
return m_latch;
|
||||||
|
return m_rom[offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE16_MEMBER(md_rom_squir_device::write)
|
||||||
|
{
|
||||||
|
if (offset >= 0x400000/2 && offset < 0x400008/2)
|
||||||
|
m_latch = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
SUPER MARIO BROS
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
READ16_MEMBER(md_rom_smb_device::read_a13)
|
||||||
|
{
|
||||||
|
if (offset == 0)
|
||||||
|
return 0x0c;
|
||||||
|
else
|
||||||
|
return 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
SUPER MARIO BROS 2
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
READ16_MEMBER(md_rom_smb2_device::read_a13)
|
||||||
|
{
|
||||||
|
if (offset == 0)
|
||||||
|
return 0x0a;
|
||||||
|
else
|
||||||
|
return 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
TOP FIGHTER
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
READ16_MEMBER(md_rom_topf_device::read)
|
||||||
|
{
|
||||||
|
//cpu #0 (PC=0004CBAE): unmapped program memory word read from 006A35D4 & 00FF -- wants regD7
|
||||||
|
if (offset == 0x645b44/2)
|
||||||
|
{
|
||||||
|
//cpu #0 (PC=0004DE00): unmapped program memory word write to 00689B80 = 004A & 00FF
|
||||||
|
//cpu #0 (PC=0004DE08): unmapped program memory word write to 00 = 00B5 & 00FF
|
||||||
|
//cpu #0 (PC=0004DE0C): unmapped program memory word read from 00645B44 & 00FF
|
||||||
|
|
||||||
|
return 0x9f;//0x25;
|
||||||
|
}
|
||||||
|
if (offset == 0x6bd294/2)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
cpu #0 (PC=00177192): unmapped program memory word write to 006BD240 = 00A8 & 00FF
|
||||||
|
cpu #0 (PC=0017719A): unmapped program memory word write to 006BD2D2 = 0098 & 00FF
|
||||||
|
cpu #0 (PC=001771A2): unmapped program memory word read from 006BD294 & 00FF
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (space.device().safe_pc()==0x1771a2) return 0x50;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_latch++;
|
||||||
|
logerror("%06x topfig_6BD294_r %04x\n",space.device().safe_pc(), m_latch);
|
||||||
|
return m_latch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (offset == 0x6f5344/2)
|
||||||
|
{
|
||||||
|
if (space.device().safe_pc()==0x4C94E)
|
||||||
|
return space.machine().device("maincpu")->state().state_int((M68K_D0)) & 0xff;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_latch++;
|
||||||
|
logerror("%06x topfig_6F5344_r %04x\n", space.device().safe_pc(), m_latch);
|
||||||
|
return m_latch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (offset >= 0x20000/2 && offset < 0x28000/2)
|
||||||
|
return m_rom[offset + (m_bank[0] * 0x188000)/2];
|
||||||
|
|
||||||
|
if (offset >= 0x58000/2 && offset < 0x60000/2)
|
||||||
|
return m_rom[offset + (m_bank[1] * 0x20000)/2];
|
||||||
|
|
||||||
|
if (offset >= 0x60000/2 && offset < 0x68000/2)
|
||||||
|
return m_rom[offset + (m_bank[2] * 0x110000)/2];
|
||||||
|
|
||||||
|
return m_rom[offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE16_MEMBER(md_rom_topf_device::write)
|
||||||
|
{
|
||||||
|
if (offset >= 0x700000/2 && offset < 0x800000/2)
|
||||||
|
{
|
||||||
|
if (data == 0x002a)
|
||||||
|
m_bank[2] = 1; // == 0x2e*0x8000?!
|
||||||
|
else if (data==0x0035) // characters ingame
|
||||||
|
m_bank[0] = 1; // == 0x35*0x8000
|
||||||
|
else if (data==0x000f) // special moves
|
||||||
|
m_bank[1] = 1; // == 0xf*0x8000
|
||||||
|
else if (data==0x0000)
|
||||||
|
{
|
||||||
|
m_bank[0] = 0;
|
||||||
|
m_bank[1] = 0;
|
||||||
|
m_bank[2] = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
logerror("%06x offset %06x, data %04x\n", space.device().safe_pc(), offset, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
RADICA TV GAMES [to be split...]
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
READ16_MEMBER(md_rom_radica_device::read)
|
||||||
|
{
|
||||||
|
return m_rom[m_bank * 0x10000/2 + offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
READ16_MEMBER(md_rom_radica_device::read_a13)
|
||||||
|
{
|
||||||
|
if (offset < 0x80)
|
||||||
|
m_bank = offset & 0x3f;
|
||||||
|
return 0;
|
||||||
|
}
|
501
src/mess/machine/md_rom.h
Normal file
501
src/mess/machine/md_rom.h
Normal file
@ -0,0 +1,501 @@
|
|||||||
|
#ifndef __MD_ROM_H
|
||||||
|
#define __MD_ROM_H
|
||||||
|
|
||||||
|
#include "machine/md_slot.h"
|
||||||
|
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// TYPE DEFINITIONS
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
// ======================> md_std_rom_device
|
||||||
|
|
||||||
|
class md_std_rom_device : public device_t,
|
||||||
|
public device_md_cart_interface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
md_std_rom_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
md_std_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_start() {};
|
||||||
|
virtual void device_config_complete() { m_shortname = "md_std_rom"; }
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ16_MEMBER(read) { return m_rom[offset]; };
|
||||||
|
virtual DECLARE_WRITE16_MEMBER(write) { };
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================> md_rom_sram_device
|
||||||
|
|
||||||
|
class md_rom_sram_device : public md_std_rom_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
md_rom_sram_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_config_complete() { m_shortname = "md_rom_sram"; }
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ16_MEMBER(read);
|
||||||
|
virtual DECLARE_WRITE16_MEMBER(write);
|
||||||
|
virtual DECLARE_WRITE16_MEMBER(write_a13);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================> md_rom_beggar_device
|
||||||
|
|
||||||
|
class md_rom_beggar_device : public md_std_rom_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
md_rom_beggar_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_config_complete() { m_shortname = "md_rom_beggar"; }
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ16_MEMBER(read);
|
||||||
|
virtual DECLARE_WRITE16_MEMBER(write);
|
||||||
|
virtual DECLARE_WRITE16_MEMBER(write_a13);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================> md_rom_fram_device
|
||||||
|
|
||||||
|
class md_rom_fram_device : public md_std_rom_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
md_rom_fram_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_config_complete() { m_shortname = "md_rom_fram"; }
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ16_MEMBER(read);
|
||||||
|
virtual DECLARE_READ16_MEMBER(read_a13);
|
||||||
|
virtual DECLARE_WRITE16_MEMBER(write_a13);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================> md_rom_ssf2_device
|
||||||
|
|
||||||
|
class md_rom_ssf2_device : public md_std_rom_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
md_rom_ssf2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_start();
|
||||||
|
virtual void device_config_complete() { m_shortname = "md_rom_ssf2"; }
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ16_MEMBER(read);
|
||||||
|
virtual DECLARE_WRITE16_MEMBER(write_a13);
|
||||||
|
|
||||||
|
private:
|
||||||
|
UINT8 m_bank[16];
|
||||||
|
int m_lastoff, m_lastdata;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================> md_rom_mcpirate_device
|
||||||
|
|
||||||
|
class md_rom_mcpirate_device : public md_std_rom_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
md_rom_mcpirate_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_start();
|
||||||
|
virtual void device_config_complete() { m_shortname = "md_rom_mcpirate"; }
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ16_MEMBER(read);
|
||||||
|
virtual DECLARE_WRITE16_MEMBER(write_a13);
|
||||||
|
|
||||||
|
private:
|
||||||
|
UINT8 m_bank;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ======================> md_rom_bugslife_device
|
||||||
|
|
||||||
|
class md_rom_bugslife_device : public md_std_rom_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
md_rom_bugslife_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_config_complete() { m_shortname = "md_rom_bugslife"; }
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ16_MEMBER(read_a13);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================> md_rom_chinf3_device
|
||||||
|
|
||||||
|
class md_rom_chinf3_device : public md_std_rom_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
md_rom_chinf3_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_start();
|
||||||
|
virtual void device_config_complete() { m_shortname = "md_rom_chinf3"; }
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ16_MEMBER(read);
|
||||||
|
virtual DECLARE_WRITE16_MEMBER(write);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_bank;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================> md_rom_elfwor_device
|
||||||
|
|
||||||
|
class md_rom_elfwor_device : public md_std_rom_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
md_rom_elfwor_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_config_complete() { m_shortname = "md_rom_elfwor"; }
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ16_MEMBER(read);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================> md_rom_kof98_device
|
||||||
|
|
||||||
|
class md_rom_kof98_device : public md_std_rom_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
md_rom_kof98_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_config_complete() { m_shortname = "md_rom_kof98"; }
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ16_MEMBER(read);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================> md_rom_kof99_device
|
||||||
|
|
||||||
|
class md_rom_kof99_device : public md_std_rom_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
md_rom_kof99_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_config_complete() { m_shortname = "md_rom_kof99"; }
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ16_MEMBER(read_a13);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================> md_rom_lion2_device
|
||||||
|
|
||||||
|
class md_rom_lion2_device : public md_std_rom_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
md_rom_lion2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_start();
|
||||||
|
virtual void device_config_complete() { m_shortname = "md_rom_lion2"; }
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ16_MEMBER(read);
|
||||||
|
virtual DECLARE_WRITE16_MEMBER(write);
|
||||||
|
|
||||||
|
private:
|
||||||
|
UINT16 m_prot1_data, m_prot2_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================> md_rom_lion3_device
|
||||||
|
|
||||||
|
class md_rom_lion3_device : public md_std_rom_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
md_rom_lion3_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_start();
|
||||||
|
virtual void device_config_complete() { m_shortname = "md_rom_lion3"; }
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ16_MEMBER(read);
|
||||||
|
virtual DECLARE_WRITE16_MEMBER(write);
|
||||||
|
|
||||||
|
private:
|
||||||
|
UINT8 m_prot_data, m_prot_cmd;
|
||||||
|
UINT16 m_bank;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================> md_rom_mjlov_device
|
||||||
|
|
||||||
|
class md_rom_mjlov_device : public md_std_rom_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
md_rom_mjlov_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_config_complete() { m_shortname = "md_rom_mjlov"; }
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ16_MEMBER(read);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================> md_rom_pokestad_device
|
||||||
|
|
||||||
|
class md_rom_pokestad_device : public md_std_rom_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
md_rom_pokestad_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_start();
|
||||||
|
virtual void device_config_complete() { m_shortname = "md_rom_pokestad"; }
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ16_MEMBER(read);
|
||||||
|
virtual DECLARE_WRITE16_MEMBER(write);
|
||||||
|
|
||||||
|
private:
|
||||||
|
UINT8 m_bank;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================> md_rom_realtec_device
|
||||||
|
|
||||||
|
class md_rom_realtec_device : public md_std_rom_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
md_rom_realtec_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_start();
|
||||||
|
virtual void device_config_complete() { m_shortname = "md_rom_realtec"; }
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ16_MEMBER(read);
|
||||||
|
virtual DECLARE_WRITE16_MEMBER(write);
|
||||||
|
|
||||||
|
private:
|
||||||
|
UINT16 m_bank_addr, m_bank_size, m_old_bank_addr;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================> md_rom_redcl_device
|
||||||
|
|
||||||
|
class md_rom_redcl_device : public md_std_rom_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
md_rom_redcl_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_config_complete() { m_shortname = "md_rom_redcl"; }
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ16_MEMBER(read);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================> md_rom_rx3_device
|
||||||
|
|
||||||
|
class md_rom_rx3_device : public md_std_rom_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
md_rom_rx3_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_config_complete() { m_shortname = "md_rom_rx3"; }
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ16_MEMBER(read_a13);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================> md_rom_sbubl_device
|
||||||
|
|
||||||
|
class md_rom_sbubl_device : public md_std_rom_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
md_rom_sbubl_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_config_complete() { m_shortname = "md_rom_sbubl"; }
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ16_MEMBER(read);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================> md_rom_smb_device
|
||||||
|
|
||||||
|
class md_rom_smb_device : public md_std_rom_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
md_rom_smb_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_config_complete() { m_shortname = "md_rom_smb"; }
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ16_MEMBER(read_a13);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================> md_rom_smb2_device
|
||||||
|
|
||||||
|
class md_rom_smb2_device : public md_std_rom_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
md_rom_smb2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_config_complete() { m_shortname = "md_rom_smb2"; }
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ16_MEMBER(read_a13);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================> md_rom_smouse_device
|
||||||
|
|
||||||
|
class md_rom_smouse_device : public md_std_rom_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
md_rom_smouse_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_config_complete() { m_shortname = "md_rom_smouse"; }
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ16_MEMBER(read);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ======================> md_rom_soulb_device
|
||||||
|
|
||||||
|
class md_rom_soulb_device : public md_std_rom_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
md_rom_soulb_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_config_complete() { m_shortname = "md_rom_soulb"; }
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ16_MEMBER(read);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================> md_rom_squir_device
|
||||||
|
|
||||||
|
class md_rom_squir_device : public md_std_rom_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
md_rom_squir_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_start();
|
||||||
|
virtual void device_config_complete() { m_shortname = "md_rom_squir"; }
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ16_MEMBER(read);
|
||||||
|
virtual DECLARE_WRITE16_MEMBER(write);
|
||||||
|
|
||||||
|
private:
|
||||||
|
UINT16 m_latch;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================> md_rom_topf_device
|
||||||
|
|
||||||
|
class md_rom_topf_device : public md_std_rom_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
md_rom_topf_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_start();
|
||||||
|
virtual void device_config_complete() { m_shortname = "md_rom_topf"; }
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ16_MEMBER(read);
|
||||||
|
virtual DECLARE_WRITE16_MEMBER(write);
|
||||||
|
|
||||||
|
private:
|
||||||
|
UINT16 m_latch;
|
||||||
|
UINT8 m_bank[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================> md_rom_radica_device
|
||||||
|
|
||||||
|
class md_rom_radica_device : public md_std_rom_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
md_rom_radica_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_start();
|
||||||
|
virtual void device_config_complete() { m_shortname = "md_rom_radica"; }
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ16_MEMBER(read);
|
||||||
|
virtual DECLARE_READ16_MEMBER(read_a13);
|
||||||
|
|
||||||
|
private:
|
||||||
|
UINT8 m_bank;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// device type definition
|
||||||
|
extern const device_type MD_STD_ROM;
|
||||||
|
extern const device_type MD_ROM_SRAM;
|
||||||
|
extern const device_type MD_ROM_FRAM;
|
||||||
|
extern const device_type MD_ROM_BEGGAR;
|
||||||
|
extern const device_type MD_ROM_BUGSLIFE;
|
||||||
|
extern const device_type MD_ROM_CHINF3;
|
||||||
|
extern const device_type MD_ROM_ELFWOR;
|
||||||
|
extern const device_type MD_ROM_KOF98;
|
||||||
|
extern const device_type MD_ROM_KOF99;
|
||||||
|
extern const device_type MD_ROM_LION2;
|
||||||
|
extern const device_type MD_ROM_LION3;
|
||||||
|
extern const device_type MD_ROM_MCPIR;
|
||||||
|
extern const device_type MD_ROM_MJLOV;
|
||||||
|
extern const device_type MD_ROM_POKESTAD;
|
||||||
|
extern const device_type MD_ROM_REALTEC;
|
||||||
|
extern const device_type MD_ROM_REDCL;
|
||||||
|
extern const device_type MD_ROM_RX3;
|
||||||
|
extern const device_type MD_ROM_SBUBL;
|
||||||
|
extern const device_type MD_ROM_SMB;
|
||||||
|
extern const device_type MD_ROM_SMB2;
|
||||||
|
extern const device_type MD_ROM_SMOUSE;
|
||||||
|
extern const device_type MD_ROM_SOULB;
|
||||||
|
extern const device_type MD_ROM_SSF2;
|
||||||
|
extern const device_type MD_ROM_SQUIR;
|
||||||
|
extern const device_type MD_ROM_TOPF;
|
||||||
|
extern const device_type MD_ROM_RADICA;
|
||||||
|
|
||||||
|
// this are currently unused... protection is directly patched out!
|
||||||
|
extern const device_type MD_ROM_MULAN;
|
||||||
|
extern const device_type MD_ROM_POKE;
|
||||||
|
extern const device_type MD_ROM_POKE2;
|
||||||
|
|
||||||
|
#endif
|
90
src/mess/machine/md_sk.c
Normal file
90
src/mess/machine/md_sk.c
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
/***********************************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
Sonic & Knuckles pass-thorugh cart emulation
|
||||||
|
|
||||||
|
|
||||||
|
TODO: currently we only support loading of base carts with no bankswitch or protection...
|
||||||
|
shall we support other as well?
|
||||||
|
|
||||||
|
|
||||||
|
***********************************************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "emu.h"
|
||||||
|
#include "machine/md_sk.h"
|
||||||
|
#include "machine/md_rom.h"
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// md_rom_device - constructor
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
const device_type MD_ROM_SK = &device_creator<md_rom_sk_device>;
|
||||||
|
|
||||||
|
|
||||||
|
md_rom_sk_device::md_rom_sk_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: device_t(mconfig, type, name, tag, owner, clock),
|
||||||
|
device_md_cart_interface( mconfig, *this ),
|
||||||
|
m_exp(*this, "subslot")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
md_rom_sk_device::md_rom_sk_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: device_t(mconfig, MD_ROM_SK, "MD Sonic & Knuckles", tag, owner, clock),
|
||||||
|
device_md_cart_interface( mconfig, *this ),
|
||||||
|
m_exp(*this, "subslot")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void md_rom_sk_device::device_start()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
mapper specific handlers
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
READ16_MEMBER(md_rom_sk_device::read)
|
||||||
|
{
|
||||||
|
if (m_exp->m_cart != NULL && m_exp->m_cart->get_rom_base() != NULL && offset >= 0x200000/2 && offset < (0x200000 + m_exp->m_cart->get_rom_size())/2)
|
||||||
|
return m_exp->m_cart->m_rom[offset - 0x200000/2];
|
||||||
|
return m_rom[offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE16_MEMBER(md_rom_sk_device::write)
|
||||||
|
{
|
||||||
|
// should there be anything here?
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// MACHINE_CONFIG_FRAGMENT( sk_slot )
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
static SLOT_INTERFACE_START(sk_sub_cart)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom", MD_STD_ROM)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_svp", MD_STD_ROM)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_sram", MD_ROM_SRAM)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_sramsafe", MD_ROM_SRAM)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom_fram", MD_ROM_FRAM)
|
||||||
|
// add all types??
|
||||||
|
SLOT_INTERFACE_END
|
||||||
|
|
||||||
|
static MACHINE_CONFIG_FRAGMENT( sk_slot )
|
||||||
|
MCFG_MDSUB_CARTRIDGE_ADD("subslot", sk_sub_cart, NULL, NULL)
|
||||||
|
MACHINE_CONFIG_END
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// machine_config_additions - device-specific
|
||||||
|
// machine configurations
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
machine_config_constructor md_rom_sk_device::device_mconfig_additions() const
|
||||||
|
{
|
||||||
|
return MACHINE_CONFIG_NAME( sk_slot );
|
||||||
|
}
|
||||||
|
|
34
src/mess/machine/md_sk.h
Normal file
34
src/mess/machine/md_sk.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#ifndef __MD_SK_H
|
||||||
|
#define __MD_SK_H
|
||||||
|
|
||||||
|
#include "machine/md_slot.h"
|
||||||
|
|
||||||
|
|
||||||
|
// ======================> md_rom_sk_device
|
||||||
|
|
||||||
|
class md_rom_sk_device : public device_t,
|
||||||
|
public device_md_cart_interface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
md_rom_sk_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
md_rom_sk_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_start();
|
||||||
|
virtual void device_config_complete() { m_shortname = "md_rom_sk"; }
|
||||||
|
virtual machine_config_constructor device_mconfig_additions() const;
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ16_MEMBER(read);
|
||||||
|
virtual DECLARE_WRITE16_MEMBER(write);
|
||||||
|
|
||||||
|
private:
|
||||||
|
required_device<md_subcart_slot_device> m_exp;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// device type definition
|
||||||
|
extern const device_type MD_ROM_SK;
|
||||||
|
|
||||||
|
#endif
|
899
src/mess/machine/md_slot.c
Normal file
899
src/mess/machine/md_slot.c
Normal file
@ -0,0 +1,899 @@
|
|||||||
|
/***********************************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
MegaDrive cart emulation
|
||||||
|
(through slot devices)
|
||||||
|
|
||||||
|
The driver exposes address ranges
|
||||||
|
0x000000-0x7fffff to read/write (typically cart data, possibly banked, and some protection)
|
||||||
|
0x130000-0x1300ff to read_a13/write_a13 (typically SRAM toggling or protection)
|
||||||
|
0x150000-0x1500ff to read_a15/write_a15 (for SVP registers, not converted yet to slots)
|
||||||
|
|
||||||
|
currently available slot devices:
|
||||||
|
md_rom: standard carts + carts with NVRAM (SRAM/FRAM) + pirate carts with protection & bankswitch
|
||||||
|
md_eeprom: carts + I2C EEPROM (EEPROM device hooked up only, support to be completed)
|
||||||
|
md_jcart: Codemasters J-Cart & J-Cart+SEPROM (again, EEPROM device hooked up only, support to be completed)
|
||||||
|
md_sk: Sonic & Knuckles pass-thorugh cart (enables a second slot to mount any other cart)
|
||||||
|
md_stm95: cart + STM95 EEPROM (e.g. Pier Solar)
|
||||||
|
|
||||||
|
TODO: currently read access in 0x000000-0x7fffff are not masked (so we assume that no game attempts to
|
||||||
|
read beyond its ROM size). A regression test is pending to identify which games need this and mirror
|
||||||
|
them properly (Eke's doc states ROM data should be mirrored), but none of the ~120 games I tried
|
||||||
|
attempted that and a testcase would be appreciated
|
||||||
|
|
||||||
|
***********************************************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include "emu.h"
|
||||||
|
#include "machine/md_slot.h"
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// GLOBAL VARIABLES
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
const device_type MD_CART_SLOT = &device_creator<md_cart_slot_device>;
|
||||||
|
const device_type PICO_CART_SLOT = &device_creator<pico_cart_slot_device>;
|
||||||
|
const device_type MD_SUBCART_SLOT = &device_creator<md_subcart_slot_device>;
|
||||||
|
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// MD cartridges Interface
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// device_md_cart_interface - constructor
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
device_md_cart_interface::device_md_cart_interface(const machine_config &mconfig, device_t &device)
|
||||||
|
: device_slot_card_interface(mconfig, device),
|
||||||
|
m_rom(NULL),
|
||||||
|
m_nvram(NULL),
|
||||||
|
m_rom_size(0),
|
||||||
|
m_nvram_size(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// ~device_md_cart_interface - destructor
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
device_md_cart_interface::~device_md_cart_interface()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// rom_alloc - alloc the space for the cart
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void device_md_cart_interface::rom_alloc(running_machine &machine, size_t size)
|
||||||
|
{
|
||||||
|
if (m_rom == NULL)
|
||||||
|
{
|
||||||
|
m_rom = auto_alloc_array_clear(machine, UINT16, size/sizeof(UINT16));
|
||||||
|
m_rom_size = size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// nvram_alloc - alloc the space for the nvram
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void device_md_cart_interface::nvram_alloc(running_machine &machine, size_t size)
|
||||||
|
{
|
||||||
|
if (m_nvram == NULL)
|
||||||
|
{
|
||||||
|
m_nvram = auto_alloc_array_clear(machine, UINT16, size/sizeof(UINT16));
|
||||||
|
m_nvram_size = size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// LIVE DEVICE
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// base_md_cart_slot_device - constructor
|
||||||
|
//-------------------------------------------------
|
||||||
|
base_md_cart_slot_device::base_md_cart_slot_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) :
|
||||||
|
device_t(mconfig, type, name, tag, owner, clock),
|
||||||
|
device_image_interface(mconfig, *this),
|
||||||
|
device_slot_interface(mconfig, *this),
|
||||||
|
m_type(SEGA_STD)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
md_cart_slot_device::md_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
|
||||||
|
base_md_cart_slot_device(mconfig, MD_CART_SLOT, "MD Cartridge Slot", tag, owner, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
md_subcart_slot_device::md_subcart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
|
||||||
|
base_md_cart_slot_device(mconfig, MD_SUBCART_SLOT, "MD Cartridge SubSlot", tag, owner, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
pico_cart_slot_device::pico_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
|
||||||
|
base_md_cart_slot_device(mconfig, PICO_CART_SLOT, "Pico Cartridge Slot", tag, owner, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// base_md_cart_slot_device - destructor
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
base_md_cart_slot_device::~base_md_cart_slot_device()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// device_start - device-specific startup
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void base_md_cart_slot_device::device_start()
|
||||||
|
{
|
||||||
|
m_cart = dynamic_cast<device_md_cart_interface *>(get_card_device());
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// device_config_complete - perform any
|
||||||
|
// operations now that the configuration is
|
||||||
|
// complete
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void base_md_cart_slot_device::device_config_complete()
|
||||||
|
{
|
||||||
|
// set brief and instance name
|
||||||
|
update_names();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// MD PCB
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
struct md_slot
|
||||||
|
{
|
||||||
|
int pcb_id;
|
||||||
|
const char *slot_option;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Here, we take the feature attribute from .xml (i.e. the PCB name) and we assign a unique ID to it
|
||||||
|
static const md_slot slot_list[] =
|
||||||
|
{
|
||||||
|
{ SEGA_SK, "rom_sk" },
|
||||||
|
{ SEGA_STD, "rom_svp"},
|
||||||
|
// { SEGA_SVP, "rom_svp"}, // not ready yet...
|
||||||
|
|
||||||
|
{ SEGA_SRAM, "rom_sram" },
|
||||||
|
{ SEGA_FRAM, "rom_fram" },
|
||||||
|
{ BEGGAR, "rom_beggar"},
|
||||||
|
|
||||||
|
{ SEGA_EEPROM, "rom_eeprom" },
|
||||||
|
{ NBA_JAM, "rom_nbajam" },
|
||||||
|
{ NBA_JAM_TE, "rom_nbajamte" },
|
||||||
|
{ NFL_QB_96, "rom_nflqb" },
|
||||||
|
{ C_SLAM, "rom_cslam" },
|
||||||
|
{ EA_NHLPA, "rom_nhlpa" },
|
||||||
|
{ BRIAN_LARA, "rom_blara" },
|
||||||
|
|
||||||
|
{ CM_JCART, "rom_jcart" },
|
||||||
|
{ CODE_MASTERS, "rom_codemast" },
|
||||||
|
{ CM_MM96, "rom_mm96" },
|
||||||
|
|
||||||
|
{ PSOLAR, "rom_stm95"},
|
||||||
|
|
||||||
|
{ SSF2, "rom_ssf2" },
|
||||||
|
{ RADICA, "rom_radica" },
|
||||||
|
// { GAME_KANDUME, "rom_gkand" }, // what's needed by this?
|
||||||
|
|
||||||
|
{ BUGSLIFE, "rom_bugs" },
|
||||||
|
{ CHINFIGHT3, "rom_chinf3" },
|
||||||
|
{ ELFWOR, "rom_elfwor" },
|
||||||
|
{ KAIJU, "rom_pokestad" },
|
||||||
|
{ KOF98, "rom_kof98" },
|
||||||
|
{ KOF99, "rom_kof99" },
|
||||||
|
{ LIONK2, "rom_lion2" },
|
||||||
|
{ LIONK3, "rom_lion3" },
|
||||||
|
{ MC_PIRATE, "rom_mcpir" },
|
||||||
|
{ MJLOVER, "rom_mjlov" },
|
||||||
|
{ MULAN, "rom_mulan"},
|
||||||
|
{ POKEMON, "rom_poke"},
|
||||||
|
{ POKEMON2, "rom_poke2"},
|
||||||
|
{ REALTEC, "rom_realtec" },
|
||||||
|
{ REDCL_EN, "rom_redcl" },
|
||||||
|
{ REDCLIFF, "rom_redcl" },
|
||||||
|
{ ROCKMANX3, "rom_rx3" },
|
||||||
|
{ SBUBBOB, "rom_sbubl" },
|
||||||
|
{ SMB, "rom_smb" },
|
||||||
|
{ SMB2, "rom_smb2" },
|
||||||
|
{ SMOUSE, "rom_smouse" },
|
||||||
|
{ SOULBLAD, "rom_soulblad" },
|
||||||
|
{ SQUIRRELK, "rom_squir" },
|
||||||
|
{ TOPFIGHTER, "rom_topf" },
|
||||||
|
|
||||||
|
{ SEGA_SRAM_FULLPATH, "rom_sram" },
|
||||||
|
{ SEGA_SRAM_FALLBACK, "rom_sramsafe" }
|
||||||
|
};
|
||||||
|
|
||||||
|
static int md_get_pcb_id(const char *slot)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < ARRAY_LENGTH(slot_list); i++)
|
||||||
|
{
|
||||||
|
if (!mame_stricmp(slot_list[i].slot_option, slot))
|
||||||
|
return slot_list[i].pcb_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SEGA_STD;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *md_get_slot(int type)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < ARRAY_LENGTH(slot_list); i++)
|
||||||
|
{
|
||||||
|
if (slot_list[i].pcb_id == type)
|
||||||
|
return slot_list[i].slot_option;
|
||||||
|
}
|
||||||
|
|
||||||
|
return "rom";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
SRAM handling
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
call load
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
bool base_md_cart_slot_device::call_load()
|
||||||
|
{
|
||||||
|
if (m_cart)
|
||||||
|
{
|
||||||
|
m_type = SEGA_STD;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
// STEP 1: load the file image and keep a copy for later banking
|
||||||
|
// STEP 2: identify the cart type
|
||||||
|
// The two steps are carried out differently if we are loading from a list or not
|
||||||
|
if (software_entry() == NULL)
|
||||||
|
res = load_nonlist();
|
||||||
|
else
|
||||||
|
res = load_list();
|
||||||
|
|
||||||
|
//printf("cart type: %d\n", m_type);
|
||||||
|
|
||||||
|
if (res == IMAGE_INIT_PASS)
|
||||||
|
{
|
||||||
|
// STEP 3: install memory handlers for this type of cart
|
||||||
|
setup_custom_mappers();
|
||||||
|
|
||||||
|
// STEP 4: take care of SRAM.
|
||||||
|
setup_nvram();
|
||||||
|
|
||||||
|
if (m_cart->get_nvram_size())
|
||||||
|
battery_load(m_cart->get_nvram_base(), m_cart->get_nvram_size(), 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return IMAGE_INIT_PASS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int base_md_cart_slot_device::load_list()
|
||||||
|
{
|
||||||
|
UINT16 *ROM;
|
||||||
|
UINT32 length = get_software_region_length("rom");
|
||||||
|
const char *slot_name;
|
||||||
|
|
||||||
|
m_cart->rom_alloc(machine(), length);
|
||||||
|
ROM = m_cart->get_rom_base();
|
||||||
|
memcpy(ROM, get_software_region("rom"), length);
|
||||||
|
|
||||||
|
if ((slot_name = get_feature("slot")) == NULL)
|
||||||
|
m_type = SEGA_STD;
|
||||||
|
else
|
||||||
|
m_type = md_get_pcb_id(slot_name);
|
||||||
|
|
||||||
|
return IMAGE_INIT_PASS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************
|
||||||
|
* Helper function: Detect SMD file
|
||||||
|
*************************************/
|
||||||
|
|
||||||
|
/* code taken directly from GoodGEN by Cowering */
|
||||||
|
static int genesis_is_SMD(unsigned char *buf,unsigned int len)
|
||||||
|
{
|
||||||
|
if (buf[0x2080] == 'S' && buf[0x80] == 'E' && buf[0x2081] == 'G' && buf[0x81] == 'A')
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* aq quiz */
|
||||||
|
if (!strncmp("UZ(-01 ", (const char *) &buf[0xf0], 8))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* Phelios USA redump */
|
||||||
|
/* target earth */
|
||||||
|
/* klax (namcot) */
|
||||||
|
if (buf[0x2080] == ' ' && buf[0x0080] == 'S' && buf[0x2081] == 'E' && buf[0x0081] == 'G')
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* jap baseball 94 */
|
||||||
|
if (!strncmp("OL R-AEAL", (const char *) &buf[0xf0], 9))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* devilish Mahjong Tower */
|
||||||
|
if (!strncmp("optrEtranet", (const char *) &buf[0xf3], 11))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* golden axe 2 beta */
|
||||||
|
if (buf[0x0100] == 0x3c && buf[0x0101] == 0 && buf[0x0102] == 0 && buf[0x0103] == 0x3c)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* omega race */
|
||||||
|
if (!strncmp("OEARC ", (const char *) &buf[0x90], 8))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* budokan beta */
|
||||||
|
if ((len >= 0x6708 + 8) && !strncmp(" NTEBDKN", (const char *) &buf[0x6708], 8))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* cdx pro 1.8 bios */
|
||||||
|
if (!strncmp("so fCXP", (const char *) &buf[0x2c0], 7))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* ishido (hacked) */
|
||||||
|
if (!strncmp("sio-Wyo ", (const char *) &buf[0x0090], 8))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* onslaught */
|
||||||
|
if (!strncmp("SS CAL ", (const char *) &buf[0x0088], 8))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* tram terror pirate */
|
||||||
|
if ((len >= 0x3648 + 8) && !strncmp("SG NEPIE", (const char *) &buf[0x3648], 8))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* breath of fire 3 chinese */
|
||||||
|
if (buf[0x0007] == 0x1c && buf[0x0008] == 0x0a && buf[0x0009] == 0xb8 && buf[0x000a] == 0x0a)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/*tetris pirate */
|
||||||
|
if ((len >= 0x1cbe + 5) && !strncmp("@TTI>", (const char *) &buf[0x1cbe], 5))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************
|
||||||
|
* Loading a cart image *not* from
|
||||||
|
* softlist
|
||||||
|
*************************************/
|
||||||
|
|
||||||
|
int base_md_cart_slot_device::load_nonlist()
|
||||||
|
{
|
||||||
|
unsigned char *ROM, *tmpROM;
|
||||||
|
UINT32 len = length();
|
||||||
|
|
||||||
|
// this contains an hack for SSF2: its current bankswitch code needs larger rom space to work
|
||||||
|
m_cart->rom_alloc(machine(), (len == 0x500000) ? 0x900000 : len);
|
||||||
|
|
||||||
|
ROM = (unsigned char *)m_cart->get_rom_base();
|
||||||
|
tmpROM = global_alloc_array(unsigned char, len);
|
||||||
|
|
||||||
|
// STEP 1: determine the file type (SMD? MD? BIN?)
|
||||||
|
fread(tmpROM, len);
|
||||||
|
|
||||||
|
/* is this a SMD file? */
|
||||||
|
if (genesis_is_SMD(&tmpROM[0x200], len))
|
||||||
|
{
|
||||||
|
mame_printf_debug("SMD!\n");
|
||||||
|
|
||||||
|
for (int ptr = 0; ptr < (len - 0x200) / 0x2000; ptr += 2)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < 0x2000; x++)
|
||||||
|
{
|
||||||
|
*ROM++ = *(tmpROM + 0x200 + ((ptr + 1) * 0x2000) + x);
|
||||||
|
*ROM++ = *(tmpROM + 0x200 + ((ptr + 0) * 0x2000) + x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
len -= 0x200;
|
||||||
|
}
|
||||||
|
/* is this a MD file? */
|
||||||
|
else if ((tmpROM[0x80] == 'E') && (tmpROM[0x81] == 'A') && (tmpROM[0x82] == 'M' || tmpROM[0x82] == 'G'))
|
||||||
|
{
|
||||||
|
mame_printf_debug("MD!\n");
|
||||||
|
|
||||||
|
for (int ptr = 0; ptr < len; ptr += 2)
|
||||||
|
{
|
||||||
|
ROM[ptr] = tmpROM[(len >> 1) + (ptr >> 1)];
|
||||||
|
ROM[ptr + 1] = tmpROM[(ptr >> 1)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* BIN it is, then */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fseek(0, SEEK_SET);
|
||||||
|
fread(ROM, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
global_free(tmpROM);
|
||||||
|
|
||||||
|
// STEP 2: determine the cart type (to deal with pirate mappers & eeprom)
|
||||||
|
m_type = get_cart_type(ROM, len);
|
||||||
|
|
||||||
|
#ifdef LSB_FIRST
|
||||||
|
unsigned char fliptemp;
|
||||||
|
// is this really needed nowadays?
|
||||||
|
for (int ptr = 0; ptr < len; ptr += 2)
|
||||||
|
{
|
||||||
|
fliptemp = ROM[ptr];
|
||||||
|
ROM[ptr] = ROM[ptr+1];
|
||||||
|
ROM[ptr+1] = fliptemp;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return IMAGE_INIT_PASS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
call_unloadload
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
void base_md_cart_slot_device::call_unload()
|
||||||
|
{
|
||||||
|
if (m_cart->get_nvram_size())
|
||||||
|
battery_save(m_cart->get_nvram_base(), m_cart->get_nvram_size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void base_md_cart_slot_device::setup_custom_mappers()
|
||||||
|
{
|
||||||
|
UINT16 *ROM16 = m_cart->get_rom_base();
|
||||||
|
|
||||||
|
switch (m_type)
|
||||||
|
{
|
||||||
|
case SSF2:
|
||||||
|
// copy the image in 0x400000-0x900000 and keep the beginning for bankswitch
|
||||||
|
for (int x = 0x500000/2; x > 0; x--)
|
||||||
|
ROM16[x + 0x400000/2 - 1] = ROM16[x - 1];
|
||||||
|
for (int x = 0; x < 0x400000/2; x++)
|
||||||
|
ROM16[x] = ROM16[x + 0x400000/2];
|
||||||
|
break;
|
||||||
|
case REDCL_EN:
|
||||||
|
// decrypt
|
||||||
|
for (int x = 0; x < 0x200000/2; x++)
|
||||||
|
ROM16[x] = ROM16[x + 2] ^ 0x4040;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// patch out protection in a bunch of titles...
|
||||||
|
case POKEMON:
|
||||||
|
/*todo: emulate protection instead
|
||||||
|
0dd19e:47f8
|
||||||
|
0dd1a0:fff0
|
||||||
|
0dd1a2:4e63
|
||||||
|
0dd46e:4ef8
|
||||||
|
0dd470:0300
|
||||||
|
0dd49c:6002
|
||||||
|
*/
|
||||||
|
/* you need to return 1 @ 0xa13002 and 0???1f @ 0xa1303e (it does word reads). */
|
||||||
|
ROM16[0x0dd19e/2] = 0x47f8;
|
||||||
|
ROM16[0x0dd1a0/2] = 0xfff0;
|
||||||
|
ROM16[0x0dd1a2/2] = 0x4e63;
|
||||||
|
ROM16[0x0dd46e/2] = 0x4ef8;
|
||||||
|
ROM16[0x0dd470/2] = 0x0300;
|
||||||
|
ROM16[0x0dd49c/2] = 0x6002;
|
||||||
|
break;
|
||||||
|
case POKEMON2:
|
||||||
|
/*todo: emulate protection instead
|
||||||
|
006036:e000
|
||||||
|
002540:6026
|
||||||
|
001ed0:6026
|
||||||
|
002476:6022
|
||||||
|
*/
|
||||||
|
ROM16[0x06036/2] = 0xe000;
|
||||||
|
ROM16[0x02540/2] = 0x6026;
|
||||||
|
ROM16[0x01ed0/2] = 0x6026;
|
||||||
|
ROM16[0x02476/2] = 0x6022;
|
||||||
|
ROM16[0x7e300/2] = 0x60fe;
|
||||||
|
break;
|
||||||
|
case MULAN:
|
||||||
|
/*todo: emulate protection instead
|
||||||
|
006036:e000
|
||||||
|
+more?
|
||||||
|
*/
|
||||||
|
// ROM16[0x01ed0/2] = 0xe000;
|
||||||
|
// ROM16[0x02540/2] = 0xe000;
|
||||||
|
ROM16[0x06036/2] = 0xe000;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void base_md_cart_slot_device::setup_nvram()
|
||||||
|
{
|
||||||
|
UINT8 *ROM = (UINT8 *)m_cart->get_rom_base();
|
||||||
|
m_cart->m_nvram_readonly = 0;
|
||||||
|
m_cart->m_nvram_active = 0;
|
||||||
|
m_cart->m_nvram_handlers_installed = 0;
|
||||||
|
|
||||||
|
/* install SRAM & i2c handlers for the specific type of cart */
|
||||||
|
switch (m_type)
|
||||||
|
{
|
||||||
|
// These types only come from fullpath loading
|
||||||
|
case SEGA_SRAM_FULLPATH:
|
||||||
|
m_cart->m_nvram_start = (ROM[0x1b5] << 24 | ROM[0x1b4] << 16 | ROM[0x1b7] << 8 | ROM[0x1b6]);
|
||||||
|
m_cart->m_nvram_end = (ROM[0x1b9] << 24 | ROM[0x1b8] << 16 | ROM[0x1bb] << 8 | ROM[0x1ba]);
|
||||||
|
logerror("SRAM detected from header: starting location %X - SRAM Length %X\n", m_cart->m_nvram_start, m_cart->m_nvram_end - m_cart->m_nvram_start + 1);
|
||||||
|
|
||||||
|
// We assume at most 64k of SRAM. is this correct?
|
||||||
|
if ((m_cart->m_nvram_start > m_cart->m_nvram_end) || ((m_cart->m_nvram_end - m_cart->m_nvram_start) >= 0x10000))
|
||||||
|
m_cart->m_nvram_end = m_cart->m_nvram_start + 0xffff;
|
||||||
|
|
||||||
|
if (m_cart->m_nvram_start & 1)
|
||||||
|
m_cart->m_nvram_start -= 1;
|
||||||
|
|
||||||
|
if (!(m_cart->m_nvram_end & 1))
|
||||||
|
m_cart->m_nvram_end += 1;
|
||||||
|
|
||||||
|
m_cart->nvram_alloc(machine(), m_cart->m_nvram_end - m_cart->m_nvram_start + 1);
|
||||||
|
if (m_cart->m_rom_size <= m_cart->m_nvram_start)
|
||||||
|
m_cart->m_nvram_active = 1;
|
||||||
|
m_cart->m_nvram_handlers_installed = 1;
|
||||||
|
// don't trust too much header?
|
||||||
|
m_cart->m_nvram_start &= 0x3fffff;
|
||||||
|
m_cart->m_nvram_end &= 0x3fffff;
|
||||||
|
break;
|
||||||
|
case SEGA_SRAM_FALLBACK:
|
||||||
|
m_cart->m_nvram_start = 0x200000;
|
||||||
|
m_cart->m_nvram_end = m_cart->m_nvram_start + 0xffff;
|
||||||
|
m_cart->nvram_alloc(machine(), m_cart->m_nvram_end - m_cart->m_nvram_start + 1);
|
||||||
|
if (m_cart->m_rom_size <= m_cart->m_nvram_start)
|
||||||
|
m_cart->m_nvram_active = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// These types only come from softlist loading
|
||||||
|
case SEGA_SRAM:
|
||||||
|
m_cart->m_nvram_start = 0x200000;
|
||||||
|
m_cart->m_nvram_end = m_cart->m_nvram_start + get_software_region_length("sram") - 1;
|
||||||
|
m_cart->nvram_alloc(machine(), m_cart->m_nvram_end - m_cart->m_nvram_start + 1);
|
||||||
|
if (m_cart->m_rom_size <= m_cart->m_nvram_start)
|
||||||
|
m_cart->m_nvram_active = 1;
|
||||||
|
m_cart->m_nvram_handlers_installed = 1;
|
||||||
|
break;
|
||||||
|
case SEGA_FRAM:
|
||||||
|
m_cart->m_nvram_start = 0x200000;
|
||||||
|
m_cart->m_nvram_end = m_cart->m_nvram_start + get_software_region_length("fram") - 1;
|
||||||
|
m_cart->nvram_alloc(machine(), m_cart->m_nvram_end - m_cart->m_nvram_start + 1);
|
||||||
|
m_cart->m_nvram_active = 1;
|
||||||
|
m_cart->m_nvram_handlers_installed = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// These types might come from both (pending proper id routines)
|
||||||
|
case BEGGAR:
|
||||||
|
m_cart->m_nvram_start = 0x400000;
|
||||||
|
m_cart->m_nvram_end = m_cart->m_nvram_start + 0xffff;
|
||||||
|
m_cart->nvram_alloc(machine(), m_cart->m_nvram_end - m_cart->m_nvram_start + 1);
|
||||||
|
m_cart->m_nvram_active = 1;
|
||||||
|
m_cart->m_nvram_handlers_installed = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
call softlist load
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
bool base_md_cart_slot_device::call_softlist_load(char *swlist, char *swname, rom_entry *start_entry)
|
||||||
|
{
|
||||||
|
load_software_part_region(this, swlist, swname, start_entry );
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int base_md_cart_slot_device::get_cart_type(UINT8 *ROM, UINT32 len)
|
||||||
|
{
|
||||||
|
int type = SEGA_STD;
|
||||||
|
|
||||||
|
/* Detect carts which need additional handlers */
|
||||||
|
static const unsigned char smouse_sig[] = { 0x4d, 0xf9, 0x00, 0x40, 0x00, 0x02 },
|
||||||
|
mjlover_sig[] = { 0x13, 0xf9, 0x00, 0x40, 0x00, 0x00 }, // move.b ($400000).l,($FFFF0C).l (partial)
|
||||||
|
squir_sig[] = { 0x26, 0x79, 0x00, 0xff, 0x00, 0xfa },
|
||||||
|
bugsl_sig[] = { 0x20, 0x12, 0x13, 0xc0, 0x00, 0xff },
|
||||||
|
sbub_sig[] = { 0x0c, 0x39, 0x00, 0x55, 0x00, 0x40 }, // cmpi.b #$55,($400000).l
|
||||||
|
lk3_sig[] = { 0x0c, 0x01, 0x00, 0x30, 0x66, 0xe4 },
|
||||||
|
sdk_sig[] = { 0x48, 0xe7, 0xff, 0xfe, 0x52, 0x79 },
|
||||||
|
redcliff_sig[] = { 0x10, 0x39, 0x00, 0x40, 0x00, 0x04 }, // move.b ($400004).l,d0
|
||||||
|
redcl_en_sig[] = { 0x50, 0x79, 0x40, 0x00, 0x40, 0x44 }, // move.b ($400004).l,d0
|
||||||
|
smb_sig[] = { 0x20, 0x4d, 0x41, 0x52, 0x49, 0x4f },
|
||||||
|
smb2_sig[] = { 0x4e, 0xb9, 0x00, 0x0f, 0x25, 0x84 },
|
||||||
|
kaiju_sig[] = { 0x19, 0x7c, 0x00, 0x01, 0x00, 0x00 },
|
||||||
|
chifi3_sig[] = { 0xb6, 0x16, 0x66, 0x00, 0x00, 0x4a },
|
||||||
|
lionk2_sig[] = { 0x26, 0x79, 0x00, 0xff, 0x00, 0xf4 },
|
||||||
|
rx3_sig[] = { 0x66, 0x00, 0x00, 0x0e, 0x30, 0x3c },
|
||||||
|
kof98_sig[] = { 0x9b, 0xfc, 0x00, 0x00, 0x4a, 0x00 },
|
||||||
|
s15in1_sig[] = { 0x22, 0x3c, 0x00, 0xa1, 0x30, 0x00 },
|
||||||
|
kof99_sig[] = { 0x20, 0x3c, 0x30, 0x00, 0x00, 0xa1 }, // move.l #$300000A1,d0
|
||||||
|
radica_sig[] = { 0x4e, 0xd0, 0x30, 0x39, 0x00, 0xa1 }, // jmp (a0) move.w ($a130xx),d0
|
||||||
|
soulb_sig[] = { 0x33, 0xfc, 0x00, 0x0c, 0x00, 0xff }, // move.w #$C,($FF020A).l (what happens if check fails)
|
||||||
|
s19in1_sig[] = { 0x13, 0xc0, 0x00, 0xa1, 0x30, 0x38 },
|
||||||
|
rockman_sig[] = { 0xea, 0x80 };
|
||||||
|
|
||||||
|
switch (len)
|
||||||
|
{
|
||||||
|
case 0x80000:
|
||||||
|
if (!memcmp(&ROM[0x08c8], smouse_sig, sizeof(smouse_sig)))
|
||||||
|
type = SMOUSE;
|
||||||
|
|
||||||
|
if (!memcmp((char *)&ROM[0x7e30e], "SEGA", 4) ||
|
||||||
|
!memcmp((char *)&ROM[0x7e100], "SEGA", 4) ||
|
||||||
|
!memcmp((char *)&ROM[0x7e1e6], "SEGA", 4))
|
||||||
|
type = REALTEC;
|
||||||
|
|
||||||
|
if (!memcmp((char *)&ROM[0x0180], "GM T-50396", 10)) // NHLPA Hockey 93
|
||||||
|
type = EA_NHLPA;
|
||||||
|
|
||||||
|
if (!memcmp((char *)&ROM[0x0180], "GM MK-1215", 10)) // Evander Holyfield
|
||||||
|
type = SEGA_EEPROM;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xc0000:
|
||||||
|
|
||||||
|
if (!memcmp((char *)&ROM[0x0180], "GM G-4060 ", 8)) // Wonder Boy V
|
||||||
|
type = SEGA_EEPROM;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x100000:
|
||||||
|
if (!memcmp(&ROM[0x01b24], mjlover_sig, sizeof(mjlover_sig)))
|
||||||
|
type = MJLOVER;
|
||||||
|
|
||||||
|
if (!memcmp(&ROM[0x03b4], squir_sig, sizeof(squir_sig)))
|
||||||
|
type = SQUIRRELK;
|
||||||
|
|
||||||
|
if (!memcmp(&ROM[0xee0d0], bugsl_sig, sizeof(bugsl_sig)))
|
||||||
|
type = BUGSLIFE;
|
||||||
|
|
||||||
|
if (!memcmp((char *)&ROM[0x0172], "GAME : ELF WOR", 14))
|
||||||
|
type = ELFWOR;
|
||||||
|
|
||||||
|
if (!memcmp(&ROM[0x123e4], sbub_sig, sizeof(sbub_sig)))
|
||||||
|
type = SBUBBOB;
|
||||||
|
|
||||||
|
if (!memcmp((char *)&ROM[0x0180], "GM T-50176", 10)) // Rings of Power
|
||||||
|
type = EA_NHLPA;
|
||||||
|
|
||||||
|
if (!memcmp((char *)&ROM[0x0180], "MK 00001211-00", 14)) // Sports Talk Baseball
|
||||||
|
type = SEGA_EEPROM;
|
||||||
|
|
||||||
|
if (!memcmp((char *)&ROM[0x0180], "GM T-120096-", 12)) // Micro Machines 2
|
||||||
|
type = CODE_MASTERS;
|
||||||
|
|
||||||
|
if (!memcmp((char *)&ROM[0x0180], "GM T-120146-", 12)) // Brian Lara Cricket 96 / Shane Wayne Cricket 96
|
||||||
|
type = BRIAN_LARA;
|
||||||
|
|
||||||
|
if (!memcmp((char *)&ROM[0x0190], "OJKRPTBVFCA ", 0x10)) // Micro Machines '96 / Military TODO: better way to recognize these?
|
||||||
|
type = CODE_MASTERS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x200000:
|
||||||
|
if (!memcmp(&ROM[0x18c6], lk3_sig, sizeof(lk3_sig)))
|
||||||
|
type = LIONK3;
|
||||||
|
|
||||||
|
if (!memcmp(&ROM[0x220], sdk_sig, sizeof(sdk_sig)))
|
||||||
|
type = LIONK3;
|
||||||
|
|
||||||
|
if (!memcmp(&ROM[0xce560], redcliff_sig, sizeof(redcliff_sig)))
|
||||||
|
type = REDCLIFF;
|
||||||
|
|
||||||
|
if (!memcmp(&ROM[0xc8cb0], smb_sig, sizeof(smb_sig)))
|
||||||
|
type = SMB;
|
||||||
|
|
||||||
|
if (!memcmp(&ROM[0xf24d6], smb2_sig, sizeof(smb2_sig)))
|
||||||
|
type = SMB2;
|
||||||
|
|
||||||
|
if (!memcmp(&ROM[0x674e], kaiju_sig, sizeof(kaiju_sig)))
|
||||||
|
type = KAIJU;
|
||||||
|
|
||||||
|
if (!memcmp(&ROM[0x1780], chifi3_sig, sizeof(chifi3_sig)))
|
||||||
|
type = CHINFIGHT3;
|
||||||
|
|
||||||
|
if (!memcmp(&ROM[0x03c2], lionk2_sig, sizeof(lionk2_sig)))
|
||||||
|
type = LIONK2;
|
||||||
|
|
||||||
|
if (!memcmp(&ROM[0xc8b90], rx3_sig, sizeof(rx3_sig)))
|
||||||
|
type = ROCKMANX3;
|
||||||
|
|
||||||
|
if (!memcmp(&ROM[0x56ae2], kof98_sig, sizeof(kof98_sig)))
|
||||||
|
type = KOF98;
|
||||||
|
|
||||||
|
if (!memcmp(&ROM[0x17bb2], s15in1_sig, sizeof(s15in1_sig)))
|
||||||
|
type = MC_PIRATE;
|
||||||
|
|
||||||
|
if (!memcmp((char *)&ROM[0x0180], "GM T-081326 ", 12)) // NBA Jam
|
||||||
|
type = NBA_JAM;
|
||||||
|
|
||||||
|
if (!memcmp((char *)&ROM[0x0180], "GM MK-1228", 10)) // Greatest Heavyweight of the Ring
|
||||||
|
type = SEGA_EEPROM;
|
||||||
|
|
||||||
|
if ((!memcmp((char *)&ROM[0x0180], "GM T-12046", 10)) || // Mega Man
|
||||||
|
(!memcmp((char *)&ROM[0x0180], "GM T-12053", 10) && !memcmp(&ROM[0x18e], rockman_sig, sizeof(rockman_sig)))) // / Rock Man (EEPROM version)
|
||||||
|
type = SEGA_EEPROM;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x200005:
|
||||||
|
if (!memcmp(&ROM[0xce564], redcl_en_sig, sizeof(redcliff_sig)))
|
||||||
|
type = REDCL_EN;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x300000:
|
||||||
|
if (!memcmp(&ROM[0x220], sdk_sig, sizeof(sdk_sig)))
|
||||||
|
type = LIONK3;
|
||||||
|
|
||||||
|
if (!memcmp(&ROM[0x1fd0d2], kof99_sig, sizeof(kof99_sig)))
|
||||||
|
type = KOF99;
|
||||||
|
|
||||||
|
if (!memcmp((char *)&ROM[0x0180], "GM T-81406", 10)) // NBA Jam TE
|
||||||
|
type = NBA_JAM_TE;
|
||||||
|
|
||||||
|
if (!memcmp((char *)&ROM[0x0180], "GM T-081276 ", 12)) // NFL Quarterback Club
|
||||||
|
type = NBA_JAM_TE;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x400000:
|
||||||
|
if (!memcmp(&ROM[0x3c031c], radica_sig, sizeof(radica_sig)) ||
|
||||||
|
!memcmp(&ROM[0x3f031c], radica_sig, sizeof(radica_sig))) // ssf+gng + radica vol1
|
||||||
|
type = RADICA;
|
||||||
|
|
||||||
|
if (!memcmp(&ROM[0x028460], soulb_sig, sizeof(soulb_sig)))
|
||||||
|
type = SOULBLAD;
|
||||||
|
|
||||||
|
if (!memcmp(&ROM[0x1e700], s19in1_sig, sizeof(s19in1_sig)))
|
||||||
|
type = MC_PIRATE;
|
||||||
|
|
||||||
|
if (!memcmp((char *)&ROM[0x0180], "GM T-081586-", 12)) // NFL Quarterback Club 96
|
||||||
|
type = NFL_QB_96;
|
||||||
|
|
||||||
|
if (!memcmp((char *)&ROM[0x0180], "GM T-081576 ", 12)) // College Slam
|
||||||
|
type = C_SLAM;
|
||||||
|
|
||||||
|
if (!memcmp((char *)&ROM[0x0180], "GM T-81476", 10)) // Big Hurt Baseball
|
||||||
|
type = C_SLAM;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x500000:
|
||||||
|
if (!memcmp((char *)&ROM[0x0120], "SUPER STREET FIGHTER2 ", 22))
|
||||||
|
type = SSF2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x800000:
|
||||||
|
if (!memcmp((char *)&ROM[0x0180], "GM T-574023-", 12)) // Pier Solar
|
||||||
|
type = PSOLAR;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//check for SRAM among the general carts
|
||||||
|
if (type == SEGA_STD)
|
||||||
|
{
|
||||||
|
// If the cart is not of a special type, we check the header for SRAM.
|
||||||
|
if (ROM[0x1b1] == 'R' && ROM[0x1b0] == 'A')
|
||||||
|
{
|
||||||
|
UINT32 start, end;
|
||||||
|
start = (ROM[0x1b5] << 24 | ROM[0x1b4] << 16 | ROM[0x1b7] << 8 | ROM[0x1b6]);
|
||||||
|
end = (ROM[0x1b9] << 24 | ROM[0x1b8] << 16 | ROM[0x1bb] << 8 | ROM[0x1ba]);
|
||||||
|
logerror("SRAM detected from header: starting location %X - SRAM Length %X\n", start, end - start + 1);
|
||||||
|
|
||||||
|
// For some games using serial EEPROM, difference between SRAM end to start is 0 or 1.
|
||||||
|
// Carts with EEPROM should have been already detected above, but better safe than sorry
|
||||||
|
if (end - start < 2)
|
||||||
|
type = SEGA_EEPROM;
|
||||||
|
else
|
||||||
|
type = SEGA_SRAM_FULLPATH;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Unfortunately, there are ROMs without correct info in the header,
|
||||||
|
// Hence, when loading from fullpath we do the SRAM mapping anyway...
|
||||||
|
// but treat it in a custom way
|
||||||
|
type = SEGA_SRAM_FALLBACK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
/*-------------------------------------------------
|
||||||
|
get default card software
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
const char * base_md_cart_slot_device::get_default_card_software(const machine_config &config, emu_options &options)
|
||||||
|
{
|
||||||
|
const char *slot_string = "rom";
|
||||||
|
|
||||||
|
if (open_image_file(options))
|
||||||
|
{
|
||||||
|
UINT32 len = core_fsize(m_file);
|
||||||
|
UINT8 *ROM = global_alloc_array(UINT8, len);
|
||||||
|
int type;
|
||||||
|
|
||||||
|
core_fread(m_file, ROM, len);
|
||||||
|
|
||||||
|
type = get_cart_type(ROM, len);
|
||||||
|
slot_string = md_get_slot(type);
|
||||||
|
|
||||||
|
global_free(ROM);
|
||||||
|
clear();
|
||||||
|
|
||||||
|
return slot_string;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return software_get_default_slot(config, options, this, "rom");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
read
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
READ16_MEMBER(base_md_cart_slot_device::read)
|
||||||
|
{
|
||||||
|
if (m_cart)
|
||||||
|
return m_cart->read(space, offset);
|
||||||
|
else
|
||||||
|
return 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
READ16_MEMBER(base_md_cart_slot_device::read_a13)
|
||||||
|
{
|
||||||
|
if (m_cart)
|
||||||
|
return m_cart->read_a13(space, offset);
|
||||||
|
else
|
||||||
|
return 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
READ16_MEMBER(base_md_cart_slot_device::read_a15)
|
||||||
|
{
|
||||||
|
if (m_cart)
|
||||||
|
return m_cart->read_a15(space, offset);
|
||||||
|
else
|
||||||
|
return 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
write
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
WRITE16_MEMBER(base_md_cart_slot_device::write)
|
||||||
|
{
|
||||||
|
if (m_cart)
|
||||||
|
m_cart->write(space, offset, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE16_MEMBER(base_md_cart_slot_device::write_a13)
|
||||||
|
{
|
||||||
|
if (m_cart)
|
||||||
|
m_cart->write_a13(space, offset, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE16_MEMBER(base_md_cart_slot_device::write_a15)
|
||||||
|
{
|
||||||
|
if (m_cart)
|
||||||
|
m_cart->write_a15(space, offset, data);
|
||||||
|
}
|
||||||
|
|
242
src/mess/machine/md_slot.h
Normal file
242
src/mess/machine/md_slot.h
Normal file
@ -0,0 +1,242 @@
|
|||||||
|
#ifndef __MD_SLOT_H
|
||||||
|
#define __MD_SLOT_H
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
TYPE DEFINITIONS
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/* PCB */
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
SEGA_STD = 0,
|
||||||
|
|
||||||
|
// Cart + Slot Expansion
|
||||||
|
SEGA_SK, /* Sonic & Knuckles pass-through cart */
|
||||||
|
|
||||||
|
// Cart + SVP
|
||||||
|
SEGA_SVP, /* Virtua Racing */
|
||||||
|
|
||||||
|
// Cart + NVRAM
|
||||||
|
SEGA_SRAM, SEGA_FRAM,
|
||||||
|
BEGGAR, /* Xin Qigai Wangzi uses different sram start address and has no valid header */
|
||||||
|
|
||||||
|
// EEPROM
|
||||||
|
SEGA_EEPROM, /* Wonder Boy V / Evander Holyfield's Boxing / Greatest Heavyweights of the Ring / Sports Talk Baseball / Megaman */
|
||||||
|
NBA_JAM, /* NBA Jam */
|
||||||
|
NBA_JAM_TE, /* NBA Jam TE / NFL Quarterback Club */
|
||||||
|
NFL_QB_96, /* NFL Quarterback Club '96 */
|
||||||
|
C_SLAM, /* College Slam / Frank Thomas Big Hurt Baseball */
|
||||||
|
EA_NHLPA, /* NHLPA Hockey 93 / Rings of Power */
|
||||||
|
BRIAN_LARA, /* Brian Lara Cricket 96 */
|
||||||
|
PSOLAR, /* Pier Solar (STM95 EEPROM) */
|
||||||
|
|
||||||
|
// J-Cart
|
||||||
|
CM_JCART, /* Pete Sampras Tennis */
|
||||||
|
CODE_MASTERS, /* Micro Machines 2 / Military (J-Cart + SEPROM) */
|
||||||
|
CM_MM96, /* Micro Machines 96 (J-Cart + SEPROM, diff I2C model) */
|
||||||
|
|
||||||
|
// Various
|
||||||
|
SSF2, /* Super Street Fighter 2 */
|
||||||
|
GAME_KANDUME, /* Game no Kandume Otokuyou */
|
||||||
|
RADICA, /* Radica TV games.. these probably should be a separate driver since they are a separate 'console' */
|
||||||
|
|
||||||
|
BUGSLIFE, /* A Bug's Life */
|
||||||
|
CHINFIGHT3, /* Chinese Fighters 3 */
|
||||||
|
ELFWOR, /* Linghuan Daoshi Super Magician */
|
||||||
|
KAIJU, /* Pokemon Stadium */
|
||||||
|
KOF98, /* King of Fighters '98 */
|
||||||
|
KOF99, /* King of Fighters '99 */
|
||||||
|
LIONK2, /* Lion King 2 */
|
||||||
|
LIONK3, /* Lion King 3, Super Donkey Kong 99, Super King Kong 99 */
|
||||||
|
MC_PIRATE, /* Super 19 in 1, Super 15 in 1, 12 in 1 and a few more multicarts */
|
||||||
|
MJLOVER, /* Mahjong Lover */
|
||||||
|
MULAN, /* Hua Mu Lan - Mulan */
|
||||||
|
POKEMON, /* Pocket Monster */
|
||||||
|
POKEMON2, /* Pocket Monster 2 */
|
||||||
|
REALTEC, /* Whac a Critter/Mallet legend, Defend the Earth, Funnyworld/Ballonboy */
|
||||||
|
REDCLIFF, /* Romance of the Three Kingdoms - Battle of Red Cliffs, already decoded from .mdx format */
|
||||||
|
REDCL_EN, /* The encoded version... */
|
||||||
|
ROCKMANX3, /* Rockman X3 */
|
||||||
|
SBUBBOB, /* Super Bubble Bobble */
|
||||||
|
SMB, /* Super Mario Bros. */
|
||||||
|
SMB2, /* Super Mario Bros. 2 */
|
||||||
|
SMOUSE, /* Smart Mouse */
|
||||||
|
SOULBLAD, /* Soul Blade */
|
||||||
|
SQUIRRELK, /* Squirrel King */
|
||||||
|
TOPFIGHTER, /* Top Fighter 2000 MK VIII */
|
||||||
|
|
||||||
|
// when loading from fullpath, we need to treat SRAM in custom way
|
||||||
|
SEGA_SRAM_FULLPATH,
|
||||||
|
SEGA_SRAM_FALLBACK
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ======================> md_cart_interface
|
||||||
|
|
||||||
|
struct md_cart_interface
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ======================> device_md_cart_interface
|
||||||
|
|
||||||
|
class device_md_cart_interface : public device_slot_card_interface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
device_md_cart_interface(const machine_config &mconfig, device_t &device);
|
||||||
|
virtual ~device_md_cart_interface();
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ16_MEMBER(read) { return 0xffff; }
|
||||||
|
virtual DECLARE_WRITE16_MEMBER(write) {}
|
||||||
|
virtual DECLARE_READ16_MEMBER(read_a13) { return 0xffff; };
|
||||||
|
virtual DECLARE_WRITE16_MEMBER(write_a13) {};
|
||||||
|
virtual DECLARE_READ16_MEMBER(read_a15) { return 0xffff; };
|
||||||
|
virtual DECLARE_WRITE16_MEMBER(write_a15) {};
|
||||||
|
|
||||||
|
/* this probably should do more, like make Genesis V2 'die' if the SEGA string is not written promptly */
|
||||||
|
virtual DECLARE_WRITE16_MEMBER(write_tmss_bank) { logerror("Write to TMSS bank: offset %x data %x\n", 0xa14000 + (offset << 1), data); };
|
||||||
|
|
||||||
|
virtual void rom_alloc(running_machine &machine, size_t size);
|
||||||
|
virtual void nvram_alloc(running_machine &machine, size_t size);
|
||||||
|
virtual UINT16* get_rom_base() { return m_rom; };
|
||||||
|
virtual UINT16* get_nvram_base() { return m_nvram; };
|
||||||
|
virtual UINT32 get_rom_size() { return m_rom_size; };
|
||||||
|
virtual UINT32 get_nvram_size() { return m_nvram_size; };
|
||||||
|
|
||||||
|
int m_nvram_start, m_nvram_end;
|
||||||
|
int m_nvram_active, m_nvram_readonly;
|
||||||
|
|
||||||
|
// when loading from fullpath, we create NVRAM even if not set in the header
|
||||||
|
// however in this case we access it only if the game turn it on
|
||||||
|
// the variable below is basically needed to track this...
|
||||||
|
int m_nvram_handlers_installed;
|
||||||
|
|
||||||
|
// internal state
|
||||||
|
UINT16 *m_rom;
|
||||||
|
UINT16 *m_nvram;
|
||||||
|
UINT32 m_rom_size;
|
||||||
|
UINT32 m_nvram_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ======================> base_md_cart_slot_device
|
||||||
|
|
||||||
|
class base_md_cart_slot_device : public device_t,
|
||||||
|
public md_cart_interface,
|
||||||
|
public device_image_interface,
|
||||||
|
public device_slot_interface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
base_md_cart_slot_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
virtual ~base_md_cart_slot_device();
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_start();
|
||||||
|
virtual void device_config_complete();
|
||||||
|
|
||||||
|
// image-level overrides
|
||||||
|
virtual bool call_load();
|
||||||
|
virtual void call_unload();
|
||||||
|
virtual bool call_softlist_load(char *swlist, char *swname, rom_entry *start_entry);
|
||||||
|
|
||||||
|
virtual int load_list();
|
||||||
|
virtual int load_nonlist();
|
||||||
|
virtual int get_cart_type(UINT8 *ROM, UINT32 len);
|
||||||
|
|
||||||
|
|
||||||
|
virtual void setup_custom_mappers();
|
||||||
|
virtual void setup_nvram();
|
||||||
|
|
||||||
|
virtual iodevice_t image_type() const { return IO_CARTSLOT; }
|
||||||
|
virtual bool is_readable() const { return 1; }
|
||||||
|
virtual bool is_writeable() const { return 0; }
|
||||||
|
virtual bool is_creatable() const { return 0; }
|
||||||
|
virtual bool must_be_loaded() const { return 1; }
|
||||||
|
virtual bool is_reset_on_load() const { return 0; }
|
||||||
|
virtual const option_guide *create_option_guide() const { return NULL; }
|
||||||
|
|
||||||
|
// slot interface overrides
|
||||||
|
virtual const char * get_default_card_software(const machine_config &config, emu_options &options);
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ16_MEMBER(read);
|
||||||
|
virtual DECLARE_WRITE16_MEMBER(write);
|
||||||
|
virtual DECLARE_READ16_MEMBER(read_a13);
|
||||||
|
virtual DECLARE_WRITE16_MEMBER(write_a13);
|
||||||
|
virtual DECLARE_READ16_MEMBER(read_a15);
|
||||||
|
virtual DECLARE_WRITE16_MEMBER(write_a15);
|
||||||
|
|
||||||
|
// FIXME:
|
||||||
|
// this should be private, but then there is some problem installing delegates in the driver...
|
||||||
|
//private:
|
||||||
|
|
||||||
|
device_md_cart_interface* m_cart;
|
||||||
|
|
||||||
|
int m_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================> md_cart_slot_device
|
||||||
|
|
||||||
|
class md_cart_slot_device : public base_md_cart_slot_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
md_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
virtual const char *image_interface() const { return "megadriv_cart"; }
|
||||||
|
virtual const char *file_extensions() const { return "smd,bin,md,gen"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ======================> md_subcart_slot_device
|
||||||
|
|
||||||
|
class md_subcart_slot_device : public base_md_cart_slot_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
md_subcart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
virtual bool must_be_loaded() const { return 0; }
|
||||||
|
virtual const char *image_interface() const { return "megadriv_cart"; }
|
||||||
|
virtual const char *file_extensions() const { return "smd,bin,md,gen"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ======================> pico_cart_slot_device
|
||||||
|
|
||||||
|
class pico_cart_slot_device : public base_md_cart_slot_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
pico_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
virtual const char *image_interface() const { return "pico_cart"; }
|
||||||
|
virtual const char *file_extensions() const { return "bin,md"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// device type definition
|
||||||
|
extern const device_type MD_CART_SLOT;
|
||||||
|
extern const device_type MD_SUBCART_SLOT; // needed to allow S&K pass-through to have non-mandatory cart
|
||||||
|
extern const device_type PICO_CART_SLOT;
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
DEVICE CONFIGURATION MACROS
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#define MCFG_MD_CARTRIDGE_ADD(_tag,_slot_intf,_def_slot,_def_inp) \
|
||||||
|
MCFG_DEVICE_ADD(_tag, MD_CART_SLOT, 0) \
|
||||||
|
MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, _def_inp, false)
|
||||||
|
|
||||||
|
#define MCFG_MDSUB_CARTRIDGE_ADD(_tag,_slot_intf,_def_slot,_def_inp) \
|
||||||
|
MCFG_DEVICE_ADD(_tag, MD_SUBCART_SLOT, 0) \
|
||||||
|
MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, _def_inp, false)
|
||||||
|
|
||||||
|
#define MCFG_PICO_CARTRIDGE_ADD(_tag,_slot_intf,_def_slot,_def_inp) \
|
||||||
|
MCFG_DEVICE_ADD(_tag, PICO_CART_SLOT, 0) \
|
||||||
|
MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, _def_inp, false)
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
245
src/mess/machine/md_stm95.c
Normal file
245
src/mess/machine/md_stm95.c
Normal file
@ -0,0 +1,245 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
MegaDrive / Genesis Cart + STM95 EEPROM device
|
||||||
|
|
||||||
|
|
||||||
|
Emulation by MetalliC, converted to slot by Fabio Priuli
|
||||||
|
|
||||||
|
|
||||||
|
TO DO: split STM95 to a separate device...
|
||||||
|
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include "emu.h"
|
||||||
|
#include "machine/md_stm95.h"
|
||||||
|
|
||||||
|
|
||||||
|
void stm95_eeprom_device::set_cs_line(int state)
|
||||||
|
{
|
||||||
|
reset_line = state;
|
||||||
|
if (reset_line != CLEAR_LINE)
|
||||||
|
{
|
||||||
|
stream_pos = 0;
|
||||||
|
stm_state = IDLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void stm95_eeprom_device::set_si_line(int state)
|
||||||
|
{
|
||||||
|
latch = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
int stm95_eeprom_device::get_so_line(void)
|
||||||
|
{
|
||||||
|
if (stm_state == READING || stm_state == CMD_RDSR)
|
||||||
|
return (stream_data >> 8) & 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void stm95_eeprom_device::set_sck_line(int state)
|
||||||
|
{
|
||||||
|
if (reset_line == CLEAR_LINE)
|
||||||
|
{
|
||||||
|
if (state == ASSERT_LINE && sck_line == CLEAR_LINE)
|
||||||
|
{
|
||||||
|
switch (stm_state)
|
||||||
|
{
|
||||||
|
case IDLE:
|
||||||
|
stream_data = (stream_data << 1) | (latch ? 1 : 0);
|
||||||
|
stream_pos++;
|
||||||
|
if (stream_pos == 8)
|
||||||
|
{
|
||||||
|
stream_pos = 0;
|
||||||
|
//printf("STM95 EEPROM: got cmd %02X\n", stream_data&0xff);
|
||||||
|
switch(stream_data & 0xff)
|
||||||
|
{
|
||||||
|
case 0x01: // write status register
|
||||||
|
if (WEL != 0)
|
||||||
|
stm_state = CMD_WRSR;
|
||||||
|
WEL = 0;
|
||||||
|
break;
|
||||||
|
case 0x02: // write
|
||||||
|
if (WEL != 0)
|
||||||
|
stm_state = CMD_WRITE;
|
||||||
|
stream_data = 0;
|
||||||
|
WEL = 0;
|
||||||
|
break;
|
||||||
|
case 0x03: // read
|
||||||
|
stm_state = M95320_CMD_READ;
|
||||||
|
stream_data = 0;
|
||||||
|
break;
|
||||||
|
case 0x04: // write disable
|
||||||
|
WEL = 0;
|
||||||
|
break;
|
||||||
|
case 0x05: // read status register
|
||||||
|
stm_state = CMD_RDSR;
|
||||||
|
stream_data = WEL<<1;
|
||||||
|
break;
|
||||||
|
case 0x06: // write enable
|
||||||
|
WEL = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
logerror("STM95 EEPROM: unknown cmd %02X\n", stream_data&0xff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CMD_WRSR:
|
||||||
|
stream_pos++; // just skip, don't care block protection
|
||||||
|
if (stream_pos == 8)
|
||||||
|
{
|
||||||
|
stm_state = IDLE;
|
||||||
|
stream_pos = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CMD_RDSR:
|
||||||
|
stream_data = stream_data<<1;
|
||||||
|
stream_pos++;
|
||||||
|
if (stream_pos == 8)
|
||||||
|
{
|
||||||
|
stm_state = IDLE;
|
||||||
|
stream_pos = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case M95320_CMD_READ:
|
||||||
|
stream_data = (stream_data << 1) | (latch ? 1 : 0);
|
||||||
|
stream_pos++;
|
||||||
|
if (stream_pos == 16)
|
||||||
|
{
|
||||||
|
eeprom_addr = stream_data & (M95320_SIZE - 1);
|
||||||
|
stream_data = eeprom_data[eeprom_addr];
|
||||||
|
stm_state = READING;
|
||||||
|
stream_pos = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case READING:
|
||||||
|
stream_data = stream_data<<1;
|
||||||
|
stream_pos++;
|
||||||
|
if (stream_pos == 8)
|
||||||
|
{
|
||||||
|
if (++eeprom_addr == M95320_SIZE)
|
||||||
|
eeprom_addr = 0;
|
||||||
|
stream_data |= eeprom_data[eeprom_addr];
|
||||||
|
stream_pos = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CMD_WRITE:
|
||||||
|
stream_data = (stream_data << 1) | (latch ? 1 : 0);
|
||||||
|
stream_pos++;
|
||||||
|
if (stream_pos == 16)
|
||||||
|
{
|
||||||
|
eeprom_addr = stream_data & (M95320_SIZE - 1);
|
||||||
|
stm_state = WRITING;
|
||||||
|
stream_pos = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WRITING:
|
||||||
|
stream_data = (stream_data << 1) | (latch ? 1 : 0);
|
||||||
|
stream_pos++;
|
||||||
|
if (stream_pos == 8)
|
||||||
|
{
|
||||||
|
eeprom_data[eeprom_addr] = stream_data;
|
||||||
|
if (++eeprom_addr == M95320_SIZE)
|
||||||
|
eeprom_addr = 0;
|
||||||
|
stream_pos = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sck_line = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// md_rom_device - constructor
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
const device_type MD_EEPROM_STM95 = &device_creator<md_eeprom_stm95_device>;
|
||||||
|
|
||||||
|
|
||||||
|
md_eeprom_stm95_device::md_eeprom_stm95_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: device_t(mconfig, type, name, tag, owner, clock),
|
||||||
|
device_md_cart_interface( mconfig, *this )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
md_eeprom_stm95_device::md_eeprom_stm95_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: device_t(mconfig, MD_EEPROM_STM95, "MD Cart + EEPROM STM95", tag, owner, clock),
|
||||||
|
device_md_cart_interface( mconfig, *this )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void md_eeprom_stm95_device::device_start()
|
||||||
|
{
|
||||||
|
m_rdcnt = 0;
|
||||||
|
m_bank[0] = 0;
|
||||||
|
m_bank[1] = 0;
|
||||||
|
m_bank[2] = 0;
|
||||||
|
nvram_alloc(machine(), M95320_SIZE);
|
||||||
|
m_stm95.eeprom_data = (UINT8*)get_nvram_base();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
mapper specific handlers
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
READ16_MEMBER(md_eeprom_stm95_device::read)
|
||||||
|
{
|
||||||
|
if (offset == 0x0015e6/2 || offset == 0x0015e8/2)
|
||||||
|
{
|
||||||
|
// ugly hack until we don't know much about game protection
|
||||||
|
// first 3 reads from 15e6 return 0x00000010, then normal 0x00018010 value for crc check
|
||||||
|
UINT16 res;
|
||||||
|
offset -= 0x0015e6/2;
|
||||||
|
logerror("read 0x15e6 %d\n", m_rdcnt);
|
||||||
|
if (m_rdcnt < 6)
|
||||||
|
{
|
||||||
|
m_rdcnt++;
|
||||||
|
res = offset ? 0x10 : 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
res = offset ? 0x8010 : 0x0001;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
if (offset < 0x280000/2)
|
||||||
|
return m_rom[offset];
|
||||||
|
else // last 0x180000 are bankswitched
|
||||||
|
{
|
||||||
|
UINT8 bank = (offset - 0x280000/2) >> 18;
|
||||||
|
return m_rom[(offset & 0x7ffff/2) + (m_bank[bank] * 0x80000)/2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
READ16_MEMBER(md_eeprom_stm95_device::read_a13)
|
||||||
|
{
|
||||||
|
if (offset == 0x0a/2)
|
||||||
|
{
|
||||||
|
return m_stm95.get_so_line() & 1;
|
||||||
|
}
|
||||||
|
return 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE16_MEMBER(md_eeprom_stm95_device::write_a13)
|
||||||
|
{
|
||||||
|
if (offset == 0x00/2)
|
||||||
|
{
|
||||||
|
logerror("A13001 write %02x\n", data);
|
||||||
|
}
|
||||||
|
else if (offset < 0x08/2)
|
||||||
|
{
|
||||||
|
m_bank[offset - 1] = data & 0x0f;
|
||||||
|
}
|
||||||
|
else if (offset < 0x0a/2)
|
||||||
|
{
|
||||||
|
m_stm95.set_si_line(BIT(data, 0));
|
||||||
|
m_stm95.set_sck_line(BIT(data, 1));
|
||||||
|
m_stm95.set_halt_line(BIT(data, 2));
|
||||||
|
m_stm95.set_cs_line(BIT(data, 3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
84
src/mess/machine/md_stm95.h
Normal file
84
src/mess/machine/md_stm95.h
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
#ifndef __MD_STM95_H
|
||||||
|
#define __MD_STM95_H
|
||||||
|
|
||||||
|
#include "machine/md_slot.h"
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// TYPE DEFINITIONS
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
/* ST M95320 32Kbit serial EEPROM implementation */
|
||||||
|
// TO DO: STM95 should be made a separate EEPROM device and this should be merged with md_eeprom.c!
|
||||||
|
|
||||||
|
#define M95320_SIZE 0x1000
|
||||||
|
|
||||||
|
enum STMSTATE
|
||||||
|
{
|
||||||
|
IDLE = 0,
|
||||||
|
CMD_WRSR,
|
||||||
|
CMD_RDSR,
|
||||||
|
M95320_CMD_READ,
|
||||||
|
CMD_WRITE,
|
||||||
|
READING,
|
||||||
|
WRITING
|
||||||
|
};
|
||||||
|
|
||||||
|
class stm95_eeprom_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
stm95_eeprom_device() :
|
||||||
|
stm_state(IDLE),
|
||||||
|
stream_pos(0)
|
||||||
|
{};
|
||||||
|
|
||||||
|
UINT8 *eeprom_data;
|
||||||
|
void set_cs_line(int);
|
||||||
|
void set_halt_line(int state) {}; // not implemented
|
||||||
|
void set_si_line(int);
|
||||||
|
void set_sck_line(int state);
|
||||||
|
int get_so_line(void);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int latch;
|
||||||
|
int reset_line;
|
||||||
|
int sck_line;
|
||||||
|
int WEL;
|
||||||
|
|
||||||
|
STMSTATE stm_state;
|
||||||
|
int stream_pos;
|
||||||
|
int stream_data;
|
||||||
|
int eeprom_addr;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ======================> md_eeprom_stm95_device
|
||||||
|
|
||||||
|
class md_eeprom_stm95_device : public device_t,
|
||||||
|
public device_md_cart_interface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
md_eeprom_stm95_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
md_eeprom_stm95_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_start();
|
||||||
|
virtual void device_config_complete() { m_shortname = "md_eeprom_stm95"; }
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ16_MEMBER(read);
|
||||||
|
virtual DECLARE_READ16_MEMBER(read_a13);
|
||||||
|
virtual DECLARE_WRITE16_MEMBER(write_a13);
|
||||||
|
|
||||||
|
private:
|
||||||
|
UINT8 m_bank[3];
|
||||||
|
int m_rdcnt;
|
||||||
|
|
||||||
|
stm95_eeprom_device m_stm95;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// device type definition
|
||||||
|
extern const device_type MD_EEPROM_STM95;
|
||||||
|
|
||||||
|
#endif
|
@ -1,11 +1,6 @@
|
|||||||
/* Megadrive SVP emulation (Virtua Racing) */
|
/* Megadrive SVP emulation (Virtua Racing) */
|
||||||
|
|
||||||
#include "includes/megadriv.h"
|
#include "includes/md.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* SVP (virtua racing) */
|
|
||||||
cpu_device *_svp_cpu;
|
|
||||||
|
|
||||||
|
|
||||||
/****************************************** SVP related *****************************************/
|
/****************************************** SVP related *****************************************/
|
||||||
@ -65,15 +60,15 @@ static UINT32 pm_io(address_space &space, int reg, int write, UINT32 d)
|
|||||||
state->m_emu_status &= ~SSP_PMC_SET;
|
state->m_emu_status &= ~SSP_PMC_SET;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// just in case
|
// just in case
|
||||||
if (state->m_emu_status & SSP_PMC_HAVE_ADDR) {
|
if (state->m_emu_status & SSP_PMC_HAVE_ADDR) {
|
||||||
state->m_emu_status &= ~SSP_PMC_HAVE_ADDR;
|
state->m_emu_status &= ~SSP_PMC_HAVE_ADDR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reg == 4 || (space.device().state().state_int(SSP_ST) & 0x60))
|
if (reg == 4 || (space.device().state().state_int(SSP_ST) & 0x60))
|
||||||
{
|
{
|
||||||
#define CADDR ((((mode<<16)&0x7f0000)|addr)<<1)
|
#define CADDR ((((mode<<16)&0x7f0000)|addr)<<1)
|
||||||
UINT16 *dram = (UINT16 *)state->m_dram;
|
UINT16 *dram = (UINT16 *)state->m_dram;
|
||||||
if (write)
|
if (write)
|
||||||
{
|
{
|
||||||
@ -83,14 +78,14 @@ static UINT32 pm_io(address_space &space, int reg, int write, UINT32 d)
|
|||||||
{
|
{
|
||||||
int inc = get_inc(mode);
|
int inc = get_inc(mode);
|
||||||
if (mode & 0x0400) {
|
if (mode & 0x0400) {
|
||||||
overwrite_write(&dram[addr], d);
|
overwrite_write(&dram[addr], d);
|
||||||
} else dram[addr] = d;
|
} else dram[addr] = d;
|
||||||
state->m_pmac_write[reg] += inc;
|
state->m_pmac_write[reg] += inc;
|
||||||
}
|
}
|
||||||
else if ((mode & 0xfbff) == 0x4018) // DRAM, cell inc
|
else if ((mode & 0xfbff) == 0x4018) // DRAM, cell inc
|
||||||
{
|
{
|
||||||
if (mode & 0x0400) {
|
if (mode & 0x0400) {
|
||||||
overwrite_write(&dram[addr], d);
|
overwrite_write(&dram[addr], d);
|
||||||
} else dram[addr] = d;
|
} else dram[addr] = d;
|
||||||
state->m_pmac_write[reg] += (addr&1) ? 31 : 1;
|
state->m_pmac_write[reg] += (addr&1) ? 31 : 1;
|
||||||
}
|
}
|
||||||
@ -103,7 +98,7 @@ static UINT32 pm_io(address_space &space, int reg, int write, UINT32 d)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
logerror("ssp FIXME: PM%i unhandled write mode %04x, [%06x] %04x\n",
|
logerror("ssp FIXME: PM%i unhandled write mode %04x, [%06x] %04x\n",
|
||||||
reg, mode, CADDR, d);
|
reg, mode, CADDR, d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -125,17 +120,17 @@ static UINT32 pm_io(address_space &space, int reg, int write, UINT32 d)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
logerror("ssp FIXME: PM%i unhandled read mode %04x, [%06x]\n",
|
logerror("ssp FIXME: PM%i unhandled read mode %04x, [%06x]\n",
|
||||||
reg, mode, CADDR);
|
reg, mode, CADDR);
|
||||||
d = 0;
|
d = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PMC value corresponds to last PMR accessed (not sure).
|
// PMC value corresponds to last PMR accessed (not sure).
|
||||||
state->m_pmc.d = state->m_pmac_read[write ? reg + 6 : reg];
|
state->m_pmc.d = state->m_pmac_read[write ? reg + 6 : reg];
|
||||||
|
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (UINT32)-1;
|
return (UINT32)-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,7 +187,7 @@ static READ16_HANDLER( read_XST )
|
|||||||
mdsvp_state *state = space.machine().driver_data<mdsvp_state>();
|
mdsvp_state *state = space.machine().driver_data<mdsvp_state>();
|
||||||
UINT32 d = pm_io(space, 3, 0, 0);
|
UINT32 d = pm_io(space, 3, 0, 0);
|
||||||
if (d != (UINT32)-1) return d;
|
if (d != (UINT32)-1) return d;
|
||||||
|
|
||||||
return state->m_XST;
|
return state->m_XST;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,7 +196,7 @@ static WRITE16_HANDLER( write_XST )
|
|||||||
mdsvp_state *state = space.machine().driver_data<mdsvp_state>();
|
mdsvp_state *state = space.machine().driver_data<mdsvp_state>();
|
||||||
UINT32 r = pm_io(space, 3, 1, data);
|
UINT32 r = pm_io(space, 3, 1, data);
|
||||||
if (r != (UINT32)-1) return;
|
if (r != (UINT32)-1) return;
|
||||||
|
|
||||||
state->m_XST2 |= 1;
|
state->m_XST2 |= 1;
|
||||||
state->m_XST = data;
|
state->m_XST = data;
|
||||||
}
|
}
|
||||||
@ -261,10 +256,10 @@ static READ16_HANDLER( svp_68k_io_r )
|
|||||||
UINT32 d;
|
UINT32 d;
|
||||||
switch (offset)
|
switch (offset)
|
||||||
{
|
{
|
||||||
// 0xa15000, 0xa15002
|
// 0xa15000, 0xa15002
|
||||||
case 0:
|
case 0:
|
||||||
case 1: return state->m_XST;
|
case 1: return state->m_XST;
|
||||||
// 0xa15004
|
// 0xa15004
|
||||||
case 2: d = state->m_XST2; state->m_XST2 &= ~1; return d;
|
case 2: d = state->m_XST2; state->m_XST2 &= ~1; return d;
|
||||||
default: logerror("unhandled SVP reg read @ %x\n", offset<<1);
|
default: logerror("unhandled SVP reg read @ %x\n", offset<<1);
|
||||||
}
|
}
|
||||||
@ -276,10 +271,10 @@ static WRITE16_HANDLER( svp_68k_io_w )
|
|||||||
mdsvp_state *state = space.machine().driver_data<mdsvp_state>();
|
mdsvp_state *state = space.machine().driver_data<mdsvp_state>();
|
||||||
switch (offset)
|
switch (offset)
|
||||||
{
|
{
|
||||||
// 0xa15000, 0xa15002
|
// 0xa15000, 0xa15002
|
||||||
case 0:
|
case 0:
|
||||||
case 1: state->m_XST = data; state->m_XST2 |= 2; break;
|
case 1: state->m_XST = data; state->m_XST2 |= 2; break;
|
||||||
// 0xa15006
|
// 0xa15006
|
||||||
case 3: break; // possibly halts SSP1601
|
case 3: break; // possibly halts SSP1601
|
||||||
default: logerror("unhandled SVP reg write %04x @ %x\n", data, offset<<1);
|
default: logerror("unhandled SVP reg write %04x @ %x\n", data, offset<<1);
|
||||||
}
|
}
|
||||||
@ -320,20 +315,9 @@ ADDRESS_MAP_START( svp_ext_map, AS_IO, 16, driver_device )
|
|||||||
ADDRESS_MAP_END
|
ADDRESS_MAP_END
|
||||||
|
|
||||||
|
|
||||||
/* emulate testmode plug */
|
|
||||||
static UINT8 megadrive_io_read_data_port_svp(running_machine &machine, int portnum)
|
|
||||||
{
|
|
||||||
if (portnum == 0 && machine.root_device().ioport("MEMORY_TEST")->read_safe(0x00))
|
|
||||||
{
|
|
||||||
return (megadrive_io_data_regs[0] & 0xc0);
|
|
||||||
}
|
|
||||||
return megadrive_io_read_data_port_3button(machine, portnum);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static READ16_HANDLER( svp_speedup_r )
|
static READ16_HANDLER( svp_speedup_r )
|
||||||
{
|
{
|
||||||
space.device().execute().spin_until_time(attotime::from_usec(100));
|
space.device().execute().spin_until_time(attotime::from_usec(100));
|
||||||
return 0x0425;
|
return 0x0425;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -341,8 +325,8 @@ static READ16_HANDLER( svp_speedup_r )
|
|||||||
void svp_init(running_machine &machine)
|
void svp_init(running_machine &machine)
|
||||||
{
|
{
|
||||||
mdsvp_state *state = machine.driver_data<mdsvp_state>();
|
mdsvp_state *state = machine.driver_data<mdsvp_state>();
|
||||||
UINT8 *ROM;
|
UINT8 *ROM = state->memregion("maincpu")->base();
|
||||||
|
|
||||||
memset(state->m_pmac_read, 0, ARRAY_LENGTH(state->m_pmac_read));
|
memset(state->m_pmac_read, 0, ARRAY_LENGTH(state->m_pmac_read));
|
||||||
memset(state->m_pmac_write, 0, ARRAY_LENGTH(state->m_pmac_write));
|
memset(state->m_pmac_write, 0, ARRAY_LENGTH(state->m_pmac_write));
|
||||||
state->m_pmc.d = 0;
|
state->m_pmc.d = 0;
|
||||||
@ -351,7 +335,7 @@ void svp_init(running_machine &machine)
|
|||||||
state->m_emu_status = 0;
|
state->m_emu_status = 0;
|
||||||
state->m_XST = 0;
|
state->m_XST = 0;
|
||||||
state->m_XST2 = 0;
|
state->m_XST2 = 0;
|
||||||
|
|
||||||
/* SVP stuff */
|
/* SVP stuff */
|
||||||
state->m_dram = auto_alloc_array(machine, UINT8, 0x20000);
|
state->m_dram = auto_alloc_array(machine, UINT8, 0x20000);
|
||||||
machine.device("maincpu")->memory().space(AS_PROGRAM).install_ram(0x300000, 0x31ffff, state->m_dram);
|
machine.device("maincpu")->memory().space(AS_PROGRAM).install_ram(0x300000, 0x31ffff, state->m_dram);
|
||||||
@ -359,14 +343,14 @@ void svp_init(running_machine &machine)
|
|||||||
// "cell arrange" 1 and 2
|
// "cell arrange" 1 and 2
|
||||||
machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x390000, 0x39ffff, FUNC(svp_68k_cell1_r));
|
machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x390000, 0x39ffff, FUNC(svp_68k_cell1_r));
|
||||||
machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x3a0000, 0x3affff, FUNC(svp_68k_cell2_r));
|
machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x3a0000, 0x3affff, FUNC(svp_68k_cell2_r));
|
||||||
|
|
||||||
machine.device("svp")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x438, 0x438, FUNC(svp_speedup_r));
|
machine.device("svp")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x438, 0x438, FUNC(svp_speedup_r));
|
||||||
|
|
||||||
|
if (state->m_slotcart->m_cart->get_rom_base() != NULL)
|
||||||
|
memcpy(ROM, state->m_slotcart->m_cart->get_rom_base(), state->m_slotcart->m_cart->get_rom_size());
|
||||||
|
|
||||||
state->m_iram = auto_alloc_array(machine, UINT8, 0x800);
|
state->m_iram = auto_alloc_array(machine, UINT8, 0x800);
|
||||||
state->membank("bank3")->set_base(state->m_iram);
|
state->membank("bank3")->set_base(state->m_iram);
|
||||||
/* SVP ROM just shares m68k region.. */
|
/* SVP ROM just shares m68k region.. */
|
||||||
ROM = state->memregion("maincpu")->base();
|
|
||||||
state->membank("bank4")->set_base(ROM + 0x800);
|
state->membank("bank4")->set_base(ROM + 0x800);
|
||||||
|
|
||||||
megadrive_io_read_data_port_ptr = megadrive_io_read_data_port_svp;
|
|
||||||
}
|
}
|
@ -455,7 +455,6 @@ $(MESSOBJ)/mame.a: \
|
|||||||
$(MAME_MACHINE)/megacd.o \
|
$(MAME_MACHINE)/megacd.o \
|
||||||
$(MAME_MACHINE)/megacdcd.o \
|
$(MAME_MACHINE)/megacdcd.o \
|
||||||
$(MAME_MACHINE)/mega32x.o \
|
$(MAME_MACHINE)/mega32x.o \
|
||||||
$(MAME_MACHINE)/megasvp.o \
|
|
||||||
$(MAME_MACHINE)/megavdp.o \
|
$(MAME_MACHINE)/megavdp.o \
|
||||||
$(MAME_MACHINE)/dc.o \
|
$(MAME_MACHINE)/dc.o \
|
||||||
$(MAME_DRIVERS)/naomi.o \
|
$(MAME_DRIVERS)/naomi.o \
|
||||||
@ -1617,7 +1616,13 @@ $(MESSOBJ)/sanyo.a: \
|
|||||||
|
|
||||||
$(MESSOBJ)/sega.a: \
|
$(MESSOBJ)/sega.a: \
|
||||||
$(MESS_DRIVERS)/sg1000.o \
|
$(MESS_DRIVERS)/sg1000.o \
|
||||||
$(MAME_MACHINE)/md_cart.o \
|
$(MESS_MACHINE)/md_slot.o \
|
||||||
|
$(MESS_MACHINE)/md_rom.o \
|
||||||
|
$(MESS_MACHINE)/md_sk.o \
|
||||||
|
$(MESS_MACHINE)/md_eeprom.o \
|
||||||
|
$(MESS_MACHINE)/md_jcart.o \
|
||||||
|
$(MESS_MACHINE)/md_stm95.o \
|
||||||
|
$(MESS_MACHINE)/megasvp.o \
|
||||||
$(MESS_DRIVERS)/megadriv.o \
|
$(MESS_DRIVERS)/megadriv.o \
|
||||||
$(MESS_DRIVERS)/dccons.o \
|
$(MESS_DRIVERS)/dccons.o \
|
||||||
$(MAME_MACHINE)/gdrom.o \
|
$(MAME_MACHINE)/gdrom.o \
|
||||||
|
Loading…
Reference in New Issue
Block a user