{
 ßßßßßßßß  ßßßßßß    ßß   ßß
   ßß     ßß   ßß   ßß  ßß
  ßß     ßß   ßßß  ßßßßß  The DoorKit!
 ßß     ßß   ßß   ßß  ßß
ßß     ßßßßßß    ßß    ßß
The BBS Door Development Kit By The People - For The People!


   Feel free to modify or optimize this code at will. All I ask is that if
   find a better way to do things (and you will), please send me a copy of
   your modifications. Thanks in advance!....Larry L. Athey....}

{$A+,B-,D+,E+,F+,G+,I-,L+,N-,O+,P-,Q-,R-,S-,T-,V+,X+}
UNIT COMM;

INTERFACE

USES TDK_VARS, FOSUNIT, ASYNC, DIGIBORD;

TYPE AsyncIOTypes = (Fossil,Internal,Bios,Digi);

VAR
  AsyncIOType     : AsyncIOTypes;
  InitOk,
  NoFossInit,
  FosBnu          : BOOLEAN;
  InternalInSize,
  InternalOutSize : WORD;

PROCEDURE SelectPort(PN : BYTE);
PROCEDURE SendChar(Ch : CHAR);
PROCEDURE ReceiveChar(VAR Ch : CHAR);
FUNCTION  CarrierPresent : BOOLEAN;
FUNCTION  Data_Available : BOOLEAN;
PROCEDURE SelectFossil(VAR FossilName : STRING);
PROCEDURE SelectInternal;
PROCEDURE SelectDigiBoard(VAR DigiBoardName : STRING);
PROCEDURE CloseUp;
PROCEDURE CloseCom(CP : BYTE);
PROCEDURE SetBaud(N : LONGINT);
PROCEDURE Set_DTR(State : BOOLEAN);
PROCEDURE Flush_Output;
PROCEDURE Purge_Input;
PROCEDURE Purge_Output;
PROCEDURE SetFlow(SoftTran,Hard,SoftRecv : BOOLEAN);
PROCEDURE BufferStatus(VAR InSize,InFree,OutSize,OutFree : WORD;
                       VAR FossilName : STRING);
PROCEDURE SetUpPorts;
PROCEDURE LoadPorts(VAR port1,port2,port3,port4 : WORD;
                    VAR irq1,irq2,irq3,irq4 : BYTE);
PROCEDURE ResetPorts(VAR port1,port2,port3,port4 : WORD;
                     VAR irq1,irq2,irq3,irq4 : BYTE);

IMPLEMENTATION

PROCEDURE SelectPort(PN : BYTE);
BEGIN;
  Comport := PN;
  CASE AsyncIOType OF
    Fossil   : BEGIN
                 Port_Num := PN - 1;
                 IF NoFossInit THEN BEGIN
                   Async_Purge_Output;
                   Async_Purge_Input;
                   InitOk := TRUE;
                 END ELSE BEGIN
                   Async_DeInit_Fossil;
                   InitOk := Async_Init_Fossil;
                 END;
               END;
    Internal : BEGIN;
                 CloseAllComs;
                 InitOk := OpenCom(PN,InternalInSize,InternalOutSize);
               END;
    Digi     : BEGIN
                 Dport_Num := PN - 1;
                 InitOk    := Digi_Init_Driver;
               END;
  END;
END;

PROCEDURE SendChar(Ch : CHAR);
BEGIN;
  CASE AsyncIOType OF
    Fossil   : Async_Send(Ch);
    Internal : BEGIN
                 WHILE CTSStat(Comport) OR RTSstat(Comport) DO IF NOT CarrierPresent THEN EXIT;
                 ComWriteChw(Comport,Ch);
               END;
    Digi     : BEGIN
                 WHILE (NOT OutReady) DO IF NOT CarrierPresent THEN EXIT;
                 Digi_Send(Ch);
               END;
  END;
END;

PROCEDURE ReceiveChar(VAR Ch : CHAR);
VAR
  B : BOOLEAN;
BEGIN;
  CASE AsyncIOType OF
    Fossil   : B  := Async_Receive(Ch);
    Internal : Ch := ComReadCh(Comport);
    Digi     : B  := Digi_Receive(Ch);
  END;
END;

FUNCTION CarrierPresent : BOOLEAN;
BEGIN;
  CASE AsyncIOType OF
    Fossil   : CarrierPresent := Async_Carrier_Present;
    Internal : CarrierPresent := DCDStat(Comport);
    Digi     : CarrierPresent := Digi_Carrier_Present;
  END;
END;

FUNCTION Data_Available : BOOLEAN;
BEGIN;
  CASE AsyncIOType OF
    Fossil   : Data_Available := Async_Buffer_Check;
    Internal : Data_Available := ComBufferLeft(Comport,'I') <> C_InSize[Comport];
    Digi     : Data_Available := Digi_Buffer_Check;
  END;
END;

PROCEDURE SelectFossil;
VAR
  InSize,InFree,OutSize,OutFree : WORD;
  S : STRING;
  P : BYTE;
