?? async.asm
字號(hào):
; interrupt driven serial port I/O module.
; written by David Kessner
; modified for MASM 5.1 compatibility on 1994-04-11 by Wolfgang Krause
; modified for better use with season on 1995-02-02 by MB
.MODEL SMALL
EOI equ 020h ; 8259 end-of-interupt
Ctrl8259_0 equ 020h ; 8259 port
Ctrl8259_1 equ 021h ; 8259 port (Masks)
BufSize equ 512 ; Buffer Size
_DATA SEGMENT WORD PUBLIC 'DATA'
assume cs:DGROUP, ds:DGROUP, ss:DGROUP
.DATA
; Various things to be set upon AsyncInit()
VectorNum db ? ; Vector Number
EnableIRQ db ? ; Mask to enable 8259 IRQ
DisableIRQ db ? ; Mask to disable 8259 IRQ
VectorSeg dw ? ; Old Vector Segment
VectorOfs dw ? ; Old Vector Offset
; Register Addresses for the 8250 UART
Port dw ? ; Port Base Address
RegStart LABEL WORD
THR dw ? ; Transmitter Holding Register
RDR dw ? ; Reciever Data Register
BRDL dw ? ; Baud Rate Divisor, Low byte
BRDH dw ? ; Baud Rate Divisor, High Byte
IER dw ? ; Interupt Enable Register
IIR dw ? ; Interupt Identification Register
LCR dw ? ; Line Control Register
MCR dw ? ; Modem Control Register
LSR dw ? ; Line Status Register
MSR dw ? ; Modem Status Register
; Buffer Data
RecBuffer db BufSize DUP (?) ; Recieve Buffer
RecHead dw ? ; Buffer Head Pointer
RecTail dw ? ; Buffer Tail Pointer
TransBuffer db BufSize DUP (?) ; Transmit Buffer
TransHead dw ? ; Buffer Head Pointer
TransTail dw ? ; Buffer Tail Pointer
; Register Offsets for the UART
RegOffsets dw 0, 0, 0, 1, 1, 2, 3, 4, 5, 6
_DATA ENDS
_TEXT SEGMENT WORD PUBLIC 'CODE'
assume cs:_TEXT, ds:DGROUP, ss:DGROUP
PUBLIC _AsyncInit, _AsyncClear, _AsyncStop
PUBLIC _AsyncIn, _AsyncOut, _AsyncSet
PUBLIC _AsyncHand, _AsyncStat, _AsyncInStat
PUBLIC _AsyncOutStat
;-----------------------------------------------------------------------------
; AsyncClear Empty the recieve buffer
;-----------------------------------------------------------------------------
; void AsyncClear( void);
;
;
;-----------------------------------------------------------------------------
_AsyncClear PROC NEAR
cli
push ax
mov ax, offset RecBuffer
mov [RecHead], ax
mov [RecTail], ax
mov ax, offset TransBuffer
mov [TransHead], ax
mov [TransTail], ax
pop ax
sti
ret
_AsyncClear ENDP
;-----------------------------------------------------------------------------
; AsyncInit Initalize Serial Port and install ISR
;-----------------------------------------------------------------------------
; void AsyncInit( int port)
;
; Where Port is
; 0 = COM1
; 1 = COM2
; 2 = COM3
; 3 = COM4
;
;-----------------------------------------------------------------------------
_AsyncInit PROC NEAR
CommPort equ bp+4
push bp
mov bp, sp
;---- Set various things according to com port number
mov ax, [CommPort]
;----- COM1
cmp ax, 0
jne _AsyncInit_1
mov [Port], 03F8h
mov [VectorNum], 0Ch
mov [EnableIRQ], 0EFh
mov [DisableIRQ], 10h
jmp _AsyncInit_Done
_AsyncInit_1:
;----- COM2
cmp ax, 1
jne _AsyncInit_2
mov [Port], 02F8h
mov [VectorNum], 0Bh
mov [EnableIRQ], 0F7h
mov [DisableIRQ], 08h
jmp _AsyncInit_Done
_AsyncInit_2:
;----- COM3
cmp ax, 2 ; 2
jne _AsyncInit_3
mov [Port], 03E8h ; 03E8
mov [VectorNum], 0Ch ; 0C
mov [EnableIRQ], 0EFh ; EF
mov [DisableIRQ], 10h ; 10
jmp _AsyncInit_Done
_AsyncInit_3:
;----- COM4
mov [Port], 02E8h ; 02E8
mov [VectorNum], 0Bh ; 0B
mov [EnableIRQ], 0F7h ; F7
mov [DisableIRQ], 08h ; 08
_AsyncInit_Done:
;---- Compute Register locations
mov cx, 10
mov bx, offset RegOffsets
push di
mov di, offset RegStart
_AsyncInit_4:
mov ax, [bx]
add ax, [Port]
mov [di], ax
add bx, 2
add di, 2
loop _AsyncInit_4
pop di
;----- Initalize Buffer
call _AsyncClear
;--- Save and reassign interrupt vector
push ds ; Save Old Vector
mov al,[VectorNum]
mov ah,35h
int 21h
mov [VectorSeg], es
mov [VectorOfs], bx
mov al, [VectorNum]
push cs ; Set New Vector
pop ds
mov dx, offset AsyncISR
mov ah, 25h
int 21h
pop ds
;----- Enable 8259 interrupt (IRQ) line for this async adapter
in al, Ctrl8259_1
and al, [EnableIRQ]
out Ctrl8259_1, al
;----- Enable 8250 Interrupt-on-data-ready
mov dx, [LCR] ; Read Line control register and clear
in al, dx ; bit 7, the Divisor Latch Address
and al, 07Fh
out dx, al
mov dx, [IER]
mov al, 0 ; we're gonna test the UART first
out dx, al
in al, dx ; if this isn't 0, there's no UART
cmp al, 0
jnz _AsyncInit_222
mov al, 3
out dx, al
;----- Clear 8250 Status and data registers
_AsyncInit_10:
mov dx, [RDR] ; Clear RDR by reading port
in al, dx
mov dx, [LSR] ; Clear LSR
in al, dx
mov dx, [MSR] ; Clear MSR
in al, dx
mov dx, [IIR] ; Clear IIR
in al, dx
test al, 1
jz _AsyncInit_10
;----- Set Bit 3 of MCR -- Enable interupts
mov dx, [MCR]
in al, dx
or al, 08h
out dx, al
;----- Clear Buffer Just in case
call _AsyncClear
;----- Return
xor ax, ax
_AsyncInit_222:
pop bp
ret
_AsyncInit ENDP
;-----------------------------------------------------------------------------
; AsyncStop Uninstall ISR
;-----------------------------------------------------------------------------
; void AsyncStop( void)
;-----------------------------------------------------------------------------
_AsyncStop PROC NEAR
push bp
mov bp, sp
;----- Mask (disable) 8259 IRQ Interrupt
in al, Ctrl8259_1
or al, [DisableIRQ]
out Ctrl8259_1, al
;----- Disable 8250 interrupt
mov dx, [LCR]
in al, dx
and al, 07Fh
out dx, al
mov dx, [IER]
xor al, al
out dx, al
;----- Set bit 3 in MCR to 0
mov dx, [MCR]
in al, dx
and al, 0F7h
out dx, al
;----- Interrupts are disables. Restore saved interrupt vector.
push ds
mov al, [VectorNum]
mov ah, 25h
mov dx, [VectorOfs]
mov ds, [VectorSeg]
int 21h
pop ds
;----- Return
pop bp
ret
_AsyncStop ENDP
;-----------------------------------------------------------------------------
; AsyncISR Async Interrupt Service Routine
;-----------------------------------------------------------------------------
; To be called only as an interrupt.
;-----------------------------------------------------------------------------
AsyncISR PROC NEAR
push ax ; Save Registers
push bx
push ds
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -