{ Copyright (c) 2015 by Nikolay Nikolov Contains Relocatable Object Module Format (OMF) definitions This is the object format used on the i8086-msdos platform. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. **************************************************************************** } unit omfbase; {$i fpcdefs.inc} interface uses owbase; const { OMF record types } RT_THEADR = $80; { Translator Header Record } RT_LHEADR = $82; { Library Module Header Record } RT_COMENT = $88; { Comment Record } RT_MODEND = $8A; { Module End Record } RT_MODEND32 = $8B; RT_EXTDEF = $8C; { External Names Definition Record } RT_PUBDEF = $90; { Public Names Definition Record } RT_PUBDEF32 = $91; RT_LINNUM = $94; { Line Numbers Record } RT_LINNUM32 = $95; RT_LNAMES = $96; { List of Names Record } RT_SEGDEF = $98; { Segment Definition Record } RT_SEGDEF32 = $99; RT_GRPDEF = $9A; { Group Definition Record } RT_FIXUPP = $9C; { Fixup Record } RT_FIXUPP32 = $9D; RT_LEDATA = $A0; { Logical Enumerated Data Record } RT_LEDATA32 = $A1; RT_LIDATA = $A2; { Logical Iterated Data Record } RT_LIDATA32 = $A3; RT_COMDEF = $B0; { Communal Names Definition Record } RT_BAKPAT = $B2; { Backpatch Record } RT_BAKPAT32 = $B3; RT_LEXTDEF = $B4; { Local External Names Definition Record } RT_LEXTDEF32 = $B5; RT_LPUBDEF = $B6; { Local Public Names Definition Record } RT_LPUBDEF32 = $B7; RT_LCOMDEF = $B8; { Local Communal Names Definition Record } RT_CEXTDEF = $BC; { COMDAT External Names Definition Record } RT_COMDAT = $C2; { Initialized Communal Data Record } RT_COMDAT32 = $C3; RT_LINSYM = $C4; { Symbol Line Numbers Record } RT_LINSYM32 = $C5; RT_ALIAS = $C6; { Alias Definition Record } RT_NBKPAT = $C8; { Named Backpatch Record } RT_NBKPAT32 = $C9; RT_LLNAMES = $CA; { Local Logical Names Definition Record } RT_VERNUM = $CC; { OMF Version Number Record } RT_VENDEXT = $CE; { Vendor-specific OMF Extension Record } type { TOmfRawRecord } TOmfRawRecord = class private function GetChecksumByte: Byte; function GetRecordLength: Word; function GetRecordType: Byte; procedure SetChecksumByte(AValue: Byte); procedure SetRecordLength(AValue: Word); procedure SetRecordType(AValue: Byte); public RawData: array [-3..65535] of Byte; property RecordType: Byte read GetRecordType write SetRecordType; property RecordLength: Word read GetRecordLength write SetRecordLength; procedure CalculateChecksumByte; function VerifyChecksumByte: boolean; property ChecksumByte: Byte read GetChecksumByte write SetChecksumByte; procedure ReadFrom(aReader: TObjectReader); procedure WriteTo(aWriter: TObjectWriter); end; implementation { TOmfRawRecord } function TOmfRawRecord.GetRecordType: Byte; begin Result:=RawData[-3]; end; procedure TOmfRawRecord.SetRecordType(AValue: Byte); begin RawData[-3]:=AValue; end; function TOmfRawRecord.GetRecordLength: Word; begin Result:=RawData[-2] or (RawData[-1] shl 8); end; procedure TOmfRawRecord.SetRecordLength(AValue: Word); begin RawData[-2]:=Byte(AValue); RawData[-1]:=Byte(AValue shr 8); end; function TOmfRawRecord.GetChecksumByte: Byte; begin if RecordLength>0 then Result:=RawData[RecordLength-1] else Result:=0; end; procedure TOmfRawRecord.SetChecksumByte(AValue: Byte); begin if RecordLength>0 then RawData[RecordLength-1]:=AValue; end; procedure TOmfRawRecord.CalculateChecksumByte; var I: Integer; b: Byte; begin b:=0; for I:=-3 to RecordLength-2 do b:=byte(b+RawData[I]); SetChecksumByte($100-b); end; function TOmfRawRecord.VerifyChecksumByte: boolean; var I: Integer; b: Byte; begin { according to the OMF spec, some tools always write a 0 rather than computing the checksum, so it should also be accepted as correct } if ChecksumByte=0 then exit(true); b:=0; for I:=-3 to RecordLength-1 do b:=byte(b+RawData[I]); Result:=(b=0); end; procedure TOmfRawRecord.ReadFrom(aReader: TObjectReader); begin aReader.read(RawData, 3); aReader.read(RawData[0], RecordLength); end; procedure TOmfRawRecord.WriteTo(aWriter: TObjectWriter); begin aWriter.write(RawData, RecordLength+3); end; end.