NT4/private/ntos/boot/detect/i386/videoa.asm

2176 lines
53 KiB
NASM
Raw Normal View History

2001-01-01 00:00:00 +01:00
title "Display Adapter type detection"
;++
;
; Copyright (c) 1989 Microsoft Corporation
;
; Module Name:
;
; video.asm
;
; Abstract:
;
; This module implements the assembley code necessary to determine
; various display chip sets.
;
; Author:
;
; Shie-Lin Tzong (shielint) 04-Dec-1991.
; Most of the code is taken from Win31 vdd and setup code(with modification.)
;
; Environment:
;
; x86 Real Mode.
;
; Revision History:
;
;
;--
if 0 ; Remove video detection
.xlist
include video.inc
.list
else
FONT_POINTERS EQU 700h ; physical addr to store font pointers
; This is also the DOS loaded area
endif ; Remove Video detection
.386
if 0 ; Remove video detection
IO_Delay macro
jmp $+2
jmp $+2
endm
TRUE EQU 1
FALSE EQU 0
extrn _HwIsMcaSystem: near;
extrn Ps2SystemBoardVideoId: near;
extrn _HwMcaPosData: DWORD;
endif ; Remove video detection
_DATA SEGMENT PARA USE16 PUBLIC 'DATA'
if 0 ; Remove video detection
;
; PVGA
;
str_Paradise DB "PARADISE"
len_str_Paradise EQU $-str_Paradise
str_WDIGITAL DB "WESTERN DIGITAL"
len_str_WDIGITAL EQU $-str_WDIGITAL
;
; followings are for Paradise 1F chip check - C. Chiang
;
bSave0F db 0 ; Unlock\Lock PR0-PR4
bSave29 db 0 ; Unlock\Lock PR11-PR17
bSave34 db 0 ; Unlock\Lock Flat Panel
bSave35 db 0 ; Unlock\Lock Mapping Ram
str_PVGA1F db "OPYRIGHT1990WDC"
len_str_1F equ $-str_PVGA1F
str_PVGA1FC db "OPYRIGHTWD90C22"
len_str_1FC equ $-str_PVGA1FC
str_1F_GEN db "WD90C2"
len_str_GEN equ $-str_1F_GEN
String db len_str_1F dup(?)
;
; ATIVGA
;
ATI_Sig DB " 761295520" ; ATI signature at in ROM at offset 30
ATI_Sig_Len EQU $-ATI_Sig
;
; TTVGA
;
TVGA_Sig DB "TRIDENT MICROSYSTEMS"
TVGA_Sig_Len EQU $-TVGA_Sig
;
; Compaq
;
CompaqSig db 'OMPAQ'
endif ; Remove video detection
_DATA ends
_TEXT SEGMENT PARA USE16 PUBLIC 'CODE'
ASSUME CS: _TEXT, DS:_DATA, SS:NOTHING
if 0 ; Remove video detection
;++
;
; ULONG
; GetVideoAdapterType (
; VOID
; )
;
; Routine Description:
;
; This function determines video adapter type in the system. If possible,
; it also determines the various chip sets used in the VGA card.
;
; N.B. Currently, we determine the chip set ONLY if it is VGA and the
; following chip sets are detectiable by this routine:
;
;
;
;
; Arguments:
;
; None.
;
; Return Value:
;
; (eax): Bit 16 - 31 Adapter type i.e. XGA, VGA, 8514
; Bit 0 - 15 Adapter subtype, V7VGA, CompaqVGA, TsengLab, ...
; zero means unknown type or subtype. EGA and CGA are NOT
; supported.
;
;--
public _GetVideoAdapterType
_GetVideoAdapterType proc near
push ebx
;
; First check if it is a XGA card?
;
call IsXga ; Is it XGA?
or ax, ax
jz gvaCompaqQVision ; if z, no, go check for Comapq QVision
mov eax, VD_XGA ; else it is XGA
jmp VideoDone
;
; Check if it is Compaq QVision?
;
gvaCompaqQVision:
call IsCompaqVideo ; Is it Compaq video ROM?
or ax, ax
jz short gvaCheckVGA ; Don't do any compaq video test
call IsCompaqQVision ; Is it Compaq QVision?
or ax, ax
jz gvaCompaqAvga ; if z, no, go check for AVGA
mov eax, VD_COMPAQ_QVIS
jmp VideoDone
;
; Check if it is Compaq AVGA?
;
gvaCompaqAvga:
call IsCompaqAvga ; Is it Compaq AVGA?
or ax, ax
jz gvaCheckVga ; if z, no, go check for VGA
mov eax, VD_COMPAQ_AVGA
jmp VideoDone
;
; Then we check the vga/svga which can be detected by int 10 func 1A.
;
gvaCheckVga:
MOV AX, 1A00h ; read display combination code
INT 10h
CMP AL, 1Ah ; function supported ?
JNZ gvaUnknown ; No, then set it to unknown
;
; BL contains active display code. I have however, seen that on some vga
; cards this call will return the active display in BH. For this reason I
; am checking BL for zero, if I find that BL is zero
; I will place BH into BL and assume that the only display attached to the
; system is the active display.
;
or bl,bl ; Do we have an active display ?
jnz Normal_combo_code ; Yes, then continue on normaly.
mov bl,bh ; No, then move bh to bl.
or bl,bl
jz gvaUnknown ; if fail, we don't know the card
Normal_combo_code:
mov eax, VD_COLOR ; Assume it is VGA color
CMP BL, 08h ; VGA color ?
je gvaVgaCheck
mov eax, VD_MONO ; Assume it is VGA mono
CMP BL, 07h ; VGA mono?
JNE gvaUnknown ; if nz, it's a code which we don't support
gvaVgaCheck:
mov ebx, eax ; [ebx] = video type
call GetVgaChipSet
or eax, ebx ; combine vga type and subtype
jmp VideoDone
gvaUnknown:
mov eax, VD_UNKNOWN ; set return type to unknown
VideoDone:
mov edx, eax
shr edx, 16 ; return (dx:ax)
pop ebx
ret
_GetVideoAdapterType endp
;++
;
; ULONG
; GetVgaChipSet (
; VOID
; )
;
; Routine Description:
;
; This function tries to determine the chip set used in the VGA card.
; Currently the followings are detectable:
;
; 8514
; GENOA VGA
; VIDEO 7 VRAM/DRAM VGA
; Trident TVGA
; Paradise VGA
; ATI VGA
; Tseng Lab VGA
; Cirrus Logic VGA
; dell dgx
;
; N.B. This function can ONLY be called when we already know the video
; type is VGA.
;
; Arguments:
;
; None.
;
; Return Value:
;
; (eax) = Video SubType.
;
;--
public GetVgaChipSet
GetVgaChipSet proc near
push bp
push bx
push si
push di
push es
;
; First check if it is 8514.
;
xor eax, eax ; clear eax
call Is8514Adapter ; Is it 8514?
or ax, ax
jz gvc10 ; if z, no, go check for other chip sets
add eax, VD_8514
jmp VRI_Exit
gvc10:
mov ax, 1130h
mov bh, 2
int 10h ; es:bp -> ROM font, so use es as ROM segment
;
; VGA real mode adapter detection
; Note that individual adapter detection routines must either
; jump to VRI_Exit with EDX = VT_Flags value or preserve
; the ES and DX register. ES is the adapter ROM segment (usually C000h)
; and DX is the status register port address (for resetting the
; attribute controller index/value toggle).
;
; Load status port value in DX
; This is to prevent duplication in OEM specific detection
;
mov dx,pMiscIn
in al,dx
test al,1
mov dl,(pStatColr AND 0FFh)
jnz SHORT gvc20
mov dl,(pStatMono AND 0FFh)
gvc20:
;
; ======================= VGA REAL mode adapter detection code ===============
; ============================================================================
;
; The code here is usually supplied by video adapter OEMs.
; Note that individual adapter detection routines must either
; jump to VRI_Exit with EAX = VIDEO_SUBTYPE_XXXX or preserve
; the ES and DX register. ES is the adapter ROM segment (usually C000h)
; and DX is the status register port address (for resetting the
; attribute controller index/value toggle).
;
; Entry:
; At this point:
; [es] = Adapter ROM segment
; [dx] = status register port addr
;
; Exit: [eax] = Video subtype
;
; ============================================================================
; ============================================================================
;
; ****************************
; * *
; * Genoa SuperVGA detection *
; * *
; ****************************
;
mov bx,WORD PTR ES:[0037h]
;
; If there is no ROM at this address, then we need to validate that BX is
; something reasonable, because some pmode guys do not emulate segment
; wrap correctly.
;
cmp bx, 0FFFCh
ja SHORT Not_GENVGA
mov eax,ES:[bx]
cmp eax,66991177h
je SHORT Is_GENVGA
cmp eax,66992277h
jnz SHORT Not_GENVGA
;
; It is a GENOA VGA
;
Is_GENVGA:
mov eax,VD_GENOA_VGA ; GENOA SuperVGA
jmp VRI_Exit
Not_GENVGA:
;
; ************************************
; * *
; * NCR 77C22 chip detection *
; * *
; ************************************
;
; NCR77C22 detection
;
push dx
;
; save the current sequencer index register.
;
mov dx, pSeqIndx ; (dx)=pSeqIndx
in al, dx
push ax ; (TOS)=content of Seq index
;
; set the sequencer index register to 0x05 which is lock register.
; save the data that we find there.
;
mov al, 05
out dx, al
inc dx ; (dx)=pSeqData
in al, dx
push ax ; (TOS)=context of LOCK reg
;
; Lock our extended registers
;
mov al, 0
out dx, al ; (dx)=pSeqData
;
; Check an extended register to see if it responds
;
mov al, 25h
dec dx ; (dx)=pSeqIndx
out dx, al
inc dx
in al, dx ; (dx)=pSeqData
push ax
;
; (TOS)= test register content
; (TOS+2) = Lock reg content
; (TOS+4) = Sequencer index reg content
;
mov al, 0AAh ; detected bit pattern
out dx, al
xor ecx, ecx ; assume not NCR77C2x
in al, dx
cmp al, 0AAh
je short NcrRestore
;
; The register didn't respond...maybe the lock is working
; Unlock the registers and see if the extended register responds now..
;
mov al, 5
dec dx ; (dx)=pSeqIndx
out dx, al
mov al, 1 ; unlock it
inc dx ; (dx)=pSeqData
out dx, al
;
; Try the lock again. This time we unlock it.
;
mov al, 25h
dec dx ; (dx)=pSeqIndx
out dx, al
mov al, 0AAh
inc dx ; (dx)=pSeqData
out dx, al
;
; Check if the unlock works
;
xor ecx, ecx ; assume not NCR
IO_Delay
in al, dx
cmp al, 0AAh
jne short NcrRestore
;
; The register responded now that we unlocked it.
; Since our lock register worked, assume an NCR 77C22 style system
;
mov al, 8 ; index of version id in SEQ
dec dx ; (dx)=pSeqIndx
out dx, al
inc dx ; (dx)=pSeqData
in al, dx
mov ecx, VD_NCR_77C22
;
; Determine what kind of 77C2x
;
and al, 0f0h
shr al, 4
cmp al, 0
je short NcrRestore
cmp al, 1
je short @f
cmp al, 2
jne short NcrRestore
@@: add ecx, VF_NCR_77C22E
NcrRestore:
mov al, 25h
mov dx, pSeqIndx
out dx, al
inc dx ; (dx)= pSeqData
pop ax ; (al) = test reg content
out dx, al ; restore test reg
mov al, 5
dec dx ; (dx)=pSeqIndx
out dx, al
inc dx ; (dx)=pSeqData
pop ax ; (al) = Lock reg content
out dx, al ; restore lock reg
dec dx
pop ax ; (al)= Index reg content
out dx, al
or ecx, ecx
jz short @f
mov eax, ecx
pop dx
jmp VRI_Exit
@@:
pop dx
;
; ************************************
; * *
; * DELL DGX video chip detection *
; * *
; ************************************
;
; DELL_DGX detection
;
push dx
mov dx,6c80h
in ax,dx
cmp ax,0ac10h
jne short NotDgx
add dx,2
in ax,dx
cmp ax,1140h
je short IsDgx
cmp ax,0160h
jne NotDgx
IsDgx:
pop dx
mov eax,VD_DELL_DGX
jmp VRI_Exit
NotDgx:
pop dx
;
; ******************************
; * *
; * Video 7 SuperVGA detection *
; * *
; ******************************
;
push dx
xor bx,bx ; clear it out
mov ax,6f00h
int 10h
cmp bx,'V7' ; any of the products?
jnz SHORT VRI_NotV7 ; nope...
;
; check the chip version #
;
mov cx,0ffffh
mov ax,06f07h ; get the # from the bios
int 10h
xor dx,dx ; Assume no flags passed in
or cx,cx ; zero?
jne SHORT VRI_NotV7
and bl,0f0h
cmp bl,70h ; V7VGA chip?
je SHORT @f ; Yes, this is VRAM 1
push ds ; Get V7VGA id from c000:86
mov cx, VIDEO_SEG
mov ds, cx
mov bx, V7_ID_OFFSET
mov cx, [bx]
pop ds
cmp cx, VRAM2_ROM_ID_1
je short @f
cmp cx, VRAM2_ROM_ID_2
je short @f
cmp cx, VRAM2ERGO_ROM_ID
je short @f
pop dx
mov eax, VD_VIDEO7_VGA
jmp VRI_Exit
@@:
add sp,2 ; Throw away DX on stack
mov cl, ah
mov eax,VD_VIDEO7_VGA + VF_V7_DRAM ; assume it's video 7 VRAM
test cl, 80h ; is it VRAM?
je VRI_Exit
mov eax,VD_VIDEO7_VGA + VF_V7_VRAM ; eax = Video 7 DRAM
jmp VRI_Exit
VRI_NotV7:
pop dx
;
; ******************************
; * *
; * Trident TVGA detection *
; * *
; ******************************
;
;
; Try to find "TRIDENT MICROSYSTEMS" from ROM BIOS.
; Search C000h. If not found, try E000h, some motherboard makers
; put our BIOS there.
; - Trident, Henry Zeng
;
lea si, TVGA_Sig
xor di, di
mov cx, 128
SearchTrident:
push si
push di
push cx
mov cx, TVGA_Sig_Len
repe cmpsb ; ? Trident
pop cx
pop di
pop si
jz short IsTVGA ; Gotcha!
inc di
loop SearchTrident
jmp short NotTVGA
public IsTVGA
IsTVGA:
mov edx, VD_TRIDENT_VGA ; Trident TVGA
;
; Check if TVGA9100
;
push dx ; ? version # (3C5.B) == 93h
mov dx, 03C4h
mov al, 0Bh
out dx, al
inc dx
in al, dx
pop dx
cmp al, 93h
jnz short Not9100
or edx, VF_TVGA_9100 ; Is TVGA9100
Not9100:
mov eax, edx
jmp VRI_Exit
NotTVGA: ; The other guy
;
; ******************************
; * *
; * Westerm Digital detection *
; * *
; ******************************
;
push dx
push bx
;
; Write 3ce.0c
;
mov al, 0Ch
mov dx, pGrpIndx
out dx, al
inc dx ; (dx)= grpData
in al, dx
push ax ; (TOS)= SaveGrph0C
and al, 0bfh
out dx, al
;
; write 3ce.0f
;
mov al, 0Fh
mov dx, pGrpIndx
out dx, al
inc dx ; (dx)= grpData
in al, dx
push ax ; (TOS)= SaveGrph0F
mov al, 0
out dx, al
;
; write 3ce.09
;
mov al, 09h
mov dx, pGrpIndx
out dx, al
inc dx ; (dx)= grpData
in al, dx
mov ah, al ; (ah)= temp1
inc al
out dx, al ; write (temp1+1)
IO_Delay
xor ecx, ecx ; Assume not WD
in al, dx ; Read it back
mov bl, al ; (bl)= temp2
mov al, ah ; restore the old value
out dx, al
inc al
cmp al, bl ; Is (temp1+1)== temp2?
je WdRestore ; if yes, not Wd
mov ax, 050Fh
mov dx, pGrpIndx
out dx, ax
mov ax, 09h
mov dx, pGrpIndx
out dx, ax
inc dx ; (dx)= grpData
in al, dx
mov ah, al ; (ah)=temp1
inc al
out dx, al ; write (temp1+1)
IO_Delay
in al, dx ; read it back
mov bl, al ; (bl) = temp 2
mov al, ah ; restore old value
out dx, al
inc al ; Is (temp1+1) == temp2
cmp al, bl
jne WdRestore ; if no, not WD
;
; it *is* a WDVGA!
;
;
; Look for extended regsiters that are only in WD90C31 and over
;
mov ecx, VD_WD_90C + VF_WD_31 ; Assume we have 90C31
mov dx, WD_EXT_IO_PORT
in al, dx
mov bl, al ; save it
mov al, 2
out dx, al
IO_Delay
in al, dx
cmp al, 2
je @f
;
; WD90C30 or older.
;
mov ecx, VD_WD_90C + VF_WD_30
@@:
mov al, bl ; restore ext io port value
out dx, al
;
; Get chip type to determine if we have a 90c30 or 90c00
;
cmp ecx, VD_WD_90C + VF_WD_30 ; Is 90C30?
jne WdRestore ; No, do nothing
mov al, 06
mov dx, pGrpIndx
out dx, al
inc dx ; (dx)= grpData
in al, dx
push ax ; save reg 06 content
mov al, 48h
out dx, al
mov al, 08
mov dx, pGrpIndx
out dx, al
inc dx ; (dx)= grpData
in al, dx
push ax ; Save reg 08 content
mov al, 5Ah
out dx, al
IO_Delay
in al, dx
cmp al, 5Ah
je short @f
;
; old chip, can't support 1R1W banking
;
mov ecx, VD_WD_90C + VF_WD_00
@@:
mov al, 08
mov dx, pGrpIndx
out dx, al
inc dx ; (dx)= grpData
pop ax
out dx, al ; Restore REg 08
mov al, 06
mov dx, pGrpIndx
out dx, al
inc dx ; (dx)= grpData
pop ax
out dx, al ; Restore reg 06
;
; Restore registers to what they were.
;
WdRestore:
mov al, 0Ch
mov dx, pGrpIndx
out dx, al
inc dx ; (dx)= grpData
pop bx ; (bl)= saved Grp0F
pop ax ; (al)= saved Crp0C
out dx, al
mov al, 0Fh
mov dx, pGrpIndx
out dx, al
inc dx ; (dx)= grpData
mov al, bl ; (al)= saved Grp0C
out dx, al
or ecx, ecx
jz short @f
mov eax, ecx
pop bx
pop dx
jmp VRI_Exit
@@:
pop bx
pop dx
if 0
;
; ******************************
; * *
; * Paradise VGA detection *
; * *
; ******************************
;
; --------------------------------------------------------------------
;
; [1]
; Paradise 1C has 5 DIP switches, not 4 any more. The 5th switch
; controls if interlace or non-interlace is used. Register 3CE.0F
; bit 0-2 used for lock/unlock PR0-PR4, bit 3-7 used to return
; DIP switch information. This affects flag fvid_pvga used for other
; modules if paradise is selected. - C. Chiang -
;
; --------------------------------------------------------------------
;
push dx
mov dl,(pGrpIndx AND 0FFh)
mov al,0Fh
out dx,al
inc dx
in al,dx
push ax
and al,0F8h
mov ah,al
xor al,0F8h ; Reverse upper 5 bits
or al,5
out dx,al
IO_Delay
in al,dx
xor al,ah ; Q: Are lower bits 5 and
cmp al,5 ; upper bits unchanged?
pop ax
out dx,al ; Restore original value
jnz NotPVGA ; N: Must not be PVGA
;
; It's Paradise VGA, check for Paradise VGA ROM
;
mov si,OFFSET str_Paradise
xor di,di
mov cx,128
mov edx,VD_PARADISE_VGA ; Assume not Paradise ROM
PVGA_FindROMLoop:
push di
push si
push cx
mov cx,len_str_Paradise
repe cmpsb ; Q: Paradise ROM?
pop cx
pop si
pop di
jz SHORT IsPVGARom ; Yes
inc di
loop PVGA_FindROMLoop ; No, look thru 128 bytes
;
; PARADISE not found, now look for WESTERN DIGITAL
;
mov si,OFFSET str_WDIGITAL
xor di,di
mov cx,128
PVGA_FindROMLoop1:
push di
push si
push cx
mov cx,len_str_WDigital
repe cmpsb ; Q: Paradise ROM?
pop cx
pop si
pop di
jz SHORT IsPVGARom ; Yes
inc di
loop PVGA_FindROMLoop1 ; No, look thru 128 bytes
;
;--------------------------------------------------------------------
;
; [3] It is Paradise Chip, but not Paradise BIOS ROM. In this case,
; set the flag to fVid_PVGA in order for OEMs who use their own
; BIOS and our Chip to work properly. - Chiang -
;
;---------------------------------------------------------------
;
mov edx,VD_PARADISE_VGA ; no Paradise ROM
jmp SHORT Chk_1F
IsPVGARom:
or edx, VF_PVGA_PROM ; with Paradise ROM
;
;---------------------------------------------------------------------
;
; [2] following are for Paradise chip type checking - C. Chiang -
;
;---------------------------------------------------------------------
;
Chk_1F:
push es
;
; SAVE 3CE.0F
;
mov dx, 3CEh
mov al, 0Fh
out dx, al
inc dx
in al,dx ; Read 3CF.F
mov bSave0F, al ; Save the lock register state
;
; get 3D4 or 3b4
;
xor ax, ax
mov es, ax
mov dx, es:463h ; Fetch the register address to use
mov ax, ds ; DS = ES
mov es, ax
mov cx, len_str_1F
lea di, String ; Get the String ptr
mov bx, 31h
;
;--- For 1F we need to unlock\lock the regs:
;--- 3?4.29 - Unlock PR11-PR17
;
; mov al, 29h ; Select PR10
; out dx, al
; inc dx
; in al, dx ; Read the contents
; mov bSave29, al ; and save it
; mov al, 80h ; Unlock the date code register
; out dx, al
; dec dx
;
;
;--- 3?4.34 - Lock Flat Panel
;
mov al, 34h ; Select PR1B
out dx, al
inc dx
in al, dx ; Read the contents
mov bSave34, al ; and save it
mov al, 0 ; Lock the flat panel
out dx, al
dec dx
;
;--- 3?4.35 - Lock Mapping Ram
;
mov al, 35h ; Select PR30
out dx, al
inc dx
in al, dx ; Read the contents
mov bSave35, al ; and save it
mov al, 0 ; Lock the mapping ram
out dx, al
dec dx
loopit: mov al, bl ; Loop to read the chip ID
out dx, al
inc dx
in al, dx
stosb
dec dx
inc bx
loop loopit
;
;--- For 1F we need to restore the regs
;
;
;--- 3?4.35 - Lock Mapping Ram
;
mov al, 35h ; Select PR30
out dx, al
mov al, bSave35 ; and restore it
cmp al, 30h ; If wasn't unlocked
jne SHORT skip1 ; then leave alone
inc dx
out dx, al
dec dx
skip1:
;
;--- 3?4.34 - Lock Flat Panel
;
mov al, 34h ; Select PR1B
out dx, al
mov al, bSave34 ; and restore it
cmp al, 0A6h ; If wasn't unlocked
jne SHORT skip2 ; then leave alone
inc dx
out dx, al
dec dx
skip2:
;
;--- IT TURNS OUT THAT THE BIOS NEVER LOCKS THESE
;--- 3?4.29 - Unlock\lock PR11-PR17
; mov al, 29h ; Select PR10
; out dx, al
; inc dx
; mov al, bSave29 ; and restore it
; out dx, al
; dec dx
;
;--- Restore the state of the lock/unlock register: 3CF.F
;
exit_pgm:
mov dx, 3CEh
mov al, 0Fh
out dx, al
inc dx
mov al, bSave0F ; Restore lock/unlock status
out dx, al
;
;--- Now, the chip signature is in String
;
mov si, OFFSET str_PVGA1F ; check string "OPYRIGHT1990WDC"
mov di, OFFSET String
mov cx, len_str_1F
repe cmpsb ; Q:
jz SHORT isPVGA1F
mov si, OFFSET str_PVGA1FC ; check string "OPYRIGHTWD90C22"
mov di, OFFSET String
mov cx, len_str_1FC
repe cmpsb ; Q:
jz SHORT isPVGA1F
mov si, OFFSET str_1F_GEN ; check string "OPYRIGHTWD90C22"
mov di, OFFSET String
mov cx, len_str_GEN
repe cmpsb ; Q:
jnz SHORT Exit_1F_check
isPVGA1F:
or edx, VF_PVGA_CHIP_1F ; set flag for Paradise 1F chip
Exit_1F_check:
pop es
;
;----------------------------------------------
; end of Paradise 1F chip checking
;----------------------------------------------
;
add sp,2 ; discard saved DX
mov eax, edx
jmp VRI_Exit
NotPVGA:
pop dx
endif
;
; ******************************
; * *
; * ATI VGA detection *
; * *
; ******************************
;
push dx
push bp
mov ax,1203h
mov bx,5506h
mov bp,0ffffh
int 10h
cmp bp,0ffffh
pop bp
je short Not_ATI_VGA
mov si,OFFSET ATI_Sig
mov di,30h
mov cx, ATI_Sig_Len
rep cmpsb
jnz SHORT Not_ATI_VGA
;
; Further checks for version of ATI VGA
;
add sp, 2
mov edx, VD_ATI_VGA
cmp es:byte ptr [40h],'3' ;VGAWONDER product code ?
jne SHORT Ati_Vga
; mov edx,VD_ATI_VGA
; cmp es:byte ptr [43h],'1' ;VGAWONDDER V3 ?
; jne short Ati_Vga
or edx,VF_ATIVGA_WONDDER3
Ati_Vga:
mov eax, edx
jmp VRI_Exit
Not_ATI_VGA:
pop dx
;
; ************************************
; * *
; * Tseng Lab VGA detection *
; * *
; ************************************
;
; Tseng Labs VGA detection
; Attribute Controller Reg 16h is known to exist only on Tseng Labs VGA
;
push dx
mov bl,0 ;ET3000/ET4000 flag (0=ET3000)
mov dx, 3BFh
xor al, al
out dx, al
pop dx
push dx
sub dl, pStatColr-03D8h ; mode control register is 3B8 or 3D8
in al, dx
test al, 01000000b ;Q: writing 0 to 3BF cleared bit 6 of
; mode control port?
jnz SHORT tlvga_2 ; N: not ET4000
mov dx, 3BFh
mov al, 10b
out dx, al
pop dx
push dx
sub dl, pStatColr-03D8h ; mode control register is 3B8 or 3D8
IO_Delay
in al, dx
test al, 01000000b ;Q: writing 10b to 3BF set bit 6 of
; mode control port?
jz SHORT tlvga_2 ; N: not ET4000
; Y: possibly an ET4000
mov bl,1 ;flag ET4000 not ET3000
;
; attempt to write ET4000 "KEY"
;
mov dx, 3BFh
mov al, 3
out dx, al
pop dx
push dx
sub dl, pStatColr-03D8h ; mode control register is 3B8 or 3D8
in al, dx
mov ah, al
IO_Delay
mov al, 0A0h
out dx, al
tlvga_2:
pop dx
push dx
push ax
push bx
call Check_Writing_ATC16 ;sets ECX=0 or VT_Flags for ET3000
pop bx
pop ax
sub dl, pStatColr-03D8h ; mode control register is 3B8 or 3D8
mov al, ah
out dx, al ; restore mode control register
mov dx,03BFh
mov al,1
out dx,al ;restore 3BF to normal value
or ecx,ecx
jz SHORT Not_TLVGA ; jump if not ET3000/ET4000
pop dx
mov edx,VD_TSENGLAB_VGA + VF_TLVGA_ET3000 ;if ET4000 with 256k
or bl,bl ;test if ET4000
jz short tlvga_4
;
;is an ET4000:
;
mov edx,VD_TSENGLAB_VGA + VF_TLVGA_ET4000 ;if ET4000 with 256k
tlvga_4:
mov eax,edx
jmp VRI_Exit
Not_TLVGA:
pop dx
;
; ************************************
; * *
; * Cirrus VGA detection *
; * *
; ************************************
;
; Cirrus Logic VGA detection
;
;
; First save SR6 and SRIndx
;
push dx
xor cx,cx ; assume not CLVGA
mov dl,(pSeqIndx AND 0FFh)
in al,dx
IO_Delay
mov bh,al ; BH = SR index
mov al,6
out dx,al
IO_Delay
inc dx
in al,dx
IO_Delay
mov bl,al ; BH=SRindx,BL=SR6 value
;
;enable extension register in the CLVGA
;
mov ecx,VD_CIRRUS_VGA ; ECX = potential VT_Flags
mov al,0ECh ; extension enable value
out dx,al
IO_Delay
in al,dx
IO_Delay
cmp al,1 ; Q: Could enable Ext?
jnz SHORT Check542x
;
; now check to see if we can disable the extensions
;
mov al,0CEh ; extension disable value
out dx,al
IO_Delay
in al,dx
IO_Delay
and al,al ; Q: extensions disabled successfully?
jz short @f ; Y: it is 610/620
; Y: its Cirrus logic
Check542x:
mov al, 12h ; Unlock ext regs with 12h
out dx, al
IO_Delay
in al, dx
IO_Delay
cmp al, 12h ; Could enable ext?
jnz Not_CLVGA ; No, not CL VGA
mov al, 0
out dx, al
IO_Delay
in al, dx
IO_Delay
cmp al, 0fh
jnz Not_CLVGA
@@:
;
; we know its a Cirrus chipset, now find out if it is a 610/620 Rev. C.
; chipset.
;
push ecx ; save flag value
push dx
mov ah,12h
mov bl,80h
int 10h ; Inquire VGA type
cmp al,3 ; returns 3 for 610/620 LCD controller
jnz short Is542x ; otherwise check for 542x
;
; its a 610/620, now find out if its RevC or not.
;
cmp bl,80h
jz short CheckChip
cmp bl,2
jnz short Not610
IsRevC:
mov eax,VF_CLVGA_REVC
jmp short Done610
CheckChip:
mov dx,3c4h
mov al,8eh
out dx,al
inc dx
in al,dx ; 8Eh is chip revision.
cmp al,0ach
jz IsRevC
Not610:
xor eax,eax
Done610:
pop dx
pop ecx
or ecx,eax
jmp short Restor_CLVGA ; all done, now get outa here
Is542x:
cmp ax, 12h ; check 5420r0
jne short @f ; Check next chip version
mov eax, VF_CLVGA_5420r0 ; We found a 5420r0
jmp short Done610
@@:
cmp ax, 16h ; check 5420r1
jne short @f ; Check next chip version
mov eax, VF_CLVGA_5420r1 ; We found a 5420r1
jmp short Done610
@@:
cmp ax, 18h ; check 5428
jne short @f ; we did not find any of compaq rev.
mov eax, VF_CLVGA_5428 ; We found a 5428
jmp short Done610
@@:
cmp ax, 12h
jb short Not610
mov eax, VF_CLVGA_542x ; if (ax) >= 12h, it's 542x
jmp short Done610
Not_CLVGA:
xor ecx,ecx ; Indicate not CL VGA
Restor_CLVGA:
dec dx
mov al,6
out dx,al
IO_Delay
mov al,bl ; old value of SR6
or ecx,ecx ; Q: CL VGA?
jz SHORT Restor_SR6 ; N: output value read
mov bl,0ECh
Restor_Ena:
or al,al ; Q: extensions enabled?
mov al,bl ; AL = 0ECh (enable)
jnz SHORT Restor_SR6 ; Y: output enable value
ror al,4 ; N: output disable (0CEh)
Restor_SR6:
inc dx
out dx,al ; Restore value of SR6
IO_Delay
mov al,bh
dec dx
out dx,al ; Restore index
IO_Delay
or ecx,ecx
jz SHORT Is_Not_CLVGA
add sp,2
mov eax,ecx
jmp VRI_Exit
Is_Not_CLVGA:
pop dx
;
; ************************************
; * *
; * S3 video chip detection *
; * *
; ************************************
;
; S3 detection
;
mov ax, dx
push dx ; save dx
push bx
and ax, 0fff0h
or ax, 4h ; (ax) = Crt index
mov dx, ax
inc dx
in al, dx
mov ah, al
dec dx
in al, dx ; (ah) = original data reg
; (al) = oroginal addr reg
push ax ; Save it
mov al, 38h
out dx, al
inc dx
in al, dx
IO_Delay
mov ah, al ; (ah) = original data on index 38
mov al, 39h
dec dx
out dx, al
IO_Delay
inc dx
in al, dx ; (al) = original data on index 39
push ax ; save them
dec dx
;
; Before unlocking all the S3 registers, lets try read the id reg
;
if 0
mov ax, 038h ; lock S3 registers
out dx, ax
IO_Delay
dec dx
mov ax, 039h
out dx, ax
IO_Delay
dec dx
mov al, 30h ; crt controller index for s3 ID reg
out dx, al
IO_Delay
inc dx
in al, dx ; get (potential) Id
mov bl, al ; (bl) = ID reg content before unlocked
dec dx
endif
;
; Now Unlock all the S3 registers
;
mov ax, 4838h
out dx, ax
IO_Delay
dec dx
mov ax, 0A039h
out dx, ax
IO_Delay
dec dx
;
; Read ID after we unlocked S3 registers
;
mov al, 30h ; crt controller index for s3 ID reg
out dx, al
IO_Delay
inc dx
in al, dx ; get (potential) Id
dec dx
if 0
cmp bl, al ; compare ids
mov ebx, 0 ; Assume it is NOT S3
je short ExitS3Detection
else
mov ebx, 0
endif
;
; Check if id is 8?. 9? or A? If yes, it is S3.
;
and al, 0f0h
cmp al, 80h ; Is Id = 8?h?
jz short IsS3 ; if e, it's s3
cmp al, 90h ; Is Id = 9?h?
jz short IsS3 ; if e, it's s3
cmp al, 0A0h ; Is Id = A?h?
jnz short ExitS3Detection ; if nz, not s3
IsS3:
mov ebx, VD_S3
ExitS3Detection:
pop ax
mov cx, ax
mov ah, al
mov al, 39h
out dx, ax ; Restore reg 39 data
IO_Delay
dec dx
mov ax, cx
mov al, 38h
out dx, ax ; Restore reg 38 data
IO_Delay
dec dx
pop ax ; (ax) = crt data and index
out dx, ax
IO_Delay
mov eax, ebx ; (eax) = VGA id
pop bx
pop dx
cmp eax, VD_S3
je VRI_Exit
;
; ==================== End of VGA H/W detection ===================
;
;
; If we come here, the detection fails.
;
mov eax, VD_VGA ; Set it to standard VGA
;
; eax = Video subtype
;
VRI_Exit:
;
; before exit do setmode to init video
;
push eax
mov ah, 0fh
int 10h ; (al) = current display mode
mov ah, 0
int 10h ; set to current mode
pop eax
pop es
pop di
pop si
pop bx
pop bp
ret
GetVgaChipSet endp
;++
;
; ULONG
; Check_Writing_ACT16 (
; VOID
; )
;
; Routine Description:
;
; This routine is part of Tseng Lab VGA detection code.
; In this routine, we try to access Attribute Controller reg 16h. It is
; known to exist only on Tseng Lab's VGA.
;
; Arguments:
;
; None.
;
; Return Value:
;
; (ecx) = 0, if NOT Tseng Lab VGA
;
;--
Check_Writing_ATC16 proc near
push dx
in al,dx
IO_Delay
mov dl,(pAttr AND 0FFh)
in al,dx
mov bh,al ; BH = current Attr index
IO_Delay
mov al,16h+20h ; Select 16h (leave video on)
out dx,al
IO_Delay
inc dx
in al,dx
IO_Delay
dec dx
mov bl,al ; Save current reg 16h in BL
xor al,10h ; Complement bit 4
out dx,al ; Write it out
IO_Delay
pop dx
push dx
in al,dx
mov dl,(pAttr AND 0FFh)
mov al,16h+20h ; Select 16h (leave video on)
out dx,al
IO_Delay
inc dx
in al,dx
IO_Delay
xor ecx,ecx ; CX = flag (not TLVGA)
dec dx
xor al,10h
cmp al,bl ; Q: Is value same as written?
jnz SHORT Restore16 ; N: Is not TLVGA
mov ecx,VD_TSENGLAB_VGA ; Y: Is TLVGA
Restore16:
mov al,bl
out dx,al
IO_Delay
pop dx
push dx
in al,dx
IO_Delay
mov dl,(pAttr AND 0FFh)
mov al,bh
out dx,al
pop dx
ret
Check_Writing_ATC16 endp
if 0 ; *** Removed
;++
;
; BOOLEAN
; IsCompaqAgb (
; VOID
; )
;
; Routine Description:
;
; Function determines if the video system is a Compaq Advanced Graphics
; Board operating if pass through configuration in conjunction with a
; VGA card.
;
; Arguments:
;
; None.
;
; Return Value:
;
; Function will return TRUE or FALSE as to whether or not the Compaq AGB
; is present and operating in pass-through mode.
;
;--
; public IsCompaqAgb
;IsCompaqAgb proc near
;
; mov dx,298h ; Port address for host CPU status reg.
; in al,dx ; Read register.
; mov cl,al ; Save value from reg.
; and al,00000011b ; Strip all but bit 0 and 1.
; or al,al ; Bits 0 and 1 should be 0.
; jnz no_CompaqAGB
; mov dx,299h ; Ok, next look at host CPU status 2 reg.
; in al,dx
; and al,00000001b ; Strip all but bit 0.
; or al,al
; jnz no_CompaqAGB ; bit zero should be 0.
; mov dx,298h
; in al,dx
; cmp al,cl ; One final check.
; jne no_CompaqAGB
; mov ax, TRUE
; jmp short AGB_done
;
;no_CompaqAGB:
; mov ax, FALSE ; return FALSE
;AGB_done:
; ret
;
;IsCompaqAgb endp
;
endif ; *** Removed
;++
;
; BOOLEAN
; Is8514Adapter (
; VOID
; )
;
; Routine Description:
;
; This function detects the presence of an 8514 display card.
;
; The way we do this is to first write to the Error Term Register and then
; make sure we can read back the value we wrote. Next I read in the value of
; the subsystem status register and check bit 7 to determine if the 8 plane
; memory configuration is present. Only if both these conditions are
; satisfied will we acknowledge that 8524 display driver is present.
;
; Arguments:
;
; None.
;
; Return Value:
;
; Function will return TRUE or FALSE as to whether or not the 8514
; display card is present and contains the proper memory configuration.
;
;--
public Is8514Adapter
Is8514Adapter proc near
mov dx, ERR_TERM ; load DX with port address (error term port).
mov ax, 5555h ; load AX with value to write to port.
out dx, ax ; Write the data.
IO_Delay
IO_Delay
in ax, dx ; Now read the data back in.
cmp ax, 5555h ; Q: is 8524 present ?
jne Not_8514 ; N: indicate 8514 not present.
; Y: 8514 is present, now check monitor.
;
; Now we need to determine what type of monitor is attached to the
; 8514 card. To do this we check ID bits 6,5,4 of the subsystem
; status register. Depending on the Monitor attached we return:
;
; There are 4 valid monitor types:
;
; bits 6-4 Type
;
; 001 Ascot (mono)
; 010 Henley (color)
; 011 Invalid (color) This is supposedly valid in spite
; of what the spec says.
; 101 Surrey (mono)
; 110 Conestoga/Crown (color)
;
mov dx,SUBSYS_STAT ; Now, we have the adapter. Check monitor.
in ax,dx ; Get word from SUBSYS_STAT
and ax,0070h ; Mask out bits 6-4
cmp ax,0020h ; Is it Henley type?
je Disp_8514 ; Yes, then it is an 8514 type
cmp ax,0060h ; Is it Conestoga/Crowwn type?
je Disp_8514 ; Yes, then it is an 8514 type
cmp ax,0030h ; Is it Korys' machine
je Disp_8514 ; Yes, then it is an 8514 type
cmp ax,0010h ; Is it Ascot type?
je Disp_8503 ; Yes, then it is a VGA Mono type
cmp ax,0050h ; Is it Surrey type?
je Disp_8503 ; Yes, then it is a VGA Mono type
mov ax,VF_MONITOR_VGA ; If none of the above, then it
jmp short fn8514Done ; is just a standard VGA
Disp_8503:
mov ax,VF_MONITOR_MONO_8503
jmp short fn8514Done
Disp_8514:
mov ax,VF_MONITOR_GAD_8514
jmp short fn8514Done
Not_8514:
mov ax,FALSE
fn8514Done:
ret
Is8514Adapter endp
;++
;
; BOOLEAN
; IsCompaqVideo (
; VOID
; )
;
; Routine Description:
;
; This function searches ROM BIOS C0000 and E0000 for 'COMPAQ' to
; determine the presence of COMPAQ video ROM.
;
; Arguments:
;
; None.
;
; Return Value:
;
; (ax) = TRUE if it is compaq video rom. Otherwise, a value of FALSE is
; returned.
;
;--
public IsCompaqVideo
IsCompaqVideo proc near
push di
push es
mov ax, 0C000h ; Video ROM is C000:0000 to 8000h
icvBeginSearch:
mov es, ax
mov di, 0000h
mov al, 'C' ; Look for 'C'
mov cx, 7FFCh ; search through 32K
cld
icvLoopAgain:
repne scasb ; search for 'C'
jne icvNotFound ; if searched entire video ROM, exit
mov edx, dword ptr es:[di]
cmp edx, 'APMO' ; search for 'OMPA'
jne short icvLoopAgain ; fail, continue search
mov dl, byte ptr es:[di+4]
cmp dl, 'Q'
jne short icvLoopAgain
;
; If we get to here we have found COMPAQ in the video ROM.
;
mov ax, 1
jmp short icvExit
icvNotFound:
push es
pop ax
cmp ax, 0E000h
je short @f
mov ax, 0E000h
jmp short icvBeginSearch
@@:
xor ax, ax ; NO, return FALSE (AX = 0)
icvExit:
pop es ; restore registers
pop di
ret
IsCompaqVideo endp
; BOOLEAN
; IsCompaqQVision (
; VOID
; )
;
; Routine Description:
;
; Function determinec if the video system is a Compaq QVision board.
;
; Arguments:
;
; None.
;
; Return Value:
;
; Function will return TRUE or FALSE as to whether or not the Compaq QVision
; is present.
;
;--
public IsCompaqQvision
IsCompaqQVision proc near
push si
push di
push es
mov ax, 0BF11h ; Get Extended Environment
int 10h
cmp al, 0BFh ; is the call supported ?
jne QVision_not_found ; no, this is not a QVision card
mov eax, DWORD PTR ES:[SI] ; get pointer to extended env DWORD
and al, 80h ; are QVision modes supported ?
jz QVision_not_found ; no, this is not a QVision card
mov eax, 01h ; yes
jmp short QVision_exit
QVision_not_found:
xor ax, ax ; NO, return FALSE (AX = 0)
QVision_exit:
pop es ; restore registers
pop di
pop si
ret
IsCompaqQVision endp
;++
;
; BOOLEAN
; IsCompaqAvga (
; VOID
; )
;
; Routine Description:
;
; This function returns whether a COMPAQ AVGA display adapter is found.
;
; This is determined by: 1. Looking for COMPAQ Video ROM
; 2. Doing COMPAQ int 10h call
;
; The presence of COMPAQ video ROM can be determined by searching through
; the Video ROM (C000:0000 to C000:FFFF) for the string 'COMPAQ'.
;
; Arguments:
;
; None.
;
; Return Value:
;
; (ax) = TRUE if it is compaq AVGA. Otherwise, a value of FALSE is
; returned.
;
;--
public IsCompaqAvga
IsCompaqAvga proc near
push si ; Save registers
push di
push es
mov ax, 0BF03h
xor cx, cx
int 10h
and cl, 050h ; Are bits 4 (BitBlt Engine
cmp cl, 050h ; and 6 (256 colors) both set
jne avga_not_found
mov eax, 01h ; YES, return TRUE (non-zero AX)
jmp short avga_exit
avga_not_found:
xor ax, ax ; NO, return FALSE (AX = 0)
avga_exit:
pop es ; restore registers
pop di
pop si
ret
IsCompaqAvga endp
;++
;
; BOOLEAN
; IsXga (
; VOID
; )
;
; Routine Description:
;
; This function returns whether a XGA display adapter is found.
;
; This is determined by: 1. Make sure this is a MicroChannel machine
; 2. Make sure Mother board VideoSubsystem Id is XGA
;
; N.B. Current assumption is that XGA is MicroChannel specific.
;
; Arguments:
;
; None.
;
; Return Value:
;
; (ax) = TRUE if it is IBM XGA. Otherwise, a value of FALSE is
; returned.
;
;--
IsXga proc near
push es
push bx
call _HwIsMcaSystem ; First check if this is MCA machine
or ax, ax ; If ax == 0, it is not.
jz short Ix99 ; exit
call Ps2SystemBoardVideoId ; (ax) = PS2 mother board video id
cmp ax, IBM_XGA_ID_LOW ; Is it XGA id?
jb short Ix50 ; if z, no, try something else.
cmp ax, IBM_XGA_ID_HIGH
jle short Ix99
Ix50: les bx, _HwMcaPosData
mov cx, 0
Ix60:
mov ax, es:[bx]
cmp ax, IBM_XGA_ID_LOW ; Is it XGA id?
jb short Ix70 ; if z, no, try next slot
cmp ax, IBM_XGA_ID_HIGH
jle short Ix99
Ix70:
add bx, MCA_POS_DATA_SIZE
inc cx
cmp cx, 8 ; end of slot?
jnz short Ix60
Ix90:
mov ax, 0
Ix99: pop bx
pop es
ret
IsXga endp
endif ; Remove Video detection
;++
;
; VOID
; GetVideoFontInformation (
; VOID
; )
;
; Routine Description:
;
; This function does int 10h, function 1130 to get font information and
; saves the pointers in the physical 700h addr.
;
; Arguments:
;
; None.
;
; Return Value:
;
; None.
;
;--
ASSUME DS:NOTHING
public _GetVideoFontInformation
_GetVideoFontInformation proc near
push ds
push es
push bp
push bx
push si
mov ax, FONT_POINTERS
shr ax, 4
mov ds, ax
mov si, FONT_POINTERS
and si, 0fh
mov bh, 2
@@:
mov ax, 1130h ; Get font information
int 10h
mov [si], bp
add si, 2
mov [si], es
add si, 2 ; (si)= 8
inc bh
cmp bh, 8
jb short @b
pop si
pop bx
pop bp
pop es
pop ds
ret
_GetVideoFontInformation endp
_TEXT ENDS
END