This is the past DOS era of the compilation of source code, although has passed, but for the study of the assembly is still helpful, assembly language is just a basic programmer language, most people can grasp, not necessarily in-depth research.
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; BIOS data segment
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; es: = bdseg
mov ax, _data
mov ds, ax;D s: = _data
Assume Cs:cseg, Ds:_data, Es:bdseg, Ss:_stack
Xor Al, Al; # of serial ports = 0
MOV dx, [COM1]
CMP DX, 0
Je eoproc
Inc al; # of serial ports = 1
Push AX
Call Uartdet
mov [Uart1], AL; Remember the type of this UART
Pop ax
MOV dx, [COM2]
CMP DX, 0
Je eoproc
Inc al; # of serial ports = 2
Push AX
Call Uartdet
mov [Uart2], AL
Pop ax
MOV dx, [COM3]
CMP DX, 0
Je eoproc
Inc al; # of serial ports = 3
Push AX
Call Uartdet
mov [UART3], AL
Pop ax
MOV dx, [COM4]
CMP DX, 0
Je eoproc
Inc al; # of serial ports = 4
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; save starting I/O addr
Add dx, 4;p oint to modem CTRL REG
In AL, DX;d isable interrupts
Push AX
And Al, 11111011b
Out DX, AL
mov ch, 0; assume type 0
MOV dx, bx
Add DX, 7; if scratch Reg exists
mov al, 55h
Cli
Out DX, Al; Write to scratch Reg
Delay
In AL, DX; Read back
CMP al, 55h
Jne Endudet
mov al, 0AAh
Out DX, Al; Write to scratch Reg
Delay
In AL, DX; Read back
STi
CMP al, 0AAh
Jne Endudet
Inc ch; Assume type 1
MOV dx, bx
Add dx, 2;p oint to FIFO CTRL reg
mov al, 7; Attempt to enable FIFOs
Cli
Out DX, AL
Delay
In AL, DX; Read Interrupt ID Reg
STi
And Al, 0c0h strip all but FIFO bits
JZ Endudet If bits 0, 16450/16550
Inc ch; Assume type 2
MOV dx, bx
Add dx, 8003h;p oint to enhanced Reg 1
Cli
In AL, DX
Push AX
Or AL, 01000000b; Enable DMA transmission
Out DX, AL
Push DX
MOV dx, bx
Add DX, 2
In AL, DX
MOV cl, AL
Pop dx; restore enhanced Reg 1
Pop ax
Out DX, AL
STi
and Cl, 0c0h again mask all but FIFO ID
CMP cl, 40h
Jne Endudet must be type 2 (FIFO)
Inc ch; must be Type 3 (DMA)
Endudet:
Pop ax
MOV dx, bx
Add dx, 4;p oint to modem CTRL REG
Out DX, AL; Restore initial condition
XOR ax, Ax
mov al, ch
MOV dx, bx
Pop CX
Pop bx
Ret
Uartdet ENDP
DISP proc Near
Push ax, save ax
CMP al, 0; no serial ports?
Je noports
mov bx, offset ds:[uart1]; offset of UART type field
mov di, offset ds:[portmsg][3]; offset of 4th Char in
MOV cx, 0
MOV cl, AL; Number of iterations
@l1:
;
; write ' COMx: ' Message substituting ' x ' for proper comport #
;
MOV dl, 4
Sub DL, CL
Add DL, 30h; Convert to ASCII number
mov [di], DL
Lea DX, portmsg
mov Ah, 9
int 21h
;
; write the UART type now
;
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
; EOF Sertype. Asm