[comp.lang.c] C code for opening a communications file

dipto@umbc3.UUCP (12/05/87)

Expertise needed to open a communications file (COM1) on an IBM PC !!!!!!

My fellow C-pals, I need your help to get  an equivalent of the following 
BASICA code. This code in BASICA works fine as an experiment. However, in
real  life, I am required to  implement the following in Microsoft C 4.0,
for a communications program. 

100 OPEN "COM1:9600, N, 8, 1, RS, CS, DS, CD" AS #1

Above given is the line which opens COM1. The IBM BASIC manual will have 
the detailed descriptions of the options used. For my friends who aren't
in touch with the finer details of BASIC syntax here is a short summary 
of the options used in the above statement.

OPEN	opens an asynchronous communications file
COM1	communications port 1
9600	speed; specifying the transmit/receive bit rate in bits/sec (bps)
N	specifies that there is no Xmit parity; no receive parity checks
8	specifies the number of transmit/receive data bits
1 	specifies the number of stop bits
RS	suppreses RTS (Request To Send)
CS	this option allows user to ignore this line
DS	this option allows user to ignore this line
CD	this option allows user to ignore the Carrier Detect checks

I elaborated on the requirements for people out there, who may know the 
technique, but may not be very familiar, or in touch with Basic. The 
description of the options explain the capability of that program line.
I am not sure whether the RS, CS, DS, CD options actually disable the 
lines from the UART level.  But if possible I would want to avoid the 
complicated task of reprogramming the UART chip. 

Thanks to all of you for reading this.-- 
BITNET : dipto@umbc2	      ------\
ARPANET: dipto@umbc3.UMD.EDU  -------> In-real-life: Dipto Chakravarty
USMAIL : CMSC, UMBC,Md 21228  ------/

dipto@umbc3.UUCP (12/05/87)

I forgot to mention before; please send me e-mail if possible. I don't
read my net news daily. Thanks again

-- 
BITNET : dipto@umbc2	      ------\
ARPANET: dipto@umbc3.UMD.EDU  -------> In-real-life: Dipto Chakravarty
USMAIL : CMSC, UMBC,Md 21228  ------/

stergios@rocky.UUCP (12/05/87)

In article <621@umbc3.UMD.EDU> dipto@umbc3.umd.edu (Dipto Chakravarty) writes:
>
>Expertise needed to open a communications file (COM1) on an IBM PC !!!!!!
>
>My fellow C-pals, I need your help to get  an equivalent of the following 
 rest of basic stuff deleted.

look in the stdio.h file (I think, its been awhile) You should see some 
references to:

	"stdprt" and "stdser" (again, I maybe off on the names).

Just fprintf(stdser,"%c", 'A') to send this out to the serial port with
the appropriate settings chosen from the dos setup command.

Stergios Marinopoulos
-- 
% Stergios Marinopoulos			% GO:     Wall Street
% UUCP:   !sun!rocky!stergios 		% DECNET: star::stergios
% ARPA:	  f.flex@macbeth.stanford.edu 	% BELL:   (415) 321-7678
% USnail: S. Marinopoulos Crothers Memorial #690, Stanford, CA. 94305

pozar@hoptoad.uucp (Tim Pozar) (12/26/87)

In article <621@umbc3.UMD.EDU> dipto@umbc3.umd.edu (Dipto Chakravarty) writes:
>
>Expertise needed to open a communications file (COM1) on an IBM PC !!!!!!
>
>My fellow C-pals, I need your help to get  an equivalent of the following 
>BASICA code. This code in BASICA works fine as an experiment. However, in
>real  life, I am required to  implement the following in Microsoft C 4.0,
>for a communications program. 
>
>100 OPEN "COM1:9600, N, 8, 1, RS, CS, DS, CD" AS #1
>
>Above given is the line which opens COM1. The IBM BASIC manual will have 
>the detailed descriptions of the options used. For my friends who aren't
>in touch with the finer details of BASIC syntax here is a short summary 
>of the options used in the above statement.
>
>OPEN	opens an asynchronous communications file
>COM1	communications port 1
>9600	speed; specifying the transmit/receive bit rate in bits/sec (bps)
>N	specifies that there is no Xmit parity; no receive parity checks
>8	specifies the number of transmit/receive data bits
>1 	specifies the number of stop bits
>RS	suppreses RTS (Request To Send)
>CS	this option allows user to ignore this line
>DS	this option allows user to ignore this line
>CD	this option allows user to ignore the Carrier Detect checks
>

  Ok, folks here it is.  I've been holding off on posting this
