Creating Unit File
CompileUnit calls this procedure to create unit file which is in fact a collection of symbol tables. All segment addresses are cleared and symbol table data is written to the file.
Procedure CreateUnitFile;
Var SavedUnitSegment: Word;
UnitFile: File;
UnitFileSize, BytesToWrite: LongInt;
UnitPtr: Pointer;
BytesWritten: Word;
UnitCounter: Word;
UnitIdentifier: PIdentifier;
UnitIdentifierRec: PtrRec absolute UnitIdentifier;
UnitIdentifierData: PUnitIdentifierData;
UnitHeader: PUnitHeader;
begin
If cmoCompileToDisk in CompilerModeOptions then
begin
UnitCounter := 0; { Push And Clear Unit Segments;}
UnitHeader := Ptr (MainSymbolTable.Segment, 0);
UnitIdentifier := Ptr (MainSymbolTable.Segment, UnitHeader^.UnitNameIdentifierOffset);
Repeat
UnitIdentifierData := PUnitIdentifierData (PChar (UnitIdentifier) + UnitIdentifier^.Name.Len + 4);
Asm
LES DI, UnitIdentifierData
PUSH WORD PTR ES:[DI] { UnitIdentifierData^.UnitSegment) }
PUSH DI { Ofs (UnitIdentifierData^) }
end;
UnitIdentifierData^.UnitSegment := 0;
Inc (UnitCounter);
UnitIdentifierRec.Ofs := UnitIdentifierData^.NextUnitIdentifier;
until UnitIdentifierRec.Ofs = 0;
SavedUnitSegment := PUnitHeader (Ptr (MainSymbolTable.Segment, 0))^.PreviousUnitSegment;
PUnitHeader (Ptr (MainSymbolTable.Segment, 0))^.PreviousUnitSegment := 0;
FindFilePath (StrPCopy (@Identifier, CurrentSourceFile^.Name.Str),
Dir_Forced or Dir_EXE_TPU or Ext_Forced or Ext_TPU);
CreateFile (UnitFile, @Identifier);
OutputFileHandle := FileRec (UnitFile).Handle;
UnitFileSize := LongInt (HeapPtrRec.Seg - MainSymbolTable.Segment) * 16;
UnitPtr := Ptr (MainSymbolTable.Segment, 0);
{$I-}
While UnitFileSize > 0 do
begin
BytesToWrite := UnitFileSize;
If BytesToWrite > $FFF0 then BytesToWrite := $FFF0;
BlockWrite (UnitFile, UnitPtr^, BytesToWrite, BytesWritten);
If IOResult <> 0 then Error (DiskFull);
Dec (UnitFileSize, BytesWritten);
UnitPtr := Ptr (Seg (UnitPtr^) + $0FFF, 0);
end;
Close (UnitFile);
{$I+}
OutputFileHandle := 0;
PUnitHeader (Ptr (MainSymbolTable.Segment, 0))^.PreviousUnitSegment := SavedUnitSegment;
Asm
LES DI, UnitHeader
MOV CX, UnitCounter
@1:
POP DI
POP WORD PTR ES:[DI]
LOOP @1
end;
end;
CodeBytes := SymbolTable [stCode].UsedSize;
DataBytes := SymbolTable [stTypedConstants].UsedSize + SizeOfVariablesInDataSegment;
end;