-- 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.