-- MMMakeBoot.mesa  Edit: Sandman on Dec 5, 1979 2:38 PM
-- Edit: Forrest on July 15, 1980  2:07 PM

DIRECTORY
  AltoFileDefs USING [CFP],
  BcplOps USING [BcplJSR, BcplOpcode],
  ControlDefs USING [TraceOff],
  FrameDefs USING [UnNew],
  FrameOps USING [MyGlobalFrame, MyLocalFrame],
  ImageDefs USING [StopMesa],
  InlineDefs USING [COPY],
  MMInit,
  MMOps USING [etherBooted, FakeModulesCode, MMAltoRam],
  Mopcodes USING [zIWDC, zSTOP],
  OsStaticDefs USING [OsStatics],
  ProcessDefs USING [DisableInterrupts, EnableInterrupts],
  ProcessOps USING [ReadWDC, WriteWDC],
  SDDefs USING [SD, sGoingAway, sXferTrap],
  StringDefs USING [MesaToBcplString],
  TrapOps USING [WriteXTS];

MMMakeBoot: PROGRAM
  IMPORTS BcplOps, FrameDefs, FrameOps, ImageDefs, InlineDefs, MMOps,
    ProcessDefs, ProcessOps, StringDefs, TrapOps
  EXPORTS MMInit = BEGIN

SwatVector: TYPE = RECORD [
  fill: ARRAY [0..4) OF UNSPECIFIED,
  swatee: AltoFileDefs.CFP,
  swat: AltoFileDefs.CFP];

SpecialOutLD: PROCEDURE [
  BcplOps.BcplOpcode, POINTER TO AltoFileDefs.CFP, POINTER] RETURNS [[0..3]] =
  MACHINE CODE BEGIN Mopcodes.zSTOP; Mopcodes.zIWDC END;

