-- EikonixProtocol.mesa
-- Last edited by Tim Diebert:   8-Apr-85  9:25:34
-- Copyright (C) 1985, Xerox Corporation.  All rights reserved.
-- Last Edited by: Diebert, March 15, 1985 9:59:34 am PST

DIRECTORY
  PupTypes USING [PupSocketID]
  ;

EikonixProtocol: DEFINITIONS = BEGIN
  
  Address: TYPE = LONG CARDINAL;
  Width: CARDINAL = 2048;
  Height: CARDINAL = 2048;
  ScanLine: TYPE = [0 .. Height);
  Pixel: TYPE = [0 .. Width);
  SampleLength: CARDINAL = 16;
  BitsPerPoint: TYPE = MACHINE DEPENDENT {bp8 (0), bp12 (1)};
  
  -- This protocol is based upon a PUP BSP stream implementing the transfer of these RECORDs.  The Well Known Sockets to be used is.
  scannerSocket: PupTypes.PupSocketID = [0, 45B];
  -- If there is a need to abort the transfer of data from the scanner to the Cedar machine, the BSP stream is simply closed, causing the scanner to abort and set up to listen again at the scannerSocket.
  -- There may be only one open BPS stream at any time.  The restriction is implemented at the scanner end by returning an ABORT [Busy] pup.
  -- If no commands are received by the scanner in 30 minutes.  The connection is closed from the scanner end.  The CEDAR code must clean-up accordingly.
  
  CommandToScanner: TYPE = MACHINE DEPENDENT RECORD [
    wastedSpace: [0 .. 256) ← 0,
    var: SELECT command: Command FROM  -- the command type of this message
      SetCommandReg => [ cmd: CARDINAL ],  -- Loads the cmd to General command reg
      SetDeviceCommandReg => [ cmd: CARDINAL ],  -- Loads the cmd to device command reg
      GetStatus => [  ],  -- Gets the general status register
      GetDeviceStatus => [  ],  -- Gets the device status register
      SetFCR => [ cmd: CARDINAL ],  -- Loads the cmd to FCR reg
      SetDMAData => [ data: CARDINAL ],  -- Loads the data to DMA data reg
      SendDataBuffer0 => [  ],  -- Sends the contents of buffer 0
      SendDataBuffer1 => [  ],  -- Sends the contents of buffer 1
      TurnOnLights => [  ],   -- Turns on lights
      TurnOffLights => [  ],   -- Turns off lights
      SetFilter => [ color: CARDINAL ],   -- Turns off lightsSets the color filter
      ScanPage =>
        [ scanStart, pixelStart, 
          -- Values are truncated to the range [0 .. Width) and [0 .. Height)
        numScans, numPixel: CARDINAL,
          -- Values are truncated to the range [0 .. Width] and [0 .. Height]
        repCount: CARDINAL, -- Limited to [1 .. 4] as number of times to scan 2↑repCount times
        bits: CARDINAL],  -- Limited by sender to BitsPerPoint
      SampleScan => [ bits: CARDINAL ],  -- Limited by sender to BitsPerPoint
      LoadNormalizer => [ darkCurrent, gain: ARRAY [0 .. 0 -- Width --) OF CARDINAL ], 
          -- Sets the dark current and the gain buffers in the normalizer board
      ScanMaxMin =>
        [ scanStart, pixelStart, 
          -- Values are truncated to the range [0 .. Width) and [0 .. Height)
        numScans, numPixel: CARDINAL],
      ComputeCal => [ ]  -- Reads the whole field and sends the average back
      ENDCASE
    ];
  
  ResponseFromScanner: TYPE = MACHINE DEPENDENT RECORD [
    ok: BOOL ← FALSE,
    wastedSpace: [0 .. 177B] ← 0,
    var: SELECT command: Command FROM  -- the command type of this message
      SetCommandReg => [  ],  -- Loads the cmd to General command reg
      SetDeviceCommandReg => [  ],  -- Loads the cmd to device command reg
      GetStatus => [ status: CARDINAL ],  -- Gets the general status register
      GetDeviceStatus => [ status: CARDINAL ],  -- Gets the device status register
      SetFCR => [  ],  -- Loads the cmd to FCR reg
      SetDMAData => [  ],  -- Loads the data to DMA data reg
      SendDataBuffer0 => [ data: ARRAY [0 .. 0) OF WORD ], -- The contents of buffer width wide
      SendDataBuffer1 => [ data: ARRAY [0 .. 0) OF WORD ], -- The contents of buffer width wide
      TurnOnLights => [  ],   -- Turns on lights
      TurnOffLights => [  ],   -- Turns off lights
      SetFilter => [  ],   -- Turns off lightsSets the color filter
      ScanPage =>
        [ numScans, numPixel: CARDINAL,
          -- Values are truncated to the range [0 .. Width] and [0 .. Height]
        data: ARRAY [0 .. 0) OF WORD],
          -- The length of the array is numScans * numPixel words;
          -- that is the number of words sent in the stream before the scanner starts
          -- listening again is numScans * numPixel.
      SampleScan => [ data: ARRAY [0 .. 0 -- 16384 --) OF WORD ],
        -- Sample always sends the data unswapped and to the left in the word.
        -- The length of the data is Width/SampleLength * Height/SampleLength,
        -- or 16384 for the standard parameters.
      LoadNormalizer => [ ],
      ScanMaxMin => [min, minScan, minPixel, max, maxScan, maxPixel: CARDINAL],
      ComputeCal => [ data: ARRAY [0 .. 0) OF CARDINAL ]
      ENDCASE
    ];
  
  Command: TYPE  = MACHINE DEPENDENT {
    SetCommandReg (0),        --  Loads the General Command Register
    SetDeviceCommandReg (1),  --  Loads the device command register
    GetStatus (2),            --  Reads the general status register
    GetDeviceStatus (3),      --  Reads the device status register
    SetFCR (4),               --  Loads the Function control register
    SetDMAData (5),           --  Loads the DMA data register
    SendDataBuffer0 (6),      --  Sends the contents of buffer 0 to host
    SendDataBuffer1 (7),      --  Sends the contents of buffer 1 to host
    TurnOnLights (8),         --  Turns on lights
    TurnOffLights (9),        --  Turns off lights
    ScanPage (10),            --  Scans a page specified by the params.
    SampleScan (11),          --  Scans every 16th bit and scan line.  Scans the whole field
    LoadNormalizer (12),      --  Loads the dark current buffer then the gain.
    SetFilter (13),           --  Sets color filter.
    ScanMaxMin (14),          --  Scan the specified area for max & min
    ComputeCal (15),          --  Computes the average of the whole field.
    (255)};
  
  Color: TYPE = MACHINE DEPENDENT
     {Red (0), Green (1), Blue (2), Clear (3), Opaque (4), (LAST[CARDINAL])};
  
  -- Addresses for the various Eikonix registers.
  -- The divide by 2 is because the Eikonix addresses are byte addresses
  
  EikonixBase:             Address = 0400000H;

  dataBuffer0:             Address = EikonixBase + 0A000H / 2;
  dataBuffer1:             Address = EikonixBase + 0C000H / 2;
  commandRegister:         Address = EikonixBase + 0E000H / 2;
  deviceCommandRegister:   Address = EikonixBase + 0E002H / 2;
  statusRegister:          Address = EikonixBase + 0E004H / 2;
  deviceStatusRegister:    Address = EikonixBase + 0E006H / 2;
  functionControlRegister: Address = EikonixBase + 0E00EH / 2;
  dataRegister:            Address = EikonixBase + 0E010H / 2;
  scc0:                    Address = EikonixBase + 9010H;
       -- This is the base address of the SCC.
  
  -- Commands
  EikonixCommand: TYPE = MACHINE DEPENDENT RECORD [
    reg:       Reg,
    readBack:  [0 .. 1] ← 0,
    bits:      [0 .. 7FFH] ← 0 ];
  
  Reg: TYPE = MACHINE DEPENDENT {
    ITime (0),    --  The integration time register
    LUT (2),      --  The lookup table
    Mag (4),      --  Magnification
    NDFiler (5),  --  ND Filter
    Solenoids (8),--  Solenoids
    Console (9),  --  Console
    Stage (0AH),   --  Stage (head platform)
    StagePosition (0CH),  -- Special stage reg.
    (0FH) };
   
   EikonixFunctionControl: TYPE = MACHINE DEPENDENT RECORD [
    j1: [0 .. 07FH] ← 0,
    direction: [0 .. 1],    --  0 to scanner, 1 from scanner
    j2: [0 .. 07B] ← 0,
    buffer: [0 .. 1],       --  0 buffer 0, 1 buffer 1
    funct: Function ← Data12Bit,
    go: [0 .. 1]];
    
  Function: TYPE = [0 .. 7];
    DarkC:      Function  =  0;    --  The dark current register
    Gain:       Function  =  1;    --  The gain registers
    HeadTest:   Function  =  4;    --  The head test register
    GainTest:   Function  =  5;    --  The gain test register.
                                   --  This is really after the dark subtract!
    Data12Bit:  Function  =  0;    --  12 bit data, no step.
    Data8Bit:   Function  =  1;    --  8 bit data, no step.
    Data12Step: Function  =  2;    --  12 bit data, step.
    Data8Step:  Function  =  3;    --  8 bit data, step.


 
  busyBit:        CARDINAL = 08000H;
  toDarkCurrent:  CARDINAL = 00000H;
  toGain:         CARDINAL = 00002H;


  END...