-- CedarSnapshotFeedback.mesa
-- last edited by Levin:  June 1, 1982 9:20 am


DIRECTORY
  CedarSnapshotPrivate USING [Direction, Phase],
  Heap USING [systemZone],
  Inline USING [BITXOR],
  UserTerminal USING [
    CursorArray, GetCursorPattern, GetState, SetCursorPattern, SetState, State];

CedarSnapshotFeedback: PROGRAM
  IMPORTS Heap, Inline, UserTerminal
  EXPORTS CedarSnapshotPrivate =

BEGIN OPEN CedarSnapshotPrivate;

FirstTwo: TYPE = [0..5);
SecondTwo: TYPE = [5..10);
LastOne: TYPE = [10..15);

cursors: ARRAY Direction OF UserTerminal.CursorArray =
  [[075122B, 041122B, 041124B, 041734B, 041124B, 041122B, 075122B, 000000B,
    017370B, 011040B, 011040B, 016040B, 010040B, 010040B, 010040B, 000000B],
   [167210B, 125210B, 125210B, 145210B, 125210B, 125210B, 127356B, 000000B,
    147352B, 125212B, 125212B, 147214B, 125212B, 125212B, 145352B, 000000B]];

savedCursor: LONG POINTER TO UserTerminal.CursorArray;
savedState: UserTerminal.State;

InitializeFeedback: PUBLIC PROCEDURE =
  BEGIN
  savedCursor ←
    Heap.systemZone.NEW[UserTerminal.CursorArray ← UserTerminal.GetCursorPattern[]];
  IF (savedState ← UserTerminal.GetState[]) = on THEN [] ← UserTerminal.SetState[off];
  END;

FinalizeFeedback: PUBLIC PROCEDURE =
  BEGIN
  UserTerminal.SetCursorPattern[savedCursor↑];
  Heap.systemZone.FREE[@savedCursor];
  [] ← UserTerminal.SetState[savedState];
  END;

SetPhase: PUBLIC PROCEDURE [phase: Phase, direction: Direction] =
  BEGIN
  cursor: UserTerminal.CursorArray ← cursors[direction];
  topMasks: ARRAY [0..4) OF WORD = [0, 377B, 177400B, 177777B];
  bottomMask: WORD = 177400B;
  Pieces: TYPE = MACHINE DEPENDENT RECORD[
    SELECT OVERLAID * FROM
      phase => [fill: [0..3777B], phase: Phase],
      pieces => [fill: [0..3777B], firstTwo, secondTwo: [0..3], lastOne: [0..1]]
      ENDCASE];
  p: Pieces = [phase[fill: 0, phase: phase]];
  FOR i: CARDINAL IN FirstTwo DO
    cursor[i] ← Inline.BITXOR[cursor[i], topMasks[p.firstTwo]];
    ENDLOOP;
  FOR i: CARDINAL IN SecondTwo DO
    cursor[i] ← Inline.BITXOR[cursor[i], topMasks[p.secondTwo]];
    ENDLOOP;
  IF p.lastOne = 1 THEN
    FOR i: CARDINAL IN LastOne DO
      cursor[i] ← Inline.BITXOR[cursor[i], bottomMask];
      ENDLOOP;
  UserTerminal.SetCursorPattern[cursor];
  END;

Twiddle: PUBLIC PROCEDURE =
  BEGIN
  cursor: UserTerminal.CursorArray ← UserTerminal.GetCursorPattern[];
  FOR i: CARDINAL IN LastOne DO
    cursor[i] ← Inline.BITXOR[cursor[i], 377B];
    ENDLOOP;
  UserTerminal.SetCursorPattern[cursor];
  END;

END.