for more than a year for fear of riticule for the sloppy code.
This is an asm source communications functions to be linked in
with MSC 3.0 to 5.0.  This is only here to see how asm is linked
in with MSC and to see how interupt handlers work.  If anyone is
planning to seriously get into communications routines, I would
suggest the FOSSIL drivers, NOT this code.  Also look carfully
at the code before using it.  This is an old version and I think
the resettty() is not fully functional...


---

/*
 * Comport.h
 *
 * defines the bit masking for the get_mcr()
 *
 * Copyright (C) Tim M. Pozar 1987
 *
 */

/*
 * get_msr()
 *   Function to read (get) the byte located in the Modem Status 
 * Register (3FEh).  The table below describes the byte returned.
 *   bit  description
 *    0   Delta Clear to Send (DCTS)
 *        Indicates that the !CTS input to the chip has changed state
 *        since the last time it was read by the processor.
 *    1   Delta Data Set Ready (DDSR)
 *        Indicates that the !DRS input to the chip has changed since 
 *        last time it was read by the processor.
 *    2   Trailing Edge Ring Indicator (TERI)
 *        Indicates that the !RI input to the chip has changed from
 *        an on (logical 1) to an off (logical 0) condition.
 *    3   Delta Rx Line Signal detect (DRLSD)
 *        Indicates that the !RLSD input to the chip has changed state.
 * NOTE: Whenever bit 0, 1, 2, or 3 is set to a logical 1, a modem status
 *       interrupt is generated.
 *
 *    4   Clear to Send (CTS)
 *        This bit is the complement of the clear to send (!CTS) input.
 *        If bit 4 (LOOP) of the MCR is set to a logical 1, this is 
 *        equivalent to RTS in the MCR.
 *    5   Data Set Ready (DSR)
 *        This bit is the complement of the data set ready (!DSR) input.
 *        If bit 4 (LOOP) of the MCR is set to a logical 1, this is 
 *        equivalent to DTR in the MCR.
 *    6   Ring Indicator (RI)
 *        This bit is the complement of the ring indicator (!RI) input.
 *        If bit 4 (LOOP) of the MCR is set to a logical 1, this is 
 *        equivalent to OUT 1 in the MCR.
 *    7   Receive Line Signal Detect (RLSD) or Carrier Detect (CD).
 *        This bit is the complement of the received line signal detect
 *        (!RLSD) input. If bit 4 (LOOP) of the MCR is set to a logical 1,
 *        this is equivalent to OUT 2 in the MCR.
 */

#define  DCTS       1
#define  DDSR       2
#define  TERI       4
#define  DRLSD      8
#define  CTS       16
#define  DST       32
#define  RI        64
#define  RLSD     128   /* Also know as ... */
#define  CD       128   
---
		  ... and the asm code...
---

