Hello Sylvain,
Sylvain Lauzon wrote to All :
SL> A routine to find whether or not a 16550 installed.
Maybe the following program helps you. I have found it on a disk that was
included with "the undocumented PC" book :
>>> File: /floppy/sertype.asm <<<
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; SERIAL TYPE
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;
; Reports current serial port I/O addresses, checks the port
; has a UART attached, and determines the basic chip type.
;
; (c) Copyright 1994 Frank van Gilluwe All Rights Reserved.
include undocpc.inc
cseg segment para public
assume cs:cseg, ds:cseg
org 100h ; build as COM program
sertype proc near
start:
jmp begin
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; DATA FOR SERTYPE
msg1 db CR, LF, CR, LF, TAB, TAB
db ' SERTYPE - Serial Port Analysis'
db CR, LF, CR, LF, TAB
db ' Serial Port Active? Basic UART Type'
db CR, LF, TAB
db 'ÄÄÄÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄ- ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ'
db CR, LF, '$'
msg2 db TAB, '#'
msgnum db '1 '
msghigh dw ' '
msglow dw ' '
db ' '
msgact db 'No '
uart db ' '
db CR, LF, '$'
typemsg db ' '
typeend db '8250 '
db '8250A or 16450 '
db '16C1450 '
db '16550 with defective FIFO'
db '16550AF/C/CF with FIFO '
db '16C1550 with FIFO '
db '16552 dual UART with FIFO'
db '82510 with FIFO '
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; start of code
begin:
OUTMSG msg1 ; initial message
mov cl, '1' ; serial port to check
mov si, 0 ; index for serial addresses
ser_loop:
mov msgnum, cl ; insert serial port number
mov msghigh, ' '
mov msglow, ' ' ; blank port number
MSGNO msgact ; assume port not active
mov ax, 40h
mov es, ax ; ES used for BIOS segment
mov dx, es:[si] ; get serial port address
mov bl, 0 ; default flag to no UART
cmp dx, 0 ; port number present ?
je ser_uart ; jump if not
mov bx, offset msghigh ; port number, high
mov al, dh
call hex ; convert to ASCII & insert
mov bx, offset msglow ; port number, low
mov al, dl
call hex ; convert to ASCII & insert
call testport ; test that serial port is
; there and chip type
cmp bl, 1 ; active port ?
jb ser_uart ; jump if not
MSGYES msgact ; serial port active
; transfer the text about which UART it is (bl= UART type)
ser_uart:
push cx
push si
mov cx, offset typeend - offset typemsg ; bytes
mov al, cl
mul bl ; ax = bl * al
mov si, ax
add si, offset typemsg ; ptr to UART string
mov di, offset uart
push cs
pop es
cld
rep movsb ; transfer string
pop si
pop cx
OUTMSG msg2 ; display info for one port
ser_next:
add si, 2 ; next index
inc cl
cmp cl, '4' ; are we done yet?
ja exit ; jump if so
jmp ser_loop ; try next port
exit:
mov ah, 4Ch
int 21h ; exit to DOS
sertype endp
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; Testport
; Check if the UART is responding and if so, test to
; find out which chip it is equivalent to.
;
; Called with: dx = serial I/O port
;
; Returns: bl = chip type
; 0 = no response, not a UART
; 1 = 8250 (no scratch register)
; 2 = 8250A or 16450
; 3 = 16C1450
; 4 = 16550 with defective FIFO
; 5 = 16550AF/C/CF with FIFO
; 6 = 16C1550 with FIFO
; 7 = 16552 dual UART with FIFO
; 8 = 82510 with FIFO
testport proc near
mov bl, 0 ; return value if no-response
mov di, dx ; save I/O port
cli ; disable interrupts
call DLAB1 ; Divisor Latch Access bit=1
mov ah, 5Ah ; test value 1
call IOtest ; write value, read it and compare
jne test_exit2 ; exit if not valid
mov ah, 0A5h ; test value 2
call IOtest ; write value, read it and compare
jne test_exit2 ; exit if not valid
sti ; enable interrupts
; now check if the scratch pad register is working (missing on 8250)
inc bl ; return 1 if 8250
add dx, 7 ; point to scratch pad register
mov ah, 5Ah ; test value 1
call IOtest ; write value, read it and compare
jne test_exit2 ; exit if no scatch register
mov ah, 0A5h ; test value 2
call IOtest ; write value, read it and compare
je scratch_ok
test_exit2:
jmp test_exit ; exit if no scratch register
scratch_ok:
mov dx, di ; restore base I/O port
; check for 1655x and 82510 FIFO versions
cli ; disable interrupts
add dx, 2 ; interrupt ID register
in al, dx
IODELAY
and al, 0C0h
cmp al, 0C0h ; is 16550 FIFO already enabled ?
je is_1655x ; jump if so
mov al, 1 ; try to enable FIFO on 1655x
out dx, al ; (if 82510 also set bank 0)
IODELAY
in al, dx ; read Interrupt Identification
IODELAY
mov bh, al ; save readback value
mov al, 0 ; Disable FIFO on 16550 or
out dx, al ; select bank 0 on 82510
IODELAY
and bh, 0C0h
cmp bh, 0C0h ; was FIFO enabled on 16550 ?
je is_1655x ; jump if so
cmp bh, 40h ; FIFO UART in some PS/2s ?
je is_16550C
cmp bh, 80h ; 16550 with defective FIFO ?
je is_16550
; not 16550, so now check for possible 82510 by switching to bank
; 3 (which is only possible on a 82510)
mov al, 60h ; select bank 3
out dx, al
IODELAY
in al, dx ; read back from port
IODELAY
mov bh, al ; save for later
mov al, 0 ; if 83510, return to
out dx, al ; bank 0
IODELAY
and bh, 60h ; now, did it goto bank 3?
cmp bh, 60h
je is_82510 ; jump if so (is 82510)
; no FIFO, so UART is 8250A or 16450 variant - Check if power down
; bit functions on this UART, in the modem control register
no_FIFO:
mov dx, di
add dx, 4 ; select modem control register
mov al, 80h ; see if power down mode allowable
out dx, al
IODELAY
in al, dx ; get modem register
IODELAY
mov ah, al ; save result
mov al, 0
out dx, al ; turn power back on
test ah, 80h ; did power down bit get set ?
jnz is_16C1450 ; jump if so
is_8250A:
mov bl, 2 ; set to 8250A/16450 UART
jmp test_exit
is_16C1450:
mov bl, 3 ; set to 16C1450 UART
jmp test_exit
is_16550:
mov bl, 4 ; set to 16550 with defective FIFO
jmp test_exit
; FIFO detected, and must be 16550 series
is_1655x:
mov dx, di
call DLAB1
add dx, 2
mov ah, 7
call IOtest ; write value, read it
mov bh, al ; save result for later
mov al, 0 ; reset register select
out dx, al
cmp bh, 7 ; did it work ?
je is_16552 ; if compare ok, is 16552
; Check if power down bit functions on this UART, in the modem
; control register (only on 16C1550)
mov dx, di
add dx, 4 ; select modem control register
mov al, 80h ; see if power down mode allowable
out dx, al
IODELAY
in al, dx ; get modem register
IODELAY
mov ah, al ; save result
mov al, 0
out dx, al ; turn power back on
test ah, 80h ; did power down bit get set ?
jnz is_16C1550 ; jump if so
is_16550C:
mov bl, 5 ; set to 16550AF/C/CF UART
jmp test_exit
is_16C1550:
mov bl, 6 ; set to 16C1550
jmp test_exit
is_16552: ; set to 16552 UART
mov bl, 7
jmp test_exit
is_82510:
mov bl, 8 ; set to 82510 UART
test_exit:
mov dx, di ; restore base port value
call DLAB0 ; reset DLAB to 0
sti ; enable interrupts in case off
ret
testport endp
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; DLAB1
; Set the Divisor Latch Access Bit to 1 without
; changing other line control bits
;
; Called with: dx = serial I/O port
;
; Regs Used: al
DLAB1 proc near
push dx
add dx, 3 ; point to Line Control Reg
in al, dx ; get current state
IODELAY
or al, 80h ; set DLAB to 1
out dx, al
pop dx
ret
DLAB1 endp
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; DLAB0
; Set the Divisor Latch Access Bit to 0 without
; changing other line control bits
;
; Called with: dx = serial I/O port
;
; Regs Used: al
DLAB0 proc near
push dx
add dx, 3 ; point to Line Control Reg
in al, dx ; get current state
IODELAY
and al, 7Fh ; set DLAB to 0
out dx, al
pop dx
ret
DLAB0 endp
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; IOtest
; Write value al to port, then read back value and compare
; to original value.
;
; Called with: ah = value to use for test
; dx = I/O port to test
;
; Returns: al = value read from port
; zero flag = 1 if register ok
IOtest proc near
mov al, ah ; value to test
out dx, al ; write value
IODELAY
in al, dx ; read back value
IODELAY
cmp al, ah ; compare if the same
ret
IOtest endp
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; HEX
; convert the hex number in al into two ascii characters
; at ptr in bx
;
; Called with: al = input hex number
; bx = ptr where to put ascii
;
; Regs Used: al,bx
hex proc near
push bx
mov bl, al
and al, 0fh
add al, 90h
daa
adc al, 40h
daa
mov bh, al
mov al, bl ; upper nibble
shr al, 1
shr al, 1
shr al, 1
shr al, 1
and al, 0fh
add al, 90h
daa
adc al, 40h
daa
mov bl, al
mov ax, bx
pop bx
mov [bx], ax ; output ascii bytes
ret
hex endp
cseg ends
end start
>>> EndFile <<<
Have a nice day Sylvain. - Jan Wagemakers -
--- FEddy 1.1 via ifcico / Debian GNU Linux
---------------
* Origin: Many Glacier BBS [32-3-4480880] (2:292/854.19)
|