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

{
Your SWAG Collection is really good and should help programmers
enourmously. I myself have learned much from SWAG. Thanks to All!

Here is Attached one FOSSIL unit that implements almost all FOSSIL rev 5
functions in both real and protected mode. I have used it almost a year
now and the real mode operation should be free from bugs, but I added
DPMI support lately so there might be some errors. If someone finds an
error or would like to have some more information then I can be
contacted by e-mail at the following address : raul@reveko.estnet.ee
I have program which uses turbo vision and currently works with four com
ports active at the same time. I use BOCA Research Inc. multiport card
and X00 fossil driver because it supports IRQ Sharing. If I complete the
testing of my own async routines then I hope I will post it too If You
don't mind. Sorry for no documentation but all functions should easy to
understand.
  Thanks again.
  Raul Rebane.
}

UNIT COMFOSS;

{$C FIXED PRELOAD PERMANENT}

{$IFDEF WINDOWS}
  This Unit Cannot be compiled to windows
{$ENDIF}

INTERFACE

CONST
     CTS_RTS          = 2;   {FOSSIL RTS/CTS Flow control value }
     RECV_XON_XOFF    = 1;   {FOSSIL XOn/XOff on receive        }
     SEND_XON_XOFF    = 8;   {FOSSIL XOn/XOff on transmit       }
     XON_XOFF	      = 9;   {FOSSIL Full XOn/XOff flow Control }
     Flow_NONE        = 1;   {No Flow control CheckBox value    }
     Flow_XONXOFF     = 2;   {XOn/XOff Flow Control CheckBox    }
     Flow_RTSCTS      = 4;   {RTS/CTS Flow Control CheckBox     }
     Flow_All	      = 6;   {Both Flow Controls Checked        }

