{ 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.