-- file:  MB.mesa
-- last modified by McCreight, August 18, 1981  10:46 AM
-- written by McCreight, August 4, 1981  2:44 PM

-- This interface supports the internalizing of the Micro Binary format
-- file originally introduced by Deutsch in the early 1970's and now
-- used to represent all of our ROM data.  As defined in Maxc Document 9.2,
-- dated July 6, 1972, pages 30-32, the format is a sequence of MBItems.

DIRECTORY
  StreamDefs: FROM "StreamDefs";

MB: DEFINITIONS = PUBLIC

  BEGIN

  --  T Y P E S

  MBItemType: TYPE = MACHINE DEPENDENT{
    end(0), dataWord(1), setLC(2), fixup(3), memName(4), addrSym(5), extRef(6)};
  MBItem: TYPE = MACHINE DEPENDENT RECORD [
    ugh(0): SELECT itemType(0): MBItemType FROM
      end => [],
      dataWord => [  -- in current memory at current LC, then advance LC
        lineNo(1): CARDINAL,
        bits(2): PACKED ARRAY [0..0) OF BOOLEAN -- high order in [0]
        ],
      setLC => [memNo(1), location(2): CARDINAL],  -- make this memory and LC current
      fixup => [
        memNo(1), location(2): CARDINAL,
        firstBit(3:0..7), lastBit(3:8..15): [0..255],
        bits(4): PACKED ARRAY [0..15] OF BOOLEAN], -- high order in [0]
      memName => [
        memNo(1), width(2): CARDINAL, name(3): PACKED ARRAY [0..0) OF CHARACTER],
      addrSym => [
        memNo(1), location(2): CARDINAL,
        name(3): PACKED ARRAY [0..0) OF CHARACTER],
      extRef => [
        memNo(1), location(2): CARDINAL,
        firstBit(3:0..7), lastBit(3:8..15): [0..255],
        name(4): PACKED ARRAY [0..0) OF CHARACTER],
      ENDCASE];

  MBHandle: TYPE = MBMemoryPtr;

  MBMemoryPtr: TYPE = LONG POINTER TO MBMemory;
  MBMemory: TYPE = RECORD [
    nextMem: MBMemoryPtr ← NIL,
    name: LONG STRING ← NIL,
    zone: UNCOUNTED ZONE ← NIL,
    memNo, length, width: CARDINAL,
    words: MBWordPtr ← NIL,
    symbols: MBSymPtr ← NIL];

  MBWordPtr: TYPE = LONG POINTER TO MBWord;
  MBWord: TYPE = RECORD [
    nextWord: MBWordPtr ← NIL,
    location: LONG CARDINAL,
    value: PACKED SEQUENCE COMPUTED CARDINAL OF BOOLEAN -- low order in [0]
    ];

  MBSymPtr: TYPE = LONG POINTER TO MBSym;
  MBSym: TYPE = RECORD [
    nextSym: MBSymPtr, location: LONG CARDINAL, name: LONG STRING];

  BitSource: TYPE = RECORD[
    invert: BOOLEAN ← FALSE,
    s: SELECT source: * FROM
      constantFalse => NULL,
      addrBit => [index: CARDINAL],
      ENDCASE
    ];
  Permutation: TYPE = RECORD[
    seq: SEQUENCE length: CARDINAL OF BitSource
    ];
    -- Permutation[0] says how to compute the low-order bit
  PermutationPtr: TYPE = LONG POINTER TO Permutation;

  --   P R O C E D U R E S


  IllegalMBFormat: SIGNAL;

  ReadMB: PROCEDURE [
    s: StreamDefs.StreamHandle -- a word stream -- , z: UNCOUNTED ZONE]
    RETURNS [MBHandle];

  FreeMB: PROCEDURE [mb: MBHandle];

  FreeMBMemory: PROCEDURE [memP: LONG POINTER TO MBMemoryPtr];

  FindMBMemory: PROCEDURE [mb: MBHandle, memName: STRING] RETURNS [MBMemoryPtr];

  AnalyzeMemory: PROCEDURE [mem: MBMemoryPtr]
    RETURNS [decodeWidth, wordCount, wordWidth: CARDINAL];

  SuppressDefaultWords: PROCEDURE [mem: MBMemoryPtr, default: BOOLEAN];

  ReCast: PROCEDURE [mem: MBMemoryPtr, newWordWidth: CARDINAL];
    -- steals low-order address bits to widen the word by a power of 2.
    -- puts all original bit 0's together, then all bit 1's, then bit 2's, etc.

  PermuteAddress: PROCEDURE [mem: MBMemoryPtr, p: PermutationPtr];

  PermuteData: PROCEDURE [mem: MBMemoryPtr, p: PermutationPtr];

  FindMBBit: PROCEDURE [
    mb: MBHandle, memName: STRING, word: LONG CARDINAL, bit: CARDINAL]
    RETURNS [BOOLEAN];

  END. -- MB