title IBM PC Communications I/O Routines 
;
; Orginal code -- Curt Klinsing
;
; Changes and updates -- Copyright (c) 1987 Tim Pozar
;
; ver: 0
; rev: 2
; March 13th 1987
; This code is in a very early stage and should not be let out.
; Several other extensive functions are planned as well as changes
; to the current code.
;
; 2/20/87 
;   Changed segment declarations and function names (eg. _function)
; to fit Microsoft C 4.0 and linker requirements.
;
; FUNCTIONS CHANGED/ADDED --
; set_tty(port_number)
;   Function to find current settings of the port and set up serial 
; port for 'baud' and 'lcbyte', and enable DTR.  This will set up the
; port number base addressed passed to it (eg. 3F8h) and all functions
; will use this port until the function is used again. (NOT READY FOR USE)
;
; reset_tty()
;   Function to put the port back into the state it was when it was 
; first found by set_tty().  If set_tty() was not called it will not 
; change the settings of the port. (NOT READY FOR USE)
;
; 3/13/87
; get_msr()
;   Function to read (get) the byte located in the Modem Status 
; Register (3FEh).  The table below describes the byte returned.
;   bit  description
;    0   Delta Clear to Send (DCTS)
;        Indicates that the !CTS input to the chip has changed state
;        since the last time it was read by the processor.
;    1   Delta Data Set Ready (DDSR)
;        Indicates that the !DRS input to the chip has changed since 
;        last time it was read by the processor.
;    2   Trailing Edge Ring Indicator (TERI)
;        Indicates that the !RI input to the chip has changed from
;        an on (logical 1) to an off (logical 0) condition.
;    3   Delta Rx Line Signal detect (DRLSD)
;        Indicates that the !RLSD input to the chip has changed state.
; NOTE: Whenever bit 0, 1, 2, or 3 is set to a logical 1, a modem status
;       interrupt is generated.
;
;    4   Clear to Send (CTS)
;        This bit is the complement of the clear to send (!CTS) input.
;        If bit 4 (LOOP) of the MCR is set to a logical 1, this is 
;        equivalent to RTS in the MCR.
;    5   Data Set Ready (DSR)
;        This bit is the complement of the data set ready (!DSR) input.
;        If bit 4 (LOOP) of the MCR is set to a logical 1, this is 
;        equivalent to DTR in the MCR.
;    6   Ring Indicator (RI)
;        This bit is the complement of the ring indicator (!RI) input.
;        If bit 4 (LOOP) of the MCR is set to a logical 1, this is 
;        equivalent to OUT 1 in the MCR.
;    7   Receive Line Signal Detect (RLSD).
;        This bit is the complement of the received line signal detect
;        (!RLSD) input. If bit 4 (LOOP) of the MCR is set to a logical 1,
;        this is equivalent to OUT 2 in the MCR.
;
;   Currently this driver is set up for COM1 (3f8h).
;   If you are using the interupt driven buffer, take out the code 
; that enables the DTR so that it doesn't get raised until the vectors
; are initilized. 
;

_TEXT   SEGMENT BYTE PUBLIC 'CODE'
_TEXT   ENDS
_DATA   SEGMENT BYTE PUBLIC 'DATA'
_DATA   ENDS
CONST   SEGMENT BYTE PUBLIC 'CONST'
CONST   ENDS
_BBS    SEGMENT BYTE PUBLIC 'BBS'
_BBS    ENDS

DGROUP  GROUP   CONST, _BBS, _DATA
      ASSUME    CS: _TEXT, DS: DGROUP, SS: DGROUP, ES: DGROUP

_TEXT      SEGMENT
;
;A set of Lattice C and MSC callable functions to support
;interrupt driven character I/O on the  IBM PC. Input
;is buffered, output is polled.
;
;added functions (TMP) --
public  _set_tty        ;find current settings, and initialize 
                        ;comm port to 8 bits and set DTR
public  _reset_tty      ;reset to settings that set_tty() found
public  _get_msr        ;get MSR byte from port.
;
;original functions --
public  _init_comm      ;initialize the comm port interupts,
public  _uninit_comm    ;remove initialization,
public  _set_xoff       ;enable/disable XON/XOFF,
public  _get_xoff       ;read XON/XOFF state,
public  _rcvd_xoff      ;returns true if XOFF rcvd,
public  _sent_xoff      ;true if XOFF sent,
public  _inp_cnt        ;returns count of rcv chars,
public  _inp_char       ;get one char from buffer,
public  _inp_flush      ;flush input buffer,
public  _outp_char      ;output a character,
;
;A better description can be found in the comment
;block  in each function.
;
;       assume  cs:pgroup
;
FALSE   EQU     0
TRUE    EQU     NOT FALSE
;
BASE    EQU     03F8H   ;BASE FOR SERIAL BOARD
;
LCR    	equ     BASE+3  ; Line control register
IER     equ     BASE+1  ; Interrup Enable Register
MCR     EQU     BASE+4  ;modem control register
MDMSTA  EQU     BASE+5  ;line status register
MDMMSR  EQU     BASE+6  ;modem status register
MDMBAD  EQU     BASE    ;lsb baud resgister
EnblDRdy equ    01H     ; enable 'data-ready' interrupt bit
IntCtlr  EQU    21H     ;OCW 1 FOR 8259 CONTROLLER
EnblIRQ4 EQU    0EFH    ;Enable COMMUNICATIONS (IRQ4)
dataport EQU    BASE    ;transmit/receive data port
MaskIRQ4 EQU    10H     ;BIT TO DISABLE COMM INTERRUPT (IRQ4)

