-- file BootNewCompiler.mesa
-- last modified by Sandman, Jan 15, 1980 1:46 PM

DIRECTORY
  AltoFileDefs: FROM "altofiledefs" USING [eofDA, fillinDA, vDA],
  BFSDefs: FROM "bfsdefs" USING [ActOnPages, GetNextDA],
  CBinary: FROM "cbinary" USING [MesaTab, ErrorTab, DebugTab],
  CompilerOps: FROM "compilerops" USING [Interface],
  CompilerUtil: FROM "compilerutil" USING [TableId, parse, error, debug],
  ControlDefs: FROM "controldefs" USING [GlobalFrameHandle],
  DiskDefs: FROM "diskdefs" USING [DiskRequest],
  FrameOps: FROM "frameops" USING [CodeHandle, MyGlobalFrame],
  MiscDefs: FROM "miscdefs" USING [DestroyFakeModule, SetBlock],
  SDDefs: FROM "sddefs" USING [sAddFileRequest, SD],
  SegmentDefs: FROM "segmentdefs" USING [
    DataSegmentAddress, DataSegmentHandle, DefaultBase, DeleteDataSegment,
    EnumerateFileSegments, FileHandle, FileSegmentHandle, memConfig,
    NewDataSegment, SetFileSegmentDA],
  SystemDefs: FROM "systemdefs" USING [PagesForWords];

BootNewCompiler: PROGRAM 
  IMPORTS
    BFSDefs, CBinary, CompilerOps, FrameOps,
    MiscDefs, SegmentDefs, SystemDefs
  SHARES SegmentDefs  =
  BEGIN

  -- Disk Addresses

  FileSegmentHandle: TYPE = SegmentDefs.FileSegmentHandle;

  CollectDiskAddresses: PROCEDURE =
    BEGIN OPEN SystemDefs, SegmentDefs, AltoFileDefs;
    ImageFile: FileHandle =FrameOps.CodeHandle[FrameOps.MyGlobalFrame[]].file;
    DAs: DESCRIPTOR FOR ARRAY OF vDA;
    maxunknown, maxknown: CARDINAL ← FIRST[CARDINAL];
    minunknown: CARDINAL ← LAST[CARDINAL];
    maxknownDA: vDA;
    DisplayHead: POINTER TO WORD = LOOPHOLE[420B];
    saveDisplay: WORD;
    diskrequest: DiskDefs.DiskRequest;
    bufseg, DAseg: DataSegmentHandle;

    FindEnds: PROCEDURE [seg: FileSegmentHandle] RETURNS [BOOLEAN] =
      BEGIN
      WITH s: seg SELECT FROM
	disk =>
	  IF s.file = ImageFile AND s.hint.da = eofDA THEN
	    BEGIN
	    maxunknown ← MAX[maxunknown,s.base];
	    minunknown ← MIN[minunknown,s.base];
	    END;
	ENDCASE;
      RETURN [FALSE];
      END;

    FindKnown: PROCEDURE [seg: FileSegmentHandle] RETURNS [BOOLEAN] =
      BEGIN
      WITH s: seg SELECT FROM
	disk =>
	  IF s.file = ImageFile AND s.hint.da # eofDA AND s.base < minunknown
	  AND s.base > maxknown THEN
	    BEGIN maxknown ← s.base; maxknownDA ← s.hint.da END;
	ENDCASE;
      RETURN [FALSE];
      END;

    PlugDA: PROCEDURE [seg: FileSegmentHandle] RETURNS [BOOLEAN] =
      BEGIN
      WITH s: seg SELECT FROM
	disk =>
	  IF s.file = ImageFile AND s.hint.da = eofDA AND
	    s.base IN (maxknown..maxunknown] THEN
	    SegmentDefs.SetFileSegmentDA[@s,DAs[s.base]];
	ENDCASE;
      RETURN [FALSE];
      END;

    saveDisplay ← DisplayHead↑;
    DisplayHead↑ ← 0;
    [] ← EnumerateFileSegments[FindEnds];
    [] ← EnumerateFileSegments[FindKnown];
    bufseg ← NewDataSegment[DefaultBase, 1];
    DAseg ← NewDataSegment[
      DefaultBase, PagesForWords[maxunknown-maxknown+3]];
    DAs ← DESCRIPTOR[DataSegmentAddress[DAseg]-(maxknown-1),maxunknown+2];
    diskrequest ← DiskDefs.DiskRequest [
      ca: DataSegmentAddress[bufseg],
      fixedCA: TRUE,
      da: @DAs[0],
      fp: @ImageFile.fp,
      firstPage: maxknown,
      lastPage: maxunknown,
      action: ReadD,
      lastAction: ReadD,
      signalCheckError: FALSE,
      option: update[cleanup: BFSDefs.GetNextDA]];
    MiscDefs.SetBlock[@DAs[maxknown-1],fillinDA,maxunknown-maxknown+3];
    DAs[maxknown] ← maxknownDA;
    [] ← BFSDefs.ActOnPages[LOOPHOLE[@diskrequest]];  -- we know it is an Update diskrequest
    [] ← EnumerateFileSegments[PlugDA];
    DeleteDataSegment[DAseg];
    DeleteDataSegment[bufseg];
    DisplayHead↑ ← saveDisplay;
    END;

  segment: ARRAY CompilerUtil.TableId OF SegmentDefs.FileSegmentHandle;

  BEGIN  OPEN CompilerUtil;
  [segment[parse],] ← MiscDefs.DestroyFakeModule[LOOPHOLE[CBinary.MesaTab]];
  [segment[error],] ← MiscDefs.DestroyFakeModule[LOOPHOLE[CBinary.ErrorTab]];
  [segment[debug],] ← MiscDefs.DestroyFakeModule[LOOPHOLE[CBinary.DebugTab]];
  END;

  START CompilerOps.Interface[
	explicitSwapping: ~SegmentDefs.memConfig.useXM,
	tableSegment: segment];
  IF (SDDefs.SD[SDDefs.sAddFileRequest] # 0) THEN
    BEGIN
    STOP;
    CollectDiskAddresses[];
    END;
  RESTART CompilerOps.Interface;

  END.