-- BruceToAscii.mesa
-- Last edited by Barth, October 13, 1981  3:16 PM
-- Last edited by Brotz, November 23, 1981  4:14 PM
-- Last edited by JWhite 25-Apr-85 12:45:00

DIRECTORY
  Ascii,
  BruceDefs,
  InlineDefs,
  ovD: FROM "OverviewDefs",
  String,
  vmD: FROM "VirtualMgrDefs";

BruceToAscii: PROGRAM
  IMPORTS InlineDefs, String, vmD
  EXPORTS BruceDefs =
BEGIN

rp: BruceDefs.RecipePtr;
mp: vmD.ComposedMessagePtr;
MultLabels: ARRAY BruceDefs.MultiplierIndex OF CHARACTER = ['A, 'B, 'C];

BinaryToAscii: PUBLIC PROCEDURE [vmp:vmD.ComposedMessagePtr,
  brp:BruceDefs.RecipePtr]=
BEGIN
  tableIndex: TYPE = [1..6];
  tableDef: ARRAY tableIndex OF RECORD[printName:STRING, proc:PROCEDURE]=
    [["Interval"L, EmitInterval],
    ["Alarm Mask/ Abort Destination"L, EmitAlarm],
    ["Temperature Setpoint"L, EmitTempTable],
    ["Gas Setpoint"L, EmitGasTable],
    ["Boat Speed"L, EmitBoatControl],
    ["Coefficient"L, EmitCoefficient]];
  rp ← brp;
  mp ← vmp;
  vmD.StartMessageInsertion[mp,0];
  FOR i:CARDINAL IN tableIndex DO
    EmitString[tableDef[i].printName];
    EmitString[":

"L];
    tableDef[i].proc[];
    EmitString["
"L];
  ENDLOOP;
  vmD.StopMessageInsertion[mp];
END; -- of BinaryToAscii

EmitChar: PROCEDURE[c:CHARACTER]=
BEGIN
vmD.InsertMessageChar[mp,c];
END; -- of EmitChar

EmitSpace: PROCEDURE[n:CARDINAL ← 1]=
BEGIN
  THROUGH [1..n] DO EmitChar[Ascii.ControlY]; ENDLOOP;
END; -- of EmitSpace

EmitTab: PROCEDURE[n:CARDINAL ← 1]=
BEGIN
  THROUGH [1..n] DO EmitChar[Ascii.TAB]; ENDLOOP;
END; -- of EmitTab

EmitString: PROCEDURE[s:STRING]=
BEGIN
  FOR i:CARDINAL IN [0..s.length) DO
    IF s[i]=Ascii.SP THEN s[i] ← Ascii.ControlY;
  ENDLOOP;
  vmD.InsertStringInMessage[mp,s];
END; -- of EmitString

EmitLine: PROCEDURE[s:STRING]=
BEGIN
  EmitString[s];
  EmitString["
"L];
END; -- of EmitLine

EmitDecimal: PROCEDURE[n:CARDINAL, w:CARDINAL ← 2]=
BEGIN
  s:STRING ← [8];
  String.AppendDecimal[s,n];
  IF w>s.length THEN THROUGH [1..w-s.length] DO EmitChar['0] ENDLOOP;
  EmitString[s];
END; -- of EmitDecimal

EmitInteger: PROCEDURE[n:INTEGER, w:CARDINAL ← 2]=
BEGIN
  s:STRING ← [8];
  String.AppendDecimal[s,n];
  IF w>s.length THEN THROUGH [1..w-s.length] DO EmitChar[' ] ENDLOOP;
  EmitString[s];
END; -- of EmitDecimal

EmitNibble: PROCEDURE[n:BruceDefs.Nibble]=
BEGIN
-- transliterated from StringsB.mesa to emit lower case letters only in hex
  xn: PROCEDURE[n: CARDINAL]=
  BEGIN
    r: CARDINAL;
    [n, r] ← InlineDefs.DIVMOD[n, 16];
    IF n#0 THEN xn[n];
    IF r>9 THEN r ← r + 'a - '0 - 10;
    String.AppendChar[s,r+'0];
  END;
  s:STRING ← [8];
  xn[n];
  EmitString[s];
END; -- of EmitDecimal

EmitMult: PROCEDURE[m:CARDINAL]=
BEGIN
    EmitDecimal[m/10,1];
    EmitChar['.];
    EmitDecimal[m MOD 10,1];
END; -- of EmitMult

EmitTemp: PROCEDURE[t:CARDINAL]=
BEGIN
  EmitDecimal[t/10,4];
  EmitChar['.];
  EmitDecimal[t MOD 10,1];
END; -- of EmitTemp

EmitInterval: PROCEDURE=
BEGIN
  EmitLine[" !								    Function Switches"L];
  EmitLine[" !Intvl           Ctrl Tmp Tmp Gas  Gas Coeff Abrt	            111"L];
  EmitLine[" !Num Duration  Alg Alrm Set Alrm  Set  Grp  Grp	123 456 789 012   123 456"L];
  EmitChar[Ascii.CR];
  FOR i:CARDINAL IN BruceDefs.IntervalIndex DO
    EmitSpace[2]; EmitDecimal[i]; EmitSpace[4];
    EmitDecimal[rp.interval[i].hours]; EmitChar[':];
    EmitDecimal[rp.interval[i].minutes]; EmitChar[':];
    EmitDecimal[rp.interval[i].seconds]; EmitSpace[4];
    EmitNibble[rp.interval[i].controlAlg]; EmitSpace[4];
    EmitNibble[rp.interval[i].tempAlarm]; EmitSpace[4];
    EmitDecimal[rp.interval[i].gasTempControl/10,1]; EmitSpace[4];
    EmitNibble[rp.interval[i].gasAlarm]; EmitSpace[4];
    EmitDecimal[rp.interval[i].gasTempControl MOD 10,1]; EmitSpace[4];
    EmitNibble[rp.interval[i].controlCoeff]; EmitSpace[4];
    EmitNibble[rp.interval[i].abortGroup]; EmitTab[];
    FOR j: CARDINAL DECREASING IN [1..8] DO
      IF rp.interval[i].function1[j]=0 THEN EmitChar['0] ELSE EmitChar['1];
      IF j=3 OR j=6 THEN EmitSpace[];
    ENDLOOP;
    FOR j: CARDINAL DECREASING IN [1..4] DO
      IF rp.interval[i].function2[j]=0 THEN EmitChar['0] ELSE EmitChar['1];
      IF j=1 OR j=4 THEN EmitSpace[];
    ENDLOOP;
    EmitSpace[2];
    FOR j: CARDINAL DECREASING IN [1..6] DO
      IF rp.interval[i].function3[j]=0 THEN EmitChar['0] ELSE EmitChar['1];
      IF j=4 THEN EmitSpace[];
    ENDLOOP;
    EmitChar[Ascii.CR];
  ENDLOOP;
END; -- of EmitInterval

EmitAlarm: PROCEDURE=
BEGIN
  lineLabels: ARRAY BruceDefs.AlarmIndex OF CHARACTER = ['A,'B,'C,'D];
  EmitLine[" !	  Binary   Temp    Gas  Sft"L];
  EmitLine[" !Abt	         1                    Abt"L];
  EmitLine[" !Grp	1234567890 123456 1234567 123 Dst"L];
  EmitChar[Ascii.CR];
  FOR i:BruceDefs.AlarmIndex IN BruceDefs.AlarmIndex DO
    EmitSpace[2]; EmitChar[lineLabels[i]]; EmitTab[];
    FOR j:CARDINAL DECREASING IN [7..16] DO
      IF rp.alarm[i].binaryMask[j]=0 THEN EmitChar['0] ELSE EmitChar['1];
    ENDLOOP;
    EmitSpace[];
    FOR j: CARDINAL DECREASING IN [3..8] DO
      IF rp.alarm[i].tempMask[j]=0 THEN EmitChar['0] ELSE EmitChar['1];
    ENDLOOP;
    EmitSpace[];
    FOR j: CARDINAL DECREASING IN [2..8] DO
      IF rp.alarm[i].gasMask[j]=0 THEN EmitChar['0] ELSE EmitChar['1];
    ENDLOOP;
    EmitSpace[];
    FOR j: CARDINAL DECREASING IN [6..8] DO
      IF rp.alarm[i].softMask[j]=0 THEN EmitChar['0] ELSE EmitChar['1];
    ENDLOOP;
    EmitSpace[];
    EmitDecimal[rp.alarm[i].destInterval];
    EmitChar[Ascii.CR];
  ENDLOOP;
END; -- of EmitAlarm

EmitTempTable: PROCEDURE=
BEGIN
  EmitTempMult: PROCEDURE[i:BruceDefs.MultiplierIndex]=
  BEGIN
    EmitSpace[2]; EmitChar[MultLabels[i]]; EmitTab[];
    EmitMult[rp.abortMultipliers.temp[i]];
  END; -- of EmitTempMult
  EmitLine[" !            Heater Thermocouple   Profile Thermocouple"L];
  EmitLine[" !            Load  Center  Source  Load  Center  Source"L];
  EmitLine[" !Row	Mult	  1      2       3      4       5      6"L];
  EmitChar[Ascii.CR];
  FOR i:BruceDefs.TempRowIndex IN BruceDefs.TempRowIndex DO
    EmitSpace[2]; EmitDecimal[i,1]; EmitTab[2];
    FOR j:BruceDefs.TempColIndex IN BruceDefs.TempColIndex DO
      EmitTemp[rp.temp[i][j]]; EmitSpace[2];
    ENDLOOP;
    EmitChar[Ascii.CR];
  ENDLOOP;
  EmitTempMult[1]; EmitTab[];
  FOR i:BruceDefs.TempColIndex IN BruceDefs.TempColIndex DO
    EmitTemp[rp.alert.temp[i]]; EmitSpace[2];
  ENDLOOP;
  EmitChar[Ascii.CR];
  FOR i:BruceDefs.MultiplierIndex IN [2..3] DO
    EmitTempMult[i];
    EmitChar[Ascii.CR];
  ENDLOOP;
END; -- of EmitTempTable

EmitGasTable: PROCEDURE=
BEGIN
  EmitGasMult: PROCEDURE[i:BruceDefs.MultiplierIndex]=
  BEGIN
    EmitSpace[2]; EmitChar[MultLabels[i]]; EmitTab[];
    EmitMult[rp.abortMultipliers.gas[i]];
  END; -- of EmitGasMult
  EmitGas: PROCEDURE[g:CARDINAL]=
  BEGIN
    EmitDecimal[g/100,2];
    EmitChar['.];
    EmitDecimal[g MOD 100,2];
  END; -- of EmitGas
  EmitLine[" !Row	Mult	 1      2     3      4     5      6     7"L];
  EmitChar[Ascii.CR];
  FOR i:BruceDefs.GasRowIndex IN BruceDefs.GasRowIndex DO
    EmitSpace[2]; EmitDecimal[i,1]; EmitTab[2];
    FOR j:BruceDefs.GasColIndex IN BruceDefs.GasColIndex DO
      EmitGas[rp.gas[i][j]]; EmitSpace[2];
    ENDLOOP;
    EmitChar[Ascii.CR];
  ENDLOOP;
  EmitGasMult[1]; EmitTab[];
  FOR i:BruceDefs.GasColIndex IN BruceDefs.GasColIndex DO
    EmitGas[rp.alert.gas[i]]; EmitSpace[2];
  ENDLOOP;
  EmitChar[Ascii.CR];
  FOR i:BruceDefs.MultiplierIndex IN [2..3] DO
    EmitGasMult[i];
    EmitChar[Ascii.CR];
  ENDLOOP;
END; -- of EmitGasTable

EmitBoatControl: PROCEDURE=
BEGIN
  EmitSubTable:PROCEDURE[br: POINTER TO BruceDefs.BoatRows,
    lp: POINTER TO lineLabel]=
  BEGIN
    FOR i:BruceDefs.BoatRowIndex IN BruceDefs.BoatRowIndex DO
      EmitString[lp[i]];
      FOR j:BruceDefs.BoatSegmentIndex IN BruceDefs.BoatSegmentIndex DO
        EmitDecimal[br[i][j].speed];
        EmitSpace[];
        EmitDecimal[br[i][j].distance];
        EmitSpace[2];
      ENDLOOP;
      EmitChar[Ascii.CR];
    ENDLOOP;
  END; -- of EmitSubTable
  lineLabel: TYPE = ARRAY BruceDefs.BoatRowIndex OF STRING;
  inLabel:lineLabel ←
    ["  In Speed	1 "
    ,"          	2 "];
  outLabel:lineLabel ←
    [" Out Speed	3 "
    ,"          	4 "];
  EmitLine[" !     Segment   1      2      3"L];
  EmitLine[" !		   S D   S  D  S  D"L];
  EmitChar[Ascii.CR];
  EmitSubTable[@rp.boat.in,@inLabel];
  EmitSubTable[@rp.boat.out,@outLabel];
END; -- of EmitBoatControl

EmitCoefficient: PROCEDURE=
BEGIN
  rowLabel:ARRAY BruceDefs.FactorIndex OF STRING ←
    ["  A"
    ,"  B"
    ,"  C"
    ,"  D"];
  EmitLine[" !				Outer				Temp"L];
  EmitLine[" !				Loop			Prop	Range"L];
  EmitLine[" !Row	Zone	Calib	Latcy	Rate	Rate	Reset	Band	Scale"L];
  EmitChar[Ascii.CR];
  FOR i:BruceDefs.FactorIndex IN BruceDefs.FactorIndex DO
    EmitString[rowLabel[i]];
    FOR j:BruceDefs.ZoneIndex IN BruceDefs.ZoneIndex DO
      EmitTab[];
      EmitDecimal[j,1]; EmitTab[];
      EmitInteger[rp.control.factorArray[i].calibration[j],4]; EmitTab[];
      EmitDecimal[rp.control.factorArray[i].latency[j],4]; EmitTab[];
      EmitDecimal[rp.control.factorArray[i].outerLoopRate[j],4]; EmitTab[];
      EmitDecimal[rp.control.factorArray[i].rate[j],4]; EmitTab[];
      EmitDecimal[rp.control.factorArray[i].reset[j],4]; EmitTab[];
      EmitDecimal[rp.control.factorArray[i].proportionalBand[j],4];
      IF j=FIRST[BruceDefs.ZoneIndex] THEN
        {EmitTab[]; EmitTemp[rp.tempRange[i]]};
      EmitChar[Ascii.CR];
    ENDLOOP;
  ENDLOOP;
  EmitChar[Ascii.CR];
  EmitTab[];
  FOR i:BruceDefs.WierdIndex IN BruceDefs.WierdIndex DO
    EmitDecimal[rp.control.wierdStuff[i],1]; EmitSpace[];
  ENDLOOP;
  EmitChar[Ascii.CR];
END; -- of EmitCoefficient

END.