MDMCD   EQU     80H     ;mask for carrier dectect
SETBAU  EQU     80H     ;code for Divisor Latch Access Bit
MDMTBE  EQU     20H     ;8250 tbe flag
MDMBRK  EQU     40H     ;command code for 8250 break
LINMOD  EQU     03H     ;line mode=8 bit, no parity
MDMMOD  EQU     0BH     ;modem mode = DTR and RTS HIGH
STOP2   EQU     04H     ;BIT FOR TWO STOP BITS IF BAUD<300
RS8259  EQU     20H     ;OCW 3 FOR 8259
RSTINT  EQU     64H     ;SPECIFIC EOI FOR COMM INTERRUPT 
XOFF    EQU     13H     ;XOFF character
XON     EQU     11H     ;XON character
;
;       MISCELLANEOUS EQUATES
;
CR      EQU     13
LF      EQU     10
DosCall EQU     33      ;INTERRUPT NUMBER FOR DOS CALL  
CNSTAT  EQU     11      ;FUNCTION NUMBER FOR CONSOLE STATUS
CNIN    EQU     1       ;FUNCTION NUMBER FOR CONSOLE INPUT
BUFSIZ  EQU     512     ;Max NUMBER OF CHARS
SetIntVect  EQU 25H     ;SET INTERRUPT VECTOR FUNCTION NUMBER

;
; Communication parameters --
;
baud    equ     96      ; 1047 =  110 (are you kidding?)
                        ;  384 =  300
                        ;   96 = 1200
                        ;   48 = 2400
                        ;   24 = 4800
                        ;   12 = 9600
parity  equ     00000b  ;00000 = none
                        ;01000 = odd
                        ;11000 = even
stopbit equ     000b    ;  000 = 1 bit
                        ;  100 = 2 bits
wordlth equ     11b     ;   10 = 7 bits
                        ;   11 = 8 bits
lcbyte  equ     parity+stopbit+wordlth      ;line control byte
div_on  equ     80h     ;divisor latch access bit (DLAB)

;
;       DUMP BUFFER, COUNT AND POINTER.  
;
CIRC_BUF DB     BUFSIZ DUP(?)   ;ALLOW 512 MaxIMUM BUFFERED CHARACTERS
BUF_TOP EQU     $ - 1           ;KEEP TRACK OF THE TOP OF THE BUFFER
CIRC_TOP DW     BUF_TOP         ;
;
CIRC_IN DW      OFFSET CIRC_BUF ;POINTER TO LAST CHAR. PLACED IN BUFFER
CIRC_CUR DW     OFFSET CIRC_BUF ;POINTER TO NEXT CHAR. TO BE RETRIEVED FROM
                                ; BUFFER
CIRC_CT DW      0               ;COUNT OF CHARACTERS USED IN BUFFER
SNT_XOFF DB     FALSE           ;FLAG TO CHECK IF AN XOFF HAS BEEN SEND
GOT_XOFF  DB    FALSE           ;FLAG TO CHECK IF AN XOFF HAS BEEN RECEIVED
SEE_XOFF  DB    FALSE           ;FLAT TO SEE IF WE ARE INTERESTED IN XON/XOFF
;
;
; set_tty()
;
_set_tty proc near
        push    bp
;        mov     dx,mcr
;        in      al,dx           ; get modem parameters
;        mov     MCR_BYTE,al     ; save them
        mov     dx,lcr
;        in      al,dx           ; get line parameters
;        mov     LCR_BYTE,al     ; save them
        mov     al,div_on
        out     dx,al           ; set 8250 for baud rate selection
        ; can the baud rate divisor be read to save the settings?
        ; if so, stick the code here.
        mov     ax,baud
        mov     dx,mdmbad
        out     dx,al           ; low byte divisor
        mov     al,ah
        inc     dx
        out     dx,al           ; high byte divisor
        mov     dx,lcr
        mov     al,lcbyte
        out     dx,al           ; set line control reg.
        mov     dx,mcr
        in      al,dx
        or      al,mdmmod
        out     dx,al           ; set DTR high
flsh:   mov     dx,dataport
        in      al,dx
        mov     dx,mdmsta
        in      al,dx
        and     al,1
        jnz     flsh
      
        pop     bp
        ret

