Category : Pascal Source Code
Archive   : PIBASY47.ZIP
Filename : ASYINT.ASM

 
Output of file : ASYINT.ASM contained in archive : PIBASY47.ZIP
STI ;Allow interrupts
;
; Begin major polling loop over pending interrupts.
;
; The polling loop is needed because the 8259 cannot handle another 8250
; interrupt while we service this interrupt. We keep polling here as long
; as an interrupt is received.
;
Poll: MOV DX,[>Async_Uart_IIR] ;Get Interrupt ident register
IN AL,DX ;Pick up interrupt type
;
TEST AL,1 ;See if any interrupt signalled.
JZ Polla ;Yes --- continue
JMP NEAR Back ;No --- return to invoker
;
; Determine type of interrupt.
; Possibilities:
;
; 0 = Modem status changed
; 2 = Transmit hold register empty (write char)
; 4 = Character received from port
; 6 = Line status changed
;
Polla: AND AL,6 ;Strip unwanted bits from interrupt type
CMP AL,4 ;Check if interrupt >= 4
JE Pollb ;
JMP NEAR Int2
;
; Write interrupts must be turned on if a higher-priority interrupt
; has been received, else the characters may not be sent (and a lockup
; may occur).
;
Pollb: PUSH AX ;Save interrupt type
CALL EnabWI ;Enable write interrupts
POP AX ;Restore interrupt type
;
; --- Received a character ----
;
Int4: CMP AL,4 ;Check for received char interrupt
JE Int4a ;Yes -- process it.
JMP NEAR Int2 ;No -- skip.
;
; Read the character from the serial port.
;
Int4a: MOV DX,[>Async_Base] ;Read character from port
IN AL,DX
;
; Check if spurious character rejection mode is active. If so, check
; the LSR for any error which occurred on this character. If any
; occurred, replace the character with the "noise filter" character.
;
TEST BYTE [ JZ Int4a1
;
TEST BYTE [ JZ Int4a1 ;No -- character must be OK
MOV AL,[>Async_Noise_Char] ;Else use "noise" character
AND BYTE [ ;
; Check if XON/XOFF honored. If so, check if incoming character is
; an XON or an XOFF.
;
Int4a1: TEST BYTE [ JZ Int4d ;No -- skip XON/XOFF checks
;
CMP AL, JE Int4b ;Skip if XON found
CMP AL, JNE Int4d ;Skip if XOFF not found
;
; XOFF received -- set flag indicating sending of chars isn't possible
;
MOV BYTE [ MOV BYTE [ JMP NEAR Poll
;
; XON received -- allow more characters to be sent.
;
Int4b: MOV BYTE [ MOV BYTE [ ;
CALL EnabWI ;Enable write interrupts
JMP NEAR Int4z
;
; Not XON/XOFF -- handle other character.
;
Int4d: TEST BYTE [>Async_Line_Status],2 ;Check for buffer overrun
JZ Int4e ;Yes --- don't store anything
JMP Int4z
;
Int4e: MOV BX,[>Async_Buffer_Head] ;Current position in input buffer
LES DI,[>Async_Buffer_Ptr] ;Pick up buffer address
ADD DI,BX ;Update position
ES: MOV [DI],AL ;Store received character in buffer
INC WORD [>Async_Buffer_Used] ;Increment count of chars in buffer
;
MOV AX,[>Async_Buffer_Used] ;Pick up buffer usage count
CMP AX,[>Async_MaxBufferUsed] ;See if greater usage than ever before
JLE Int4f ;Skip if not
MOV [>Async_MaxBufferUsed],AX ;This is greatest use thus far
;
Int4f: INC BX ;Increment buffer pointer
CMP BX,[>Async_Buffer_Size] ;Check if past end of buffer
JLE Int4h
XOR BX,BX ;If so, wrap around to front
;
Int4h: CMP WORD [>Async_Buffer_Tail],BX ;Check for overflow
JE Int4s ;Jump if head ran into tail
;
MOV [>Async_Buffer_Head],BX ;Update head pointer
;
; Check for receive buffer nearly full here.
;
; If XON/XOFF available, and buffer getting full, set up to send
; XOFF to remote system.
;
; This happens in two possible stages:
;
; (1) An XOFF is sent right when the buffer becomes 'Async_Buffer_High'
; characters full.
;
; (2) A second XOFF is sent right when the buffer becomes
; 'Async_Buffer_High_2' characters full; this case is likely the
; result of the remote not having seen our XOFF because it was
; lost in transmission.
;
; If CTS/RTS handshaking, then drop RTS here if buffer nearly full.
; Note that this has to be done even if the XOFF is being sent as well.
;
;
; Check receive buffer size against first high-water mark.
;
CMP AX,[>Async_Buffer_High] ;AX still has Async_Buffer_Used
JL Int4z ;Not very full, so keep going.
;
; Remember if we've already (supposedly) disabled sender.
;
MOV DL,[ ;
; Drop through means receive buffer getting full.
; Check for XON/XOFF.
;
TEST BYTE [ ; ; for buffer overflow
JZ Int4k ;No -- skip XON/XOFF checks
;
; Check if we've already sent XOFF.
;
TEST BYTE [ JZ Int4j ;No -- go send it now.
;
; Check against second high-water mark.
; If we are right at it, send an XOFF regardless of whether we've
; already sent one or not. (Perhaps the first got lost.)
;
CMP AX,[>Async_Buffer_High_2]
JNE Int4k ;Not at 2nd mark -- skip
;
Int4j: MOV BYTE [ CALL EnabWI ;Ensure write interrupts enabled
MOV BYTE [ ;
; Check here if we're doing hardware handshakes.
; Drop RTS if CTS/RTS handshaking.
; Drop DTR if DSR/DTR handshaking.
;
Int4k: TEST DL,1 ;See if sender already disabled
JZ Int4z ;Yes -- skip hardware handshakes.
;
XOR AH,AH ;No hardware handshakes
;
TEST BYTE [ JZ Int4l ;No -- skip it
;
MOV AH, ;
Int4l: TEST BYTE [ JZ Int4m ;No -- skip it
;
OR AH, ;
Int4m: CMP AH,0 ;Any hardware signal?
JZ Int4z ;No -- skip
;
MOV DX,[>Async_Uart_MCR] ;Get modem control register
IN AL,DX
NOT AH ;Complement hardware flags
AND AL,AH ;Nuke RTS/DTR
OUT DX,AL
;
MOV BYTE [ JMP Int4z
;
; If we come here, then the input buffer has overflowed.
; Characters will be thrown away until the buffer empties at least one slot.
;
Int4s: OR BYTE [>Async_Line_Status],2 ;Flag overrun
MOV BYTE [>Async_Buffer_OverFlow],1
;
Int4z: JMP NEAR Poll
;
; --- Write a character ---
;
Int2: CMP AL,2 ;Check for THRE interrupt
JE Int2a ;Yes -- process it.
JMP NEAR Int6 ;No -- skip.
;
; Check first if we need to send an XOFF to remote system.
;
Int2a: TEST BYTE [ JZ Int2d ;No -- skip it
;
; Yes, we are to send XOFF to remote.
;
; First, check DSR and CTS as requested.
; If those status lines aren't ready, turn off write interrupts and
; try later, after a line status change.
;
TEST BYTE [ JZ Int2b ;No -- skip it
;
MOV DX,[>Async_Uart_MSR] ;Get modem status register
IN AL,DX
TEST AL, JZ Int2e ;If not DSR, turn off write interrupts
;
Int2b: TEST BYTE [ JZ Int2c ;No -- skip it
;
MOV DX,[>Async_Uart_MSR] ;Get modem status register
IN AL,DX
TEST AL, JZ Int2e ;If not CTS, turn off write ints
;
; All status lines look OK.
; Send the XOFF.
;
Int2c: MOV AL, MOV DX,[>Async_Base] ;Get transmit hold register address
OUT DX,AL ;Output the XOFF
MOV BYTE [ MOV BYTE [ JMP NEAR Poll ;Return
;
; Not sending XOFF -- see if any character in buffer to be sent.
;
Int2d: MOV BX,[>Async_OBuffer_Tail] ;Pick up output buffer pointers
CMP BX,[>Async_OBuffer_Head]
JNE Int2m ;Skip if not equal --> something to send
;
; If nothing to send, turn off write interrupts to avoid unnecessary
; time spent handling useless THRE interrupts.
;
Int2e: MOV DX,[>Async_Uart_IER] ;If nothing -- or can't -- send ...
IN AL,DX ;
AND AL,$FD ;
OUT DX,AL ;... disable write interrupts
JMP NEAR Poll ;
;
; If something to send, ensure that remote system didn't send us XOFF.
; If it did, we can't send anything, so turn off write interrupts and
; wait for later (after an XON has been received).
;
Int2m: TEST BYTE [ JNZ Int2e ;Yes -- can't send anything now
;
; If we can send character, check DSR and CTS as requested.
; If those status lines aren't ready, turn off write interrupts and
; try later, after a line status change.
;
MOV DX,[>Async_Uart_MSR] ;Otherwise get modem status
IN AL,DX
MOV [>Async_Modem_Status],AL ;and save modem status for later
;
TEST BYTE [ JZ Int2n ;No -- skip it
;
TEST AL, JZ Int2e ;If not DSR, turn off write ints
;
Int2n: TEST BYTE [ JZ Int2o ;No -- skip it
;
TEST AL, JZ Int2e ;If not CTS, turn off write ints
;
; Everything looks OK for sending, so send the character.
;
Int2o: LES DI,[>Async_OBuffer_Ptr] ;Get output buffer pointer
ADD DI,BX ;Position to character to output
ES: MOV AL,[DI] ;Get character to output
MOV DX,[>Async_Base] ;Get transmit hold register address
OUT DX,AL ;Output the character
;
DEC WORD [>Async_OBuffer_Used] ;Decrement count of chars in buffer
INC BX ;Increment tail pointer
CMP BX,[>Async_OBuffer_Size] ;See if past end of buffer
JLE Int2z
XOR BX,BX ;If so, wrap to front
;
Int2z: MOV [>Async_OBuffer_Tail],BX ;Store updated buffer tail
JMP NEAR Poll
;
; --- Line status change ---
;
Int6: CMP AL,6 ;Check for line status interrupt
JNE Int0 ;No -- skip.
;
MOV DX,[>Async_Uart_LSR] ;Yes -- pick up line status register
IN AL,DX ;and its contents
AND AL,$1E ;Strip unwanted bits
MOV [>Async_Line_Status],AL ;Store for future reference
OR [>Async_Line_Error_Flags],AL ;Add to any past transgressions
;
JMP NEAR Poll
;
; --- Modem status change ---
;
Int0: CMP AL,0 ;Check for modem status change
JE Int0a ;Yes -- handle it
JMP NEAR Poll ;Else get next interrupt
;
Int0a: MOV DX,[>Async_Uart_MSR] ;Pick up modem status reg. address
IN AL,DX ;and its contents
MOV [>Async_Modem_Status],AL ;Store for future reference
CALL EnabWI ;Turn on write interrupts, in case
; ;status change resulted from CTS/DSR
; ;changing state.
JMP NEAR Poll
;
; Internal subroutine to enable write interrupts.
;
EnabWI: ;PROC NEAR
MOV DX,[>Async_Uart_IER] ;Get interrupt enable register
IN AL,DX ;Check contents of IER
TEST AL,2 ;See if write interrupt enabled
JNZ EnabRet ;Skip if so
OR AL,2 ;Else enable write interrupts ...
OUT DX,AL ;... by rewriting IER contents
EnabRet: RET ;Return to caller
;
; Send non-specific EOI to 8259 controller.
;
Back: MOV AL,$20 ;EOI = $20
CMP BYTE [>Async_Irq],8 ;Get IRQ level
JB Back2 ;Only reset 1st 8259
;
OUT $A0,AL ;Reset second 8259
Back2: OUT $20,AL ;Reset first 8259


  3 Responses to “Category : Pascal Source Code
Archive   : PIBASY47.ZIP
Filename : ASYINT.ASM

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/