trunk/src/mess/machine/snescart.c
| r21587 | r21588 | |
| 1017 | 1017 | case SNES_MODE_BSHI: |
| 1018 | 1018 | /* not handled yet */ |
| 1019 | 1019 | mame_printf_error("This is a BS-X Satellaview image: MESS does not support these yet, sorry.\n"); |
| 1020 | | #if 0 |
| 1021 | | // shall we force incompatibility of flash carts without a base unit? |
| 1022 | | if (!has_bsx_slot) |
| 1023 | | { |
| 1024 | | mame_printf_error("This is a BS-X flash cart and cannot be loaded in snes/snespal.\n"); |
| 1025 | | // mame_printf_error("Please use snesbsx driver to load it, instead.\n"); |
| 1026 | | return IMAGE_INIT_FAIL; |
| 1027 | | } |
| 1028 | | #endif |
| 1029 | | break; |
| 1020 | /* so treat it like MODE_20 */ |
| 1021 | state->m_cart[0].mode = SNES_MODE_20; |
| 1022 | /* and load it as such... */ |
| 1030 | 1023 | |
| 1031 | 1024 | default: |
| 1032 | 1025 | case SNES_MODE_20: |
| r21587 | r21588 | |
| 1237 | 1230 | return IMAGE_INIT_PASS; |
| 1238 | 1231 | } |
| 1239 | 1232 | |
| 1240 | | DEVICE_IMAGE_LOAD_MEMBER( snes_state,bsx_cart ) |
| 1241 | | { |
| 1242 | | running_machine &machine = image.device().machine(); |
| 1243 | | snes_state *state = machine.driver_data<snes_state>(); |
| 1244 | | int total_blocks, read_blocks; |
| 1245 | | int has_bsx_slot = 0; |
| 1246 | | UINT32 offset, int_header_offs; |
| 1247 | | UINT8 *ROM = state->memregion("cart")->base(); |
| 1248 | | |
| 1249 | | if (image.software_entry() == NULL) |
| 1250 | | state->m_cart_size = image.length(); |
| 1251 | | else |
| 1252 | | state->m_cart_size = image.get_software_region_length("rom"); |
| 1253 | | |
| 1254 | | /* Check for a header (512 bytes), and skip it if found */ |
| 1255 | | offset = snes_skip_header(image, state->m_cart_size); |
| 1256 | | |
| 1257 | | if (image.software_entry() == NULL) |
| 1258 | | { |
| 1259 | | image.fseek(offset, SEEK_SET); |
| 1260 | | image.fread( ROM, state->m_cart_size - offset); |
| 1261 | | } |
| 1262 | | else |
| 1263 | | memcpy(ROM, image.get_software_region("rom") + offset, state->m_cart_size - offset); |
| 1264 | | |
| 1265 | | if (SNES_CART_DEBUG) mame_printf_error("size %08X\n", state->m_cart_size - offset); |
| 1266 | | |
| 1267 | | /* First, look if the cart is HiROM or LoROM (and set snes_cart accordingly) */ |
| 1268 | | int_header_offs = snes_find_hilo_mode(image, ROM, offset, 0); |
| 1269 | | |
| 1270 | | // Detect presence of BS-X flash cartridge connector |
| 1271 | | if ((ROM[int_header_offs - 14] == 'Z') && (ROM[int_header_offs - 11] == 'J')) |
| 1272 | | { |
| 1273 | | UINT8 n13 = ROM[int_header_offs - 13]; |
| 1274 | | if ((n13 >= 'A' && n13 <= 'Z') || (n13 >= '0' && n13 <= '9')) |
| 1275 | | { |
| 1276 | | if (ROM[int_header_offs + 0x1a] == 0x33 || |
| 1277 | | (ROM[int_header_offs - 10] == 0x00 && ROM[int_header_offs - 4] == 0x00)) |
| 1278 | | { |
| 1279 | | has_bsx_slot = 1; |
| 1280 | | } |
| 1281 | | } |
| 1282 | | } |
| 1283 | | |
| 1284 | | // If there is a BS-X connector, detect if it is the Base Cart or a compatible slotted cart |
| 1285 | | if (has_bsx_slot) |
| 1286 | | { |
| 1287 | | if (!memcmp(ROM + int_header_offs, "Satellaview BS-X ", 21)) |
| 1288 | | { |
| 1289 | | //BS-X Base Cart |
| 1290 | | state->m_cart[0].mode = SNES_MODE_BSX; |
| 1291 | | // handle RAM |
| 1292 | | } |
| 1293 | | else |
| 1294 | | { |
| 1295 | | state->m_cart[0].mode = (int_header_offs ==0x007fc0) ? SNES_MODE_BSLO : SNES_MODE_BSHI; |
| 1296 | | // handle RAM? |
| 1297 | | } |
| 1298 | | } |
| 1299 | | else |
| 1300 | | { |
| 1301 | | mame_printf_error("This is not a BS-X compatible cart.\n"); |
| 1302 | | mame_printf_error("This image cannot be loaded in the first cartslot of snesbsx.\n"); |
| 1303 | | return IMAGE_INIT_FAIL; |
| 1304 | | } |
| 1305 | | |
| 1306 | | |
| 1307 | | /* FIXME: Insert crc check here? */ |
| 1308 | | |
| 1309 | | /* How many blocks of data are available to be loaded? */ |
| 1310 | | total_blocks = (state->m_cart_size - offset) / 0x8000; |
| 1311 | | read_blocks = 0; |
| 1312 | | |
| 1313 | | if (SNES_CART_DEBUG) mame_printf_error("blocks %d\n", total_blocks); |
| 1314 | | |
| 1315 | | // actually load the cart |
| 1316 | | while (read_blocks < 64 && read_blocks < total_blocks) |
| 1317 | | { |
| 1318 | | /* Loading data */ |
| 1319 | | memcpy(&snes_ram[0x008000 + read_blocks * 0x10000], &ROM[0x000000 + read_blocks * 0x8000], 0x8000); |
| 1320 | | /* Mirroring */ |
| 1321 | | memcpy(&snes_ram[0x808000 + read_blocks * 0x10000], &snes_ram[0x8000 + (read_blocks * 0x10000)], 0x8000); |
| 1322 | | |
| 1323 | | read_blocks++; |
| 1324 | | } |
| 1325 | | |
| 1326 | | /* Filling banks up to 0x3f and their mirrors */ |
| 1327 | | while (read_blocks % 64) |
| 1328 | | { |
| 1329 | | int j = 0, repeat_blocks; |
| 1330 | | while ((read_blocks % (64 >> j)) && j < 6) |
| 1331 | | j++; |
| 1332 | | repeat_blocks = read_blocks % (64 >> (j - 1)); |
| 1333 | | |
| 1334 | | memcpy(&snes_ram[read_blocks * 0x10000], &snes_ram[(read_blocks - repeat_blocks) * 0x10000], repeat_blocks * 0x10000); |
| 1335 | | memcpy(&snes_ram[0x800000 + read_blocks * 0x10000], &snes_ram[(read_blocks - repeat_blocks) * 0x10000], repeat_blocks * 0x10000); |
| 1336 | | read_blocks += repeat_blocks; |
| 1337 | | } |
| 1338 | | |
| 1339 | | return IMAGE_INIT_PASS; |
| 1340 | | } |
| 1341 | | |
| 1342 | | DEVICE_IMAGE_LOAD_MEMBER( snes_state,bsx2slot_cart ) |
| 1343 | | { |
| 1344 | | running_machine &machine = image.device().machine(); |
| 1345 | | snes_state *state = machine.driver_data<snes_state>(); |
| 1346 | | UINT32 offset, int_header_offs; |
| 1347 | | UINT8 *ROM = state->memregion("flash")->base(); |
| 1348 | | |
| 1349 | | if (image.software_entry() == NULL) |
| 1350 | | state->m_cart_size = image.length(); |
| 1351 | | else |
| 1352 | | state->m_cart_size = image.get_software_region_length("rom"); |
| 1353 | | |
| 1354 | | /* Check for a header (512 bytes), and skip it if found */ |
| 1355 | | offset = snes_skip_header(image, state->m_cart_size); |
| 1356 | | |
| 1357 | | if (image.software_entry() == NULL) |
| 1358 | | { |
| 1359 | | image.fseek(offset, SEEK_SET); |
| 1360 | | image.fread( ROM, state->m_cart_size - offset); |
| 1361 | | } |
| 1362 | | else |
| 1363 | | memcpy(ROM, image.get_software_region("rom") + offset, state->m_cart_size - offset); |
| 1364 | | |
| 1365 | | if (SNES_CART_DEBUG) mame_printf_error("size %08X\n", state->m_cart_size - offset); |
| 1366 | | |
| 1367 | | /* First, look if the cart is HiROM or LoROM (and set snes_cart accordingly) */ |
| 1368 | | int_header_offs = snes_find_hilo_mode(image, ROM, offset, 1); |
| 1369 | | |
| 1370 | | // Detect presence of BS-X Flash Cart |
| 1371 | | if ((ROM[int_header_offs + 0x13] == 0x00 || ROM[int_header_offs + 0x13] == 0xff) && |
| 1372 | | ROM[int_header_offs + 0x14] == 0x00) |
| 1373 | | { |
| 1374 | | UINT8 n15 = ROM[int_header_offs + 0x15]; |
| 1375 | | if (n15 == 0x00 || n15 == 0x80 || n15 == 0x84 || n15 == 0x9c || n15 == 0xbc || n15 == 0xfc) |
| 1376 | | { |
| 1377 | | if (ROM[int_header_offs + 0x1a] == 0x33 || ROM[int_header_offs + 0x1a] == 0xff) |
| 1378 | | { |
| 1379 | | // BS-X Flash Cart |
| 1380 | | state->m_cart[1].mode = SNES_MODE_BSX; |
| 1381 | | } |
| 1382 | | } |
| 1383 | | } |
| 1384 | | |
| 1385 | | if (state->m_cart[1].mode != SNES_MODE_BSX) |
| 1386 | | { |
| 1387 | | mame_printf_error("This is not a BS-X flash cart.\n"); |
| 1388 | | mame_printf_error("This image cannot be loaded in the second cartslot of snesbsx.\n"); |
| 1389 | | return IMAGE_INIT_FAIL; |
| 1390 | | } |
| 1391 | | |
| 1392 | | // actually load the cart |
| 1393 | | return IMAGE_INIT_PASS; |
| 1394 | | } |
| 1395 | | |
| 1396 | 1233 | MACHINE_CONFIG_FRAGMENT( snes_cartslot ) |
| 1397 | 1234 | MCFG_CARTSLOT_ADD("cart") |
| 1398 | 1235 | MCFG_CARTSLOT_EXTENSION_LIST("sfc,smc,fig,swc,bin") |
| r21587 | r21588 | |
| 1433 | 1270 | // MCFG_SOFTWARE_LIST_ADD("cart_list","snes") |
| 1434 | 1271 | MACHINE_CONFIG_END |
| 1435 | 1272 | |
| 1436 | | // This (hackily) emulates a SNES unit where you want to load a BS-X compatible cart: |
| 1437 | | // hence, the user can mount a SNES cart in the first slot (either a BS-X BIOS cart, or a |
| 1438 | | // BS-X compatible one, e.g. Same Game), and there is a second slot for the 8M data pack |
| 1439 | | // (in a real SNES this would have been inserted in the smaller slot on the cart itself) |
| 1440 | | MACHINE_CONFIG_FRAGMENT( bsx_cartslot ) |
| 1441 | | MCFG_CARTSLOT_ADD("cart") |
| 1442 | | MCFG_CARTSLOT_EXTENSION_LIST("sfc,smc,fig,swc,bin") |
| 1443 | | MCFG_CARTSLOT_NOT_MANDATORY |
| 1444 | | MCFG_CARTSLOT_INTERFACE("snes_cart") |
| 1445 | | MCFG_CARTSLOT_LOAD(snes_state,bsx_cart) |
| 1446 | 1273 | |
| 1447 | | MCFG_CARTSLOT_ADD("slot2") |
| 1448 | | MCFG_CARTSLOT_EXTENSION_LIST("bs,sfc") |
| 1449 | | MCFG_CARTSLOT_NOT_MANDATORY |
| 1450 | | MCFG_CARTSLOT_INTERFACE("bsx_cart") |
| 1451 | | MCFG_CARTSLOT_LOAD(snes_state,bsx2slot_cart) |
| 1452 | | |
| 1453 | | // MCFG_SOFTWARE_LIST_ADD("cart_list","snes") |
| 1454 | | MACHINE_CONFIG_END |
| 1455 | | |
| 1456 | 1274 | DRIVER_INIT_MEMBER(snes_state,snes_mess) |
| 1457 | 1275 | { |
| 1458 | 1276 | snes_ram = machine().root_device().memregion("maincpu")->base(); |
trunk/src/mess/drivers/snes.c
| r21587 | r21588 | |
| 1283 | 1283 | MCFG_FRAGMENT_ADD(sufami_cartslot) |
| 1284 | 1284 | MACHINE_CONFIG_END |
| 1285 | 1285 | |
| 1286 | | static MACHINE_CONFIG_DERIVED( snesbsx, snes_base ) |
| 1287 | 1286 | |
| 1288 | | MCFG_FRAGMENT_ADD(bsx_cartslot) |
| 1289 | | MACHINE_CONFIG_END |
| 1290 | | |
| 1291 | | |
| 1292 | 1287 | /************************************* |
| 1293 | 1288 | * |
| 1294 | 1289 | * ROM definition(s) |
| r21587 | r21588 | |
| 1428 | 1423 | ROM_REGION( 0x800, "dspdata", ROMREGION_ERASEFF) |
| 1429 | 1424 | ROM_END |
| 1430 | 1425 | |
| 1431 | | ROM_START( snesbsx ) |
| 1432 | | ROM_REGION( 0x1000000, "maincpu", ROMREGION_ERASE00 ) |
| 1433 | 1426 | |
| 1434 | | ROM_REGION( 0x100, "sound_ipl", 0 ) /* IPL ROM */ |
| 1435 | | ROM_LOAD( "spc700.rom", 0, 0x40, CRC(44bb3a40) SHA1(97e352553e94242ae823547cd853eecda55c20f0) ) /* boot rom */ |
| 1436 | 1427 | |
| 1437 | | ROM_REGION( 0x10000, "addons", 0 ) /* add-on chip ROMs (DSP, SFX, etc) */ |
| 1438 | | ROM_LOAD( "dsp1b.bin", SNES_DSP1B_OFFSET, 0x002800, CRC(453557e0) SHA1(3a218b0e4572a8eba6d0121b17fdac9529609220) ) |
| 1439 | | ROM_LOAD( "dsp1.bin", SNES_DSP1_OFFSET, 0x002800, CRC(2838f9f5) SHA1(0a03ccb1fd2bea91151c745a4d1f217ae784f889) ) |
| 1440 | | ROM_LOAD( "dsp2.bin", SNES_DSP2_OFFSET, 0x002800, CRC(8e9fbd9b) SHA1(06dd9fcb118d18f6bbe234e013cb8780e06d6e63) ) |
| 1441 | | ROM_LOAD( "dsp3.bin", SNES_DSP3_OFFSET, 0x002800, CRC(6b86728a) SHA1(1b133741fad810eb7320c21ecfdd427d25a46da1) ) |
| 1442 | | ROM_LOAD( "dsp4.bin", SNES_DSP4_OFFSET, 0x002800, CRC(ce0c7783) SHA1(76fd25f7dc26c3b3f7868a3aa78c7684068713e5) ) |
| 1443 | | |
| 1444 | | ROM_REGION( MAX_SNES_CART_SIZE, "cart", ROMREGION_ERASE00 ) |
| 1445 | | ROM_REGION( MAX_SNES_CART_SIZE, "flash", ROMREGION_ERASE00 ) |
| 1446 | | ROM_REGION( 0x2000, "dspprg", ROMREGION_ERASEFF) |
| 1447 | | ROM_REGION( 0x800, "dspdata", ROMREGION_ERASEFF) |
| 1448 | | ROM_END |
| 1449 | | |
| 1450 | | |
| 1451 | | |
| 1452 | 1428 | /************************************* |
| 1453 | 1429 | * |
| 1454 | 1430 | * Game driver(s) |
| r21587 | r21588 | |
| 1473 | 1449 | |
| 1474 | 1450 | // These would require cartslot to be added/removed depending on the cart which is loaded |
| 1475 | 1451 | CONS( 1989, snesst, snes, 0, snesst, snes, snes_state, snesst, "Nintendo", "Super Nintendo Entertainment System / Super Famicom (NTSC, w/Sufami Turbo)", GAME_NOT_WORKING ) |
| 1476 | | CONS( 1989, snesbsx, snes, 0, snesbsx, snes, snes_state, snes_mess, "Nintendo", "Super Nintendo Entertainment System / Super Famicom (NTSC, w/BS-X Satellaview slotted cart)", GAME_NOT_WORKING ) |
| 1477 | 1452 | |
| 1478 | 1453 | |
| 1479 | 1454 | |
trunk/src/mame/machine/snesbsx.c
| r21587 | r21588 | |
| 1 | | /*************************************************************************** |
| 2 | | |
| 3 | | snesbsx.c |
| 4 | | |
| 5 | | File to handle emulation of the SNES "BS-X Satellaview". |
| 6 | | |
| 7 | | Based on byuu's research. |
| 8 | | |
| 9 | | TODO: basically everything. The hardware can dynamically remap where |
| 10 | | the memory handlers read/write (this will probably require some more |
| 11 | | rethinking of the way we use snes_ram), see bsx_update_memory_map |
| 12 | | |
| 13 | | ***************************************************************************/ |
| 14 | | |
| 15 | | |
| 16 | | enum |
| 17 | | { |
| 18 | | SNES_BSX_CARTROM = 0, |
| 19 | | SNES_BSX_PRAM, |
| 20 | | SNES_BSX_FLASH |
| 21 | | }; |
| 22 | | |
| 23 | | |
| 24 | | struct snes_bsx_state |
| 25 | | { |
| 26 | | // base regs |
| 27 | | // we don't emulate the base unit yet |
| 28 | | |
| 29 | | // cart regs |
| 30 | | UINT8 cart_regs[16]; |
| 31 | | |
| 32 | | // flash regs |
| 33 | | UINT32 command; |
| 34 | | UINT8 write_old; |
| 35 | | UINT8 write_new; |
| 36 | | |
| 37 | | int flash_enable; |
| 38 | | int read_enable; |
| 39 | | int write_enable; |
| 40 | | |
| 41 | | UINT8 *pram; |
| 42 | | int ram_source; |
| 43 | | }; |
| 44 | | |
| 45 | | static snes_bsx_state bsx_state; |
| 46 | | |
| 47 | | |
| 48 | | static void bsx_update_memory_map(void) |
| 49 | | { |
| 50 | | bsx_state.ram_source = BIT(bsx_state.cart_regs[0x01], 7) ? SNES_BSX_PRAM : SNES_BSX_FLASH; |
| 51 | | // UINT8 *RAM = (bsx_state.cart_regs[0x01] & 0x80) == 0x00 ? space.memregion("flash")->base() : bsx_state.pram; |
| 52 | | |
| 53 | | logerror("BSX: updated memory map, current RAM: %d", bsx_state.ram_source); |
| 54 | | if (!BIT(bsx_state.cart_regs[0x02], 7)) |
| 55 | | { |
| 56 | | //LoROM mapping |
| 57 | | // 0x00-0x7d:0x8000-0xfff -> RAM (either flash or pram) |
| 58 | | // 0x80-0xff:0x8000-0xfff -> RAM |
| 59 | | } |
| 60 | | else |
| 61 | | { |
| 62 | | //HiROM mapping |
| 63 | | // 0x00-0x3f:0x8000-0xfff -> RAM - 'shadowed' |
| 64 | | // 0x40-0x7d:0x0000-0xfff -> RAM |
| 65 | | // 0x80-0xbf:0x8000-0xfff -> RAM - 'shadowed' |
| 66 | | // 0xc0-0xff:0x0000-0xfff -> RAM |
| 67 | | } |
| 68 | | |
| 69 | | if (BIT(bsx_state.cart_regs[0x03], 7)) |
| 70 | | { |
| 71 | | // 0x60-0x6f:0x0000-0xffff -> PRAM |
| 72 | | } |
| 73 | | |
| 74 | | if (!BIT(bsx_state.cart_regs[0x05], 7)) |
| 75 | | { |
| 76 | | // 0x40-0x4f:0x0000-0xffff -> PRAM |
| 77 | | } |
| 78 | | |
| 79 | | if (!BIT(bsx_state.cart_regs[0x06], 7)) |
| 80 | | { |
| 81 | | // 0x50-0x5f:0x0000-0xffff -> PRAM |
| 82 | | } |
| 83 | | |
| 84 | | if (BIT(bsx_state.cart_regs[0x07], 7)) |
| 85 | | { |
| 86 | | // 0x00-0x1f:0x8000-0xffff -> CART |
| 87 | | } |
| 88 | | |
| 89 | | if (BIT(bsx_state.cart_regs[0x08], 7)) |
| 90 | | { |
| 91 | | // 0x80-0x9f:0x8000-0xffff -> CART |
| 92 | | } |
| 93 | | |
| 94 | | // 0x20-0x3f:0x6000-0x7fff -> PRAM |
| 95 | | // 0x70-0x77:0x0000-0xffff -> PRAM |
| 96 | | } |
| 97 | | |
| 98 | | static READ8_HANDLER( bsx_read ) |
| 99 | | { |
| 100 | | if ((offset & 0xf0ffff) == 0x005000) |
| 101 | | { |
| 102 | | //$[00-0f]:5000 MMIO |
| 103 | | UINT8 n = (offset >> 16) & 0x0f; |
| 104 | | return bsx_state.cart_regs[n]; |
| 105 | | } |
| 106 | | |
| 107 | | if ((offset & 0xf8f000) == 0x105000) |
| 108 | | { |
| 109 | | //$[10-17]:[5000-5fff] SRAM |
| 110 | | return bsx_state.pram[((offset >> 16) & 7) * 0x1000 + (offset & 0xfff)]; |
| 111 | | } |
| 112 | | |
| 113 | | return 0x00; |
| 114 | | } |
| 115 | | |
| 116 | | |
| 117 | | static WRITE8_HANDLER( bsx_write ) |
| 118 | | { |
| 119 | | if ((offset & 0xf0ffff) == 0x005000) |
| 120 | | { |
| 121 | | //$[00-0f]:5000 MMIO |
| 122 | | UINT8 n = (offset >> 16) & 0x0f; |
| 123 | | bsx_state.cart_regs[n] = data; |
| 124 | | if ((n == 0x0e) && (data & 0x80)) |
| 125 | | bsx_update_memory_map(); |
| 126 | | } |
| 127 | | |
| 128 | | if ((offset & 0xf8f000) == 0x105000) |
| 129 | | { |
| 130 | | //$[10-17]:[5000-5fff] SRAM |
| 131 | | bsx_state.pram[((offset >> 16) & 7) * 0x1000 + (offset & 0xfff)] = data; |
| 132 | | } |
| 133 | | } |
| 134 | | |
| 135 | | static void bsx_init( running_machine &machine ) |
| 136 | | { |
| 137 | | memset(bsx_state.cart_regs, 0, ARRAY_LENGTH(bsx_state.cart_regs)); |
| 138 | | |
| 139 | | bsx_state.cart_regs[0x07] = 0x80; |
| 140 | | bsx_state.cart_regs[0x08] = 0x80; |
| 141 | | |
| 142 | | bsx_state.pram = auto_alloc_array(machine, UINT8, 0x80000); |
| 143 | | |
| 144 | | bsx_update_memory_map(); |
| 145 | | // saves |
| 146 | | } |
| 147 | | |
| 148 | | #ifdef UNUSED_FUNCTION |
| 149 | | static READ8_HANDLER( bsx_flash_read ) |
| 150 | | { |
| 151 | | UINT8 *FLASH = space.memregion("flash")->base(); |
| 152 | | |
| 153 | | if (offset == 0x0002) |
| 154 | | { |
| 155 | | if (bsx_state.flash_enable) |
| 156 | | return 0x80; |
| 157 | | } |
| 158 | | |
| 159 | | if (offset == 0x5555) |
| 160 | | { |
| 161 | | if (bsx_state.flash_enable) |
| 162 | | return 0x80; |
| 163 | | } |
| 164 | | |
| 165 | | if (bsx_state.read_enable && offset >= 0xff00 && offset <= 0xff13) |
| 166 | | { |
| 167 | | //read flash cartridge vendor information |
| 168 | | switch(offset - 0xff00) |
| 169 | | { |
| 170 | | case 0x00: return 0x4d; |
| 171 | | case 0x01: return 0x00; |
| 172 | | case 0x02: return 0x50; |
| 173 | | case 0x03: return 0x00; |
| 174 | | case 0x04: return 0x00; |
| 175 | | case 0x05: return 0x00; |
| 176 | | case 0x06: return 0x2a; //0x2a = 8mbit, 0x2b = 16mbit (not known to exist, though BIOS recognizes ID) |
| 177 | | case 0x07: return 0x00; |
| 178 | | default: return 0x00; |
| 179 | | } |
| 180 | | } |
| 181 | | |
| 182 | | return FLASH[offset]; |
| 183 | | } |
| 184 | | |
| 185 | | static WRITE8_HANDLER( bsx_flash_write ) |
| 186 | | { |
| 187 | | if ((offset & 0xff0000) == 0) |
| 188 | | { |
| 189 | | bsx_state.write_old = bsx_state.write_new; |
| 190 | | bsx_state.write_new = data; |
| 191 | | |
| 192 | | if (bsx_state.write_enable && bsx_state.write_old == bsx_state.write_new) |
| 193 | | { |
| 194 | | // currently we have the flashcart loaded in a rom_region -> we cannot write yet |
| 195 | | } |
| 196 | | } |
| 197 | | else |
| 198 | | { |
| 199 | | if (bsx_state.write_enable) |
| 200 | | { |
| 201 | | // currently we have the flashcart loaded in a rom_region -> we cannot write yet |
| 202 | | } |
| 203 | | } |
| 204 | | |
| 205 | | if (offset == 0x0000) |
| 206 | | { |
| 207 | | bsx_state.command <<= 8; |
| 208 | | bsx_state.command |= data; |
| 209 | | |
| 210 | | if ((bsx_state.command & 0xffff) == 0x38d0) |
| 211 | | { |
| 212 | | bsx_state.flash_enable = 1; |
| 213 | | bsx_state.read_enable = 1; |
| 214 | | } |
| 215 | | } |
| 216 | | |
| 217 | | if (offset == 0x2aaa) |
| 218 | | { |
| 219 | | bsx_state.command <<= 8; |
| 220 | | bsx_state.command |= data; |
| 221 | | } |
| 222 | | |
| 223 | | if (offset == 0x5555) |
| 224 | | { |
| 225 | | bsx_state.command <<= 8; |
| 226 | | bsx_state.command |= data; |
| 227 | | |
| 228 | | if ((bsx_state.command & 0xffffff) == 0xaa5570) |
| 229 | | { |
| 230 | | bsx_state.write_enable = 0; |
| 231 | | } |
| 232 | | |
| 233 | | if ((bsx_state.command & 0xffffff) == 0xaa55a0) |
| 234 | | { |
| 235 | | bsx_state.write_old = 0x00; |
| 236 | | bsx_state.write_new = 0x00; |
| 237 | | bsx_state.flash_enable = 1; |
| 238 | | bsx_state.write_enable = 1; |
| 239 | | } |
| 240 | | |
| 241 | | if ((bsx_state.command & 0xffffff) == 0xaa55f0) |
| 242 | | { |
| 243 | | bsx_state.flash_enable = 0; |
| 244 | | bsx_state.read_enable = 0; |
| 245 | | bsx_state.write_enable = 0; |
| 246 | | } |
| 247 | | } |
| 248 | | } |
| 249 | | |
| 250 | | #endif |
trunk/src/mame/machine/snes.c
| r21587 | r21588 | |
| 41 | 41 | #include "machine/snesrtc.c" |
| 42 | 42 | #include "machine/snessdd1.c" |
| 43 | 43 | #include "machine/snes7110.c" |
| 44 | | #include "machine/snesbsx.c" |
| 45 | 44 | |
| 46 | 45 | |
| 47 | 46 | VIDEO_START( snes ) |
| r21587 | r21588 | |
| 694 | 693 | /* 0x000000 - 0x2fffff */ |
| 695 | 694 | READ8_HANDLER( snes_r_bank1 ) |
| 696 | 695 | { |
| 697 | | snes_state *state = space.machine().driver_data<snes_state>(); |
| 698 | 696 | UINT8 value = 0xff; |
| 699 | 697 | UINT16 address = offset & 0xffff; |
| 700 | 698 | |
| 701 | 699 | if (address < 0x2000) /* Mirror of Low RAM */ |
| 702 | 700 | value = space.read_byte(0x7e0000 + address); |
| 703 | 701 | else if (address < 0x6000) /* I/O */ |
| 704 | | { |
| 705 | | if (state->m_cart[0].mode == SNES_MODE_BSX && address >= 0x5000) |
| 706 | | value = bsx_read(space, offset, mem_mask); |
| 707 | | else |
| 708 | | value = snes_r_io(space, address); |
| 709 | | } |
| 702 | value = snes_r_io(space, address); |
| 710 | 703 | else if (address < 0x8000) |
| 711 | 704 | { |
| 712 | 705 | logerror("(PC=%06x) snes_r_bank1: Unmapped external chip read: %04x\n",space.device().safe_pc(),address); |
| r21587 | r21588 | |
| 728 | 721 | if (address < 0x2000) /* Mirror of Low RAM */ |
| 729 | 722 | value = space.read_byte(0x7e0000 + address); |
| 730 | 723 | else if (address < 0x6000) /* I/O */ |
| 731 | | { |
| 732 | | if (state->m_cart[0].mode == SNES_MODE_BSX && address >= 0x5000) |
| 733 | | value = bsx_read(space, 0x300000 + offset, mem_mask); |
| 734 | | else |
| 735 | | value = snes_r_io(space, address); |
| 736 | | } |
| 724 | value = snes_r_io(space, address); |
| 737 | 725 | else if (address < 0x8000) /* SRAM for mode_21, Reserved othewise */ |
| 738 | 726 | { |
| 739 | 727 | if (state->m_cart[0].mode == SNES_MODE_21 && state->m_cart[0].sram > 0) |
| r21587 | r21588 | |
| 834 | 822 | /* 0x800000 - 0xbfffff */ |
| 835 | 823 | READ8_HANDLER( snes_r_bank6 ) |
| 836 | 824 | { |
| 837 | | snes_state *state = space.machine().driver_data<snes_state>(); |
| 838 | 825 | UINT8 value = 0; |
| 839 | | UINT16 address = offset & 0xffff; |
| 840 | 826 | |
| 841 | | if (address < 0x8000) |
| 842 | | { |
| 843 | | if (state->m_cart[0].mode != SNES_MODE_25) |
| 844 | | value = space.read_byte(offset); |
| 845 | | else /* Mode 25 has SRAM not mirrored from lower banks */ |
| 846 | | { |
| 847 | | if (address < 0x6000) |
| 848 | | value = space.read_byte(offset); |
| 849 | | else if ((offset >= 0x300000) && (state->m_cart[0].sram > 0)) |
| 850 | | { |
| 851 | | int mask = (state->m_cart[0].sram - 1) & 0x7fff; /* Limit SRAM size to what's actually present */ |
| 852 | | value = snes_ram[0xb06000 + ((offset - 0x6000) & mask)]; |
| 853 | | } |
| 854 | | else /* Area 0x6000-0x8000 with offset < 0x300000 is reserved */ |
| 855 | | { |
| 856 | | logerror("(PC=%06x) snes_r_bank6: Unmapped external chip read: %04x\n",space.device().safe_pc(),address); |
| 857 | | value = snes_open_bus_r(space, 0); |
| 858 | | } |
| 859 | | } |
| 860 | | } |
| 827 | if ((offset & 0xffff) < 0x8000) |
| 828 | value = space.read_byte(offset); |
| 861 | 829 | else |
| 862 | 830 | value = snes_ram[0x800000 + offset]; |
| 863 | 831 | |
| r21587 | r21588 | |
| 888 | 856 | /* 0x000000 - 0x2fffff */ |
| 889 | 857 | WRITE8_HANDLER( snes_w_bank1 ) |
| 890 | 858 | { |
| 891 | | snes_state *state = space.machine().driver_data<snes_state>(); |
| 892 | 859 | UINT16 address = offset & 0xffff; |
| 893 | 860 | |
| 894 | 861 | if (address < 0x2000) /* Mirror of Low RAM */ |
| 895 | 862 | space.write_byte(0x7e0000 + address, data); |
| 896 | 863 | else if (address < 0x6000) /* I/O */ |
| 897 | | { |
| 898 | | if (state->m_cart[0].mode == SNES_MODE_BSX && address >= 0x5000) |
| 899 | | bsx_write(space, offset, data, mem_mask); |
| 900 | | else |
| 901 | | snes_w_io(space, address, data); |
| 902 | | } |
| 864 | snes_w_io(space, address, data); |
| 903 | 865 | else if (address < 0x8000) |
| 904 | 866 | logerror("snes_w_bank1: Attempt to write to reserved address: %x = %02x\n", offset, data); |
| 905 | 867 | else |
| r21587 | r21588 | |
| 915 | 877 | if (address < 0x2000) /* Mirror of Low RAM */ |
| 916 | 878 | space.write_byte(0x7e0000 + address, data); |
| 917 | 879 | else if (address < 0x6000) /* I/O */ |
| 918 | | { |
| 919 | | if (state->m_cart[0].mode == SNES_MODE_BSX && address >= 0x5000) |
| 920 | | bsx_write(space, 0x300000 + offset, data, mem_mask); |
| 921 | | else |
| 922 | | snes_w_io(space, address, data); |
| 923 | | } |
| 880 | snes_w_io(space, address, data); |
| 924 | 881 | else if (address < 0x8000) /* SRAM for mode_21, Reserved othewise */ |
| 925 | 882 | { |
| 926 | 883 | if ((state->m_cart[0].mode == SNES_MODE_21) && (state->m_cart[0].sram > 0)) |
| r21587 | r21588 | |
| 985 | 942 | /* 0x800000 - 0xbfffff */ |
| 986 | 943 | WRITE8_HANDLER( snes_w_bank6 ) |
| 987 | 944 | { |
| 988 | | snes_state *state = space.machine().driver_data<snes_state>(); |
| 989 | | UINT16 address = offset & 0xffff; |
| 990 | | |
| 991 | | if (address < 0x8000) |
| 992 | | { |
| 993 | | if (state->m_cart[0].mode != SNES_MODE_25) |
| 994 | | space.write_byte(offset, data); |
| 995 | | else /* Mode 25 has SRAM not mirrored from lower banks */ |
| 996 | | { |
| 997 | | if (address < 0x6000) |
| 998 | | space.write_byte(offset, data); |
| 999 | | else if ((offset >= 0x300000) && (state->m_cart[0].sram > 0)) |
| 1000 | | { |
| 1001 | | int mask = (state->m_cart[0].sram - 1) & 0x7fff; /* Limit SRAM size to what's actually present */ |
| 1002 | | snes_ram[0xb06000 + ((offset - 0x6000) & mask)] = data; |
| 1003 | | } |
| 1004 | | else /* Area in 0x6000-0x8000 && offset < 0x300000 is Reserved! */ |
| 1005 | | logerror("snes_w_bank6: Attempt to write to reserved address: %X = %02x\n", offset + 0x800000, data); |
| 1006 | | } |
| 1007 | | } |
| 945 | if ((offset & 0xffff) < 0x8000) |
| 946 | space.write_byte(offset, data); |
| 1008 | 947 | else |
| 1009 | 948 | logerror("(PC=%06x) Attempt to write to ROM address: %X\n",space.device().safe_pc(),offset + 0x800000); |
| 1010 | 949 | } |
| r21587 | r21588 | |
| 1215 | 1154 | // SNES_CPU_REG_STATE(WRDIVL) = 0xff; |
| 1216 | 1155 | // SNES_CPU_REG_STATE(WRDIVH) = 0xff; |
| 1217 | 1156 | |
| 1218 | | if (state->m_cart[0].mode == SNES_MODE_BSX) |
| 1219 | | bsx_init(machine); |
| 1220 | | |
| 1221 | 1157 | snes_init_timers(machine); |
| 1222 | 1158 | |
| 1223 | 1159 | for (int i = 0; i < 6; i++) |