public void DumpPrg(FamicomDumperConnection dumper, List <byte> data, int size) { dumper.WriteCpu((ushort)(0x5000), (byte)0x00); dumper.WriteCpu((ushort)(0x5001), (byte)0x10); dumper.WriteCpu((ushort)(0x5002), (byte)0x10); dumper.WriteCpu((ushort)(0x5006), (byte)0x07); dumper.WriteCpu((ushort)(0x5007), (byte)0x03); byte banks = (byte)(size / 0x8000); for (int bank = 0; bank < banks; bank++) { Console.Write("Reading PRG bank #{0}... ", bank); // TODO: избежать конфликтов шины // Avoiding bus conflicts /* * for (int i = 0; i < lastBank.Length; i++) * { * if (lastBank[i] == bank) * { * break; * } * } */ dumper.WriteCpu((ushort)(0x8000), (byte)bank); data.AddRange(dumper.ReadCpu(0x8000, 0x8000)); Console.WriteLine("OK"); } }
public static void PPBClear(FamicomDumperConnection dumper) { LockBitsCheckPrint(dumper); PPBLockBitCheckPrint(dumper); Console.Write($"Erasing all PBBs... "); // PPB Command Set Entry dumper.WriteCpu(0x8AAA, 0xAA); dumper.WriteCpu(0x8555, 0x55); dumper.WriteCpu(0x8AAA, 0xC0); // All PPB Erase dumper.WriteCpu(0x8000, 0x80); dumper.WriteCpu(0x8000, 0x30); // Check try { DateTime startTime = DateTime.Now; while (true) { byte b = dumper.ReadCpu(0x8000); if (b == 0x01) { break; } if ((DateTime.Now - startTime).TotalMilliseconds >= 1500) { throw new IOException("PPB clear failed"); } } } finally { ResetFlash(dumper); } Console.WriteLine("OK"); }
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"); } } }
static void StartServer(FamicomDumperConnection dumper, uint tcpPort) { BinaryServerFormatterSinkProvider binaryServerFormatterSinkProvider = new BinaryServerFormatterSinkProvider(); BinaryClientFormatterSinkProvider binaryClientFormatterSinkProvider = new BinaryClientFormatterSinkProvider(); binaryServerFormatterSinkProvider.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full; var dict = new System.Collections.Hashtable(); dict["name"] = "FamicomDumperServer"; dict["port"] = tcpPort; dict["secure"] = false; var channel = new TcpChannel(dict, binaryClientFormatterSinkProvider, binaryServerFormatterSinkProvider); ChannelServices.RegisterChannel(channel, false); dumper.Verbose = true; RemotingServices.Marshal(dumper, "dumper"); Console.WriteLine($"Listening port {tcpPort}, press any key to stop"); Console.ReadKey(); Console.WriteLine(); ChannelServices.UnregisterChannel(channel); channel.StopListening(null); }
public void DumpPrg(FamicomDumperConnection dumper, List <byte> data, int size) { //dumper.WritePrg((ushort)(0x5001), (byte)0x02); Console.Write("Reading PRG... "); data.AddRange(dumper.ReadCpu(0x8000, size)); Console.WriteLine("OK"); }
static void TestChrRam(FamicomDumperConnection dumper) { var rnd = new Random(); while (true) { var data = new byte[0x2000]; rnd.NextBytes(data); Console.Write("Writing CHR RAM... "); dumper.WritePpu(0x0000, data); Console.Write("Reading CHR RAM... "); var rdata = dumper.ReadPpu(0x0000, 0x2000); bool ok = true; for (int b = 0; b < 0x2000; b++) { if (data[b] != rdata[b]) { Console.WriteLine($"Mismatch at {b:X4}: {rdata[b]:X2} != {data[b]:X2}"); ok = false; } } if (!ok) { File.WriteAllBytes("chrramgood.bin", data); Console.WriteLine("chrramgood.bin writed"); File.WriteAllBytes("chrrambad.bin", rdata); Console.WriteLine("chrrambad.bin writed"); throw new VerificationException("Failed!"); } 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) { byte banks = (byte)(size / 0x4000); Console.Write("Reading last PRG bank... "); byte[] lastBank = dumper.ReadCpu(0xC000, 0x4000); Console.WriteLine("OK"); for (int bank = 0; bank < banks - 1; bank++) { Console.Write("Reading PRG bank #{0}... ", bank); // Avoiding bus conflicts bool noBusConflict = false; for (int i = 0; i < lastBank.Length; i++) { if (lastBank[i] == bank) { dumper.WriteCpu((ushort)(0xC000 + i), (byte)bank); noBusConflict = true; break; } } if (!noBusConflict) // Whatever... { dumper.WriteCpu((ushort)0x8000, (byte)bank); } data.AddRange(dumper.ReadCpu(0x8000, 0x4000)); Console.WriteLine("OK"); } data.AddRange(lastBank); }
public void DumpPrg(FamicomDumperConnection dumper, List <byte> data, int size) { Console.Write("Dumping PRG... "); prg = dumper.ReadCpu(0x8000, size); data.AddRange(prg); 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) { //dumper.WritePrg(0xFFC9, 1); dumper.WriteCpu((ushort)(0x5000), (byte)0x00); dumper.WriteCpu((ushort)(0x5001), (byte)0x08); dumper.WriteCpu((ushort)(0x5002), (byte)0xF8); dumper.WriteCpu((ushort)(0x5003), (byte)0x00); dumper.WriteCpu((ushort)(0x5004), (byte)0x00); dumper.WriteCpu((ushort)(0x5005), (byte)0x00); dumper.WriteCpu((ushort)(0x5006), (byte)0x02); dumper.WriteCpu((ushort)(0x5007), (byte)0x82); byte banks = (byte)(size / 0x4000); Console.Write("Reading last PRG bank... "); byte[] lastBank = dumper.ReadCpu(0xC000, 0x4000); Console.WriteLine("OK"); for (int bank = 0; bank < banks - 1; bank++) { Console.Write("Reading PRG bank #{0}... ", bank); // Avoiding bus conflicts for (int i = 0; i < lastBank.Length; i++) { if (lastBank[i] == bank) { dumper.WriteCpu((ushort)(0xC000 + i), (byte)bank); break; } } data.AddRange(dumper.ReadCpu(0x8000, 0x4000)); Console.WriteLine("OK"); } data.AddRange(lastBank); }
public static void PPBSet(FamicomDumperConnection dumper) { Console.Write("Writing PPB for sector... "); // PPB Command Set Entry dumper.WriteCpu(0x8AAA, 0xAA); dumper.WriteCpu(0x8555, 0x55); dumper.WriteCpu(0x8AAA, 0xC0); // PPB Program dumper.WriteCpu(0x8000, 0xA0); dumper.WriteCpu(0x8000, 0x00); // Check try { DateTime startTime = DateTime.Now; while (true) { byte b = dumper.ReadCpu(0x8000); if (b == 0x00) { break; } if ((DateTime.Now - startTime).TotalMilliseconds >= 1500) { throw new IOException("PPB write failed"); } } } finally { ResetFlash(dumper); } Console.WriteLine("OK"); }
public static void LockBitsCheckPrint(FamicomDumperConnection dumper) { try { // Lock Register Set Entry dumper.WriteCpu(0x8AAA, 0xAA); dumper.WriteCpu(0x8555, 0x55); dumper.WriteCpu(0x8AAA, 0x40); var lockRegister = dumper.ReadCpu(0x8000); if ((lockRegister & 1) == 0) { Console.WriteLine("WARNING: Secured Silicon Sector Protection Bit is set!"); } if ((lockRegister & 2) == 0) { Console.WriteLine("WARNING: Persistent Protection Mode Lock Bit is set!"); } if ((lockRegister & 4) == 0) { Console.WriteLine("WARNING: Password Protection Mode Lock Bit is set!"); } } finally { ResetFlash(dumper); } }
private static void CheckRAMAdapter(FamicomDumperConnection dumper) { // Just simple test that RAM adapter is connected bool ramAdapterPresent = true; dumper.WriteCpu(0x4023, 0x01); // enable disk registers dumper.WriteCpu(0x4026, 0x00); dumper.WriteCpu(0x4025, 0b00100110); // reset dumper.WriteCpu(0x0000, 0xFF); // to prevent open bus read var ext = dumper.ReadCpu(0x4033); if (ext != 0x00) { ramAdapterPresent = false; } dumper.WriteCpu(0x4026, 0xFF); dumper.WriteCpu(0x0000, 0x00); // to prevent open bus read ext = dumper.ReadCpu(0x4033); if ((ext & 0x7F) != 0x7F) { ramAdapterPresent = false; } if (!ramAdapterPresent) { throw new IOException("RAM adapter IO error, is it connected?"); } }
public static void PasswordUnlock(FamicomDumperConnection dumper, byte[] password) { try { if (password.Length != 8) { throw new InvalidDataException("Invalid password length"); } Console.Write("Unlocking password... "); // Password Protection Set Entry dumper.WriteCpu(0x8AAA, 0xAA); dumper.WriteCpu(0x8555, 0x55); dumper.WriteCpu(0x8AAA, 0x60); // Password unlock dumper.WriteCpu(0x8000, 0x25); dumper.WriteCpu(0x8000, 0x03); for (byte i = 0; i < password.Length; i++) { dumper.WriteCpu((ushort)(0x8000 + i), password[i]); } dumper.WriteCpu(0x8000, 0x29); Console.WriteLine("OK"); } finally { ResetFlash(dumper); } }
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 DumpChr(FamicomDumperConnection dumper, List <byte> data, int size = 0) { this.dumper = dumper; resultChr.Clear(); script.Call(script.Globals["DumpChr"], size); data.AddRange(resultChr); }
public static void ResetFlash(FamicomDumperConnection dumper) { // Exit command set entry if any dumper.WriteCpu(0x8000, 0x90); dumper.WriteCpu(0x8000, 0x00); // Reset dumper.WriteCpu(0x8000, 0xF0); }
void WriteMMC1(FamicomDumperConnection dumper, UInt16 address, byte data) { byte[] buffer = new byte[5]; for (int i = 0; i < 5; i++) { buffer[i] = (byte)(data >> i); } dumper.WriteCpu(address, buffer); }
public static void PasswordProgramm(FamicomDumperConnection dumper, byte[] password) { if (password.Length != 8) { throw new InvalidDataException("Invalid password length"); } Console.Write("Programming password... "); // Password Protection Set Entry dumper.WriteCpu(0x8AAA, 0xAA); dumper.WriteCpu(0x8555, 0x55); dumper.WriteCpu(0x8AAA, 0x60); try { for (byte i = 0; i < password.Length; i++) { dumper.WriteCpu(0x8000, 0xA0); dumper.WriteCpu((ushort)(0x8000 + i), password[i]); } var verify = dumper.ReadCpu(0x8000, 8); for (byte i = 0; i < password.Length; i++) { if (password[i] != verify[i]) { throw new InvalidDataException("Password verification failed"); } } } finally { ResetFlash(dumper); } Console.WriteLine("OK"); Console.Write("Programming lock register... "); // Lock Register Set Entry dumper.WriteCpu(0x8AAA, 0xAA); dumper.WriteCpu(0x8555, 0x55); dumper.WriteCpu(0x8AAA, 0x40); try { // Bits Program dumper.WriteCpu(0x8000, 0xA0); dumper.WriteCpu(0x8000, (byte)(1 << 2) ^ 0xFF); // password protection var r = dumper.ReadCpu(0x8000); if ((r & 7) != 3) { throw new InvalidDataException("Lock bit verification failed"); } } finally { ResetFlash(dumper); } Console.WriteLine("OK"); }
public static void PringFlashInfo(FamicomDumperConnection dumper) { Program.Reset(dumper); dumper.WriteCpu(0x5007, 0x04); // enable PRG write dumper.WriteCpu(0x5002, 0xFE); // mask = 32K var cfi = FlashHelper.GetCFIInfo(dumper); FlashHelper.PrintCFIInfo(cfi); FlashHelper.LockBitsCheckPrint(dumper); FlashHelper.PPBLockBitCheckPrint(dumper); }
public void Execute(FamicomDumperConnection dumper, string scriptSource, bool useFile = true) { this.dumper = dumper; if (useFile) { script.DoFile(scriptSource); } else { script.DoString(scriptSource); } }
public static void FullTest(FamicomDumperConnection dumper, int count = -1, int chrSize = -1) { while (count != 0) { TestChrRam(dumper, 1, chrSize); TestPrgRam(dumper, 1); if (count > 0) { count--; } } }
public static void PPBClear(FamicomDumperConnection dumper) { // enable PRG write dumper.WriteCpu(0x5007, 0x04); // mask = 32K dumper.WriteCpu(0x5002, 0xFE); // Sector 0 dumper.WriteCpu(0x5000, 0); dumper.WriteCpu(0x5001, 0); FlashHelper.PPBClear(dumper); }
static NesFile.MirroringType GetMirroring(FamicomDumperConnection dumper, IMapper mapper) { var method = mapper.GetType().GetMethod( "GetMirroring", BindingFlags.Instance | BindingFlags.Public, null, CallingConventions.Any, new Type[] { typeof(IFamicomDumperConnection) }, new ParameterModifier[0]); if (method == null) { return(dumper.GetMirroring()); } return((NesFile.MirroringType)method.Invoke(mapper, new object[] { dumper })); }
public void DumpChr(FamicomDumperConnection dumper, List <byte> data, int size) { dumper.WriteCpu(0x8000, 0x80); WriteMMC1(dumper, 0x8000, 0x0C); byte banks = (byte)(size / 0x1000); for (int bank = 0; bank < banks; bank += 2) { Console.Write("Reading CHR banks #{0} and #{1}... ", bank, bank + 1); WriteMMC1(dumper, 0xA000, (byte)bank); data.AddRange(dumper.ReadPpu(0x0000, 0x2000)); Console.WriteLine("OK"); } }
public void DumpPrg(FamicomDumperConnection dumper, List <byte> data, int size) { byte banks = (byte)(size / 0x2000); for (byte bank = 0; bank < banks - 2; bank += 2) { Console.Write("Reading PRG banks #{0} and #{1}... ", bank, bank + 1); 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 #{0} and #{1}... ", banks - 2, banks - 1); data.AddRange(dumper.ReadCpu(0xC000, 0x4000)); Console.WriteLine("OK"); }
public static byte PPBRead(FamicomDumperConnection dumper) { try { // PPB Command Set Entry dumper.WriteCpu(0x8AAA, 0xAA); dumper.WriteCpu(0x8555, 0x55); dumper.WriteCpu(0x8AAA, 0xC0); // PPB Status Read return(dumper.ReadCpu(0x8000)); } finally { ResetFlash(dumper); } }
public static void DumpFDS(FamicomDumperConnection dumper, string fileName, byte sides = 1, bool dumpHiddenFiles = true, bool useHeader = true) { if (dumper.ProtocolVersion < 3) { throw new NotSupportedException("Dumper firmware version is too old, update it to read/write FDS cards"); } CheckRAMAdapter(dumper); var sideImages = new List <FdsDiskSide>(); for (int side = 1; side <= sides; side++) { var driveStatus = dumper.ReadCpu(0x4032); if ((driveStatus & 1) != 0) { Console.Write($"Please set disk card, side #{side}... "); while ((driveStatus & 1) != 0) { Thread.Sleep(100); driveStatus = dumper.ReadCpu(0x4032); } Console.WriteLine("OK"); } var sideImage = DumpFDSSide(dumper, dumpHiddenFiles, printDiskInfo: true); sideImages.Add(sideImage); if (side < sides) { driveStatus = dumper.ReadCpu(0x4032); if ((driveStatus & 1) == 0) { Console.Write($"Please remove disk card... "); while ((driveStatus & 1) == 0) { Thread.Sleep(100); driveStatus = dumper.ReadCpu(0x4032); } Console.WriteLine("OK"); } } } Console.Write($"Saving to {fileName}... "); var fdsImage = new FdsFile(sideImages); fdsImage.Save(fileName, useHeader); Console.WriteLine("OK"); }