trunk/src/mame/machine/snes.c
| r22739 | r22740 | |
| 678 | 678 | UINT8 value = 0xff; |
| 679 | 679 | UINT8 base_bank = (offset < 0x800000) ? 0x80 : 0x00; |
| 680 | 680 | |
| 681 | | switch (m_cart[0].mode) |
| 681 | switch (m_cart.mode) |
| 682 | 682 | { |
| 683 | 683 | case SNES_MODE_20: |
| 684 | 684 | case SNES_MODE_22: |
| 685 | | addr = (m_cart[0].rom_bank_map[offset/0x10000] * 0x8000) + (offset & 0x7fff); |
| 686 | | value = m_cart[0].m_rom[addr]; |
| 685 | addr = (m_cart.rom_bank_map[offset/0x10000] * 0x8000) + (offset & 0x7fff); |
| 686 | value = m_cart.m_rom[addr]; |
| 687 | 687 | break; |
| 688 | 688 | case SNES_MODE_21: |
| 689 | 689 | case SNES_MODE_25: |
| 690 | 690 | offset &= 0x3fffff; |
| 691 | | addr = (m_cart[0].rom_bank_map[base_bank + (offset/0x8000)] * 0x8000) + (offset & 0x7fff); |
| 692 | | value = m_cart[0].m_rom[addr]; |
| 691 | addr = (m_cart.rom_bank_map[base_bank + (offset/0x8000)] * 0x8000) + (offset & 0x7fff); |
| 692 | value = m_cart.m_rom[addr]; |
| 693 | 693 | break; |
| 694 | 694 | } |
| 695 | 695 | |
| r22739 | r22740 | |
| 710 | 710 | value = snes_r_io(space, address); |
| 711 | 711 | else if (address < 0x8000) |
| 712 | 712 | { |
| 713 | | if (offset >= 0x300000 && m_cart[0].mode == SNES_MODE_21 && m_cart[0].m_nvram_size > 0) |
| 713 | if (offset >= 0x300000 && m_cart.mode == SNES_MODE_21 && m_cart.m_nvram_size > 0) |
| 714 | 714 | { |
| 715 | 715 | /* Donkey Kong Country checks this and detects a copier if 0x800 is not masked out due to sram size */ |
| 716 | 716 | /* OTOH Secret of Mana does not work properly if sram is not mirrored on later banks */ |
| 717 | | int mask = (m_cart[0].m_nvram_size - 1) & 0x7fff; /* Limit SRAM size to what's actually present */ |
| 718 | | value = m_cart[0].m_nvram[(offset - 0x6000) & mask]; |
| 717 | int mask = (m_cart.m_nvram_size - 1) & 0x7fff; /* Limit SRAM size to what's actually present */ |
| 718 | value = m_cart.m_nvram[(offset - 0x6000) & mask]; |
| 719 | 719 | } |
| 720 | 720 | else |
| 721 | 721 | value = snes_open_bus_r(space, 0); /* Reserved */ |
| r22739 | r22740 | |
| 725 | 725 | } |
| 726 | 726 | else if (offset < 0x700000) |
| 727 | 727 | { |
| 728 | | if (m_cart[0].mode & 5 && address < 0x8000) /* Mode 20 & 22 in 0x0000-0x7fff */ |
| 728 | if (m_cart.mode & 5 && address < 0x8000) /* Mode 20 & 22 in 0x0000-0x7fff */ |
| 729 | 729 | value = snes_open_bus_r(space, 0); |
| 730 | 730 | else |
| 731 | 731 | value = snes_rom_access(offset); //ROM |
| 732 | 732 | } |
| 733 | 733 | else |
| 734 | 734 | { |
| 735 | | if (m_cart[0].mode & 5 && address < 0x8000) /* Mode 20 & 22 */ |
| 735 | if (m_cart.mode & 5 && address < 0x8000) /* Mode 20 & 22 */ |
| 736 | 736 | { |
| 737 | | if (m_cart[0].m_nvram_size > 0x8000) |
| 737 | if (m_cart.m_nvram_size > 0x8000) |
| 738 | 738 | { |
| 739 | 739 | // In this case, SRAM is mapped in 0x8000 chunks at diff offsets: 0x700000-0x707fff, 0x710000-0x717fff, etc. |
| 740 | | int mask = m_cart[0].m_nvram_size - 1; |
| 740 | int mask = m_cart.m_nvram_size - 1; |
| 741 | 741 | offset = (offset / 0x10000) * 0x8000 + (offset & 0x7fff); |
| 742 | | value = m_cart[0].m_nvram[offset & mask]; |
| 742 | value = m_cart.m_nvram[offset & mask]; |
| 743 | 743 | } |
| 744 | | else if (m_cart[0].m_nvram_size > 0) |
| 744 | else if (m_cart.m_nvram_size > 0) |
| 745 | 745 | { |
| 746 | | int mask = m_cart[0].m_nvram_size - 1; /* Limit SRAM size to what's actually present */ |
| 747 | | value = m_cart[0].m_nvram[offset & mask]; |
| 746 | int mask = m_cart.m_nvram_size - 1; /* Limit SRAM size to what's actually present */ |
| 747 | value = m_cart.m_nvram[offset & mask]; |
| 748 | 748 | } |
| 749 | 749 | else |
| 750 | 750 | { |
| r22739 | r22740 | |
| 775 | 775 | } |
| 776 | 776 | else |
| 777 | 777 | { |
| 778 | | if (m_cart[0].mode & 5 && address < 0x8000) /* Mode 20 & 22 in 0x0000-0x7fff */ |
| 778 | if (m_cart.mode & 5 && address < 0x8000) /* Mode 20 & 22 in 0x0000-0x7fff */ |
| 779 | 779 | { |
| 780 | 780 | if (offset < 0x700000) |
| 781 | 781 | value = space.read_byte(offset); |
| 782 | 782 | else |
| 783 | 783 | { |
| 784 | | if (m_cart[0].m_nvram_size > 0x8000) |
| 784 | if (m_cart.m_nvram_size > 0x8000) |
| 785 | 785 | { |
| 786 | 786 | // In this case, SRAM is mapped in 0x8000 chunks at diff offsets: 0x700000-0x707fff, 0x710000-0x717fff, etc. |
| 787 | | int mask = m_cart[0].m_nvram_size - 1; |
| 787 | int mask = m_cart.m_nvram_size - 1; |
| 788 | 788 | offset = (offset / 0x10000) * 0x8000 + (offset & 0x7fff); |
| 789 | | value = m_cart[0].m_nvram[offset & mask]; |
| 789 | value = m_cart.m_nvram[offset & mask]; |
| 790 | 790 | } |
| 791 | | else if (m_cart[0].m_nvram_size > 0) |
| 791 | else if (m_cart.m_nvram_size > 0) |
| 792 | 792 | { |
| 793 | | int mask = m_cart[0].m_nvram_size - 1; /* Limit SRAM size to what's actually present */ |
| 794 | | value = m_cart[0].m_nvram[offset & mask]; |
| 793 | int mask = m_cart.m_nvram_size - 1; /* Limit SRAM size to what's actually present */ |
| 794 | value = m_cart.m_nvram[offset & mask]; |
| 795 | 795 | } |
| 796 | 796 | else |
| 797 | 797 | { |
| r22739 | r22740 | |
| 821 | 821 | snes_w_io(space, address, data); |
| 822 | 822 | else if (address < 0x8000) |
| 823 | 823 | { |
| 824 | | if (offset >= 0x300000 && m_cart[0].mode == SNES_MODE_21 && m_cart[0].m_nvram_size > 0) |
| 824 | if (offset >= 0x300000 && m_cart.mode == SNES_MODE_21 && m_cart.m_nvram_size > 0) |
| 825 | 825 | { |
| 826 | 826 | /* Donkey Kong Country checks this and detects a copier if 0x800 is not masked out due to sram size */ |
| 827 | 827 | /* OTOH Secret of Mana does not work properly if sram is not mirrored on later banks */ |
| 828 | | int mask = (m_cart[0].m_nvram_size - 1) & 0x7fff; /* Limit SRAM size to what's actually present */ |
| 829 | | m_cart[0].m_nvram[(offset - 0x6000) & mask] = data; |
| 828 | int mask = (m_cart.m_nvram_size - 1) & 0x7fff; /* Limit SRAM size to what's actually present */ |
| 829 | m_cart.m_nvram[(offset - 0x6000) & mask] = data; |
| 830 | 830 | } |
| 831 | 831 | else |
| 832 | 832 | logerror("(PC=%06x) snes_w_bank1: Attempt to write to reserved address: %X = %02X\n", space.device().safe_pc(), offset, data); |
| r22739 | r22740 | |
| 836 | 836 | } |
| 837 | 837 | else if (offset >= 0x600000 && offset < 0x700000) |
| 838 | 838 | { |
| 839 | | if (m_cart[0].mode & 5 && address < 0x8000) /* Mode 20 & 22 */ |
| 839 | if (m_cart.mode & 5 && address < 0x8000) /* Mode 20 & 22 */ |
| 840 | 840 | logerror("(PC=%06x) snes_w_bank1: Attempt to write to reserved address: %X = %02X\n", space.device().safe_pc(), offset, data); |
| 841 | 841 | else |
| 842 | 842 | logerror("(PC=%06x) Attempt to write to ROM address: %X\n", space.device().safe_pc(), offset); |
| 843 | 843 | } |
| 844 | 844 | else if (offset >= 0x700000) |
| 845 | 845 | { |
| 846 | | if (m_cart[0].mode & 5 && address < 0x8000) /* Mode 20 & 22 */ |
| 846 | if (m_cart.mode & 5 && address < 0x8000) /* Mode 20 & 22 */ |
| 847 | 847 | { |
| 848 | | if (m_cart[0].m_nvram_size > 0x8000) |
| 848 | if (m_cart.m_nvram_size > 0x8000) |
| 849 | 849 | { |
| 850 | 850 | // In this case, SRAM is mapped in 0x8000 chunks at diff offsets: 0x700000-0x707fff, 0x710000-0x717fff, etc. |
| 851 | | int mask = m_cart[0].m_nvram_size - 1; |
| 851 | int mask = m_cart.m_nvram_size - 1; |
| 852 | 852 | offset = (offset / 0x10000) * 0x8000 + (offset & 0x7fff); |
| 853 | | m_cart[0].m_nvram[offset & mask] = data; |
| 853 | m_cart.m_nvram[offset & mask] = data; |
| 854 | 854 | } |
| 855 | | else if (m_cart[0].m_nvram_size > 0) |
| 855 | else if (m_cart.m_nvram_size > 0) |
| 856 | 856 | { |
| 857 | | int mask = m_cart[0].m_nvram_size - 1; /* Limit SRAM size to what's actually present */ |
| 858 | | m_cart[0].m_nvram[offset & mask] = data; |
| 857 | int mask = m_cart.m_nvram_size - 1; /* Limit SRAM size to what's actually present */ |
| 858 | m_cart.m_nvram[offset & mask] = data; |
| 859 | 859 | } |
| 860 | 860 | else |
| 861 | 861 | logerror("(PC=%06x) snes_w_bank1: Attempt to write to reserved address: %X = %02X\n", space.device().safe_pc(), offset, data); |
| r22739 | r22740 | |
| 879 | 879 | } |
| 880 | 880 | else |
| 881 | 881 | { |
| 882 | | if (m_cart[0].mode & 5 && address < 0x8000) /* Mode 20 & 22 in 0x0000-0x7fff */ |
| 882 | if (m_cart.mode & 5 && address < 0x8000) /* Mode 20 & 22 in 0x0000-0x7fff */ |
| 883 | 883 | { |
| 884 | 884 | if (offset < 0x700000) |
| 885 | 885 | space.write_byte(offset, data); |
| 886 | 886 | else |
| 887 | 887 | { |
| 888 | | if (m_cart[0].m_nvram_size > 0x8000) |
| 888 | if (m_cart.m_nvram_size > 0x8000) |
| 889 | 889 | { |
| 890 | 890 | // In this case, SRAM is mapped in 0x8000 chunks at diff offsets: 0x700000-0x707fff, 0x710000-0x717fff, etc. |
| 891 | | int mask = m_cart[0].m_nvram_size - 1; |
| 891 | int mask = m_cart.m_nvram_size - 1; |
| 892 | 892 | offset = (offset / 0x10000) * 0x8000 + (offset & 0x7fff); |
| 893 | | m_cart[0].m_nvram[offset & mask] = data; |
| 893 | m_cart.m_nvram[offset & mask] = data; |
| 894 | 894 | } |
| 895 | | else if (m_cart[0].m_nvram_size > 0) |
| 895 | else if (m_cart.m_nvram_size > 0) |
| 896 | 896 | { |
| 897 | | int mask = m_cart[0].m_nvram_size - 1; /* Limit SRAM size to what's actually present */ |
| 898 | | m_cart[0].m_nvram[offset & mask] = data; |
| 897 | int mask = m_cart.m_nvram_size - 1; /* Limit SRAM size to what's actually present */ |
| 898 | m_cart.m_nvram[offset & mask] = data; |
| 899 | 899 | } |
| 900 | 900 | else |
| 901 | 901 | logerror("(PC=%06x) snes_w_bank2: Attempt to write to reserved address: %X = %02X\n", space.device().safe_pc(), offset, data); |
| r22739 | r22740 | |
| 1152 | 1152 | int i; |
| 1153 | 1153 | // setup the rom_bank_map array to faster ROM read |
| 1154 | 1154 | for (i = 0; i < size / 0x8000; i++) |
| 1155 | | m_cart[0].rom_bank_map[i] = i; |
| 1155 | m_cart.rom_bank_map[i] = i; |
| 1156 | 1156 | |
| 1157 | 1157 | // fill up remaining blocks with mirrors |
| 1158 | 1158 | while (i % 256) |
| r22739 | r22740 | |
| 1162 | 1162 | j++; |
| 1163 | 1163 | repeat_banks = i % (256 >> (j - 1)); |
| 1164 | 1164 | for (int k = 0; k < repeat_banks; k++) |
| 1165 | | m_cart[0].rom_bank_map[i + k] = m_cart[0].rom_bank_map[i + k - repeat_banks]; |
| 1165 | m_cart.rom_bank_map[i + k] = m_cart.rom_bank_map[i + k - repeat_banks]; |
| 1166 | 1166 | i += repeat_banks; |
| 1167 | 1167 | } |
| 1168 | 1168 | } |
| r22739 | r22740 | |
| 1170 | 1170 | /* for mame we use an init, maybe we will need more for the different games */ |
| 1171 | 1171 | DRIVER_INIT_MEMBER(snes_state,snes) |
| 1172 | 1172 | { |
| 1173 | | m_cart[0].m_rom_size = memregion("user3")->bytes(); |
| 1174 | | m_cart[0].m_rom = memregion("user3")->base(); |
| 1175 | | rom_map_setup(m_cart[0].m_rom_size); |
| 1173 | m_cart.m_rom_size = memregion("user3")->bytes(); |
| 1174 | m_cart.m_rom = memregion("user3")->base(); |
| 1175 | rom_map_setup(m_cart.m_rom_size); |
| 1176 | 1176 | |
| 1177 | | m_cart[0].m_nvram_size = 0; |
| 1178 | | if (m_cart[0].m_rom[0x7fd8] > 0) |
| 1177 | m_cart.m_nvram_size = 0; |
| 1178 | if (m_cart.m_rom[0x7fd8] > 0) |
| 1179 | 1179 | { |
| 1180 | | UINT32 nvram_size = (1024 << m_cart[0].m_rom[0x7fd8]); |
| 1180 | UINT32 nvram_size = (1024 << m_cart.m_rom[0x7fd8]); |
| 1181 | 1181 | if (nvram_size > 0x40000) |
| 1182 | 1182 | nvram_size = 0x40000; |
| 1183 | 1183 | |
| 1184 | | m_cart[0].m_nvram = auto_alloc_array_clear(machine(), UINT8, nvram_size); |
| 1185 | | m_cart[0].m_nvram_size = nvram_size; |
| 1184 | m_cart.m_nvram = auto_alloc_array_clear(machine(), UINT8, nvram_size); |
| 1185 | m_cart.m_nvram_size = nvram_size; |
| 1186 | 1186 | } |
| 1187 | 1187 | |
| 1188 | 1188 | /* all NSS games seem to use MODE 20 */ |
| 1189 | | m_cart[0].mode = SNES_MODE_20; |
| 1190 | | m_has_addon_chip = HAS_NONE; |
| 1189 | m_cart.mode = SNES_MODE_20; |
| 1191 | 1190 | } |
| 1192 | 1191 | |
| 1193 | 1192 | DRIVER_INIT_MEMBER(snes_state,snes_hirom) |
| 1194 | 1193 | { |
| 1195 | | m_cart[0].m_rom_size = memregion("user3")->bytes(); |
| 1196 | | m_cart[0].m_rom = memregion("user3")->base(); |
| 1197 | | rom_map_setup(m_cart[0].m_rom_size); |
| 1194 | m_cart.m_rom_size = memregion("user3")->bytes(); |
| 1195 | m_cart.m_rom = memregion("user3")->base(); |
| 1196 | rom_map_setup(m_cart.m_rom_size); |
| 1198 | 1197 | |
| 1199 | | m_cart[0].m_nvram_size = 0; |
| 1200 | | if (m_cart[0].m_rom[0xffd8] > 0) |
| 1198 | m_cart.m_nvram_size = 0; |
| 1199 | if (m_cart.m_rom[0xffd8] > 0) |
| 1201 | 1200 | { |
| 1202 | | UINT32 nvram_size = (1024 << m_cart[0].m_rom[0xffd8]); |
| 1201 | UINT32 nvram_size = (1024 << m_cart.m_rom[0xffd8]); |
| 1203 | 1202 | if (nvram_size > 0x40000) |
| 1204 | 1203 | nvram_size = 0x40000; |
| 1205 | 1204 | |
| 1206 | | m_cart[0].m_nvram = auto_alloc_array_clear(machine(), UINT8, nvram_size); |
| 1207 | | m_cart[0].m_nvram_size = nvram_size; |
| 1205 | m_cart.m_nvram = auto_alloc_array_clear(machine(), UINT8, nvram_size); |
| 1206 | m_cart.m_nvram_size = nvram_size; |
| 1208 | 1207 | } |
| 1209 | 1208 | |
| 1210 | | m_cart[0].mode = SNES_MODE_21; |
| 1211 | | m_has_addon_chip = HAS_NONE; |
| 1209 | m_cart.mode = SNES_MODE_21; |
| 1212 | 1210 | } |
| 1213 | 1211 | |
| 1214 | 1212 | |