-- TesterImpl.mesa
-- created by Haeberli:  6-Sep-81 18:15:47

DIRECTORY
  StringDefs,
  Mopcodes,
  InlineDefs,
  Tester;

TesterImpl: PROGRAM IMPORTS InlineDefs, Tester EXPORTS Tester =
  {
  OPEN InlineDefs, Tester;


  --vector of channel commands for the tester A channels
  --In OutA and Enable, bit 0 means send this group of 8 bits at the next step
  OutA: ARRAY [0..15] OF WORD;
  InitialA: ARRAY [0..15] OF WORD = [
    40000B, 40400B, 41000B, 41400B, 42000B, 42400B, 43000B, 43400B, 44000B,
    44400B, 45000B, 45400B, 46000B, 46400B, 47000B, 47400B];
  OutB: ARRAY [0..15] OF WORD;
  InitialB: ARRAY [0..15] OF WORD = [
    60377B, 60777B, 61377B, 61777B, 62377B, 62777B, 63377B, 63777B, 64377B,
    64777B, 65377B, 65777B, 66377B, 66777B, 67377B, 67777B];

  --vector of channel commands for the tester Enable channels.  Initialized
  --to Disabled (0).
  Enable: ARRAY [0..15] OF WORD;
  InitialEnable: ARRAY [0..15] OF WORD = [
    20377B, 20777B, 21377B, 21777B, 22377B, 22777B, 23377B, 23777B, 24377B,
    24777B, 25377B, 25777B, 26377B, 26777B, 27377B, 27777B];

  --Set up fixed tester registers
  Reset: PUBLIC PROC = {
    OutA ← InitialA;
    OutB ← InitialB;
    Enable ← InitialEnable;

    DoOutput[1, 0];  --release reset
    DoOutput[2000B, 1];  --input group select buffer ← 0
    DoOutput[4020B, 1];  --clock parameter 1
    DoOutput[10777B, 1];  --clock parameter 2
    FOR i: CARDINAL IN [0..14] DO
      DoOutput[Enable[i], 1];  --Enable channels ← 1 (open) 
      DoOutput[OutA[i], 1];  --A channels ← 0 
      DoOutput[OutB[i], 1];  --B channels ← 1 
      ENDLOOP;
    DoOutput[100000B, 1];  --Do one step
    };


  --Set the state of a single tester channel
  SetChannelValue: PUBLIC PROC [channel: Channel, value: Value] = {

    first, second: WORD;

    [first, second] ← SetChannelValueCommands[channel, value];
    DoOutput[first, 1];
    DoOutput[second, 1];
    };


  --Return commands to set the state of a single tester channel
  SetChannelValueCommands: PUBLIC PROC [channel: Channel, value: Value]  RETURNS [first, second: WORD] = {

    index: [0..14];
    bitshift: [0..7];

    index ← channel/8;
    bitshift ← 7 - (channel MOD 8);
    IF value = x THEN {
      Enable[index] ← BITOR[BITSHIFT[1, bitshift], Enable[index]];
      OutA[index] ← BITAND[BITNOT[BITSHIFT[1, bitshift]], OutA[index]];
      RETURN[BITOR[Enable[index], 100000B], BITOR[OutA[index], 100000B]];
      }
    ELSE {
      Enable[index] ← BITAND[BITNOT[BITSHIFT[1, bitshift]], Enable[index]];
      OutA[index] ← BITOR[
        BITSHIFT[value, bitshift], BITAND[
        BITNOT[BITSHIFT[1, bitshift]], OutA[index]]];
      RETURN[OutA[index], BITOR[Enable[index], 100000B]];
      };

    };


  --Get the state of a single tester channel
  GetChannelValue: PUBLIC PROC [channel: Channel] RETURNS [value: Value] = {


    index: [0..14];
    bitshift: [0..7];

    index ← channel/8;
    bitshift ← 7 - (channel MOD 8);
    IF BITAND[BITSHIFT[Enable[index], -bitshift], 1] = 1 THEN {
      DoOutput[102000B + (index/2), 1];  -- set input group select buffer
      value ← BITAND[BITSHIFT[DoInput[1], -(15 - (channel MOD 16))], 1];
      }
    ELSE {value ← BITAND[BITSHIFT[OutA[index], -bitshift], 1]; };

    RETURN[value];
    };


  Reset;

  }.