public void DumpChr(FamicomDumperConnection dumper, List <byte> data, int size) { byte outbanks = (byte)(size / (256 * 1024)); for (byte outbank = 0; outbank < outbanks; outbank += 1) { dumper.Reset(); dumper.WriteCpu(0xA001, 0x80); // RAM protect dumper.WriteCpu((ushort)(0x6828 | (outbank << 1)), 0x00); dumper.WriteCpu(0xA001, 0); // disable W-RAM int banks = 256; if (banks > 256) { throw new Exception("CHR size is too big"); } for (int bank = 0; bank < banks; bank += 4) { Console.Write("Reading CHR banks #{4}|{0}, #{4}|{1}, #{4}|{2}, #{4}|{3}... ", bank, bank + 1, bank + 2, bank + 3, outbank); dumper.WriteCpu(0x8000, new byte[] { 2, (byte)bank }); dumper.WriteCpu(0x8000, new byte[] { 3, (byte)(bank | 1) }); dumper.WriteCpu(0x8000, new byte[] { 4, (byte)(bank | 2) }); dumper.WriteCpu(0x8000, new byte[] { 5, (byte)(bank | 3) }); data.AddRange(dumper.ReadPpu(0x1000, 0x1000)); Console.WriteLine("OK"); } } }
public void EnablePrgRam(FamicomDumperConnection dumper) { dumper.Reset(); dumper.WriteCpu(0xA001, 0x00); dumper.WriteCpu(0x6003, 0x80); dumper.WriteCpu(0xA001, 0x80); }
public void DumpPrg(FamicomDumperConnection dumper, List <byte> data, int size) { dumper.Reset(); int outbanks = size / (128 * 1024); int outbankSize = 512; for (int outbank = 0; outbank < outbanks; outbank += outbankSize / 128) { byte r0 = (byte)((outbank & 0x07) | ((outbank & 0xc0) >> 2)); byte r1 = (byte)(((outbank & 0x30) >> 2) | ((outbank << 1) & 0x10)); byte r2 = 0; byte r3 = 0; dumper.WriteCpu(0x6000, new byte[] { r0 }); dumper.WriteCpu(0x6001, new byte[] { r1 }); dumper.WriteCpu(0x6002, new byte[] { r2 }); dumper.WriteCpu(0x6003, new byte[] { r3 }); int banks = outbankSize * 1024 / 0x2000; for (int bank = 0; bank < banks - 2; bank += 2) { Console.Write("Reading PRG banks #{2}|{0} and #{2}|{1}... ", bank, bank + 1, outbank); dumper.WriteCpu(0x8000, new byte[] { 6, (byte)(bank) }); dumper.WriteCpu(0x8000, new byte[] { 7, (byte)(bank | 1) }); data.AddRange(dumper.ReadCpu(0x8000, 0x4000)); Console.WriteLine("OK"); } Console.Write("Reading last PRG banks #{2}|{0} and #{2}|{1}... ", banks - 2, banks - 1, outbank); data.AddRange(dumper.ReadCpu(0xC000, 0x4000)); Console.WriteLine("OK"); } }
public void DumpPrg(FamicomDumperConnection dumper, List <byte> data, int size) { dumper.Reset(); version = CoolboyWriter.DetectVersion(dumper); UInt16 coolboyReg = (UInt16)(version == 2 ? 0x5000 : 0x6000); int banks = size / 0x4000; for (int bank = 0; bank < banks; bank++) { byte r0 = (byte)(((bank >> 3) & 0x07) // 5, 4, 3 bits | (((bank >> 9) & 0x03) << 4) // 10, 9 bits | (1 << 6)); // resets 4th mask bit byte r1 = (byte)((((bank >> 7) & 0x03) << 2) // 8, 7 | (((bank >> 6) & 1) << 4) // 6 | (1 << 7)); // resets 5th mask bit byte r2 = 0; byte r3 = (byte)((1 << 4) // NROM mode | ((bank & 7) << 1)); // 2, 1, 0 bits dumper.WriteCpu(coolboyReg, new byte[] { r0, r1, r2, r3 }); Console.Write("Reading PRG banks #{0}/{1}... ", bank, banks); data.AddRange(dumper.ReadCpu(0x8000, 0x4000)); Console.WriteLine("OK"); } }
public void DumpPrg(FamicomDumperConnection dumper, List <byte> data, int size) { dumper.Reset(); int banks = size / 0x4000; for (int bank = 0; bank < banks; bank++) { byte r0 = (byte)(((bank >> 3) & 0x07) // 5, 4, 3 bits | (((bank >> 9) & 0x03) << 4) // 10, 9 bits | (1 << 6)); // resets 4th mask bit byte r1 = (byte)((((bank >> 7) & 0x03) << 2) // 8, 7 | (((bank >> 6) & 1) << 4) // 6 | (1 << 7)); // resets 5th mask bit byte r2 = 0; byte r3 = (byte)((1 << 4) // NROM mode | ((bank & 7) << 1)); // 2, 1, 0 bits dumper.WriteCpu(0x6000, new byte[] { r0 }); dumper.WriteCpu(0x6001, new byte[] { r1 }); dumper.WriteCpu(0x6002, new byte[] { r2 }); dumper.WriteCpu(0x6003, new byte[] { r3 }); Console.Write("Reading PRG banks #{0}/{1}... ", bank, banks); data.AddRange(dumper.ReadCpu(0x8000, 0x4000)); Console.WriteLine("OK"); } }
public void DumpPrg(FamicomDumperConnection dumper, List <byte> data, int size) { int prgBanks = size / 0x8000; Console.Write("Reset... "); dumper.Reset(); Console.WriteLine("OK"); dumper.WriteCpu(0x5002, 0xFE); // mask = 8K for (int bank = 0; bank < prgBanks; bank++) { byte r0 = (byte)(bank >> 7); byte r1 = (byte)(bank << 1); dumper.WriteCpu(0x5000, r0); dumper.WriteCpu(0x5001, r1); Console.Write("Reading PRG bank #{0}/{1}... ", bank, prgBanks); data.AddRange(dumper.ReadCpu(0x8000, 0x8000)); Console.WriteLine("OK"); } Console.WriteLine("Done!"); }
public void DumpPrg(FamicomDumperConnection dumper, List <byte> data, int size) { byte outbanks = (byte)(size / (256 * 1024)); for (byte outbank = 0; outbank < outbanks; outbank += 1) { dumper.Reset(); dumper.WriteCpu(0xA001, 0x80); // RAM protect dumper.WriteCpu((ushort)(0x6828 | (outbank << 1)), 0x00); dumper.WriteCpu(0xA001, 0); // disable W-RAM byte banks = 32; //(byte)(size / 0x2000); for (byte bank = 0; bank < banks - 2; bank += 2) { Console.Write("Reading PRG banks #{2}|{0} and #{2}|{1}... ", bank, bank + 1, outbank); dumper.WriteCpu(0x8000, new byte[] { 6, bank }); dumper.WriteCpu(0x8000, new byte[] { 7, (byte)(bank | 1) }); data.AddRange(dumper.ReadCpu(0x8000, 0x4000)); Console.WriteLine("OK"); } Console.Write("Reading last PRG banks #{2}|{0} and #{2}|{1}... ", banks - 2, banks - 1, outbank); data.AddRange(dumper.ReadCpu(0xC000, 0x4000)); Console.WriteLine("OK"); } }
public void EnablePrgRam(FamicomDumperConnection dumper) { dumper.Reset(); dumper.WriteCpu(0x5007, 0x01); // enable SRAM dumper.WriteCpu(0x5005, 0x02); // select bank }
public LuaMapper() { script = new Script(); script.Globals["ReadPrg"] = script.Globals["ReadCpu"] = (Func <UInt16, int, List <byte> >) delegate(UInt16 address, int length) { if (Verbose) { Console.WriteLine("Reading {0} bytes from CPU:${1:X4}", length, address); } var result = new List <byte>(); result.AddRange(dumper.ReadCpu(address, length)); return(result); }; script.Globals["WritePrg"] = script.Globals["WriteCpu"] = (Action <UInt16, List <byte> >) delegate(UInt16 address, List <byte> data) { if (Verbose) { var a = address; foreach (var v in data) { Console.WriteLine("CPU write ${0:X2} => ${1:X4}", v, a); a++; } } dumper.WriteCpu(address, data.ToArray()); }; script.Globals["AddPrg"] = script.Globals["AddPrgResult"] = (Action <List <byte> >) delegate(List <byte> r) { resultPrg.AddRange(r); }; script.Globals["ReadAddPrg"] = script.Globals["ReadAddCpu"] = (Action <UInt16, int>) delegate(UInt16 address, int length) { if (Verbose) { Console.WriteLine("Reading {0} bytes from CPU:${1:X4}", length, address); } resultPrg.AddRange(dumper.ReadCpu(address, length)); }; script.Globals["ReadChr"] = script.Globals["ReadPpu"] = (Func <UInt16, int, List <byte> >) delegate(UInt16 address, int length) { if (Verbose) { Console.WriteLine("Reading {0} bytes from PPU:${1:X4}", length, address); } var result = new List <byte>(); result.AddRange(dumper.ReadPpu(address, length)); return(result); }; script.Globals["WriteChr"] = script.Globals["WritePpu"] = (Action <UInt16, List <byte> >) delegate(UInt16 address, List <byte> data) { if (Verbose) { var a = address; foreach (var v in data) { Console.WriteLine("PPU write ${0:X2} => ${1:X4}", v, a); a++; } } dumper.WritePpu(address, data.ToArray()); }; script.Globals["ReadAddChr"] = script.Globals["ReadAddPpu"] = (Action <UInt16, int>) delegate(UInt16 address, int length) { if (Verbose) { Console.WriteLine("Reading {0} bytes from PPU:${1:$X4}", length, address); } resultChr.AddRange(dumper.ReadPpu(address, length)); }; script.Globals["AddChr"] = script.Globals["AddChrResult"] = (Action <List <byte> >) delegate(List <byte> r) { resultChr.AddRange(r); }; script.Globals["Reset"] = (Action) delegate { if (Verbose) { Console.Write("Reset... "); } dumper.Reset(); if (Verbose) { Console.WriteLine("OK"); } }; script.Globals["WriteFile"] = (Action <string, List <byte> >) delegate(string filename, List <byte> data) { if (Verbose) { Console.Write("Writing data to \"{0}\"... ", Path.GetFileName(filename)); } File.WriteAllBytes(filename, data.ToArray()); if (Verbose) { Console.WriteLine("OK"); } }; script.Globals["WriteNes"] = (WriteNesDelegate) delegate(string filename, List <byte> prgData, List <byte> chrData, byte mapper, bool vertical) { if (Verbose) { Console.Write("Writing data to NES file \"{0}\" (mapper={1}, mirroring={2})... ", Path.GetFileName(filename), mapper, vertical ? "vertical" : "horizontal"); } var nesFile = new NesFile(); nesFile.PRG = prgData.ToArray(); nesFile.CHR = chrData.ToArray(); nesFile.Mapper = 0; nesFile.Mirroring = vertical ? NesFile.MirroringType.Vertical : NesFile.MirroringType.Horizontal; nesFile.Save(filename); if (Verbose) { Console.WriteLine("OK"); } }; script.Globals["Error"] = (Action <string>) delegate(string message) { throw new Exception(message); }; }
static public void Reset(FamicomDumperConnection dumper) { Console.Write("Reset... "); dumper.Reset(); Console.WriteLine("OK"); }