Exemplo n.º 1
0
        /// <summary>
        ///     Constructor
        /// </summary>
        /// <param name="prgRom"></param>
        /// <param name="chrRom"></param>
        /// <param name="mirroring"></param>
        public NROM(byte[] prgRom, byte[] chrRom, enumNametableMirroring mirroring = enumNametableMirroring.Horizontal)
        {
            NametableMirroring = mirroring;

            //Assign first 16k of ROM
            Array.Copy(prgRom, 0, _prgRom, 0, prgRom.Length);

            //If it's less than 16k, just mirror it to the second bank
            if (prgRom.Length <= 0x4000)
            {
                Array.Copy(prgRom, 0, _prgRom, 0x4000, prgRom.Length);
            }

            //Setup PPU ROM
            if (chrRom != null)
            {
                Array.Copy(chrRom, 0, _chrRom, 0, chrRom.Length);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        ///     Loads the specified iNES ROM
        /// </summary>
        /// <param name="ROM">Byte Array containing the desired iNES ROM to load</param>
        /// <returns>TRUE if load was successful</returns>
        public bool LoadROM(byte[] ROM)
        {
            //Header is 16 bytes

            //PRG Rom starts right after, unless there's a 512 byte trainer (indicated by flags)
            var prgROMOffset = 16;

            //_header == "NES<EOF>"
            if (BitConverter.ToInt32(ROM, 0) != 0x1A53454E)
            {
                throw new Exception("Invalid ROM Header");
            }

            //Setup Memory
            _prgRomBanks = ROM[4];
            var prgROMSize = _prgRomBanks * 16384;

            _prgRom = new byte[prgROMSize];
            _logger.Info($"PRG ROM Size: {prgROMSize}");

            _chrRomBanks = ROM[5];
            var chrROMSize = _chrRomBanks * 8192; //0 denotes default 8k

            if (ROM[5] == 0)
            {
                _chrRom    = new byte[8192];
                UsesCHRRAM = true;
            }
            else
            {
                _chrRom = new byte[chrROMSize];
            }
            _logger.Info($"CHR ROM Size: {chrROMSize}");

            //Set Flags6
            Flags6 = ROM[6];

            //Move PGR ROM Start if Trainer Present
            if (Flags6.IsFlagSet(Byte6Flags.TrainerPresent))
            {
                prgROMOffset += 512;
            }

            //Set Initial Mirroring Mode
            _nametableMirroring = Flags6.IsFlagSet(Byte6Flags.VerticalMirroring) ? enumNametableMirroring.Vertical : enumNametableMirroring.Horizontal;

            //Set Flags7
            Flags7 = ROM[7];

            var prgRAMSize = ROM[8] == 0 ? 8192 : ROM[8] * 8192; //0 denoted default 8k

            _prgRam = new byte[prgRAMSize];

            //Load PRG ROM
            Array.Copy(ROM, prgROMOffset, _prgRom, 0, prgROMSize);

            //Load CHR ROM
            Array.Copy(ROM, prgROMOffset + prgROMSize, _chrRom, 0, chrROMSize);

            //Load Proper Mapper
            var mapperNumber = Flags7 & 0xF0 | (Flags6 >> 4 & 0xF);

            switch (mapperNumber)
            {
            case 0:
                MemoryMapper = new NROM(_prgRom, _chrRom, _nametableMirroring);
                break;

            case 1:
                MemoryMapper = new MMC1(_prgRomBanks, _chrRom, _prgRom, UsesCHRRAM, false, _nametableMirroring);
                break;

            case 2:
                MemoryMapper = new UxROM(_prgRom, _prgRomBanks, _chrRom, _nametableMirroring);
                break;

            case 3:
                MemoryMapper = new CNROM(_prgRom, _prgRomBanks, _chrRom, _nametableMirroring);
                break;

            default:
                throw new Exception($"Unsupported Mapper: {mapperNumber}");
            }

            return(true);
        }