-- Copyright (C) 1984  by Xerox Corporation. All rights reserved. 
-- TTYPortHeadDicentra.mesa, HGM, 14-Sep-84  8:18:03

DIRECTORY
  DicentraInputOutput USING [
    Input, InterruptLevel, IOAddress, Output, SetPhonelineCSB, SetWakeupMask],
  Inline USING [BITAND],
  MultibusAddresses USING [scc2],
  TTYPortFace USING [DeviceStatus, Parameter, TransferStatus];

TTYPortHeadDicentra: MONITOR
  IMPORTS DicentraInputOutput, Inline
  EXPORTS TTYPortFace =
  BEGIN
  
-- Krock: Use second connector because it doesn't fit.
  scc0: DicentraInputOutput.IOAddress = MultibusAddresses.scc2;
  chanB: LONG POINTER TO Words = scc0 + 00H;
  chanA: LONG POINTER TO Words = scc0 + 10H;
  chan: LONG POINTER TO Words ← chanA;  -- Line 0
  Words: TYPE = RECORD [
    r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15: WORD];

  GetCommand: PUBLIC PROCEDURE [CARDINAL]
    RETURNS [data: CHARACTER, stat: TTYPortFace.TransferStatus] =
    BEGIN
    IF ~ReadyToGet[] THEN RETURN[TRASH, notReady];
    data ← Inline.BITAND[DicentraInputOutput.Input[@chan.r8],177B];
    stat ← success;
    END;
  
  GetLineCount: PUBLIC PROCEDURE RETURNS [CARDINAL] = {RETURN[1]};

  GetStatus: PUBLIC PROCEDURE [CARDINAL] RETURNS [TTYPortFace.DeviceStatus] =
    BEGIN
    RETURN[[
      readyToPut: ReadyToPut[],
      readyToGet: ReadyToGet[],
      dataTerminalReady: TRUE,
      requestToSend: TRUE]];
    END;

  PutCommand: PUBLIC PROCEDURE [lineNumber: CARDINAL, data: CHARACTER]
    RETURNS [TTYPortFace.TransferStatus] =
    BEGIN
    IF ~ReadyToPut[] THEN RETURN[notReady];
    DicentraInputOutput.Output[data, @chan.r8];
    RETURN[success];
    END;

  SendBreak: PUBLIC PROCEDURE [lineNumber: CARDINAL] =
    BEGIN
    END;

  SetParameter: PUBLIC PROCEDURE [lineNumber: CARDINAL, parameter: TTYPortFace.Parameter] =
    BEGIN
    END;

  On: PUBLIC PROCEDURE [lineNumber: CARDINAL, mask: UNSPECIFIED] =
    BEGIN
    DicentraInputOutput.SetPhonelineCSB[NIL];
    DicentraInputOutput.Output[002H, @chanB.r0];  -- Shift Left (ADR0 is ignored)
    DicentraInputOutput.Output[0C9H, @chan.r9];  -- Hardware Reset, MIE, V, VIS
    DicentraInputOutput.Output[012H, @chan.r1];  -- Rx All Int, Tx Int En
    DicentraInputOutput.Output[0C0H, @chan.r2];  -- Init Vector Base
    DicentraInputOutput.Output[0C1H, @chan.r3];  -- 8bits/char, RxE
    DicentraInputOutput.Output[04AH, @chan.r4];  -- 16xClock, 2 Stop Bits
    DicentraInputOutput.Output[0EAH, @chan.r5];  -- DTR, 8bits/char, TxE, RTS
    DicentraInputOutput.Output[050H, @chan.r11];  -- Clocks from BR Gen
    DicentraInputOutput.Output[006H, @chan.r12];  -- Low byte of time constant
    DicentraInputOutput.Output[000H, @chan.r13];  -- High byte of time constant
    DicentraInputOutput.Output[003H, @chan.r14];  -- Enable Baud Rate Gen from PClk
    DicentraInputOutput.SetWakeupMask[mask, phoneLine];
    END;

  Off: PUBLIC PROCEDURE [CARDINAL] = BEGIN END;

  InitializeCleanup: PROCEDURE = BEGIN END;
    
  ReadyToGet: PROCEDURE RETURNS [BOOLEAN] =
    BEGIN
    bits: WORD = DicentraInputOutput.Input[@chan.r0];
    DicentraInputOutput.Output[010H, @chan.r0];  -- Reset Ext/Status Interrupts
    RETURN[Inline.BITAND[bits, 1] # 0];  -- Rx Character Available
    END;
  
  ReadyToPut: PROCEDURE RETURNS [BOOLEAN] =
    BEGIN
    bits: WORD = DicentraInputOutput.Input[@chan.r0];
    DicentraInputOutput.Output[028H, @chan.r0];  -- Reset Tx Int Pending
    RETURN[Inline.BITAND[bits, 4] # 0];  -- Tx Buffer Empty
    END;
  
  -- Mainline code
  InitializeCleanup[];

  END....