Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!think.com!paperboy!hsdndev!husc6!popvax!rind From: rind@popvax.uucp (747707@d.rind) Newsgroups: comp.lang.pascal Subject: Re: Turbo Pascal serial port I/O Message-ID: <6767@husc6.harvard.edu> Date: 13 May 91 19:58:54 GMT References: <1991May10.202334.21630@colorado.edu> Sender: news@husc6.harvard.edu Organization: Health Sciences Computing Facility, Harvard University Lines: 134 program Modemo; {This is a demo of how to use the comports (COM1 and COM2 only) from Turbo Pascal. It is just stripped down code, to give you an idea of how to deal with the ports. If the code looks odd, it's because I've taken it from a real application of mine and just left the parts necessary to initialize the ports and send and receive characters. Typing a capital 'S' should stop the program. David Rind rind@popvax.harvard.edu } Uses dos, crt; const baud: array[2..7] of word=(300,600,1200,2400,4800,9600); {Baud rates} Parity : Byte = 3; {Even parity} Stopbits : Byte = 0; {1 stop bits} Wordlength : Byte = 2; {7 bit words} PortBufSize = 10000; var ch: char; {Current character} regs: registers; base: word; com1,com2: pointer; {Address of com-port interrupt vector saved here} hd,tl : word; {Head and tail of com-port buffer} bd,comport,holdint: byte; buf: array[0..portbufsize] of byte; sb,quit : Boolean; x : integer; procedure send(ch: char); {Send character out COM port} begin while port[base+5] and $20=0 do; {Wait for ready to receive message from port} port[base]:=ord(ch); {Send character} end; procedure alt(st: string); var i:integer; begin for i:=1 to length(st) do send(st[i]); ch:=#0; end; Function GetBufChar(Var Ch : Char) : Boolean; {Get a character from the buffer and return it by reference in Ch. Function returns False if buffer was empty, True otherwise.} Begin If hd = tl then GetBufChar := False Else {Something in buffer} Begin GetBufChar := True; Ch := Chr(buf[tl]); If sb and ((hd+portbufsize-tl) mod portbufsize < 65) then Begin {^S pending and buffer now with < 65 characters in it.} sb := False; End; Inc(tl); If tl = portbufsize then tl := 0; End; End; procedure input(flags,CS,IP,AX,BX,CX,DX,SI,DI,DS,ES,BP: word); interrupt; begin if port[base+5] and 1=1 then {If bit 0=1 then something came in the com port} Begin buf[hd]:=port[base]; {Put new character from com1 into buffer} inc(hd); if hd = portbufsize then hd := 0; if not sb and ((hd+portbufsize-tl) mod portbufsize > (portbufsize-100) ) then begin {Running out of buffer room?} send(^S); {Control S} sb:=true; end; End; port[$20]:=$20; {Clear the interrupt} end; begin bd:=4; {set baud rate=1200} Comport := 1; regs.AX:=(bd*32)+(Parity*8)+(Stopbits*4)+Wordlength; {Set up for setting baud rate of serial port} regs.DX:=comport-1; {for com1, DX := 0} intr($14,regs); {Set baud rate, etc. for port} getintvec($0C,com1); {Save old interrupt for com1} getintvec($0B,com2); {Save old interrupt for com2} hd:=0; tl:=0; {Head and Tail of buffer} Holdint := port[$21]; {Save initial status of interrupt enables.} if comport = 1 then Begin setintvec($0C,@input); {Redirect input from Com1 to procedure Input} port[$21]:=port[$21] and $EF; {Enable interrupts for Com1} base:=memw[$40:$00]; {Get base address of Com1} End Else Begin Setintvec($0B,@input); {Redirect input from Com2 to procedure Input} port[$21]:=port[$21] and $F7; {Enable interrupts for Com2} base := memw[$40:$02]; {Get base address of Com2} End; {The next 3 lines have to do with setting up the modem control register. I'd suggest getting a book if you really need to understand this.} port[base+3]:=port[base+3] and $7F; port[base+1]:=$01; port[base+4]:=$09; x:=port[base]; port[$20]:=$20; {Read from port to initialize and clear port} quit := false; repeat if keypressed then begin {Accept input from keyboard!} ch := readkey; if ch='S' then quit := True; send(ch); {Send ASCII value of character out com1} end else if GetBufChar(ch) then begin write(ch); end; until quit; port[$21]:= Holdint; port[base+3]:=port[base+3] and $7F; port[base+1]:=$0; port[base+4]:=$0; setintvec($0C,com1); setintvec($0B,com2); end. David Rind rind@popvax.harvard.edu