-- Copyright (C) 1983  by Xerox Corporation. All rights reserved. 
-- OscarTTY.mesa, HGM, 23-Sep-83  0:20:03

DIRECTORY
  Ascii USING [BS, CR],
  Inline USING [BITNOT],
  KeyStations USING [D1, D2, KeyBits],
  OthelloDefs USING [Cursor],
  OthelloForgot USING [],
  Runtime USING [IsBound],
  TTY USING [
    BlinkDisplay, Create, GetChar, Handle, PutChar, ResetUserAbort,
    UserAbort],
  UserTerminal USING [
    CursorArray, GetCursorPattern, keyboard, SetCursorPattern];

OscarTTY: PROGRAM
  IMPORTS
    Inline, Runtime,
    LfTTY: TTY, AdmTTY: TTY, UserTerminal
  EXPORTS OthelloDefs, OthelloForgot =
  BEGIN

  -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  -- TTY Interface Stuff
  -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  hasADM: BOOLEAN = Runtime.IsBound[LOOPHOLE[AdmTTY.Create]] AND 
    (LOOPHOLE[UserTerminal.keyboard, LONG POINTER TO KeyStations.KeyBits]
      [KeyStations.D1]=up 
    OR LOOPHOLE[UserTerminal.keyboard, LONG POINTER TO KeyStations.KeyBits]
         [KeyStations.D2]=up);
  ttyHandle: TTY.Handle =
    (IF hasADM THEN AdmTTY.Create ELSE LfTTY.Create)["Othello"L];
  
  BlinkDisplay: PUBLIC PROC = {
    (IF hasADM THEN AdmTTY.BlinkDisplay ELSE LfTTY.BlinkDisplay)[ttyHandle]};
    
  CheckUserAbort: PUBLIC PROC = {
    IF (IF hasADM THEN AdmTTY.UserAbort ELSE LfTTY.UserAbort)[ttyHandle] THEN {
      ResetAbort[]; ERROR ABORTED}};
    
  EraseTTYChar: PUBLIC PROC [c: CHARACTER] = {
    SELECT c FROM IN [' ..'~] => NULL; Ascii.CR => RETURN; ENDCASE => EraseTTYChar[' ];
    WriteChar[Ascii.BS]; WriteChar[' ]; WriteChar[Ascii.BS]};

  ReadChar: PUBLIC PROC RETURNS [c: CHARACTER] = {
    RETURN[(IF hasADM THEN AdmTTY.GetChar ELSE LfTTY.GetChar)[ttyHandle]]};

  SetCursor: PUBLIC PROC [c: OthelloDefs.Cursor] = {
    cursor: ARRAY OthelloDefs.Cursor OF UserTerminal.CursorArray = [
      pointer: [
        100000B, 140000B, 160000B, 170000B, 174000B, 176000B, 177000B, 170000B,
	154000B, 114000B, 006000B, 006000B, 003000B, 003000B, 001400B, 001400B],
      ftp: [
        000177B, 076077B, 040037B, 040017B, 070007B, 043703B, 040401B, 040400B,
        000400B, 100436B, 140421B, 160421B, 170036B, 174020B, 176020B, 177020B]];
      IF ~hasADM THEN UserTerminal.SetCursorPattern[cursor[c]]};

  FlipCursor: PUBLIC PROC = {
    c: UserTerminal.CursorArray;
    IF ~hasADM THEN  {
      c ← UserTerminal.GetCursorPattern[];
      FOR i: CARDINAL IN [0..LENGTH[c]) DO c[i] ← Inline.BITNOT[c[i]] ENDLOOP;
      UserTerminal.SetCursorPattern[c]}
    ELSE {
      string: STRING = " FTP "L;
      WriteString[string];
      FOR i: CARDINAL DECREASING IN [0..string.length) DO
        EraseTTYChar[string[i]] ENDLOOP}};

  NewLine: PUBLIC PROC = {WriteChar[Ascii.CR]};

  ResetAbort: PUBLIC PROC = {
    (IF hasADM THEN AdmTTY.ResetUserAbort ELSE LfTTY.ResetUserAbort)[ttyHandle]};
  
  WriteChar: PUBLIC PROC [c: CHARACTER] = {
    (IF hasADM THEN AdmTTY.PutChar ELSE LfTTY.PutChar)[ttyHandle, c]};

  WriteLine: PUBLIC PROC [s: LONG STRING] = {WriteString[s]; NewLine[]};
  
  WriteString: PUBLIC PROC [s: LONG STRING] = {
    i: CARDINAL;
    IF s # NIL THEN FOR i ← 0, i + 1 WHILE i < s.length DO
      IF s[i] = '\\ AND s[i + 1] = 'r THEN {
      NewLine[]; i ← i + 1} ELSE WriteChar[s[i]];
      ENDLOOP};

  END..