SERTYPE 掃描系統 BIOS 數據區 (0040h:0000h) 中的 COM 端口基址 (最多 4 個),對每個存在的端口通過 I/O 端口操作識別 UART 型號:
檢測結果直接輸出到屏幕,無參數交互。
uartdet 子程序)PUSH BX, CX,BX 保存基址。CH=1。endudet。CH=2。CH=3。AL=CH (0-3)。| 偏移 | 讀/寫 | 功能 |
|---|---|---|
| +0 | R/W | RBR/THR/DLL (接收/發送緩衝/除數鑰低位) |
| +1 | R/W | IER/DLM (中斷使能/除數鑰高位) |
| +2 | R | IIR (中斷識別) |
| +2 | W | FCR (FIFO 控制) |
| +3 | R/W | LCR (線路控制) |
| +4 | R/W | MCR (Modem 控制) |
| +5 | R | LSR (線路狀態) |
| +6 | R | MSR (Modem 狀態) |
| +7 | R/W | SCR (Scratch 暫存) |
comment *
SERTYPE.ASM
Purpose: Determines the type of UART in each serial port
Author: Douglas Boling, in PcMag. With some modifications by Yousuf Khan.
*
dosseg
bdseg segment at 40h
com1 dw ?
com2 dw ?
com3 dw ?
com4 dw ?
ends
_data segment para 'data'
uart1 db 0
uart2 db 0
uart3 db 0
uart4 db 0
portmsg db "COMx: $"
x8250 db "NS 8250 (non-FIFO)",13,10,"$"
x16450 db "NS 8250A/16450/16550 (non-FIFO)",13,10,"$"
xfifo db "NS 16550A/Intel 82510 (FIFO)",13,10,"$"
xdma db "IBM type 3 (FIFO/DMA)",13,10,"$"
pas_de_ports db "No serial ports detected",13,10,"$"
ends
_stack segment para stack 'stack'
db 200h dup (?)
ends
cseg segment para 'code'
mov ax, bdseg
mov es, ax
mov ax, _data
mov ds, ax
assume cs:cseg, ds:_data, es:bdseg, ss:_stack
xor al, al
mov dx, [com1]
cmp dx, 0
je eoproc
inc al
push ax
call uartdet
mov [uart1], al
pop ax
mov dx, [com2]
cmp dx, 0
je eoproc
inc al
push ax
call uartdet
mov [uart2], al
pop ax
mov dx, [com3]
cmp dx, 0
je eoproc
inc al
push ax
call uartdet
mov [uart3], al
pop ax
mov dx, [com4]
cmp dx, 0
je eoproc
inc al
push ax
call uartdet
mov [uart4], al
pop ax
eoproc:
call disp
mov ah, 4ch
int 21h
delay macro
jmp $+2
endm
uartdet proc near
push bx
push cx
mov bx, dx
add dx, 4
in al, dx
push ax
and al, 11111011b
out dx, al
mov ch, 0
mov dx, bx
add dx, 7
mov al, 55h
cli
out dx, al
delay
in al, dx
cmp al, 55h
jne endudet
mov al, 0AAh
out dx, al
delay
in al, dx
sti
cmp al, 0AAh
jne endudet
inc ch
mov dx, bx
add dx, 2
mov al, 7
cli
out dx, al
delay
in al, dx
sti
and al, 0c0h
jz endudet
inc ch
mov dx, bx
add dx, 8003h
cli
in al, dx
push ax
or al, 01000000b
out dx, al
push dx
mov dx, bx
add dx, 2
in al, dx
mov cl, al
pop dx
pop ax
out dx, al
sti
and cl, 0c0h
cmp cl, 40h
jne endudet
inc ch
endudet:
pop ax
mov dx, bx
add dx, 4
out dx, al
xor ax, ax
mov al, ch
mov dx, bx
pop cx
pop bx
ret
uartdet endp
disp proc near
push ax
cmp al, 0
je noports
mov bx, offset ds:[uart1]
mov di, offset ds:[portmsg][3]
mov cx, 0
mov cl, al
@l1:
mov dl, 4
sub dl, cl
add dl, 30h
mov [di], dl
lea dx, portmsg
mov ah, 9
int 21h
mov dl, [bx]
cmp dl, 0
jne @t2
lea dx, x8250
mov ah, 9
int 21h
jmp @eot
@t2: cmp dl, 1
jne @t3
lea dx, x16450
mov ah, 9
int 21h
jmp @eot
@t3: cmp dl, 2
jne @t4
lea dx, xfifo
mov ah, 9
int 21h
jmp @eot
@t4: lea dx, xdma
mov ah, 9
int 21h
@eot: inc bx
loop @l1
jmp eoproc2
noports:
lea dx, pas_de_ports
mov ah, 9
int 21h
eoproc2:
pop ax
ret
disp endp
ends
end
delay macro (JMP $+2) 提供極短 I/O 恢復延遲,兼容慢速總線。現代系統串口多為 PCIe/USB 虛擬 UART,BIOS 數據區可能不再準確反映硬件。但該檢測邏輯在嵌入式開發、舊硬件維護、引導加載器早期串口初始化中仍具參考價值。理解 8250/16450/16550/16550A/16750/16950 等 UART 演進歷史,有助於編寫健壯的串口驅動。