-- InitialXD.Mesa  Edited by:
  -- Evans on May 19, 1980  4:33 PM
  -- Bruce on Oct 13, 1980 10:01 AM
  -- Sandman on July 18, 1980  3:49 PM
  -- Johnsson on July 15, 1980  2:54 PM
  
DIRECTORY
  Ascii USING [CR],
  DebugOps USING [ShortCopyREAD, ShortREAD, window],
  DOutput USING [Char, Line],
  Event USING [Notify],
  FrameDefs USING [MakeCodeResident, UnlockCode],
  FrameOps USING [MyGlobalFrame],
  ImageDefs USING [ImageTime],
  Init USING [bootLoaded, RestartMsg],
  InitXD USING [XDSwap],
  Inline USING [BITAND, BITNOT, BITOR],
  MachineDefs USING [],
  Mopcodes USING [zRBL, zWBL],
  NucleusOps USING [HyperRegion],
  OsStaticDefs USING [OsStaticRecord, OsStatics],
  Profile USING [bitmap],
  SegmentDefs USING [
    Banks, DataSegmentHandle, DefaultANYBase,
    HardUp, LongDataSegmentAddress, MakeDataSegment, MemoryConfig],
  Source USING [SetSize],
  State USING [GetGS, GetString, GSHandle],
  Storage USING [String],
  String USING [AppendString],
  StringDefs USING [BcplToMesaString],
  SwapperOps USING [ComputeRealMemory, EnableBank, memConfig, SystemTable],
  TajoMisc USING [SetBitmap, SetState],
  Time USING [Append, AppendCurrent, Unpack],
  UserTerminalOps USING [SetBitmapSpace],
  ToolWindow USING [SetBox];
  
