private static bool PrepareMemoryHex(MemorySpecification ms) { bool result = false; try { using (FileStream fs = new FileStream(ms.FileName, FileMode.Open, FileAccess.Read)) using (TextReader br = new StreamReader(fs)) { result = true; bool fail = false; INTEL_COMMAND command = INTEL_COMMAND.EOF; string line; int lineNumber = 0; uint count = 0, address = 0; byte data = 0, checksum; UInt32 extendAddress = 0, startAddress = 0, segment_address = 0; int idx = 0; while ((line = br.ReadLine()) != null) { lineNumber++; line = line.Trim(); if (line.Length == 0) { continue; } if (line.StartsWith("S")) { // Motorola format Console.WriteLine("Motorola format not support"); result = false; break; } if (line.StartsWith(":")) { // Intel format if (line.Length < 11) { fail = true; } else { fail |= !uint.TryParse(line.Substring(1, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out count); fail |= !uint.TryParse(line.Substring(3, 4), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out address); fail |= !byte.TryParse(line.Substring(7, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out data); command = (INTEL_COMMAND)data; fail |= !byte.TryParse(line.Substring(line.Length - 2, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out checksum); } if (fail) { Console.WriteLine(string.Format("Can't parse line {0}", lineNumber)); result = false; break; } switch (command) { case INTEL_COMMAND.EOF: // End of File break; case INTEL_COMMAND.DATA: idx = 9; goto data_loop; case INTEL_COMMAND.DATA_LOOP: data_loop: for (; !fail && count > 0; --count) { if (line.Length < idx + 2) { Console.WriteLine(string.Format("Data record too short at line {0}", lineNumber)); fail = true; } else { fail = !byte.TryParse(line.Substring(idx, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out data); } if (!fail) { writeToMemory(segment_address + extendAddress + address - StartAddress, data); } address++; idx += 2; } break; case INTEL_COMMAND.EXT_SEGMENT_ADDR: // Extended Segment Address Record #region Extended segment address record if (count != 2 || line.Length != 15) { Console.WriteLine(string.Format("Bad Extended segment address record line {0}.", lineNumber)); } else { fail |= !uint.TryParse(line.Substring(9, 4), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out segment_address); if (fail) { result = false; Console.WriteLine(string.Format("Bad Extended segment address record line {0}.", lineNumber)); } else { segment_address <<= 4; } } break; #endregion case INTEL_COMMAND.SEGMENT_ADDR: #region Start Segment Address Record if (count != 4) { Console.WriteLine(string.Format("Bad Start Segment record line {0}.", lineNumber)); } else { fail |= !uint.TryParse(line.Substring(9, 8), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out startAddress); if (fail) { result = false; Console.WriteLine(string.Format("Bad Start Segment records line {0}.", lineNumber)); } } break; #endregion case INTEL_COMMAND.EXTEND_ADDR: #region Extended Linear Address Record if (line.Length != 15) { Console.WriteLine(string.Format("Bad Extended Address record line {0}.", lineNumber)); fail = true; } else { fail |= !uint.TryParse(line.Substring(9, 4), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out extendAddress); if (fail) { result = false; Console.WriteLine(string.Format("Bad Extended Address record line {0}.", lineNumber)); } else { extendAddress = extendAddress << 16; } } break; #endregion case INTEL_COMMAND.LINEAR_ADDR: #region Start Linear Address Record if (count != 4) { Console.WriteLine(string.Format("Bad Start Address record line {0}.", lineNumber)); } else { fail |= !uint.TryParse(line.Substring(9, 8), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out startAddress); if (fail) { result = false; Console.WriteLine(string.Format("Bad Start Address record line {0}.", lineNumber)); } } break; #endregion default: Console.WriteLine(string.Format("Bad command {0} at line {1}.", command, lineNumber)); fail = true; result = false; break; } if (fail) { break; } } } br.Close(); fs.Close(); } } catch (Exception ex) { Console.WriteLine(string.Format("PrepareMemory: {0}", ex.Message)); } if (result && HexMaxAddress >= HexMinAddress) { StartAddress = HexMinAddress; uint i = HexMaxAddress - HexMinAddress + 1; byte[] image = new byte[i]; while (i != 0) { --i; image[i] = HexMemory[i]; } ms.Image = image; } return(result); }
/// <summary> /// Convert HEX|S file to internal byte array /// </summary> /// <param name="fileIn"></param> /// <returns>error code (0=none)</returns> private static int loadHex(string fileIn) { uint extend_address = 0, start_address = 0, segment_address = 0, linear_address = 0; string line; int lineNumber = 0; bool fail = false; uint count = 0, address = 0; byte data = 0, checksum; int idx = 0; INTEL_COMMAND command = INTEL_COMMAND.UNKNOWN; using (TextReader s = new StreamReader(fileIn)) { while ((line = s.ReadLine()) != null) { ++lineNumber; line = line.Trim(); if (line.Length == 0) { continue; } if (line.StartsWith("S")) { #region Motorola format // Stccaaaaaaadd...ddss if (line.Length < 9) { fail = true; } else { fail |= !byte.TryParse(line.Substring(1, 1), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out data); MOTOROLA_COMMAND m_command = (MOTOROLA_COMMAND)data; switch (m_command) { case MOTOROLA_COMMAND.CMD_01: fail |= !uint.TryParse(line.Substring(2, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out count); fail |= !uint.TryParse(line.Substring(4, 4), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out address); command = INTEL_COMMAND.DATA_LOOP; idx = 8; count -= 3; break; case MOTOROLA_COMMAND.CMD_02: if (line.Length < 11) { fail = true; } else { fail |= !uint.TryParse(line.Substring(2, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out count); fail |= !uint.TryParse(line.Substring(4, 6), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out address); } command = INTEL_COMMAND.DATA_LOOP; idx = 10; count -= 4; break; case MOTOROLA_COMMAND.CMD_03: if (line.Length < 13) { fail = true; } else { fail |= !uint.TryParse(line.Substring(2, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out count); fail |= !uint.TryParse(line.Substring(4, 8), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out address); } command = INTEL_COMMAND.DATA_LOOP; idx = 12; count -= 5; break; case MOTOROLA_COMMAND.CMD_00: case MOTOROLA_COMMAND.CMD_04: case MOTOROLA_COMMAND.CMD_05: case MOTOROLA_COMMAND.CMD_06: fail = true; break; case MOTOROLA_COMMAND.CMD_07: case MOTOROLA_COMMAND.CMD_08: case MOTOROLA_COMMAND.CMD_09: continue; } } #endregion } else if (line.StartsWith(":")) { #region Intel format if (line.Length < 11) { fail = true; } else { fail |= !uint.TryParse(line.Substring(1, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out count); fail |= !uint.TryParse(line.Substring(3, 4), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out address); fail |= !byte.TryParse(line.Substring(7, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out data); command = (INTEL_COMMAND)data; fail |= !byte.TryParse(line.Substring(line.Length - 2, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out checksum); } #endregion } else { continue; // Ignore line } if (fail) { Console.WriteLine(string.Format("Can't parse line {0}", lineNumber)); break; } switch (command) { case INTEL_COMMAND.EOF: // End of File return(0); case INTEL_COMMAND.DATA: #region Data Record idx = 9; goto data_loop; case INTEL_COMMAND.DATA_LOOP: data_loop: for (; !fail && count > 0; --count) { if (line.Length < idx + 2) { Console.WriteLine(string.Format("Data record too short at line {0}", lineNumber)); fail = true; } else { fail = !byte.TryParse(line.Substring(idx, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out data); } if (!fail) { writeToMemory(segment_address + extend_address + address - BaseAddress, data); } address++; idx += 2; } break; #endregion case INTEL_COMMAND.EXT_SEGMENT_ADDR: // Extended Segment Address Record #region Extended segment address record if (count != 2 || line.Length != 15) { Console.WriteLine(string.Format("Bad Extended segment address record line {0}.", lineNumber)); } else { fail |= !uint.TryParse(line.Substring(9, 4), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out segment_address); if (fail) { Console.WriteLine(string.Format("Bad Start Address records line {0}.", lineNumber)); } else { segment_address <<= 4; } } break; #endregion case INTEL_COMMAND.SEGMENT_ADDR: #region Start Segment Address Record if (count != 4) { Console.WriteLine(string.Format("Bad Start Segment records line {0}.", lineNumber)); } else { fail |= !uint.TryParse(line.Substring(9, 8), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out start_address); if (fail) { Console.WriteLine(string.Format("Bad Start Segment records line {0}.", lineNumber)); } else { Console.WriteLine(string.Format("Start Segment: {0:X}", start_address)); } } break; #endregion case INTEL_COMMAND.EXTEND_ADDR: #region Extended Linear Address Record if (line.Length != 15) { Console.WriteLine(string.Format("Bad Extended Address records line {0}.", lineNumber)); fail = true; } else { fail |= !uint.TryParse(line.Substring(9, 4), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out extend_address); if (!fail) { extend_address = extend_address << 16; } } break; #endregion case INTEL_COMMAND.LINEAR_ADDR: #region Start Linear Address Record if (count != 4) { Console.WriteLine(string.Format("Bad Linear Address record line {0}.", lineNumber)); } else { fail |= !uint.TryParse(line.Substring(9, 8), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out linear_address); if (fail) { Console.WriteLine(string.Format("Bad Linear Address record line {0}.", lineNumber)); } else { Console.WriteLine(string.Format("Linear Address: 0x{0:X}", linear_address)); } } break; #endregion default: Console.WriteLine(string.Format("Bad command {0} at line {1}.", command, lineNumber)); fail = true; break; } if (fail) { break; } } } return(fail ? 1 : 0); }