Exemplo n.º 1
0
        public Cartridge(string romFile)
        {
            using (FileStream fs = new FileStream(romFile, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                // Read in the first ROM bank, which also contains the cartridge header
                rom0 = new byte[0x4000];
                fs.Read(rom0, 0, 0x4000);

                // Check to make sure that this is an actual GameBoy ROM File by checking the logo in the header
                // (CGB only checks first 18 bytes, so that's what we will do)
                for (int i = 0, addr = 0x0104; i < LogoData.Length; i++, addr++)
                {
                    if (addr >= rom0.Length || rom0[addr] != LogoData[i])
                    {
                        throw new FileFormatException("File is not a valid GameBoy ROM");
                    }
                }

                // Get the number of ROM and RAM banks from the cartridge header.
                int romSize = rom0[0x0148];
                switch (romSize)
                {
                case 0x52: romSize = 0x4000 * 72; break;     // Awkward sizes

                case 0x53: romSize = 0x4000 * 80; break;

                case 0x54: romSize = 0x4000 * 92; break;

                default: romSize = 0x8000 << romSize; break;
                }

                int ramSize = rom0[0x0149];
                switch (ramSize) // 0 => 0, 1 => 1
                {
                case 0: ramSize = 0; break;

                case 1: ramSize = 0x800; break;

                case 2: ramSize = 0x2000; break;

                case 3: ramSize = 0x2000 * 4; break;

                case 4: ramSize = 0x2000 * 16; break;

                case 5: ramSize = 0x2000 * 8; break;
                }

                // Determine cartridge features

                switch (rom0[0x0147])
                {
                default:
                    throw new NotSupportedException("Cartridge type not supported.");

                case 9:
                    hasBattery = true;
                    goto case 8;

                case 8:
                case 0:
                    mbc = new ROMOnlyController(ramSize);
                    break;

                case 3:
                    hasBattery = true;
                    goto case 2;

                case 2:
                case 1:
                    mbc = new MBC1(romSize, ramSize);
                    break;

                case 6:
                    hasBattery = true;
                    goto case 5;

                case 5:
                    mbc = new MBC2(romSize);
                    break;

                case 16:
                case 15:
                    hasBattery = true;
                    mbc        = new MBC3(romSize, ramSize, true);
                    break;

                case 19:
                    hasBattery = true;
                    goto case 18;

                case 18:
                case 17:
                    mbc = new MBC3(romSize, ramSize, false);
                    break;
                }

                mbc.LoadROM(fs);
            }

            storageFile = Path.Combine(StoragePath, Path.ChangeExtension(Path.GetFileName(romFile), BatteryExtension));

            if (hasBattery && File.Exists(storageFile))
            {
                mbc.LoadStorageRAM(storageFile);
            }
        }