home *** CD-ROM | disk | FTP | other *** search
/ Power Programming / powerprogramming1994.iso / progtool / c / commasm.arc / COMM-ASM.MSG
Text File  |  1988-07-13  |  25KB  |  718 lines

  1. Article 5187 of comp.sys.ibm.pc:
  2. Path: cgh!vu-vlsi!cbmvax!rutgers!ames!ucbcad!ucbvax!hoptoad!pozar
  3. From: pozar@hoptoad.uucp (Tim Pozar)
  4. Newsgroups: comp.lang.c,comp.sys.ibm.pc
  5. Subject: Re: C code for opening a communications file
  6. Message-ID: <3731@hoptoad.uucp>
  7. Date: 25 Dec 87 16:39:42 GMT
  8. References: <621@umbc3.UMD.EDU>
  9. Reply-To: pozar@hoptoad.UUCP (Tim Pozar)
  10. Organization: Syncstream/Widget Systems (San Francisco)
  11. Lines: 704
  12. Xref: cgh comp.lang.c:2667 comp.sys.ibm.pc:5187
  13.  
  14. In article <621@umbc3.UMD.EDU> dipto@umbc3.umd.edu (Dipto Chakravarty) writes:
  15. >
  16. >Expertise needed to open a communications file (COM1) on an IBM PC !!!!!!
  17. >
  18. >My fellow C-pals, I need your help to get  an equivalent of the following
  19. >BASICA code. This code in BASICA works fine as an experiment. However, in
  20. >real  life, I am required to  implement the following in Microsoft C 4.0,
  21. >for a communications program.
  22. >
  23. >100 OPEN "COM1:9600, N, 8, 1, RS, CS, DS, CD" AS #1
  24. >
  25. >Above given is the line which opens COM1. The IBM BASIC manual will have
  26. >the detailed descriptions of the options used. For my friends who aren't
  27. >in touch with the finer details of BASIC syntax here is a short summary
  28. >of the options used in the above statement.
  29. >
  30. >OPEN   opens an asynchronous communications file
  31. >COM1   communications port 1
  32. >9600   speed; specifying the transmit/receive bit rate in bits/sec (bps)
  33. >N      specifies that there is no Xmit parity; no receive parity checks
  34. >8      specifies the number of transmit/receive data bits
  35. >1      specifies the number of stop bits
  36. >RS     suppreses RTS (Request To Send)
  37. >CS     this option allows user to ignore this line
  38. >DS     this option allows user to ignore this line
  39. >CD     this option allows user to ignore the Carrier Detect checks
  40. >
  41.  
  42.   Ok, folks here it is.  I've been holding off on posting this
  43. for more than a year for fear of riticule for the sloppy code.
  44. This is an asm source communications functions to be linked in
  45. with MSC 3.0 to 5.0.  This is only here to see how asm is linked
  46. in with MSC and to see how interupt handlers work.  If anyone is
  47. planning to seriously get into communications routines, I would
  48. suggest the FOSSIL drivers, NOT this code.  Also look carfully
  49. at the code before using it.  This is an old version and I think
  50. the resettty() is not fully functional...
  51.  
  52.  
  53. ---
  54.  
  55. /*
  56.  * Comport.h
  57.  *
  58.  * defines the bit masking for the get_mcr()
  59.  *
  60.  * Copyright (C) Tim M. Pozar 1987
  61.  *
  62.  */
  63.  
  64. /*
  65.  * get_msr()
  66.  *   Function to read (get) the byte located in the Modem Status
  67.  * Register (3FEh).  The table below describes the byte returned.
  68.  *   bit  description
  69.  *    0   Delta Clear to Send (DCTS)
  70.  *        Indicates that the !CTS input to the chip has changed state
  71.  *        since the last time it was read by the processor.
  72.  *    1   Delta Data Set Ready (DDSR)
  73.  *        Indicates that the !DRS input to the chip has changed since
  74.  *        last time it was read by the processor.
  75.  *    2   Trailing Edge Ring Indicator (TERI)
  76.  *        Indicates that the !RI input to the chip has changed from
  77.  *        an on (logical 1) to an off (logical 0) condition.
  78.  *    3   Delta Rx Line Signal detect (DRLSD)
  79.  *        Indicates that the !RLSD input to the chip has changed state.
  80.  * NOTE: Whenever bit 0, 1, 2, or 3 is set to a logical 1, a modem status
  81.  *       interrupt is generated.
  82.  *
  83.  *    4   Clear to Send (CTS)
  84.  *        This bit is the complement of the clear to send (!CTS) input.
  85.  *        If bit 4 (LOOP) of the MCR is set to a logical 1, this is
  86.  *        equivalent to RTS in the MCR.
  87.  *    5   Data Set Ready (DSR)
  88.  *        This bit is the complement of the data set ready (!DSR) input.
  89.  *        If bit 4 (LOOP) of the MCR is set to a logical 1, this is
  90.  *        equivalent to DTR in the MCR.
  91.  *    6   Ring Indicator (RI)
  92.  *        This bit is the complement of the ring indicator (!RI) input.
  93.  *        If bit 4 (LOOP) of the MCR is set to a logical 1, this is
  94.  *        equivalent to OUT 1 in the MCR.
  95.  *    7   Receive Line Signal Detect (RLSD) or Carrier Detect (CD).
  96.  *        This bit is the complement of the received line signal detect
  97.  *        (!RLSD) input. If bit 4 (LOOP) of the MCR is set to a logical 1,
  98.  *        this is equivalent to OUT 2 in the MCR.
  99.  */
  100.  
  101. #define  DCTS       1
  102. #define  DDSR       2
  103. #define  TERI       4
  104. #define  DRLSD      8
  105. #define  CTS       16
  106. #define  DST       32
  107. #define  RI        64
  108. #define  RLSD     128   /* Also know as ... */
  109. #define  CD       128
  110. ---
  111.                   ... and the asm code...
  112. ---
  113.  
  114. title IBM PC Communications I/O Routines
  115. ;
  116. ; Orginal code -- Curt Klinsing
  117. ;
  118. ; Changes and updates -- Copyright (c) 1987 Tim Pozar
  119. ;
  120. ; ver: 0
  121. ; rev: 2
  122. ; March 13th 1987
  123. ; This code is in a very early stage and should not be let out.
  124. ; Several other extensive functions are planned as well as changes
  125. ; to the current code.
  126. ;
  127. ; 2/20/87
  128. ;   Changed segment declarations and function names (eg. _function)
  129. ; to fit Microsoft C 4.0 and linker requirements.
  130. ;
  131. ; FUNCTIONS CHANGED/ADDED --
  132. ; set_tty(port_number)
  133. ;   Function to find current settings of the port and set up serial
  134. ; port for 'baud' and 'lcbyte', and enable DTR.  This will set up the
  135. ; port number base addressed passed to it (eg. 3F8h) and all functions
  136. ; will use this port until the function is used again. (NOT READY FOR USE)
  137. ;
  138. ; reset_tty()
  139. ;   Function to put the port back into the state it was when it was
  140. ; first found by set_tty().  If set_tty() was not called it will not
  141. ; change the settings of the port. (NOT READY FOR USE)
  142. ;
  143. ; 3/13/87
  144. ; get_msr()
  145. ;   Function to read (get) the byte located in the Modem Status
  146. ; Register (3FEh).  The table below describes the byte returned.
  147. ;   bit  description
  148. ;    0   Delta Clear to Send (DCTS)
  149. ;        Indicates that the !CTS input to the chip has changed state
  150. ;        since the last time it was read by the processor.
  151. ;    1   Delta Data Set Ready (DDSR)
  152. ;        Indicates that the !DRS input to the chip has changed since
  153. ;        last time it was read by the processor.
  154. ;    2   Trailing Edge Ring Indicator (TERI)
  155. ;        Indicates that the !RI input to the chip has changed from
  156. ;        an on (logical 1) to an off (logical 0) condition.
  157. ;    3   Delta Rx Line Signal detect (DRLSD)
  158. ;        Indicates that the !RLSD input to the chip has changed state.
  159. ; NOTE: Whenever bit 0, 1, 2, or 3 is set to a logical 1, a modem status
  160. ;       interrupt is generated.
  161. ;
  162. ;    4   Clear to Send (CTS)
  163. ;        This bit is the complement of the clear to send (!CTS) input.
  164. ;        If bit 4 (LOOP) of the MCR is set to a logical 1, this is
  165. ;        equivalent to RTS in the MCR.
  166. ;    5   Data Set Ready (DSR)
  167. ;        This bit is the complement of the data set ready (!DSR) input.
  168. ;        If bit 4 (LOOP) of the MCR is set to a logical 1, this is
  169. ;        equivalent to DTR in the MCR.
  170. ;    6   Ring Indicator (RI)
  171. ;        This bit is the complement of the ring indicator (!RI) input.
  172. ;        If bit 4 (LOOP) of the MCR is set to a logical 1, this is
  173. ;        equivalent to OUT 1 in the MCR.
  174. ;    7   Receive Line Signal Detect (RLSD).
  175. ;        This bit is the complement of the received line signal detect
  176. ;        (!RLSD) input. If bit 4 (LOOP) of the MCR is set to a logical 1,
  177. ;        this is equivalent to OUT 2 in the MCR.
  178. ;
  179. ;   Currently this driver is set up for COM1 (3f8h).
  180. ;   If you are using the interupt driven buffer, take out the code
  181. ; that enables the DTR so that it doesn't get raised until the vectors
  182. ; are initilized.
  183. ;
  184.  
  185. _TEXT   SEGMENT BYTE PUBLIC 'CODE'
  186. _TEXT   ENDS
  187. _DATA   SEGMENT BYTE PUBLIC 'DATA'
  188. _DATA   ENDS
  189. CONST   SEGMENT BYTE PUBLIC 'CONST'
  190. CONST   ENDS
  191. _BBS    SEGMENT BYTE PUBLIC 'BBS'
  192. _BBS    ENDS
  193.  
  194. DGROUP  GROUP   CONST, _BBS, _DATA
  195.       ASSUME    CS: _TEXT, DS: DGROUP, SS: DGROUP, ES: DGROUP
  196.  
  197. _TEXT      SEGMENT
  198. ;
  199. ;A set of Lattice C and MSC callable functions to support
  200. ;interrupt driven character I/O on the  IBM PC. Input
  201. ;is buffered, output is polled.
  202. ;
  203. ;added functions (TMP) --
  204. public  _set_tty        ;find current settings, and initialize
  205.                         ;comm port to 8 bits and set DTR
  206. public  _reset_tty      ;reset to settings that set_tty() found
  207. public  _get_msr        ;get MSR byte from port.
  208. ;
  209. ;original functions --
  210. public  _init_comm      ;initialize the comm port interupts,
  211. public  _uninit_comm    ;remove initialization,
  212. public  _set_xoff       ;enable/disable XON/XOFF,
  213. public  _get_xoff       ;read XON/XOFF state,
  214. public  _rcvd_xoff      ;returns true if XOFF rcvd,
  215. public  _sent_xoff      ;true if XOFF sent,
  216. public  _inp_cnt        ;returns count of rcv chars,
  217. public  _inp_char       ;get one char from buffer,
  218. public  _inp_flush      ;flush input buffer,
  219. public  _outp_char      ;output a character,
  220. ;
  221. ;A better description can be found in the comment
  222. ;block  in each function.
  223. ;
  224. ;       assume  cs:pgroup
  225. ;
  226. FALSE   EQU     0
  227. TRUE    EQU     NOT FALSE
  228. ;
  229. BASE    EQU     03F8H   ;BASE FOR SERIAL BOARD
  230. ;
  231. LCR     equ     BASE+3  ; Line control register
  232. IER     equ     BASE+1  ; Interrup Enable Register
  233. MCR     EQU     BASE+4  ;modem control register
  234. MDMSTA  EQU     BASE+5  ;line status register
  235. MDMMSR  EQU     BASE+6  ;modem status register
  236. MDMBAD  EQU     BASE    ;lsb baud resgister
  237. EnblDRdy equ    01H     ; enable 'data-ready' interrupt bit
  238. IntCtlr  EQU    21H     ;OCW 1 FOR 8259 CONTROLLER
  239. EnblIRQ4 EQU    0EFH    ;Enable COMMUNICATIONS (IRQ4)
  240. dataport EQU    BASE    ;transmit/receive data port
  241. MaskIRQ4 EQU    10H     ;BIT TO DISABLE COMM INTERRUPT (IRQ4)
  242.  
  243. MDMCD   EQU     80H     ;mask for carrier dectect
  244. SETBAU  EQU     80H     ;code for Divisor Latch Access Bit
  245. MDMTBE  EQU     20H     ;8250 tbe flag
  246. MDMBRK  EQU     40H     ;command code for 8250 break
  247. LINMOD  EQU     03H     ;line mode=8 bit, no parity
  248. MDMMOD  EQU     0BH     ;modem mode = DTR and RTS HIGH
  249. STOP2   EQU     04H     ;BIT FOR TWO STOP BITS IF BAUD<300
  250. RS8259  EQU     20H     ;OCW 3 FOR 8259
  251. RSTINT  EQU     64H     ;SPECIFIC EOI FOR COMM INTERRUPT
  252. XOFF    EQU     13H     ;XOFF character
  253. XON     EQU     11H     ;XON character
  254. ;
  255. ;       MISCELLANEOUS EQUATES
  256. ;
  257. CR      EQU     13
  258. LF      EQU     10
  259. DosCall EQU     33      ;INTERRUPT NUMBER FOR DOS CALL
  260. CNSTAT  EQU     11      ;FUNCTION NUMBER FOR CONSOLE STATUS
  261. CNIN    EQU     1       ;FUNCTION NUMBER FOR CONSOLE INPUT
  262. BUFSIZ  EQU     512     ;Max NUMBER OF CHARS
  263. SetIntVect  EQU 25H     ;SET INTERRUPT VECTOR FUNCTION NUMBER
  264.  
  265. ;
  266. ; Communication parameters --
  267. ;
  268. baud    equ     96      ; 1047 =  110 (are you kidding?)
  269.                         ;  384 =  300
  270.                         ;   96 = 1200
  271.                         ;   48 = 2400
  272.                         ;   24 = 4800
  273.                         ;   12 = 9600
  274. parity  equ     00000b  ;00000 = none
  275.                         ;01000 = odd
  276.                         ;11000 = even
  277. stopbit equ     000b    ;  000 = 1 bit
  278.                         ;  100 = 2 bits
  279. wordlth equ     11b     ;   10 = 7 bits
  280.                         ;   11 = 8 bits
  281. lcbyte  equ     parity+stopbit+wordlth      ;line control byte
  282. div_on  equ     80h     ;divisor latch access bit (DLAB)
  283.  
  284. ;
  285. ;       DUMP BUFFER, COUNT AND POINTER.
  286. ;
  287. CIRC_BUF DB     BUFSIZ DUP(?)   ;ALLOW 512 MaxIMUM BUFFERED CHARACTERS
  288. BUF_TOP EQU     $ - 1           ;KEEP TRACK OF THE TOP OF THE BUFFER
  289. CIRC_TOP DW     BUF_TOP         ;
  290. ;
  291. CIRC_IN DW      OFFSET CIRC_BUF ;POINTER TO LAST CHAR. PLACED IN BUFFER
  292. CIRC_CUR DW     OFFSET CIRC_BUF ;POINTER TO NEXT CHAR. TO BE RETRIEVED FROM
  293.                                 ; BUFFER
  294. CIRC_CT DW      0               ;COUNT OF CHARACTERS USED IN BUFFER
  295. SNT_XOFF DB     FALSE           ;FLAG TO CHECK IF AN XOFF HAS BEEN SEND
  296. GOT_XOFF  DB    FALSE           ;FLAG TO CHECK IF AN XOFF HAS BEEN RECEIVED
  297. SEE_XOFF  DB    FALSE           ;FLAT TO SEE IF WE ARE INTERESTED IN XON/XOFF
  298. ;
  299. ;
  300. ; set_tty()
  301. ;
  302. _set_tty proc near
  303.         push    bp
  304. ;        mov     dx,mcr
  305. ;        in      al,dx           ; get modem parameters
  306. ;        mov     MCR_BYTE,al     ; save them
  307.         mov     dx,lcr
  308. ;        in      al,dx           ; get line parameters
  309. ;        mov     LCR_BYTE,al     ; save them
  310.         mov     al,div_on
  311.         out     dx,al           ; set 8250 for baud rate selection
  312.         ; can the baud rate divisor be read to save the settings?
  313.         ; if so, stick the code here.
  314.         mov     ax,baud
  315.         mov     dx,mdmbad
  316.         out     dx,al           ; low byte divisor
  317.         mov     al,ah
  318.         inc     dx
  319.         out     dx,al           ; high byte divisor
  320.         mov     dx,lcr
  321.         mov     al,lcbyte
  322.         out     dx,al           ; set line control reg.
  323.         mov     dx,mcr
  324.         in      al,dx
  325.         or      al,mdmmod
  326.         out     dx,al           ; set DTR high
  327. flsh:   mov     dx,dataport
  328.         in      al,dx
  329.         mov     dx,mdmsta
  330.         in      al,dx
  331.         and     al,1
  332.         jnz     flsh
  333.  
  334.         pop     bp
  335.         ret
  336.  
  337. _set_tty endp
  338.  
  339.  
  340. _reset_tty proc near
  341.         push    bp
  342.  
  343.         pop     bp
  344.         ret
  345.  
  346. _reset_tty endp
  347.  
  348. _get_msr proc near
  349.         push    bp
  350.         push    ds              ; save data segment
  351.         push    cs
  352.         pop     ds
  353.  
  354.         xor     ax,ax
  355.         mov     dx,MDMMSR
  356.         in      al,dx
  357.  
  358.         pop     ds
  359.         pop     bp
  360.         ret
  361.  
  362. _get_msr endp
  363.  
  364. ;
  365. ; set_xoff(flag)         Enable (flag != 0) or disable
  366. ;int flag;              (flag == 0) XON/ XOFF protocol
  367. ;                       for the character input stream.
  368. ;If enabled, an XOFF will be sent when  the buffer
  369. ;reaches 3/4 full. NOTE: an XON will not be sent auto-
  370. ;matically. Your program must do it when it sees
  371. ;the _rcvd_xoff() flag,  and ready for more chars.
  372. ;
  373. _set_xoff proc near
  374.         push    bp
  375.         PUSH    DS              ;SAVE DATA SEGMENT
  376.         mov     bx,[bp+6]
  377.         push    cs
  378.         pop     ds              ; move code seg addr to data seg reg.
  379.         cmp     bx,0
  380.         jnz     to_on
  381.         mov     see_xoff,FALSE
  382.         jmp     done1
  383. to_on:  mov     see_xoff,TRUE
  384. done1:  pop     ds
  385.         pop     bp
  386.         ret
  387. _set_xoff endp
  388. ;
  389. ;flag = get_xoff()      Returns the current setting
  390. ;                       of the XON/ XOFF flag set
  391. ;by set_xoff(), above.
  392. ;
  393. _get_xoff proc near
  394.         push    bp
  395.         push    ds              ; save data reg
  396.         push    cs
  397.         pop     ds              ; move code seg addr to data seg reg.
  398.         xor     ax,ax
  399.         mov     al,see_xoff
  400.         pop     ds
  401.         pop     bp
  402.         ret
  403. _get_xoff endp
  404. ;
  405. ;flag = sent_xoff();    Returns true if an XOFF
  406. ;                       character was sent, indicating
  407. ;the receive buffer is  3/4 full.
  408. ;
  409. _sent_xoff proc  near
  410.         push    bp
  411.         push    ds              ; save data reg
  412.         push    cs
  413.         pop     ds              ; move code seg addr to data seg reg.
  414.         xor     ax,ax
  415.         mov     al,snt_xoff
  416.         pop     ds
  417.         pop     bp
  418.         ret
  419. _sent_xoff endp
  420. ;
  421. ; rcvd_xoff()            Returns true if an XOFF was
  422. ;                       received; will return false as
  423. ;soon as an XON is received. Does not effect data output,
  424. ;only indicates the above. (Obviously useless for binary
  425. ;data.)
  426. ;
  427. _rcvd_xoff proc  near
  428.         push    bp
  429.         push    ds              ; save data reg
  430.         push    cs
  431.         pop     ds              ; move code seg addr to data seg reg.
  432.         xor     ax,ax
  433.         mov     al,got_xoff
  434.         pop     ds              ; restore data reg
  435.         pop     bp
  436.         ret
  437. _rcvd_xoff endp
  438. ;
  439. ;count = inp_cnt()       Returns the number of characters
  440. ;                       available in the input buffer.
  441. ;
  442.  
  443. _inp_cnt proc near
  444.         push    bp
  445.         push    ds              ; save data segment
  446.         push    cs
  447.         pop     ds              ; move code seg addr to data seg reg
  448.         mov     ax,circ_ct
  449.         pop     ds
  450.         pop     bp
  451.         ret
  452. _inp_cnt endp
  453. ;
  454. ; inp_flush()    Flush the input buffer.
  455. ;
  456. _inp_flush proc  near
  457.         push    bp
  458.         push    ds              ; save data reg
  459.         push    cs
  460.         pop     ds              ; move code seg addr to data seg reg.
  461.         mov     bx,offset circ_buf
  462.         mov     circ_in,bx
  463.         mov     circ_cur,bx
  464.         xor     ax,ax
  465.         mov     circ_ct,ax
  466.         pop     ds
  467.         pop     bp
  468.         ret
  469. _inp_flush endp
  470.  
  471. ; --------- Init -----------------------------------
  472. ; Program initialization:
  473. ;   --  Set up vector for RS232 interrupt (0CH)
  474. ;   --  Enbl IRQ4
  475. ;   --  Enbl RS232 interrupt on data ready
  476. ;
  477. ; ---------------------------------------------------
  478.  
  479. _init_comm proc  near
  480.         push    bp
  481.         cli
  482.  
  483. ;  ---- Set up  INT x'0C' for IRQ4
  484.  
  485.         push    ds
  486.         push    cs
  487.         pop     ds              ;cs to ds
  488.         mov     dx,offset IntHdlr ;relative adddres of interrupt handler
  489.         mov     al,0cH          ;interrupt number for comm.
  490.         mov     ah,SetIntVect   ;function number for setting int vector
  491.         int     DosCall         ;set interrupt in 8086 table
  492.         pop     ds              ;restore DS
  493.  
  494. ;  ---- Enbl IRQ4 on 8259 interrupt controller
  495.  
  496.         cli
  497.  
  498.         in      al,IntCtlr      ; get current masks
  499.         and     al,EnblIRQ4     ; Reset IRQ4 mask
  500.         out     IntCtlr,al      ; And restore to IMR
  501.  
  502. ;  ---   Enbl 8250 data ready interrupt
  503.  
  504.         mov     dx,LCR          ; DX ==> LCR
  505.         in      al,dx           ; Reset DLAB for IER access
  506.         and     al,7FH
  507.         out     dx,al
  508.         mov     dx,IER          ; Interrupt Enbl Register
  509.         mov     al,EnblDRdy     ; Enable 'data-ready' interrupt
  510.         out     dx,al
  511.  
  512. ;  ---   Enbl OUT2 on 8250
  513.  
  514.         mov     dx,MCR          ; modem control register
  515.         in      al,dx           ; Enable OUT2
  516.         or      al,08h            ; find out what is in there and
  517.         out     dx,al            ; enable the DTR
  518.  
  519.         sti
  520.  
  521.         pop     bp
  522.         ret
  523. _init_comm endp
  524. ;
  525. ; uninit_comm()          Removes the interrupt structure
  526. ;                       installed by _init_comm(). Must be
  527. ;done before passing control to the DOS, else chars received
  528. ;will be stored into the next program loaded!
  529. ;
  530. _uninit_comm proc near
  531.         push    bp
  532. ; ---   Disable IRQ4 on 8259
  533.  
  534.         cli
  535.         in      al,IntCtlr      ;GET OCW1 FROM 8259
  536.         or      al,MaskIRQ4     ;DISABLE COMMUNICATIONS INTERRUPT
  537.         out     IntCtlr,al
  538.  
  539. ; ---   Disable 8250 data ready interrupt
  540.  
  541.         mov     dx,LCR          ; DX ==> LCR
  542.         in      al,dx           ; Reset DLAB for IER access
  543.         and     al,7FH
  544.         out     dx,al
  545.         mov     dx,IER          ; Interrupt Enbl Register
  546.         mov     al,0            ; Disable all 8250 interrupts
  547.         out     dx,al
  548.  
  549. ;  ---   Disable OUT2 on 8250
  550.  
  551.         mov     dx,MCR          ; modem control register
  552.         mov     al,0            ; Disable OUT2
  553.         out     dx,al
  554.  
  555.         sti
  556.         pop     bp
  557.         ret
  558. _uninit_comm endp
  559. ;
  560. ;char  inp_char()      Return a character from the input
  561. ;                      buffer. Assumes you have called
  562. ;inp_cnt() to see if theres any characters to get.
  563. ;
  564. _inp_char proc near
  565.         push    bp
  566.         push    ds              ; save data reg
  567.         push    cs
  568.         pop     ds              ; move code seg addr to data seg reg.
  569.         mov     bx,circ_cur
  570.         xor     ax,ax
  571.         mov     al,[bx]         ;get next char from circ_buf
  572.         DEC     circ_ct         ;decrement circ_buf COUNT
  573.         CMP     bx,circ_top     ;ARE WE AT THE TOP OF THE circ_buf?
  574.         JZ      reset_cur       ;JUMP IF SO
  575.         INC     bx              ;ELSE, BUMP PTR
  576.         JMP SHORT upd_cur
  577. reset_cur:
  578.         mov     bx,OFFSET circ_buf      ;RESET circ_in TO BOTTOM OF BUF.
  579. upd_cur:
  580.         mov     circ_cur,bx             ;SAVE NEW PTR
  581.         xor     cx,cx
  582.         mov     cl,see_xoff     ;check if interested in xon/xoff
  583.         cmp     cl,TRUE
  584.         jnz     clnup2          ;not interested, so goto return
  585.         cmp     snt_xoff,TRUE   ;have we sent an xoff?
  586.         jnz     clnup2          ;no, so return
  587.         cmp     circ_ct,80h     ;yes, so see in buf is now emptying
  588.         jg      clnup2          ;not empty enuf to send xon, jump to ret
  589.         mov     snt_xoff,FALSE
  590.         mov     cl,XON
  591.         push    ax              ; save char
  592.         call    comout
  593.         pop     ax
  594. clnup2: pop     DS              ;GET BACK ENTERING DS
  595.         pop     bp
  596.         ret
  597. _inp_char endp
  598. ;
  599. ; outp_char(c)           Output the character to the
  600. ;char c;                serial port. This is not buffered
  601. ;                       or interrupt driven.
  602. ;
  603. _outp_char proc  near
  604.         push    bp
  605.         mov     bp,sp
  606.         mov     cl,[bp+4]
  607.         sti
  608.         call    comout
  609.         pop     bp
  610.         ret
  611. _outp_char endp
  612. ;
  613. ;Local  subroutine: output CL to the port.
  614. ;
  615. comout: mov     dx,MDMSTA
  616.         in      al,dx           ; get 8250 status
  617.         and     al,MDMTBE       ; check for transmitter ready
  618.         jz      comout          ; jump if not to wait
  619.         mov     al,cl           ; get char to al
  620.         mov     dx,dataport
  621.         out     dx,al           ; output char to 8251
  622.         ret
  623. ;
  624. ;       RECEIVE INTERRUPT HANDLER (CHANGED TO PLACE CHARACTERS IN A
  625. ;        CIRCULAR circ_buf AND TO SEND AN XOFF IF THE circ_buf IS MORE THAN
  626. ;        3/4 FULL - S.G.)
  627. ;
  628. IntHdlr:
  629.         CLI
  630.         push    cx
  631.         push    dx
  632.         push    bx
  633.         push    ax
  634.         push    ds
  635.         mov     ax,cs           ;get cur code segment
  636.         mov     ds,ax           ;and set it as data segment
  637.         mov     bx,circ_in      ;GET circ_buf IN PTR
  638.         mov     DX,dataport     ;GET DATA PORT NUMBER
  639.         IN      AL,DX           ;GET RECEIVED CHARACTER
  640. ;       push    ax
  641. ;       push    dx
  642. ;       xor     ax,ax
  643. ;       xor     dx,dx
  644. ;       mov     dl,al
  645. ;       mov     ah,2
  646. ;       int     DosCall
  647. ;       pop     dx
  648. ;       pop     ax
  649.         xor     cx,cx
  650.         mov     cl,see_xoff     ;check if interested in xon/xoff
  651.         cmp     cl,TRUE
  652.         jnz     ck_full         ;not interested goto ck if buf full
  653.         mov     cl,al           ;put char in cl for testing
  654.         and     cl,7fh          ;turn off any parity bits
  655.         cmp     cl,XOFF         ;see if we got an xoff
  656.         jnz     ck_xon
  657.         mov     got_Xoff,TRUE   ; code for handling xon/xoff from remote
  658.         jmp     clnup
  659. ck_xon: cmp     cl,XON
  660.         jnz     reg_ch
  661.         mov     got_Xoff,FALSE
  662.         jmp     clnup
  663. ;
  664. ;Normal character; not  XON/XOFF, or XON/XOFF disabled.
  665. ;
  666. reg_ch: test    snt_Xoff,TRUE   ;SEE IF sentXoff IS SET
  667.         jnz     ck_full         ;IF SO, DON'T SEND ANOTHER XOFF
  668.         CMP     circ_ct,(BUFSIZ * 3)/4  ;ALLOW BUF TO BECOME 3/4 FULL BEFORE
  669.                                         ; SENDING XOFF
  670.         jb      savch           ;IF IT'S OK, CONTINUE
  671.         push    ax              ;SAVE CHARACTER
  672.         mov     CL,XOFF         ;GET XOFF CHARACTER
  673.         mov     snt_Xoff,TRUE  ;RESET sentXoff
  674.         call    comout          ; AND SEND IT
  675.         pop     ax              ;RETRIEVE CHARACTER
  676.         JMP SHORT savch         ;IF WE'RE HERE, THE circ_buf HAS BUFSIZ-80H
  677.                                 ;  CHARACTERS
  678. ck_full:
  679.         CMP     circ_ct,BUFSIZ  ;SEE IF circ_buf ALREADY FULL
  680.         JZ      clnup           ; JUMP IF SO, DO NOT PLACE CHARACTER IN BFR
  681. savch:
  682.         mov     [bx],AL         ;SAVE NEW CHARACTER IN circ_buf
  683.         inc     circ_ct         ;BUMP circ_buf COUNT
  684.         CMP     bx,circ_top     ;ARE WE AT THE TOP OF THE circ_buf?
  685.         JZ      reset_in        ;JUMP IF SO
  686.         inc     bx              ;ELSE, BUMP PTR
  687.         JMP SHORT into_buf
  688. reset_in:
  689.         mov     bx,OFFSET circ_buf      ;RESET circ_in TO BOTTOM OF BUF.
  690. into_buf:
  691.         mov     circ_in,bx              ;SAVE NEW PTR
  692. clnup:
  693.         mov     AL,RSTINT
  694.         OUT     RS8259,AL       ;ISSUE SPECIFIC EOI FOR 8259
  695.         pop     ds              ;GET BACK ENTERING DS
  696.         pop     ax
  697.         pop     bx
  698.         pop     dx
  699.         pop     cx
  700.         sti
  701.         iret
  702.  
  703. _TEXT   ENDS
  704.  
  705. end
  706. ---
  707.  
  708.    And that's all folks!!!
  709.  
  710.  
  711. --
  712. =======================================================================
  713. | ...sun!hoptoad!\                                     Tim Pozar      |
  714. |                 >fidogate!pozar               Fido:  1:125/406      |
  715. |  ...lll-winken!/                            PaBell:  (415) 788-3904 |
  716. |         USNail:  KKSF  77 Maiden Lane  San Francisco CA 94108       |
  717. =======================================================================
  718.