_set_tty endp


_reset_tty proc near
        push    bp

        pop     bp
        ret

_reset_tty endp

_get_msr proc near
        push    bp
        push    ds              ; save data segment
        push    cs
        pop     ds

        xor     ax,ax
        mov     dx,MDMMSR
        in      al,dx

        pop     ds
        pop     bp
        ret

_get_msr endp

;
; set_xoff(flag)         Enable (flag != 0) or disable
;int flag;              (flag == 0) XON/ XOFF protocol
;                       for the character input stream.
;If enabled, an XOFF will be sent when  the buffer
;reaches 3/4 full. NOTE: an XON will not be sent auto-
;matically. Your program must do it when it sees
;the _rcvd_xoff() flag,  and ready for more chars.
;
_set_xoff proc near
        push    bp
        PUSH    DS              ;SAVE DATA SEGMENT
        mov     bx,[bp+6]       
        push    cs
        pop     ds              ; move code seg addr to data seg reg.
        cmp     bx,0
        jnz     to_on
        mov     see_xoff,FALSE
        jmp     done1
to_on:  mov     see_xoff,TRUE
done1:  pop     ds
        pop     bp
        ret
_set_xoff endp
;
;flag = get_xoff()      Returns the current setting
;                       of the XON/ XOFF flag set
;by set_xoff(), above.
;
_get_xoff proc near
        push    bp
        push    ds              ; save data reg
        push    cs
        pop     ds              ; move code seg addr to data seg reg.
        xor     ax,ax
        mov     al,see_xoff
        pop     ds
        pop     bp
        ret
_get_xoff endp
;
;flag = sent_xoff();    Returns true if an XOFF
;                       character was sent, indicating
;the receive buffer is  3/4 full.
;
_sent_xoff proc  near
        push    bp
        push    ds              ; save data reg
        push    cs
        pop     ds              ; move code seg addr to data seg reg.
        xor     ax,ax
        mov     al,snt_xoff
        pop     ds
        pop     bp
        ret
_sent_xoff endp
;
; rcvd_xoff()            Returns true if an XOFF was
;                       received; will return false as
;soon as an XON is received. Does not effect data output,
;only indicates the above. (Obviously useless for binary
;data.)
;
_rcvd_xoff proc  near
        push    bp
        push    ds              ; save data reg
        push    cs
        pop     ds              ; move code seg addr to data seg reg.
        xor     ax,ax
        mov     al,got_xoff
        pop     ds              ; restore data reg
        pop     bp
        ret
_rcvd_xoff endp
;
;count = inp_cnt()       Returns the number of characters
;                       available in the input buffer.
;

_inp_cnt proc near       
        push    bp
        push    ds              ; save data segment
        push    cs
        pop     ds              ; move code seg addr to data seg reg
        mov     ax,circ_ct
        pop     ds
        pop     bp
        ret
_inp_cnt endp
;
; inp_flush()    Flush the input buffer.
;
_inp_flush proc  near    
        push    bp
        push    ds              ; save data reg
        push    cs
        pop     ds              ; move code seg addr to data seg reg.
        mov     bx,offset circ_buf
        mov     circ_in,bx      
        mov     circ_cur,bx
        xor     ax,ax
        mov     circ_ct,ax
        pop     ds
        pop     bp
        ret
_inp_flush endp

; --------- Init -----------------------------------
; Program initialization:
;   --  Set up vector for RS232 interrupt (0CH)
;   --  Enbl IRQ4
;   --  Enbl RS232 interrupt on data ready
;
; ---------------------------------------------------

_init_comm proc  near
        push    bp
        cli

;  ---- Set up  INT x'0C' for IRQ4

        push    ds
        push    cs
        pop     ds              ;cs to ds
        mov     dx,offset IntHdlr ;relative adddres of interrupt handler
        mov     al,0cH          ;interrupt number for comm.
        mov     ah,SetIntVect   ;function number for setting int vector
        int     DosCall         ;set interrupt in 8086 table
        pop     ds              ;restore DS

;  ---- Enbl IRQ4 on 8259 interrupt controller

        cli

        in      al,IntCtlr      ; get current masks 
        and     al,EnblIRQ4     ; Reset IRQ4 mask
        out     IntCtlr,al      ; And restore to IMR

