-- EikonixProtocol.mesa
-- Last edited by Tim Diebert: 22-Jan-86 12:22:54
-- Copyright (C) 1985, 1986, Xerox Corporation. All rights reserved.
-- Tim Diebert: January 27, 1986 9:21:56 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 cmd reg
SetDeviceCommandReg => [cmd: CARDINAL], -- Loads the cmd to Device cmd 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 ], -- Sets the color filter
ScanPage =>
[ scanStart, pixelStart,
numScans, numPixel: CARDINAL,
bits: CARDINAL], -- Limited by sender to BitsPerPoint
SampleScan => [ bits: CARDINAL ], -- Limited by sender
LoadNormalizer =>
[ darkCurrent: ARRAY [0 .. 0 -- Width --) OF CARDINAL,
gain: ARRAY [0 .. 0 -- Width --) OF CARDINAL ],
-- Sets the dark current and the gain buffers in the normalizer board
ScanMaxMin =>
[ scanStart, pixelStart,
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 buffer width
SendDataBuffer1 => [ data: ARRAY [0 .. 0) OF WORD ], -- The buffer width
TurnOnLights => [ ], -- Turns on lights
TurnOffLights => [ ], -- Turns off lights
SetFilter => [ ], -- Sets the color filter
ScanPage =>
[ numScans, numPixel: CARDINAL,
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 pixel and scan line.
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 {
ITimeLow (0), -- The integration time register
ITimeHigh (1), -- The high byte of the integration time.
Filter (8), -- Filter Control
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.
Data4Bit: Function = 4; -- 4 bit data, no step.
Data2Bit: Function = 5; -- 2 bit data, no step.
Data4Step: Function = 6; -- 4 bit data, step.
Data2Step: Function = 7; -- 2 bit data, step.


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


END...