[Back to COMM SWAG index]  [Back to Main SWAG index]  [Original]

Unit FWizard;

{/
      Fossil Wizard Unit v1.0 by Steve Connet - Tuesday, Jan. 19, 1993

       This program provides an easy interface to access the routines
       provided by a fossil driver.
//}

INTERFACE
Function SetBaud(Port, Baud : Word; Parms : Byte) : Boolean;
Function OutBufferFull(Port : Word) : Boolean;
Function CharWaiting(Port : Word) : Boolean;
Function ComReadChar(Port : Word) : Char;
Function CarrierDetected(Port : Word) : Boolean;
Function ModemRinging(Port : Word) : Boolean;
Function FossilPresent : Boolean;
Function RemoteAnsiDetected(Port : Word) : Boolean;
Function LocalAnsiDetected : Boolean;
Function RemoteAvatarDetected(Port : Word) : Boolean;

Procedure ActivatePort(Port : Word);
Procedure DTR(Port : Word; Action : Byte);
Procedure ReBoot(Action : Byte);
Procedure DeActivatePort(Port : Word);
Procedure ComWriteChar(Port : Word; Ch : Char);
Procedure ClearOutBuffer(Port : Word);
Procedure ClearInBuffer(Port : Word);
Procedure FlowControl(Port : Word; XON_XOFFR, XON_XOFFT, RTS_CTS : Boolean);
Procedure WatchDog(Port : Word; Action : Byte);
Procedure Chat(Port : Word);
Procedure ComWrite(Port : Word; Msg : String);
Procedure ComWriteln(Port : Word; Msg : String);
Procedure Wait(Seconds : Word);
Procedure GetCursor(VAR x, y : Byte);
Procedure SetCursor(Port : Word; x, y : Byte);
Procedure SendBreak(Port : Word);
Procedure ComReadln(Port : Word; VAR Msg : String; Count : Byte);
Procedure CLS(Port : Word);

CONST
  N81=$03; E81 =$1b; O81 =$0b; LOWER=$00; CTS =$10; RDA =$01; XONR=$01;
  N82=$07; E82 =$1f; O82 =$0f; RAISE=$01; DSR =$20; THRE=$20; XONT=$08;
  N71=$02; E71 =$1a; O71 =$0a; COLD =$00; RI  =$40; TSRE=$40; RTS =$02;
  N72=$06; E72 =$1e; O72 =$0e; WARM =$01; DCD =$80; ON  =$01; OFF =$00;
  Esc=#27; COM1=$00; COM2=$01; COM3 =$02; COM4=$03;

IMPLEMENTATION
Uses Crt;

Function SetBaud(Port, Baud : Word; Parms : Byte) : Boolean;
VAR Dummy : Word;
Begin
  Case Baud of
    300:   Baud := $40;    { 01000000 }
    600:   Baud := $60;    { 01100000 }
    1200:  Baud := $80;    { 10000000 }
    2400:  Baud := $a0;    { 10100000 }
    4800:  Baud := $c0;    { 11000000 }
    9600:  Baud := $e0;    { 11100000 }
    19200: Baud := $00;    { 00000000 }
    38400,
    14400,
    16800: Baud := $20;    { 00100000 }
  End;
  Parms := Parms OR Baud;  { merge baud bits with parm bits }
  Asm
    mov ah,00h
    mov al,parms
    mov dx,port
    int 14h
    mov dummy,ax
  End;
  SetBaud := ((Dummy AND CTS) = CTS) or     { clear to send }
             ((Dummy AND DSR) = DSR) or     { data set ready }
             ((Dummy AND RI)  = RI)  or     { ring indicator }
             ((Dummy AND DCD) = DCD)        { data carrier detect }
End;

Function OutBufferFull(Port : Word) : Boolean;
VAR Dummy : Byte;
Begin
  Asm
    mov ah,03h
    mov dx,port
    int 14h
    mov dummy,ah
  End;
  OutBufferFull := ((Dummy AND THRE) <> THRE) or  { room in out buffer }
                   ((Dummy AND TSRE) <> TSRE)     { out buffer empty }
End;

Function CharWaiting(Port : Word) : Boolean;
VAR Dummy : Byte;
Begin
  Asm
    mov ah,03h
    mov dx,port
    int 14h
    mov dummy,ah
  End;
  CharWaiting := (Dummy AND RDA) = RDA        { character waiting }
End;

Function ComReadChar(Port : Word) : Char;
VAR Dummy : Byte;
Begin
  Asm
    mov ah,02h
    mov dx,port
    int 14h
    mov dummy,al
  End;
  ComReadChar := Char(Dummy)
End;

Function CarrierDetected(Port : Word) : Boolean;
VAR Dummy : Byte;
Begin
  Asm
    mov ah,03h
    mov dx,port
    int 14h
    mov dummy,al
  End;
  CarrierDetected := (Dummy AND DCD) = DCD       { carrier detected }
End;

Function ModemRinging(Port : Word) : Boolean;
VAR Dummy : Byte;
Begin
  Asm
    mov ah,03h
    mov dx,port
    int 14h
    mov dummy,al
  End;
  ModemRinging := (Dummy AND RI) = RI       { ring indicated }
End;

Function FossilPresent : Boolean;
VAR Dummy : Word;
Begin
  Asm
    mov ah,04h
    mov dx,00ffh
    int 14h
    mov dummy,ax
  End;
  FossilPresent := Dummy = $1954;
End;

Function RemoteAnsiDetected(Port : Word) : Boolean;
VAR Dummy : Char;
Begin
  If Not OutBufferFull(Port) then
  Begin
    ComWriteChar(Port, #27); ComWriteChar(Port, '[');
    ComWriteChar(Port, '6'); ComWriteChar(Port, 'n')
  End;
  If CharWaiting(Port) then
     RemoteAnsiDetected := ComReadChar(Port) in [#27,'0'..'9','[','H'] else
     RemoteAnsiDetected := False;
  ClearInBuffer(Port)
End;

Function LocalAnsiDetected : Boolean;
VAR Dummy : Byte;
Begin
  Asm
    mov ah,1ah                { detect ANSI.SYS device driver }
    mov al,00h
    int 2fh
    mov dummy,al
  End;
  LocalAnsiDetected := Dummy = $FF
End;

Function RemoteAvatarDetected(Port : Word) : Boolean;
Begin
  If Not OutBufferFull(Port) then
  Begin
    ComWriteChar(Port, ' '); ComWriteChar(Port, ' ');
    ComWriteChar(Port, ' ');
  End;
  If CharWaiting(Port) then
     RemoteAvatarDetected := ComReadChar(Port) in ['A','V','T'] else
     RemoteAvatarDetected := False;
  ClearInBuffer(Port)
End;


Procedure ActivatePort(Port : Word); Assembler;
Asm
  mov ah,04h
  mov dx,port
  int 14h
End;

Procedure DTR(Port : Word; Action : Byte); Assembler;
Asm
  mov ah,06h
  mov al,action
  mov dx,port
  int 14h
End;

Procedure ReBoot(Action : Byte); Assembler;
Asm
  mov ah,17h
  mov al,action
  int 14h
End;

Procedure DeActivatePort(Port : Word); Assembler;
Asm
  mov ax,05h
  mov dx,port
  int 14h
End;

Procedure ComWriteChar(Port : Word; Ch : Char);
VAR Dummy : Byte;
Begin
  Dummy := Ord(Ch);
  Asm
    mov ah,01h
    mov al,dummy
    mov dx,port
    int 14h
  End;
End;

Procedure ClearOutBuffer(Port : Word); Assembler;
Asm
  mov ah,09h
  mov dx,port
  int 14h
End;

Procedure ClearInBuffer(Port : Word); Assembler;
Asm
  mov ah,0ah
  mov dx,port
  int 14h
End;

Procedure FlowControl(Port : Word; XON_XOFFR, XON_XOFFT, RTS_CTS : Boolean);
VAR Dummy : Byte;
Begin
  Dummy := $00;
  If XON_XOFFR then                 { Xon/Xoff receive enable }
     Dummy := Dummy OR XONR else    { set bit 0 on }
     Dummy := Dummy AND XONR;       { set bit 0 off }
  If XON_XOFFT then                 { Xon/Xoff transmit enable }
     Dummy := Dummy OR XONT else    { set bit 3 on }
     Dummy := Dummy AND XONT;       { set bit 3 off }
  If RTS_CTS then                   { RTS_CTS enabled }
     Dummy := Dummy OR RTS else     { set bit 1 on }
     Dummy := Dummy AND RTS;        { set bit 1 off }
  Asm
    mov ah,0fh
    mov al,dummy
    mov dx,port
    int 14h
  End
End;

Procedure WatchDog(Port : Word; Action : Byte); Assembler;
Asm
  mov ah,14h
  mov al,action
  mov dx,port
  int 14h
End;

Procedure Chat(Port : Word);

VAR Ch,
  AnsiCh : Char;
  Ansi   : Text;
Begin
  Assign(Ansi,'');
  ReWrite(Ansi);
  Repeat
     If Keypressed then
     Begin
       Ch := Readkey;
       If Ch <> Esc then
          ComWriteChar(Port,ch)
     End;
     If CharWaiting(Port) then
     Begin
        AnsiCh := ComReadChar(Port);
        If FossilPresent then
        Asm
          mov ah,13h
          mov al,ansich
          int 14h
        End else
        Write(Ansi,AnsiCh)          { no fossil driver }
     End
  Until Ch = Esc;
  Close(Ansi)
End;

Procedure ComWrite(Port : Word; Msg : String);
VAR Dummy, x,
    SegMsg,
    OfsMsg : Word;
    Ansich : Char;
    Ansi   : Text;
Begin
  Assign(Ansi,'');
  ReWrite(Ansi);
  Dummy := Ord(Msg[0]);             { length (msg) }
  If FossilPresent then
  Begin
    SegMsg := Seg(Msg);
    OfsMsg := Ofs(Msg) + 1;           { don't include length of msg }
    Asm                               { use fossil driver }
      mov ah,19h
      mov dx,port
      mov cx,dummy
      mov es,SegMsg
      mov di,OfsMsg
      int 14h
    End;
    While CharWaiting(Port) do
    Begin
      AnsiCh := ComReadChar(Port);
      Asm
        mov ah,13h
        mov al,ansich
        int 14h
      End
    End
  End else
  For x := 1 to dummy do
  Begin
    ComWriteChar(Port,Msg[x]);
    If CharWaiting(Port) then
      Write(Ansi,ComReadChar(Port))
  End;
  Close(Ansi)
End;

Procedure ComWriteln(Port : Word; Msg : String);
Begin
   Msg := Msg + #13 + #10;
   ComWrite(Port, Msg)
End;

Procedure Wait(Seconds : Word);
VAR Delay : Word;
Begin
   Delay := ((976 SHL 10) * Seconds) SHR 16;  { (976*1024*seconds)/65536 }
   Asm
     mov ah,86h
     mov cx,delay
     mov dx,0
     int 15h
   End
End;

Procedure GetCursor(VAR x, y : Byte);
VAR x1, y1 : Byte;
Begin
  If FossilPresent then
  Asm
    mov ah,12h
    int 14h
    mov x1,dl
    mov y1,dh
  End else
  Asm
    mov ah,03h
    mov bh,00h
    int 10h
    mov x1,dl
    mov y1,dh
  End;
  x := x1; y := y1
End;

Procedure SetCursor(Port : Word; x, y : Byte);
VAR x1,y1 : String;
Begin
  If FossilPresent then
  Asm
    mov ah,11h
    mov dh,y
    mov dl,x
    int 14h
  End else
  Asm
    mov ah,02h
    mov bh,00h
    mov dh,y
    mov dl,x
    int 10h
  End;
  If (CarrierDetected(port)) and (RemoteAnsiDetected(Port)) then
  Begin
    Str(x,x1);
    Str(y,y1);
    ComWrite(Port,' ['+y1+';'+x1+'H')     { ESC[y;xH }
  End
End;

Procedure SendBreak(Port : Word); Assembler;
Asm
  mov ah,1ah             {; start sending break }
  mov al,01h
  mov dx,port
  int 14h
  mov ah,86h             {; wait 1 second }
  mov cx,0fh
  mov dx,00h
  int 15h
  mov ah,1ah             {; stop sending break }
  mov al,00h
  mov dx,port
  int 14h
  mov ah,0ah             {; purge input buffer }
  mov dx,port
  int 14h
End;

Procedure ComReadln(Port : Word; VAR Msg : String; Count : Byte);
VAR WLength,
    SegMsg,
    OfsMsg : Word;
Begin
   SegMsg := Seg(Msg);
   OfsMsg := Ofs(Msg);
   WLength := Count;
   Asm
     mov ah,18h
     mov di,ofsmsg
     mov es,segmsg
     mov cx,wlength
     mov dx,port
     int 14h
   End;
End;

Procedure CLS(Port : Word);
Begin
  ClrScr;
  If CarrierDetected(Port) then
     If RemoteAnsiDetected(Port) then
        ComWrite(Port,' [2J') else
        ComWriteChar(Port,' ');
End;

Begin
   Writeln('Fossil Wizard v1.0 by Steve Connet - Jan. 19, 1993');
   Writeln('This is removed when you register.');
   Wait(2)
End.


(* This is an example of how to use Fossil Wizard *)

Uses FWizard, Crt;

VAR
         Ch : Char;
       Baud : Word;

Begin
  Baud := 2400;    { change this to the appropriate baud }
  ClrScr;

  SetCursor(Com2,50,19);
  If FossilPresent then
  Begin
    ActivatePort(Com2);                { wake up fossil driver }
    Write('[FOSSIL PRESENT]')
  End else
  Write('[FOSSIL NOT PRESENT]');

  SetCursor(Com2,50,20);
  If SetBaud(Com2,Baud,N81) then       { set baud rate }
     Write('[MODEM READY]') else
     Write('[MODEM NOT RESPONDING]');

  SetCursor(Com2,50,21);
  If CarrierDetected(Com2) then
     Write('[CARRIER DETECTED]') else
     Write('[NO CARRIER]');

  SetCursor(Com2,50,22);
  If (CarrierDetected(Com2)) and (RemoteAvatarDetected(Com2)) then
    Write('[REMOTE AVATAR DETECTED]') else
    Write('[REMOTE AVATAR NOT DETECTED]');

  SetCursor(Com2,50,23);
  If (CarrierDetected(Com2)) and (RemoteAnsiDetected(Com2)) then
    Write('[REMOTE ANSI DETECTED]') else
    Write('[REMOTE ANSI NOT DETECTED]');

  SetCursor(Com2,50,24);
  If LocalAnsiDetected then
     Write('[LOCAL ANSI DETECTED]') else
     Write('[LOCAL ANSI NOT DETECTED]');

  SetCursor(Com2,0,0);
  Chat(Com2);              { built in chat mode }
  DTR(Com2,Lower);         { lower data terminal ready }
  DeActivatePort(Com2);    { put fossil driver to sleep }
  ClrScr
End.

[Back to COMM SWAG index]  [Back to Main SWAG index]  [Original]