src/mess/machine/sms.c
| r8905 | r8906 | |
| 12 | 12 | #define CF_CODEMASTERS_MAPPER 0x01 |
| 13 | 13 | #define CF_KOREAN_MAPPER 0x02 |
| 14 | 14 | #define CF_KOREAN_ZEMINA_MAPPER 0x04 |
| 15 | | #define CF_93C46_EEPROM 0x08 |
| 16 | | #define CF_ONCART_RAM 0x10 |
| 17 | | #define CF_GG_SMS_MODE 0x20 |
| 15 | #define CF_KOREAN_NOBANK_MAPPER 0x08 |
| 16 | #define CF_93C46_EEPROM 0x10 |
| 17 | #define CF_ONCART_RAM 0x20 |
| 18 | #define CF_GG_SMS_MODE 0x40 |
| 18 | 19 | |
| 19 | 20 | #define MAX_CARTRIDGES 16 |
| 20 | 21 | |
| r8905 | r8906 | |
| 830 | 831 | } |
| 831 | 832 | } |
| 832 | 833 | |
| 834 | static READ8_HANDLER( sms_kor_nobank_r ) |
| 835 | { |
| 836 | // printf("read %x\n", offset); |
| 837 | return space->read_byte(0xdffc + offset); |
| 838 | } |
| 833 | 839 | |
| 840 | static WRITE8_HANDLER( sms_kor_nobank_w ) |
| 841 | { |
| 842 | UINT8 *SOURCE_BIOS; |
| 843 | UINT8 *SOURCE = NULL; |
| 844 | |
| 845 | space->write_byte(0xdffc + offset, data); |
| 846 | sms_state.mapper[offset] = data; |
| 847 | |
| 848 | // FIXME: the code below (which only handles the BIOS bankswitch at start) should be cleaned up |
| 849 | // currently, it's just a stripped down version of sms_mapper_w |
| 850 | if (sms_state.BIOS) |
| 851 | SOURCE_BIOS = sms_state.BIOS + ((sms_state.bios_page_count > 0) ? data % sms_state.bios_page_count : 0) * 0x4000; |
| 852 | else |
| 853 | SOURCE_BIOS = sms_state.banking_none[1]; |
| 854 | |
| 855 | if (sms_state.bios_port & IO_BIOS_ROM || (sms_state.is_gamegear && sms_state.BIOS == NULL)) |
| 856 | return; |
| 857 | else |
| 858 | { |
| 859 | if (!sms_state.BIOS) |
| 860 | return; |
| 861 | SOURCE = SOURCE_BIOS; |
| 862 | } |
| 863 | |
| 864 | // printf("write %x, %x\n", offset, data); |
| 865 | |
| 866 | switch (offset) |
| 867 | { |
| 868 | case 0: /* Control */ |
| 869 | if (!(data & 0x08)) /* it's not ram */ |
| 870 | { |
| 871 | if (!(sms_state.bios_port & IO_BIOS_ROM) && sms_state.has_bios) |
| 872 | { |
| 873 | SOURCE = sms_state.banking_bios[5]; |
| 874 | memory_set_bankptr(space->machine, "bank5", SOURCE); |
| 875 | memory_set_bankptr(space->machine, "bank6", SOURCE + 0x2000); |
| 876 | } |
| 877 | } |
| 878 | break; |
| 879 | |
| 880 | case 1: /* Select 16k ROM bank for 0400-3FFF */ |
| 881 | sms_state.banking_bios[2] = SOURCE_BIOS + 0x0400; |
| 882 | memory_set_bankptr(space->machine, "bank2", SOURCE + 0x0400); |
| 883 | break; |
| 884 | |
| 885 | case 2: /* Select 16k ROM bank for 4000-7FFF */ |
| 886 | sms_state.banking_bios[3] = SOURCE_BIOS; |
| 887 | memory_set_bankptr(space->machine, "bank3", SOURCE); |
| 888 | memory_set_bankptr(space->machine, "bank4", SOURCE + 0x2000); |
| 889 | break; |
| 890 | |
| 891 | case 3: /* Select 16k ROM bank for 8000-BFFF */ |
| 892 | sms_state.banking_bios[5] = SOURCE_BIOS; |
| 893 | if (!(sms_state.mapper[0] & 0x08)) /* is RAM disabled? */ |
| 894 | { |
| 895 | memory_set_bankptr(space->machine, "bank5", SOURCE); |
| 896 | memory_set_bankptr(space->machine, "bank6", SOURCE + 0x2000); |
| 897 | } |
| 898 | break; |
| 899 | } |
| 900 | } |
| 901 | |
| 834 | 902 | WRITE8_HANDLER( sms_bios_w ) |
| 835 | 903 | { |
| 836 | 904 | sms_state.bios_port = data; |
| r8905 | r8906 | |
| 1283 | 1351 | if (strcmp(image.device().tag(), "cart16") == 0) |
| 1284 | 1352 | index = 15; |
| 1285 | 1353 | |
| 1354 | sms_state.cartridge[index].features = 0; |
| 1355 | |
| 1286 | 1356 | if (image.software_entry() == NULL) |
| 1287 | 1357 | { |
| 1288 | 1358 | size = image.length(); |
| r8905 | r8906 | |
| 1320 | 1390 | return IMAGE_INIT_FAIL; |
| 1321 | 1391 | } |
| 1322 | 1392 | else |
| 1393 | { |
| 1323 | 1394 | memcpy(sms_state.cartridge[index].ROM, image.get_software_region("rom") + offset, size); |
| 1324 | 1395 | |
| 1396 | // check for mapper feature (currently only KOREAN_NOBANK, but eventually we will add the other mappers as well) |
| 1397 | if (image.get_feature("pcb") != NULL) |
| 1398 | { |
| 1399 | const char *mapper = image.get_feature("pcb"); |
| 1400 | if (!strcmp(mapper, "korean_nobank")) |
| 1401 | sms_state.cartridge[index].features |= CF_KOREAN_NOBANK_MAPPER; |
| 1402 | } |
| 1403 | } |
| 1404 | |
| 1325 | 1405 | /* check the image */ |
| 1326 | 1406 | if (!sms_state.has_bios) |
| 1327 | 1407 | { |
| r8905 | r8906 | |
| 1331 | 1411 | } |
| 1332 | 1412 | } |
| 1333 | 1413 | |
| 1334 | | sms_state.cartridge[index].features = 0; |
| 1335 | | |
| 1336 | 1414 | /* Detect special features from the extrainfo field */ |
| 1337 | 1415 | if (extrainfo) |
| 1338 | 1416 | { |
| r8905 | r8906 | |
| 1424 | 1502 | memory_nop_write(program, 0xa000, 0xa000, 0, 0); |
| 1425 | 1503 | } |
| 1426 | 1504 | |
| 1505 | if (sms_state.cartridge[index].features & CF_KOREAN_NOBANK_MAPPER) |
| 1506 | { |
| 1507 | // FIXME: we should have by default FFFD-FFFF to be only a mirror for DFFD-DFFF (with no bankswitch logic) |
| 1508 | // and then the handlers should be installed here for all but the KOREAN_NOBANK carts |
| 1509 | // However, to avoid memory map breakage, we currently go the other way around |
| 1510 | address_space *program = cputag_get_address_space(image.device().machine, "maincpu", ADDRESS_SPACE_PROGRAM); |
| 1511 | memory_install_readwrite8_handler(program, 0xfffc, 0xffff, 0, 0, &sms_kor_nobank_r, &sms_kor_nobank_w); |
| 1512 | } |
| 1513 | |
| 1427 | 1514 | LOG(("Cart Features: %x\n", sms_state.cartridge[index].features)); |
| 1428 | 1515 | |
| 1429 | 1516 | /* Load battery backed RAM, if available */ |