trunk/src/mame/machine/megadriv.c
| r20808 | r20809 | |
| 22 | 22 | |
| 23 | 23 | |
| 24 | 24 | #include "emu.h" |
| 25 | | #include "coreutil.h" |
| 26 | | #include "cpu/m68000/m68000.h" |
| 27 | | #include "cpu/sh2/sh2.h" |
| 28 | | #include "cpu/sh2/sh2comn.h" |
| 29 | | #include "cpu/z80/z80.h" |
| 30 | | #include "sound/2612intf.h" |
| 31 | | |
| 32 | | #include "sound/dac.h" |
| 33 | | #include "sound/sn76496.h" |
| 34 | | |
| 35 | | #include "imagedev/chd_cd.h" |
| 36 | | #include "imagedev/cartslot.h" |
| 37 | | #include "formats/imageutl.h" |
| 38 | | |
| 39 | 25 | #include "includes/megadriv.h" |
| 40 | | #include "machine/nvram.h" |
| 41 | | #include "cpu/ssp1601/ssp1601.h" |
| 42 | 26 | |
| 43 | | #include "machine/megavdp.h" |
| 44 | 27 | |
| 45 | 28 | |
| 46 | 29 | MACHINE_CONFIG_EXTERN( megadriv ); |
| r20808 | r20809 | |
| 880 | 863 | AM_RANGE(0xe00000, 0xe0ffff) AM_RAM AM_MIRROR(0x1f0000) AM_SHARE("megadrive_ram") |
| 881 | 864 | ADDRESS_MAP_END |
| 882 | 865 | |
| 883 | | MACHINE_CONFIG_DERIVED( md_bootleg, megadriv ) |
| 866 | MACHINE_CONFIG_START( md_bootleg, md_base_state ) |
| 867 | MCFG_FRAGMENT_ADD( md_ntsc ) |
| 884 | 868 | |
| 885 | 869 | MCFG_CPU_MODIFY("maincpu") |
| 886 | 870 | MCFG_CPU_PROGRAM_MAP(md_bootleg_map) |
| r20808 | r20809 | |
| 1160 | 1144 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker",0.25) /* 3.58 MHz */ |
| 1161 | 1145 | MACHINE_CONFIG_END |
| 1162 | 1146 | |
| 1163 | | MACHINE_CONFIG_START( megadriv, md_base_state ) |
| 1164 | | MCFG_FRAGMENT_ADD(md_ntsc) |
| 1165 | | MACHINE_CONFIG_END |
| 1166 | | |
| 1167 | 1147 | /************ PAL hardware has a different master clock *************/ |
| 1168 | 1148 | |
| 1169 | 1149 | MACHINE_CONFIG_FRAGMENT( md_pal ) |
| r20808 | r20809 | |
| 1215 | 1195 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker",0.25) /* 3.58 MHz */ |
| 1216 | 1196 | MACHINE_CONFIG_END |
| 1217 | 1197 | |
| 1218 | | MACHINE_CONFIG_START( megadpal, md_base_state ) |
| 1219 | | MCFG_FRAGMENT_ADD(md_pal) |
| 1220 | | MACHINE_CONFIG_END |
| 1221 | 1198 | |
| 1222 | | |
| 1223 | | |
| 1224 | | |
| 1225 | | MACHINE_CONFIG_DERIVED( genesis_32x, megadriv ) |
| 1226 | | |
| 1227 | | MCFG_DEVICE_ADD("sega32x", SEGA_32X_NTSC, 0) |
| 1228 | | |
| 1229 | | // we need to remove and re-add the sound system because the balance is different |
| 1230 | | // due to MAME / MESS having severe issues if the dac output is > 0.40? (sound is corrupted even if DAC is slient?!) |
| 1231 | | MCFG_DEVICE_REMOVE("ymsnd") |
| 1232 | | MCFG_DEVICE_REMOVE("snsnd") |
| 1233 | | |
| 1234 | | MCFG_SOUND_ADD("ymsnd", YM2612, MASTER_CLOCK_NTSC/7) |
| 1235 | | MCFG_SOUND_ROUTE(0, "lspeaker", (0.50)/2) |
| 1236 | | MCFG_SOUND_ROUTE(1, "rspeaker", (0.50)/2) |
| 1237 | | |
| 1238 | | /* sound hardware */ |
| 1239 | | MCFG_SOUND_ADD("snsnd", SEGAPSG, MASTER_CLOCK_NTSC/15) |
| 1240 | | MCFG_SOUND_CONFIG(psg_intf) |
| 1241 | | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", (0.25)/2) |
| 1242 | | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", (0.25)/2) |
| 1243 | | |
| 1244 | | MACHINE_CONFIG_END |
| 1245 | | |
| 1246 | | |
| 1247 | | MACHINE_CONFIG_DERIVED( genesis_32x_pal, megadpal ) |
| 1248 | | |
| 1249 | | MCFG_DEVICE_ADD("sega32x", SEGA_32X_PAL, 0) |
| 1250 | | |
| 1251 | | // we need to remove and re-add the sound system because the balance is different |
| 1252 | | // due to MAME / MESS having severe issues if the dac output is > 0.40? (sound is corrupted even if DAC is slient?!) |
| 1253 | | MCFG_DEVICE_REMOVE("ymsnd") |
| 1254 | | MCFG_DEVICE_REMOVE("snsnd") |
| 1255 | | |
| 1256 | | MCFG_SOUND_ADD("ymsnd", YM2612, MASTER_CLOCK_NTSC/7) |
| 1257 | | MCFG_SOUND_ROUTE(0, "lspeaker", (0.50)/2) |
| 1258 | | MCFG_SOUND_ROUTE(1, "rspeaker", (0.50)/2) |
| 1259 | | |
| 1260 | | /* sound hardware */ |
| 1261 | | MCFG_SOUND_ADD("snsnd", SEGAPSG, MASTER_CLOCK_NTSC/15) |
| 1262 | | MCFG_SOUND_CONFIG(psg_intf) |
| 1263 | | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", (0.25)/2) |
| 1264 | | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", (0.25)/2) |
| 1265 | | |
| 1266 | | MACHINE_CONFIG_END |
| 1267 | | |
| 1268 | | |
| 1269 | | |
| 1270 | | /******* 32X image loading *******/ |
| 1271 | | |
| 1272 | | // FIXME: non-softlist loading should keep using ROM_CART_LOAD in the ROM definitions, |
| 1273 | | // once we better integrate softlist with the old loading procedures |
| 1274 | | DEVICE_IMAGE_LOAD_MEMBER( md_base_state, _32x_cart ) |
| 1275 | | { |
| 1276 | | UINT32 length; |
| 1277 | | UINT8 *temp_copy; |
| 1278 | | UINT16 *ROM16; |
| 1279 | | UINT32 *ROM32; |
| 1280 | | int i; |
| 1281 | | |
| 1282 | | if (image.software_entry() == NULL) |
| 1283 | | { |
| 1284 | | length = image.length(); |
| 1285 | | temp_copy = auto_alloc_array(image.device().machine(), UINT8, length); |
| 1286 | | image.fread(temp_copy, length); |
| 1287 | | } |
| 1288 | | else |
| 1289 | | { |
| 1290 | | length = image.get_software_region_length("rom"); |
| 1291 | | temp_copy = auto_alloc_array(image.device().machine(), UINT8, length); |
| 1292 | | memcpy(temp_copy, image.get_software_region("rom"), length); |
| 1293 | | } |
| 1294 | | |
| 1295 | | /* Copy the cart image in the locations the driver expects */ |
| 1296 | | // Notice that, by using pick_integer, we are sure the code works on both LE and BE machines |
| 1297 | | ROM16 = (UINT16 *) image.device().machine().root_device().memregion("gamecart")->base(); |
| 1298 | | for (i = 0; i < length; i += 2) |
| 1299 | | ROM16[i / 2] = pick_integer_be(temp_copy, i, 2); |
| 1300 | | |
| 1301 | | ROM32 = (UINT32 *) image.device().machine().root_device().memregion("gamecart_sh2")->base(); |
| 1302 | | for (i = 0; i < length; i += 4) |
| 1303 | | ROM32[i / 4] = pick_integer_be(temp_copy, i, 4); |
| 1304 | | |
| 1305 | | ROM16 = (UINT16 *) image.device().machine().root_device().memregion("maincpu")->base(); |
| 1306 | | for (i = 0x00; i < length; i += 2) |
| 1307 | | ROM16[i / 2] = pick_integer_be(temp_copy, i, 2); |
| 1308 | | |
| 1309 | | auto_free(image.device().machine(), temp_copy); |
| 1310 | | |
| 1311 | | return IMAGE_INIT_PASS; |
| 1312 | | } |
| 1313 | | |
| 1314 | | |
| 1315 | | MACHINE_CONFIG_FRAGMENT( _32x_cartslot ) |
| 1316 | | MCFG_CARTSLOT_ADD("cart") |
| 1317 | | MCFG_CARTSLOT_EXTENSION_LIST("32x,bin") |
| 1318 | | MCFG_CARTSLOT_MANDATORY |
| 1319 | | MCFG_CARTSLOT_INTERFACE("_32x_cart") |
| 1320 | | MCFG_CARTSLOT_LOAD(md_base_state, _32x_cart) |
| 1321 | | MCFG_SOFTWARE_LIST_ADD("cart_list","32x") |
| 1322 | | MACHINE_CONFIG_END |
| 1323 | | |
| 1324 | | |
| 1325 | | |
| 1326 | | struct cdrom_interface scd_cdrom = |
| 1327 | | { |
| 1328 | | "scd_cdrom", |
| 1329 | | NULL |
| 1330 | | }; |
| 1331 | | |
| 1332 | | MACHINE_CONFIG_DERIVED( genesis_scd, megadriv ) |
| 1333 | | MCFG_DEVICE_ADD("segacd", SEGA_SEGACD_US, 0) |
| 1334 | | MCFG_CDROM_ADD( "cdrom",scd_cdrom ) |
| 1335 | | MACHINE_CONFIG_END |
| 1336 | | |
| 1337 | | /* Different Softlists for different regions (for now at least) */ |
| 1338 | | MACHINE_CONFIG_DERIVED( genesis_scd_scd, genesis_scd ) |
| 1339 | | MCFG_SOFTWARE_LIST_ADD("cd_list","segacd") |
| 1340 | | MACHINE_CONFIG_END |
| 1341 | | |
| 1342 | | MACHINE_CONFIG_DERIVED( genesis_scd_mcd, genesis_scd ) |
| 1343 | | MCFG_SOFTWARE_LIST_ADD("cd_list","megacd") |
| 1344 | | MACHINE_CONFIG_END |
| 1345 | | |
| 1346 | | MACHINE_CONFIG_DERIVED( genesis_scd_mcdj, genesis_scd ) |
| 1347 | | MCFG_SOFTWARE_LIST_ADD("cd_list","megacdj") |
| 1348 | | MACHINE_CONFIG_END |
| 1349 | | |
| 1350 | | MACHINE_CONFIG_DERIVED( genesis_32x_scd, genesis_32x ) |
| 1351 | | |
| 1352 | | MCFG_DEVICE_ADD("segacd", SEGA_SEGACD_US, 0) |
| 1353 | | //MCFG_QUANTUM_PERFECT_CPU("32x_master_sh2") |
| 1354 | | MACHINE_CONFIG_END |
| 1355 | | |
| 1356 | | |
| 1357 | | |
| 1358 | | |
| 1359 | 1199 | static int megadriv_tas_callback(device_t *device) |
| 1360 | 1200 | { |
| 1361 | 1201 | return 0; // writeback not allowed |
trunk/src/mess/machine/md_slot.c
| r20808 | r20809 | |
| 16 | 16 | md_sk: Sonic & Knuckles pass-thorugh cart (enables a second slot to mount any other cart) |
| 17 | 17 | md_stm95: cart + STM95 EEPROM (e.g. Pier Solar) |
| 18 | 18 | |
| 19 | | TODO: currently read access in 0x000000-0x7fffff are not masked (so we assume that no game attempts to |
| 20 | | read beyond its ROM size). A regression test is pending to identify which games need this and mirror |
| 21 | | them properly (Eke's doc states ROM data should be mirrored), but none of the ~120 games I tried |
| 22 | | attempted that and a testcase would be appreciated |
| 23 | 19 | |
| 20 | Cart Mirroring (based Eke's research) |
| 21 | |
| 22 | MD Cartridge area is mapped to $000000-$3fffff: when accessing ROM, 68k address lines A1 to A21 can be |
| 23 | used by the internal cartridge hardware to decode full 4MB address range. |
| 24 | Depending on ROM total size and additional decoding hardware, some address lines might be ignored, |
| 25 | resulting in ROM mirroring. |
| 26 | |
| 27 | Cartridges typically use either 8-bits (x2) or 16-bits (x1, x2) Mask ROM chips, each chip size is a |
| 28 | factor of 2 bytes. |
| 29 | When one chip ROM1 of size 2^N is present, it is generally mirrored each 2^N bytes so that read access |
| 30 | to cart area sees the sequence ROM1,ROM1,ROM1,... (up to 4MB) |
| 31 | When two chips ROM1 & ROM2 are present and the whole size is 2^N, then the block ROM1+ROM2 is mirrored |
| 32 | in the cart area, and reads see the sequence ROM1+ROM2,ROM1+ROM2,... (up to 4MB) |
| 33 | When two chips ROM1 & ROM2 are present and the whole size is not 2^N (e.g. because ROM1 and ROM2 have |
| 34 | different sizes), then the area between the end of ROM2 and next power 2^N is generally ignored, and |
| 35 | reads see the sequence ROM1,ROM2,XXXX,ROM1,ROM2,XXXX... (up to 4MB) |
| 36 | |
| 37 | At loading time we first compute first power 2^N larger than cart size (see get_padded_size function), |
| 38 | we allocate such a size for ROM and we fill of 0xff the area between end of dump and 2^N. |
| 39 | Then we handle mirroring by creating a rom_bank_map[] (see rom_map_setup function) which points each |
| 40 | access in 0x000000-0x400000 to the correct 64K ROM bank. |
| 41 | |
| 24 | 42 | ***********************************************************************************************************/ |
| 25 | 43 | |
| 26 | 44 | |
| r20808 | r20809 | |
| 89 | 107 | } |
| 90 | 108 | } |
| 91 | 109 | |
| 110 | //------------------------------------------------- |
| 111 | // rom_map_setup - setup map of rom banks in 64K |
| 112 | // blocks, so to simplify ROM mirroring |
| 113 | //------------------------------------------------- |
| 92 | 114 | |
| 115 | void device_md_cart_interface::rom_map_setup(UINT32 size) |
| 116 | { |
| 117 | int i; |
| 118 | // setup the rom_bank_map array to faster ROM read |
| 119 | for (i = 0; i < size / 0x10000; i++) |
| 120 | rom_bank_map[i] = i; |
| 121 | |
| 122 | // fill up remaining blocks with mirrors |
| 123 | while (i % 64) |
| 124 | { |
| 125 | int j = 0, repeat_banks; |
| 126 | while ((i % (64 >> j)) && j < 7) |
| 127 | j++; |
| 128 | repeat_banks = i % (64 >> (j - 1)); |
| 129 | for (int k = 0; k < repeat_banks; k++) |
| 130 | rom_bank_map[i + k] = rom_bank_map[i + k - repeat_banks]; |
| 131 | i += repeat_banks; |
| 132 | } |
| 133 | |
| 134 | // check bank map! |
| 135 | // for (i = 0; i < 64; i++) |
| 136 | // { |
| 137 | // printf("bank %3d = %3d\t", i, rom_bank_map[i]); |
| 138 | // if ((i%8) == 7) |
| 139 | // printf("\n"); |
| 140 | // } |
| 141 | } |
| 142 | |
| 143 | //------------------------------------------------- |
| 144 | // |
| 145 | // |
| 146 | //------------------------------------------------- |
| 147 | |
| 148 | UINT32 device_md_cart_interface::get_padded_size(UINT32 size) |
| 149 | { |
| 150 | UINT32 pad_size = 0x10000; |
| 151 | while (size > pad_size) |
| 152 | pad_size <<= 1; |
| 153 | |
| 154 | if (pad_size < 0x800000 && size < pad_size) |
| 155 | return pad_size; |
| 156 | else |
| 157 | return size; |
| 158 | } |
| 159 | |
| 160 | |
| 161 | |
| 93 | 162 | //************************************************************************** |
| 94 | 163 | // LIVE DEVICE |
| 95 | 164 | //************************************************************************** |
| r20808 | r20809 | |
| 170 | 239 | |
| 171 | 240 | { SEGA_SRAM, "rom_sram" }, |
| 172 | 241 | { SEGA_FRAM, "rom_fram" }, |
| 242 | { HARDBALL95, "rom_hardbl95" }, |
| 173 | 243 | { BEGGAR, "rom_beggar"}, |
| 174 | 244 | |
| 175 | 245 | { SEGA_EEPROM, "rom_eeprom" }, |
| r20808 | r20809 | |
| 294 | 364 | UINT32 length = get_software_region_length("rom"); |
| 295 | 365 | const char *slot_name; |
| 296 | 366 | |
| 297 | | m_cart->rom_alloc(machine(), length); |
| 367 | // if cart size is not (2^n * 64K), the system will see anyway that size so we need to alloc a bit more space |
| 368 | length = m_cart->get_padded_size(length); |
| 369 | |
| 370 | m_cart->rom_alloc(machine(), length); |
| 298 | 371 | ROM = m_cart->get_rom_base(); |
| 299 | | memcpy(ROM, get_software_region("rom"), length); |
| 372 | memcpy(ROM, get_software_region("rom"), get_software_region_length("rom")); |
| 373 | |
| 374 | // if we allocated a ROM larger that the file (e.g. due to uneven cart size), set remaining space to 0xff |
| 375 | if (length > get_software_region_length("rom")) |
| 376 | memset(ROM + get_software_region_length("rom")/2, 0xffff, (length - get_software_region_length("rom"))/2); |
| 300 | 377 | |
| 301 | 378 | if ((slot_name = get_feature("slot")) == NULL) |
| 302 | 379 | m_type = SEGA_STD; |
| 303 | 380 | else |
| 304 | 381 | m_type = md_get_pcb_id(slot_name); |
| 305 | | |
| 382 | |
| 383 | // handle mirroring of ROM, unless it's SSF2 or Pier Solar |
| 384 | if (m_type != SSF2 && m_type != PSOLAR) |
| 385 | m_cart->rom_map_setup(length); |
| 386 | |
| 306 | 387 | return IMAGE_INIT_PASS; |
| 307 | 388 | } |
| 308 | 389 | |
| r20808 | r20809 | |
| 382 | 463 | int base_md_cart_slot_device::load_nonlist() |
| 383 | 464 | { |
| 384 | 465 | unsigned char *ROM, *tmpROM; |
| 385 | | UINT32 len = length(); |
| 466 | 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 |
| 386 | 467 | |
| 387 | 468 | // this contains an hack for SSF2: its current bankswitch code needs larger rom space to work |
| 388 | 469 | m_cart->rom_alloc(machine(), (len == 0x500000) ? 0x900000 : len); |
| r20808 | r20809 | |
| 428 | 509 | } |
| 429 | 510 | |
| 430 | 511 | global_free(tmpROM); |
| 431 | | |
| 512 | |
| 513 | // if we allocated a ROM larger that the file (e.g. due to uneven cart size), set remaining space to 0xff |
| 514 | if (len > length()) |
| 515 | memset(m_cart->get_rom_base() + length()/2, 0xffff, (len - length())/2); |
| 516 | |
| 432 | 517 | // STEP 2: determine the cart type (to deal with pirate mappers & eeprom) |
| 433 | | m_type = get_cart_type(ROM, len); |
| 518 | m_type = get_cart_type(ROM, length()); |
| 434 | 519 | |
| 520 | // handle mirroring of ROM, unless it's SSF2 or Pier Solar |
| 521 | if (m_type != SSF2 && m_type != PSOLAR) |
| 522 | m_cart->rom_map_setup(len); |
| 523 | |
| 435 | 524 | #ifdef LSB_FIRST |
| 436 | 525 | unsigned char fliptemp; |
| 437 | 526 | // is this really needed nowadays? |
| r20808 | r20809 | |
| 577 | 666 | m_cart->m_nvram_active = 1; |
| 578 | 667 | m_cart->m_nvram_handlers_installed = 1; |
| 579 | 668 | break; |
| 580 | | |
| 669 | |
| 581 | 670 | // These types might come from both (pending proper id routines) |
| 671 | case HARDBALL95: |
| 672 | m_cart->m_nvram_start = 0x300000; |
| 673 | m_cart->m_nvram_end = m_cart->m_nvram_start + get_software_region_length("sram") - 1; |
| 674 | m_cart->nvram_alloc(machine(), m_cart->m_nvram_end - m_cart->m_nvram_start + 1); |
| 675 | m_cart->m_nvram_active = 1; |
| 676 | m_cart->m_nvram_handlers_installed = 1; |
| 677 | break; |
| 582 | 678 | case BEGGAR: |
| 583 | 679 | m_cart->m_nvram_start = 0x400000; |
| 584 | 680 | m_cart->m_nvram_end = m_cart->m_nvram_start + 0xffff; |
trunk/src/mess/machine/md_rom.c
| r20808 | r20809 | |
| 37 | 37 | const device_type MD_ROM_SOULB = &device_creator<md_rom_soulb_device>; |
| 38 | 38 | const device_type MD_ROM_CHINF3 = &device_creator<md_rom_chinf3_device>; |
| 39 | 39 | const device_type MD_ROM_ELFWOR = &device_creator<md_rom_elfwor_device>; |
| 40 | const device_type MD_ROM_YASECH = &device_creator<md_rom_yasech_device>; |
| 40 | 41 | const device_type MD_ROM_LION2 = &device_creator<md_rom_lion2_device>; |
| 41 | 42 | const device_type MD_ROM_LION3 = &device_creator<md_rom_lion3_device>; |
| 42 | 43 | const device_type MD_ROM_MCPIR = &device_creator<md_rom_mcpirate_device>; |
| r20808 | r20809 | |
| 46 | 47 | const device_type MD_ROM_SQUIR = &device_creator<md_rom_squir_device>; |
| 47 | 48 | const device_type MD_ROM_TOPF = &device_creator<md_rom_topf_device>; |
| 48 | 49 | const device_type MD_ROM_RADICA = &device_creator<md_rom_radica_device>; |
| 49 | | const device_type MD_ROM_BEGGAR = &device_creator<md_rom_beggar_device>; |
| 50 | 50 | |
| 51 | 51 | // below ones are currently unused, because the protection is patched out |
| 52 | 52 | const device_type MD_ROM_MULAN = &device_creator<md_std_rom_device>; |
| r20808 | r20809 | |
| 71 | 71 | { |
| 72 | 72 | } |
| 73 | 73 | |
| 74 | | md_rom_beggar_device::md_rom_beggar_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 75 | | : md_std_rom_device(mconfig, MD_ROM_BEGGAR, "MD Xin Qigai Wangzi", tag, owner, clock) |
| 76 | | { |
| 77 | | } |
| 78 | | |
| 79 | 74 | md_rom_fram_device::md_rom_fram_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 80 | 75 | : md_std_rom_device(mconfig, MD_ROM_FRAM, "MD Standard cart + FRAM", tag, owner, clock) |
| 81 | 76 | { |
| r20808 | r20809 | |
| 151 | 146 | { |
| 152 | 147 | } |
| 153 | 148 | |
| 149 | md_rom_yasech_device::md_rom_yasech_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 150 | : md_std_rom_device(mconfig, MD_ROM_YASECH, "MD Ya Se Chuan Shuo", tag, owner, clock) |
| 151 | { |
| 152 | } |
| 153 | |
| 154 | 154 | md_rom_lion2_device::md_rom_lion2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 155 | 155 | : md_std_rom_device(mconfig, MD_ROM_LION2, "MD Lion King 2", tag, owner, clock) |
| 156 | 156 | { |
| r20808 | r20809 | |
| 282 | 282 | |
| 283 | 283 | READ16_MEMBER(md_rom_sram_device::read) |
| 284 | 284 | { |
| 285 | | offset <<= 1; |
| 286 | 285 | // since a lot of generic carts ends up here if loaded from fullpath |
| 287 | 286 | // we access nvram only if m_nvram_handlers_installed has been turned on |
| 288 | 287 | if (m_nvram_handlers_installed) |
| 289 | 288 | { |
| 290 | | if (offset >= m_nvram_start && offset < m_nvram_end && m_nvram_active) |
| 291 | | return m_nvram[(offset - m_nvram_start)/2]; |
| 289 | if (offset >= m_nvram_start/2 && offset < m_nvram_end/2 && m_nvram_active) |
| 290 | return m_nvram[offset - m_nvram_start/2]; |
| 292 | 291 | } |
| 293 | | return m_rom[offset/2]; |
| 292 | if (offset < 0x400000/2) |
| 293 | return m_rom[MD_ADDR(offset)]; |
| 294 | else |
| 295 | return 0xffff; |
| 294 | 296 | } |
| 295 | 297 | |
| 296 | 298 | WRITE16_MEMBER(md_rom_sram_device::write) |
| r20808 | r20809 | |
| 299 | 301 | // we access nvram only if m_nvram_handlers_installed has been turned on |
| 300 | 302 | if (m_nvram_handlers_installed) |
| 301 | 303 | { |
| 302 | | offset <<= 1; |
| 303 | | if (offset >= m_nvram_start && offset <= m_nvram_end && m_nvram_active && !m_nvram_readonly) |
| 304 | | m_nvram[(offset - m_nvram_start)/2] = data; |
| 304 | if (offset >= m_nvram_start/2 && offset <= m_nvram_end/2 && m_nvram_active && !m_nvram_readonly) |
| 305 | m_nvram[offset - m_nvram_start/2] = data; |
| 305 | 306 | } |
| 306 | 307 | } |
| 307 | 308 | |
| 308 | 309 | WRITE16_MEMBER(md_rom_sram_device::write_a13) |
| 309 | 310 | { |
| 310 | | offset <<= 1; |
| 311 | | if (offset == 0xf) |
| 311 | if (offset == 0xf0/2) |
| 312 | 312 | { |
| 313 | 313 | /* unsure if this is actually supposed to toggle or just switch on? yet to encounter game that uses this */ |
| 314 | 314 | m_nvram_active = BIT(data, 0); |
| r20808 | r20809 | |
| 322 | 322 | } |
| 323 | 323 | |
| 324 | 324 | /*------------------------------------------------- |
| 325 | | BEGGAR PRINCE / XIN QIGAI WANGZI [same as above, but diff start/end... merge?] |
| 326 | | -------------------------------------------------*/ |
| 327 | | |
| 328 | | READ16_MEMBER(md_rom_beggar_device::read) |
| 329 | | { |
| 330 | | offset <<= 1; |
| 331 | | if (offset >= m_nvram_start && offset < m_nvram_end && m_nvram_active) |
| 332 | | return m_nvram[(offset - m_nvram_start)/2]; |
| 333 | | return m_rom[offset/2]; |
| 334 | | } |
| 335 | | |
| 336 | | WRITE16_MEMBER(md_rom_beggar_device::write) |
| 337 | | { |
| 338 | | offset <<= 1; |
| 339 | | if (offset >= m_nvram_start && offset <= m_nvram_end && m_nvram_active && !m_nvram_readonly) |
| 340 | | m_nvram[(offset - m_nvram_start)/2] = data; |
| 341 | | } |
| 342 | | |
| 343 | | WRITE16_MEMBER(md_rom_beggar_device::write_a13) |
| 344 | | { |
| 345 | | offset <<= 1; |
| 346 | | if (offset == 0xf) |
| 347 | | { |
| 348 | | /* unsure if this is actually supposed to toggle or just switch on? yet to encounter game that uses this */ |
| 349 | | m_nvram_active = BIT(data, 0); |
| 350 | | m_nvram_readonly = BIT(data, 1); |
| 351 | | } |
| 352 | | } |
| 353 | | |
| 354 | | /*------------------------------------------------- |
| 355 | 325 | CART + FRAM [almost same as SRAM... merge common parts?] |
| 356 | 326 | -------------------------------------------------*/ |
| 357 | 327 | |
| 358 | 328 | READ16_MEMBER(md_rom_fram_device::read) |
| 359 | 329 | { |
| 360 | | offset <<= 1; |
| 361 | | if (offset >= m_nvram_start && offset < m_nvram_end && m_nvram_active) |
| 362 | | return m_nvram[(offset - m_nvram_start)/2]; |
| 363 | | return m_rom[offset/2]; |
| 330 | if (offset >= m_nvram_start/2 && offset < m_nvram_end/2 && m_nvram_active) |
| 331 | return m_nvram[offset - m_nvram_start/2]; |
| 332 | if (offset < 0x400000/2) |
| 333 | return m_rom[MD_ADDR(offset)]; |
| 334 | else |
| 335 | return 0xffff; |
| 364 | 336 | } |
| 365 | 337 | |
| 366 | 338 | WRITE16_MEMBER(md_rom_fram_device::write_a13) |
| 367 | 339 | { |
| 368 | | offset <<= 1; |
| 369 | | if (offset == 0xf) |
| 340 | if (offset == 0xf0/2) |
| 370 | 341 | m_nvram_active = BIT(data, 0); |
| 371 | 342 | } |
| 372 | 343 | |
| 373 | 344 | |
| 374 | 345 | READ16_MEMBER(md_rom_fram_device::read_a13) |
| 375 | 346 | { |
| 376 | | if (offset == 0xf) |
| 347 | if (offset == 0xf0/2) |
| 377 | 348 | return m_nvram_active; |
| 378 | 349 | else |
| 379 | 350 | return 0xffff; |
| r20808 | r20809 | |
| 564 | 535 | } |
| 565 | 536 | |
| 566 | 537 | /*------------------------------------------------- |
| 538 | YA SE CHUAN SHUO |
| 539 | -------------------------------------------------*/ |
| 540 | |
| 541 | READ16_MEMBER(md_rom_yasech_device::read) |
| 542 | { |
| 543 | if (offset == 0x400000/2) return 0x6300; |
| 544 | if (offset == 0x400002/2) return 0x9800; |
| 545 | if (offset == 0x400004/2) return 0xc900; |
| 546 | if (offset == 0x400006/2) return 0x1800; |
| 547 | return m_rom[offset]; |
| 548 | } |
| 549 | |
| 550 | /*------------------------------------------------- |
| 567 | 551 | KOF98 |
| 568 | 552 | -------------------------------------------------*/ |
| 569 | 553 | |
trunk/src/mess/drivers/megadriv.c
| r20808 | r20809 | |
| 9 | 9 | #include "machine/md_jcart.h" |
| 10 | 10 | #include "machine/md_stm95.h" |
| 11 | 11 | |
| 12 | #include "sound/sn76496.h" |
| 12 | 13 | |
| 14 | #include "imagedev/chd_cd.h" |
| 15 | #include "imagedev/cartslot.h" |
| 16 | |
| 17 | #include "formats/imageutl.h" |
| 18 | |
| 19 | |
| 13 | 20 | /************************************* |
| 14 | 21 | * |
| 15 | 22 | * Input handlers |
| r20808 | r20809 | |
| 296 | 303 | SLOT_INTERFACE_INTERNAL("rom_sram", MD_ROM_SRAM) |
| 297 | 304 | SLOT_INTERFACE_INTERNAL("rom_sramsafe", MD_ROM_SRAM) |
| 298 | 305 | SLOT_INTERFACE_INTERNAL("rom_fram", MD_ROM_FRAM) |
| 299 | | SLOT_INTERFACE_INTERNAL("rom_beggar", MD_ROM_BEGGAR) |
| 306 | SLOT_INTERFACE_INTERNAL("rom_hardbl95", MD_ROM_SRAM) |
| 307 | SLOT_INTERFACE_INTERNAL("rom_beggar", MD_ROM_SRAM) |
| 300 | 308 | // EEPROM handling (not supported fully yet) |
| 301 | 309 | SLOT_INTERFACE_INTERNAL("rom_eeprom", MD_STD_EEPROM) |
| 302 | 310 | SLOT_INTERFACE_INTERNAL("rom_nbajam", MD_EEPROM_NBAJAM) |
| r20808 | r20809 | |
| 319 | 327 | SLOT_INTERFACE_INTERNAL("rom_bugs", MD_ROM_BUGSLIFE) |
| 320 | 328 | SLOT_INTERFACE_INTERNAL("rom_chinf3", MD_ROM_CHINF3) |
| 321 | 329 | SLOT_INTERFACE_INTERNAL("rom_elfwor", MD_ROM_ELFWOR) |
| 330 | SLOT_INTERFACE_INTERNAL("rom_yasech", MD_ROM_YASECH) |
| 322 | 331 | SLOT_INTERFACE_INTERNAL("rom_kof98", MD_ROM_KOF98) |
| 323 | 332 | SLOT_INTERFACE_INTERNAL("rom_kof99", MD_ROM_KOF99) |
| 324 | 333 | SLOT_INTERFACE_INTERNAL("rom_lion2", MD_ROM_LION2) |
| r20808 | r20809 | |
| 443 | 452 | megadrive_region_pal = 0; |
| 444 | 453 | } |
| 445 | 454 | |
| 446 | | /****************************************** SegaCD & 32X emulation ****************************************/ |
| 455 | /****************************************** 32X emulation ****************************************/ |
| 447 | 456 | |
| 457 | static const sn76496_config psg_intf = |
| 458 | { |
| 459 | DEVCB_NULL |
| 460 | }; |
| 448 | 461 | |
| 462 | // FIXME: non-softlist loading should keep using ROM_CART_LOAD in the ROM definitions, |
| 463 | // once we better integrate softlist with the old loading procedures |
| 464 | DEVICE_IMAGE_LOAD_MEMBER( md_base_state, _32x_cart ) |
| 465 | { |
| 466 | UINT32 length; |
| 467 | UINT8 *temp_copy; |
| 468 | UINT16 *ROM16; |
| 469 | UINT32 *ROM32; |
| 470 | int i; |
| 471 | |
| 472 | if (image.software_entry() == NULL) |
| 473 | { |
| 474 | length = image.length(); |
| 475 | temp_copy = auto_alloc_array(image.device().machine(), UINT8, length); |
| 476 | image.fread(temp_copy, length); |
| 477 | } |
| 478 | else |
| 479 | { |
| 480 | length = image.get_software_region_length("rom"); |
| 481 | temp_copy = auto_alloc_array(image.device().machine(), UINT8, length); |
| 482 | memcpy(temp_copy, image.get_software_region("rom"), length); |
| 483 | } |
| 484 | |
| 485 | /* Copy the cart image in the locations the driver expects */ |
| 486 | // Notice that, by using pick_integer, we are sure the code works on both LE and BE machines |
| 487 | ROM16 = (UINT16 *) image.device().machine().root_device().memregion("gamecart")->base(); |
| 488 | for (i = 0; i < length; i += 2) |
| 489 | ROM16[i / 2] = pick_integer_be(temp_copy, i, 2); |
| 490 | |
| 491 | ROM32 = (UINT32 *) image.device().machine().root_device().memregion("gamecart_sh2")->base(); |
| 492 | for (i = 0; i < length; i += 4) |
| 493 | ROM32[i / 4] = pick_integer_be(temp_copy, i, 4); |
| 494 | |
| 495 | ROM16 = (UINT16 *) image.device().machine().root_device().memregion("maincpu")->base(); |
| 496 | for (i = 0x00; i < length; i += 2) |
| 497 | ROM16[i / 2] = pick_integer_be(temp_copy, i, 2); |
| 498 | |
| 499 | auto_free(image.device().machine(), temp_copy); |
| 500 | |
| 501 | return IMAGE_INIT_PASS; |
| 502 | } |
| 503 | |
| 504 | |
| 505 | static MACHINE_CONFIG_START( genesis_32x, md_cons_state ) |
| 506 | //MACHINE_CONFIG_DERIVED( genesis_32x, megadriv ) |
| 507 | MCFG_FRAGMENT_ADD( md_ntsc ) |
| 508 | |
| 509 | MCFG_DEVICE_ADD("sega32x", SEGA_32X_NTSC, 0) |
| 510 | |
| 511 | // we need to remove and re-add the sound system because the balance is different |
| 512 | // due to MAME / MESS having severe issues if the dac output is > 0.40? (sound is corrupted even if DAC is slient?!) |
| 513 | MCFG_DEVICE_REMOVE("ymsnd") |
| 514 | MCFG_DEVICE_REMOVE("snsnd") |
| 515 | |
| 516 | MCFG_SOUND_ADD("ymsnd", YM2612, MASTER_CLOCK_NTSC/7) |
| 517 | MCFG_SOUND_ROUTE(0, "lspeaker", (0.50)/2) |
| 518 | MCFG_SOUND_ROUTE(1, "rspeaker", (0.50)/2) |
| 519 | |
| 520 | /* sound hardware */ |
| 521 | MCFG_SOUND_ADD("snsnd", SEGAPSG, MASTER_CLOCK_NTSC/15) |
| 522 | MCFG_SOUND_CONFIG(psg_intf) |
| 523 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", (0.25)/2) |
| 524 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", (0.25)/2) |
| 525 | |
| 526 | MACHINE_CONFIG_END |
| 527 | |
| 528 | |
| 529 | static MACHINE_CONFIG_START( genesis_32x_pal, md_cons_state ) |
| 530 | //MACHINE_CONFIG_DERIVED( genesis_32x_pal, megadpal ) |
| 531 | MCFG_FRAGMENT_ADD( md_pal ) |
| 532 | |
| 533 | MCFG_DEVICE_ADD("sega32x", SEGA_32X_PAL, 0) |
| 534 | |
| 535 | // we need to remove and re-add the sound system because the balance is different |
| 536 | // due to MAME / MESS having severe issues if the dac output is > 0.40? (sound is corrupted even if DAC is slient?!) |
| 537 | MCFG_DEVICE_REMOVE("ymsnd") |
| 538 | MCFG_DEVICE_REMOVE("snsnd") |
| 539 | |
| 540 | MCFG_SOUND_ADD("ymsnd", YM2612, MASTER_CLOCK_NTSC/7) |
| 541 | MCFG_SOUND_ROUTE(0, "lspeaker", (0.50)/2) |
| 542 | MCFG_SOUND_ROUTE(1, "rspeaker", (0.50)/2) |
| 543 | |
| 544 | /* sound hardware */ |
| 545 | MCFG_SOUND_ADD("snsnd", SEGAPSG, MASTER_CLOCK_NTSC/15) |
| 546 | MCFG_SOUND_CONFIG(psg_intf) |
| 547 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", (0.25)/2) |
| 548 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", (0.25)/2) |
| 549 | |
| 550 | MACHINE_CONFIG_END |
| 551 | |
| 552 | |
| 553 | MACHINE_CONFIG_FRAGMENT( _32x_cartslot ) |
| 554 | MCFG_CARTSLOT_ADD("cart") |
| 555 | MCFG_CARTSLOT_EXTENSION_LIST("32x,bin") |
| 556 | MCFG_CARTSLOT_MANDATORY |
| 557 | MCFG_CARTSLOT_INTERFACE("_32x_cart") |
| 558 | MCFG_CARTSLOT_LOAD(md_base_state, _32x_cart) |
| 559 | MCFG_SOFTWARE_LIST_ADD("cart_list","32x") |
| 560 | MACHINE_CONFIG_END |
| 561 | |
| 449 | 562 | static MACHINE_CONFIG_DERIVED( ms_32x, genesis_32x ) |
| 450 | 563 | MCFG_FRAGMENT_ADD( _32x_cartslot ) |
| 451 | 564 | MCFG_DEVICE_MODIFY("cart_list") |
| r20808 | r20809 | |
| 499 | 612 | _32X_ROMS |
| 500 | 613 | ROM_END |
| 501 | 614 | |
| 615 | |
| 616 | /****************************************** SegaCD emulation ****************************************/ |
| 617 | |
| 618 | struct cdrom_interface scd_cdrom = |
| 619 | { |
| 620 | "scd_cdrom", |
| 621 | NULL |
| 622 | }; |
| 623 | |
| 624 | static MACHINE_CONFIG_START( genesis_scd, md_cons_state ) |
| 625 | //MACHINE_CONFIG_DERIVED( genesis_scd, megadriv ) |
| 626 | MCFG_FRAGMENT_ADD( md_ntsc ) |
| 627 | MCFG_DEVICE_ADD("segacd", SEGA_SEGACD_US, 0) |
| 628 | MCFG_CDROM_ADD( "cdrom",scd_cdrom ) |
| 629 | |
| 630 | MCFG_SOFTWARE_LIST_ADD("cd_list","segacd") |
| 631 | MACHINE_CONFIG_END |
| 632 | |
| 633 | static MACHINE_CONFIG_START( mega_scd, md_cons_state ) |
| 634 | //MACHINE_CONFIG_DERIVED( genesis_scd, megadriv ) |
| 635 | MCFG_FRAGMENT_ADD( md_pal ) |
| 636 | MCFG_DEVICE_ADD("segacd", SEGA_SEGACD_EUROPE, 0) |
| 637 | |
| 638 | MCFG_CDROM_ADD( "cdrom",scd_cdrom ) |
| 639 | |
| 640 | MCFG_SOFTWARE_LIST_ADD("cd_list","megacd") |
| 641 | MACHINE_CONFIG_END |
| 642 | |
| 643 | static MACHINE_CONFIG_START( megaj_scd, md_cons_state ) |
| 644 | //MACHINE_CONFIG_DERIVED( genesis_scd, megadriv ) |
| 645 | MCFG_FRAGMENT_ADD( md_ntsc ) |
| 646 | MCFG_DEVICE_ADD("segacd", SEGA_SEGACD_JAPAN, 0) |
| 647 | MCFG_CDROM_ADD( "cdrom",scd_cdrom ) |
| 648 | |
| 649 | MCFG_SOFTWARE_LIST_ADD("cd_list","megacdj") |
| 650 | MACHINE_CONFIG_END |
| 651 | |
| 652 | |
| 653 | static MACHINE_CONFIG_DERIVED( genesis_32x_scd, genesis_32x ) |
| 654 | |
| 655 | MCFG_DEVICE_ADD("segacd", SEGA_SEGACD_US, 0) |
| 656 | //MCFG_QUANTUM_PERFECT_CPU("32x_master_sh2") |
| 657 | MACHINE_CONFIG_END |
| 658 | |
| 659 | |
| 660 | |
| 502 | 661 | /* We need proper names for most of these BIOS ROMs! */ |
| 503 | 662 | ROM_START( segacd ) |
| 504 | 663 | ROM_REGION16_BE( 0x400000, "maincpu", ROMREGION_ERASE00 ) |
| r20808 | r20809 | |
| 954 | 1113 | CONS( 1994, 32xj, 32x, 0, ms_32x_jpn, md, md_cons_state, md_jpn, "Sega", "Mega Drive with 32X (Japan, NTSC)", GAME_NOT_WORKING ) |
| 955 | 1114 | |
| 956 | 1115 | // the SegaCD plugged into the expansion port.. |
| 957 | | CONS( 1992, segacd, 0, 0, genesis_scd_scd, md, md_cons_state, genesis, "Sega", "Sega CD (USA, NTSC)", GAME_NOT_WORKING ) |
| 958 | | CONS( 1993, megacd, segacd, 0, genesis_scd_mcd, md, md_cons_state, md_eur, "Sega", "Mega-CD (Europe, PAL)", GAME_NOT_WORKING ) |
| 959 | | 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?! |
| 960 | | CONS( 1991, megacda, segacd, 0, genesis_scd_mcdj,md, md_cons_state, md_eur, "Sega", "Mega-CD (Asia, PAL)", GAME_NOT_WORKING ) |
| 961 | | CONS( 1993, segacd2, 0, 0, genesis_scd_scd, md, md_cons_state, genesis, "Sega", "Sega CD 2 (USA, NTSC)", GAME_NOT_WORKING ) |
| 962 | | CONS( 1993, megacd2, segacd2, 0, genesis_scd_mcd, md, md_cons_state, md_eur, "Sega", "Mega-CD 2 (Europe, PAL)", GAME_NOT_WORKING ) |
| 963 | | CONS( 1993, megacd2j, segacd2, 0, genesis_scd_mcdj,md, md_cons_state, md_jpn, "Sega", "Mega-CD 2 (Japan, NTSC)", GAME_NOT_WORKING ) |
| 1116 | CONS( 1992, segacd, 0, 0, genesis_scd, md, md_cons_state, genesis, "Sega", "Sega CD (USA, NTSC)", GAME_NOT_WORKING ) |
| 1117 | CONS( 1993, megacd, segacd, 0, mega_scd, md, md_cons_state, md_eur, "Sega", "Mega-CD (Europe, PAL)", GAME_NOT_WORKING ) |
| 1118 | 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?! |
| 1119 | CONS( 1991, megacda, segacd, 0, megaj_scd, md, md_cons_state, md_eur, "Sega", "Mega-CD (Asia, PAL)", GAME_NOT_WORKING ) |
| 1120 | CONS( 1993, segacd2, 0, 0, genesis_scd, md, md_cons_state, genesis, "Sega", "Sega CD 2 (USA, NTSC)", GAME_NOT_WORKING ) |
| 1121 | CONS( 1993, megacd2, segacd2, 0, mega_scd, md, md_cons_state, md_eur, "Sega", "Mega-CD 2 (Europe, PAL)", GAME_NOT_WORKING ) |
| 1122 | CONS( 1993, megacd2j, segacd2, 0, megaj_scd, md, md_cons_state, md_jpn, "Sega", "Mega-CD 2 (Japan, NTSC)", GAME_NOT_WORKING ) |
| 964 | 1123 | CONS( 1993, laseract, 0, 0, genesis_scd, md, md_cons_state, genesis, "Pioneer","LaserActive (USA, NTSC)", GAME_NOT_WORKING ) |
| 965 | | CONS( 1993, laseractj, laseract, 0, genesis_scd, md, md_cons_state, md_jpn, "Pioneer","LaserActive (Japan, NTSC)", GAME_NOT_WORKING ) |
| 1124 | CONS( 1993, laseractj, laseract, 0, megaj_scd, md, md_cons_state, md_jpn, "Pioneer","LaserActive (Japan, NTSC)", GAME_NOT_WORKING ) |
| 966 | 1125 | CONS( 1993, xeye, 0, 0, genesis_scd, md, md_cons_state, genesis, "JVC", "X'eye (USA, NTSC)", GAME_NOT_WORKING ) |
| 967 | | CONS( 1992, wmega, xeye, 0, genesis_scd, md, md_cons_state, md_jpn, "Sega", "Wondermega (Japan, NTSC)", GAME_NOT_WORKING ) |
| 968 | | CONS( 1993, wmegam2, xeye, 0, genesis_scd, md, md_cons_state, md_jpn, "Victor", "Wondermega M2 (Japan, NTSC)", GAME_NOT_WORKING ) |
| 1126 | CONS( 1992, wmega, xeye, 0, megaj_scd, md, md_cons_state, md_jpn, "Sega", "Wondermega (Japan, NTSC)", GAME_NOT_WORKING ) |
| 1127 | CONS( 1993, wmegam2, xeye, 0, megaj_scd, md, md_cons_state, md_jpn, "Victor", "Wondermega M2 (Japan, NTSC)", GAME_NOT_WORKING ) |
| 969 | 1128 | CONS( 1994, cdx, 0, 0, genesis_scd, md, md_cons_state, genesis, "Sega", "CDX (USA, NTSC)", GAME_NOT_WORKING ) |
| 970 | | CONS( 1994, multmega, cdx, 0, genesis_scd, md, md_cons_state, md_eur, "Sega", "Multi-Mega (Europe, PAL)", GAME_NOT_WORKING ) |
| 971 | | CONS( 1994, 32x_scd, 0, 0, genesis_32x_scd, md, md_cons_state, genesis, "Sega", "Sega CD (USA, NTSC, w/32X)", GAME_NOT_WORKING ) |
| 1129 | CONS( 1994, multmega, cdx, 0, mega_scd, md, md_cons_state, md_eur, "Sega", "Multi-Mega (Europe, PAL)", GAME_NOT_WORKING ) |
| 1130 | CONS( 1994, 32x_scd, 0, 0, genesis_32x_scd, md, md_cons_state, genesis, "Sega", "Sega CD (USA, NTSC, w/32X)", GAME_NOT_WORKING ) |
| 972 | 1131 | |
| 973 | 1132 | // this is a standalone system based on the md-like hardware (same vdp etc.) |
| 974 | 1133 | |