📄 async.asm
字号:
out dx,al
;----- Return
pop ds
pop bp
ret
ENDP _AsyncStop
;-----------------------------------------------------------------------------
; AsyncISR Async Interrupt Service Routine
;-----------------------------------------------------------------------------
; To be called only as an interrupt.
;-----------------------------------------------------------------------------
PROC AsyncISR
push ax ; Save Registers
push bx
push ds
push dx
push cs
pop ds
call eoi
mov dx, [IIR] ; Check if data actually received
in al, dx
and al, 06h
cmp al, 04h
je @@receive
cmp al, 02h
jne @@3
;----- Transmit A byte
@@transmit:
mov ax,[word ptr ds:_TXints+2]
mov dx,[word ptr ds:_TXints]
add dx,1
adc ax,0
mov [word ptr ds:_TXints+2],ax
mov [word ptr ds:_TXints],dx
mov bx, [TransTail]
cmp bx, [TransHead]
jne @@1
mov dx, [IER] ; Buffer empty
mov al, 1
out dx, al ; Disable THR empty interrupt
@@3: jmp @@end
@@1:
mov al, [byte ptr bx] ; Get Byte
inc [TransTail] ; Update buffer pointer
cmp [word ptr TransTail], offset TransBuffer + BufSize
jb @@2
mov [TransTail], offset TransBuffer
@@2:
mov dx, [THR]
out dx, al
;
; check for rcv hwater
;
mov ax,[TransHead]
sub ax, [TransTail]
jge @@21
add ax, BufSize
@@21:
cmp ax, [_TXhw]
jle @@end
mov [_TXhw],ax
jmp @@end
;----- Recieve a byte
@@receive:
mov dx, [RDR] ; Get Byte
in al, dx
mov bx, [RecHead] ; Store Byte in buffer
mov [byte ptr bx], al
inc bx ; Update RecHead
cmp bx, offset RecBuffer + BufSize
jb @@10
mov bx, offset RecBuffer
@@10:
cmp bx, [RecTail]
jne @@20
mov bx, [RecHead] ; Cancel Pointer advance on overflow
inc [_RXoverrun]
@@20:
mov [RecHead], bx ; Store new pointer
mov ax,[word ptr ds:_RXints+2]
mov dx,[word ptr ds:_RXints]
add dx,1
adc ax,0
mov [word ptr ds:_RXints+2],ax
mov [word ptr ds:_RXints],dx
;
; check for rcv hwater
;
mov ax,[RecHead]
sub ax, [RecTail]
jge @@22
add ax, BufSize
@@22:
cmp ax, [_RXhw]
jle @@end
mov [_RXhw],ax
@@end:
; Disable and re-enable interrupts so that there
; is an interrupt edge.
; mov al, EOIX ; Signal end ot interrupt
; out Ctrl8259_0, al
mov dx,[IER] ; Point to Interrupt Enable Register.
in al,dx ; Read the current value.
push ax ; Save it.
mov al,0 ; Disable the interrupts.
out dx,al
pop ax ; Restore original mask.
out dx,al ; Re-enable interrupts.
pop dx ; Restore saved registers.
pop ds
pop bx
pop ax
iret
ENDP AsyncISR
;-----------------------------------------------------------------------------
; AsyncIn Gets a byte from the input buffer
;-----------------------------------------------------------------------------
; int AsyncIn( void)
;-----------------------------------------------------------------------------
PROC _AsyncIn
push bp
mov bp, sp
push ds
push cs
pop ds
xor ax, ax ; Pre-Set result to 0
mov bx, [RecTail]
cmp bx, [RecHead]
je @@return
mov al, [byte ptr bx]
inc [RecTail]
cmp [word ptr RecTail], offset RecBuffer + BufSize
jb @@return
mov [RecTail], offset RecBuffer
@@return:
pop ds
pop bp
ret
ENDP _AsyncIn
;-----------------------------------------------------------------------------
; AsyncOut Output a byte
;-----------------------------------------------------------------------------
; void AsyncOut( int c)
;-----------------------------------------------------------------------------
PROC _AsyncOut
ARG CharOut:word
push bp
mov bp, sp
push ds
push cs
pop ds
mov ax, [CharOut]
mov bx, [TransHead]
mov cx, bx
inc cx ; Compute NEW buffer position
cmp cx, offset TransBuffer + BufSize
jb @@1
mov cx, offset TransBuffer
cmp cx, [TransTail] ; Wait for space in buffer
jne @@2
inc [_TXoverrun]
mov cx, offset TransBuffer
cmp cx, [TransTail] ; Wait for space in buffer
@@1:
cmp cx, [TransTail] ; Wait for space in buffer
je @@1
@@2:
mov [byte ptr bx], al ; Add byte to buffer
mov [TransHead], cx ; Update pointer
mov dx, [IER] ; Enable THR empty interrupt
mov al, 3
out dx, al
mov ax,[IRQgen]
cmp ax,1
je myret
;
; Kick start transmit just in case enabling the int didn't generate
; an interrupt
mov al,[VectorNum]
mov [cs:intit],al
nop ; Since we're modifing code we will
nop ; immediately execute, we put a few
nop ; nop's to allow for possible pre-fetch
nop
db 0CDh
intit db ?
mov ax,1
mov [IRQgen],ax
myret:
pop ds
pop bp
ret
ENDP _AsyncOut
;-----------------------------------------------------------------------------
; AsyncSet Set communication paramaters
;-----------------------------------------------------------------------------
; void AsyncSet( int Baud, int Control)
;
; Baud = 150, 300, 600, 1200, 2400, 4800, 9600, 19200, 28800, 38400, 57600
; Baud of 115200 is set when parameter passed in is 0
; Control = The value to place in the LCR
;-----------------------------------------------------------------------------
PROC _AsyncSet
ARG Baud:word, Control:word
push bp
mov bp, sp
push ds
push cs
pop ds
mov bx, [Baud]
cmp bx, 0
jne @@set115200
mov ax, 1
jmp @@skipit
@@set115200:
mov ax, 0C200h ; Baud rate divisor = 115200 / Baud
mov dx, 0001h ; 115200 = 0001C200h
div bx
@@skipit:
mov cx, ax
cli
mov dx, [LCR] ; Set Port Toggle to BRDL/BRDH registers
mov al, 0ffh
out dx, al
mov dx, [BRDL] ; Set Baud Rate
mov al, cl
out dx, al
mov dx, [BRDH]
mov al, ch
out dx, al
mov dx, [LCR] ; Set LCR and Port Toggle
mov ax, [Control]
and al, 07Fh
out dx, al
sti
pop ds
pop bp
ret
ENDP _AsyncSet
;-----------------------------------------------------------------------------
; AsyncInStat Returns the # of characters in buffer
;-----------------------------------------------------------------------------
; int AsyncInStat( void)
;-----------------------------------------------------------------------------
PROC _AsyncInStat
push bp
mov bp, sp
push ds
push cs
pop ds
mov ax,[RecHead]
sub ax, [RecTail]
jge @@10
add ax, BufSize
@@10:
pop ds
pop bp
ret
ENDP _AsyncInStat
;-----------------------------------------------------------------------------
; AsyncOutStat Returns the # of characters in buffer
;-----------------------------------------------------------------------------
; int AsyncOutStat( void)
;-----------------------------------------------------------------------------
PROC _AsyncOutStat
push bp
mov bp, sp
push ds
push cs
pop ds
mov ax,[TransHead]
sub ax, [TransTail]
jge @@10
add ax, BufSize
@@10:
pop ds
pop bp
ret
ENDP _AsyncOutStat
;-----------------------------------------------------------------------------
; AsyncHand Sets various handshaking lines
;-----------------------------------------------------------------------------
; void AsyncHand( int Hand)
;-----------------------------------------------------------------------------
PROC _AsyncHand
ARG Hand:word
push bp
mov bp, sp
push ds
push cs
pop ds
mov dx, [MCR]
mov ax, [Hand]
or al, 08h ; Keep interrupt enable ON
out dx, al
pop ds
pop bp
ret
ENDP _AsyncHand
;-----------------------------------------------------------------------------
; AsyncStat Returns Async/Modem status
;-----------------------------------------------------------------------------
; unsigned AsyncStat( void)
;
; MSR is returned in the high byte, LSR in the low byte
;-----------------------------------------------------------------------------
PROC _AsyncStat
push bp
mov bp, sp
push ds
push cs
pop ds
mov dx, [MSR]
in al, dx
mov cl, al
mov dx, [LSR]
in al, dx ; LSR in low byte
mov ah, cl ; MSR in high byte
pop ds
pop bp
ret
ENDP _AsyncStat
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -