-- File: PupShow.mesa,  Last Edit: HGM January 7, 1981  10:29 PM

DIRECTORY
  Ascii USING [TAB, CR, LF, FF],
  Inline USING [LowHalf, HighHalf],
  Put USING [Char, Decimal, Line, Octal, Text],
  String USING [AppendLongDecimal],
  System USING [Pulses, GetClockPulses, PulsesToMicroseconds],
  Window USING [Handle],
  CommUtilDefs USING [GetEthernetHostNumber],
  PupDefs USING [
    incomingPup, outgoingPup, PupAddress, PupBuffer, PupHostID, PupSocketID],
  BufferDefs;

-- SHAREs

PupShow: MONITOR
  IMPORTS Inline, Put, String, System, CommUtilDefs
  EXPORTS PupDefs
  SHARES BufferDefs =
  BEGIN OPEN PupDefs;

  myHost: PupHostID ← [CommUtilDefs.GetEthernetHostNumber[]];

  s: ARRAY [0..9] OF PupSocketID;
  i: CARDINAL;
  h1, h2, h3, h4: PupHostID;
  startPulses: System.Pulses = System.GetClockPulses[];

  ShowPupBuffer: PUBLIC ENTRY PROCEDURE [
    wh: Window.Handle, c: CARDINAL, b: PupBuffer] =
    BEGIN
    IF b.pupType = gatewayInfo THEN RETURN;
    SELECT c FROM
      0 => NULL;
      incomingPup => Put.Text[wh, "incoming"L];
      outgoingPup => Put.Text[wh, "outgoing "L];
      ENDCASE => BEGIN Put.Text[wh, "code="L]; Put.Decimal[wh, c]; END;
    IF b.queue # NIL THEN
      BEGIN
      low: WORD ← Inline.LowHalf[b.queue];
      high: WORD ← Inline.HighHalf[b.queue];
      Put.Text[wh, "  on queue "];
      IF high # 0 THEN BEGIN Put.Octal[wh, high]; Put.Char[wh, '|]; END;
      Put.Octal[wh, low];
      END;
    Put.Text[wh, "  "];
    ShowPupPacket[wh, 0, b];
    Put.Line[wh, " "];
    END;

  ShowPupPacket: PROCEDURE [wh: Window.Handle, c: CARDINAL, b: PupBuffer] =
    BEGIN
    char: CHARACTER;
    IF c # 0 THEN BEGIN Put.Text[wh, "  call="L]; Put.Decimal[wh, c]; END;
    Put.Text[wh, "lengths "];
    Put.Decimal[wh, b.length];
    Put.Text[wh, " "];
    Put.Decimal[wh, b.pupLength];
    Put.Text[wh, " "];
    Put.Decimal[wh, b.pupLength - 22];
    Put.Text[wh, "  "];
    Put.Text[wh, "Encap: to="];
    Put.Octal[wh, b.encapsulation.ethernetOneDest];
    Put.Text[wh, ",  from="];
    Put.Octal[wh, b.encapsulation.ethernetOneSource];
    Put.Text[wh, ",  type="];
    Put.Octal[wh, b.encapsulation.ethernetOneType];
    Put.Line[wh, " "];
    SELECT b.pupType FROM
      error => Put.Text[wh, "ERROR "];
      rfc => Put.Text[wh, "RFC "];
      abort => Put.Text[wh, "ABORT "];
      end => Put.Text[wh, "END "];
      endRep => Put.Text[wh, "ENDREPLY "];
      data => Put.Text[wh, "DATA "];
      aData => Put.Text[wh, "ADATA "];
      ack => Put.Text[wh, "ACK "];
      mark => Put.Text[wh, "MARK "];
      aMark => Put.Text[wh, "AMARK "];
      ENDCASE =>
	BEGIN
	Put.Text[wh, "pup Type "];
	Put.Octal[wh, LOOPHOLE[b.pupType, CARDINAL]];
	END;
    Put.Text[wh, "  From: "];
    ShowPupAddress[wh, b.source];
    Put.Text[wh, "   "];
    Put.Text[wh, " To: "];
    ShowPupAddress[wh, b.dest];
    Put.Line[wh, ""];
    Put.Text[wh, "id: "];
    Put.Decimal[wh, b.pupID.a];
    Put.Char[wh, '|];
    Put.Decimal[wh, b.pupID.b];
    Put.Text[wh, "   t: "];
    PrintTimeSinceStartup[wh];
    Put.Line[wh, " "];
    SELECT b.pupType FROM
      rfc => ShowPupAddress[wh, b.address];
      ack =>
	FOR i IN [0..2] DO
	  Put.Decimal[wh, LOOPHOLE[b.pupWords[i]]]; Put.Text[wh, "  "]; ENDLOOP;
      ENDCASE =>
	FOR i IN [22..b.pupLength) DO
	  SELECT (char ← b.pupChars[i - 22]) FROM
	    IN [' ..'~] => Put.Char[wh, char];
	    Ascii.TAB => Put.Text[wh, "<TAB>"L];
	    Ascii.CR => Put.Text[wh, "<CR>"L];
	    Ascii.LF => Put.Text[wh, "<LF>"L];
	    Ascii.FF => Put.Text[wh, "<FF>"L];
	    ENDCASE =>
	      BEGIN Put.Char[wh, '<]; Put.Octal[wh, char]; Put.Char[wh, '>]; END;
	  ENDLOOP;
    Put.Line[wh, " "];
    END;

  ShowPupSocket: PROCEDURE [wh: Window.Handle, x: PupSocketID] =
    BEGIN
    Put.Text[wh, "   "];
    Put.Decimal[wh, x.a];
    Put.Char[wh, '|];
    Put.Decimal[wh, x.b];
    END;

  ShowPupAddress: PROCEDURE [wh: Window.Handle, x: PupAddress] =
    BEGIN
    Put.Text[wh, "  "];
    SELECT x.host FROM
      myHost => Put.Text[wh, "ME"];
      0 => Put.Text[wh, "BC"];
      h1 => Put.Text[wh, "H1"];
      h2 => Put.Text[wh, "H2"];
      h3 => Put.Text[wh, "H3"];
      h4 => Put.Text[wh, "H4"];
      ENDCASE =>
	BEGIN
	SELECT 0 FROM
	  h1 => BEGIN h1 ← x.host; Put.Text[wh, "H1 = "]; END;
	  h2 => BEGIN h2 ← x.host; Put.Text[wh, "H2 = "]; END;
	  h3 => BEGIN h3 ← x.host; Put.Text[wh, "H3 = "]; END;
	  h4 => BEGIN h4 ← x.host; Put.Text[wh, "H4 = "]; END;
	  ENDCASE;
	Put.Decimal[wh, x.host];
	END;
    FOR i IN [0..9] DO
      IF s[i] = [0, 0] THEN
	BEGIN s[i] ← x.socket; ShowPupSocket[wh, x.socket]; END;
      IF s[i] = x.socket THEN
	BEGIN Put.Text[wh, " Soc"]; Put.Decimal[wh, i]; EXIT; END
      REPEAT FINISHED => ShowPupSocket[wh, x.socket];
      ENDLOOP;
    END;

  PrintTimeSinceStartup: PROCEDURE [wh: Window.Handle] =
    BEGIN
    now: System.Pulses = System.GetClockPulses[];
    ms: LONG CARDINAL = System.PulsesToMicroseconds[[now - startPulses]]/1000;
    s: STRING = [20];
    String.AppendLongDecimal[s, ms];
    IF s.length > 3 THEN
      BEGIN
      FOR i: CARDINAL IN [0..s.length - 3) DO Put.Char[wh, s[i]]; ENDLOOP;
      Put.Char[wh, '.];
      FOR i: CARDINAL IN [s.length - 3..s.length) DO Put.Char[wh, s[i]]; ENDLOOP;
      END
    ELSE
      BEGIN
      Put.Text[wh, "0."L];
      FOR i: CARDINAL IN [s.length..3) DO Put.Char[wh, '0]; ENDLOOP;
      Put.Text[wh, s];
      END;
    END;

  -- initialization

  FOR i IN [0..9] DO s[i] ← [0, 0]; ENDLOOP;
  s[0] ← [0, 3];
  h1 ← h2 ← h3 ← h4 ← [0];
  END.