BEGIN;
  AsyncIOType := Fossil;
  BufferStatus(InSize,InFree,OutSize,OutFree,FossilName);
  S := '';
  FOR P := 1 TO LENGTH(FossilName) DO S := S + UPCASE(FossilName[P]);
  P := POS('BNU',S);
  IF P > 0 THEN FosBnu := TRUE;
END;

PROCEDURE SelectDigiBoard;
VAR
  InSize,InFree,OutSize,OutFree : WORD;
BEGIN;
  AsyncIOType := Digi;
  Digi_Get_Info(DigiBoardName);
END;

PROCEDURE CloseUp;
BEGIN;
  CASE AsyncIOType OF
    Fossil   : Async_DeInit_Fossil;
    Internal : CloseAllComs;
    Digi     : Digi_DeInit_Driver;
  END;
END;

PROCEDURE CloseCom;
BEGIN;
  CASE AsyncIOType OF
    Fossil   : Async_DeInit_Fossil;
    Internal : CloseCom(CP);
    Digi     : Digi_DeInit_Driver;
  END;
END;

PROCEDURE SetBaud(N : LONGINT);
VAR
  I : BYTE;
BEGIN;
  CASE asynciotype OF
    Fossil   : IF NOT NoFossInit THEN
               IF FosBnu THEN Async_Set_BaudBnu(N)
               ELSE Async_Set_Baud(N);
    Internal : ComParams(Comport,N,DoorSys.WordSize,DoorSys.Parity,DoorSys.StopBits);
    Digi     : BEGIN
                {InitOk := Digi_Set_Baud(N,DoorSys.WordSize,DoorSys.Parity,DoorSys.StopBits);}
                 Digi_Flush_IO;
               END;

  END;
END;

PROCEDURE SelectInternal;
BEGIN;
  AsyncIOType := Internal;
END;

PROCEDURE Set_DTR(State : BOOLEAN);
BEGIN;
  CASE AsyncIOType OF
    Fossil   : Async_Set_DTR(State);
    Internal : SetDTR(Comport,State);
  END;
END;

PROCEDURE Flush_Output;
BEGIN;
  CASE AsyncIOType OF
    Fossil   : Async_Flush_Output;
    Internal : ComWaitForClear(Comport);
    Digi     : Digi_Flush_Output;
  END;
END;

PROCEDURE Purge_Output;
BEGIN;
  CASE AsyncIOType OF
    Fossil   : Async_Purge_Output;
    Internal : ClearCom(comport,'O');
    Digi     : Digi_Flush_Output;
  END;
END;

PROCEDURE Purge_Input;
BEGIN
  CASE AsyncIOType OF
    Fossil   : Async_Purge_Input;
    Internal : ClearCom(Comport,'I');
    Digi     : Digi_Flush_Input;
  END;
END;

PROCEDURE SetFlow(SoftTran,Hard,SoftRecv : BOOLEAN);
BEGIN;
  CASE AsyncIOType OF
    Fossil   : Async_Set_Flow(SoftTran,Hard,SoftRecv);
    Internal : BEGIN;
                 SetCTSMode(Comport,Hard);
                 SetRTSMode(Comport,Hard,C_RTSOn[Comport],C_RTSOff[Comport]);
                 SoftHandShake(Comport,SoftTran,'A','A');
               END;
  END;
END;

PROCEDURE BufferStatus(VAR InSize,InFree,OutSize,OutFree : WORD;
                       VAR FossilName : STRING);
BEGIN;
  CASE AsyncIOType OF
    Fossil   : Async_Buffer_Status(InSize,InFree,OutSize,OutFree,FossilName);
    Internal : BEGIN;
                 InSize  := InternalInSize;
                 OutSize := InternalOutSize;
                 InFree  := ComBufferLeft(Comport,'I');
                 OutFree := ComBufferLeft(Comport,'O');
               END;
  END;
END;

PROCEDURE SetUpPorts;
VAR
  I : BYTE;
BEGIN
  FOR I := 1 TO 4 DO BEGIN
    C_PortAddr[I] := D_PortAddr[I];
    C_PortInt[I]  := D_PortInt[I];
  END;
END;

PROCEDURE LoadPorts (VAR port1,port2,port3,port4 : WORD;
                     VAR irq1,irq2,irq3,irq4 : BYTE);
BEGIN
 port1 :=  D_PortAddr[1];
 irq1  :=  D_PortInt[1];
 port2 :=  D_PortAddr[2];
 irq2  :=  D_PortInt[2];
 port3 :=  D_PortAddr[3];
 irq3  :=  D_PortInt[3];
 port4 :=  D_PortAddr[4];
 irq4  :=  D_PortInt[4];
END;

PROCEDURE ResetPorts (VAR port1,port2,port3,port4 : WORD;
                      VAR irq1,irq2,irq3,irq4 : BYTE);
BEGIN
  C_PortAddr[1] := port1;
  C_PortInt[1]  := irq1;
  C_PortAddr[2] := port2;
  C_PortInt[2]  := irq2;
  C_PortAddr[3] := port3;
  C_PortInt[3]  := irq3;
  C_PortAddr[4] := port4;
  C_PortInt[4]  := irq4;
END;

BEGIN;
  AsyncIOType     := Internal;
  Comport         := 1;
  InternalInSize  := 4096;
  InternalOutSize := 4126;
END.