;  ---   Enbl 8250 data ready interrupt

        mov     dx,LCR          ; DX ==> LCR
        in      al,dx           ; Reset DLAB for IER access
        and     al,7FH
        out     dx,al
        mov     dx,IER          ; Interrupt Enbl Register
        mov     al,EnblDRdy     ; Enable 'data-ready' interrupt
        out     dx,al

;  ---   Enbl OUT2 on 8250

        mov     dx,MCR          ; modem control register        
        in      al,dx           ; Enable OUT2
        or      al,08h            ; find out what is in there and
        out     dx,al            ; enable the DTR

        sti

        pop     bp
        ret
_init_comm endp
;
; uninit_comm()          Removes the interrupt structure
;                       installed by _init_comm(). Must be
;done before passing control to the DOS, else chars received
;will be stored into the next program loaded!
;
_uninit_comm proc near
        push    bp
; ---   Disable IRQ4 on 8259

        cli
        in      al,IntCtlr      ;GET OCW1 FROM 8259
        or      al,MaskIRQ4     ;DISABLE COMMUNICATIONS INTERRUPT
        out     IntCtlr,al

; ---   Disable 8250 data ready interrupt
        
        mov     dx,LCR          ; DX ==> LCR
        in      al,dx           ; Reset DLAB for IER access
        and     al,7FH
        out     dx,al
        mov     dx,IER          ; Interrupt Enbl Register
        mov     al,0            ; Disable all 8250 interrupts
        out     dx,al

;  ---   Disable OUT2 on 8250

        mov     dx,MCR          ; modem control register        
        mov     al,0            ; Disable OUT2
        out     dx,al

        sti
        pop     bp
        ret
_uninit_comm endp
;
;char  inp_char()      Return a character from the input
;                      buffer. Assumes you have called
;inp_cnt() to see if theres any characters to get.
;
_inp_char proc near      
        push    bp
        push    ds              ; save data reg
        push    cs
        pop     ds              ; move code seg addr to data seg reg.
        mov     bx,circ_cur
        xor     ax,ax
        mov     al,[bx]         ;get next char from circ_buf
        DEC     circ_ct         ;decrement circ_buf COUNT
        CMP     bx,circ_top     ;ARE WE AT THE TOP OF THE circ_buf?
        JZ      reset_cur       ;JUMP IF SO
        INC     bx              ;ELSE, BUMP PTR
        JMP SHORT upd_cur
reset_cur:
        mov     bx,OFFSET circ_buf      ;RESET circ_in TO BOTTOM OF BUF.
upd_cur:
        mov     circ_cur,bx             ;SAVE NEW PTR
        xor     cx,cx
        mov     cl,see_xoff     ;check if interested in xon/xoff
        cmp     cl,TRUE
        jnz     clnup2          ;not interested, so goto return
        cmp     snt_xoff,TRUE   ;have we sent an xoff?
        jnz     clnup2          ;no, so return
        cmp     circ_ct,80h     ;yes, so see in buf is now emptying
        jg      clnup2          ;not empty enuf to send xon, jump to ret
        mov     snt_xoff,FALSE
        mov     cl,XON
        push    ax              ; save char
        call    comout
        pop     ax
clnup2: pop     DS              ;GET BACK ENTERING DS
        pop     bp
        ret
_inp_char endp
;
; outp_char(c)           Output the character to the
;char c;                serial port. This is not buffered
;                       or interrupt driven.
;
_outp_char proc  near
        push    bp
        mov     bp,sp
        mov     cl,[bp+4]
        sti
        call    comout
        pop     bp
        ret
_outp_char endp
;
;Local  subroutine: output CL to the port.
;
comout: mov     dx,MDMSTA       
        in      al,dx           ; get 8250 status
        and     al,MDMTBE       ; check for transmitter ready
        jz      comout          ; jump if not to wait
        mov     al,cl           ; get char to al
        mov     dx,dataport     
        out     dx,al           ; output char to 8251
        ret
