-- LarkPromsImpl.mesa
-- Last Edit: Stewart, October 8, 1982 9:56 pm
-- Last Edit: Stewart, December 6, 1982 4:08 pm, Cedar 3.5

DIRECTORY
  Inline USING [BITAND, HighByte, LowByte, LowHalf],
  FileIO,
  IO,
  Rope USING [Cat, Fetch, Length, ROPE],
  Transaction,
  UserExec USING [RegisterCommand, CommandProc];

LarkPromsImpl: PROGRAM
IMPORTS FileIO, Inline, IO, Rope, UserExec =
BEGIN

Bit: TYPE = BOOL;

-- The default PNEW command does the following, where
-- Bit refers to the Mesa RECORD and An refers to the address
-- bit of the PROM
--  .MB bit		Prom bit	prom pin		signal			new prom pin	new MB
--  Bit 15		A7		pin 15		LA13			pin 01			bit 14
--  Bit 14		A6		pin 01		LA14			pin 15			bit 15
--  Bit 13		A5		pin 02		LA15			pin 07			bit 10
--  Bit 12		A4		pin 03		SelEnc'		pin 06			bit 09
--  Bit 11		A3		pin 04		HoldA		pin 05			bit 08
--  Bit 10		A2		pin 07		PIO			pin 03			bit 12
--  Bit 09		A1		pin 06		SLCDAck		pin 02			bit 13
--  Bit 08		A0		pin 05		LA07			pin 04			bit 11

--  Bit 00		D0			pin 12		EnMXcvr'	pin 09			bit 03
--  Bit 01		D1			pin 11		OffBoard'		pin 12			bit 00
--  Bit 02		D2			pin 10		SelROM'		pin 10			bit 02
--  Bit 03		D3			pin 09		SelRAM		pin 11			bit 01

StitchWeldMainPromAddress: TYPE = MACHINE DEPENDENT RECORD [
  pad (0: 0..7): [0..377B],
  LA07 (0: 8..8): Bit,
  SLCDAck (0: 9..9): Bit,
  PIO (0: 10..10): Bit,
  HoldA (0: 11..11): Bit,
  SelEncryptBar (0: 12..12): Bit,
  LA15 (0: 13..13): Bit,
  LA14 (0: 14..14): Bit,
  LA13 (0: 15..15): Bit
  ];

-- PC
MainPromAddress: TYPE = MACHINE DEPENDENT RECORD [
  pad (0: 0..7): [0..377B],
  HoldA (0: 8..8): Bit,
  SelEncryptBar (0: 9..9): Bit,
  LA15 (0: 10..10): Bit,
  LA07 (0: 11..11): Bit,
  PIO (0: 12..12): Bit,
  SLCDAck (0: 13..13): Bit,
  LA13 (0: 14..14): Bit,
  LA14 (0: 15..15): Bit
  ];

StitchWeldMainPromData: TYPE = MACHINE DEPENDENT RECORD [
  EnMXcvrBar (0: 0..0): Bit,
  OffBoardBar (0: 1..1): Bit,
  SelROMBar (0: 2..2): Bit,
  SelRAM (0: 3..3): Bit,
  pad (0: 4..15): [0..7777B]
  ];

-- PC

MainPromData: TYPE = MACHINE DEPENDENT RECORD [
  OffBoardBar (0: 0..0): Bit,
  SelRAM (0: 1..1): Bit,
  SelROMBar (0: 2..2): Bit,
  EnMXcvrBar (0: 3..3): Bit,
  pad (0: 4..15): [0..7777B]
  ];

PromProc: TYPE = PROC [in: CARDINAL] RETURNS [out: CARDINAL];

MainProm: PromProc = {
  address: MainPromAddress = LOOPHOLE[in];
  data: MainPromData;
  data.pad ← 0;
  -- PROM logic goes here

  -- SelROM' = (LA13 . LA14 . LA15 . HoldA' . PIO')'
  data.SelROMBar ← NOT (address.LA13 AND address.LA14 AND address.LA15 AND (NOT address.HoldA) AND (NOT address.PIO));

  -- EnMXcvr' = ((HoldA' . PIO' . SelROM') + SLCDAck + SelEncrypt)'
  data.EnMXcvrBar ← NOT (((NOT address.HoldA) AND (NOT address.PIO) AND data.SelROMBar) OR address.SLCDAck OR (NOT address.SelEncryptBar));

  -- OffBoard' =  (HoldA' . PIO . LA07)'
  data.OffBoardBar ← NOT ((NOT address.HoldA) AND address.PIO AND address.LA07);

  -- SelRAM = HoldA + (HoldA' . PIO')
  data.SelRAM ← address.HoldA OR ((NOT address.HoldA) AND (NOT address.PIO));

  out ← LOOPHOLE[data, CARDINAL];
  };

