diff options
-rw-r--r-- | hash/megadriv.xml | 27 | ||||
-rw-r--r-- | src/mame/includes/megadriv.h | 17 | ||||
-rw-r--r-- | src/mame/machine/megadriv.c | 164 | ||||
-rw-r--r-- | src/mess/drivers/megadriv.c | 187 | ||||
-rw-r--r-- | src/mess/machine/md_eeprom.c | 49 | ||||
-rw-r--r-- | src/mess/machine/md_jcart.c | 10 | ||||
-rw-r--r-- | src/mess/machine/md_rom.c | 88 | ||||
-rw-r--r-- | src/mess/machine/md_rom.h | 37 | ||||
-rw-r--r-- | src/mess/machine/md_sk.c | 5 | ||||
-rw-r--r-- | src/mess/machine/md_slot.c | 118 | ||||
-rw-r--r-- | src/mess/machine/md_slot.h | 7 |
11 files changed, 411 insertions, 298 deletions
diff --git a/hash/megadriv.xml b/hash/megadriv.xml index 21c8d0f6b1f..46ca85d719a 100644 --- a/hash/megadriv.xml +++ b/hash/megadriv.xml @@ -3122,9 +3122,13 @@ better to use names related to the actual pcb, possibly even reverting to use th <year>199?</year> <publisher><unlicensed></publisher> <part name="cart" interface="megadriv_cart"> + <feature name="pcb_type" value="SEGA-SRAM" /> + <feature name="slot" value="rom_sram" /> <dataarea name="rom" size="2097152"> <rom name="barver battle saga - tai kong zhan shi (chi) (unl).bin" size="2097152" crc="d37a37c6" sha1="6d49a0db7687ccad3441f47fbc483c87cd6eab53" offset="000000" loadflag="load16_word_swap" /> </dataarea> + <dataarea name="sram" size="16384"> <!-- Size to be confirmed. It does not work without SRAM. --> + </dataarea> </part> </software> @@ -3778,11 +3782,12 @@ better to use names related to the actual pcb, possibly even reverting to use th </part> </software> - <software name="blockb" supported="no"> + <software name="blockb"> <description>Blockbuster World Video Game Championship II (USA)</description> <year>1995</year> <publisher>Acclaim Entertainment</publisher> <part name="cart" interface="megadriv_cart"> + <feature name="slot" value="rom_nbajamte" /> <dataarea name="rom" size="4194304"> <rom name="blockbuster world video game championship ii (usa).bin" size="4194304" crc="4385e366" sha1="1a06213a3a26c9105fc3013a141c22d212045a0b" offset="000000" loadflag="load16_word_swap" /> </dataarea> @@ -4667,9 +4672,13 @@ better to use names related to the actual pcb, possibly even reverting to use th <year>199?</year> <publisher>Gametec?</publisher> <part name="cart" interface="megadriv_cart"> + <feature name="pcb_type" value="SEGA-SRAM" /> + <feature name="slot" value="rom_sram" /> <dataarea name="rom" size="1048576"> <rom name="chao ji da fu weng (chi) (unl).bin" size="1048576" crc="2e2ea687" sha1="be1a66bd1f75f5b1b37b8ae18e6334c36291e63d" offset="000000" loadflag="load16_word_swap" /> </dataarea> + <dataarea name="sram" size="16384"> <!-- Size to be confirmed. It does not work without SRAM. --> + </dataarea> </part> </software> @@ -9808,9 +9817,13 @@ better to use names related to the actual pcb, possibly even reverting to use th <year>1995</year> <publisher>Accolade</publisher> <part name="cart" interface="megadriv_cart"> + <feature name="pcb_type" value="SEGA-SRAM" /> + <feature name="slot" value="rom_hardbl95" /> <dataarea name="rom" size="3145728"> <rom name="hardball '95 (usa).bin" size="3145728" crc="ed10bc9e" sha1="6a63fba59add9ba8e1845cbfcf4722833893113f" offset="000000" loadflag="load16_word_swap" /> </dataarea> + <dataarea name="sram" size="65536"> <!-- Size to be confirmed. It does not work without SRAM. --> + </dataarea> </part> </software> @@ -9819,9 +9832,13 @@ better to use names related to the actual pcb, possibly even reverting to use th <year>1993</year> <publisher>Accolade</publisher> <part name="cart" interface="megadriv_cart"> + <feature name="pcb_type" value="SEGA-SRAM" /> + <feature name="slot" value="rom_sram" /> <dataarea name="rom" size="2097152"> <rom name="hardball iii (usa).bin" size="2097152" crc="a4f2f011" sha1="88812ae494288fbf3dda86ccc69161ad960a2e3b" offset="000000" loadflag="load16_word_swap" /> </dataarea> + <dataarea name="sram" size="65536"> <!-- Size to be confirmed. It does not work without SRAM. --> + </dataarea> </part> </software> @@ -22040,7 +22057,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i <part name="cart" interface="megadriv_cart"> <feature name="pcb_type" value="SSF2" /> <feature name="slot" value="rom_ssf2" /> - <dataarea name="rom" size="5242880"> + <dataarea name="rom" size="9437184"> <rom name="super street fighter ii - the new challengers (jpn).bin" size="5242880" crc="d8eeb2bd" sha1="24c8634f59a481118f8350125fa6e00d33e04c95" offset="00000" loadflag="load16_word_swap" /> </dataarea> </part> @@ -22053,7 +22070,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i <part name="cart" interface="megadriv_cart"> <feature name="pcb_type" value="SSF2" /> <feature name="slot" value="rom_ssf2" /> - <dataarea name="rom" size="5242880"> + <dataarea name="rom" size="9437184"> <rom name="super street fighter ii - the new challengers (usa).bin" size="5242880" crc="165defbf" sha1="9ce6e69db9d28386f7542dacd3e3ead28eacf2a4" offset="00000" loadflag="load16_word_swap" /> </dataarea> </part> @@ -26496,13 +26513,13 @@ Notice that these are not working on real hardware due to bugged code with VDP i </part> </software> -<!-- Freezes during the intro sequence... --> - <software name="yasech" supported="no"> + <software name="yasech"> <description>Ya Se Chuan Shuo (Chi)</description> <year>1995</year> <publisher>Chuanpu Technologies</publisher> <info name="alt_title" value="亚瑟传说"/> <part name="cart" interface="megadriv_cart"> + <feature name="slot" value="rom_yasech" /> <dataarea name="rom" size="2097152"> <rom name="ya se chuan shuo (chi) (unl).bin" size="2097152" crc="095b9a15" sha1="8fe0806427e123717ba20478ab1410c25fa942e6" offset="000000" loadflag="load16_word_swap" /> </dataarea> diff --git a/src/mame/includes/megadriv.h b/src/mame/includes/megadriv.h index 813acefe63b..dd03321871e 100644 --- a/src/mame/includes/megadriv.h +++ b/src/mame/includes/megadriv.h @@ -39,15 +39,6 @@ INPUT_PORTS_EXTERN( mk3mdb ); MACHINE_CONFIG_EXTERN( megadriv_timers ); MACHINE_CONFIG_EXTERN( md_ntsc ); MACHINE_CONFIG_EXTERN( md_pal ); -MACHINE_CONFIG_EXTERN( md_svp ); - -MACHINE_CONFIG_EXTERN( genesis_32x ); -MACHINE_CONFIG_EXTERN( genesis_32x_pal ); -MACHINE_CONFIG_EXTERN( genesis_scd ); -MACHINE_CONFIG_EXTERN( genesis_scd_scd ); -MACHINE_CONFIG_EXTERN( genesis_scd_mcd ); -MACHINE_CONFIG_EXTERN( genesis_scd_mcdj ); -MACHINE_CONFIG_EXTERN( genesis_32x_scd ); MACHINE_CONFIG_EXTERN( md_bootleg ); // for topshoot.c & hshavoc.c extern cpu_device *_svp_cpu; @@ -408,14 +399,6 @@ public: { } }; -MACHINE_CONFIG_EXTERN( _32x_cartslot ); - - -/*----------- defined in drivers/megadriv.c -----------*/ - -/* These are needed to handle J-Cart inputs */ -extern DECLARE_WRITE16_HANDLER( jcart_ctrl_w ); -extern DECLARE_READ16_HANDLER( jcart_ctrl_r ); /* machine/megavdp.c */ extern UINT16 (*vdp_get_word_from_68k_mem)(running_machine &machine, UINT32 source, address_space& space); diff --git a/src/mame/machine/megadriv.c b/src/mame/machine/megadriv.c index bc5b07c6faf..90998e1252d 100644 --- a/src/mame/machine/megadriv.c +++ b/src/mame/machine/megadriv.c @@ -22,25 +22,8 @@ Known Non-Issues (confirmed on Real Genesis) #include "emu.h" -#include "coreutil.h" -#include "cpu/m68000/m68000.h" -#include "cpu/sh2/sh2.h" -#include "cpu/sh2/sh2comn.h" -#include "cpu/z80/z80.h" -#include "sound/2612intf.h" - -#include "sound/dac.h" -#include "sound/sn76496.h" - -#include "imagedev/chd_cd.h" -#include "imagedev/cartslot.h" -#include "formats/imageutl.h" - #include "includes/megadriv.h" -#include "machine/nvram.h" -#include "cpu/ssp1601/ssp1601.h" -#include "machine/megavdp.h" MACHINE_CONFIG_EXTERN( megadriv ); @@ -880,7 +863,8 @@ static ADDRESS_MAP_START( md_bootleg_map, AS_PROGRAM, 16, md_base_state ) AM_RANGE(0xe00000, 0xe0ffff) AM_RAM AM_MIRROR(0x1f0000) AM_SHARE("megadrive_ram") ADDRESS_MAP_END -MACHINE_CONFIG_DERIVED( md_bootleg, megadriv ) +MACHINE_CONFIG_START( md_bootleg, md_base_state ) + MCFG_FRAGMENT_ADD( md_ntsc ) MCFG_CPU_MODIFY("maincpu") MCFG_CPU_PROGRAM_MAP(md_bootleg_map) @@ -1160,10 +1144,6 @@ MACHINE_CONFIG_FRAGMENT( md_ntsc ) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker",0.25) /* 3.58 MHz */ MACHINE_CONFIG_END -MACHINE_CONFIG_START( megadriv, md_base_state ) - MCFG_FRAGMENT_ADD(md_ntsc) -MACHINE_CONFIG_END - /************ PAL hardware has a different master clock *************/ MACHINE_CONFIG_FRAGMENT( md_pal ) @@ -1215,146 +1195,6 @@ MACHINE_CONFIG_FRAGMENT( md_pal ) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker",0.25) /* 3.58 MHz */ MACHINE_CONFIG_END -MACHINE_CONFIG_START( megadpal, md_base_state ) - MCFG_FRAGMENT_ADD(md_pal) -MACHINE_CONFIG_END - - - - -MACHINE_CONFIG_DERIVED( genesis_32x, megadriv ) - - MCFG_DEVICE_ADD("sega32x", SEGA_32X_NTSC, 0) - - // we need to remove and re-add the sound system because the balance is different - // due to MAME / MESS having severe issues if the dac output is > 0.40? (sound is corrupted even if DAC is slient?!) - MCFG_DEVICE_REMOVE("ymsnd") - MCFG_DEVICE_REMOVE("snsnd") - - MCFG_SOUND_ADD("ymsnd", YM2612, MASTER_CLOCK_NTSC/7) - MCFG_SOUND_ROUTE(0, "lspeaker", (0.50)/2) - MCFG_SOUND_ROUTE(1, "rspeaker", (0.50)/2) - - /* sound hardware */ - MCFG_SOUND_ADD("snsnd", SEGAPSG, MASTER_CLOCK_NTSC/15) - MCFG_SOUND_CONFIG(psg_intf) - MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", (0.25)/2) - MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", (0.25)/2) - -MACHINE_CONFIG_END - - -MACHINE_CONFIG_DERIVED( genesis_32x_pal, megadpal ) - - MCFG_DEVICE_ADD("sega32x", SEGA_32X_PAL, 0) - - // we need to remove and re-add the sound system because the balance is different - // due to MAME / MESS having severe issues if the dac output is > 0.40? (sound is corrupted even if DAC is slient?!) - MCFG_DEVICE_REMOVE("ymsnd") - MCFG_DEVICE_REMOVE("snsnd") - - MCFG_SOUND_ADD("ymsnd", YM2612, MASTER_CLOCK_NTSC/7) - MCFG_SOUND_ROUTE(0, "lspeaker", (0.50)/2) - MCFG_SOUND_ROUTE(1, "rspeaker", (0.50)/2) - - /* sound hardware */ - MCFG_SOUND_ADD("snsnd", SEGAPSG, MASTER_CLOCK_NTSC/15) - MCFG_SOUND_CONFIG(psg_intf) - MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", (0.25)/2) - MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", (0.25)/2) - -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 -DEVICE_IMAGE_LOAD_MEMBER( md_base_state, _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(md_base_state, _32x_cart) - MCFG_SOFTWARE_LIST_ADD("cart_list","32x") -MACHINE_CONFIG_END - - - -struct cdrom_interface scd_cdrom = -{ - "scd_cdrom", - NULL -}; - -MACHINE_CONFIG_DERIVED( genesis_scd, megadriv ) - MCFG_DEVICE_ADD("segacd", SEGA_SEGACD_US, 0) - MCFG_CDROM_ADD( "cdrom",scd_cdrom ) -MACHINE_CONFIG_END - -/* Different Softlists for different regions (for now at least) */ -MACHINE_CONFIG_DERIVED( genesis_scd_scd, genesis_scd ) - MCFG_SOFTWARE_LIST_ADD("cd_list","segacd") -MACHINE_CONFIG_END - -MACHINE_CONFIG_DERIVED( genesis_scd_mcd, genesis_scd ) - MCFG_SOFTWARE_LIST_ADD("cd_list","megacd") -MACHINE_CONFIG_END - -MACHINE_CONFIG_DERIVED( genesis_scd_mcdj, genesis_scd ) - MCFG_SOFTWARE_LIST_ADD("cd_list","megacdj") -MACHINE_CONFIG_END - -MACHINE_CONFIG_DERIVED( genesis_32x_scd, genesis_32x ) - - MCFG_DEVICE_ADD("segacd", SEGA_SEGACD_US, 0) - //MCFG_QUANTUM_PERFECT_CPU("32x_master_sh2") -MACHINE_CONFIG_END - - - static int megadriv_tas_callback(device_t *device) { diff --git a/src/mess/drivers/megadriv.c b/src/mess/drivers/megadriv.c index ba730a63d57..4ea48530fc5 100644 --- a/src/mess/drivers/megadriv.c +++ b/src/mess/drivers/megadriv.c @@ -9,6 +9,13 @@ #include "machine/md_jcart.h" #include "machine/md_stm95.h" +#include "sound/sn76496.h" + +#include "imagedev/chd_cd.h" +#include "imagedev/cartslot.h" + +#include "formats/imageutl.h" + /************************************* * @@ -296,7 +303,8 @@ static SLOT_INTERFACE_START(md_cart) 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) + SLOT_INTERFACE_INTERNAL("rom_hardbl95", MD_ROM_SRAM) + SLOT_INTERFACE_INTERNAL("rom_beggar", MD_ROM_SRAM) // EEPROM handling (not supported fully yet) SLOT_INTERFACE_INTERNAL("rom_eeprom", MD_STD_EEPROM) SLOT_INTERFACE_INTERNAL("rom_nbajam", MD_EEPROM_NBAJAM) @@ -319,6 +327,7 @@ static SLOT_INTERFACE_START(md_cart) 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_yasech", MD_ROM_YASECH) SLOT_INTERFACE_INTERNAL("rom_kof98", MD_ROM_KOF98) SLOT_INTERFACE_INTERNAL("rom_kof99", MD_ROM_KOF99) SLOT_INTERFACE_INTERNAL("rom_lion2", MD_ROM_LION2) @@ -443,8 +452,112 @@ DRIVER_INIT_MEMBER(md_cons_state,md_jpn) megadrive_region_pal = 0; } -/****************************************** SegaCD & 32X emulation ****************************************/ +/****************************************** 32X emulation ****************************************/ + +static const sn76496_config psg_intf = +{ + DEVCB_NULL +}; + +// FIXME: non-softlist loading should keep using ROM_CART_LOAD in the ROM definitions, +// once we better integrate softlist with the old loading procedures +DEVICE_IMAGE_LOAD_MEMBER( md_base_state, _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; +} + + +static MACHINE_CONFIG_START( genesis_32x, md_cons_state ) +//MACHINE_CONFIG_DERIVED( genesis_32x, megadriv ) + MCFG_FRAGMENT_ADD( md_ntsc ) + + MCFG_DEVICE_ADD("sega32x", SEGA_32X_NTSC, 0) + + // we need to remove and re-add the sound system because the balance is different + // due to MAME / MESS having severe issues if the dac output is > 0.40? (sound is corrupted even if DAC is slient?!) + MCFG_DEVICE_REMOVE("ymsnd") + MCFG_DEVICE_REMOVE("snsnd") + + MCFG_SOUND_ADD("ymsnd", YM2612, MASTER_CLOCK_NTSC/7) + MCFG_SOUND_ROUTE(0, "lspeaker", (0.50)/2) + MCFG_SOUND_ROUTE(1, "rspeaker", (0.50)/2) + + /* sound hardware */ + MCFG_SOUND_ADD("snsnd", SEGAPSG, MASTER_CLOCK_NTSC/15) + MCFG_SOUND_CONFIG(psg_intf) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", (0.25)/2) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", (0.25)/2) + +MACHINE_CONFIG_END + + +static MACHINE_CONFIG_START( genesis_32x_pal, md_cons_state ) +//MACHINE_CONFIG_DERIVED( genesis_32x_pal, megadpal ) + MCFG_FRAGMENT_ADD( md_pal ) + + MCFG_DEVICE_ADD("sega32x", SEGA_32X_PAL, 0) + + // we need to remove and re-add the sound system because the balance is different + // due to MAME / MESS having severe issues if the dac output is > 0.40? (sound is corrupted even if DAC is slient?!) + MCFG_DEVICE_REMOVE("ymsnd") + MCFG_DEVICE_REMOVE("snsnd") + + MCFG_SOUND_ADD("ymsnd", YM2612, MASTER_CLOCK_NTSC/7) + MCFG_SOUND_ROUTE(0, "lspeaker", (0.50)/2) + MCFG_SOUND_ROUTE(1, "rspeaker", (0.50)/2) + /* sound hardware */ + MCFG_SOUND_ADD("snsnd", SEGAPSG, MASTER_CLOCK_NTSC/15) + MCFG_SOUND_CONFIG(psg_intf) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", (0.25)/2) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", (0.25)/2) + +MACHINE_CONFIG_END + + +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(md_base_state, _32x_cart) + MCFG_SOFTWARE_LIST_ADD("cart_list","32x") +MACHINE_CONFIG_END static MACHINE_CONFIG_DERIVED( ms_32x, genesis_32x ) MCFG_FRAGMENT_ADD( _32x_cartslot ) @@ -499,6 +612,52 @@ ROM_START( 32xj ) _32X_ROMS ROM_END + +/****************************************** SegaCD emulation ****************************************/ + +struct cdrom_interface scd_cdrom = +{ + "scd_cdrom", + NULL +}; + +static MACHINE_CONFIG_START( genesis_scd, md_cons_state ) +//MACHINE_CONFIG_DERIVED( genesis_scd, megadriv ) + MCFG_FRAGMENT_ADD( md_ntsc ) + MCFG_DEVICE_ADD("segacd", SEGA_SEGACD_US, 0) + MCFG_CDROM_ADD( "cdrom",scd_cdrom ) + + MCFG_SOFTWARE_LIST_ADD("cd_list","segacd") +MACHINE_CONFIG_END + +static MACHINE_CONFIG_START( mega_scd, md_cons_state ) +//MACHINE_CONFIG_DERIVED( genesis_scd, megadriv ) + MCFG_FRAGMENT_ADD( md_pal ) + MCFG_DEVICE_ADD("segacd", SEGA_SEGACD_EUROPE, 0) + + MCFG_CDROM_ADD( "cdrom",scd_cdrom ) + + MCFG_SOFTWARE_LIST_ADD("cd_list","megacd") +MACHINE_CONFIG_END + +static MACHINE_CONFIG_START( megaj_scd, md_cons_state ) +//MACHINE_CONFIG_DERIVED( genesis_scd, megadriv ) + MCFG_FRAGMENT_ADD( md_ntsc ) + MCFG_DEVICE_ADD("segacd", SEGA_SEGACD_JAPAN, 0) + MCFG_CDROM_ADD( "cdrom",scd_cdrom ) + + MCFG_SOFTWARE_LIST_ADD("cd_list","megacdj") +MACHINE_CONFIG_END + + +static MACHINE_CONFIG_DERIVED( genesis_32x_scd, genesis_32x ) + + MCFG_DEVICE_ADD("segacd", SEGA_SEGACD_US, 0) + //MCFG_QUANTUM_PERFECT_CPU("32x_master_sh2") +MACHINE_CONFIG_END + + + /* We need proper names for most of these BIOS ROMs! */ ROM_START( segacd ) ROM_REGION16_BE( 0x400000, "maincpu", ROMREGION_ERASE00 ) @@ -954,21 +1113,21 @@ CONS( 1994, 32xe, 32x, 0, ms_32x_pal, md, md_cons_state, CONS( 1994, 32xj, 32x, 0, ms_32x_jpn, md, md_cons_state, md_jpn, "Sega", "Mega Drive with 32X (Japan, NTSC)", GAME_NOT_WORKING ) // the SegaCD plugged into the expansion port.. -CONS( 1992, segacd, 0, 0, genesis_scd_scd, md, md_cons_state, genesis, "Sega", "Sega CD (USA, NTSC)", GAME_NOT_WORKING ) -CONS( 1993, megacd, segacd, 0, genesis_scd_mcd, md, md_cons_state, md_eur, "Sega", "Mega-CD (Europe, PAL)", GAME_NOT_WORKING ) -CONS( 1991, megacdj, segacd, 0, genesis_scd_mcdj,md, md_cons_state, md_jpn, "Sega", "Mega-CD (Japan, NTSC)", GAME_NOT_WORKING ) // this bios doesn't work with our ram interleave needed by a few games?! -CONS( 1991, megacda, segacd, 0, genesis_scd_mcdj,md, md_cons_state, md_eur, "Sega", "Mega-CD (Asia, PAL)", GAME_NOT_WORKING ) -CONS( 1993, segacd2, 0, 0, genesis_scd_scd, md, md_cons_state, genesis, "Sega", "Sega CD 2 (USA, NTSC)", GAME_NOT_WORKING ) -CONS( 1993, megacd2, segacd2, 0, genesis_scd_mcd, md, md_cons_state, md_eur, "Sega", "Mega-CD 2 (Europe, PAL)", GAME_NOT_WORKING ) -CONS( 1993, megacd2j, segacd2, 0, genesis_scd_mcdj,md, md_cons_state, md_jpn, "Sega", "Mega-CD 2 (Japan, NTSC)", GAME_NOT_WORKING ) +CONS( 1992, segacd, 0, 0, genesis_scd, md, md_cons_state, genesis, "Sega", "Sega CD (USA, NTSC)", GAME_NOT_WORKING ) +CONS( 1993, megacd, segacd, 0, mega_scd, md, md_cons_state, md_eur, "Sega", "Mega-CD (Europe, PAL)", GAME_NOT_WORKING ) +CONS( 1991, megacdj, segacd, 0, megaj_scd, md, md_cons_state, md_jpn, "Sega", "Mega-CD (Japan, NTSC)", GAME_NOT_WORKING ) // this bios doesn't work with our ram interleave needed by a few games?! +CONS( 1991, megacda, segacd, 0, megaj_scd, md, md_cons_state, md_eur, "Sega", "Mega-CD (Asia, PAL)", GAME_NOT_WORKING ) +CONS( 1993, segacd2, 0, 0, genesis_scd, md, md_cons_state, genesis, "Sega", "Sega CD 2 (USA, NTSC)", GAME_NOT_WORKING ) +CONS( 1993, megacd2, segacd2, 0, mega_scd, md, md_cons_state, md_eur, "Sega", "Mega-CD 2 (Europe, PAL)", GAME_NOT_WORKING ) +CONS( 1993, megacd2j, segacd2, 0, megaj_scd, md, md_cons_state, md_jpn, "Sega", "Mega-CD 2 (Japan, NTSC)", GAME_NOT_WORKING ) CONS( 1993, laseract, 0, 0, genesis_scd, md, md_cons_state, genesis, "Pioneer","LaserActive (USA, NTSC)", GAME_NOT_WORKING ) -CONS( 1993, laseractj, laseract, 0, genesis_scd, md, md_cons_state, md_jpn, "Pioneer","LaserActive (Japan, NTSC)", GAME_NOT_WORKING ) +CONS( 1993, laseractj, laseract, 0, megaj_scd, md, md_cons_state, md_jpn, "Pioneer","LaserActive (Japan, NTSC)", GAME_NOT_WORKING ) CONS( 1993, xeye, 0, 0, genesis_scd, md, md_cons_state, genesis, "JVC", "X'eye (USA, NTSC)", GAME_NOT_WORKING ) -CONS( 1992, wmega, xeye, 0, genesis_scd, md, md_cons_state, md_jpn, "Sega", "Wondermega (Japan, NTSC)", GAME_NOT_WORKING ) -CONS( 1993, wmegam2, xeye, 0, genesis_scd, md, md_cons_state, md_jpn, "Victor", "Wondermega M2 (Japan, NTSC)", GAME_NOT_WORKING ) +CONS( 1992, wmega, xeye, 0, megaj_scd, md, md_cons_state, md_jpn, "Sega", "Wondermega (Japan, NTSC)", GAME_NOT_WORKING ) +CONS( 1993, wmegam2, xeye, 0, megaj_scd, md, md_cons_state, md_jpn, "Victor", "Wondermega M2 (Japan, NTSC)", GAME_NOT_WORKING ) CONS( 1994, cdx, 0, 0, genesis_scd, md, md_cons_state, genesis, "Sega", "CDX (USA, NTSC)", GAME_NOT_WORKING ) -CONS( 1994, multmega, cdx, 0, genesis_scd, md, md_cons_state, md_eur, "Sega", "Multi-Mega (Europe, PAL)", GAME_NOT_WORKING ) -CONS( 1994, 32x_scd, 0, 0, genesis_32x_scd, md, md_cons_state, genesis, "Sega", "Sega CD (USA, NTSC, w/32X)", GAME_NOT_WORKING ) +CONS( 1994, multmega, cdx, 0, mega_scd, md, md_cons_state, md_eur, "Sega", "Multi-Mega (Europe, PAL)", GAME_NOT_WORKING ) +CONS( 1994, 32x_scd, 0, 0, genesis_32x_scd, md, md_cons_state, genesis, "Sega", "Sega CD (USA, NTSC, w/32X)", GAME_NOT_WORKING ) // this is a standalone system based on the md-like hardware (same vdp etc.) diff --git a/src/mess/machine/md_eeprom.c b/src/mess/machine/md_eeprom.c index 3f8a5c7b1f4..f1f72500143 100644 --- a/src/mess/machine/md_eeprom.c +++ b/src/mess/machine/md_eeprom.c @@ -213,10 +213,13 @@ READ16_MEMBER(md_std_eeprom_device::read) { if (offset == 0x200000/2) { - m_i2c_mem = i2cmem_sda_read(m_i2cmem); +// m_i2c_mem = i2cmem_sda_read(m_i2cmem); return ~m_i2c_mem & 1; } - return m_rom[offset]; + if (offset < 0x400000/2) + return m_rom[MD_ADDR(offset)]; + else + return 0xffff; } WRITE16_MEMBER(md_std_eeprom_device::write) @@ -234,10 +237,13 @@ READ16_MEMBER(md_eeprom_nbajam_device::read) { if (offset == 0x200000/2) { - m_i2c_mem = i2cmem_sda_read(m_i2cmem); +// m_i2c_mem = i2cmem_sda_read(m_i2cmem); return m_i2c_mem & 1; } - return m_rom[offset]; + if (offset < 0x400000/2) + return m_rom[MD_ADDR(offset)]; + else + return 0xffff; } WRITE16_MEMBER(md_eeprom_nbajam_device::write) @@ -255,10 +261,13 @@ READ16_MEMBER(md_eeprom_nbajamte_device::read) { if (offset == 0x200000/2) { - m_i2c_mem = i2cmem_sda_read(m_i2cmem); +// m_i2c_mem = i2cmem_sda_read(m_i2cmem); return m_i2c_mem & 1; } - return m_rom[offset]; + if (offset < 0x400000/2) + return m_rom[MD_ADDR(offset)]; + else + return 0xffff; } WRITE16_MEMBER(md_eeprom_nbajamte_device::write) @@ -277,10 +286,13 @@ READ16_MEMBER(md_eeprom_cslam_device::read) { if (offset == 0x200000/2) { - m_i2c_mem = i2cmem_sda_read(m_i2cmem); +// m_i2c_mem = i2cmem_sda_read(m_i2cmem); return m_i2c_mem & 1; } - return m_rom[offset]; + if (offset < 0x400000/2) + return m_rom[MD_ADDR(offset)]; + else + return 0xffff; } WRITE16_MEMBER(md_eeprom_cslam_device::write) @@ -299,10 +311,13 @@ READ16_MEMBER(md_eeprom_nflqb_device::read) { if (offset == 0x200000/2) { - m_i2c_mem = i2cmem_sda_read(m_i2cmem); +// m_i2c_mem = i2cmem_sda_read(m_i2cmem); return m_i2c_mem & 1; } - return m_rom[offset]; + if (offset < 0x400000/2) + return m_rom[MD_ADDR(offset)]; + else + return 0xffff; } WRITE16_MEMBER(md_eeprom_nflqb_device::write) @@ -320,10 +335,13 @@ READ16_MEMBER(md_eeprom_nhlpa_device::read) { if (offset == 0x200000/2) { - m_i2c_mem = i2cmem_sda_read(m_i2cmem); +// m_i2c_mem = i2cmem_sda_read(m_i2cmem); return (m_i2c_mem & 1) << 7; } - return m_rom[offset]; + if (offset < 0x400000/2) + return m_rom[MD_ADDR(offset)]; + else + return 0xffff; } WRITE16_MEMBER(md_eeprom_nhlpa_device::write) @@ -341,10 +359,13 @@ READ16_MEMBER(md_eeprom_blara_device::read) { if (offset == 0x380000/2) { - m_i2c_mem = i2cmem_sda_read(m_i2cmem); +// m_i2c_mem = i2cmem_sda_read(m_i2cmem); return (m_i2c_mem & 1) << 7; } - return m_rom[offset]; + if (offset < 0x400000/2) + return m_rom[MD_ADDR(offset)]; + else + return 0xffff; } WRITE16_MEMBER(md_eeprom_blara_device::write) diff --git a/src/mess/machine/md_jcart.c b/src/mess/machine/md_jcart.c index 606563e5f6a..5aadc882a25 100644 --- a/src/mess/machine/md_jcart.c +++ b/src/mess/machine/md_jcart.c @@ -188,7 +188,10 @@ READ16_MEMBER(md_jcart_device::read) return (m_jcart_io_data[0] & 0x40) | joy[0] | (joy[1] << 8); } } - return m_rom[offset]; + if (offset < 0x400000/2) + return m_rom[MD_ADDR(offset)]; + else + return 0xffff; } WRITE16_MEMBER(md_jcart_device::write) @@ -228,7 +231,10 @@ READ16_MEMBER(md_seprom_codemast_device::read) return (m_jcart_io_data[0] & 0x40) | joy[0] | (joy[1] << 8); } } - return m_rom[offset]; + if (offset < 0x400000/2) + return m_rom[MD_ADDR(offset)]; + else + return 0xffff; } WRITE16_MEMBER(md_seprom_codemast_device::write) diff --git a/src/mess/machine/md_rom.c b/src/mess/machine/md_rom.c index 8f8fd3246cc..a6755a9aa80 100644 --- a/src/mess/machine/md_rom.c +++ b/src/mess/machine/md_rom.c @@ -37,6 +37,7 @@ 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_YASECH = &device_creator<md_rom_yasech_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>; @@ -46,7 +47,6 @@ 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>; @@ -71,11 +71,6 @@ md_rom_sram_device::md_rom_sram_device(const machine_config &mconfig, const char { } -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) { @@ -151,6 +146,11 @@ md_rom_elfwor_device::md_rom_elfwor_device(const machine_config &mconfig, const { } +md_rom_yasech_device::md_rom_yasech_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : md_std_rom_device(mconfig, MD_ROM_YASECH, "MD Ya Se Chuan Shuo", 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) { @@ -282,15 +282,17 @@ void md_rom_radica_device::device_start() 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]; + if (offset >= m_nvram_start/2 && offset < m_nvram_end/2 && m_nvram_active) + return m_nvram[offset - m_nvram_start/2]; } - return m_rom[offset/2]; + if (offset < 0x400000/2) + return m_rom[MD_ADDR(offset)]; + else + return 0xffff; } WRITE16_MEMBER(md_rom_sram_device::write) @@ -299,16 +301,14 @@ WRITE16_MEMBER(md_rom_sram_device::write) // 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; + if (offset >= m_nvram_start/2 && offset <= m_nvram_end/2 && 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) + if (offset == 0xf0/2) { /* 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); @@ -322,58 +322,29 @@ WRITE16_MEMBER(md_rom_sram_device::write_a13) } /*------------------------------------------------- - 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]; + if (offset >= m_nvram_start/2 && offset < m_nvram_end/2 && m_nvram_active) + return m_nvram[offset - m_nvram_start/2]; + if (offset < 0x400000/2) + return m_rom[MD_ADDR(offset)]; + else + return 0xffff; } WRITE16_MEMBER(md_rom_fram_device::write_a13) { - offset <<= 1; - if (offset == 0xf) + if (offset == 0xf0/2) m_nvram_active = BIT(data, 0); } READ16_MEMBER(md_rom_fram_device::read_a13) { - if (offset == 0xf) + if (offset == 0xf0/2) return m_nvram_active; else return 0xffff; @@ -564,6 +535,19 @@ READ16_MEMBER(md_rom_smouse_device::read) } /*------------------------------------------------- + YA SE CHUAN SHUO + -------------------------------------------------*/ + +READ16_MEMBER(md_rom_yasech_device::read) +{ + if (offset == 0x400000/2) return 0x6300; + if (offset == 0x400002/2) return 0x9800; + if (offset == 0x400004/2) return 0xc900; + if (offset == 0x400006/2) return 0x1800; + return m_rom[offset]; +} + +/*------------------------------------------------- KOF98 -------------------------------------------------*/ diff --git a/src/mess/machine/md_rom.h b/src/mess/machine/md_rom.h index 1ad1b9c4fe8..fd7b03d0901 100644 --- a/src/mess/machine/md_rom.h +++ b/src/mess/machine/md_rom.h @@ -3,7 +3,6 @@ #include "machine/md_slot.h" - //************************************************************************** // TYPE DEFINITIONS //************************************************************************** @@ -23,7 +22,7 @@ public: virtual void device_config_complete() { m_shortname = "md_std_rom"; } // reading and writing - virtual DECLARE_READ16_MEMBER(read) { return m_rom[offset]; }; + virtual DECLARE_READ16_MEMBER(read) { if (offset < 0x400000/2) return m_rom[MD_ADDR(offset)]; else return 0xffff; }; virtual DECLARE_WRITE16_MEMBER(write) { }; }; @@ -44,23 +43,6 @@ public: 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 @@ -170,6 +152,21 @@ public: virtual DECLARE_READ16_MEMBER(read); }; +// ======================> md_rom_yasech_device + +class md_rom_yasech_device : public md_std_rom_device +{ +public: + // construction/destruction + md_rom_yasech_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_yasech"; } + + // reading and writing + virtual DECLARE_READ16_MEMBER(read); +}; + // ======================> md_rom_kof98_device class md_rom_kof98_device : public md_std_rom_device @@ -469,10 +466,10 @@ private: 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_YASECH; extern const device_type MD_ROM_KOF98; extern const device_type MD_ROM_KOF99; extern const device_type MD_ROM_LION2; diff --git a/src/mess/machine/md_sk.c b/src/mess/machine/md_sk.c index dbaf0822f69..e2b38b7da47 100644 --- a/src/mess/machine/md_sk.c +++ b/src/mess/machine/md_sk.c @@ -52,7 +52,10 @@ 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]; + if (offset < 0x400000/2) + return m_rom[MD_ADDR(offset)]; + else + return 0xffff; } WRITE16_MEMBER(md_rom_sk_device::write) diff --git a/src/mess/machine/md_slot.c b/src/mess/machine/md_slot.c index 7b0fec66188..2ab615dddd5 100644 --- a/src/mess/machine/md_slot.c +++ b/src/mess/machine/md_slot.c @@ -16,11 +16,29 @@ 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 + Cart Mirroring (based Eke's research) + + MD Cartridge area is mapped to $000000-$3fffff: when accessing ROM, 68k address lines A1 to A21 can be + used by the internal cartridge hardware to decode full 4MB address range. + Depending on ROM total size and additional decoding hardware, some address lines might be ignored, + resulting in ROM mirroring. + + Cartridges typically use either 8-bits (x2) or 16-bits (x1, x2) Mask ROM chips, each chip size is a + factor of 2 bytes. + When one chip ROM1 of size 2^N is present, it is generally mirrored each 2^N bytes so that read access + to cart area sees the sequence ROM1,ROM1,ROM1,... (up to 4MB) + When two chips ROM1 & ROM2 are present and the whole size is 2^N, then the block ROM1+ROM2 is mirrored + in the cart area, and reads see the sequence ROM1+ROM2,ROM1+ROM2,... (up to 4MB) + When two chips ROM1 & ROM2 are present and the whole size is not 2^N (e.g. because ROM1 and ROM2 have + different sizes), then the area between the end of ROM2 and next power 2^N is generally ignored, and + reads see the sequence ROM1,ROM2,XXXX,ROM1,ROM2,XXXX... (up to 4MB) + + At loading time we first compute first power 2^N larger than cart size (see get_padded_size function), + we allocate such a size for ROM and we fill of 0xff the area between end of dump and 2^N. + Then we handle mirroring by creating a rom_bank_map[] (see rom_map_setup function) which points each + access in 0x000000-0x400000 to the correct 64K ROM bank. + ***********************************************************************************************************/ @@ -89,6 +107,57 @@ void device_md_cart_interface::nvram_alloc(running_machine &machine, size_t size } } +//------------------------------------------------- +// rom_map_setup - setup map of rom banks in 64K +// blocks, so to simplify ROM mirroring +//------------------------------------------------- + +void device_md_cart_interface::rom_map_setup(UINT32 size) +{ + int i; + // setup the rom_bank_map array to faster ROM read + for (i = 0; i < size / 0x10000; i++) + rom_bank_map[i] = i; + + // fill up remaining blocks with mirrors + while (i % 64) + { + int j = 0, repeat_banks; + while ((i % (64 >> j)) && j < 7) + j++; + repeat_banks = i % (64 >> (j - 1)); + for (int k = 0; k < repeat_banks; k++) + rom_bank_map[i + k] = rom_bank_map[i + k - repeat_banks]; + i += repeat_banks; + } + +// check bank map! +// for (i = 0; i < 64; i++) +// { +// printf("bank %3d = %3d\t", i, rom_bank_map[i]); +// if ((i%8) == 7) +// printf("\n"); +// } +} + +//------------------------------------------------- +// +// +//------------------------------------------------- + +UINT32 device_md_cart_interface::get_padded_size(UINT32 size) +{ + UINT32 pad_size = 0x10000; + while (size > pad_size) + pad_size <<= 1; + + if (pad_size < 0x800000 && size < pad_size) + return pad_size; + else + return size; +} + + //************************************************************************** // LIVE DEVICE @@ -170,6 +239,7 @@ static const md_slot slot_list[] = { SEGA_SRAM, "rom_sram" }, { SEGA_FRAM, "rom_fram" }, + { HARDBALL95, "rom_hardbl95" }, { BEGGAR, "rom_beggar"}, { SEGA_EEPROM, "rom_eeprom" }, @@ -294,15 +364,26 @@ int base_md_cart_slot_device::load_list() UINT32 length = get_software_region_length("rom"); const char *slot_name; - m_cart->rom_alloc(machine(), length); + // if cart size is not (2^n * 64K), the system will see anyway that size so we need to alloc a bit more space + length = m_cart->get_padded_size(length); + + m_cart->rom_alloc(machine(), length); ROM = m_cart->get_rom_base(); - memcpy(ROM, get_software_region("rom"), length); + memcpy(ROM, get_software_region("rom"), get_software_region_length("rom")); + + // if we allocated a ROM larger that the file (e.g. due to uneven cart size), set remaining space to 0xff + if (length > get_software_region_length("rom")) + memset(ROM + get_software_region_length("rom")/2, 0xffff, (length - get_software_region_length("rom"))/2); if ((slot_name = get_feature("slot")) == NULL) m_type = SEGA_STD; else m_type = md_get_pcb_id(slot_name); - + + // handle mirroring of ROM, unless it's SSF2 or Pier Solar + if (m_type != SSF2 && m_type != PSOLAR) + m_cart->rom_map_setup(length); + return IMAGE_INIT_PASS; } @@ -382,7 +463,7 @@ static int genesis_is_SMD(unsigned char *buf,unsigned int len) int base_md_cart_slot_device::load_nonlist() { unsigned char *ROM, *tmpROM; - UINT32 len = length(); + UINT32 len = m_cart->get_padded_size(length()); // if cart size is not (2^n * 64K), the system will see anyway that size so we need to alloc a bit more space // 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); @@ -428,10 +509,18 @@ int base_md_cart_slot_device::load_nonlist() } global_free(tmpROM); - + + // if we allocated a ROM larger that the file (e.g. due to uneven cart size), set remaining space to 0xff + if (len > length()) + memset(m_cart->get_rom_base() + length()/2, 0xffff, (len - length())/2); + // STEP 2: determine the cart type (to deal with pirate mappers & eeprom) - m_type = get_cart_type(ROM, len); + m_type = get_cart_type(ROM, length()); + // handle mirroring of ROM, unless it's SSF2 or Pier Solar + if (m_type != SSF2 && m_type != PSOLAR) + m_cart->rom_map_setup(len); + #ifdef LSB_FIRST unsigned char fliptemp; // is this really needed nowadays? @@ -577,8 +666,15 @@ void base_md_cart_slot_device::setup_nvram() 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 HARDBALL95: + m_cart->m_nvram_start = 0x300000; + 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); + m_cart->m_nvram_active = 1; + m_cart->m_nvram_handlers_installed = 1; + break; case BEGGAR: m_cart->m_nvram_start = 0x400000; m_cart->m_nvram_end = m_cart->m_nvram_start + 0xffff; diff --git a/src/mess/machine/md_slot.h b/src/mess/machine/md_slot.h index fca02970d83..a51b3f5bc01 100644 --- a/src/mess/machine/md_slot.h +++ b/src/mess/machine/md_slot.h @@ -5,6 +5,7 @@ TYPE DEFINITIONS ***************************************************************************/ +#define MD_ADDR(a) rom_bank_map[(a / 0x10000) & 0x3f] * 0x10000 + (a & 0xffff) /* PCB */ enum @@ -19,6 +20,7 @@ enum // Cart + NVRAM SEGA_SRAM, SEGA_FRAM, + HARDBALL95, /* Hardball 95 uses different sram start address */ BEGGAR, /* Xin Qigai Wangzi uses different sram start address and has no valid header */ // EEPROM @@ -106,6 +108,9 @@ public: virtual UINT32 get_rom_size() { return m_rom_size; }; virtual UINT32 get_nvram_size() { return m_nvram_size; }; + virtual void rom_map_setup(UINT32 size); + virtual UINT32 get_padded_size(UINT32 size); + int m_nvram_start, m_nvram_end; int m_nvram_active, m_nvram_readonly; @@ -119,6 +124,8 @@ public: UINT16 *m_nvram; UINT32 m_rom_size; UINT32 m_nvram_size; + + UINT8 rom_bank_map[128]; // 64K chunks of rom }; |