public bool DumpRom(int firstAddress, int lastAddress) { const ushort BLOCK_SIZE = 0x0100; // 256 bytes per block const byte MAX_CHUNK = 13; // protocol limit const bool DEBUG = true; if (firstAddress < 0 || lastAddress < 0 || lastAddress < firstAddress) { Logger.Write("ReadRomEepromBlock: invalid address range."); return false; } // Number of 0x0100 blocks touched by the requested range int numBlocks = ((lastAddress - firstAddress) / BLOCK_SIZE) + 1; // Fresh buffer for this dump var packets2 = new List(numBlocks * BLOCK_SIZE); Logger.Write($"ROM EEPROM BIN dump start: 0x{firstAddress:X4} .. 0x{lastAddress:X4}"); try { int addr = firstAddress; while (addr <= lastAddress) { ushort blockBase = (ushort)(addr & 0xFF00); if (DEBUG) Logger.Write($"===== ROM EEPROM block base 0x{blockBase:X4} ====="); // Last address we may read inside this current 0x0100 block int blockEnd = blockBase + BLOCK_SIZE - 1; // Do not read past: // 1) requested lastAddress // 2) current block end int maxReadableAbs = Math.Min(lastAddress, blockEnd); while (addr <= maxReadableAbs) { int remaining = maxReadableAbs - addr + 1; byte len = (byte)Math.Min(MAX_CHUNK, remaining); var chunk = ReadRomEeprom((ushort)addr, len); // Safety: if the ECU returns fewer bytes than requested, don't infinite-loop if (chunk == null || chunk.Count == 0) { Logger.Write($"ReadRomEeprom returned 0 bytes at 0x{addr:X4}"); return false; } packets2.AddRange(chunk); if (DEBUG) //Logger.Write($"{addr:X4}: " + string.Join(" ", chunk.Select(b => b.ToString("X2")))); // Advance by what was actually received addr += chunk.Count; } // Move to next block if still not finished if (addr <= lastAddress) { addr = blockBase + BLOCK_SIZE; } } KeepAlive(); string fileName = $"rom_eeprom_dump_{firstAddress:X4}-{lastAddress:X4}.bin"; File.WriteAllBytes(fileName, packets2.ToArray()); Logger.Write($"ROM EEPROM BIN dump done: {packets2.Count} bytes -> {fileName}"); return true; } catch (Exception ex) { Logger.Write($"ReadRomEepromBlock failed: {ex.Message}"); return false; } } public bool DumpEeprom(int startAddress, int endAddress) { const ushort BLOCK_SIZE = 0x0100; // logical block stride const ushort VALID_BYTES_PER_BLOCK = 0x00C0; // EEPROM valid region: 0x0000..0x00BF const byte MAX_CHUNK = 13; // protocol limit / safe chunk size if (startAddress < 0 || endAddress < 0 || endAddress < startAddress) { Logger.Write("ReadEepromBlock: invalid address range."); return false; } // Fresh buffer for this dump var packets2 = new List(); Logger.Write($"EEPROM BIN dump start: 0x{startAddress:X4} .. 0x{endAddress:X4}"); try { // Walk absolute address range, but only read valid EEPROM bytes inside each 0x0100 block int addr = startAddress; while (addr <= endAddress) { ushort blockBase = (ushort)(addr & 0xFF00); // start of current 0x0100 block ushort offsetInBlock = (ushort)(addr & 0x00FF); // If current address is outside valid EEPROM region of this block, skip to next block if (offsetInBlock >= VALID_BYTES_PER_BLOCK) { addr = blockBase + BLOCK_SIZE; continue; } // Last valid absolute address inside this block int blockValidEndAbs = blockBase + VALID_BYTES_PER_BLOCK - 1; // Do not read past: // 1) requested endAddress // 2) valid EEPROM end within this block int maxReadableAbs = Math.Min(endAddress, blockValidEndAbs); while (addr <= maxReadableAbs) { int remaining = maxReadableAbs - addr + 1; byte len = (byte)Math.Min(MAX_CHUNK, remaining); var chunk = ReadEeprom((ushort)addr, len); if (chunk == null || chunk.Count == 0) { Logger.Write($"ReadEeprom returned 0 bytes at 0x{addr:X4}"); return false; } packets2.AddRange(chunk); float progress = 1.0f * (addr - startAddress) / (endAddress - startAddress); Logger.Write($"Progress{progress:P1}"); //Logger.Write(string.Join(" ", chunk.Select(b => $"0x{b:X2}"))); // Safety: advance by what was actually received addr += chunk.Count; } // Move to next block if needed if (addr <= endAddress) { addr = (blockBase + BLOCK_SIZE); } } KeepAlive(); string fileName = $"eeprom_dump_{startAddress:X4}-{endAddress:X4}.bin"; File.WriteAllBytes(fileName, packets2.ToArray()); Logger.Write($"EEPROM BIN dump done: {packets2.Count} bytes -> {fileName}"); return true; } catch (Exception ex) { Logger.Write($"ReadEepromBlock failed: {ex.Message}"); return false; } } public bool DumpAllEeprom() { int startAddress = 0x0000; int endAddress = 0x0000; //0x00BF const ushort VALID_BYTES_PER_BLOCK = 0x00C0; // EEPROM valid region: 0x0000..0x00BF const byte MAX_CHUNK = 13; // protocol limit / safe chunk size if (startAddress < 0 || endAddress < 0 || endAddress < startAddress) { Logger.Write("ReadEepromBlock: invalid address range."); return false; } // Fresh buffer for this dump var packets2 = new List(); Logger.Write($"EEPROM BIN dump start: 0x{startAddress:X4} .. 0x{endAddress:X4}"); try { // Walk absolute address range, but only read valid EEPROM bytes inside each 0x0100 block int addr = startAddress; while (addr <= endAddress) { ushort blockBase = (ushort)(addr & 0xFF00); // start of current 0x0100 block ushort offsetInBlock = (ushort)(addr & 0x00FF); // Last valid absolute address inside this block int blockValidEndAbs = blockBase + VALID_BYTES_PER_BLOCK - 1; // Do not read past: // 1) requested endAddress // 2) valid EEPROM end within this block int maxReadableAbs = Math.Min(endAddress, blockValidEndAbs); while (addr <= maxReadableAbs) { int remaining = maxReadableAbs - addr + 1; byte len = (byte)Math.Min(MAX_CHUNK, remaining); var chunk = ReadEeprom((ushort)addr, len); if (chunk == null || chunk.Count == 0) { Logger.Write($"ReadEeprom returned 0 bytes at 0x{addr:X4}"); return false; } packets2.AddRange(chunk); float progress = 1.0f * (addr - startAddress) / (endAddress - startAddress); Logger.Write($"Progress{progress:P1}"); //Logger.Write(string.Join(" ", chunk.Select(b => $"0x{b:X2}"))); // Safety: advance by what was actually received addr += chunk.Count; } } packets2.AddRange(new byte[16]); packets2.AddRange(Enumerable.Repeat((byte)0xFF, 7)); var oemzone = SendCustom(new List { 0x18, 0x00, 0x00, 0x82, 0x33 }); oemzone = oemzone.Where(b => !b.IsAckNak).ToList(); var newbytes = oemzone[0].Body; newbytes.RemoveRange(0,4); packets2.AddRange(newbytes); /*oemzone = SendCustom(new List { 0x18, 0x00, 0x00, 0x00, 0x00 }); oemzone = oemzone.Where(b => !b.IsAckNak).ToList(); newbytes = oemzone[0].Body; packets2.AddRange(newbytes); oemzone = SendCustom(new List { 0x18, 0x00, 0x00, 0x9F, 0xFF }); oemzone = oemzone.Where(b => !b.IsAckNak).ToList(); newbytes = oemzone[0].Body; packets2.AddRange(newbytes); oemzone = SendCustom(new List { 0x18, 0x00, 0x00, 0xD7, 0x01 }); oemzone = oemzone.Where(b => !b.IsAckNak).ToList(); newbytes = oemzone[0].Body; packets2.AddRange(newbytes); oemzone = SendCustom(new List { 0x18, 0x00, 0x00, 0xFF, 0xFC }); oemzone = oemzone.Where(b => !b.IsAckNak).ToList(); newbytes = oemzone[0].Body; packets2.AddRange(newbytes);*/ oemzone = SendCustom(new List { 0x18, 0x00, 0x01, 0x6A, 0x89 }); oemzone = oemzone.Where(b => !b.IsAckNak).ToList(); newbytes = oemzone[0].Body; newbytes.RemoveRange(0, 4); packets2.AddRange(newbytes); oemzone = SendCustom(new List { 0x18, 0x00, 0x02, 0x2E, 0x10 }); oemzone = oemzone.Where(b => !b.IsAckNak).ToList(); newbytes = oemzone[0].Body; newbytes.RemoveRange(0, 4); packets2.AddRange(newbytes); oemzone = SendCustom(new List { 0x18, 0x00, 0x03, 0xFF, 0xFF }); oemzone = oemzone.Where(b => !b.IsAckNak).ToList(); newbytes = oemzone[0].Body; newbytes.RemoveRange(0, 4); packets2.AddRange(newbytes); oemzone = SendCustom(new List { 0x18, 0x00, 0x04, 0xC7, 0xAE }); oemzone = oemzone.Where(b => !b.IsAckNak).ToList(); newbytes = oemzone[0].Body; newbytes.RemoveRange(0, 4); packets2.AddRange(newbytes); KeepAlive(); string fileName = $"eeprom_dump_{startAddress:X4}-{0x00FF:X4}.bin"; File.WriteAllBytes(fileName, packets2.ToArray()); Logger.Write($"EEPROM BIN dump done: {packets2.Count} bytes -> {fileName}"); return true; } catch (Exception ex) { Logger.Write($"ReadEepromBlock failed: {ex.Message}"); return false; } }