Unit Modem; {$O+,F+} InterFace uses dos; const crlf:string[2] = #13+#10; type pDriverInfo = ^DriverInfo; DriverInfo = record Size : Word; Spec : byte; Rev : Byte; ID : String; Ibuf : Word; Iavl : Word; OBuf : Word; Oavl : Word; Width : Byte; Height: Byte; Baud : Byte; end; Type pModemObj = ^ModemObj; ModemObj = object Function Init(c:byte):boolean; Procedure Close; Function Spec:byte; Function Rev :byte; Function ID :String; Function InputBuf : word; Function OutputBuf: word; Function DTEBaud: word; Function OutBufUsed: word; Function InBufUsed: word; Procedure SetParams(baud_:word; DataBits:byte; Parity:char; StopBit:byte); Procedure SetDtr(state:boolean); Procedure SetFlow(state:boolean); Function CD:boolean; Procedure KillOut; Procedure KillIn; Procedure Flush; Function Available:boolean; Function OkToSend:boolean; Function Empty:boolean; Procedure WriteChar(c:char); Procedure Write(s:string); Procedure Writeln(s:string); Function Readkey:char; Function HangUp:boolean; Function ATCommand(command:string):boolean; Function PeekAhead:char; Procedure Snarf(n:word); Procedure ReadBlock(var s:string;reqnum,maxnum:byte); Private ComPortVal: byte; DriverInfo: pDriverInfo; Procedure SetComPort(c:byte); Function ComPort:byte; Procedure GetInfo; end; IMPLEMENTATION uses Crt; { needed for Delay() } Procedure ModemObj.GetInfo; type DvrInfo = Record Size : Word; Spec : byte; Rev : Byte; ID : Pointer; Ibuf : Word; Iavl : Word; OBuf : Word; Oavl : Word; Width : Byte; Height: Byte; Baud : Byte; End; var regs:registers; di: dvrinfo; ts: string; Begin fillchar(regs,sizeof(regs),0); Regs.Cx := Sizeof(di); Regs.Es := Seg(di); Regs.Di := Ofs(di); Regs.Dx := comport-1; Regs.ah := $1B; Intr($14,Regs); DriverInfo^.Size := di.size; DriverInfo^.spec := di.spec; DriverInfo^.rev := di.rev; DriverInfo^.ibuf := di.ibuf; DriverInfo^.iavl := di.iavl; DriverInfo^.obuf := di.obuf; DriverInfo^.oavl := di.oavl; DriverInfo^.width := di.width; DriverInfo^.height := di.height; DriverInfo^.baud := di.baud; move ( di.id^, mem[seg(ts):ofs(ts)+1], sizeof(ts)-1); ts[0]:=#255; ts[0]:=char(pos(#0,ts)-1); DriverInfo^.id:=ts; End; Function ModemObj.Spec:byte; begin Spec := DriverInfo^.Spec; end; Function ModemObj.Rev :byte; begin Rev:=DriverInfo^.Rev; end; Function ModemObj.ID :String; begin ID:=DriverInfo^.id; end; Function ModemObj.InputBuf : word; begin InputBuf := DriverInfo^.IBuf; end; Function ModemObj.OutputBuf: word; begin OutputBuf := DriverInfo^.OBuf; end; { 010 = 300 baud 011 = 600 '' 100 = 1200 '' 101 = 2400 '' 110 = 4800 '' 111 = 9600 '' 000 = 19200 '' (Replaces old 110 baud mask) 001 = 38400 '' (Replaces old 150 baud mask) } Function ModemObj.DTEBaud: word; begin case driverinfo^.baud of 0: dtebaud := 19200; 1: dtebaud := 38400; 2: dtebaud := 300; 3: dtebaud := 600; 4: dtebaud := 1200; 5: dtebaud := 2400; 6: dtebaud := 4800; 7: dtebaud := 9600; else dtebaud := 0; end; end; Function ModemObj.OutBufUsed:word; begin GetInfo; OutBufUsed := DriverInfo^.OAvl; end; Function ModemObj.InBufUsed:word; begin GetInfo; InBufUsed := DriverInfo^.IAvl; end; function ModemObj.PeekAhead:char; var regs:registers; begin fillchar(regs,sizeof(regs),0); with regs do begin ah:=$0C; dx:=comport-1; end; Intr($14, regs); if regs.ax=$ffff then PeekAhead:=#0 else PeekAhead:=char(regs.al); end; Procedure ModemObj.SetComPort(c:byte); begin ComPortVal:=c; end; Function ModemObj.ComPort:byte; begin; ComPort:=ComPortVal; end; Function ModemObj.Init(c: Byte):boolean; var regs:registers; Begin ModemObj.SetComPort(c); FillChar(regs,sizeof(regs),0); With Regs Do Begin AH := 4; DX := (ComPort-1); end; Intr($14, Regs); if (regs.AX=$1954) then begin Init:=True; New(DriverInfo); GetInfo; end else Init:=False; end; Procedure ModemObj.Close; var regs:registers; Begin FillChar(regs,sizeof(regs),0); {a setdtr(false) used to be here} With Regs Do Begin AH := 5; DX := (ComPort-1); Intr($14, Regs); end; dispose(Driverinfo); end; { | AH = 18h Read block (transfer from FOSSIL to user buffer) | Parameters: | Entry: CX = Maximum number of characters to transfer | DX = Port number | ES = Segment of user buffer | DI = Offset into ES of user buffer | Exit: AX = Number of characters actually transferred | A "no-wait" block read of 0 to FFFFh characters from the FOSSIL inbound | ring buffer to the calling routine's buffer. ES:DI are left unchanged by | the call; the count of bytes actually transferred will be returned in AX. } Procedure ModemObj.ReadBlock(var s:string;reqnum,maxnum:byte); var regs:registers; t:string; begin with regs do begin if maxnum<=255 then cx := maxnum else cx := 255; dx := comport-1; es := seg(s); di := ofs(s) +1; end; Intr($14, regs); s[0] := chr(regs.ax); if regs.ax