SlavePromAddress: TYPE = MACHINE DEPENDENT RECORD [
  pad (0: 0..10): [0..3777B],
  SA15 (0: 11..11): Bit,
  SA14 (0: 12..12): Bit,
  SA13 (0: 13..13): Bit,
  SlaveIO (0: 14..14): Bit,
  SLA02 (0: 15..15): Bit
  ];

SlavePromData: TYPE = MACHINE DEPENDENT RECORD [
  pad2 (0: 0..1): [0..3B],
  SelSlvRAMBar (0: 2..2): Bit,
  SelISRBar (0: 3..3): Bit,
  SelOSRBar (0: 4..4): Bit,
  SelShareBar (0: 5..5): Bit,
  EnSlaveROMBar (0: 6..6): Bit,
  PreSlaveReq (0: 7..7): Bit,
  pad (0: 8..15): [0..377B]
  ];

SlaveProm: PromProc = {
  address: SlavePromAddress = LOOPHOLE[in];
  data: SlavePromData;
  region: [0..7];
  data.pad ← 0;
  -- PROM logic goes here
  region ← 0;
  IF address.SA13 THEN region ← region + 1;
  IF address.SA14 THEN region ← region + 2;
  IF address.SA15 THEN region ← region + 4;
  
  -- SelSlvRAM' = (SlaveIO' . [SA15,,SA14,,SA13] = 1)'
  data.SelSlvRAMBar ← NOT ((NOT address.SlaveIO) AND (region = 1));

  -- SelISR' = (SlaveIO . SLA02')'
  data.SelISRBar ← NOT (address.SlaveIO AND (NOT address.SLA02));

  -- SelOSR' = (SlaveIO . SLA02)'
  data.SelOSRBar ← NOT (address.SlaveIO AND address.SLA02);

  -- SelShare' = (([SA15,,SA14,,SA13] IN [2..6]) . SlaveIO')'
  data.SelShareBar ← NOT ((NOT address.SlaveIO) AND (region IN [2..6]));

  -- EnSlaveROM' = (([SA15,,SA14,,SA13] IN 0,7) . SlaveIO')'
  data.EnSlaveROMBar ← NOT ((NOT address.SlaveIO) AND (region=0 OR region=7));

  -- PreSlaveReq = (SelShare')'
  data.PreSlaveReq ← NOT data.SelShareBar;

  data.pad2 ← 0;

  out ← LOOPHOLE[data, CARDINAL];
  };

  OByte: PROC [s: IO.Handle, x: CARDINAL] = INLINE { s.PutChar[LOOPHOLE[x]]; };
  OWord: PROC [s: IO.Handle, x: CARDINAL] = INLINE {
    s.PutChar[LOOPHOLE[Inline.HighByte[x]]];
    s.PutChar[LOOPHOLE[Inline.LowByte[x]]];
    };

  MakeMBFile: PROC [name: Rope.ROPE, size: CARDINAL, width: CARDINAL, proc: PromProc] = {
    filename: Rope.ROPE ← Rope.Cat[name, ".mb"];
    s: IO.STREAM ← FileIO.Open[filename, FileIO.AccessOptions[overwrite]];
    namelength: INT ← name.Length[];
    OWord[s, 4];  -- boilerplate
    OWord[s, 1];  -- memorynumber
    OWord[s, width];  -- memorywidth in bits
    FOR i: INT IN [0..namelength) DO
      OByte[s, name.Fetch[i]-0C];
      ENDLOOP;
    OByte[s, 0];  -- ASCIZ end of string
    -- pad to word boundary
    IF Inline.BITAND[Inline.LowHalf[namelength], 1] = 0 THEN OByte[s, 0];
    OWord[s, 2];  -- set current memory and location
    OWord[s, 1];  -- memorynumber again
    OWord[s, 0];  -- location
    FOR i: CARDINAL IN [0..size) DO
      OWord[s, 1];  -- memory data word
      OWord[s, 0];  -- source line number (not used)
      OWord[s, proc[i]]; -- left justified
      ENDLOOP;
    OWord[s, 0];  -- end of file
    s.Close[];
    };


Main: UserExec.CommandProc = TRUSTED {
  MakeMBFile["LarkMainProm", 256, 4, MainProm];
  MakeMBFile["LarkSlaveProm", 32, 8, SlaveProm];
  };

-- Mainline Code
  UserExec.RegisterCommand["MakeLarkProms.~", Main, "Create .mb files for Lark"];

END.
March 21, 1982 6:12 pm, Stewart, created
June 2, 1982 3:46 pm, Stewart, added SelSlvRAMBar to slave PROM