/// <summary> /// Reads LDA data blocks /// </summary> /// <remarks> /// The format of LDA blocks is: /// +------+ /// | 0001 | - word16 - Magic /// |------| /// | BC | - word16 - Count /// |------| /// | ADDR | - word16 - Absolute load address /// |------| /// | Data | - byte[] - Data (`Count` bytes, including the first 6 bytes) /// ... /// |------| /// | Chk | - byte - Checksum /// +------+ /// </remarks> /// <param name="rdr"></param> /// <returns></returns> public Tuple<ushort, byte[]> ReadDataBlock(LeImageReader rdr) { ushort count; ushort uAddr; byte b; // Eat bytes until 1 followed by 0. do { while (rdr.TryReadByte(out b) && b != 1) ; if (b != 1) return null; // invalid file if (!rdr.TryReadByte(out b)) return null; } while (b != 0); if (!rdr.TryReadLeUInt16(out count)) return null; if (!rdr.TryReadLeUInt16(out uAddr)) return null; if (count == 6) return new Tuple<ushort, byte[]>(uAddr, null); var data = rdr.ReadBytes(count - 6); if (data == null || data.Length < count - 6) return null; if (!rdr.TryReadByte(out b)) // read (and ignore) checksum return null; Debug.Print("Data block: {0:X4} {1:X4}", uAddr, count); return Tuple.Create(uAddr, data); }
/// <summary> /// Reads LDA data blocks /// </summary> /// <remarks> /// The format of LDA blocks is: /// +------+ /// | 0001 | - word16 - Magic /// |------| /// | BC | - word16 - Count /// |------| /// | ADDR | - word16 - Absolute load address /// |------| /// | Data | - byte[] - Data (`Count` bytes, including the first 6 bytes) /// ... /// |------| /// | Chk | - byte - Checksum /// +------+ /// </remarks> /// <param name="rdr"></param> /// <returns></returns> public (ushort, byte[]?) ReadDataBlock(LeImageReader rdr) { ushort count; ushort uAddr; byte b; // Eat bytes until 1 followed by 0. do { while (rdr.TryReadByte(out b) && b != 1) { ; } if (b != 1) { return(0, null); // invalid file } if (!rdr.TryReadByte(out b)) { return(0, null); } } while (b != 0); if (!rdr.TryReadLeUInt16(out count)) { return(0, null); } if (!rdr.TryReadLeUInt16(out uAddr)) { return(0, null); } if (count == 6) { return(uAddr, null); } var data = rdr.ReadBytes(count - 6); if (data == null || data.Length < count - 6) { return(0, null); } if (!rdr.TryReadByte(out b)) // read (and ignore) checksum { return(0, null); } Debug.Print("Data block: {0:X4} {1:X4}", uAddr, count); return(uAddr, data); }
/// <summary> /// Reads LDA data blocks /// </summary> /// <remarks> /// The format of LDA blocks is: /// +------+ /// | 0001 | - word16 - Magic /// |------| /// | BC | - word16 - Count /// |------| /// | ADDR | - word16 - Absolute load address /// |------| /// | Data | - byte[] - Data (`Count` bytes) /// ... /// |------| /// | Chk | - byte - Checksum /// +------+ /// </remarks> /// <param name="rdr"></param> /// <returns></returns> public ImageSegment ReadDataBlock(LeImageReader rdr) { ushort w; ushort count; ushort uAddr; byte b; if (!rdr.TryReadLeUInt16(out w) || w != 0x0001) { return(null); } if (!rdr.TryReadLeUInt16(out count)) { return(null); } if (!rdr.TryReadLeUInt16(out uAddr)) { return(null); } var data = rdr.ReadBytes(count); if (data == null || data.Length < count) { return(null); } if (!rdr.TryReadByte(out b)) { return(null); } Debug.Print("Data block: {0:X4} {1:X4}", uAddr, count); return(new ImageSegment( string.Format("seg{0:X4}", uAddr), new MemoryArea(Address.Ptr16(uAddr), data), AccessMode.ReadWriteExecute)); }
public override TypeLibrary Load(IPlatform platform, TypeLibrary dstLib) { var loader = new TypeLibraryDeserializer(platform, true, dstLib); var rdr = new LeImageReader(rawImage); var(type, _) = ReadRecord(rdr); if (type != RecordType.LibraryHeader) { return(dstLib); } (type, _) = ReadRecord(rdr); if (type != RecordType.THEADR) { return(dstLib); } for (; ;) { byte[] data; (type, data) = ReadRecord(rdr); if (data == null) { break; } switch (type) { default: throw new NotImplementedException($"OMF record type {type} ({(int) type:X} has not been implemented yet."); case RecordType.THEADR: // Can't seem to do anything useful with THEADRs break; case RecordType.COMENT: var rdrComent = new LeImageReader(data); if (!rdrComent.TryReadByte(out byte _)) // Ignore the comment type { break; } if (!rdrComent.TryReadByte(out byte cmtClass)) { break; } if ((CommentClass)cmtClass != CommentClass.Extensions) { break; } if (!rdrComent.TryReadByte(out byte cmtExt)) { break; } if ((CommentExtension)cmtExt == CommentExtension.IMPDEF) { ReadImpdef(rdrComent, loader); } else { throw new NotImplementedException($"OMF COMENT extension {(CommentExtension) cmtExt} (0x{cmtExt:X}) is not implemented yet."); } break; case RecordType.MODEND: // Modend's seem to be followed by padding to a 16-byte boundary. while ((rdr.Offset & 0xF) != 0 && rdr.TryReadByte(out _)) { ; } break; case RecordType.LibraryEnd: return(dstLib); } } return(dstLib); }