;
;       RECEIVE INTERRUPT HANDLER (CHANGED TO PLACE CHARACTERS IN A
;        CIRCULAR circ_buf AND TO SEND AN XOFF IF THE circ_buf IS MORE THAN
;        3/4 FULL - S.G.)
;
IntHdlr:
        CLI
        push    cx
        push    dx
        push    bx
        push    ax
        push    ds
        mov     ax,cs           ;get cur code segment
        mov     ds,ax           ;and set it as data segment
        mov     bx,circ_in      ;GET circ_buf IN PTR
        mov     DX,dataport     ;GET DATA PORT NUMBER
        IN      AL,DX           ;GET RECEIVED CHARACTER
;       push    ax
;       push    dx   
;       xor     ax,ax
;       xor     dx,dx
;       mov     dl,al
;       mov     ah,2
;       int     DosCall
;       pop     dx
;       pop     ax
        xor     cx,cx
        mov     cl,see_xoff     ;check if interested in xon/xoff
        cmp     cl,TRUE
        jnz     ck_full         ;not interested goto ck if buf full
        mov     cl,al           ;put char in cl for testing
        and     cl,7fh          ;turn off any parity bits 
        cmp     cl,XOFF         ;see if we got an xoff
        jnz     ck_xon
        mov     got_Xoff,TRUE   ; code for handling xon/xoff from remote
        jmp     clnup
ck_xon: cmp     cl,XON
        jnz     reg_ch
        mov     got_Xoff,FALSE
        jmp     clnup
;
;Normal character; not  XON/XOFF, or XON/XOFF disabled.
;
reg_ch: test    snt_Xoff,TRUE   ;SEE IF sentXoff IS SET
        jnz     ck_full         ;IF SO, DON'T SEND ANOTHER XOFF
        CMP     circ_ct,(BUFSIZ * 3)/4  ;ALLOW BUF TO BECOME 3/4 FULL BEFORE
                                        ; SENDING XOFF
        jb      savch           ;IF IT'S OK, CONTINUE
        push    ax              ;SAVE CHARACTER
        mov     CL,XOFF         ;GET XOFF CHARACTER
        mov     snt_Xoff,TRUE  ;RESET sentXoff
        call    comout          ; AND SEND IT
        pop     ax              ;RETRIEVE CHARACTER
        JMP SHORT savch         ;IF WE'RE HERE, THE circ_buf HAS BUFSIZ-80H
                                ;  CHARACTERS
ck_full:
        CMP     circ_ct,BUFSIZ  ;SEE IF circ_buf ALREADY FULL
        JZ      clnup           ; JUMP IF SO, DO NOT PLACE CHARACTER IN BFR
savch:                          
        mov     [bx],AL         ;SAVE NEW CHARACTER IN circ_buf
        inc     circ_ct         ;BUMP circ_buf COUNT
        CMP     bx,circ_top     ;ARE WE AT THE TOP OF THE circ_buf?
        JZ      reset_in        ;JUMP IF SO
        inc     bx              ;ELSE, BUMP PTR
        JMP SHORT into_buf
reset_in:
        mov     bx,OFFSET circ_buf      ;RESET circ_in TO BOTTOM OF BUF.
into_buf:
        mov     circ_in,bx              ;SAVE NEW PTR
clnup:
        mov     AL,RSTINT
        OUT     RS8259,AL       ;ISSUE SPECIFIC EOI FOR 8259
        pop     ds              ;GET BACK ENTERING DS
        pop     ax
        pop     bx
        pop     dx
        pop     cx
        sti
        iret

_TEXT   ENDS

end
---

   And that's all folks!!!


-- 
=======================================================================
| ...sun!hoptoad!\                                     Tim Pozar      |
|                 >fidogate!pozar               Fido:  1:125/406      |
|  ...lll-winken!/                            PaBell:  (415) 788-3904 |
|         USNail:  KKSF  77 Maiden Lane  San Francisco CA 94108       |
=======================================================================

pozar@hoptoad.uucp (Tim Pozar) (12/26/87)

In article <622@umbc3.UMD.EDU> dipto@umbc3.UMD.EDU (Dipto Chakravarty) writes:
>
>I forgot to mention before; please send me e-mail if possible. I don't
>read my net news daily. Thanks again
>

    NOW he tells me....

-- 
=======================================================================
| ...sun!hoptoad!\                                     Tim Pozar      |
|                 >fidogate!pozar               Fido:  1:125/406      |
|  ...lll-winken!/                            PaBell:  (415) 788-3904 |
|         USNail:  KKSF  77 Maiden Lane  San Francisco CA 94108       |
=======================================================================