private Address HandleAddress(IntelHexRecord hexRecord) { switch (hexRecord.RecordType) { case IntelHexRecordType.Data: return(AddressBase + hexRecord.Address); case IntelHexRecordType.ExtendedSegmentAddress: if (IsLinear) { throw new IntelHexException($"Mixed segmented/linear address.", lineNum); } IsSegmented = true; var seg = ((uint)hexRecord.Data ![0] << 8) | hexRecord.Data[1];
private Address HandleAddress(IntelHexRecord hexRecord) { switch (hexRecord.RecordType) { case IntelHexRecordType.Data: return(AddressBase + hexRecord.Address); case IntelHexRecordType.ExtendedSegmentAddress: if (IsLinear) { throw new IntelHexException($"Mixed segmented/linear address.", lineNum); } IsSegmented = true; var seg = ((uint)hexRecord.Data[0] << 8) | hexRecord.Data[1]; AddressBase = Address.SegPtr((ushort)seg, 0); return(AddressBase); case IntelHexRecordType.ExtendedLinearAddress: if (IsSegmented) { throw new IntelHexException($"Mixed segmented/linear address.", lineNum); } IsLinear = true; AddressBase = Address.Ptr32((((uint)hexRecord.Data[0] << 8) | hexRecord.Data[1]) << 16); return(AddressBase); case IntelHexRecordType.StartSegmentAddress: if (IsLinear) { throw new IntelHexException($"Mixed segmented/linear address.", lineNum); } IsSegmented = true; StartAddress = Address.SegPtr((ushort)((hexRecord.Data[0] << 8) | hexRecord.Data[1]), (ushort)((hexRecord.Data[2] << 8) | hexRecord.Data[3])); return(AddressBase); case IntelHexRecordType.StartLinearAddress: if (IsSegmented) { throw new IntelHexException($"Mixed segmented/linear address.", lineNum); } IsLinear = true; StartAddress = Address.Ptr32(((uint)hexRecord.Data[0] << 24) | ((uint)hexRecord.Data[1] << 16) | ((uint)hexRecord.Data[2] << 8) | hexRecord.Data[3]); return(AddressBase); default: throw new IntelHexException($"Unknown value read for [{nameof(hexRecord.RecordType)}]", lineNum); } }
/// <summary> /// Parse a single Intel Hex32 hexadecimal record. /// </summary> /// <param name="hexRecord">The hexadecimal record as a string.</param> /// <param name="lineNum">(Optional) The line number in the IHex32 binary stream.</param> /// <returns> /// An <see cref="IntelHexRecord"/> . /// </returns> /// <exception cref="IntelHex32Exception">Thrown whenever an error is found in the IHex32 record.</exception> public static IntelHexRecord ParseRecord(string hexRecord, int lineNum = 0) { List <byte> ParseHexData() { try { return(Enumerable.Range(1, hexRecord.Length - 1) .Where(i => (i & 1) != 0) .Select(i => Convert.ToByte(hexRecord.Substring(i, 2), 16)) .ToList()); } catch (Exception ex) { throw new IntelHexException($"Unable to parse hexedecimal numbers in Intel Hex line [{hexRecord}]", ex, lineNum); } } if (hexRecord == null) { throw new IntelHexException("Intel Hex line can not be null.", lineNum); } if (hexRecord.Length < MinHexRecordSize) { throw new IntelHexException($"Intel Hex line [{hexRecord}] is less than {MinHexRecordSize} characters long.", lineNum); } if (hexRecord.Length % 2 == 0) { throw new IntelHexException($"Intel Hex line has an even number of characters [{hexRecord}].", lineNum); } if (!hexRecord.StartsWith(":")) { throw new IntelHexException($"Illegal Intel Hex line start character [{hexRecord}].", lineNum); } var hexData = ParseHexData(); if (hexData.Count != hexData[0] + 5) { throw new IntelHexException($"Intel Hex line [{hexRecord}] does not have required record length of [{hexData[0] + 5}].", lineNum); } if (!Enum.IsDefined(typeof(IntelHexRecordType), hexData[3])) { throw new IntelHexException($"Intel Hex line has an invalid/unsupported record type value: [{hexData[3]}].", lineNum); } if ((hexData.Sum(b => b) % 256) != 0) { throw new IntelHexException($"Checksum for Intel Hex line [{hexRecord}] is incorrect.", lineNum); } var rdr = new ByteImageReader(hexData.ToArray()); var datasize = rdr.ReadByte(); var newRecord = new IntelHexRecord { ByteCount = datasize, Address = rdr.ReadBeUInt16(), RecordType = (IntelHexRecordType)rdr.ReadByte(), Data = rdr.ReadBytes(datasize).ToList(), CheckSum = rdr.ReadByte() }; return(newRecord); }