TYPE
{$IFDEF DPMI}
    RealModeRegs  = Record
     Case Integer Of
      0: ( EDI, ESI, EBP, EXX, EBX, EDX, ECX, EAX: Longint;
           Flags, ES, DS, FS, GS, IP, CS, SP, SS: Word) ;
      1: ( DI,DIH, SI, SIH, BP, BPH, XX, XXH: Word;
       Case Integer of
        0: (BX, BXH, DX, DXH, CX, CXH, AX, AXH: Word);
        1: (BL, BH, BLH, BHH, DL, DH, DLH, DHH,
            CL, CH, CLH, CHH, AL, AH, ALH, AHH: Byte));
     end;
{$ENDIF}

    HandTypes = (TERM, CDRM, MODM);

    ComSetupRec = record     {ComPort Setup dialog datarec which has next radiobuttons }
      Baud_Rate   : Word;    {Baud Rate index radiobutton value  }
      Data_Bits   : Word;    {Number Of DataBits radiobutton     }
      Stop_Bits   : Word;    {Number Of StopBits radiobutton     }
      Parity      : Word;    {Parity setting radiobutton         }
      FlowControl : Word;    {FlowControl CheckBox group         }
    end;

   PFOS_Record = ^FOS_Record;
   FOS_Record = Record
     StructSize : Word;         {FOSSIL information structure size in bytes }
     MajorVer   : Byte;         {Active FOSSIL's Major Version number       }
     MinVer     : Byte;         {Active FOSSIL's Minor Version number       }
     ID_String  : Pointer;      {Pointer to FOSSIL's ID String (PChar)      }
     InBufSize  : Word;         {Incoming Buffer Size in Bytes              }
     Rcvd_Free  : Word;         {Free Bytes in Incoming Buffer              }
     OutBufSize : Word;         {Outgoing Buffer Size in Bytes              }
     Send_Free  : Word;         {Free Bytes in Outgoing Buffer              }
     SWidth     : Byte;         {Screen Width in Characters                 }
     SHeight    : Byte;         {Screen Height in Characters                }
     BaudRate   : Byte          {Active BaudRate (Computer to Modem)        }
   End;

   PortInfo = Record
     Active    : Boolean;       {Is Port active                            }
     Carrier   : Boolean;       {Do we Have a Carrier                      }
     Handler   : Pointer;       {Port Handler (In My App points to Object) }
     HandType  : HandTypes;     {Handler Type                              }
     Baud      : LongInt;       {Current Port Settings                     }
     ComParams : ComSetupRec;   {Com Parameter record see above            }
     InfoRec   : FOS_Record;    {FOSSIL information record see above       }
   end;

Var
  ActivePorts : Array[1..4] of PortInfo;

Function  FOS_Install    (ComPort : Byte) : Boolean;
Procedure FOS_Close      (ComPort : Byte);
Procedure FOS_SetPort    (ComPort : Byte; COMSET : ComSetupRec);
Procedure FOS_GetPort	 (Comport : Byte);
Function  FOS_TxChar     (ComPort : Byte; Ch : Char) : Boolean;
Procedure FOS_TxStr      (ComPort : Byte; Str : String);
Function  FOS_RxChar     (ComPort : Byte) : Char;
Procedure FOS_RxStr      (ComPort : Byte; Var S : String);
Function  FOS_CharAvail  (ComPort : Byte) : Boolean;
Function  FOS_Carrier    (ComPort : Byte) : Boolean;
Procedure FOS_DTR        (ComPort : Byte; State : Boolean);
Function  Hangup         (Comport : Byte) : Boolean;
Procedure FOS_Timer      (Var Timer_Int, Ints_PerSec : Byte; VAR ms_PerTick : Integer);
Procedure FOS_Flush      (ComPort : Byte);
Procedure FOS_KillInBuf  (ComPort : Byte);
Procedure FOS_KillOutBuf (ComPort : Byte);
Function  FOS_TxNoWait   (ComPort : Byte; Ch : Char) : Boolean;
Function  FOS_Peek       (ComPort : Byte) : Char;
Function  FOS_PeekKey    : Word;
Function  FOS_KeyPressed : Boolean;
Function  FOS_WaitKey    : Word;
Procedure FOS_FLOW       (ComPort, State : Byte);
Procedure Set_CtrlC      (ComPort, State : Byte);
Function  CtrlC_Check    (ComPort : Byte) : Boolean;
Procedure FOS_GotoXY     (X,Y : Byte);
Procedure FOS_Position   (Var X,Y : Byte);
Function  FOS_WhereX     : Byte;
Function  FOS_WhereY     : Byte;
Procedure ANSI_Write     (Ch : Char);
Procedure WatchDog       (ComPort : Byte; Status : Boolean);
Procedure BIOS_Write     (Ch : Char);
{$IFDEF DPMI}
{$ELSE}

{These functions can be implemented too under DPMI using realmode callback
 services. DPMI function 0303h

  AX = 0303H
  DS:SI = Selector:Offset Of Your procedure/Function to call
  ES:DI = Selector:Offset Of real mode call structure

 This function returns

  Carry Flag clear if successful
  CX:DX = Segment:Offset Of realmode call address

 Now You Have the realmode address for realmode app to link with Your code

 When Your code gets called You Have the following:

  DS:SI = Selector:Offset Of real mode SS:SP
  ES:DI = Selector:Offset of real mode Call structure
  SS:SP = Locked protected mode API stack
  other registers undefined

 On return from Your code:

  Set ES:DI = Selector:Offset of real mode call structure to restore
  Execute an IRET instruction
}

Function  FOS_AddProc    (Var P) : Boolean;
Function  FOS_DelProc    (Var P) : Boolean;
{$ENDIF}

Procedure Boot		 (Method : Boolean);
Function  FOS_BlockRead  (ComPort : Byte; Bytes : Word; Var Buffer) : Word;
Function  FOS_BlockWrite (ComPort : Byte; Bytes : Word; Var Buffer) : Word;
Function  FOS_Info	 (ComPort : Byte) : Boolean;
Function  FOS_InFree     (ComPort : Byte; Free : Word) : Boolean;
Function  FOS_OutFree	 (ComPort : Byte; Free : Word) : Boolean;
Function  FOS_Ringing    (ComPort : Byte) : Boolean;

{This Function returns for You pointer to COMPORT Parameters DIALOG

Usage example:

Function SetPortParameters(ComPort) : Boolean;
Var
  P : PDIALOG
  Ch : Char;
  DlgResult : Word;
begin
 Ch := Char(ComPort + 48);
 IF ActivePorts[ComPort].Active then
  begin
    ParamDlg := CommSettings('COM' + Ch + ' Parameters');
    IF ValidView(ParamDlg) <> NIL then
     begin
       ParamDlg^.SetData(ActivePorts[ComPort].ComParams);
       DlgResult := DeskTop^.ExecView(ParamDlg);
       IF DlgResult = cmOk then
	begin
	  IF LogAct then
           begin
	     Writeln(LOGFILE, Clock^.DateStr + ' ' + CLock^.TimeStr + ' COM',
                              Char(ComPort + 48), ' parameters changed');
             Flush(LOGFILE);
           end;
	  ParamDlg^.GetData(ActivePorts[ComPort].ComParams);
	  FOS_SetPort(ComPort, ActivePorts[ComPort].ComParams);
	  Case ActivePorts[ComPort].ComParams.FlowControl of
	    Flow_None : FOS_Flow(ComPort, 0);
	    Flow_XONXOFF : FOS_Flow(ComPort, RECV_XON_XOFF OR SEND_XON_XOFF);
	    Flow_RTSCTS : FOS_Flow(ComPort, CTS_RTS);
	    Flow_All : FOS_Flow(ComPort, 11);
	  else
	   FOS_Flow(ComPort, 0); If user selected all or none CheckBoxes
	  end;
         FOS_TxStr(ComPort, 'AT'); Send AT for framing modem
	end;
       Dispose(ParamDlg, Done);
     end;
   end
  else
   MessageBox(^C'Port not active.' + #13#13 + ^C'Unable to change parameters', NIL, mfError or mfOkButton);
  SetPortParameters := DlgResult = cmOk;
end;

{Function CommSettings   (Str : String) : PDIALOG;}

IMPLEMENTATION

{$IFDEF DPMI}
USES OBJECTS, CRT, WINAPI;
{$ELSE}
USES OBJECTS, CRT, DOS;
{$ENDIF}

VAR
{$IFDEF DPMI}
  REGS : RealModeRegs;
  BuffSeg  : Word;
  PMBuffer : Pointer;
  Temp_Selector : Word;
{$ELSE}
  REGS : Registers;
{$ENDIF}
  SavedExitProc : Pointer;

{$IFDEF DPMI}
Function RealModeInt(IntNo : Byte; Var RealRegs : RealModeRegs) : Boolean;assembler;
asm
  MOV AX, 0300h
  MOV BL, [IntNo]
  XOR BH, BH
  XOR CX, CX
  LES DI, [RealRegs]
  INT 31h
  JC  @Error
  MOV AX, 1
  JMP @Exit
@Error:
  MOV AX, 0
@Exit:
end;

Function SetSelector(Var Selector : Word; Base, Limit : LongInt) : Boolean;
begin
  If (Selector <> 0) AND (SetSelectorBase( Selector, Base) = Selector) AND
     (SetSelectorLimit(Selector, Limit) = 0) then
   SetSelector:= True
  else
   SetSelector := False;
end;

Function AllocateLowMem(Size : Word; var PMPointer : Pointer ) : Word;
Var
 TempAddr : LongInt;
begin
  TempAddr := GlobalDOSAlloc(Size) ;
  If TempAddr = 0 then RunError(0);
  PMPointer := Ptr(LongRec(TempAddr).Lo, 0);
  AllocateLowMem := LongRec(TempAddr).Hi;
end ;

Procedure FreeLowMem(Var PMPointer : Pointer ) ;
begin
  GlobalDOSFree( Seg(PMPointer^));
  PMPointer := nil;
end;
{$ENDIF}

Function FOS_Install (ComPort:Byte) : Boolean;
Begin
  REGS.AH := $04;
  REGS.CX := 0;
  REGS.DX := ComPort - 1;
  REGS.BX := $4F50;
{$IFDEF DPMI}
  RealModeInt($14, REGS);
{$ELSE}
  Intr($14, REGS);
{$ENDIF}
  FOS_Install := REGS.AX = $1954;
  ActivePorts[Comport].Active := REGS.AX = $1954;
End;

Procedure FOS_Close(ComPort : Byte);
Begin
  REGS.AH := $05;
  REGS.DX := ComPort - 1;
{$IFDEF DPMI}
  RealModeInt($14, REGS);
{$ELSE}
  Intr($14, REGS);
{$ENDIF}
  ActivePorts[ComPort].Active := False;
End;

Procedure FOS_SetPort(ComPort : Byte; COMSET : ComSetupRec);
Var
   Setting : Byte;   { 1 1 1 1 1 1 1 1 }
Begin
  With COMSET do
   begin
     Case COMSET.Baud_Rate of
       0 : Setting := 224; 		{Default speed 9600}
       1 : Setting := 128; 		{1200		   }
       2 : Setting := 160; 		{2400		   }
       3 : Setting := 192; 		{4800		   }
       4 : Setting := 224; 		{9600		   }
       5 : Setting := 0;    		{19200  	   }
       6 : Setting := 32;     		{S38400		   }
     End;
     Case Data_Bits of
{       0 : Setting := Setting + 1; 	{6 Data}
       0 : Setting := Setting + 2; 	{7 Data}
       1 : Setting := Setting + 3  	{8 Data}
     End;
     Case Parity of
       0 : Setting := Setting + 0;      {No Parity}
       1 : Setting := Setting + 8;      {Odd Parity}
       2 : Setting := Setting + 24      {Even Parity}
     End;
     Case Stop_Bits of
       0 : Setting := Setting + 0;	{1 Stop}
       1 : Setting := Setting + 4	{2 Stop}
     End;
   End;
  REGS.AH := 0;
  REGS.AL := Setting;
  REGS.DX := ComPort - 1;
{$IFDEF DPMI}
  RealModeInt($14, REGS);
{$ELSE}
  Intr($14, REGS);
{$ENDIF}
End;

Procedure FOS_GetPort(ComPort : Byte);
Var
 Setting : Byte;
begin
  Setting := ActivePorts[ComPort].InfoRec.BaudRate;
  With ActivePorts[ComPort].ComParams do
   begin
     Case Setting AND $E0 Of
       224 : Baud_Rate := 0; 		{Default speed 9600}
       128 : Baud_Rate := 1; 		{1200		   }
       160 : Baud_Rate := 2; 		{2400		   }
       192 : Baud_Rate := 3; 		{4800		   }
	 0 : Baud_Rate := 5;    	{19200  	   }
	32 : Baud_Rate := 6;     	{S38400		   }
     end;
     Case Setting AND $3 of
       0 : Data_Bits := 2;	 	{6 Data}
       2 : Data_Bits := 0; 		{7 Data}
       3 : Data_Bits := 1;	  	{8 Data}
     End;
     Case Setting AND $18 of
       0 : Parity := 0;      		{No Parity}
       8 : Parity := 1;      		{Odd Parity}
      24 : Parity := 2;      		{Even Parity}
     End;
     Case Setting AND $4 of
       0 : Stop_Bits := 0;		{1 Stop}
       4 : Stop_Bits := 1;		{2 Stop}
     End;
   end;
end;

Function FOS_Ringing(ComPort : Byte) : Boolean;
var
  TempCh : Char;
begin
  FOS_Ringing := False;
  REGS.AH := $0C;
  REGS.DX := ComPort - 1;
{$IFDEF DPMI}
  RealModeInt($14, REGS);
{$ELSE}
  Intr($14, REGS);
{$ENDIF}
  If REGS.AX = $FFFF Then
   FOS_Ringing := False
  else
   begin
     TempCh := Chr(REGS.AL);
     if TempCh = #13 then
      FOS_Ringing := true;
   end;
end;

Function FOS_TxChar(ComPort : Byte; Ch : Char) : Boolean;
Begin
  REGS.AH := $01;
  REGS.AL := Ord(Ch);
  REGS.DX := ComPort - 1;
{$IFDEF DPMI}
  RealModeInt($14, REGS);
{$ELSE}
  Intr($14, REGS);
{$ENDIF}
  FOS_TxChar := (REGS.AH AND $80) = $80;
End;

Procedure FOS_TxStr(ComPort : Byte; Str : String);
Var
 I:Integer;
 S : String;

Begin
  S:= Str + #13#10;
  If FOS_OutFree(ComPort, Length(S)) then
  I:=FOS_BlockWrite(ComPort, Length(S), S[1])
End;

Function FOS_RxChar(ComPort : Byte) : Char;
Begin
  REGS.AH := $02;
  REGS.DX := ComPort - 1;
{$IFDEF DPMI}
  RealModeInt($14, REGS);
{$ELSE}
  Intr($14, REGS);
{$ENDIF}
  If (REGS.AH AND $80) = $80 then
   FOS_RxChar := #0
  else
   FOS_RxChar := Chr(REGS.AL)
End;

Procedure FOS_RxStr(ComPort : Byte; Var S : String);
Var
  Ch : Char;
  Count : Byte;
begin
  Count := 1;                             {Current_Pos = 1                }
  While FOS_CharAvail(ComPort) do         {While Chars available do       }
   begin
     If FOS_Peek(ComPort) <> #10 then     {If NextChar = LineFeed then    }
      begin
        S[Count] := FOS_RxChar(ComPort);  {String[Current_Pos] = NextChar }
        IF S[Count] <> #00 then           {Ignore NULL Chars              }
         Inc(Count);                      {Increment Current_Pos          }
        IF Count = 255 then               {If Current_Pos = Maxlen(String)}
         begin
           S[0] := #255;                  {Return MaxLen String           }
           Break;
         end;
      end;
   end;
end;

Function FOS_CharAvail(ComPort : Byte) : Boolean;
Begin
  REGS.AH := $03;
  REGS.DX := ComPort - 1;
{$IFDEF DPMI}
  RealModeInt($14, REGS);
{$ELSE}
  Intr($14, REGS);
{$ENDIF}
  FOS_CharAvail := (REGS.AH And 1) = 1
End;

Function FOS_Carrier(ComPort : Byte) : Boolean;
Begin
  REGS.AH := $03;
  REGS.DX := ComPort - 1;
{$IFDEF DPMI}
  RealModeInt($14, REGS);
{$ELSE}
  Intr($14, REGS);
{$ENDIF}
  FOS_Carrier := (REGS.AL And 128) = 128
End;

Procedure FOS_DTR (ComPort : Byte; State : Boolean);
Begin
  REGS.AH := $06;
  REGS.AL := Byte(State);
  REGS.DX := ComPort - 1;
{$IFDEF DPMI}
  RealModeInt($14, REGS);
{$ELSE}
  Intr($14, REGS)
{$ENDIF}
End;

Function Hangup(ComPort : Byte) : Boolean;
Begin
  HangUp := False;
  If Not FOS_Carrier(ComPort) Then
   HangUp := True
  else
   begin
     FOS_DTR (ComPort,False);
     Delay (1000);
     FOS_DTR (ComPort,True);
     If FOS_Carrier(ComPort) Then
      Begin
	FOS_TxStr(ComPort, '+++');
	Delay (1000);
	FOS_TxStr(ComPort, 'ATH0'+ #10#13);
	Delay(1000);
      end
     else
      HangUp := True;
   end;
  If Not FOS_Carrier(ComPort) Then
   HangUp := True
End;

Procedure FOS_Timer(Var Timer_Int, Ints_PerSec : Byte; VAR ms_PerTick : Integer);
Begin
  REGS.AH := $07;
{$IFDEF DPMI}
  RealModeInt($14, REGS);
{$ELSE}
  Intr($14, REGS);
{$ENDIF}
  Timer_Int := REGS.AL;
  Ints_PerSec := REGS.AH;
  ms_PerTick  := REGS.DX
End;

Procedure FOS_Flush(ComPort:Byte);
Begin
  REGS.AH := $08;
  REGS.DX := ComPort - 1;
{$IFDEF DPMI}
  RealModeInt($14, REGS);
{$ELSE}
  Intr($14, REGS)
{$ENDIF}
End;

Procedure FOS_KillOutBuf(ComPort:Byte);
Begin                                   { Purges the OutPut Buffer   }
  REGS.AH := $09;
  REGS.DX := ComPort - 1;
{$IFDEF DPMI}
  RealModeInt($14, REGS);
{$ELSE}
  Intr($14, REGS)
{$ENDIF}
End;

Procedure FOS_KillInBuf(ComPort:Byte);
Begin                                   { Purges the Input Buffer    }
  REGS.AH := $0A;
  REGS.DX := ComPort - 1;
{$IFDEF DPMI}
  RealModeInt($14, REGS);
{$ELSE}
  Intr($14, REGS)
{$ENDIF}
End;

Function FOS_TxNoWait(ComPort : Byte; Ch : Char) : Boolean;
Begin
  REGS.AH := $0B;
  REGS.AL := Ord(Ch);
  REGS.DX := ComPort - 1;
{$IFDEF DPMI}
  RealModeInt($14, REGS);
{$ELSE}
  Intr($14, REGS);
{$ENDIF}
  FOS_TxNoWait := (REGS.AH AND $80) = $80;
End;

Function FOS_Peek(ComPort : Byte) : Char;
Begin
  REGS.AH := $0C;
  REGS.DX := ComPort - 1;
{$IFDEF DPMI}
  RealModeInt($14, REGS);
{$ELSE}
  Intr($14, REGS);
{$ENDIF}
  FOS_Peek := Chr(REGS.AL)
End;

Function FOS_PeekKey : Word;
Begin
  REGS.AH := $0D;
{$IFDEF DPMI}
  RealModeInt($14, REGS);
{$ELSE}
  Intr($14, REGS);
{$ENDIF}
  FOS_PeekKey := REGS.AX
End;

Function FOS_KeyPressed : Boolean;
Begin
  REGS.AH := $0D;
{$IFDEF DPMI}
  RealModeInt($14, REGS);
{$ELSE}
  Intr($14, REGS);
{$ENDIF}
  FOS_KeyPressed := (REGS.AX <> $FFFF);
End;

Function FOS_WaitKey : Word;
Begin
  REGS.AH := $0E;
{$IFDEF DPMI}
  RealModeInt($14, REGS);
{$ELSE}
  Intr($14, REGS);
{$ENDIF}
  FOS_WaitKey := REGS.AX
End;

Procedure FOS_FLOW(ComPort, State : Byte);
Begin
  REGS.AH := $0F;
  REGS.AL := State + $F0;
  REGS.DX := ComPort - 1;
{$IFDEF DPMI}
  RealModeInt($14, REGS);
{$ELSE}
  Intr($14, REGS)
{$ENDIF}
End;

Procedure Set_CtrlC (ComPort, State : Byte);
Begin
  REGS.AH := $10;
  REGS.AL := State;
  REGS.DX := ComPort - 1;
{$IFDEF DPMI}
  RealModeInt($14, REGS);
{$ELSE}
  Intr($14, REGS)
{$ENDIF}
End;

Function CtrlC_Check(ComPort : Byte) : Boolean;
Begin
  REGS.AH := $10;
  REGS.AL := 2;
  REGS.DX := ComPort - 1;
{$IFDEF DPMI}
  RealModeInt($14, REGS);
{$ELSE}
  Intr($14, REGS);
{$ENDIF}
  CtrlC_Check := Boolean(REGS.AX)
End;

Procedure FOS_GotoXY(X, Y : Byte);
Begin
  REGS.AH := $11;
  REGS.DH := Y - 1;
  REGS.DL := X - 1;
{$IFDEF DPMI}
  RealModeInt($14, REGS);
{$ELSE}
  Intr($14, REGS)
{$ENDIF}
End;

Procedure FOS_Position (Var X,Y:Byte);
Begin
  REGS.AH := $12;
{$IFDEF DPMI}
  RealModeInt($14, REGS);
{$ELSE}
  Intr($14, REGS);
{$ENDIF}
  X := REGS.DL + 1;
  Y := REGS.DH + 1
End;

Function FOS_WhereX : Byte;
Begin
  REGS.AH := $12;
{$IFDEF DPMI}
  RealModeInt($14, REGS);
{$ELSE}
  Intr($14, REGS);
{$ENDIF}
  FOS_WhereX := REGS.DL + 1
End;

Function FOS_WhereY : Byte;
Begin
  REGS.AH := $12;
{$IFDEF DPMI}
  RealModeInt($14, REGS);
{$ELSE}
  Intr($14, REGS);
{$ENDIF}
  FOS_WhereY := REGS.DH + 1
End;

Procedure ANSI_Write(Ch : Char);
Begin
  REGS.AH := $13;
  REGS.AL := Ord(Ch);
{$IFDEF DPMI}
  RealModeInt($14, REGS);
{$ELSE}
  Intr($14, REGS)
{$ENDIF}
End;

Procedure WatchDog(ComPort : Byte; Status : Boolean);
Begin
  REGS.AH := $14;
  REGS.AL := Byte(Status);
  REGS.DX := ComPort - 1;
{$IFDEF DPMI}
  RealModeInt($14, REGS);
{$ELSE}
  Intr($14, REGS)
{$ENDIF}
End;

Procedure BIOS_Write(Ch : Char);
Begin
  REGS.AH := $15;
  REGS.AL := Ord(Ch);
{$IFDEF DPMI}
  RealModeInt($14, REGS);
{$ELSE}
  Intr($14, REGS)
{$ENDIF}
End;

{$IFDEF DPMI}
{$ELSE}
Function FOS_AddProc(Var P) : Boolean;
Begin
  REGS.AH := $16;
  REGS.AL := $01;
  REGS.ES := Seg(P);
  REGS.DX := Ofs(P);
  Intr($14, REGS);
  FOS_AddProc := REGS.AX = 0
End;
{$ENDIF}

{$IFDEF DPMI}
{$ELSE}
Function FOS_DelProc(Var P) : Boolean;
Begin
  REGS.AH := $16;
  REGS.AL := $00;
  REGS.ES := Seg (P);
  REGS.DX := Ofs (P);
  Intr($14, REGS);
  FOS_DelProc := REGS.AX = 0
End;
{$ENDIF}

Procedure Boot(Method : Boolean);
Begin
  REGS.AH := $17;
  REGS.AL := Byte(Method); 		{Cold, Warm}
{$IFDEF DPMI}
  RealModeInt($14, REGS);
{$ELSE}
  Intr($14, REGS)
{$ENDIF}
End;

Function FOS_BlockRead(ComPort : Byte; Bytes : Word; Var Buffer) : Word;
Begin
  REGS.AH := $18;
  REGS.DX := ComPort - 1;
  REGS.CX := Bytes;
{$IFDEF DPMI}
  REGS.DI := 0;
  REGS.ES := BuffSeg;
  RealModeInt($14, REGS);
  Move(PMBuffer^, Buffer, REGS.AX);
{$ELSE}
  REGS.ES := Seg(Buffer);
  REGS.DI := Ofs(Buffer);
  Intr($14, REGS);
{$ENDIF}
  FOS_BlockRead := REGS.AX
End;

Function FOS_BlockWrite(ComPort : Byte; Bytes : Word; Var Buffer) : Word;
Begin
  REGS.AH := $19;
  REGS.DX := ComPort - 1;
  REGS.CX := Bytes;
{$IFDEF DPMI}
  Move(Buffer, PMBuffer^, Bytes);
  REGS.DI := 0;
  REGS.ES := BuffSeg;
  RealModeInt($14, REGS);
{$ELSE}
  REGS.ES := Seg (Buffer);
  REGS.DI := Ofs (Buffer);
  Intr($14, REGS);
{$ENDIF}
  FOS_BlockWrite := REGS.AX
End;

Function FOS_Info(ComPort : Byte) : Boolean;
begin
  REGS.AH := $1B;
  REGS.DX := ComPort - 1;
  REGS.CX := SizeOf(ActivePorts[ComPort].InfoRec);
{$IFDEF DPMI}
  REGS.DI := 0;
  REGS.ES := BuffSeg;
  RealModeInt($14, REGS);
  If NOT SetSelector(Temp_Selector, PtrRec(PFOS_Record(PMBuffer)^.ID_String).Seg*LongInt(16),
                           PtrRec(PFOS_Record(PMBuffer)^.ID_String).Ofs + 256) then
   PFOS_Record(PMBuffer)^.ID_String := Nil
  else
   PtrRec(PFOS_Record(PMBuffer)^.ID_String).Seg := Temp_Selector;
  Move(PMBuffer^, ActivePorts[ComPort].InfoRec, SizeOf(FOS_Record));
{$ELSE}
  REGS.ES := Seg(ActivePorts[ComPort].InfoRec);
  REGS.DI := Ofs(ActivePorts[ComPort].InfoRec);
  Intr($14, REGS);
{$ENDIF}
  If (ActivePorts[ComPort].InfoRec.Rcvd_Free) <=
     (ActivePorts[ComPort].InfoRec.InBufSize) then
   FOS_Info := True
  else
   FOS_Info := False;
end;

Function FOS_InFree(ComPort : Byte; Free : Word) : Boolean;
begin
  REGS.AH := $1B;
  REGS.DX := ComPort - 1;
  REGS.CX := SizeOf(ActivePorts[ComPort].InfoRec);
{$IFDEF DPMI}
  REGS.DI := 0;
  REGS.ES := BuffSeg;
  RealModeInt($14, REGS);
  If PFOS_Record(PMBuffer)^.Rcvd_Free > Free then
   FOS_InFree := True
  else
   FOS_InFree := False;
{$ELSE}
  REGS.ES := Seg(ActivePorts[ComPort].InfoRec);
  REGS.DI := Ofs(ActivePorts[ComPort].InfoRec);
  Intr($14, REGS);
  If (ActivePorts[ComPort].InfoRec.Rcvd_Free) > Free then
   FOS_InFree := True
  else
   FOS_InFree := False;
{$ENDIF}
end;

Function FOS_OutFree(ComPort : Byte; Free : Word) : Boolean;
begin
  REGS.AH := $1B;
  REGS.DX := ComPort - 1;
  REGS.CX := SizeOf(ActivePorts[ComPort].InfoRec);
{$IFDEF DPMI}
  REGS.DI := 0;
  REGS.ES := BuffSeg;
  RealModeInt($14, REGS);
  If PFOS_Record(PMBuffer)^.Send_Free > Free then
   FOS_OutFree := True
  else
   FOS_OutFree := False;
{$ELSE}
  REGS.ES := Seg(ActivePorts[ComPort].InfoRec);
  REGS.DI := Ofs(ActivePorts[ComPort].InfoRec);
  Intr($14, REGS);
  If (ActivePorts[ComPort].InfoRec.Send_Free) >= Free then
   FOS_OutFree := True
  else
   FOS_OutFree := False;
{$ENDIF}
end;

procedure CustomExit; FAR;
Var
 Counter : Byte;
begin
  ExitProc := SavedExitProc;
  For Counter := 1 to 4 do
   If ActivePorts[Counter].Active then
    FOS_Close(Counter);
{$IFDEF DPMI}
  FreeLowMem(PMBuffer);
{$ENDIF}
end;

{FUNCTION CommSettings(Str : String) : PDialog;
var
  DlgWin : PDialog;
  R : TRect;
  Control, Labl, Histry : PView;
Begin
R.Assign(18,2,58,18);
New(DlgWin, Init(R, Str));

R.Assign(3,2,17,9);
Control := New(PRadioButtons, Init(R,
  NewSItem('~H~ardware',
  NewSItem('~1~200',
  NewSItem('~2~400',
  NewSItem('~4~800',
  NewSItem('9~6~00',
  NewSItem('1~9~200',
  NewSItem('3~8~400',Nil)))))))));
Control^.HelpCtx := hcSelBaudRate;
DlgWin^.Insert(Control);

  R.Assign(3,1,14,2);
  Labl := New(PLabel, Init(R, '~B~aud Rate ', Control));
  DlgWin^.Insert(Labl);

R.Assign(20,2,27,4);
Control := New(PRadioButtons, Init(R,
  NewSItem('7',
  NewSItem('8',Nil))));
Control^.HelpCtx := hcSelDataBits;
DlgWin^.Insert(Control);

  R.Assign(20,1,26,2);
  Labl := New(PLabel, Init(R, '~D~ata ', Control));
  DlgWin^.Insert(Labl);

R.Assign(30,2,37,4);
Control := New(PRadioButtons, Init(R,
  NewSItem('1',
  NewSItem('2',Nil))));
Control^.HelpCtx := hcSelStopBits;
DlgWin^.Insert(Control);

  R.Assign(30,1,36,2);
  Labl := New(PLabel, Init(R, '~S~top ', Control));
  DlgWin^.Insert(Labl);

R.Assign(20,6,30,9);
Control := New(PRadioButtons, Init(R,
  NewSItem('~N~one',
  NewSItem('~O~dd',
  NewSItem('~E~ven',Nil)))));
Control^.HelpCtx := hcSelParity;
DlgWin^.Insert(Control);

  R.Assign(20,5,28,6);
  Labl := New(PLabel, Init(R, '~P~arity ', Control));
  DlgWin^.Insert(Labl);

R.Assign(3,11,21,14);
Control := New(PCheckboxes, Init(R,
  NewSItem('None',
  NewSItem('~X~ON/XOFF',
  NewSItem('~R~TS/CTS',Nil)))));
Control^.HelpCtx := hcSelFlowControl;
DlgWin^.Insert(Control);

  R.Assign(3,10,17,11);
  Labl := New(PLabel, Init(R, '~F~low Control ', Control));
  DlgWin^.Insert(Labl);

R.Assign(23,11,37,13);
Control := New(PButton, Init(R, 'Ok', cmOK, bfDefault));
DlgWin^.Insert(Control);

R.Assign(23,13,37,15);
Control := New(PButton, Init(R, 'Cancel', cmCancel, bfNormal));
DlgWin^.Insert(Control);

R.Assign(2,1,3,9);
Control := New(PStaticText, Init(R, 'Ú³³³³³³³'));
DlgWin^.Insert(Control);

R.Assign(2,9,18,10);
Control := New(PStaticText, Init(R, 'ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ'));
DlgWin^.Insert(Control);

R.Assign(17,2,18,9);
Control := New(PStaticText, Init(R, '³³³³³³³'));
DlgWin^.Insert(Control);

R.Assign(19,4,28,5);
Control := New(PStaticText, Init(R, 'ÀÄÄÄÄÄÄÄÙ'));
DlgWin^.Insert(Control);

R.Assign(29,4,38,5);
Control := New(PStaticText, Init(R, 'ÀÄÄÄÄÄÄÄÙ'));
DlgWin^.Insert(Control);

R.Assign(27,2,28,4);
Control := New(PStaticText, Init(R, '³³'));
DlgWin^.Insert(Control);

R.Assign(37,2,38,4);
Control := New(PStaticText, Init(R, '³³'));
DlgWin^.Insert(Control);

R.Assign(19,1,20,4);
Control := New(PStaticText, Init(R, 'Ú³³'));
DlgWin^.Insert(Control);

R.Assign(29,1,30,4);
Control := New(PStaticText, Init(R, 'Ú³³'));
DlgWin^.Insert(Control);

R.Assign(19,9,31,10);
Control := New(PStaticText, Init(R, 'ÀÄÄÄÄÄÄÄÄÄÄÙ'));
DlgWin^.Insert(Control);

R.Assign(19,5,20,9);
Control := New(PStaticText, Init(R, 'Ú³³³'));
DlgWin^.Insert(Control);

R.Assign(30,6,31,9);
Control := New(PStaticText, Init(R, '³³³'));
DlgWin^.Insert(Control);

R.Assign(2,14,22,15);
Control := New(PStaticText, Init(R, 'ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ'));
DlgWin^.Insert(Control);

R.Assign(21,11,22,14);
Control := New(PStaticText, Init(R, '³³³'));
DlgWin^.Insert(Control);

R.Assign(2,10,3,14);
Control := New(PStaticText, Init(R, 'Ú³³³'));
DlgWin^.Insert(Control);

R.Assign(14,1,18,2);
Control := New(PStaticText, Init(R, 'ÄÄÄ¿'));
DlgWin^.Insert(Control);

R.Assign(26,1,28,2);
Control := New(PStaticText, Init(R, 'Ä¿'));
DlgWin^.Insert(Control);

R.Assign(36,1,38,2);
Control := New(PStaticText, Init(R, 'Ä¿'));
DlgWin^.Insert(Control);

R.Assign(17,10,22,11);
Control := New(PStaticText, Init(R, 'ÄÄÄÄ¿'));
DlgWin^.Insert(Control);

R.Assign(28,5,31,6);
Control := New(PStaticText, Init(R, 'ÄÄ¿'));
DlgWin^.Insert(Control);

DlgWin^.SelectNext(False);
CommSettings := DlgWin;
end;}


Begin
  {$IFDEF DPMI}
     BuffSeg := AllocateLowMem(1024, PMBuffer);
     Temp_Selector := AllocSelector(0);
     FillChar(ActivePorts, SizeOf(ActivePorts), #00);
  {$ELSE}
     FillChar(ActivePorts, SizeOf(ActivePorts), #00);
  {$ENDIF}
  SavedExitProc := ExitProc;
  ExitProc := @CustomExit;
end.



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