Esempio n. 1
0
        public static int ConvertSnesToPc(int address, RomMapMode mode, int size)
        {
            if (address < 0)
            {
                return(-1);
            }

            int UnmirroredOffset(int offset) => RomUtil.UnmirroredOffset(offset, size);

            // WRAM is N/A to PC addressing
            if ((address & 0xFE0000) == 0x7E0000)
            {
                return(-1);
            }

            // WRAM mirror & PPU regs are N/A to PC addressing
            if (((address & 0x400000) == 0) && ((address & 0x8000) == 0))
            {
                return(-1);
            }

            switch (mode)
            {
            case RomMapMode.LoRom:
            {
                // SRAM is N/A to PC addressing
                if (((address & 0x700000) == 0x700000) && ((address & 0x8000) == 0))
                {
                    return(-1);
                }

                return(UnmirroredOffset(((address & 0x7F0000) >> 1) | (address & 0x7FFF)));
            }

            case RomMapMode.HiRom:
            {
                return(UnmirroredOffset(address & 0x3FFFFF));
            }

            case RomMapMode.SuperMmc:
            {
                return(UnmirroredOffset(address & 0x3FFFFF));    // todo, treated as hirom atm
            }

            case RomMapMode.Sa1Rom:
            case RomMapMode.ExSa1Rom:
            {
                // BW-RAM is N/A to PC addressing
                if (address >= 0x400000 && address <= 0x7FFFFF)
                {
                    return(-1);
                }

                if (address >= 0xC00000)
                {
                    return(mode == RomMapMode.ExSa1Rom ? UnmirroredOffset(address & 0x7FFFFF) : UnmirroredOffset(address & 0x3FFFFF));
                }

                if (address >= 0x800000)
                {
                    address -= 0x400000;
                }

                // SRAM is N/A to PC addressing
                if (((address & 0x8000) == 0))
                {
                    return(-1);
                }

                return(UnmirroredOffset(((address & 0x7F0000) >> 1) | (address & 0x7FFF)));
            }

            case RomMapMode.SuperFx:
            {
                // BW-RAM is N/A to PC addressing
                if (address >= 0x600000 && address <= 0x7FFFFF)
                {
                    return(-1);
                }

                if (address < 0x400000)
                {
                    return(UnmirroredOffset(((address & 0x7F0000) >> 1) | (address & 0x7FFF)));
                }

                if (address < 0x600000)
                {
                    return(UnmirroredOffset(address & 0x3FFFFF));
                }

                if (address < 0xC00000)
                {
                    return(0x200000 + UnmirroredOffset(((address & 0x7F0000) >> 1) | (address & 0x7FFF)));
                }

                return(0x400000 + UnmirroredOffset(address & 0x3FFFFF));
            }

            case RomMapMode.ExHiRom:
            {
                return(UnmirroredOffset(((~address & 0x800000) >> 1) | (address & 0x3FFFFF)));
            }

            case RomMapMode.ExLoRom:
            {
                // SRAM is N/A to PC addressing
                if (((address & 0x700000) == 0x700000) && ((address & 0x8000) == 0))
                {
                    return(-1);
                }

                return(UnmirroredOffset((((address ^ 0x800000) & 0xFF0000) >> 1) | (address & 0x7FFF)));
            }

            default:
            {
                return(-1);
            }
            }
        }