-- PrincOps.Mesa  Edited by JGS on  2-Nov-81 11:22:20

-- Copyright (C) Xerox Corporation 1982. All rights reserved.

PrincOps: DEFINITIONS =
  BEGIN

  BYTE: TYPE = [0..377B];

  -- control link definitions

  ControlLinkTag: TYPE = {frame, procedure, indirect, rep};

  ControlLink: TYPE = MACHINE DEPENDENT RECORD [
    SELECT OVERLAID ControlLinkTag FROM
      frame => [frame: LocalFrameHandle],
      procedure => [gfi: GFTIndex, ep: EPIndex, tag: BOOLEAN],
      indirect => [
	SELECT OVERLAID * FROM
	  port => [port: PortHandle],
	  link => [link: POINTER TO ControlLink],
	  ENDCASE],
      rep => [fill: [0..37777B], indirect: BOOLEAN, proc: BOOLEAN],
      ENDCASE];

  ProcDesc, SignalDesc: TYPE = procedure ControlLink;

  TrapLink, NullLink: ControlLink = ControlLink[frame[NullLocalFrame]];
  trapLink, nullLink: ControlLink = NullLink;
  UnboundLink: ControlLink = ControlLink[procedure[gfi: 0, ep: 0, tag: TRUE]];
  unboundLink: ControlLink = UnboundLink;

  PortHandle: TYPE = POINTER TO Port;

  Port: TYPE = MACHINE DEPENDENT RECORD [
    SELECT OVERLAID * FROM
      representation => [in, out: UNSPECIFIED],
      links => [frame: LocalFrameHandle, dest: ControlLink],
      ENDCASE];

  -- local frames

  LocalFrameHandle: TYPE = POINTER TO LocalVariables;
  
  LocalVariables: TYPE = ARRAY CARDINAL[0..0) OF UNSPECIFIED;
  
  LocalFrameBase: TYPE = POINTER TO LocalOverhead;
  
  LocalWord: TYPE = MACHINE DEPENDENT RECORD [
    available (0:0..7): BYTE,
    fsi (0:8..15): FSIndex];
  
  LocalOverhead: TYPE = MACHINE DEPENDENT RECORD [
    word (0): LocalWord,
    returnlink (1): ControlLink,
    globallink (2): GlobalFrameHandle,
    pc (3): BytePC,
    local (4): LocalVariables];
  
  NullLocalFrame, nullLocalFrame: LocalFrameHandle = LOOPHOLE[0];
  
  localWordOffset: CARDINAL = 4;
  returnOffset: CARDINAL = 3;
  globalOffset, accessOffset: CARDINAL = 2;
  pcOffset: CARDINAL = 1;


  -- global frame

  GlobalFrameHandle: TYPE = POINTER TO GlobalVariables;
  
  GlobalVariables: TYPE = ARRAY CARDINAL[0..0) OF UNSPECIFIED;
  
  GlobalFrameBase: TYPE = POINTER TO GlobalOverhead;
  
  GlobalWord: TYPE = MACHINE DEPENDENT RECORD [
    gfi (0:0..9): GFTIndex,
    started (0:10..10),
    copied (0:11..11),
    alloced (0:12..12),
    shared (0:13..13),
    trapxfers (0:14..14),
    codelinks (0:15..15): BOOLEAN];
  
  GlobalCodebase: TYPE = MACHINE DEPENDENT RECORD [
    SELECT OVERLAID * FROM
      code => [codebase: PrefixHandle],
      offset => [offset, highHalf: CARDINAL],
      either => [
        fill: CARDINAL[0..77777B], out: BOOLEAN, highByte, otherByte: BYTE],
      ENDCASE];

  GlobalOverhead: TYPE = MACHINE DEPENDENT RECORD [
    word (0): GlobalWord,
    codebase (1): GlobalCodebase,
    global (3): GlobalVariables];
  
  NullGlobalFrame, nullGlobalFrame: GlobalFrameHandle = LOOPHOLE[0];
  
  globalWordOffset: CARDINAL = 3;
  codebaseLowOffset: CARDINAL = 2;
  codebaseHighOffset: CARDINAL = 1;

  -- efficiently addressable portion of frames

  globalbase: CARDINAL = 0;
  localbase: CARDINAL = 0;
  framelink: CARDINAL = localbase;

  -- code segments

  BytePC: TYPE = RECORD [CARDINAL];

  InstWord: TYPE = MACHINE DEPENDENT RECORD [evenbyte, oddbyte: BYTE];

  FieldDescriptor: TYPE = MACHINE DEPENDENT RECORD [
    offset: BYTE, posn: [0..16), size: [1..16]];

  BiasRange: CARDINAL = 4;
  EPBias: TYPE = [0..BiasRange);
  EPRange: CARDINAL = 32;
  EPIndex: TYPE = [0..EPRange);
  EVRange: CARDINAL = BiasRange*EPRange;
  EVIndex: TYPE = [0..EVRange);

  -- Global frame size preceeds body zero

  CodeSegment: TYPE = MACHINE DEPENDENT RECORD [
    header: PrefixHeader, entry: ARRAY [0..0) OF EVItem];

  PrefixHandle: TYPE = LONG BASE POINTER TO CodeSegment;

  PrefixHeader: TYPE = MACHINE DEPENDENT RECORD [
    globalFsi (0:0..7): BYTE,
    nEntries (0:8..15): [0..377B],
    info (1): PrefixInfo];

  PrefixInfo: TYPE = MACHINE DEPENDENT RECORD [
    available (0:0..4): [0..37B],
    stops (0:5..5): BOOLEAN,
    ngfi (0:6..7): [1..MaxNGfi],
    nlinks (0:8..15): [0..MaxNLinks]];

  EVItem: TYPE = MACHINE DEPENDENT RECORD [
    pc: BytePC];

  CSegPrefix: TYPE = CodeSegment;
  EntryVectorItem: TYPE = EVItem;

  MaxNLinks, maxNLinks: CARDINAL = 255;
  MainBodyIndex, mainBodyIndex: CARDINAL = 0;

  -- Global Frame Table definitions

  MaxNGfi, maxNGfi: CARDINAL = 4;

  GFTIndex: TYPE = [0..1777B];
  GFTNull, nullGFT: GFTIndex = 0;

  -- system frame allocation vector

  AllocTag: TYPE = {frame, empty, indirect, unused};

  AVItem: TYPE = MACHINE DEPENDENT RECORD [
    SELECT OVERLAID * FROM
      data => [fsi: [0..37777B], tag: AllocTag],
      link => [link: POINTER TO AVItem],
      frame => [frame: LocalFrameHandle],
      ENDCASE];

  FSIndex: TYPE = CARDINAL[0..256);
  
  AllocationVector: TYPE = ARRAY FSIndex OF AVItem;
  AVHandle: TYPE = POINTER TO AllocationVector;
  AV: AVHandle = LOOPHOLE[400B];

  AVHeapSize: CARDINAL = 40B;
  AVHeap: TYPE = ARRAY [0..AVHeapSize) OF AVItem;
  LastAVHeapSlot: CARDINAL = AVHeapSize - 2;
  FrameSizeIndex: TYPE = [0..LastAVHeapSlot];

  -- frame definitions

  MaxFrameSize, maxFrameSize: CARDINAL = 4092;
  MaxSmallFrameIndex, maxSmallFrameIndex: CARDINAL = 17;

  FrameVec, frameSizeMap: ARRAY FrameSizeIndex OF [0..MaxFrameSize] = [
   8, 12, 16, 20, 24, 28, 32, 40, 48, 56, 68, 80, 96, 112, 128, 148, 168, 192,
   224, 252, 508, 764, 1020, 1276, 1532, 1788, 2044, 2556, 3068, 3580, 4092];

  LargeReturnSlot: CARDINAL = AVHeapSize - 1;

  -- ESC and ESCL trap table

  OpTrapTable: TYPE = POINTER TO ARRAY BYTE OF ControlLink;

  ESCTrapTable: OpTrapTable = LOOPHOLE[1400B];

  -- Global Frame Table definitions

  GFTHandle: TYPE = POINTER TO ARRAY [0..0) OF GFTItem;
  GFT: GFTHandle = LOOPHOLE[2000B];

  GFTItem: TYPE = MACHINE DEPENDENT RECORD [
    SELECT OVERLAID * FROM
      frame => [gf: GlobalFrameHandle],
      ep => [data: [0..37777B], epbias: [0..3]],
      ENDCASE];

  EmptyGFTItem: GFTItem = [ep[data: 0, epbias: 0]];
  FreedGFTItem: GFTItem = [ep[data: 0, epbias: 3]];

  -- Evaluation Stack

  SVPointer: TYPE = POINTER TO StateVector;

  stackDepth: CARDINAL = 14;

  StateVector: TYPE = MACHINE DEPENDENT RECORD [
    stk(0): ARRAY [0..stackDepth) OF UNSPECIFIED,
    instbyte(stackDepth:0..7): BYTE,
    stkptr(stackDepth:8..15): BYTE, -- 0 => empty stack
    data(stackDepth+1): SELECT OVERLAID * FROM
      dst => NULL,
      lst => [dest(stackDepth+1), source(stackDepth+2): PrincOps.ControlLink],
      fault => [
	frame(stackDepth+1): LocalFrameHandle,
	faultData(stackDepth+2): SELECT OVERLAID * FROM
	  allocFault => [fsi(stackDepth+2): FrameSizeIndex],
	  memFault => [memPointer(stackDepth+2): LONG POINTER],
	  otherFault => [dataArray(stackDepth+2): ARRAY [0..0) OF UNSPECIFIED],
	  ENDCASE],
      ENDCASE];

  MaxParamsInStack, maxParamsInStack: CARDINAL = stackDepth - 2;

  END.