MakeBootFile: PUBLIC PROCEDURE =
  BEGIN OPEN InlineDefs;
  foo: ARRAY[0..19] OF WORD; -- "message" for OutLd
  wdc: CARDINAL;
  pageOne: ARRAY [0..256) OF WORD;
  swatVector: POINTER TO POINTER TO SwatVector = LOOPHOLE[567B];
  JSRCode: ARRAY [0..2) OF UNSPECIFIED←[
    161000B,	-- mov 3,0
    001400B];  -- jmp 0,3
  HostCode: ARRAY [0..3) OF UNSPECIFIED←[
    102400B,	-- sub 0,0
    061004B,	-- startio - returns host number in ac0
    001400B];  -- jmp 0,3
  VersionCode: ARRAY [0..2) OF UNSPECIFIED←[
    061014B,	-- vers - returns version info in ac0
    001400B];  -- jmp 0,3
  fixCodeSize: CARDINAL = 58;
  fixCodeReturnOffset: CARDINAL = fixCodeSize-5;
  fixCodeRamOffset: CARDINAL = fixCodeSize-25;
  FixCode: ARRAY [0..fixCodeSize) OF UNSPECIFIED←[
    -- FIX UP PAGE 1
    4415B,  --jsr foo (.+13D)
    0,0,0,  -- first source-1
    0,0,0,  -- last destination
    0,0,0,  -- minus count
    0,0,0,
    -- args for BLT get filled in by MesaCode after it figures out where page 1 is saved
    171000B,  --foo:	mov 3 2
    21000B,  --lda 0 0 2
    25001B,  --lda 1 1 2
    35002B,  --lda 3 2 2
    61005B,  --blt
    21003B,  --lda 0 3 2
    25004B,  --lda 1 4 2
    35005B,  --lda 3 5 2
    61005B,  --blt
    21006B,  --lda 0 6 2
    25007B,  --lda 1 7 2
    35010B,  --lda 3 10 2
    61005B,  --blt
    21011B,  --lda 0 11 2
    25012B,  --lda 1 12 2
    35013B,  --lda 3 13 2
    61005B,  --blt
    -- LOAD RAM
    126400B,  -- sub 1,1
    030402B,  -- lda 2,p (.+2)
    000403B,  -- jmp loop (.+3)
    000000B,  --  p: location of Ram
    002000B,  --  n: size of Ram
    021000B,  -- loop: lda 0,0,2
    035001B,  -- lda 3,1,2
    061012B,  -- WRTRAM  Ram[ac1] ← [ac0,ac3]
    125400B,  -- inc 1,1
    151400B,  -- inc 2,2
    151400B,  -- inc 2,2
    014771B,  -- dsz n (.-7)
    000771B,  --  jmp loop (.-7)
    -- Set Ram Start Address
    034416B,  -- lda 3 c20
    126400B,  -- sub 1,1
    061014B,  -- vers
    030411B,  -- lda 2 c37777
    112423B,  -- subz 0,2 snc
    024410B,  --   lda 1 c400
    137000B,  -- add 1 3
    054062B,  -- sta 3 62
    -- GET BACK to MESA
    020403B,  --lda 0 three
    002401B,  --jmp @.+1
    174533B,  --174533 for mesa 4.0, patched by MesaCode
    3B,       --three: 3  EtherBoot return value
    37777B,   -- c37777: 37777
    400B,     -- c400: 400
    20B];     -- c20: 20
  BEGIN OPEN StringDefs, OsStaticDefs.OsStatics↑↑;
    MesaToBcplString["No Name"L,UserName];
    MesaToBcplString["****************"L,UserPassword];
    MesaToBcplString[""L,UserPassword];
    END;
  FixCode[fixCodeRamOffset] ← MMOps.FakeModulesCode[MMOps.MMAltoRam];
  ProcessDefs.DisableInterrupts[];
  FixCode[fixCodeReturnOffset] ← BcplOps.BcplJSR[JSR,@JSRCode[0],NIL];
  BEGIN
  p: POINTER TO ARRAY [0..2] OF POINTER = LOOPHOLE[0];
  p[0]←@FixCode[0];
  p[1]←FrameOps.MyLocalFrame[];
  p[2]←FrameOps.MyGlobalFrame[];
  END;
  -- save page 1 in case of EtherBoot
  COPY[to:@pageOne,from:LOOPHOLE[400B],nwords:256];
  FixCode[1]←(@pageOne)-1;
  FixCode[2]←427B;
  FixCode[3]←-30B;
  FixCode[4]←(@pageOne)-1+31B;
  FixCode[5]←520B;
  FixCode[6]←-70B;
  FixCode[7]←(@pageOne)-1+124B;
  FixCode[8]←567B;
  FixCode[9]←-44B;
  FixCode[10]←(@pageOne)-1+200B;
  FixCode[11]←777B;
  FixCode[12]←-200B;
  SDDefs.SD[SDDefs.sXferTrap] ← FrameOps.MyLocalFrame[];
  wdc ← ProcessOps.ReadWDC[];
  SELECT (SpecialOutLD[OutLd, @swatVector.swatee,@foo]) FROM
    0 => -- normal return (OutLd just finished)
      BEGIN
      SDDefs.SD[SDDefs.sGoingAway]←0;
      ImageDefs.StopMesa[];
      END;
    1 => NULL;  -- InLd-ed
    2 => NULL;  -- booted
    3 => NULL;  -- EtherBoot
    ENDCASE => ERROR;
  -- fixup registers in microcode in case they weren't setup right
  TrapOps.WriteXTS[ControlDefs.TraceOff];
  ProcessOps.WriteWDC[wdc];
  OsStaticDefs.OsStatics↑.SerialNumber ←
    BcplOps.BcplJSR[JSR,@HostCode[0],NIL] MOD 400B;
  OsStaticDefs.OsStatics↑.AltoVersion ←
    BcplOps.BcplJSR[JSR,@VersionCode[0],NIL];
  FrameDefs.UnNew[LOOPHOLE[MMOps.MMAltoRam]];
  MMOps.etherBooted ← TRUE;
  ProcessDefs.EnableInterrupts[];
  RETURN
  END;

END.