home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / progm / pibasy.zip / ASYINT.ASM < prev    next >
Assembly Source File  |  1987-11-11  |  13KB  |  286 lines

  1.          STI                                ;Allow interrupts
  2. ;
  3. ;  Begin major polling loop over pending interrupts.
  4. ;
  5. ;  The polling loop is needed because the 8259 cannot handle another 8250
  6. ;  interrupt while we service this interrupt.  We keep polling here as long
  7. ;  as an interrupt is received.
  8. ;
  9. Poll:    MOV     DX,[>Async_Uart_IIR]       ;Get Interrupt ident register
  10.          IN      AL,DX                      ;Pick up interrupt type
  11. ;
  12.          TEST    AL,1                       ;See if any interrupt signalled.
  13.          JZ      Polla                      ;Yes --- continue
  14.          JMP     NEAR Back                  ;No  ---  return to invoker
  15. ;
  16. ;  Determine type of interrupt.
  17. ;  Possibilities:
  18. ;
  19. ;     0 = Modem status changed
  20. ;     2 = Transmit hold register empty (write char)
  21. ;     4 = Character received from port
  22. ;     6 = Line status changed
  23. ;
  24. Polla:   AND     AL,6                       ;Strip unwanted bits from interrupt type
  25.          CMP     AL,4                       ;Check if interrupt >= 4
  26.          JE      Pollb                      ;
  27.          JMP     NEAR Int2
  28. ;
  29. ;  Write interrupts must be turned on if a higher-priority interrupt
  30. ;  has been received, else the characters may not be sent (and a lockup
  31. ;  may occur).
  32. ;
  33. Pollb:   PUSH    AX                         ;Save interrupt type
  34.          CALL    EnabWI                     ;Enable write interrupts
  35.          POP     AX                         ;Restore interrupt type
  36. ;
  37. ;  --- Received a character ----
  38. ;
  39. Int4:    CMP     AL,4                       ;Check for received char interrupt
  40.          JE      Int4a                      ;Yes -- process it.
  41.          JMP     NEAR Int2                  ;No -- skip.
  42. ;
  43. ;  Read the character from the serial port.
  44. ;
  45. Int4a:   MOV     DX,[>Async_Base]           ;Read character from port
  46.          IN      AL,DX
  47. ;
  48. ;  Check if XON/XOFF honored.  If so, check if incoming character is
  49. ;  an XON or an XOFF.
  50. ;
  51.          TEST    BYTE [<Async_Do_XonXoff],1 ;See if we honor XON/XOFF
  52.          JZ      Int4d                      ;No -- skip XON/XOFF checks
  53. ;
  54.          CMP     AL,<XON                    ;See if XON found
  55.          JE      Int4b                      ;Skip if XON found
  56.          CMP     AL,<XOFF                   ;See if XOFF found
  57.          JNE     Int4d                      ;Skip if XOFF not found
  58. ;
  59. ;  XOFF received -- set flag indicating sending of chars isn't possible
  60. ;
  61.          MOV     BYTE [<Async_XOFF_Received],1    ;Turn on received XOFF flag
  62.          MOV     BYTE [<Async_XOFF_Rec_Display],1 ;Turn on display flag
  63.          JMP     NEAR Poll
  64. ;
  65. ;  XON received -- allow more characters to be sent.
  66. ;
  67. Int4b:   MOV     BYTE [<Async_XOFF_Received],0   ;Turn off received XOFF flag
  68.          MOV     BYTE [<Async_XON_Rec_Display],1 ;Turn on display flag
  69. ;
  70.          CALL    EnabWI                     ;Enable write interrupts
  71.          JMP     NEAR Int4z
  72. ;
  73. ;  Not XON/XOFF -- handle other character.
  74. ;
  75. Int4d:   TEST    BYTE [>Async_Line_Status],2 ;Check for buffer overrun
  76.          JNZ     Int4z                      ;Yes --- don't store anything
  77. ;
  78.          MOV     BX,[>Async_Buffer_Head]    ;Current position in input buffer
  79.          LES     DI,[>Async_Buffer_Ptr]     ;Pick up buffer address
  80.          ADD     DI,BX                      ;Update position
  81.      ES: MOV     [DI],AL                    ;Store received character in buffer
  82.          INC     WORD [>Async_Buffer_Used]  ;Increment count of chars in buffer
  83. ;
  84.          MOV     AX,[>Async_Buffer_Used]    ;Pick up buffer usage count
  85.          CMP     AX,[>Async_MaxBufferUsed]  ;See if greater usage than ever before
  86.          JLE     Int4f                      ;Skip if not
  87.          MOV     [>Async_MaxBufferUsed],AX  ;This is greatest use thus far
  88. ;
  89. Int4f:   INC     BX                         ;Increment buffer pointer
  90.          CMP     BX,[>Async_Buffer_Size]    ;Check if past end of buffer
  91.          JLE     Int4h
  92.          XOR     BX,BX                      ;If so, wrap around to front
  93. ;
  94. Int4h:   CMP     WORD [>Async_Buffer_Tail],BX ;Check for overflow
  95.          JE      Int4s                      ;Jump if head ran into tail
  96. ;
  97.          MOV     [>Async_Buffer_Head],BX    ;Update head pointer
  98. ;
  99. ;  If XON/XOFF available, and buffer getting full, set up to send
  100. ;  XOFF to remote system.
  101. ;
  102. ;  This happens in two possible stages:
  103. ;
  104. ;     (1)  An XOFF is sent right when the buffer becomes 'Async_Buffer_High'
  105. ;          characters full.
  106. ;
  107. ;     (2)  A second XOFF is sent right when the buffer becomes
  108. ;          'Async_Buffer_High_2' characters full;  this case is likely the
  109. ;          result of the remote not having seen our XOFF because it was
  110. ;          lost in transmission.
  111. ;
  112.          TEST    BYTE [<Async_Do_XonXoff],1 ;See if we honor XON/XOFF
  113.          JZ      Int4z                      ;No -- skip XON/XOFF checks
  114. ;
  115. ;  Check against first high-water mark.
  116. ;
  117.          CMP     AX,[>Async_Buffer_High]    ;AX still has Async_Buffer_Used
  118.          JL      Int4z                      ;Not very full, so keep going.
  119. ;
  120. ;  Check if we've already sent XOFF.
  121. ;
  122.          TEST    BYTE [<Async_XOFF_Sent],1  ;Remember if we sent XOFF or not
  123.          JZ      Int4j                      ;No -- go send it now.
  124. ;
  125. ;  Check against second high-water mark.
  126. ;  If we are right at it, send an XOFF regardless of whether we've
  127. ;  already sent one or not.  (Perhaps the first got lost.)
  128. ;
  129.          CMP     AX,[>Async_Buffer_High_2]
  130.          JNE     Int4z                      ;Not at 2nd mark -- skip
  131. ;
  132. Int4j:   MOV     BYTE [<Async_Send_XOFF],1  ;Indicate we need to send XOFF
  133.          CALL    EnabWI                     ;Ensure write interrupts enabled
  134.          JMP     NEAR Poll                  ;
  135. ;
  136. ;  If we come here, then the input buffer has overflowed.
  137. ;  Characters will be thrown away until the buffer empties at least one slot.
  138. ;
  139. Int4s:   OR      BYTE PTR [>Async_Line_Status],2 ;Flag overrun
  140. ;
  141. Int4z:   JMP     NEAR Poll
  142. ;
  143. ;  --- Write a character ---
  144. ;
  145. Int2:    CMP     AL,2                       ;Check for THRE interrupt
  146.          JE      Int2a                      ;Yes -- process it.
  147.          JMP     NEAR Int6                  ;No -- skip.
  148. ;
  149. ;  Check first if we need to send an XOFF to remote system.
  150. ;
  151. Int2a:   TEST    BYTE [<Async_Send_Xoff],1  ;See if we are sending XOFF
  152.          JZ      Int2d                      ;No -- skip it
  153. ;
  154. ;  Yes, we are to send XOFF to remote.
  155. ;
  156. ;  First, check DSR and CTS as requested.
  157. ;  If those status lines aren't ready, turn off write interrupts and
  158. ;  try later, after a line status change.
  159. ;
  160.          TEST    BYTE [<Async_Do_DSR],1     ;See if DSR checking required
  161.          JZ      Int2b                      ;No -- skip it
  162. ;
  163.          MOV     DX,[>Async_Uart_MSR]       ;Get modem status register
  164.          IN      AL,DX
  165.          TEST    AL,<Async_DSR              ;Check for Data Set Ready
  166.          JZ      Int2e                      ;If not DSR, turn off write interrupts
  167. ;
  168. Int2b:   TEST    BYTE [<Async_Do_CTS],1     ;See if CTS checking required
  169.          JZ      Int2c                      ;No -- skip it
  170. ;
  171.          MOV     DX,[>Async_Uart_MSR]       ;Get modem status register
  172.          IN      AL,DX
  173.          TEST    AL,<Async_CTS              ;Check for Clear To Send
  174.          JZ      Int2e                      ;If not CTS, turn off write ints
  175. ;
  176. ;  All status lines look OK.
  177. ;  Send the XOFF.
  178. ;
  179. Int2c:   MOV     AL,<XOFF                   ;Get XOFF Character
  180.          MOV     DX,[>Async_Base]           ;Get transmit hold register address
  181.          OUT     DX,AL                      ;Output the XOFF
  182.          MOV     BYTE [<Async_Send_XOFF],0  ;Turn off send XOFF flag
  183.          MOV     BYTE [<Async_XOFF_Sent],1  ;Turn on sent XOFF flag
  184.          JMP     NEAR Poll                  ;Return
  185. ;
  186. ;  Not sending XOFF -- see if any character in buffer to be sent.
  187. ;
  188. Int2d:   MOV     BX,[>Async_OBuffer_Tail]   ;Pick up output buffer pointers
  189.          CMP     BX,[>Async_OBuffer_Head]
  190.          JNE     Int2m                      ;Skip if not equal --> something to send
  191. ;
  192. ;  If nothing to send, turn off write interrupts to avoid unnecessary
  193. ;  time spent handling useless THRE interrupts.
  194. ;
  195. Int2e:   MOV     DX,[>Async_Uart_IER]       ;If nothing -- or can't -- send ...
  196.          IN      AL,DX                      ;
  197.          AND     AL,$FD                     ;
  198.          OUT     DX,AL                      ;... disable write interrupts
  199.          JMP     NEAR Poll                  ;
  200. ;
  201. ;  If something to send, ensure that remote system didn't send us XOFF.
  202. ;  If it did, we can't send anything, so turn off write interrupts and
  203. ;  wait for later (after an XON has been received).
  204. ;
  205. Int2m:   TEST    BYTE [<Async_XOFF_Received],1 ;See if we received XOFF
  206.          JNZ     Int2e                      ;Yes -- can't send anything now
  207. ;
  208. ;  If we can send character, check DSR and CTS as requested.
  209. ;  If those status lines aren't ready, turn off write interrupts and
  210. ;  try later, after a line status change.
  211. ;
  212.          MOV     DX,[>Async_Uart_MSR]       ;Otherwise get modem status
  213.          IN      AL,DX
  214.          MOV     [>Async_Modem_Status],AL   ;and save modem status for later
  215. ;
  216.          TEST    BYTE [<Async_Do_DSR],1     ;See if DSR checking required
  217.          JZ      Int2n                      ;No -- skip it
  218. ;
  219.          TEST    AL,<Async_DSR              ;Check for Data Set Ready
  220.          JZ      Int2e                      ;If not DSR, turn off write ints
  221. ;
  222. Int2n:   TEST    BYTE [<Async_Do_CTS],1     ;See if CTS checking required
  223.          JZ      Int2o                      ;No -- skip it
  224. ;
  225.          TEST    AL,<Async_CTS              ;Check for Clear To Send
  226.          JZ      Int2e                      ;If not CTS, turn off write ints
  227. ;
  228. ;  Everything looks OK for sending, so send the character.
  229. ;
  230. Int2o:   LES     DI,[>Async_OBuffer_Ptr]    ;Get output buffer pointer
  231.          ADD     DI,BX                      ;Position to character to output
  232.      ES: MOV     AL,[DI]                    ;Get character to output
  233.          MOV     DX,[>Async_Base]           ;Get transmit hold register address
  234.          OUT     DX,AL                      ;Output the character
  235. ;
  236.          DEC     WORD [>Async_OBuffer_Used] ;Decrement count of chars in buffer
  237.          INC     BX                         ;Increment tail pointer
  238.          CMP     BX,[>Async_OBuffer_Size]   ;See if past end of buffer
  239.          JLE     Int2z
  240.          XOR     BX,BX                      ;If so, wrap to front
  241. ;
  242. Int2z:   MOV     [>Async_OBuffer_Tail],BX   ;Store updated buffer tail
  243.          JMP     NEAR Poll
  244. ;
  245. ;  --- Line status change ---
  246. ;
  247. Int6:    CMP     AL,6                       ;Check for line status interrupt
  248.          JNE     Int0                       ;No -- skip.
  249. ;
  250.          MOV     DX,[>Async_Uart_LSR]       ;Yes -- pick up line status register
  251.          IN      AL,DX                      ;and its contents
  252.          AND     AL,$1E                     ;Strip unwanted bits
  253.          MOV     [>Async_Line_Status],AL    ;Store for future reference
  254.          OR      [>Async_Line_Error_Flags],AL ;Add to any past transgressions
  255.          JMP     NEAR Poll
  256. ;
  257. ;  --- Modem status change ---
  258. ;
  259. Int0:    CMP     AL,0                       ;Check for modem status change
  260.          JE      Int0a                      ;Yes -- handle it
  261.          JMP     NEAR Poll                  ;Else get next interrupt
  262. ;
  263. Int0a:   MOV     DX,[>Async_Uart_MSR]       ;Pick up modem status reg. address
  264.          IN      AL,DX                      ;and its contents
  265.          MOV     [>Async_Modem_Status],AL   ;Store for future reference
  266.          CALL    EnabWI                     ;Turn on write interrupts, in case
  267. ;                                           ;status change resulted from CTS/DSR
  268. ;                                           ;changing state.
  269.          JMP     NEAR Poll
  270. ;
  271. ;  Internal subroutine to enable write interrupts.
  272. ;
  273. EnabWI: ;PROC    NEAR
  274.          MOV     DX,[>Async_Uart_IER]       ;Get interrupt enable register
  275.          IN      AL,DX                      ;Check contents of IER
  276.          TEST    AL,2                       ;See if write interrupt enabled
  277.          JNZ     EnabRet                    ;Skip if so
  278.          OR      AL,2                       ;Else enable write interrupts ...
  279.          OUT     DX,AL                      ;... by rewriting IER contents
  280. EnabRet: RET                                ;Return to caller
  281. ;
  282. ;  Send non-specific EOI to 8259 controller.
  283. ;
  284. Back:    MOV     AL,$20                     ;EOI = $20
  285.          OUT     $20,AL
  286.