InitialXD: PROGRAM
  IMPORTS DebugOps, DOutput, Event, FrameDefs, FrameOps, ImageDefs, Init, InitXD,
    Inline, NucleusOps, Profile, SegmentDefs, Source, Storage, String, StringDefs,
    SwapperOps, State, TajoMisc, Time, UserTerminalOps, 
    ToolWindow
  EXPORTS Init, InitXD =
  BEGIN OPEN Init, MachineDefs;
  
  herald: STRING;
  data: State.GSHandle;
  ourBitmapSeg: PUBLIC SegmentDefs.DataSegmentHandle ← NIL;
  
  WriteHerald: PUBLIC PROCEDURE [install: BOOLEAN ← FALSE] =
    BEGIN
    time: STRING ← [18];
    IF install THEN
      BEGIN
      data ← State.GetGS[];
      herald ← Storage.String[46];
      String.AppendString[herald, "Alto/Mesa Debugger 6.0 of "L];
      Time.Append[herald, Time.Unpack[ImageDefs.ImageTime[]]];
      herald.length ← herald.length - 3;
      RETURN;
      END;
    DOutput.Line[herald];
    Time.AppendCurrent[time];
    time.length ← time.length - 3;
    DOutput.Line[time];
    Init.RestartMsg[];
    DOutput.Char[Ascii.CR]
    END;
    
  CopyUserNamePassword: PUBLIC PROCEDURE =
    BEGIN OPEN OsStaticDefs;
    userStatics: POINTER TO OsStaticRecord = DebugOps.ShortREAD[OsStatics];
    debuggerStatics: POINTER TO OsStaticRecord = OsStatics↑;
    pc: TYPE = POINTER TO CARDINAL;
    IF data.loggedIn OR Init.bootLoaded THEN RETURN;
    DebugOps.ShortCopyREAD[
      from: DebugOps.ShortREAD[@userStatics.UserName],
      to: debuggerStatics.UserName,
      nwords: LOOPHOLE[debuggerStatics.UserName-1,pc]↑];
    DebugOps.ShortCopyREAD[
      from: DebugOps.ShortREAD[@userStatics.UserPassword],
      to: debuggerStatics.UserPassword,
      nwords: LOOPHOLE[debuggerStatics.UserPassword-1,pc]↑];
    debuggerStatics.SerialNumber ←
      DebugOps.ShortREAD[@userStatics.SerialNumber];
    StringDefs.BcplToMesaString[
      s: State.GetString[user], t: OsStatics.UserName];
    StringDefs.BcplToMesaString[
      s: State.GetString[password], t: OsStatics.UserPassword];
    Event.Notify[setDefaults];
    END;
    
  allowed: WORD ← SwapperOps.memConfig.banks;
  
  CheckMemory: PUBLIC PROCEDURE =
    BEGIN OPEN SwapperOps, Inline;
    real, weUse, iUse: SegmentDefs.Banks;
    clientMemConfig: SegmentDefs.MemoryConfig;
    table: POINTER TO SystemTable = data.ESV.tables;
    CopyUserNamePassword[];
    IF table = NIL --OR bootLoaded --THEN {CheckOutBitmap[TRUE]; RETURN};
    real ← SwapperOps.ComputeRealMemory[].banks;
    IF ~bootLoaded THEN {
      DebugOps.ShortCopyREAD[
	to: @clientMemConfig,
	from: DebugOps.ShortREAD[@table.memConfig],
	nwords: SIZE[SegmentDefs.MemoryConfig]];
      memConfig ← clientMemConfig}
    ELSE clientMemConfig.banks ← LOOPHOLE[100000B, CARDINAL];
    weUse ← BITOR[allowed, clientMemConfig.banks];
    iUse ← BITOR[
      100000B, BITAND[BITAND[real, allowed], BITNOT[clientMemConfig.banks]]];
    memConfig.banks ← LOOPHOLE[weUse];
    IF iUse # LOOPHOLE[100000B] THEN
      BEGIN
      FrameDefs.MakeCodeResident[LOOPHOLE[InitXD.XDSwap]];
      FrameDefs.MakeCodeResident[LOOPHOLE[NucleusOps.HyperRegion]];
      FrameDefs.MakeCodeResident[FrameOps.MyGlobalFrame[]];
      memConfig.useXM ← TRUE;
      FOR i: CARDINAL IN [1..15] DO IF iUse[i] THEN EnableBank[i]; ENDLOOP;
      CheckOutBitmap[FALSE];
      FrameDefs.UnlockCode[NucleusOps.HyperRegion];
      FrameDefs.UnlockCode[FrameOps.MyGlobalFrame[]];
      END
    ELSE {memConfig.useXM ← FALSE; CheckOutBitmap[TRUE]};
    RETURN
    END;
    
  RBL: PROCEDURE [LONG POINTER] RETURNS [CARDINAL] =
    MACHINE CODE BEGIN Mopcodes.zRBL, 0 END;
    
  WBL: PROCEDURE [CARDINAL, LONG POINTER] =
    MACHINE CODE BEGIN Mopcodes.zWBL, 0 END;
    
  LP: PROCEDURE [CARDINAL, CARDINAL] RETURNS [LONG POINTER] =
    MACHINE CODE BEGIN END;
    
  providedBitmap: LONG POINTER ← NIL;
  BitmapPassword: ARRAY [0..3] OF CARDINAL = [
    126027B, 27072B, 125241B, 107426B];
  firstNewSession: BOOLEAN ← TRUE;
  
  CheckOutBitmap: PROCEDURE [oneBank: BOOLEAN] =
    BEGIN
    [] ← TajoMisc.SetState[disconnected];
    SELECT TRUE FROM
      oneBank AND providedBitmap = NIL AND data.ESV.bitmap = NIL =>
	TajoMisc.SetBitmap[[[48, 72], [512, 352]]];
      providedBitmap # NIL AND providedBitmap = data.ESV.bitmap AND
	BitmapOK[data.ESV.bitmapPages] => NULL;
      data.ESV.bitmap # NIL =>
	BEGIN
	providedBitmap ← data.ESV.bitmap;
	UserTerminalOps.SetBitmapSpace[
	  address: providedBitmap+4, words: (256*data.ESV.bitmapPages)-4];
	SetBitmapPassword[data.ESV.bitmapPages];
	TajoMisc.SetBitmap[[[32, 32], [544, 744]]];
	END;
      providedBitmap # NIL =>
	BEGIN
	providedBitmap ← NIL;
	IF oneBank THEN
	  BEGIN
	  UserTerminalOps.SetBitmapSpace[address: NIL, words: 0];
	  TajoMisc.SetBitmap[[[48, 72], [512, 352]]];
	  END
	ELSE
	  BEGIN OPEN SegmentDefs;
	  ourBitmapSeg ←
	    MakeDataSegment[base: DefaultANYBase, pages: 99, info: HardUp];
	  UserTerminalOps.SetBitmapSpace[
	    address: LongDataSegmentAddress[ourBitmapSeg], words: 99*256];
	  TajoMisc.SetBitmap[[[32, 32], [544, 744]]];
	  END;
	END;
      ENDCASE =>
	BEGIN OPEN SegmentDefs;
	ourBitmapSeg ←
	  MakeDataSegment[base: DefaultANYBase, pages: 99, info: HardUp];
	UserTerminalOps.SetBitmapSpace[
	  address: LongDataSegmentAddress[ourBitmapSeg], words: 99*256];
	TajoMisc.SetBitmap[[[32, 32], [544, 744]]];
	END;
    IF firstNewSession AND Profile.bitmap = [[32, 32], [544, 744]] THEN {
      ToolWindow.SetBox[DebugOps.window, [[0,0],DebugOps.window.box.dims]];
      Source.SetSize[];
      firstNewSession ← FALSE};
    RETURN
    END;
    
  BitmapOK: PROCEDURE [pages: CARDINAL] RETURNS [BOOLEAN] =
    BEGIN
    FOR i: CARDINAL IN [0..3] DO
      IF RBL[providedBitmap+i] # BitmapPassword[i]+pages THEN RETURN[FALSE];
      ENDLOOP;
    RETURN[TRUE];
    END;
    
  SetBitmapPassword: PROCEDURE [pages: CARDINAL] =
    BEGIN
    FOR i: CARDINAL IN [0..3] DO
      WBL[BitmapPassword[i]+pages, providedBitmap+i];
      ENDLOOP;
    END;
    
  END.