trunk/src/mame/machine/snes.c
| r21632 | r21633 | |
| 693 | 693 | value = snes_open_bus_r(space, 0); /* Reserved */ |
| 694 | 694 | } |
| 695 | 695 | else |
| 696 | | value = snes_ram[offset]; |
| 696 | value = snes_ram[offset]; //ROM |
| 697 | 697 | |
| 698 | 698 | return value; |
| 699 | 699 | } |
| r21632 | r21633 | |
| 711 | 711 | value = state->snes_r_io(space, address); |
| 712 | 712 | else if (address < 0x8000) /* SRAM for mode_21, Reserved othewise */ |
| 713 | 713 | { |
| 714 | | if (state->m_cart[0].mode == SNES_MODE_21 && state->m_cart[0].sram > 0) |
| 714 | if (state->m_cart[0].mode == SNES_MODE_21 && state->m_cart[0].m_nvram_size > 0) |
| 715 | 715 | { |
| 716 | 716 | /* Donkey Kong Country checks this and detects a copier if 0x800 is not masked out due to sram size */ |
| 717 | 717 | /* OTOH Secret of Mana does not work properly if sram is not mirrored on later banks */ |
| 718 | | int mask = (state->m_cart[0].sram - 1) & 0x7fff; /* Limit SRAM size to what's actually present */ |
| 719 | | value = snes_ram[0x306000 + ((offset - 0x6000) & mask)]; |
| 718 | int mask = (state->m_cart[0].m_nvram_size - 1) & 0x7fff; /* Limit SRAM size to what's actually present */ |
| 719 | value = state->m_cart[0].m_nvram[(offset - 0x6000) & mask]; |
| 720 | 720 | } |
| 721 | 721 | else |
| 722 | 722 | { |
| r21632 | r21633 | |
| 725 | 725 | } |
| 726 | 726 | } |
| 727 | 727 | else |
| 728 | | value = snes_ram[0x300000 + offset]; |
| 728 | value = snes_ram[0x300000 + offset]; //ROM |
| 729 | 729 | |
| 730 | 730 | return value; |
| 731 | 731 | } |
| r21632 | r21633 | |
| 742 | 742 | if ((address < 0x8000) && (state->m_cart[0].mode == SNES_MODE_20)) |
| 743 | 743 | value = snes_open_bus_r(space, 0); /* Reserved */ |
| 744 | 744 | else |
| 745 | | value = snes_ram[0x400000 + offset]; |
| 745 | value = snes_ram[0x400000 + offset]; //ROM |
| 746 | 746 | } |
| 747 | 747 | else /* Mode 21 & 25 */ |
| 748 | | value = snes_ram[0x400000 + offset]; |
| 748 | value = snes_ram[0x400000 + offset]; //ROM |
| 749 | 749 | |
| 750 | 750 | return value; |
| 751 | 751 | } |
| r21632 | r21633 | |
| 760 | 760 | if (state->m_cart[0].mode & 5) /* Mode 20 & 22 */ |
| 761 | 761 | { |
| 762 | 762 | if (address >= 0x8000) |
| 763 | | value = snes_ram[0x600000 + offset]; |
| 763 | value = snes_ram[0x600000 + offset]; //ROM |
| 764 | 764 | else |
| 765 | 765 | { |
| 766 | 766 | logerror("(PC=%06x) snes_r_bank4: Unmapped external chip read: %04x\n",space.device().safe_pc(),address); |
| r21632 | r21633 | |
| 768 | 768 | } |
| 769 | 769 | } |
| 770 | 770 | else if (state->m_cart[0].mode & 0x0a) /* Mode 21 & 25 */ |
| 771 | | value = snes_ram[0x600000 + offset]; |
| 771 | value = snes_ram[0x600000 + offset]; //ROM |
| 772 | 772 | |
| 773 | 773 | return value; |
| 774 | 774 | } |
| r21632 | r21633 | |
| 782 | 782 | |
| 783 | 783 | if ((state->m_cart[0].mode & 5) && (address < 0x8000)) /* Mode 20 & 22 */ |
| 784 | 784 | { |
| 785 | | if (state->m_cart[0].sram > 0x8000) |
| 785 | if (state->m_cart[0].m_nvram_size > 0x8000) |
| 786 | 786 | { |
| 787 | 787 | // In this case, SRAM is mapped in 0x8000 chunks at diff offsets: 0x700000-0x707fff, 0x710000-0x717fff, etc. |
| 788 | | int mask = (state->m_cart[0].sram << 1) - 1; |
| 789 | | mask &= ~0x8000; |
| 790 | | value = snes_ram[0x700000 + (offset & mask)]; |
| 788 | int mask = state->m_cart[0].m_nvram_size - 1; |
| 789 | offset = (offset / 0x10000) * 0x8000 + (offset & 0x7fff); |
| 790 | value = state->m_cart[0].m_nvram[offset & mask]; |
| 791 | 791 | } |
| 792 | | else if (state->m_cart[0].sram > 0) |
| 792 | else if (state->m_cart[0].m_nvram_size > 0) |
| 793 | 793 | { |
| 794 | | int mask = state->m_cart[0].sram - 1; /* Limit SRAM size to what's actually present */ |
| 795 | | value = snes_ram[0x700000 + (offset & mask)]; |
| 794 | int mask = state->m_cart[0].m_nvram_size - 1; /* Limit SRAM size to what's actually present */ |
| 795 | value = state->m_cart[0].m_nvram[offset & mask]; |
| 796 | 796 | } |
| 797 | 797 | else |
| 798 | 798 | { |
| r21632 | r21633 | |
| 801 | 801 | } |
| 802 | 802 | } |
| 803 | 803 | else |
| 804 | | value = snes_ram[0x700000 + offset]; |
| 804 | value = snes_ram[0x700000 + offset]; //ROM |
| 805 | 805 | |
| 806 | 806 | return value; |
| 807 | 807 | } |
| r21632 | r21633 | |
| 814 | 814 | if ((offset & 0xffff) < 0x8000) |
| 815 | 815 | value = space.read_byte(offset); |
| 816 | 816 | else |
| 817 | | value = snes_ram[0x800000 + offset]; |
| 817 | value = snes_ram[0x800000 + offset]; //ROM |
| 818 | 818 | |
| 819 | 819 | return value; |
| 820 | 820 | } |
| r21632 | r21633 | |
| 826 | 826 | UINT8 value = 0; |
| 827 | 827 | UINT16 address = offset & 0xffff; |
| 828 | 828 | |
| 829 | | if (state->m_cart[0].mode & 5) /* Mode 20 & 22 */ |
| 829 | if (state->m_cart[0].mode & 5 && address < 0x8000) /* Mode 20 & 22 in 0x0000-0x7fff */ |
| 830 | 830 | { |
| 831 | | if (address < 0x8000) |
| 831 | if (offset < 0x300000) |
| 832 | 832 | value = space.read_byte(0x400000 + offset); |
| 833 | 833 | else |
| 834 | | value = snes_ram[0xc00000 + offset]; |
| 834 | { |
| 835 | if (state->m_cart[0].m_nvram_size > 0x8000) |
| 836 | { |
| 837 | // In this case, SRAM is mapped in 0x8000 chunks at diff offsets: 0x700000-0x707fff, 0x710000-0x717fff, etc. |
| 838 | int mask = state->m_cart[0].m_nvram_size - 1; |
| 839 | offset = (offset / 0x10000) * 0x8000 + (offset & 0x7fff); |
| 840 | value = state->m_cart[0].m_nvram[offset & mask]; |
| 841 | } |
| 842 | else if (state->m_cart[0].m_nvram_size > 0) |
| 843 | { |
| 844 | int mask = state->m_cart[0].m_nvram_size - 1; /* Limit SRAM size to what's actually present */ |
| 845 | value = state->m_cart[0].m_nvram[offset & mask]; |
| 846 | } |
| 847 | } |
| 835 | 848 | } |
| 836 | | else /* Mode 21 & 25 */ |
| 837 | | value = snes_ram[0xc00000 + offset]; |
| 849 | else |
| 850 | value = snes_ram[0xc00000 + offset]; //ROM |
| 838 | 851 | |
| 839 | 852 | return value; |
| 840 | 853 | } |
| r21632 | r21633 | |
| 868 | 881 | state->snes_w_io(space, address, data); |
| 869 | 882 | else if (address < 0x8000) /* SRAM for mode_21, Reserved othewise */ |
| 870 | 883 | { |
| 871 | | if ((state->m_cart[0].mode == SNES_MODE_21) && (state->m_cart[0].sram > 0)) |
| 884 | if (state->m_cart[0].mode == SNES_MODE_21 && state->m_cart[0].m_nvram_size > 0) |
| 872 | 885 | { |
| 873 | 886 | /* Donkey Kong Country checks this and detects a copier if 0x800 is not masked out due to sram size */ |
| 874 | 887 | /* OTOH Secret of Mana does not work properly if sram is not mirrored on later banks */ |
| 875 | | int mask = (state->m_cart[0].sram - 1) & 0x7fff; /* Limit SRAM size to what's actually present */ |
| 876 | | snes_ram[0x306000 + ((offset - 0x6000) & mask)] = data; |
| 888 | int mask = (state->m_cart[0].m_nvram_size - 1) & 0x7fff; /* Limit SRAM size to what's actually present */ |
| 889 | state->m_cart[0].m_nvram[(offset - 0x6000) & mask] = data; |
| 877 | 890 | } |
| 878 | 891 | else |
| 879 | 892 | logerror("snes_w_bank2: Attempt to write to reserved address: %X = %02x\n", offset + 0x300000, data); |
| r21632 | r21633 | |
| 907 | 920 | |
| 908 | 921 | if ((state->m_cart[0].mode & 5) && (address < 0x8000)) /* Mode 20 & 22 */ |
| 909 | 922 | { |
| 910 | | if (state->m_cart[0].sram > 0x8000) |
| 923 | if (state->m_cart[0].m_nvram_size > 0x8000) |
| 911 | 924 | { |
| 912 | 925 | // In this case, SRAM is mapped in 0x8000 chunks at diff offsets: 0x700000-0x707fff, 0x710000-0x717fff, etc. |
| 913 | | int mask = (state->m_cart[0].sram << 1) - 1; |
| 914 | | mask &= ~0x8000; |
| 915 | | snes_ram[0x700000 + (offset & mask)] = data; |
| 926 | int mask = state->m_cart[0].m_nvram_size - 1; |
| 927 | offset = (offset / 0x10000) * 0x8000 + (offset & 0x7fff); |
| 928 | state->m_cart[0].m_nvram[offset & mask] = data; |
| 916 | 929 | } |
| 917 | | else if (state->m_cart[0].sram > 0) |
| 930 | else if (state->m_cart[0].m_nvram_size > 0) |
| 918 | 931 | { |
| 919 | | int mask = state->m_cart[0].sram - 1; /* Limit SRAM size to what's actually present */ |
| 920 | | snes_ram[0x700000 + (offset & mask)] = data; |
| 932 | int mask = state->m_cart[0].m_nvram_size - 1; /* Limit SRAM size to what's actually present */ |
| 933 | state->m_cart[0].m_nvram[offset & mask] = data; |
| 921 | 934 | } |
| 922 | 935 | else |
| 923 | 936 | logerror("snes_w_bank5: Attempt to write to reserved address: %X = %02x\n", offset + 0x700000, data); |
| r21632 | r21633 | |
| 943 | 956 | snes_state *state = space.machine().driver_data<snes_state>(); |
| 944 | 957 | UINT16 address = offset & 0xffff; |
| 945 | 958 | |
| 946 | | if (state->m_cart[0].mode & 5) /* Mode 20 & 22 */ |
| 959 | if (state->m_cart[0].mode & 5 && address < 0x8000) /* Mode 20 & 22 in 0x0000-0x7fff */ |
| 947 | 960 | { |
| 948 | | if (address < 0x8000) |
| 961 | if (offset >= 0x300000) |
| 949 | 962 | { |
| 950 | | if (offset >= 0x3e0000) |
| 951 | | logerror("Attempt to write to banks 0xfe - 0xff address: %X\n", offset); |
| 952 | | else if (offset >= 0x300000) |
| 953 | | snes_w_bank5(space, offset - 0x300000, data); |
| 954 | | else if (offset >= 0x200000) |
| 955 | | snes_w_bank4(space, offset - 0x200000, data); |
| 963 | if (state->m_cart[0].m_nvram_size > 0x8000) |
| 964 | { |
| 965 | // In this case, SRAM is mapped in 0x8000 chunks at diff offsets: 0x700000-0x707fff, 0x710000-0x717fff, etc. |
| 966 | int mask = state->m_cart[0].m_nvram_size - 1; |
| 967 | offset = (offset / 0x10000) * 0x8000 + (offset & 0x7fff); |
| 968 | state->m_cart[0].m_nvram[offset & mask] = data; |
| 969 | return; |
| 970 | } |
| 971 | else if (state->m_cart[0].m_nvram_size > 0) |
| 972 | { |
| 973 | int mask = state->m_cart[0].m_nvram_size - 1; /* Limit SRAM size to what's actually present */ |
| 974 | state->m_cart[0].m_nvram[offset & mask] = data; |
| 975 | return; |
| 976 | } |
| 956 | 977 | } |
| 957 | | else |
| 958 | | logerror("(PC=%06x) snes_w_bank7: Attempt to write to ROM address: %X = %02x\n",space.device().safe_pc(),offset + 0xc00000, data); |
| 978 | logerror("(PC=%06x) snes_w_bank7: Attempt to write to ROM address: %X = %02x\n",space.device().safe_pc(),offset + 0xc00000, data); |
| 959 | 979 | } |
| 960 | 980 | else if (state->m_cart[0].mode & 0x0a) |
| 961 | 981 | logerror("(PC=%06x) Attempt to write to ROM address: %X\n",space.device().safe_pc(),offset + 0xc00000); |
| r21632 | r21633 | |
| 1232 | 1252 | /* for mame we use an init, maybe we will need more for the different games */ |
| 1233 | 1253 | DRIVER_INIT_MEMBER(snes_state,snes) |
| 1234 | 1254 | { |
| 1235 | | address_space &space = machine().device("maincpu")->memory().space(AS_PROGRAM); |
| 1236 | 1255 | UINT16 total_blocks, read_blocks; |
| 1237 | 1256 | UINT8 *rom; |
| 1238 | 1257 | |
| 1239 | 1258 | rom = memregion("user3")->base(); |
| 1240 | 1259 | snes_ram = auto_alloc_array_clear(machine(), UINT8, 0x1400000); |
| 1241 | 1260 | |
| 1261 | m_cart[0].m_rom_size = memregion("user3")->bytes(); |
| 1262 | m_cart[0].m_rom = auto_alloc_array_clear(machine(), UINT8, m_cart[0].m_rom_size); |
| 1263 | memcpy(m_cart[0].m_rom, rom, m_cart[0].m_rom_size); |
| 1264 | |
| 1265 | m_cart[0].m_nvram_size = 0; |
| 1266 | if (rom[0x7fd8] > 0) |
| 1267 | { |
| 1268 | UINT32 nvram_size = (1024 << rom[0x7fd8]); |
| 1269 | if (nvram_size > 0x40000) |
| 1270 | nvram_size = 0x40000; |
| 1271 | |
| 1272 | m_cart[0].m_nvram = auto_alloc_array_clear(machine(), UINT8, nvram_size); |
| 1273 | m_cart[0].m_nvram_size = nvram_size; |
| 1274 | } |
| 1275 | |
| 1242 | 1276 | /* all NSS games seem to use MODE 20 */ |
| 1243 | 1277 | m_cart[0].mode = SNES_MODE_20; |
| 1244 | | m_cart[0].sram_max = 0x40000; |
| 1245 | 1278 | m_has_addon_chip = HAS_NONE; |
| 1246 | 1279 | |
| 1247 | 1280 | /* Find the number of blocks in this ROM */ |
| r21632 | r21633 | |
| 1284 | 1317 | |
| 1285 | 1318 | read_blocks += repeat_blocks; |
| 1286 | 1319 | } |
| 1287 | | |
| 1288 | | /* Find the amount of sram */ |
| 1289 | | m_cart[0].sram = snes_r_bank1(space, 0x00ffd8); |
| 1290 | | if (m_cart[0].sram > 0) |
| 1291 | | { |
| 1292 | | m_cart[0].sram = (1024 << m_cart[0].sram); |
| 1293 | | if (m_cart[0].sram > m_cart[0].sram_max) |
| 1294 | | m_cart[0].sram = m_cart[0].sram_max; |
| 1295 | | } |
| 1296 | 1320 | } |
| 1297 | 1321 | |
| 1298 | 1322 | DRIVER_INIT_MEMBER(snes_state,snes_hirom) |
| 1299 | 1323 | { |
| 1300 | | address_space &space = machine().device("maincpu")->memory().space(AS_PROGRAM); |
| 1301 | 1324 | UINT16 total_blocks, read_blocks; |
| 1302 | 1325 | UINT8 *rom; |
| 1303 | 1326 | |
| r21632 | r21633 | |
| 1305 | 1328 | snes_ram = auto_alloc_array(machine(), UINT8, 0x1400000); |
| 1306 | 1329 | memset(snes_ram, 0, 0x1400000); |
| 1307 | 1330 | |
| 1331 | m_cart[0].m_rom_size = memregion("user3")->bytes(); |
| 1332 | m_cart[0].m_rom = auto_alloc_array_clear(machine(), UINT8, m_cart[0].m_rom_size); |
| 1333 | memcpy(m_cart[0].m_rom, rom, m_cart[0].m_rom_size); |
| 1334 | |
| 1335 | m_cart[0].m_nvram_size = 0; |
| 1336 | if (rom[0xffd8] > 0) |
| 1337 | { |
| 1338 | UINT32 nvram_size = (1024 << rom[0xffd8]); |
| 1339 | if (nvram_size > 0x40000) |
| 1340 | nvram_size = 0x40000; |
| 1341 | |
| 1342 | m_cart[0].m_nvram = auto_alloc_array_clear(machine(), UINT8, nvram_size); |
| 1343 | m_cart[0].m_nvram_size = nvram_size; |
| 1344 | } |
| 1345 | |
| 1308 | 1346 | m_cart[0].mode = SNES_MODE_21; |
| 1309 | | m_cart[0].sram_max = 0x40000; |
| 1310 | 1347 | m_has_addon_chip = HAS_NONE; |
| 1311 | 1348 | |
| 1312 | 1349 | /* Find the number of blocks in this ROM */ |
| r21632 | r21633 | |
| 1343 | 1380 | memcpy(&snes_ram[0x800000 + read_blocks * 0x10000], &snes_ram[0x800000 + (read_blocks - repeat_blocks) * 0x10000], repeat_blocks * 0x10000); |
| 1344 | 1381 | read_blocks += repeat_blocks; |
| 1345 | 1382 | } |
| 1346 | | |
| 1347 | | /* Find the amount of sram */ |
| 1348 | | m_cart[0].sram = snes_r_bank1(space, 0x00ffd8); |
| 1349 | | if (m_cart[0].sram > 0) |
| 1350 | | { |
| 1351 | | m_cart[0].sram = (1024 << m_cart[0].sram); |
| 1352 | | if (m_cart[0].sram > m_cart[0].sram_max) |
| 1353 | | m_cart[0].sram = m_cart[0].sram_max; |
| 1354 | | } |
| 1355 | 1383 | } |
| 1356 | 1384 | |
| 1357 | 1385 | |
trunk/src/mess/machine/snescart.c
| r21632 | r21633 | |
| 123 | 123 | static void snes_load_sram(running_machine &machine) |
| 124 | 124 | { |
| 125 | 125 | snes_state *state = machine.driver_data<snes_state>(); |
| 126 | | UINT8 ii; |
| 127 | | UINT8 *battery_ram, *ptr; |
| 128 | | |
| 129 | | battery_ram = (UINT8*)malloc(state->m_cart[0].sram_max); |
| 130 | | ptr = battery_ram; |
| 131 | 126 | device_image_interface *image = dynamic_cast<device_image_interface *>(machine.device("cart")); |
| 132 | | image->battery_load(battery_ram, state->m_cart[0].sram_max, 0xff); |
| 133 | | |
| 134 | | if (state->m_cart[0].mode == SNES_MODE_20) |
| 135 | | { |
| 136 | | UINT32 size = state->m_cart[0].small_sram ? 0x8000 : 0x10000; |
| 137 | | |
| 138 | | /* There could be some larger image needing banks 0x70 to 0x7f at address 0x8000 for ROM |
| 139 | | * mirroring. These should be treated separately or data would be overwritten by SRAM */ |
| 140 | | for (ii = 0; ii < 16; ii++) |
| 141 | | { |
| 142 | | /* loading */ |
| 143 | | memmove(&snes_ram[0x700000 + (ii * 0x010000)], ptr, size); |
| 144 | | /* mirroring */ |
| 145 | | memcpy(&snes_ram[0xf00000 + (ii * 0x010000)], &snes_ram[0x700000 + (ii * 0x010000)], size); |
| 146 | | ptr += size; |
| 147 | | } |
| 148 | | } |
| 149 | | else if (state->m_cart[0].mode == SNES_MODE_21) |
| 150 | | { |
| 151 | | for (ii = 0; ii < 16; ii++) |
| 152 | | { |
| 153 | | /* loading */ |
| 154 | | memmove(&snes_ram[0x306000 + (ii * 0x010000)], ptr, 0x2000); |
| 155 | | /* mirroring */ |
| 156 | | memcpy(&snes_ram[0xb06000 + (ii * 0x010000)], &snes_ram[0x306000 + (ii * 0x010000)], 0x2000); |
| 157 | | ptr += 0x2000; |
| 158 | | } |
| 159 | | } |
| 160 | | else if (state->m_cart[0].mode == SNES_MODE_25) |
| 161 | | { |
| 162 | | for (ii = 0; ii < 16; ii++) |
| 163 | | { |
| 164 | | memmove(&snes_ram[0xb06000 + (ii * 0x010000)], ptr, 0x2000); |
| 165 | | ptr += 0x2000; |
| 166 | | } |
| 167 | | } |
| 168 | | |
| 169 | | free(battery_ram); |
| 127 | image->battery_load(state->m_cart[0].m_nvram, state->m_cart[0].m_nvram_size, 0xff); |
| 170 | 128 | } |
| 171 | 129 | |
| 172 | 130 | /* Saves the battery backed RAM from the appropriate memory area */ |
| 173 | 131 | static void snes_save_sram(running_machine &machine) |
| 174 | 132 | { |
| 175 | 133 | snes_state *state = machine.driver_data<snes_state>(); |
| 176 | | UINT8 ii; |
| 177 | | UINT8 *battery_ram, *ptr; |
| 178 | | |
| 179 | | battery_ram = (UINT8*)malloc(state->m_cart[0].sram_max); |
| 180 | | ptr = battery_ram; |
| 181 | | |
| 182 | | if (state->m_cart[0].mode == SNES_MODE_20) |
| 183 | | { |
| 184 | | UINT32 size = state->m_cart[0].small_sram ? 0x8000 : 0x10000; |
| 185 | | |
| 186 | | for (ii = 0; ii < 16; ii++) |
| 187 | | { |
| 188 | | memmove(ptr, &snes_ram[0x700000 + (ii * 0x010000)], size); |
| 189 | | ptr += size; |
| 190 | | } |
| 191 | | } |
| 192 | | else if (state->m_cart[0].mode == SNES_MODE_21) |
| 193 | | { |
| 194 | | for (ii = 0; ii < 16; ii++) |
| 195 | | { |
| 196 | | memmove(ptr, &snes_ram[0x306000 + (ii * 0x010000)], 0x2000); |
| 197 | | ptr += 0x2000; |
| 198 | | } |
| 199 | | } |
| 200 | | else if (state->m_cart[0].mode == SNES_MODE_25) |
| 201 | | { |
| 202 | | for (ii = 0; ii < 16; ii++) |
| 203 | | { |
| 204 | | memmove(ptr, &snes_ram[0xb06000 + (ii * 0x010000)], 0x2000); |
| 205 | | ptr += 0x2000; |
| 206 | | } |
| 207 | | } |
| 208 | 134 | device_image_interface *image = dynamic_cast<device_image_interface *>(machine.device("cart")); |
| 209 | | image->battery_save(battery_ram, state->m_cart[0].sram_max); |
| 210 | | |
| 211 | | free(battery_ram); |
| 135 | image->battery_save(state->m_cart[0].m_nvram, state->m_cart[0].m_nvram_size); |
| 212 | 136 | } |
| 213 | 137 | |
| 214 | 138 | void snes_machine_stop(running_machine &machine) |
| r21632 | r21633 | |
| 216 | 140 | snes_state *state = machine.driver_data<snes_state>(); |
| 217 | 141 | |
| 218 | 142 | /* Save SRAM */ |
| 219 | | if (state->m_cart[0].sram > 0) |
| 143 | if (state->m_cart[0].m_nvram_size > 0) |
| 220 | 144 | snes_save_sram(machine); |
| 221 | 145 | } |
| 222 | 146 | |
| r21632 | r21633 | |
| 437 | 361 | |
| 438 | 362 | |
| 439 | 363 | /* This determines if a cart is in Mode 20, 21, 22 or 25; sets state->m_cart[0].mode and |
| 440 | | state->m_cart[0].sram accordingly; and returns the offset of the internal header (needed to |
| 441 | | detect BSX and ST carts) */ |
| 364 | state->m_cart[0].sram_max accordingly; and returns the offset of the internal header |
| 365 | (needed to detect BSX and ST carts) */ |
| 442 | 366 | static UINT32 snes_find_hilo_mode( device_image_interface &image, UINT8 *buffer, UINT32 offset, int cartid ) |
| 443 | 367 | { |
| 444 | 368 | snes_state *state = image.device().machine().driver_data<snes_state>(); |
| r21632 | r21633 | |
| 731 | 655 | logerror( " [%d]\n", snes_r_bank1(space, 0x00ffd6) ); |
| 732 | 656 | |
| 733 | 657 | logerror( "\tSize: %d megabits [%d]\n", 1 << (snes_r_bank1(space, 0x00ffd7) - 7), snes_r_bank1(space, 0x00ffd7) ); |
| 734 | | logerror( "\tSRAM: %d kilobits [%d]\n", state->m_cart[0].sram * 8, snes_ram[0xffd8] ); |
| 658 | logerror( "\tSRAM: %d kilobits [%d]\n", state->m_cart[0].m_nvram_size * 8, snes_ram[0xffd8] ); |
| 735 | 659 | logerror( "\tCountry: %s [%d]\n", countries[snes_r_bank1(space, 0x00ffd9)], snes_r_bank1(space, 0x00ffd9) ); |
| 736 | 660 | logerror( "\tLicense: %s [%X]\n", companies[snes_r_bank1(space, 0x00ffda)], snes_r_bank1(space, 0x00ffda) ); |
| 737 | 661 | logerror( "\tVersion: 1.%d\n", snes_r_bank1(space, 0x00ffdb) ); |
| r21632 | r21633 | |
| 773 | 697 | |
| 774 | 698 | if (SNES_CART_DEBUG) mame_printf_error("size %08X\n", m_cart_size - offset); |
| 775 | 699 | |
| 700 | m_cart[0].m_rom_size = m_cart_size; |
| 701 | m_cart[0].m_rom = auto_alloc_array_clear(machine, UINT8, m_cart[0].m_rom_size); |
| 702 | memcpy(m_cart[0].m_rom, ROM, m_cart[0].m_rom_size - offset); |
| 703 | |
| 776 | 704 | /* First, look if the cart is HiROM or LoROM (and set snes_cart accordingly) */ |
| 777 | 705 | int_header_offs = snes_find_hilo_mode(image, ROM, offset, 0); |
| 778 | 706 | |
| r21632 | r21633 | |
| 914 | 842 | /* Loading data */ |
| 915 | 843 | memcpy(&snes_ram[0xc00000 + read_blocks * 0x10000], &ROM[0x000000 + read_blocks * 0x10000], 0x10000); |
| 916 | 844 | /* Mirroring */ |
| 917 | | memcpy( &snes_ram[0x808000 + read_blocks * 0x10000], &snes_ram[0xc08000 + read_blocks * 0x10000], 0x8000); |
| 845 | memcpy(&snes_ram[0x808000 + read_blocks * 0x10000], &snes_ram[0xc08000 + read_blocks * 0x10000], 0x8000); |
| 918 | 846 | read_blocks++; |
| 919 | 847 | } |
| 920 | 848 | /* ExHiROMs are supposed to be larger than 32Mbits! */ |
| r21632 | r21633 | |
| 1066 | 994 | j++; |
| 1067 | 995 | repeat_blocks = read_blocks % (128 >> (j - 1)); |
| 1068 | 996 | |
| 1069 | | memcpy( &snes_ram[read_blocks * 0x10000], &snes_ram[(read_blocks - repeat_blocks) * 0x10000], repeat_blocks * 0x10000); |
| 1070 | | memcpy( &snes_ram[0x800000 + read_blocks * 0x10000], &snes_ram[(read_blocks - repeat_blocks) * 0x10000], repeat_blocks * 0x10000); |
| 997 | memcpy(&snes_ram[read_blocks * 0x10000], &snes_ram[(read_blocks - repeat_blocks) * 0x10000], repeat_blocks * 0x10000); |
| 998 | memcpy(&snes_ram[0x800000 + read_blocks * 0x10000], &snes_ram[(read_blocks - repeat_blocks) * 0x10000], repeat_blocks * 0x10000); |
| 1071 | 999 | read_blocks += repeat_blocks; |
| 1072 | 1000 | } |
| 1073 | 1001 | } |
| r21632 | r21633 | |
| 1077 | 1005 | /* Detect special chips */ |
| 1078 | 1006 | supported_type = snes_find_addon_chip(machine); |
| 1079 | 1007 | |
| 1080 | | /* Find the amount of cart ram (even if we call it sram...) */ |
| 1008 | /* Find the amount of cart ram */ |
| 1009 | m_cart[0].m_nvram_size = 0; |
| 1081 | 1010 | if (image.software_entry() == NULL) |
| 1082 | 1011 | { |
| 1012 | UINT32 nvram_size; |
| 1083 | 1013 | if ((m_has_addon_chip != HAS_SUPERFX)) |
| 1084 | | m_cart[0].sram = snes_r_bank1(space, 0x00ffd8); |
| 1014 | nvram_size = snes_r_bank1(space, 0x00ffd8); |
| 1085 | 1015 | else |
| 1086 | | m_cart[0].sram = (snes_r_bank1(space, 0x00ffbd) & 0x07); |
| 1016 | nvram_size = (snes_r_bank1(space, 0x00ffbd) & 0x07); |
| 1087 | 1017 | |
| 1088 | | if (m_cart[0].sram > 0) |
| 1018 | if (nvram_size > 0) |
| 1089 | 1019 | { |
| 1090 | | m_cart[0].sram = (1024 << m_cart[0].sram); |
| 1091 | | if (m_cart[0].sram > m_cart[0].sram_max) |
| 1092 | | m_cart[0].sram = m_cart[0].sram_max; |
| 1020 | nvram_size = (1024 << nvram_size); |
| 1021 | if (nvram_size > m_cart[0].sram_max) |
| 1022 | nvram_size = m_cart[0].sram_max; |
| 1023 | |
| 1024 | m_cart[0].m_nvram_size = nvram_size; |
| 1093 | 1025 | } |
| 1094 | | // printf("size %x\n", m_cart[0].sram); |
| 1026 | // printf("size %x\n", m_cart[0].m_nvram_size); |
| 1095 | 1027 | } |
| 1096 | 1028 | else |
| 1097 | 1029 | { |
| 1098 | 1030 | // if we are loading from softlist, take memory length from the xml |
| 1099 | | m_cart[0].sram = image.get_software_region("nvram") ? image.get_software_region_length("nvram") : 0; |
| 1031 | m_cart[0].m_nvram_size = image.get_software_region("nvram") ? image.get_software_region_length("nvram") : 0; |
| 1100 | 1032 | |
| 1101 | | if (m_cart[0].sram > 0) |
| 1033 | if (m_cart[0].m_nvram_size > 0) |
| 1102 | 1034 | { |
| 1103 | | if (m_cart[0].sram > m_cart[0].sram_max) |
| 1104 | | fatalerror("Found more memory than max allowed (found: %x, max: %x), check xml file!\n", m_cart[0].sram, m_cart[0].sram_max); |
| 1035 | if (m_cart[0].m_nvram_size > m_cart[0].sram_max) |
| 1036 | fatalerror("Found more memory than max allowed (found: %x, max: %x), check xml file!\n", m_cart[0].m_nvram_size, m_cart[0].sram_max); |
| 1105 | 1037 | } |
| 1106 | 1038 | // TODO: Eventually sram handlers should point to the allocated cart:sram region! |
| 1107 | 1039 | // For now, we only use the region as a placeholder to carry size info... |
| 1108 | | // printf("size %x\n", m_cart[0].sram); |
| 1040 | // printf("size %x\n", m_cart[0].m_nvram_size); |
| 1109 | 1041 | } |
| 1110 | 1042 | |
| 1111 | | /* adjust size for very large carts */ |
| 1112 | | if (m_cart[0].mode == SNES_MODE_20 && ((m_cart_size - offset) > 0x200000 || m_cart[0].sram > (32 * 1024))) |
| 1113 | | m_cart[0].small_sram = 1; |
| 1114 | | else |
| 1115 | | m_cart[0].small_sram = 0; |
| 1043 | if (m_cart[0].m_nvram_size > 0) |
| 1044 | m_cart[0].m_nvram = auto_alloc_array_clear(machine, UINT8, m_cart[0].m_nvram_size); |
| 1116 | 1045 | |
| 1117 | 1046 | /* Log snes_cart information */ |
| 1118 | 1047 | snes_cart_log_info(machine, total_blocks, supported_type); |
| r21632 | r21633 | |
| 1219 | 1148 | read_blocks += repeat_blocks; |
| 1220 | 1149 | } |
| 1221 | 1150 | |
| 1151 | // currently we still use snes_ram for STROM ram... |
| 1152 | // m_cart[slot_id].m_nvram_size = 0x20000; |
| 1153 | // m_cart[slot_id].m_nvram = auto_alloc_array_clear(machine, UINT8, m_cart[slot_id].m_nvram_size); |
| 1154 | m_cart[slot_id].m_nvram_size = 0; |
| 1155 | |
| 1222 | 1156 | sufami_load_sram(machine, image.device().tag()); |
| 1223 | 1157 | |
| 1224 | 1158 | m_cart[slot_id].slot_in_use = 1; // aknowledge the cart in this slot, for saving sram at exit |