using System; using System.IO; public enum MIRRORING {HORIZONTAL, VERTICAL, FOUR_SCREEN, ONE_SCREEN}; public class Cartridge { public byte [][] prg_rom; public byte [][] chr_rom; public MIRRORING mirroring; public bool trainer_present; public bool save_ram_present; public bool is_vram; public byte mapper; public byte prg_rom_pages; public byte chr_rom_pages; public uint mirroringBase; // For one screen mirroring public Cartridge() { } public bool Load(string filename) { byte[] nesHeader = new byte[16]; int i; try { using (FileStream reader = File.OpenRead(filename)) { reader.Read(nesHeader, 0, 16); //Allocate space, because of mappers we don't use the 16k default int prg_roms = nesHeader[4] * 4; prg_rom_pages = nesHeader[4]; //Console.WriteLine("Number of PRG pages: {0}", prg_rom_pages); prg_rom = new byte[prg_roms][]; for (i = 0; i < (prg_roms); i++) { //Console.WriteLine("Create PRG Page: {0}", i); prg_rom[i] = new byte[4096]; reader.Read(prg_rom[i], 0, 4096); } //Allocate space, because of mappers we don't use the 16k default int chr_roms = nesHeader[5] * 8; chr_rom_pages = nesHeader[5]; //Console.WriteLine("Number of CHR pages: {0}", chr_rom_pages); if (chr_rom_pages != 0) { chr_rom = new byte[chr_roms][]; for (i = 0; i < (chr_roms); i++) { chr_rom[i] = new byte[1024]; reader.Read(chr_rom[i], 0, 1024); } is_vram = false; } else { //If we have 0 CHR pages, we're dealing with VRAM instead of VROM //So make enough space by providing the minimum for 0x0000 and 0x1000 //and set the toggle that allows us to to write to the video memory chr_rom = new byte[8][]; for (i = 0; i < 8; i++) { chr_rom[i] = new byte[1024]; } is_vram = true; } if ((nesHeader[6] & 0x1) == 0x0) { mirroring = MIRRORING.HORIZONTAL; } else { mirroring = MIRRORING.VERTICAL; } if ((nesHeader[6] & 0x2) == 0x0) { Console.WriteLine("No Save RAM"); save_ram_present = false; } else { Console.WriteLine("Save RAM enabled"); save_ram_present = true; } if ((nesHeader[6] & 0x4) == 0x0) { trainer_present = false; } else { trainer_present = true; } if ((nesHeader[6] & 0x8) != 0x0) { mirroring = MIRRORING.FOUR_SCREEN; } if (nesHeader[7] == 0x44) { mapper = (byte)(nesHeader[6] >> 4); } else { mapper = (byte)((nesHeader[6] >> 4) + (nesHeader[7] & 0xf0)); } if ((nesHeader[6] == 0x23) && (nesHeader[7] == 0x64)) mapper = 2; } } catch (FileNotFoundException e) { Console.Error.WriteLine("File not found: {0}", filename); return false; } catch (Exception e) { Console.Error.WriteLine(e); return false; } return true; } }