-- ControlDefs.Mesa  Edited by Sandman on July 1, 1980  8:57 AM
-- Copyright  Xerox Corporation 1979, 1980

DIRECTORY
  PrincOps USING [
    AllocationVector, AllocationVectorSize, AllocTag, ATPreg, AV, BYTE, BytePC,
    EntryInfo, EPIndex, EPRange, FieldDescriptor, FrameClass, FrameCodeBase,
    FrameVec, LargeReturnSlot, LastAVSlot, MainBodyIndex, MaxFrameSize, MaxNGfi,
    MaxNLinks, MaxParamsInStack, MaxSmallFrameIndex, MDSreg, OTPreg, PDAreg,
    PrefixHeader, PrefixInfo, PTCreg, SpecialReturnSlot, StateVector, SVPointer,
    WDCreg, XTPreg, XTSreg];

ControlDefs: DEFINITIONS =
  BEGIN

  BYTE: TYPE = PrincOps.BYTE;

  -- control link definitions

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

  ControlLink: TYPE = MACHINE DEPENDENT RECORD [
    SELECT OVERLAID ControlLinkTag FROM
      frame => [frame: FrameHandle],
      procedure => [gfi: GFTIndex, ep: EPIndex, tag: ControlLinkTag],
      indirect => [
	SELECT OVERLAID * FROM
	  port => [port: PortHandle],
	  link => [link: POINTER TO ControlLink],
	  ENDCASE],
      ENDCASE];

  ProcDesc, SignalDesc: TYPE = procedure ControlLink;

  TrapLink, NullLink: ControlLink = ControlLink[frame[NullFrame]];
  UnboundLink: ControlLink = ControlLink[
    procedure[gfi: 0, ep: 0, tag: procedure]];

  PortHandle: TYPE = POINTER TO Port;

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

  -- frame definitions

  MaxFrameSize: CARDINAL = PrincOps.MaxFrameSize;
  MaxSmallFrameIndex: CARDINAL = PrincOps.MaxSmallFrameIndex;

  FrameVec: ARRAY [0..LastAVSlot] OF [0..MaxFrameSize] = PrincOps.FrameVec;

  FrameClass: TYPE = PrincOps.FrameClass;

  Frame: TYPE = MACHINE DEPENDENT RECORD [
    accesslink: GlobalFrameHandle,
    pc: WordPC,
    returnlink: ControlLink,
    extensions:
      SELECT OVERLAID FrameClass FROM
	local => [unused: UNSPECIFIED, local: ARRAY [0..0) OF UNSPECIFIED],
	signal => [mark: BOOLEAN, unused: [0..77777B]],
	catch => [
	  unused: UNSPECIFIED, staticlink: FrameHandle, messageval: UNSPECIFIED],
	dying => [state: {dead, alive}, unused: [0..77777B]],
	ENDCASE];

  FrameHandle: TYPE = POINTER TO Frame;
  NullFrame: FrameHandle = LOOPHOLE[0];

  GlobalFrame: TYPE = MACHINE DEPENDENT RECORD [
    gfi: GFTIndex,
    unused: [0..1], -- reserved for future gfi expansion
    copied, alloced, shared, started: BOOLEAN,
    trapxfers, codelinks: BOOLEAN,
    code: FrameCodeBase,
    global: ARRAY [0..0) OF UNSPECIFIED];

  FrameCodeBase: TYPE = PrincOps.FrameCodeBase;

  GlobalFrameHandle: TYPE = POINTER TO GlobalFrame;
  NullGlobalFrame: GlobalFrameHandle = LOOPHOLE[0];

  -- The following offsets are used by the compiler and MUST
  -- reflect the field offsets in the definitions of Frame
  -- local frames

  accessOffset: CARDINAL = 0;
  pcOffset: CARDINAL = 1;
  returnOffset: CARDINAL = 2;

  -- global frames

  gfiOffset: CARDINAL = 0;
  codebaseOffset: CARDINAL = 1;

  -- efficiently addressable portion of frames

  globalbase: CARDINAL = SIZE[GlobalFrame];
  localbase: CARDINAL = SIZE[local Frame];
  framelink: CARDINAL = localbase;

  -- code segments

  WordPC: TYPE = RECORD [INTEGER];
  BytePC: TYPE = PrincOps.BytePC;

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

  FieldDescriptor: TYPE = PrincOps.FieldDescriptor;

  EPRange: CARDINAL = PrincOps.EPRange;
  EPIndex: TYPE = PrincOps.EPIndex;

  -- Global frame size preceeds body zero

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

  PrefixHandle: TYPE = POINTER TO CSegPrefix;

  PrefixHeader: TYPE = PrincOps.PrefixHeader;

  PrefixInfo: TYPE = PrincOps.PrefixInfo;

  EntryVectorItem: TYPE = MACHINE DEPENDENT RECORD [
    initialpc: WordPC, info: EntryInfo];

  EntryInfo: TYPE = PrincOps.EntryInfo;

  MaxNLinks: CARDINAL = PrincOps.MaxNLinks;
  MainBodyIndex: CARDINAL = PrincOps.MainBodyIndex;

  -- Global Frame Table definitions

  MaxNGfi: CARDINAL = PrincOps.MaxNGfi;

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

  GFTItem: TYPE = MACHINE DEPENDENT RECORD [
    frame: GlobalFrameHandle, epbase: CARDINAL];

  GFTIndex: TYPE = [0..777B];
  GFTNull: GFTIndex = 0;
  NullEpBase: CARDINAL = LAST[CARDINAL];

  MaxGFTSize: CARDINAL = (LAST[GFTIndex] + 1)*SIZE[GFTItem];

  -- system frame allocation vector

  AllocTag: TYPE = PrincOps.AllocTag;

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

  AllocationVectorSize: CARDINAL = PrincOps.AllocationVectorSize;
  LastAVSlot: CARDINAL = PrincOps.LastAVSlot;
  AllocationVector: TYPE = ARRAY [0..AllocationVectorSize) OF AVItem;
  AVHandle: TYPE = POINTER TO AllocationVector;
  AV: AVHandle = LOOPHOLE[PrincOps.AV];
  LargeReturnSlot: CARDINAL = PrincOps.LargeReturnSlot;
  SpecialReturnSlot: CARDINAL = PrincOps.SpecialReturnSlot;

  -- control module stuff

  ControlModule: TYPE = MACHINE DEPENDENT RECORD [
    SELECT OVERLAID * FROM
      frame => [frame: GlobalFrameHandle],
      list => [list: POINTER TO FrameList],
      tag => [fill: [0..77777B], multiple: BOOLEAN],
      ENDCASE];

  FrameList: TYPE = MACHINE DEPENDENT RECORD [
    nModules: CARDINAL, frames: ARRAY [0..0) OF GlobalFrameHandle];

  NullControl: ControlModule = [frame[NullGlobalFrame]];

  -- control registers
  -- known by the microcode

  WDCreg: CARDINAL = PrincOps.WDCreg; -- wakeup disable counter

  XTSreg: CARDINAL = PrincOps.XTSreg; -- xfer trap status

  XTPreg: CARDINAL = PrincOps.XTPreg; -- xfer trap parameter

  ATPreg: CARDINAL = PrincOps.ATPreg; -- alloc trap parameter

  OTPreg: CARDINAL = PrincOps.OTPreg; -- other trap parameter

  MDSreg: CARDINAL = PrincOps.MDSreg; -- main data space

  PDAreg: CARDINAL = PrincOps.PDAreg; -- process data area

  PTCreg: CARDINAL = PrincOps.PTCreg; -- process tick count

  SVPointer: TYPE = PrincOps.SVPointer;

  StateVector: TYPE = PrincOps.StateVector;

  MaxParamsInStack: CARDINAL = PrincOps.MaxParamsInStack;

  -- Xfer Trap Stuff

  TrapReason: TYPE = {other, localCall, return};
  TrapState: TYPE = {off, on, pending};

  TrapStatus: TYPE = MACHINE DEPENDENT RECORD [
    fill1: [0..177B], reason: TrapReason, fill2: [0..37B], state: TrapState];

  TrapParameter: TYPE = RECORD [
    SELECT OVERLAID TrapReason FROM
      other => [link: ControlLink],
      localCall => [ep: CARDINAL], -- Actually 2*ep+2
      return => [frame: FrameHandle], -- Actually frame+6

      ENDCASE];

  NullReason: TrapReason = LOOPHOLE[0];

  TraceOff: TrapStatus = [0, NullReason, 0, off];
  TraceNext: TrapStatus = [0, NullReason, 0, pending];

  END.