Press enter to see results or esc to cancel.

Importing SEGDEF Object File Record

This procedure processes SEGDEF record ($98), finds appropriate Turbo Pascal segment and creates space in the symbol table for that segment.

Procedure OMF_SEGDEF; Far;
Var SegmentClass: Byte;
    SegmentLength: Word;
    SegDef: PSegDef;

  Function FindSegmentClass (SegmentNameIndex: Byte): Boolean;
  Type TSegData = Record
                    Name: String [5];
                    Class: Byte;
                  end;
  Const SegData: Array [1..8] of TSegData = (
          (Name:  'CODE'; Class: 0),
          (Name:  'CSEG'; Class: 0),
          (Name: '_TEXT'; Class: 0),
          (Name: 'CONST'; Class: 1),
          (Name: '_DATA'; Class: 1),
          (Name:  'DATA'; Class: 2),
          (Name:  'DSEG'; Class: 2),
          (Name:  '_BSS'; Class: 2));
  Var TempObjectFileRecordPtr,
      NextObjectFileRecordPtr: PObjectFileRecord;
      TempObjectFileRecordPtrRec: PtrRec absolute TempObjectFileRecordPtr;
      SegmentNameStr: String;
      N: Byte;
      NamePtr: PString;

{$IFDEF DEBUGOMF}
      SegmentName: String;
{$ENDIF}

  begin
    FindSegmentClass := False;
    TempObjectFileRecordPtr := Ptr (ObjectFileSegment, 0);
    Repeat
      NextObjectFileRecordPtr := Ptr (ObjectFileSegment,
                                      Ofs (TempObjectFileRecordPtr^) + TempObjectFileRecordPtr^.RecordLength + 3);
      If TempObjectFileRecordPtr^.RecordType = $96 then { LNAMES }
        begin
          Dec (PChar (NextObjectFileRecordPtr));
          NamePtr := @TempObjectFileRecordPtr^.Name;
          Repeat
            Dec (SegmentNameIndex);
            If SegmentNameIndex = 0 then
              begin
                For N := 1 to 8 do
                  begin
                    SegmentNameStr := NamePtr^;
{$IFDEF DEBUGOMF}
                    SegmentName := SegmentNameStr;
{$ENDIF}
                    If (Length (SegData [N].Name) < Length (SegmentNameStr)) and (SegData [N].Name [1] = '_') then
                      SegmentNameStr := Copy (SegmentNameStr, Length (SegmentNameStr) - Length (SegData [N].Name) + 1,
                                                              Length (SegData [N].Name));
                    If SegmentNameStr = SegData [N].Name then
                      begin
                        SegmentClass := SegData [N].Class;
{$IFDEF DEBUGOMF}
                        Writeln (SegmentName, ', Class: ', SegmentClass);
{$ENDIF}
                        FindSegmentClass := True;
                        Exit;
                      end;
                  end;
                Exit;
              end;
            Inc (PChar (NamePtr), Length (NamePtr^) + 1);
          until Pointer (NamePtr) = NextObjectFileRecordPtr;
          Inc (PChar (NextObjectFileRecordPtr));
        end;
      TempObjectFileRecordPtr := NextObjectFileRecordPtr;
    until False;
  end;

begin

{$IFDEF DEBUGOMF}
  Write ('        SEGDEF: ');
{$ENDIF}

  SegDef := @ObjectFilePtr^.SegDef;
  Repeat
    Inc (SegmentCounter);
    If SegDef^.SegmentAttributes and $E0 <> 0 then       { not absolute segment }
      begin
        SegmentLength := SegDef^.SegmentLength;
        If FindSegmentClass (SegDef^.SegmentNameIndex) then
          begin
            Case SegmentClass of
              0: If CodeSegmentIndex = 0 then
                   begin
                     CodeSegmentIndex := SegmentCounter;
                     FillChar (IncreaseSymbolTable (stCode, SegmentLength)^, SegmentLength, 0);
                   end;
              1: If TypedConstantsSegmentIndex = 0 then
                   begin
                     TypedConstantsSegmentIndex := SegmentCounter;
                     FillChar (IncreaseSymbolTable (stTypedConstants, SegmentLength)^, SegmentLength, 0);
                   end;
              else If VariablesSegmentIndex = 0 then
                     begin
                       VariablesSegmentIndex := SegmentCounter;
                       If LongInt (SizeOfVariablesInDataSegment) + SegmentLength > $FFFF then
                         FileError (@Identifier, DataSegmentTooLarge);
                       Inc (SizeOfVariablesInDataSegment, SegmentLength);
                     end;
            end;
          end;
        Inc (PChar (SegDef), 6);
      end else Inc (PChar (SegDef), 9);
  until Ofs (SegDef^) >= ObjectRecordChecksumOffset;
end;