-- File: EiaKludge.mesa,  Last Edit: HGM  July 20, 1980  3:31 AM

-- BEWARE: If the display is on while the XEOS EIA board is running the clock will drift. The problem is that the microcode can't process an interrupt within one scan line (38 microseconds) when the display uses too many cycles.  It works ok when the display is off.

DIRECTORY
  Process USING [Detach, SetTimeout, SecondsToTicks],
  UserTerminal USING [GetState],
  Trouble USING [];

EiaKludge: MONITOR IMPORTS Process, UserTerminal EXPORTS Trouble =
  BEGIN

  onWarning, offWarning: PROCEDURE;
  once: BOOLEAN ← FALSE;

  SetDisplayOnOffProcs: PUBLIC ENTRY PROCEDURE [on, off: PROCEDURE] =
    BEGIN
    onWarning ← on;
    offWarning ← off;
    IF once THEN RETURN;
    once ← TRUE;
    Process.Detach[FORK DisplayWatcher[]];
    END;

  DisplayWatcher: ENTRY PROCEDURE =
    BEGIN
    displayState: {unknown, on, off} ← unknown;
    pause: CONDITION;
    Process.SetTimeout[@pause, Process.SecondsToTicks[15]];
    DO
      -- forever
      WAIT pause;
      SELECT UserTerminal.GetState[] FROM
	on =>
	  BEGIN
	  IF displayState # on THEN BEGIN displayState ← on; onWarning[]; END;
	  END;
	off, disconnected =>
	  BEGIN
	  IF displayState # off THEN BEGIN displayState ← off; offWarning[]; END;
	  END;
	ENDCASE => ERROR;
      ENDLOOP;
    END;

  -- initialization;

  END.