home *** CD-ROM | disk | FTP | other *** search
- ;*DDK*************************************************************************/
- ;
- ; COPYRIGHT (C) Microsoft Corporation, 1989
- ; COPYRIGHT Copyright (C) 1995 IBM Corporation
- ;
- ; The following IBM OS/2 WARP source code is provided to you solely for
- ; the purpose of assisting you in your development of OS/2 WARP device
- ; drivers. You may use this code in accordance with the IBM License
- ; Agreement provided in the IBM Device Driver Source Kit for OS/2. This
- ; Copyright statement may not be removed.;
- ;*****************************************************************************/
- ;/*****************************************************************************
- ;*
- ;* SOURCE FILE NAME = svgaid.asm
- ;*
- ;* DESCRIPTIVE NAME = Identify a super VGA adapter in the system, if one exsts.
- ;*
- ;*
- ;* VERSION V2.0
- ;*
- ;* DATE
- ;*
- ;* DESCRIPTION Identify a super VGA adapter in the system, if one exists.
- ;*
- ;* extern void _IdentifySVGA (void);
- ;*
- ;* Call from 'C' as:
- ;*
- ;* IdentifySVGA();
- ;*
- ;* FUNCTIONS
- ;* UpperCaseSearch
- ;* FindStringExpansion
- ;* FindStringSomewhere
- ;* FindStringPlanar
- ;* FindString
- ;* LookStringExpansion
- ;* LookStringSomewhere
- ;* LookStringPlanar
- ;* LookString
- ;* TextDelay
- ;* OutpwDelay
- ;* OutpDelay
- ;* OutpData
- ;* InpDelay
- ;* InpwDelay
- ;* InpData
- ;* OutpInp
- ;* OutpChk
- ;* OutpIdxInpData
- ;* SaveOutpChk
- ;* OutpIdxXchgData
- ;* OutpIdxChkXchgData
- ;* OutpwChk
- ;* SaveOutpwChk
- ;* SaveXORChk
- ;* SaveXORConst
- ;* GetPortBase
- ;* GetCrtcBase
- ;* GetCrtcBaseSave1
- ;* GetSave1
- ;* GetSave2
- ;* GetCrtcBaseSave2
- ;* RestoreSave2
- ;* RestoreSave1
- ;* ATCOutpIdx
- ;* IsNoCrtCWrap
- ;* IsNOTISAAliased
- ;* ATIWaitIdle
- ;* ATIOutpChk
- ;* ATIDestXOutpChk
- ;* ATIAccelerator
- ;* IsATI
- ;* IsSpeedWay
- ;* IsTrident
- ;* IsTseng
- ;* Video7EnableExt
- ;* Video7DisableExt
- ;* IsVideo7
- ;* IsChips
- ;* IsWeitek
- ;* IsWeitekP9x00
- ;* IsWesternDig
- ;* WhichATI
- ;* WhichTrident
- ;* TsengSetATCMisc
- ;* TsengLock
- ;* TsengEnableExt
- ;* TsengDisableExt
- ;* WhichTseng
- ;* WhichVideo7
- ;* WhichWeitek
- ;* WhichWeitekP9x00
- ;* WhichWesternDig
- ;* _IdentifySVGA
- ;*
- ;* NOTES NONE
- ;*
- ;* STRUCTURES NONE
- ;*
- ;* EXTERNAL REFERENCES
- ;*
- ;* EXTERNAL FUNCTIONS
- ;*
- ;****************************************************************************
-
- PAGE 58,132
- TITLE SVGA Idenfication Routines - (svgaid.asm)
-
- INCL_16 EQU 1 ;/* */
-
- ifdef SVGAUTIL
- .286
- ;!! Should this be imported somehow? ;/* */
- DOSIODELAYCNT EQU 10
- else ;/* SVGAUTIL */
- .386p
- include devhlp.inc ;Define DevHlp functions
- endif ;/* SVGAUTIL */
-
-
- .xlist
- include struc.inc ;/* */
- include iodelay.inc ;/* */
- UNDEFINE_SVGA EQU 1 ; exclude various unwanted defs
- include svgadefs.inc ;
- .list
-
- ;!! How do we insure no one interrupts us while we do this? /* */
- ;* There is some chance of incorrect results here, /* */
- ;* due to an interrupting process which changes the contents of /* */
- ;* of some VGA index register(s) between our setting them, /* */
- ;* and our reading or setting the associated data register. /* */
- ;* A screen saver program would be an example such process. /* */
-
- ;/*
- ;** Stuff which should be private
- ;*/
-
- ; all important indicies and values are saved on the stack
- ; STACK FRAME for identify routines
- ;Index/Value pairs must be in consecutive bytes for load by word.
- ;Reorder for easy loading /* */
- SaveValue1 EQU <BYTE PTR [bp-1]> ; BYTE
- SaveIndex1 EQU <BYTE PTR [bp-2]> ; BYTE
- SaveReg1 EQU <WORD PTR [bp-4]> ; WORD
- SaveValue2 EQU <BYTE PTR [bp-5]> ; BYTE
- SaveIndex2 EQU <BYTE PTR [bp-6]> ; BYTE
- SaveReg2 EQU <WORD PTR [bp-8]> ; WORD
- SaveValue3 EQU <BYTE PTR [bp-9]> ; BYTE
- SaveIndex3 EQU <BYTE PTR [bp-10]> ; BYTE
- SaveReg3 EQU <WORD PTR [bp-12]> ; WORD
- SaveValue4 EQU <BYTE PTR [bp-13]> ; BYTE
- SaveIndex4 EQU <BYTE PTR [bp-14]> ; BYTE
- SaveReg4 EQU <BYTE PTR [bp-16]> ; WORD
- STACKBLOCK EQU 16
-
- DGROUP GROUP BioData
-
- EXTRN _sSVGA:DWORD ; /* */
- EXTRN _XGAInstance:WORD ; /* */
- ifndef SVGAUTIL
- EXTRN PCI_DeviceTbl:DWORD ;@senja array of upto 8 (hw=Vendow ID, lw=Device ID)
- EXTRN PCI_Num:WORD ;@senja number of PCI devices found
- endif
-
- ifdef SVGAUTIL
- BioData SEGMENT WORD PUBLIC 'DATA'
- else
- BioData SEGMENT WORD PUBLIC 'DATA' USE16
- endif ;/* SVGAUTIL */
-
- ASSUME DS:DGROUP
-
-
- ifdef SVGAUTIL
- else
- EXTRN DevHelp: DWORD
- endif ;/* SVGAUTIL */
-
- PUBLIC SvgaOEMInfo
- PUBLIC SvgaBaseAddr
- PUBLIC DATA_END
-
- SvgaOEMInfo OEMINFO <SIZE OEMINFO,,> ;@senja
- SvgaBaseAddr DD 0
-
- ;
- ; The following label defines the end of the Screen resident data.
- ;
- DATA_END LABEL BYTE
-
- ATISig DB ' 761295520' ;
- DiamondViperSig DB 'VIPER' ; /* */
- WDSig DB 'VGA=' ;
- WeitekSig DB 'WEITEK' ; /* */
- ; /* */
- ; SEQ06 == Everybody's favorite lock register! /* */
- ; /* */
- ; But since WD and Video7 made the restore value /* */
- ; not DIRECTLY readable, we cannot just read it /* */
- ; while poking around looking for something else and /* */
- ; restore what we read, expecting to preserve things! /* */
- ; /* */
- ; In fact, we CANNOT restore SEQ06 until after we know /* */
- ; which adapter it is! /* */
- ; /* */
- ; But we CAN read enough without knowing which adapter /* */
- ; to restore SEQ06 once we know which adapter! /* */
- ; /* */
- ; WD's SEQ06 restore value can be determined from /* */
- ; how many bits the sequencer index preserves /* */
- ; when you write to it: 6 unlocked, 3 locked. /* */
- ; /* */
- ; Video's SEQ06 restore value can be determined from /* */
- ; the bit zero of what you read from SEQ06. /* */
- ; /* */
- ; Cirrus uses SEQ06 as a lock, /* */
- ; but at least you can read it! (Thank you!) /* */
- ; /* */
- SEQ06 DB ? ;What we will restore! /* */
- SEQ06WD DB ? ;Unless we are WD! /* */
-
- BioData ends
-
-
-
- ifdef SVGAUTIL
- BiosSeg SEGMENT WORD Public 'CODE'
- else
- BiosSeg SEGMENT WORD Public 'CODE' USE16
- endif ;/* SVGAUTIL */
-
- BIOSSeg ends
-
-
-
-
- ;;endif ;endif svgautil
-
- ; set opcodes back to normal
-
- ifdef SVGAUTIL
- .286
- else ;/* SVGAUTIL */
- .386p
- endif ;/* SVGAUTIL */
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; end jwk18
-
-
-
- ifdef SVGAUTIL
- BiosSeg SEGMENT WORD Public 'CODE'
- else
- BiosSeg SEGMENT WORD Public 'CODE' USE16
- endif ;/* SVGAUTIL */
-
- ASSUME CS:BiosSeg
-
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = SVGAPhysToVirt
- ;*
- ;* DESCRIPTION = Convert physical address to virtual.
- ;*
- ;* INPUT = AX = address high
- ;* BX = address low
- ;* CX = length
- ;* OUTPUT = DS:SI = selector/offset pair.
- ;*
- ;* RETURN-NORMAL = NC if no errors.
- ;* RETURN-ERROR = CR if errors.
- ;*
- ;****************************************************************************/
-
- SVGAPhysToVirt PROC Near
- PUBLIC SVGAPhysToVirt
-
- ifdef SVGAUTIL
- mov si, ax
- ror si, 4
- and si, 0f000h ;Clears carry too!
- mov ds, si
- mov si, bx
- else
- push dx ; /* */
- mov dh, 0 ;
- mov dl, DevHlp_PhysToVirt
- call DevHelp ;Leave result in DS:SI
- pop dx ; /* */
- endif ;/* SVGAUTIL */
-
- ret
-
- SVGAPhysToVirt ENDP
-
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = SVGAUnPhysToVirt
- ;*
- ;* DESCRIPTION = Unconvert physical address to virtual.
- ;*
- ;* INPUT = AX = address high
- ;* BX = address low
- ;* CX = length
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = NONE
- ;* RETURN-ERROR = NONE
- ;*
- ;****************************************************************************/
-
- SVGAUnPhysToVirt PROC Near
- PUBLIC SVGAUnPhysToVirt
-
- ifdef SVGAUTIL
- clc ;Return NC.
- else
- push dx ; /* */
- mov dl, DevHlp_UnPhysToVirt ;Let DevHlp know we're done
- pushf ;Save results flags /* */
- call DevHelp ; using virtual addresses.
- popf ;Restore results flags /* */
- pop dx ; /* */
- endif ;/* SVGAUTIL */
-
- ret
-
- SVGAUnPhysToVirt ENDP
-
- ;* ;/* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = SVGAPhysToUVirt
- ;*
- ;* DESCRIPTION = Convert physical address to virtual.
- ;*
- ;* INPUT = AX = address high
- ;* BX = address low
- ;* CX = length
- ;* OUTPUT = ES:BX = selector/offset pair.
- ;*
- ;* RETURN-NORMAL = NC if no errors.
- ;* RETURN-ERROR = CR if errors.
- ;*
- ;****************************************************************************/
-
- SVGAPhysToUVirt PROC Near
- PUBLIC SVGAPhysToUVirt
-
- ifdef SVGAUTIL
- ;*
- ;*!!This is a non-working "safe"? dummy routine which points to ROM.
- ;*!!What we really need is an extension to the DOS XMS specification
- ;*!!or a ROM BIOS routine which handles 32-bit (not 24-bit) addresses,
- ;*!!which would provide a handle to physical memory which do not
- ;*!!have RAM in them.
- ;*
- mov si, 0f000h ;Point to ROM in case no carry check!
- mov es, si
- mov si, bx
- stc ;Always an error for now!
- else
- push dx ; /* */
- mov dh, 004h ;Read/Write Segment&I/O Privilege
- mov dl, DevHlp_PhysToUVirt
- call DevHelp
- pop dx ; /* */
- endif ;/* SVGAUTIL */
-
- ret
-
- SVGAPhysToUVirt ENDP
-
- ;* ;/* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = SVGAUnPhysToUVirt
- ;*
- ;* DESCRIPTION = Unconvert physical address to virtual.
- ;*
- ;* INPUT = ES = selector to virtual address.
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = NC if no errors.
- ;* RETURN-ERROR = CR if errors.
- ;*
- ;****************************************************************************/
-
- SVGAUnPhysToUVirt PROC Near
- PUBLIC SVGAUnPhysToUVirt
-
- ifdef SVGAUTIL
- clc ;Return NC.
- else
- push ax ; /* */
- mov ax, es ;DevHelp Selector reg /* */
- push dx ; /* */
- mov dh, 002h ;UnMap
- mov dl, DevHlp_PhysToUVirt
- pushf ;Save results flags /* */
- call DevHelp
- popf ;Restore results flags /* */
- pop dx ; /* */
- pop ax ; /* */
- endif ;/* SVGAUTIL */
-
- ret
-
- SVGAUnPhysToUVirt ENDP
-
-
- ;*** UpperCaseSearch
- ;
- ; Entry: DS : SI Starting address of the string
- ; CX = length of string
- ; ES : DI ROM address to compare with
- ;
- ; Capitalize the string at the location.
- ; Restores all entry registers
- ;
- ;* RETURN-NORMAL = ZR if found.
- ;* RETURN-ERROR = NZ if not found.
- ;
- UpperCaseSearch PROC Near
- PUBLIC UpperCaseSearch
-
- push cx ; /* */
- jcxz ExitUpperCase ;Exit w/CX zero=success!/* */
- push ax ; /* */
- push si ; /* */
- push di ; /* */
- UpperCaseLoop: ; /* */
- mov al, byte ptr ds:[si]
- cmp al, 'a'
- jl short @F
- cmp al, 'z'
- jg short @F
- sub al, 20h
- @@:
- cmp es:[di], al
- jne StringNotFound ;Exit with CX non zero=failure!
- inc si
- inc di
- loop UpperCaseLoop ;Loop or w/CX=success! /* */
- StringNotFound: ; /* */
- pop di ; /* */
- pop si ; /* */
- pop ax ; /* */
- ExitUpperCase:
- and cx, cx ;Success=no chars left /* */
- pop cx ; /* */
- ret
-
- UpperCaseSearch ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = FindStringExpansion
- ;*
- ;* DESCRIPTION =
- ;* Look for string at C000:xxxx ROM BIOS location to identify a SVGA card.
- ;* Capitalize the string searched as to make it case insensitive.
- ;*
- ;* INPUT = BX = ROM address (low)
- ;* CX = length of string
- ;* DS:DI -> string to compare (in DGROUP)
- ;*
- ;* OUTPUT = AX = 0000ch
- ;*
- ;* RETURN-NORMAL = ZR if found.
- ;* RETURN-ERROR = NZ if not found.
- ;*
- ;****************************************************************************/
-
- FindStringExpansion PROC Near
- PUBLIC FindStringExpansion
-
- mov ax, 0000ch ; /* */
- ; Now fall thru to (call and return):
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = FindStringSomewhere
- ;*
- ;* DESCRIPTION =
- ;* Look for string at ROM BIOS location to identify a SVGA card.
- ;* Capitalize the string searched as to make it case insensitive.
- ;*
- ;* INPUT = AX = ROM address (high)
- ;* BX = ROM address (low)
- ;* CX = length of string
- ;* DS:DI -> string to compare (in DGROUP)
- ;*
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = ZR if found.
- ;* RETURN-ERROR = NZ if not found.
- ;*
- ;****************************************************************************/
-
- FindStringSomewhere PROC Near
- PUBLIC FindStringSomewhere
-
- push es
- push ds
- push ds ;Move match string selector to ES.
- pop es
- call SVGAPhysToVirt ;Get virtual address into DS:SI.
-
- ASSUME DS:NOTHING, ES:DGROUP
-
- cld
- ; xor ax, ax ; /* */
- call UpperCaseSearch
- pop ds ;Restore DEVHLP ptr selector!
- pop es
-
- ASSUME DS:DGROUP, ES:NOTHING
-
- call SVGAUnPhysToVirt ;Unmap AX:BX.
- ret
-
- FindStringSomewhere ENDP
-
- FindStringExpansion ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = FindStringPlanar
- ;*
- ;* DESCRIPTION =
- ;* Look for string at E000:xxxx ROM BIOS location to identify a SVGA card.
- ;* Capitalize the string searched as to make it case insensitive.
- ;*
- ;* INPUT = BX = ROM address (low)
- ;* CX = length of string
- ;* DS:DI -> string to compare (in DGROUP)
- ;*
- ;* OUTPUT = AX = 0000eh
- ;*
- ;* RETURN-NORMAL = ZR if found.
- ;* RETURN-ERROR = NZ if not found.
- ;*
- ;****************************************************************************/
-
- FindStringPlanar PROC Near
- PUBLIC FindStringPlanar
-
- mov ax, 0000eh ; /* */
- call FindStringSomewhere
- ret
-
- FindStringPlanar ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = FindString
- ;*
- ;* DESCRIPTION =
- ;* Look for string at ROM BIOS location to identify a SVGA card.
- ;* Capitalize the string searched as to make it case insensitive.
- ;*
- ;* INPUT = BX = ROM address (low)
- ;* CX = length of string
- ;* DS:DI -> string to compare (in DGROUP)
- ;*
- ;* OUTPUT = AX = ROM address (high)
- ;*
- ;* RETURN-NORMAL = ZR if found.
- ;* RETURN-ERROR = NZ if not found.
- ;*
- ;****************************************************************************/
-
- FindString PROC Near
- PUBLIC FindString
-
- call FindStringExpansion
- .if < nz > ;If not found on expansion card:
- call FindStringPlanar ;Try planar ROM instead.
- .endif
- ret
-
- FindString ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = LookStringExpansion
- ;*
- ;* DESCRIPTION =
- ;* Look for string at C000:0-200 ROM BIOS location to identify a SVGA card.
- ;* Capitalize the string searched as to make it case insensitive.
- ;*
- ;* INPUT = CX = length of string
- ;* DS:DI -> string to compare (in DGROUP)
- ;*
- ;* OUTPUT = AX = 0000ch
- ;*
- ;* RETURN-NORMAL = ZR if found.
- ;* RETURN-ERROR = NZ if not found.
- ;*
- ;****************************************************************************/
-
- LookStringExpansion PROC Near
- PUBLIC LookStringExpansion
-
- mov ax, 0000ch ; /* */
- ; Now fall thru to (call and return):
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = LookStringSomewhere
- ;*
- ;* DESCRIPTION =
- ;* Look for string at ROM BIOS offsets 0-200 to identify a SVGA card.
- ;* Capitalize the string searched as to make it case insensitive.
- ;*
- ;* INPUT = AX = ROM address (high)
- ;* CX = length of string
- ;* DS:DI -> string to compare (in DGROUP)
- ;*
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = ZR if found.
- ;* RETURN-ERROR = NZ if not found.
- ;*
- ;****************************************************************************/
-
- LookStringSomewhere PROC Near
- PUBLIC LookStringSomewhere
-
- push bx
- push es
- push ds
- push cx ;Save string length.
- push ds ;Move match string selector to ES.
- pop es
- xor bx, bx ;Low offset zero.
- add cx, 00200h ;Limit search to first 200 bytes.
- call SVGAPhysToVirt ;Get virtual address into DS:SI.
- pop cx ;Restore string length
-
- ASSUME DS:NOTHING, ES:DGROUP
-
- cld
- ; xor ax, ax ; /* */
- .repeat
- call UpperCaseSearch
- .until <e> OR ;Until string found (z).
- inc si ;Check next location in ROM.
- .until <si a 00200h> ;Until no more locations to check (nz).
- pop ds ;Restore DEVHLP ptr selector!
- pop es
-
- ASSUME DS:DGROUP, ES:NOTHING
-
- call SVGAUnPhysToVirt ;Unmap AX:BX.
- pop bx
- ret
-
- LookStringSomewhere ENDP
-
- LookStringExpansion ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = LookStringPlanar
- ;*
- ;* DESCRIPTION =
- ;* Look for string at E000:0-200 ROM BIOS location to identify a SVGA card.
- ;* Capitalize the string searched as to make it case insensitive.
- ;*
- ;* INPUT = CX = length of string
- ;* DS:DI -> string to compare (in DGROUP)
- ;*
- ;* OUTPUT = AX = 0000eh
- ;*
- ;* RETURN-NORMAL = ZR if found.
- ;* RETURN-ERROR = NZ if not found.
- ;*
- ;****************************************************************************/
-
- LookStringPlanar PROC Near
- PUBLIC LookStringPlanar
-
- mov ax, 0000eh ; /* */
- call LookStringSomewhere
- ret
-
- LookStringPlanar ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = LookString
- ;*
- ;* DESCRIPTION =
- ;* Look for string at ROM BIOS offsets 0-200 to identify a SVGA card.
- ;* Capitalize the string searched as to make it case insensitive.
- ;*
- ;* INPUT = CX = length of string
- ;* DS:DI -> string to compare (in DGROUP)
- ;*
- ;* OUTPUT = AX = ROM address (high)
- ;*
- ;* RETURN-NORMAL = ZR if found.
- ;* RETURN-ERROR = NZ if not found.
- ;*
- ;****************************************************************************/
-
- LookString PROC Near
- PUBLIC LookString
-
- call LookStringExpansion
- .if < nz > ;If not found on expansion card:
- call LookStringPlanar ;Try planar ROM instead.
- .endif
- ret
-
- LookString ENDP
-
- ;*
- ;* All input and output instructions were deliberately put into
- ;* separate subroutines to insure that a TextDelay preceeded each.
- ;* Even though the chip being LOOKED FOR often does not need such
- ;* delays, the chip being TESTED may need them!
- ;*
- ;* We need to be able to minimize changes made to the chip being TESTED
- ;* and restore it to its original state when we are done,
- ;* so that we minimize the potential for annoying or damaging
- ;* "special effects" on OTHER manufacturer's chips.
- ;*
-
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = TextDelay
- ;*
- ;* DESCRIPTION = Instead of using the macro to save code space
- ;*
- ;* INPUT = NONE
- ;* OUTPUT = NONE
- ;* WARNING - trashes si
- ;*
- ;* RETURN-NORMAL = NONE
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;* OutpwDelay
- ;* OutpDelay
- ;* InpDelay
- ;* InpwDelay
- ;*
- ;****************************************************************************/
-
- TextDelay PROC Near ;
- PUBLIC TextDelay ;
-
- push si ; ;JWK07
- pushf ;Save flag register. /* */
- DevIODelay si ;
- popf ;Restore flags. /* */
- pop si ; ;JWK07
- ret ;
-
- TextDelay ENDP ;
-
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = _TextDelay
- ;*
- ;* DESCRIPTION = Instead of using the macro to save code space
- ;*
- ;* INPUT = NONE
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = NONE
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;* InputDelay
- ;* OutputDelay
- ;*
- ;****************************************************************************/
-
- _TextDelay PROC Far ; /* */
- PUBLIC _TextDelay ;
-
- call TextDelay ;
- ret
-
- _TextDelay ENDP ;
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = OutpwDelay
- ;*
- ;* DESCRIPTION = Output to word port preceeded by I/O delay.
- ;*
- ;* INPUT = DX = Output port.
- ;* AX = Value to output.
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = NONE
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- OutpwDelay PROC Near
- PUBLIC OutpwDelay
-
- call TextDelay ;IMMEDIATELY before to minimize delay!
- out dx, ax ;Output to port.
- ret
-
- OutpwDelay ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = OutpDelay
- ;*
- ;* DESCRIPTION = Output to byte port preceeded by I/O delay.
- ;*
- ;* INPUT = DX = Output port.
- ;* AL = Value to output.
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = NONE
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- OutpDelay PROC Near
- PUBLIC OutpDelay
-
- call TextDelay ;IMMEDIATELY before to minimize delay!
- out dx, al ;Output to port.
- ret
-
- OutpDelay ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = OutpData
- ;*
- ;* DESCRIPTION = Output to byte port preceeded by I/O delay.
- ;*
- ;* INPUT = DX = Output index port.
- ;* AL = Data value to output.
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = NONE
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- OutpData PROC Near
- PUBLIC OutpData
-
- inc dx ;Point to data register.
- call OutpDelay ;
- dec dx ;Point back to index register.
- ret
-
- OutpData ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = InpDelay
- ;*
- ;* DESCRIPTION = Input from byte port preceeded by I/O delay.
- ;*
- ;* INPUT = DX = Input port.
- ;* OUTPUT = AL = Input value.
- ;*
- ;* RETURN-NORMAL = NONE
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- InpDelay PROC Near
- PUBLIC InpDelay
-
- call TextDelay ;IMMEDIATELY before to minimize delay!
- in al, dx ;Input from port.
- ret
-
- InpDelay ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = InpwDelay
- ;*
- ;* DESCRIPTION = Input from word port preceeded by I/O delay.
- ;*
- ;* INPUT = DX = Input port.
- ;* OUTPUT = AX = Input value.
- ;*
- ;* RETURN-NORMAL = NONE
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- InpwDelay PROC Near
- PUBLIC InpwDelay
-
- call TextDelay ;IMMEDIATELY before to minimize delay!
- in ax, dx ;Input from port.
- ret
-
- InpwDelay ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = InpData
- ;*
- ;* DESCRIPTION = Input from byte port preceeded by I/O delay.
- ;*
- ;* INPUT = DX = Output index port.
- ;* OUTPUT = AL = Data value input.
- ;*
- ;* RETURN-NORMAL = NONE
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;* OutpIdxInpData
- ;* IsTrident
- ;* IsWeitek
- ;* IsWeitekP9x00
- ;* WhichWesternDig
- ;*
- ;****************************************************************************/
-
- InpData PROC Near
- PUBLIC InpData
-
- inc dx ;Point to data register.
- call InpDelay ;
- dec dx ;Point back to index register.
- ret
-
- InpData ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = OutpInp
- ;*
- ;* DESCRIPTION = Output to byte port and re-read it.
- ;*
- ;* INPUT = DX = Input port.
- ;* AL = New value.
- ;* OUTPUT = AL = Modified new value.
- ;*
- ;* RETURN-NORMAL = NONE
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;* OutpChk
- ;* SaveXORConst
- ;* IsNotISAAliased
- ;* IsCirrus
- ;*
- ;****************************************************************************/
-
- OutpInp PROC Near
- PUBLIC OutpInp
-
- call OutpDelay ;Write byte out.
- call InpDelay ;Read modified byte back.
- ret
-
- OutpInp ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = OutpChk
- ;*
- ;* DESCRIPTION = Test for read/write register.
- ;*
- ;* INPUT = DX = port address.
- ;* AL = new value.
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = ZR (reads match writes).
- ;* RETURN-ERROR = NZ (reads do not match writes).
- ;*
- ;* CALLED BY
- ;* SaveOutpChk
- ;* OutpIdxXchgData
- ;* OutpIdxChkXchgData
- ;* OutpwChk
- ;* SaveXORChk
- ;* ATCOutpIdx
- ;* IsTseng
- ;* LastAttempt
- ;*
- ;****************************************************************************/
-
- OutpChk PROC Near
- PUBLIC OutpChk
-
- push ax
- mov ah, al ;Save value written.
- call OutpInp ;Write new & read modified value.
- cmp al, ah ;Was read same as write?
- pop ax
- ret
-
- OutpChk ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = OutpIdxInpData
- ;*
- ;* DESCRIPTION = Read indexed register.
- ;*
- ;* INPUT = DX = port address.
- ;* AL = index.
- ;* OUTPUT = AL = value read.
- ;*
- ;* RETURN-NORMAL = NONE
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;* OutpIdxXchgData
- ;* IsNoCrtcWrap
- ;* IsS3
- ;* TsengSetATCMisc
- ;* IsVideo7
- ;* WDRegPairString
- ;* IsWeitek
- ;* IsWeitekP9x00
- ;* LastAttempt
- ;* WhichATI
- ;* WhichCirrus
- ;* WhichS3
- ;* WhichTrident
- ;* WhichTseng
- ;* WhichVideo7
- ;* WhichWeitek
- ;* WhichWesternDig
- ;*
- ;****************************************************************************/
-
- OutpIdxInpData PROC Near
- PUBLIC OutpIdxInpData
-
- call OutpDelay ;Write the new index value.
- call InpData ;Read the data value.
- ret
-
- OutpIdxInpData ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = SaveOutpChk
- ;*
- ;* DESCRIPTION = Test for read/write register.
- ;*
- ;* INPUT = DX = port address.
- ;* AL = new value.
- ;* OUTPUT = NONE
- ;* original value restored.
- ;*
- ;* RETURN-NORMAL = ZR (reads match writes).
- ;* RETURN-ERROR = NZ (reads do not match writes).
- ;*
- ;* CALLED BY
- ;* OutpIdxChkXchgData
- ;* OutpwChk
- ;* SaveOutpwChk
- ;* LastAttempt
- ;*
- ;****************************************************************************/
-
- SaveOutpChk PROC Near
- PUBLIC SaveOutpChk
-
- push ax
- mov ah, al ;Save new value.
- call InpDelay ;Read the original value.
- xchg ah, al ;Save original value, use new.
- call OutpChk ;Write new value and compare.
- mov al, ah ;Get back old value.
- call OutpDelay ;Restore old value if possible.
- .if < z > ;If new value was the same,
- call InpDelay ;Read back the value.
- cmp al, ah ;Was read same as write?
- .endif
- pop ax
- ret
-
- SaveOutpChk ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = OutpIdxXchgData
- ;*
- ;* DESCRIPTION = Read and save indexed register, write with new value.
- ;*
- ;* INPUT = DX = port address.
- ;* AL = index.
- ;* AH = new value to write.
- ;* OUTPUT = AL = value read.
- ;* This value can be/must be "restored" to register addressed
- ;* with the INPUT index.
- ;*
- ;* RETURN-NORMAL = NONE
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;* IsCirrus
- ;* IsTrident
- ;* WhichS3
- ;*
- ;****************************************************************************/
-
- OutpIdxXchgData PROC Near
- PUBLIC OutpIdxXchgData
-
- call OutpIdxInpData ;Read the original value.
- xchg al, ah ;Exchange old & new values.
- call OutpData ;Test for read/writable reg
- xchg al, ah ;Exchange old & new values.
- ret
-
- OutpIdxXchgData ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = OutpIdxChkXchgData
- ;*
- ;* DESCRIPTION = Read and save indexed register, write with new value.
- ;*
- ;* INPUT = DX = port address.
- ;* AL = index.
- ;* AH = new value to write.
- ;* OUTPUT = AL = value read.
- ;* This value can be/must be "restored" to register addressed
- ;* with the INPUT index, even when error (NZ) returned!
- ;*
- ;* RETURN-NORMAL = ZR (reads match writes).
- ;* RETURN-ERROR = NZ (reads do not match writes).
- ;*
- ;* CALLED BY
- ;* GetCrtcBaseSave2
- ;* IsCirrus
- ;* Video7EnableExt
- ;* IsVideo7
- ;* WDEnableExt
- ;* WhichCirrus
- ;*
- ;****************************************************************************/
-
- OutpIdxChkXchgData PROC Near
- PUBLIC OutpIdxChkXchgData
-
- call SaveOutpChk ;Test for read/writeable index reg.
- pushf ;Save flags.
- call OutpIdxInpData ;Read the original value.
- popf ;Restore flags.
- .if < z > ;If read/write index:
- xchg al, ah ;Exchange old & new values.
- push dx
- inc dx ;Point to the data register.
- call OutpChk ;Test for read/writable reg
- pop dx
- xchg al, ah ;Exchange old & new values.
- .endif
- ret
-
- OutpIdxChkXchgData ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = OutpwChk
- ;*
- ;* DESCRIPTION = Test for read/write indexed/word register.
- ;*
- ;* INPUT = DX = port address.
- ;* AX = index (AL) and new value (AH).
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = ZR (reads match writes).
- ;* RETURN-ERROR = NZ (reads do not match writes).
- ;*
- ;* CALLED BY
- ;* WhichCirrus
- ;*
- ;****************************************************************************/
-
- OutpwChk PROC Near
- PUBLIC OutpwChk
-
- call SaveOutpChk ;Check index set.
- .if < z > ;If no error setting index:
- push dx
- call OutpDelay ;Write the new index value.
- inc dx ;Point to the data register.
- xchg al, ah ;Get new value.
- call OutpChk
- xchg al, ah
- pop dx
- .endif
- ret
-
- OutpwChk ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = SaveOutpwChk
- ;*
- ;* DESCRIPTION = Test indexed register for read/write register.
- ;*
- ;* INPUT = DX = port address.
- ;* AL = index register number.
- ;* AH = new value.
- ;* OUTPUT = original value restored.
- ;*
- ;* RETURN-NORMAL = ZR (reads match writes).
- ;* RETURN-ERROR = NZ (reads do not match writes).
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- SaveOutpwChk PROC Near
- PUBLIC SaveOutpwChk
-
- call SaveOutpChk ;Check index set.
- .if < z > ;If no error and can set index:
- push dx
- call OutpDelay ;Write the new index value.
- inc dx ;Point to the data register.
- xchg al, ah ;Get new value.
- call SaveOutpChk
- xchg al, ah
- pop dx
- .endif
- ret
-
- SaveOutpwChk ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = SaveXORChk
- ;*
- ;* DESCRIPTION = Test for read write register.
- ;*
- ;* INPUT = DX = port address.
- ;* AL = value to XOR with.
- ;* OUTPUT = original value restored.
- ;*
- ;* RETURN-NORMAL = ZR (reads match writes).
- ;* RETURN-ERROR = NZ (reads do not match writes).
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- SaveXORChk PROC Near
- PUBLIC SaveXORChk
-
- push ax
- mov ah, al ;Save bits to modify.
- call InpDelay ;Read the original value.
- xchg ah, al ;Save original value, restore mask.
- xor al, ah ;XOR in changable bits.
- call OutpChk ;Write new value and compare.
- mov al, ah ;Get back old value.
- call OutpDelay ;Restore old value if possible.
- .if < z > ;If new value was the same,
- call InpDelay ;Read back the value.
- cmp al, ah ;Was read same as write?
- .endif
- pop ax
- ret
-
- SaveXORChk ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = SaveXORConst
- ;*
- ;* DESCRIPTION = Test for unwritable (constant) bits in register.
- ;*
- ;* INPUT = DX = port address.
- ;* AL = value to XOR with.
- ;* OUTPUT = original value restored.
- ;*
- ;* RETURN-NORMAL = ZR (no bits changed).
- ;* RETURN-ERROR = NZ (some bits changed).
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- SaveXORConst PROC Near
- PUBLIC SaveXORConst
-
- push ax
- mov ah, al ;Save bits to modify.
- call InpDelay ;Get original value.
- xchg ah, al ;Save original value, restore mask.
- xor al, ah ;XOR in presumed constant bits.
- call OutpInp ;Write new & read modified values.
- xor al, ah ;Did bits stay same? Return success!
- mov al, ah ;Get original value.
- call OutpDelay ;Restore original value.
- pop ax
- ret
-
- SaveXORConst ENDP
-
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = GetPortBase
- ;*
- ;* DESCRIPTION = Return port base address in DX (3b0 or 3d0)
- ;* depending on mono/colour mode.
- ;*
- ;* INPUT = NONE
- ;* OUTPUT = DX = 3x0 (3b0 or 3d0) port base address.
- ;*
- ;* RETURN-NORMAL = NONE
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;* GetCrtcBase
- ;* ATCOutpIdx
- ;* TsengLock
- ;* TsengEnableExt
- ;*
- ;****************************************************************************/
-
- GetPortBase PROC Near
- PUBLIC GetPortBase
-
- push ax ; /* */
- mov dx, 03cch ;Misc Output Read addr
- call InpDelay ;Input from port.
- mov dl, 0b0h ; assume mono /* */
- and al, 001h ; /* */
- shl al, 5 ; /* */
- add dl, al ;Bump up to color maybe /* */
- pop ax ; /* */
- ret ; /* */
-
- GetPortBase ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = GetCrtcBase
- ;*
- ;* DESCRIPTION = Return port base address in DX (3b0 or 3d0)
- ;* depending on mono/colour mode.
- ;*
- ;* INPUT = NONE
- ;* OUTPUT = DX = 3x4 port base address.
- ;* CX = 3x0 base address.
- ;*
- ;* RETURN-NORMAL = NONE
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;* GetCrtcBaseSave1
- ;* WhichCirrus
- ;* WhichTrident
- ;* WhichTseng
- ;*
- ;****************************************************************************/
-
- GetCrtcBase PROC Near
- PUBLIC GetCrtcBase
-
- call GetPortBase ;Depends on mono/color /* */
- mov cx, dx ;
- add dl, 0004h ;Crtc index address.
- ret
-
- GetCrtcBase ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = GetCrtcBaseSave1
- ;*
- ;* DESCRIPTION = Return port base address in DX (3b0 or 3d0)
- ;* depending on mono/colour mode.
- ;*
- ;* INPUT = AX = index register to save and new value.
- ;* BP = stack frame pointer.
- ;* OUTPUT = DX = 3x4 port base address.
- ;* CX = 3x0 base address.
- ;*
- ;* RETURN-NORMAL = NONE
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- GetCrtcBaseSave1 PROC Near
- PUBLIC GetCrtcBaseSave1
-
- call GetCrtcBase ;(3d4) /* */
- ;* OUTPUT = DX = 003x4 (CRTC index address)
- ; Now fall thru to (call and return):
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = GetSave1
- ;*
- ;* DESCRIPTION = Input from byte port preceeded by I/O delay.
- ;* Save into SaveReg1/SaveIndex1 pair.
- ;*
- ;* INPUT = DX = Input port.
- ;* BP = Stack frame pointer.
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = NONE
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;* GetCrtcBaseSave1
- ;* IsCirrus
- ;* IsTrident
- ;* IsWeitek
- ;* IsWeitekP9x00
- ;* WhichCirrus
- ;* WhichTseng
- ;* WhichWeitek
- ;*
- ;****************************************************************************/
-
- GetSave1 PROC Near
- PUBLIC GetSave1
-
- mov [SaveReg1], dx
- push ax
- call InpDelay ;Read the original value.
- mov [SaveIndex1], al ;Save it.
- pop ax
- ret
-
- GetSave1 ENDP
-
- GetCrtcBaseSave1 ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = GetSave2
- ;*
- ;* DESCRIPTION = Input from byte port preceeded by I/O delay.
- ;* Save into SaveReg2/SaveIndex2 pair.
- ;*
- ;* INPUT = DX = Input port.
- ;* BP = Stack frame pointer.
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = NONE
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;* TsengEnableExt
- ;* Video7EnableExt
- ;* LastAttempt
- ;*
- ;****************************************************************************/
-
- GetSave2 PROC Near
- PUBLIC GetSave2
-
- mov [SaveReg2], dx
- push ax
- call InpDelay ;Read the original value.
- mov [SaveIndex2], al ;Save it.
- pop ax
- ret
-
- GetSave2 ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = GetCrtcBaseSave2
- ;*
- ;* DESCRIPTION = Return port base address in DX (3b0 or 3d0)
- ;* depending on mono/colour mode.
- ;*
- ;* INPUT = AX = index register to save and new value.
- ;* BP = stack frame pointer.
- ;* OUTPUT = DX = 3x4 port base address.
- ;* CX = 3x0 base address.
- ;*
- ;* RETURN-NORMAL = ZR (reads match writes).
- ;* RETURN-ERROR = NZ (reads do not match writes).
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- GetCrtcBaseSave2 PROC Near
- PUBLIC GetCrtcBaseSave2
-
- call GetCrtcBaseSave1 ;(3d4) /* */
- ;* OUTPUT = DX = 003x4 (CRTC index address)
- mov [SaveReg2], dx ;Save register address.
- mov [SaveIndex2], al ;Save index register.
- push ax ;Save index register and value.
- call OutpIdxChkXchgData ;Read original value, write new.
- mov [SaveValue2], al ;Save original value for restore.
- pop ax ;Restore index register and value.
- ret
-
- GetCrtcBaseSave2 ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = RestoreSave2
- ;*
- ;* DESCRIPTION = Restore indexed register and index value.
- ;*
- ;* INPUT = BP = Stack frame pointer.
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = NONE
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;* IsCirrus
- ;* WDDisableExt
- ;* WhichCirrus
- ;* WhichS3
- ;*
- ;****************************************************************************/
-
- RestoreSave2 PROC Near
- PUBLIC RestoreSave2
-
- mov dx, [SaveReg2]
- push ax
- mov ax, word ptr [SaveIndex2] ;Get the original value.
- call OutpwDelay ;Write the original value.
- pop ax
- ; Now fall thru to (call and return):
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = RestoreSave1
- ;*
- ;* DESCRIPTION = Restore original index register value.
- ;*
- ;* INPUT = BP = Stack frame pointer.
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = NONE
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;* RestoreSave2
- ;* IsTrident
- ;* IsTseng
- ;* IsVideo7
- ;* IsWeitek
- ;* IsWeitekP9x00
- ;* LastAttempt
- ;* WhichTseng
- ;* WhichWeitek
- ;*
- ;****************************************************************************/
-
- RestoreSave1 PROC Near
- PUBLIC RestoreSave1
-
- mov dx, [SaveReg1]
- push ax
- mov al, [SaveIndex1] ;Get the original value.
- call OutpDelay ;Write the original value.
- pop ax
- ret
-
- RestoreSave1 ENDP
-
- RestoreSave2 ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = ATCOutpIdx
- ;*
- ;* DESCRIPTION = Reset ATC Flip flop and set ATC index.
- ;*
- ;* INPUT = AL = New index value to set.
- ;* OUTPUT = DX = 3c0 = ATC Index address
- ;* CX = 3x0 base address
- ;* CLOBBERS = AH
- ;*
- ;* RETURN-NORMAL = ZR (reads match writes).
- ;* RETURN-ERROR = NZ (reads do not match writes).
- ;*
- ;* CALLED BY
- ;* IsTseng
- ;*
- ;****************************************************************************/
-
- ATCOutpIdx PROC Near
- PUBLIC ATCOutpIdx
-
- call GetPortBase ;Get port base address
- add dx, 00ah
- push ax ;Save new index to set.
- call InpDelay ;Dummy read to set to index write.
- pop ax ;Restore new index to set.
- mov dl, 0c0h ;ATC address (3c0)
- call OutpChk ;Write new ATC index value.
- ret
-
- ATCOutpIdx ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = IsNoCrtcWrap
- ;*
- ;* DESCRIPTION = Check for CTRC Wrap at 020h
- ;*
- ;* INPUT = BP = Stack frame pointer.
- ;* DX = 3x4 port base address.
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = ZR (if no wrap).
- ;* RETURN-ERROR = NZ (if wrap).
- ;*
- ;* CALLED BY
- ;* WDEnableExt
- ;* IsS3
- ;* IsTseng
- ;*
- ;****************************************************************************/
-
- IsNoCrtcWrap PROC Near
- PUBLIC IsNoCrtcWrap
-
- mov al, 00fh + 020h ;Use safe reg: cur addr low
- call OutpIdxInpData ;Get current value
- mov ah, al ;
- mov al, 00fh ;Point to cur addr low reg
- call OutpIdxInpData ;
- .if <al e ah> ;If regs are same:
- not al ;Get ones complement.
- call OutpData ;
- mov al, 00fh + 020h ;Point past wrapping
- call OutpIdxInpData ;
- not al ;Get ones complement.
- cmp al, ah ;See if regs are still the same.
- mov al, 00fh ;Point to row offset reg
- call OutpwDelay ;Restore cur addr low.
- .endif
- lahf ;Get flags into AH.
- and ah, 040h ;Complement zero flag!
- ret
-
- IsNoCrtcWrap ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = IsNotISAAliased
- ;*
- ;* DESCRIPTION = Test for register NOT ISA aliased.
- ;*
- ;* INPUT = DX = port address.
- ;* AL = SAFE new mask to XOR test.
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = ZR (reads do not match writes). Is NOT Aliased!
- ;* RETURN-ERROR = NZ (reads match writes). Is Aliased!
- ;*
- ;* CALLED BY
- ;* IsSpeedWay
- ;*
- ;****************************************************************************/
-
- IsNotISAAliased PROC Near
- PUBLIC IsNotISAAliased
-
- push ax ;Save original & test values.
- push bx
- push cx
- mov bl, al ;Save test mask to XOR.
- mov cx, dx ;Save original port.
- call InpDelay ;Get value at original port.
- mov bh, al ;Save value at original port.
- ;
- ; 003ffh mask should be similarly effective. /* */
- ;
- and dx, 00fffh ;Get alias port address.
- call InpDelay ;Get value at alias port.
- xchg dx, cx ;Get back original port.
- .if <al e bh> ;Can only be alias if same now first!
- mov al, bh ;Restore original value.
- xor al, bl ;XOR with test mask to force changes.
- call OutpInp ;Write new & read modified values.
- mov ah, al ;Save modified test value.
- xchg dx, cx ;Get back alias port.
- call InpDelay ;Read back the value.
- cmp al, ah ;Was alias read same as write?
- xchg dx, cx ;Get back original port.
- mov al, bh ;Get original value.
- call OutpDelay ;Restore original value.
- .endif
- lahf ;Get flags.
- and ah, 040h ;Complement ZR, now NOT aliased!
- pop cx
- pop bx
- pop ax
- ret
-
- IsNotISAAliased ENDP
-
- ;*****************************************************************************
- ;
- ;
- ;
- ;*****************************************************************************
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = ATIWaitIdle
- ;*
- ;* DESCRIPTION = Wait for ATI accelerator to be idle.
- ;*
- ;* INPUT = NONE
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = ZR (now idle)
- ;* RETURN-ERROR = NZ (timeout)
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- ATIWaitIdle PROC near ;
- PUBLIC ATIWaitIdle
-
- xor cx, cx ;Initialize timeout.
- push dx
- mov dx, 09aeeh ;EXT_FIFO_STATUS reg.
- .repeat
- call InpwDelay ;Read EXT_FIFO_STATUS reg.
- test ax, 00001h ;16 free FIFOs?
- .loop < nz > ;Wait until timeout or YES.
- .if < z > ;If no failure:
- xor cx, cx ;Initialize timeout.
- mov dx, 09ae8h ;GP_STAT reg.
- .repeat
- call InpwDelay ;Read GP_STAT reg.
- test ax, 00200h ;GP_BUSY?
- .loop < nz > ;Wait until timeout or NO.
- .endif
- pop dx
- ret
-
- ATIWaitIdle ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = ATIOutpChk
- ;*
- ;* DESCRIPTION = Test ATI chip for register writable.
- ;*
- ;* INPUT = AX - value to write.
- ;* DX - register address to write to and read from.
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = ZR (now idle and same)
- ;* RETURN-ERROR = NZ (timeout or different)
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- ATIOutpChk PROC near ;
- PUBLIC ATIOutpChk
-
- mov bx, ax ;Save original value to write.
- call OutpwDelay ;Write register value.
- call ATIWaitIdle
- .if < z > ;If idle and OK so far:
- call InpwDelay ;Read the register again.
- cmp ax, bx ;Compare with original written value.
- .endif ;Else failure.
- ret
-
- ATIOutpChk ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = ATIDestXOutpChk
- ;*
- ;* DESCRIPTION = Test ATI chip for DESTX_DIASTP set effecting READ_SRC_X.
- ;*
- ;* INPUT = AX - value to write.
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = ZR (now idle and same)
- ;* RETURN-ERROR = NZ (timeout or different)
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- ATIDestXOutpChk PROC Near
- PUBLIC ATIDestXOutpChk
-
- mov bx, ax ;Save original value to write.
- mov dx, 08ee8h ;Get DESTX_DIASTP reg address.
- call OutpwDelay ;Write the new value.
- call ATIWaitIdle
- .if < z > ;If idle and OK so far:
- mov dx,0daeeh ;Get READ_SRC_X reg address.
- call InpwDelay ;Read the value.
- cmp ax,bx ;Compare with original written value.
- .endif ;Else failure.
- ret
-
- ATIDestXOutpChk ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = ATI8514
- ;*
- ;* DESCRIPTION = Test ATI chip for 8514 Accelerator.
- ;*
- ;* INPUT = NONE
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = ZR (has 8514 Accelerator)
- ;* RETURN-ERROR = NZ (timeout or other failure)
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- ATI8514 PROC near ; /* */
- PUBLIC ATI8514 ; /* */
-
- ;*
- ;* Test for 8514 first.
- ;*
- mov dx, 042e8h ;SUBSYS_CNTL reg.
- mov ax, 0900fh
- call OutpwDelay ;Write the new value.
- mov ax, 0400fh
- call OutpwDelay ;Write the new value.
- mov dx, 002ebh ;DAC_R_INDEX reg.
- mov al, 0a4h
- call OutpDelay ;Write the new value.
- xor cx, cx
- .repeat ;Wait fixed amount of time.
- .loop
- mov dx, 002ech ;DAC_W_INDEX reg
- call InpDelay ;Input from port.
- .if <al e 0a5h> ;Always one more! /* */
- mov dx, 092e8h ;ERR_TERM reg address.
- call InpwDelay ;Read the value.
- push ax ;Save original value.
- not ax ;Change all the bits. /* */
- call ATIOutpChk ;See if they all change./* */
- pop ax ; /* */
- call OutpwDelay ;Restore original value./* */
- .endif ;Else success! 8514!
- ;*
- ;* Test for ATI Accelerator:
- ;*
- .if < z > ;If some type of 8514:
- mov dx, 052eeh ;ROM_ADDR_1 reg address.
- call InpwDelay ;Read the value.
- push ax ;
- not ax ;Change all the bits. /* */
- call ATIOutpChk ;See if they all change.
- pop ax ;
- call OutpwDelay ;Restore original value.
- .endif ;Else failure.
- ret ;
-
- ATI8514 ENDP ; /* */
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = ATIMach64
- ;*
- ;* DESCRIPTION = Test ATI chip for Mach64 Accelerator.
- ;*
- ;* INPUT = NONE
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = ZR (has Mach64 Accelerator)
- ;* RETURN-ERROR = NZ (timeout or other failure)
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- ATIMach64 PROC near ; /* */
- PUBLIC ATIMach64
-
- mov dx, 01eeeh ;CRTC_GEN_CTRL addr.
- call InpwDelay ;Read the current value.
- push ax ;Save current value.
- and ah, not 001h ;Disable VGA passthru.
- call OutpwDelay ;Write the new value.
- mov dx, 066eeh ;GEN_TEST_CTRL reg.
- call InpwDelay ;Read the current value.
- push ax ;Save gen_test_ctrl.
- and al, not 070h ;Turn off test mode.
- call OutpwDelay ;Write the new value.
- mov dx, 066ech ;GEN_TEST_CTRL reg.
- call InpwDelay ;Read the current value.
- push ax ;Save gen_test_ctrl.
- and ah, not 001h ;Reset GUI engine.
- call OutpwDelay ;Write the new value.
- pop ax ;Restore gen_test_ctrl.
- call OutpwDelay ;Restore original value.
- mov dx, 01ceh ;ATI Extended regs index/* */
- mov ah, 0a0h ;ATI20 index value /* */
- mov al, ah ; /* */
- call OutpIdxInpData ;Get current DAC RS[3:2]/* */
- push ax ;Save ATI20 data /* */
- and al, not 060h ;Clear DAC RS[3:2] /* */
- xchg ah, al ;Restore index,save data/* */
- call OutpwDelay ; /* */
- mov dx, 05eefh ;DAC_R_INDEX reg.
- mov al, 0a4h ;
- call OutpDelay ;Write the new value.
- xor cx, cx ;
- .repeat ;Wait fixed amount of time.
- .loop ;
- mov dx, 05eech ;DAC_W_INDEX reg
- call InpDelay ;Input from port.
- .if <al e 0a5h> ;Always one more!
- mov dx, 042ech ;SCRATCH_REG0 reg addr.
- call InpwDelay ;Read the value.
- push ax ;
- not ax ;Change all the bits.
- call OutpwChk ;See if it changes.
- pop ax ;
- call OutpwDelay ;Restore original value.
- .endif ;Else failure.
- mov dx, 01ceh ;ATI Extended regs index/* */
- pop ax ;Restore ATI20 data /* */
- call OutpwDelay ;Restore original value./* */
- pop ax ;Restore gen_test_ctrl.
- mov dx, 066eeh ;GEN_TEST_CTRL reg.
- call OutpwDelay ;Restore original value.
- pop ax ;Restore Crtc ctrl.
- mov dx, 01eeeh ;CRTC_GEN_CTRL addr.
- call OutpwDelay ;Restore original value.
- ret
-
- ATIMach64 ENDP
-
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = IsATI
- ;*
- ;* DESCRIPTION = Look for an ATI Wonder.
- ;*
- ;* Check for product signature string at C000:30
- ;* which should read '761295520'
- ;*
- ;* Assume DS -> DGROUP on entry
- ;*
- ;* INPUT = NONE
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = NONE
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- IsATI PROC Near
- PUBLIC IsATI
-
- push di
- mov bx, 00030h ;Search target offset.
- mov cx, 10 ;Search string length.
- mov di, OFFSET DGROUP :ATISig ;Search string value.
- ;@V3.0JLO01 call FindString ;See if string is there in ROM.
- call LookString ;See if string is there in ROM.
- pop di
- ret
-
- IsATI ENDP
-
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = IsCirrus
- ;*
- ;* DESCRIPTION = Graphics Cursor X position register (3c5, index 10,30,50...F0)
- ;* uses both index and data for position value. Bits 7-5 of
- ;* the index are bits 0-2 of the cursor position. Data value
- ;* represents bits 3-10 of the cursor position.
- ;* If 3c4 loaded with a value and then read without
- ;* writing data to 3c5, it returns 3 bits of the
- ;* previously set cursor position.
- ;*
- ;* INPUT = NONE
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = ZR if found.
- ;* RETURN-ERROR = NZ if not found.
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
- ;
-
- IsCirrus PROC Near
- PUBLIC IsCirrus
-
- enter STACKBLOCK, 0 ;
- mov dx, 03c4h ;SEQ index address (3c4)/* */
- call GetSave1 ;Read original index & save it.
- mov ax, 01206h ; sr6 register index and unlock.
- ; Current SEQ06 value now saved globally! /* */
- ; But at least TRY to restore it as soon as possible! /* */
- mov [SaveReg2], dx ; /* */
- mov [SaveIndex2], al ; /* */
- ; /* */
- ; Cannot call OutpIdxChkXchgData here /* */
- ; since GD5401 has no SEQ SR6! /* */
- ; /* */
- call OutpIdxXchgData ;Try setting SEQ SR6. /* */
- mov [SaveValue2], al ;Save old value. /* */
- mov al, 010h ;SEQ SR10 index.
- call OutpInp ;Write new & read modified values.
- ; ;Read value is first 3 bits, shifted by 5
- cmp al, 010h ;Test for read/writable /* */
- jb IsCirrusExit ;Exit if not. /* */
- test al, 00fh ;Test for read/writable /* */
- jnz IsCirrusExit ;Exit if not. /* */
- mov [SaveIndex3], al ;Read/writable index? /* */
- ; mov ah, 000h ;Any data at all! /* */
- call OutpIdxChkXchgData ;Test for read/writable /* */
- ;Read value is bits 3-10 of the current position
- mov [SaveValue3], al ; /* */
- .if < z > ;If read/write: /* */
- mov ax, 02850h ;Set cursor to position 322. This value chosen in
- mov bl, al ;Save index. /* */
- ; /* */
- ; Cannot call OutpIdxChkXchgData here /* */
- ; since index register has extra "data" bits. /* */
- ; /* */
- call OutpIdxXchgData ;No index check! /* */
- mov bh, al ;Save data. /* */
- mov al, 070h ; write the index only
- call OutpInp ;Write new & read modified values.
- ; ;Read value should be 50h
- cmp al, bl ; if 0 it is Cirrus, else not
- mov ax, bx ;Restore index & data /* */
- call OutpwDelay ;Restore the old value. /* */
- .endif ;Else not read/write /* */
- mov ax, word ptr [SaveIndex3]
- call OutpwDelay ;Restore the old value.
- IsCirrusExit:
- call RestoreSave2 ;Restore original values/* */
- leave ;
- ret
-
- IsCirrus ENDP
-
- ;/***************************************************************** ;
- ;*
- ;* FUNCTION NAME = IsS3
- ;*
- ;* DESCRIPTION =
- ;*
- ;* INPUT = NONE
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = ZR if found.
- ;* RETURN-ERROR = NZ if not found.
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- IsS3 PROC Near ; /* */
- PUBLIC IsS3
-
- enter STACKBLOCK, 0 ; /* */
- ;* /* */
- ;* Weitek VGA used to pass the following test!
- ;* so it was clearly not specific enough!
- ;*
- mov ax, 04838h ;Unlock extensions.
- call GetCrtcBaseSave2 ;(3d4) /* */
- ;* OUTPUT = DX = 003x4 (CRTC index address)
- ;* /* */
- ;* Cannot check return since /* */
- ;* not all the S3 bits are writable! /* */
- ;* /* */
- ;* .if <z> AND ;Exit if not R/W! /* */
- ;* /* */
- mov al, 0cch ; /* */
- inc dx ;Point to data register /* */
- call SaveXORChk ; /* */
- .if <z> AND ;Exit if not R/W!
- dec dx ;Point back to index reg/* */
- ;* /* */
- ;* We must eliminate this possibility
- ;* to reject the Weitek VGA!
- ;*
- call IsNoCrtcWrap ;(3d4) /* */
- .if <z> AND ;Exit if wraps! /* */
- ;*
- mov al, 030h ;Chip-ID/Rev index /* */
- call OutpDelay ; /* */
- inc dx ;Point to data register /* */
- mov al, 0ffh ; /* */
- call SaveXORConst ;Must be read only! /* */
- .if <z> AND ;Exit if R/W! /* */
- dec dx ;Point back to index reg/* */
- mov al, 030h ;
- call OutpIdxInpData ;Read indexed reg /* */
- and al, 0f0h ;mask out lower nibble /* */
- .if <al be 0d0h> ;Vision964 /*@V3.0YEE01*/
- ; cmp al, 0a0h ;801/805 family
- ; je S3Exit
- ; cmp al, 080h ;80 is 911/924 /* */
- ; je S3Exit
- ; cmp al, 090h ;928 family
- ; je S3Exit
- ; cmp al, 0b0h ;928 PCI /* */
- cmp al, al ;Always success here! /* */
- .endif /*@V2.1MNH13*/
- S3Exit: ; /* */
- call RestoreSave2 ;Restore original values
- leave ; /* */
- ret
-
- IsS3 ENDP
-
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = IsSpeedWay
- ;*
- ;* DESCRIPTION = Look for IBM 'SVGA'
- ;*
- ;* INPUT = NONE
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = NONE
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- IsSpeedWay PROC Near
- PUBLIC IsSpeedWay
-
- mov dx, 02170h ;Start from 8th instance OpMode Reg.
- .repeat
- call InpDelay ;Read the OpMode setting.
- test al, 0eah ;Any of these bits on?
- .if < z > AND ;Valid value?
- mov al, 0ffh ;Test all of the bits.
- call IsNotISAAliased
- .if < z > AND ;If not aliased
- ;
- ; This should be INSIDE the loop & not AFTER! /* */
- ; If both XGA and Speedway
- ; (a real but maybe dumb possibility),
- ; then keep looking until we find the speedway address!
- ;
- mov al, 0eah
- call SaveXORConst
- .if < z > AND ;If no changes:
- mov al, 00fh
- or dl, 008h ;VRAM Index
- call SaveXORChk
- .if < z > AND ;If reads match writes:
- mov al, 0f4h
- or dl, 009h ;Setup Memory Access /* */
- call SaveXORConst
- .if < z > ;Exit with success!
- and dx, not 0000fh
- mov [_XGAInstance], dx ;Remember XGA instance /* */
- cmp al, al ;Return success
- jmp short @F
- .endif
- SWayNextPort:
- sub dx, 00010h ;Next configuration
- .until <dx b 02100h> ;Still more ports to check
- @@:
- ret
-
- IsSpeedWay ENDP
-
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = _GetXGAInstance
- ;*
- ;* DESCRIPTION = Get XGAInstance value
- ;*
- ;* INPUT = NONE
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = NONE
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- _GetXGAInstance PROC Far ; /* */
- PUBLIC _GetXGAInstance ; /* */
-
- call IsSpeedWay
- ret
-
- _GetXGAInstance ENDP ; /* */
-
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = IsTrident
- ;*
- ;* DESCRIPTION = Look for Trident chip set
- ;* check for presence of inverting bit field in
- ;* Mode Control register 1
- ;*
- ;* INPUT = NONE
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = NONE
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- IsTrident PROC Near
- PUBLIC IsTrident
-
- enter STACKBLOCK, 0 ;
- mov dx, 03c4h ;SEQ index address (3c4)/* */
- call GetSave1 ;Read value & save it. /* */
- call OutpChk
- mov ax, 0000eh ;Write all zeroes /* */
- ; /* */
- ; Need to check for index wrap so we do not clobber /* */
- ; TSeng Tsequencer 0x0e&0x07==0x06! (Tsix!) /* */
- ; Which we may not be able to restore TsucceTsTsfully! /* */
- ; /* */
- call OutpChk ;Check index for wrap /* */
- .if <z> ;If R/W: Else Tskip! /* */
- ; /* */
- ; Cannot call OutpIdxChkXchgData here /* */
- ; since read value changes! /* */
- ; /* */
- call OutpIdxXchgData ;Read indexed reg /* */
- mov ah, al ;Save old value /* */
- call InpData ;Read value 2nd time!
- and al, 00fh ;
- xchg al, ah ;get old value back
- xor al, 002h ;flip bit
- call OutpData ;Write the new value, restore.
- cmp ah, 002h ;ZR => Trident, NZ => not
- .endif ; /* */
- call RestoreSave1 ;Restore the original index.
- leave ;
- ret
-
- IsTrident ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = TsengSetATCMisc
- ;*
- ;* DESCRIPTION = Point to Tseng ATC Misc and set the value.
- ;*
- ;* INPUT = CX = 3x0 CrtcBase
- ;* = AL = New Tseng ATC Misc Reg value
- ;* OUTPUT = DX = 3c0 = ATC Index address
- ;* CLOBBERS = AX
- ;*
- ;* RETURN-NORMAL = ZR (reads match writes).
- ;* RETURN-ERROR = NZ (reads do not match writes).
- ;*
- ;* CALLED BY
- ;* IsTseng
- ;*
- ;****************************************************************************/
-
- TsengSetATCMisc PROC Near
- PUBLIC TsengSetATCMisc
-
- mov ah, al ;Save new ATC Misc value.
- mov al, 016h ;Tseng ATC Misc index.
- call ATCOutpIdx ;Set index & test for read/writeable.
- .if < z > ;If NO errors setting index:
- mov al, ah ;Restore new ATC Misc value.
- call OutpIdxInpData ;Write new ATC Misc value & reread it.
- cmp al, ah
- .endif
- ret
-
- TsengSetATCMisc ENDP
-
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = TsengEnableExt
- ;*
- ;* DESCRIPTION =
- ;*
- ;* INPUT = BP = Stack Frame Pointer
- ;* OUTPUT = DX = 03c4 = SEQ index address
- ;*
- ;* RETURN-NORMAL = NONE
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- TsengEnableExt PROC Near
- PUBLIC TsengEnableExt
-
- call GetPortBase ;Depends on mono/color /* */
- add dl, 008h ;Mode Ctrl (3b8/3d8) /* */
- call GetSave2 ;
- ;;JWK07 mov ax, 02901h ;Unlock values.
- mov ax, 0a003h ;JWK07 ;Correct Unlock values.
- ; Now fall thru to (call and return):
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = TsengLock
- ;*
- ;* DESCRIPTION = Lock or Unlock Tseng extended registers.
- ;*
- ;* INPUT = AX = Lock 0a003h or Unlock 02901h
- ;* DX = Mode Ctrl (3b8/3d8)
- ;*
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = NONE
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- TsengLock PROC Near
- PUBLIC TsengLock
-
- push dx
- mov dl, 0bfh ;Lock/Unlock extended regs
- call OutpDelay ;Write the new value.
- pop dx
- mov al, ah ;
- call OutpDelay ;Write the new value.
- ret
-
- TsengLock ENDP
-
- TsengEnableExt ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = TsengDisableExt
- ;*
- ;* DESCRIPTION =
- ;*
- ;* INPUT = BP = Stack Frame Pointer
- ;* OUTPUT = DX = 03c4 = SEQ index address
- ;*
- ;* RETURN-NORMAL = NONE
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- TsengDisableExt PROC Near
- PUBLIC TsengDisableExt
-
- mov dx, [SaveReg2] ;Mode Ctrl (3b8/3d8) /* */
- push ax
- mov al, [SaveValue2] ;
- mov ah, al ;
- and al, 040h ;
- rol al, 3 ;
- or al, 001h ;
- call TsengLock ;Restore lock state /* */
- pop ax
- ret
-
- TsengDisableExt ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = IsTseng
- ;*
- ;* DESCRIPTION = Look for Tseng chip
- ;*
- ;* Use:
- ;*
- ;* read old reg value
- ;* write a new value
- ;* read the new value
- ;* write old value back
- ;* if new value written equals value read, chip is Tseng
- ;*
- ;* INPUT = NONE
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = NONE
- ;* RETURN-ERROR = NONE
- ;*
- ;* USES: AX, BX, DX
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- IsTseng PROC Near
- PUBLIC IsTseng
-
- enter STACKBLOCK, 0 ; /* */
- mov dx, 003cdh ;Tseng Tsegment Tselect /* */
- mov al, 0ffh ;Test all bits for R/W /* */
- call SaveXORChk ; /* */
- .if <z> ;If R/W /* */
- call GetCrtcBaseSave1 ;(3d4) /* */
- ;* OUTPUT = DX = 003x4 (CRTC index address)
- ;* /* */
- ;* We must eliminate this possibility to reject the Weitek VGA!
- ;*
- call IsNoCrtcWrap ;(3d4) /* */
- ;* OUTPUT = DX = 003x4 (CRTC index address)
- .if < z > ;If no wrap: /* */
- mov al, 033h ;Point to extended start/* */
- call OutpChk ;Extra sanity check for L40
- ; which ignores index set,
- .if < z > ; so check it worked: /* */
- inc dl ;
- mov al, 00fh ; /* */
- call SaveXORChk ;Test for read/writable./* */
- .if < z > ;If read/write: /* */
- ;* /* */
- ;* We must eliminate this possibility to reject the WD90C24!
- ;*
- mov dl, 0cdh ;GDC Segment Select 1 /* */
- mov al, 0ffh ;Test all bits /* */
- call SaveXORChk ;Test for read/writable./* */
- .endif
- .endif
- .endif
- .if < nz > ;If NOT ET4000+: /* */
- IsTsengExit: ;could be ET3000
- ;!! Trident TR8900 passes ET3000 test! /* */
- ;!! Can we TStrENGthen it somehow?
- mov al, 016h ;Tseng ATC Misc index.
- call ATCOutpIdx ;Set index & test for read/writeable.
- inc dx
- call InpDelay ;Read the value.
- mov bl, al ;Save original value in bl
- xor al, 10h ;Toggle bit /* */
- call TsengSetATCMisc ;Write new ATC Misc val /* */
- .if < z > ;If read/writeable: /* */
- mov al, bl ;Get original value
- call TsengSetATCMisc ;Restore ATC Misc /* */
- .endif
- .endif
- MustBeTseng:
- pushf ;Save flags
- mov al, 20h ;Turn palette back on
- call ATCOutpIdx ;Set ATC index reg /* */
- popf ;restore flags
- call RestoreSave1 ;Restore the original index.
- .endif ; /* */
- leave ; /* */
- ret ;
-
- IsTseng ENDP
-
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = Video7EnableExt
- ;*
- ;* DESCRIPTION =
- ;*
- ;* INPUT = BP = Stack Frame Pointer
- ;* OUTPUT = DX = 03c4 = SEQ index address
- ;*
- ;* RETURN-NORMAL = ZR (reads do not match writes).
- ;* RETURN-ERROR = NZ (reads match writes).
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- Video7EnableExt PROC Near
- PUBLIC Video7EnableExt
-
- mov dx, 03c4h ;SEQ index address (3c4)/* */
- call GetSave2 ;
- mov ax, 0ea06h ;write 0eah to reg 6 /* */
- ; Don't check index, since we want failure for output chk!/* */
- call OutpIdxChkXchgData ;Read indexed reg /* */
- ; Current SEQ06 value now saved globally! /* */
- ; But at least TRY to restore it as soon as possible! /* */
- ; mov [SaveValue2], al ;In case NOT Video7! /* */
- lahf ;Did reads match writes?/* */
- test ah,040h ;NZ=>Z, Z=>NZ /* */
- ret
-
- Video7EnableExt ENDP
-
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = Video7DisableExt
- ;*
- ;* DESCRIPTION =
- ;*
- ;* INPUT = BP = Stack Frame Pointer
- ;* FL = ZR = Video7, NZ = not Video7
- ;* OUTPUT = DX = 03c4 = SEQ index address
- ;*
- ;* RETURN-NORMAL = NONE
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- Video7DisableExt PROC Near
- PUBLIC Video7DisableExt
-
- mov dx, 03c4h ;SEQ index address (3c4)/* */
- ;We do not want to lock it now, we want to restore the lock state!
- ; mov ax, 0ae06h ;write 0aeh to reg 6 /* */
- ; call OutpwDelay ;Write the new value. /* */
- ; mov dx, [SaveReg2] ; /* */
- ; Current SEQ06 value now saved globally! /* */
- ; But at least TRY to restore it as soon as possible! /* */
- mov al, 006h ; /* */
- mov ah, [SEQ06] ;Use global lock restore/* */
- call OutpwDelay ;Restore original lock /* */
- mov al, [SaveIndex2] ;
- call OutpDelay ;Restore the index.
- ret
-
- Video7DisableExt ENDP
-
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = IsVideo7
- ;*
- ;* DESCRIPTION = Look for Headland chip (Video7)
- ;*
- ;* read value of Start Address High (SAH) register
- ;* read Identification register (ID field)
- ;* if (SAH ^ 0EAH == ID reg) its a Video7 chip
- ;*
- ;* INPUT = NONE
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = NONE
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- IsVideo7 PROC Near
- PUBLIC IsVideo7
-
- enter STACKBLOCK, 0 ;
- call Video7EnableExt ;enable extended registers
- jnz IsVideo7Exit ;Exit if read/write /* */
- call GetCrtcBaseSave1 ;(3d4) /* */
- ;* OUTPUT = DX = 003x4 (CRTC index address)
- ; mov bx, dx ;save copy /* */
- xor bh, bh ;Default value /* */
- mov ax, 0550ch ;select Start Address High reg
- call OutpIdxChkXchgData ;Read indexed reg /* */
- mov bl, al ;Save previous value
- .if < z > ;If read/write: /* */
- ; call InpDelay ;Read the value back. /* */
- mov al, 01fh ;select ID register
- call OutpIdxInpData ;Read indexed reg /* */
-
- mov bh, al ; /* */
- .endif ;Else not read/write /* */
- mov al, 00ch ;select SAH register
- mov ah, bl ;Get back old value /* */
- call OutpwDelay ;Write old value back
- cmp bh, 055h xor 0eah ;ZR => Video7, NZ => not/* */
- call RestoreSave1 ;Restore the original index.
- IsVideo7Exit: ; /* */
- call Video7DisableExt ;disable extended regs
- leave ;
- ret
-
- IsVideo7 ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = WDDisableExt
- ;*
- ;* DESCRIPTION = Relock WD private registers.
- ;* Maintain Z/NZ
- ;*
- ;* INPUT = BP = Stack frame pointer.
- ;* DX = 3x4 port base address.
- ;*
- ;* RETURN-NORMAL = NONE
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;* IsWesternDig
- ;* WhichWesternDig
- ;*
- ;****************************************************************************/
-
- WDDisableExt PROC near
- PUBLIC WDDisableExt
-
- pushf ;Save results flags. /* */
- call GetCrtcBase ;(3d4) /* */
- ;* OUTPUT = DX = 003x4 (CRTC index address)
- call IsNoCrtcWrap ;(3d4) /* */
- ;* OUTPUT = DX = 003x4 (CRTC index address)
- .if < z > ;If no wrap: /* */
- mov al, 035h ;PR30/Mapping RAM Unlock/* */
- mov ah, [SaveValue3] ; /* */
- call OutpwDelay ;Restore lock/unlock /* */
- mov al, 034h ;PR1B/Flat Panel Unlock /* */
- mov ah, [SaveIndex3] ; /* */
- call OutpwDelay ;Restore lock/unlock /* */
- .endif /*@V2.1MNH01*/
- popf ;Restore results flags /* */
- call RestoreSave2
- mov al, 000h ;Lock extensions /* */
- ; Now fall thru to (call and return):
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = WDLock
- ;*
- ;* DESCRIPTION = Lock/Unlock WD private registers.
- ;*
- ;* INPUT = AL = Lock (000h)/Unlock(080h) bit.
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = NONE
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- WDLock PROC Near
- PUBLIC WDLock
- ;
- ; Which adapter needs this lock/unlock? /* */
- ; And does this code really work? /* */
- ; Shouldn't this be 001h->0102h instead of 080h->0103h? /* */
- ;
- ; This routine must be removed since the WD90C24A2B /* */
- ; & WD90C24A2C have a which causes all output to /* */
- ; 003c3 to put the chip to sleep. /* */
- ;
- ; Since historically this routine has output to the /* */
- ; address and the bit, it is effectively a nop /* */
- ; anyway. So it should not be missed. /* */
- ;
- ; mov ah, al ;Save lock/unlock bit
- ; mov dx, 003c3h ;Same as 046e8h!
- ; push dx ;
- ; call InpDelay ;
- ; push ax ;Save Subsys Enable
- ; or al, 010h ;Add Setup bit
- ; call OutpDelay ;Write new value, enter setup mode.
- ; mov dx, 00103h ;!!What is this addr?! (102?)
- ; call InpDelay ;
- ; pushf ;Save results flags.
- ; or al, ah ;Add in lock/unlock bit
- ; popf ;Restore results flags
- ; call OutpDelay ;Write new value, unlock extensions.
- ; pop ax ;Restore Subsys Enable
- ; pop dx ;(003c3h)
- ; call OutpDelay ;Write new value, exit setup mode.
- ret
-
- WDLock ENDP
-
- WDDisableExt ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = WDEnableExt
- ;*
- ;* DESCRIPTION = Unlock WD private registers.
- ;*
- ;* INPUT = BP = Stack frame pointer.
- ;* OUTPUT = DX = 003x4 (CRTC index address)
- ;*
- ;* RETURN-NORMAL = NONE
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- WDEnableExt PROC near
- PUBLIC WDEnableExt
-
- ;!! mov al, 080h ;Unlock extensions /* */
- ;!! call WDLock ;Is this the right bit? /* */
- mov ax, 08529h ;Set PR10, RW enable PR11-PR1A /* */
- call GetCrtcBaseSave2 ;(3d4) /* */
- ;* OUTPUT = DX = 003x4 (CRTC index address)
- ;* ;Write the new value, RW enable PR11-PR1A.
- ; /* */
- ; Cannot check the following because PVGA1A only has /* */
- ; PR0-PR5, and the 029h index is not read/writable! /* */
- ; /* */
- ; jnz WDEnableExtExit ;Exit if not read/write./* */
- ; /* */
- ;* /* */
- ;* We must eliminate this possibility to reject the Weitek VGA!
- ;*
- call IsNoCrtcWrap ;(3d4) /* */
- jnz WDEnableExtExit ;Exit if wraps! /* */
- mov ax, 05934h ;Set PR1B/Flat Panel Unlock
- call OutpIdxChkXchgData ;Write new value, lock for read ID!
- mov [SaveIndex3],al ;Save for non-WDs! /* */
- mov ax, 04335h ;Set PR30/Mapping RAM Unlock
- call OutpIdxChkXchgData ;Write new value, lock for read ID!
- mov [SaveValue3],al ;Save for non-WDs! /* */
- cmp al, al ;WD's MAY not read! /* */
- WDEnableExtExit:
- ret
-
- WDEnableExt ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = WDRegPairString
- ;*
- ;* DESCRIPTION = Test for WD string presence at CRTC reg pair.
- ;*
- ;* INPUT = AL = index of first CRTC reg in pair.
- ;* = DX = 003x4 (CRTC index address)
- ;* OUTPUT = AL = First reg
- ;* AH = Second reg
- ;*
- ;* RETURN-NORMAL = (zr if WD string found)
- ;* RETURN-ERROR = (nz if WD string NOT found)
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- WDRegPairString PROC Near
- PUBLIC WDRegPairString
-
- mov ah, al ;Save register index.
- call OutpIdxInpData ;Read high byte of chip 90cxx
- xchg ah, al ;Save high byte, restore index.
- inc al ;Get next index.
- call OutpIdxInpData ;Read low byte of chip 90cxx
- cmp ax, 05744h ;"WD"
- ret
-
- WDRegPairString ENDP
-
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = IsWesternDig
- ;*
- ;* DESCRIPTION =
- ;* At index 30 thru 3f, the WD90cxx chips have an encoded device id.
- ;* Certain unlocks must be done to allow it to be read.
- ;* This is NOT documented in ALL of their data books.
- ;* It IS documented in the data book for the WD90C26.
- ;* It IS hinted at ("reserved") in other data books.
- ;*
- ;* 3333333333333333
- ;* 0123456789ABCDEF
- ;* PVGA1A ->################ #=0ffh or 000h
- ;* WD90c00 ->COPYRIGHT1989WDC
- ;* WD90c24 ->#WD90C24REVC0892 #=varies Toshiba T4700CT
- ;* WD90c24a2a->#WD90C24AREVA293 #=varies z=000h WD90C24 Demo Board
- ;* WD90c24a2b->#WD90C24AREVB293 #=varies z=000h IBM ThinkPad
- ;* WD90c24a2c->#WD90C24AREVC### #=varies WD program checks this!
- ;* WD90c26 ->#WD90C26REV#199# #=varies WD ref documents this!
- ;* WD90c31 ->#WD90C310200zzzz #=varies z=000h WD program checks this!
- ;* WD90c31A ->#WD90C31050zzzzz #=varies z=000h WD program checks this!
- ;* WD90c33 ->#WD90C33######## #=varies z=000h WD program checks this!
- ;* WD90c34 ->#WD90C34######## #=varies z=000h WD program checks this!
- ;* WD90cxx ->#WD90Cxx######## #=varies x=chip
- ;*
- ;* So for PVGA1A, Look for string 'VGA=' at BIOS location C000:007D
- ;* Physical address = C007D or E007D
- ;* For the other adapters, look for a 'WD' at either possible port pair.
- ;*
- ;* INPUT = NONE
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = ZR if found.
- ;* RETURN-ERROR = NZ if not found.
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- IsWesternDig PROC Near
- PUBLIC IsWesternDig
-
- enter STACKBLOCK, 0 ;
- call WDEnableExt ;Unlock needed registers.
- ;* OUTPUT = DX = 003x4 (CRTC index address)
- jnz ExitWD ;Exit if wraps! /* */
- mov al, 03dh ; /* */
- call WDRegPairString ;Test reg pair for "WD" /* */
- jz ExitWD ;Yes, it's a WD! /* */
- mov al, 031h ; /* */
- call WDRegPairString ;Test reg pair for "WD" /* */
- jz ExitWD ;Yes, it's a WD! /* */
- ;*
- ;* Now test for PVGA1A: ; /* */
- ;* WD test program suggests the following for all WD chips:
- ;* and 3cf.e, 0fd
- ;* and 3cf.c, not 040 to reset out of NON-VGA mode
- ;* lock 3cf.f=000
- ;* test 3cf.9 NOT writable==>next test
- ;* unlock 3cf.f=005
- ;* test 3cf.9 writable==>WD chip!
- ;* restore all regs
- ;*
- push di
- mov bx, 0007dh ;Search target offset.
- mov cx, 4 ;Search string length.
- mov di, OFFSET DGROUP :WDSig ;Search string value.
- call FindString ;See if string is there in ROM.
- pop di
- ExitWD:
- call WDDisableExt
- leave ;
- ret
-
- IsWesternDig ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = IsChips
- ;*
- ;* DESCRIPTION = Read value of XR00 register. If value is NOT 00 or FF,
- ;* then C&T SVGA exists.
- ;* Some non-C&T adapters may carry over the last value set
- ;* from a previous instruction when querying 3c6, so use
- ;* the cursor reg for test. s3 964 did this.
- ;*
- ;* INPUT = NONE
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = ZR if found.
- ;* RETURN-ERROR = NZ if not found.
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- IsChips PROC Near
- PUBLIC IsChips
-
- enter STACKBLOCK, 0
-
- mov ax, 0000fh ;Write 00 to cursor reg
- call GetCrtcBaseSave2 ;(3d4)
-
- mov dx, 03d6h ;XR extension index register (3d6)
- call GetSave1 ;Read original index & save it.
-
- mov al, 00h ;XR00
- call OutpIdxInpData ;Read indexed reg
-
- cmp al,00h ;
- je NotChips ;
- cmp al,0FFh
- je NotChips ;
- cmp al,al ;found one!!!
- jz @F
- NotChips:
- cmp al,01h ;set nz flag
- @@:
- call RestoreSave1 ;Restore the original values.
- call RestoreSave2 ;Restore the original values.
- leave
- ret
-
- IsChips ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = IsWeitek
- ;*
- ;* DESCRIPTION =
- ;* Setting the index at 3c4, or setting the 3c5.11 20 bit
- ;* (a second time) locks (reads as zero)
- ;* 3c5.11 when the 3c5.11 20 bit is already set.
- ;* Two outputs to 3c5.11 (of any value) when the hidden
- ;* 3c5.11 20 bit is set unlock 3c5.11.
- ;* Setting the 3c5.11 20 bit also locks (reads as zero)
- ;* 3c5.12. In spite of documentation, ALL bits in the
- ;* 3c5.12 register are writable when unlocked.
- ;*
- ;* INPUT = NONE
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = ZR if found.
- ;* RETURN-ERROR = NZ if not found.
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- IsWeitek PROC Near
- PUBLIC IsWeitek
-
- enter STACKBLOCK, 0
- mov dx, 03c4h ;SEQ index address (3c4)/* */
- call GetSave1 ;Read original index & save it.
- mov al, 011h ;SEQ misc index.
- call OutpIdxInpData ;Read POSSIBLY locked value.
- test al, 020h ;Test SEQ Misc CRLOCK.
- .if < z > ;Only W5x86 if zero!
- call OutpData ;Output twice to unlock.
- call OutpData ;
- call InpData ;Read UNlocked original value.
- mov ah, al ;Save value to restore.
- and al, not 020h ;Unlock Output register.
- call OutpData ;
- mov al, 010h ;SEQ W5x86 ID Register.
- call OutpIdxInpData ;
- and al, 0f0h ;Extract W5x86 ID bits.
- cmp al, 050h ;Only W5x86 if equal!
- mov al, 011h ;SEQ misc index.
- call OutpwDelay ;Restore original lock/unlock.
- .endif
- call RestoreSave1 ;Restore the original values.
- leave
- ret
-
- IsWeitek ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = WeitekP9000Chk
- ;*
- ;* DESCRIPTION = Check physical memory addresses for Weitek 9000
- ;*
- ;* ONLY 9000 PASSES THIS TEST, NOT 9100!
- ;*
- ;* INTERRUPT REG @ ADDR 00100008+xxx00000 (xxx=top 10 bits)
- ;* xxx usually C00,D00,E00,F00 in Weitek implementation
- ;* xxx usually 800,A00,200 for Diamond Viper
- ;* Bits 31-6 always zero.
- ;* Bit pairs 5-4,3-2,1-0 must set high bit to chg low.
- ;* Safe to change other bits momentarily in text modes
- ;* for testing existence.
- ;* Works strangely enough to be a reasonable test.
- ;* SYS CONFIG REG @ ADDR 00100004+xxx00000 (xxx=top 10 bits)
- ;* Bits 31-26,8-3 always zero.
- ;* Bits 2-0 are chip version
- ;* Safe to change other bits momentarily in text modes
- ;* for testing existence.
- ;* Decent redundancy check for first test.
- ;*
- ;* INPUT = DI == high word of address to check
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = ZR if found.
- ;* RETURN-ERROR = NZ if not found.
- ;*
- ;* CALLED BY
- ;* IsWeitek9x00
- ;*
- ;****************************************************************************/
-
- ifndef SVGAUTIL
-
- WeitekP9000Chk PROC Near ; /*@V3.0MNH04*/
- PUBLIC WeitekP9000Chk ; /*@V3.0MNH04*/
-
- xor bx, bx ;Low word of physical address.
- mov cx, WEITEK_P9000_REGLENGTH ;Length of area selected
- push es
- mov ax, di ;High word of physical address.
- call SVGAPhysToUVirt
- mov ax, 000h ;Convert nc to z, c to nz
- rcl ax, 001h ;
- .if < z > ;If selector returned:
- mov ax, word ptr es:[bx][WEITEK_P9000_SYSCONFIG][word]
- and ax, 0fe80h
- .if < z >
- mov ax, word ptr es:[bx][WEITEK_P9000_SYSCONFIG]
- and ax, 001f8h
- .if < z >
- mov ax, word ptr es:[bx][WEITEK_P9000_ENABLE][word]
- and ax, ax
- .if < z >
- mov ax, word ptr es:[bx][WEITEK_P9000_ENABLE]
- and ax, 0ffaah
- .if <ax e 000aah>
- mov ax, word ptr es:[bx][WEITEK_P9000_INTERRUPT][word]
- and ax, ax
- .if < z >
- cli
- mov ax, word ptr es:[bx][WEITEK_P9000_INTERRUPT]
- mov dx, ax ;Save a copy for restore.
- and ax, 0ffeah
- .if <ax e 0002ah>
- ;
- ; These XOR'd bits should be read only!
- ;
- xor word ptr es:[bx][WEITEK_P9000_INTERRUPT], 0ffffh
- .if <dx e es:[bx][WEITEK_P9000_INTERRUPT]> ;Same?
- mov ax, 00015h ;Only these bits should change!
- xor word ptr es:[bx][WEITEK_P9000_INTERRUPT], ax
- xor ax, dx
- cmp ax, es:[bx][WEITEK_P9000_INTERRUPT] ;Same?
- .endif
- mov es:[bx][WEITEK_P9000_INTERRUPT], dx ;Restore non-WEITEK_P9000!
- .endif ;Else already nz for not found.
- .endif ;Else already nz for not found.
- .endif ;Else already nz for not found.
- .endif ;Else already nz for not found.
- .endif ;Else already nz for not found.
- .endif ;Else already nz for not found.
- sti
- call SVGAUnPhysToUVirt ;ES=selector to free.
- .endif ;Else already nz for not found.
- pop es
- ret
-
- WeitekP9000Chk ENDP ; /*@V3.0MNH04*/
-
- endif ;/* SVGAUTIL */
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = IsWeitekP9x00
- ;*
- ;* DESCRIPTION = Hunt thru physical memory addresses for Weitek
- ;* INTERRUPT REG @ ADDR 00100008+xxx00000 (xxx=top 10 bits)
- ;* xxx usually C00,D00,E00,F00 in Weitek implementation
- ;* xxx usually 800,A00,200 for Diamond Viper
- ;* Bits 31-6 always zero.
- ;* Bit pairs 5-4,3-2,1-0 must set high bit to chg low.
- ;* Safe to change other bits momentarily in text modes
- ;* for testing existence.
- ;* Works strangely enough to be a reasonable test.
- ;* SYS CONFIG REG @ ADDR 00100004+xxx00000 (xxx=top 10 bits)
- ;* Bits 31-26,8-3 always zero.
- ;* Bits 2-0 are chip version
- ;* Safe to change other bits momentarily in text modes
- ;* for testing existence.
- ;* Decent redundancy check for first test.
- ;*
- ;* For Diamond Viper, the P9x00 chip must first be
- ;* mapped into the address space.
- ;* Setting the index at 3c4, or setting the 3c5.11 20 bit
- ;* (a second time) locks (reads as zero)
- ;* 3c5.11 when the 3c5.11 20 bit is already set.
- ;* Two outputs to 3c5.11 (of any value) when the hidden
- ;* 3c5.11 20 bit is set unlock 3c5.11.
- ;* Setting the 3c5.11 20 bit also locks (reads as zero)
- ;* 3c5.12. In spite of documentation, ALL bits in the
- ;* 3c5.12 register are writable when unlocked.
- ;*
- ;* INPUT = NONE
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = ZR if found.
- ;* RETURN-ERROR = NZ if not found.
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- IsWeitekP9x00 PROC Near ; /*@V3.0MNH04*/
- PUBLIC IsWeitekP9x00 ; /*@V3.0MNH04*/
-
- enter STACKBLOCK, 0
- push di
- mov bx, 00037h ;Search target offset.
- mov cx, 5 ;Search string length.
- mov di, OFFSET DGROUP :DiamondViperSig ;Search string value.
- call FindString ;See if string is there in ROM.
- .if < z > ;If Diamond Viper.
- ;*
- ;* Diamond Viper does not map the P9x00 into memory
- ;* until you indicate where by outputting where to (locked)
- ;* SEQ register 012. One bit value means unmapped.
- ;* So we cannot just hunt thru memory for the P9x00!
- ;* This test works for both real DOS and OS/2.
- ;*
- mov dx, 03c4h ;SEQ index address (3c4)/* */
- call GetSave1 ;Read original index & save it.
- mov al, 011h ;SEQ misc index.
- call OutpIdxInpData ;Read POSSIBLY locked value.
- test al, 020h ;Test SEQ Misc CRLOCK.
- .if < z > ;Only Diamond Viper if zero!
- mov [SvgaOEMInfo.Manufacturer], DIAMOND_MANUFACTURER ; 1 ;
- call OutpData ;Output twice to unlock.
- call OutpData ;
- call InpData ;Read UNlocked original value.
- mov ah, al ;Save value to restore.
- and al, not 020h ;Unlock Output register.
- call OutpData ;
- mov al, 012h ;SEQ Output index.
- call OutpIdxInpData ;
- or al, 003h ;Set base address to 80000000.
- call OutpData ;So following test works!
- mov al, 011h ;SEQ misc index.
- call OutpwDelay ;Restore original lock/unlock.
- mov di, 08000h+WEITEK_P9000_REGISTERS ;Indicate base address.
- xor ax, ax ;Always successful here!
- .endif
- call RestoreSave1 ;Restore the original values.
- .endif ;Endif Diamond Viper.
- .if < nz > ;If NOT Diamond Viper.
- ;*
- ;* Since unextended real DOS cannot peek and poke the P9x00,
- ;* we need a reasonable facsimile.
- ;* Also since poking in memory can be dangerous,
- ;* it would be helpful to have some hints that we will find it,
- ;* before we go off and poke into a possible NMI handler.
- ;* Besides checking for the "WEITEK" string,
- ;* Another possibility would be to also check for a Weitek VGA!
- ;* Weitek VGA existence could also justify P9x00 memory search or
- ;* could also presumably "imply" P9x00 existence (for real DOS).
- ;* For WPOS, we might not have a BIOS, so we should just
- ;* do the hunt or require a Weitek VGA.
- ;*
- .if <[_sSVGA.AdapterType] ne WEITEK_ADAPTER>
- mov cx, 6 ;Search string length.
- mov di, OFFSET DGROUP:WeitekSig ;Search string value.
- call LookString ;See if string is anywhere in ROM.
- .endif
- ; ;Indicate presumed addr./*@V3.0MNH04*/
- mov di, 0c000h+WEITEK_P9000_REGISTERS ; /*@V3.0MNH04*/
- .endif ;Endif NOT Diamond Viper.
- .if < z > ;If we found a Weitek P9000:
- mov word ptr [SvgaBaseAddr][word], di ;Save addr. /*@V3.0MNH04*/
- .endif
- pop di
- leave
- ret
-
- IsWeitekP9x00 ENDP ; /*@V3.0MNH04*/
-
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = LastAttempt
- ;*
- ;* DESCRIPTION = This function attempts to detect chipsets of the
- ;* manufacturers which we don't successfuly identify
- ;* in "IsAdapter" functions. For example:
- ;* WD adapters are identified depending on the presence
- ;* of VGA= string in the BIOS. For many OEM implementations,
- ;* this test would fail. The code must not trash VGA registers.
- ;*
- ;* INPUT = NONE
- ;* OUTPUT = AX = usAdapterType
- ;* BX = ChipType
- ;*
- ;* RETURN-NORMAL = non zero AX
- ;* RETURN-ERROR = AX zero
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- LastAttempt PROC Near
- PUBLIC LastAttempt
-
- enter STACKBLOCK, 0 ;
- ; I doubt that the WD code is necessary any longer! /* */
- xor ax, ax ;No identifiable VGA. /* */
- leave ;
- ret
-
- LastAttempt ENDP
-
- ;*****************************************************************************
- ;
- ;
- ;
- ;*****************************************************************************
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = WhichATIUnaccelerated
- ;*
- ;* DESCRIPTION = Test ATI chip for Unaccelerated.
- ;*
- ;* INPUT = NONE
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = 1 - ATI18800-x chip
- ;* 2 - ATI28800-x chip
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;* WhichATI
- ;*
- ;****************************************************************************/
-
- WhichATIUnaccelerated PROC near ; /* */
- PUBLIC WhichATIUnaccelerated
-
- push ds ;
- mov ax, 0ch ; ROM Address high
- xor bx, bx ; ROM Address low
- mov cx, 100h ;
- call SVGAPhysToVirt ;
-
- ASSUME DS:NOTHING
-
- xor ah, ah ;
- mov al, ds:[si+43h] ; Chip version number
- sub al, '0' ;
- pop ds ;
-
- ASSUME DS:DGROUP
-
- call SVGAUnPhysToVirt ;
- mov dx, 01ceh ;ATI Extended regs index
- mov ah, al ;Save version number
- call InpDelay ;Get current index reg /* */
- or al, 080h ;This bit not readable /* */
- push ax ;Save index & version
- .if <ah be 2> ;Not Ver 3 or higher /* */
- mov al, 0bbh ; /* */
- call OutpIdxInpData ;Read indexed reg /* */
- mov cx, 4 ;assume 256k /* */
- test al, 20h ;
- .if < nz > ; /* */
- shl cx, 1 ; /* */
- .endif ; /* */
- .else /*@V2.1MNH13*/
- ATIV3:
- mov al, 0b0h ; /* */
- call OutpIdxInpData ;Read indexed reg /* */
- mov cx, 4 ;assume 256k /* */
- test al, 18h ;
- .if < nz > ; /* */
- shl cx, 1 ;make it 512k /* */
- test al, 10h ;
- .if < z > ; /* */
- shl cx, 1 ;make it 1M /* */
- .endif ; /* */
- .endif ; /* */
- .endif ; /* */
- ATIMEM: ; /* */
- mov word ptr [_sSVGA.Memory][1*word], cx ; /* */
- ; ; start
- pop ax ;Restore index & ver.
- call OutpDelay ;Restore original index /* */
- ;!! .if < ah b 5 > ;Was this in SVGAROUT but not SVGAID!
- .if < ah b 3 > ;Was this in SVGAID but not SVGAROUT!
- mov ax, ATI_18800_CHIP ;
- .else ;
- mov ax, ATI_28800_CHIP ;
- .endif ;
- ATIExit: ;
- ret
-
- WhichATIUnaccelerated ENDP
-
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = WhichATI
- ;*
- ;* DESCRIPTION = ATI Wonder boards V3, V4, V5 use ATI18800-x chips
- ;* V6, +, XL use ATI28800-x chips
- ;* ATI "Ultra" boards use Mach 8 == ATI38800-x chips
- ;* ATI "Graphics Ultra" uses Mach 32 == ATI68800-x chips
- ;*
- ;* INPUT = NONE
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = 1 - ATI18800-x chip
- ;* 2 - ATI28800-x chip
- ;* 3 - ATI38800-x chip /* */
- ;* 4 - ATI68800-x chip /* */
- ;* 5 - ATI88800-x chip /* */
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- WhichATI PROC Near ;
- PUBLIC WhichATI ;
-
- call ATI8514 ;Test for ATI 8514 /* */
- .if < z > ;If ATI 8154:
- mov ax,0aaaah AND 003ffh;Must limit to 11 bits!
- call ATIDestXOutpChk ;
- .if < z > ;If OK so far:
- mov ax,05555h AND 003ffh ;Must limit to 11 bits!
- call ATIDestXOutpChk ;
- .endif ;
- .if < z > ;If 68800 (Mach 32)
- mov dx, 036eeh ;Misc_Options /* */
- mov cl, 002h ;Get shift count /* */
- mov bx, ATI_68800_CHIP ; /* */
- .else ;Else 38800 (Mach 8)
- mov dx, 012eeh ;Config_Status_1 /* */
- mov cl, 005h ;Get shift count /* */
- mov bx, ATI_38800_CHIP ; /* */
- .endif ;
- call InpwDelay ; /* */
- shr al, cl ;Shift to low bits /* */
- and al, 003h ;Get memory size bits. /* */
- mov cl, al ;Use as shift count /* */
- mov ax, 00008h ;Start with 64K*8=512K /* */
- shl ax, cl ; /* */
- mov word ptr [_sSVGA.Memory][1*word], ax ; /* */
- mov ax, bx ;Set chiptype /* */
- .else ;If NOT ATI 8514:
- ; /* */
- ; Check for Mach64 AFTER Mach8/32: /* */
- ; ValuePoint AMBRA system has Mach32 which /* */
- ; responds to 0x02ec + ? * 0x0400 /* */
- ; when it should not. /* */
- ; Problem is that it hangs the system when you /* */
- ; write to such an address! /* */
- ; /* */
- ; Since it did not happen with all Mach32s /* */
- ; it is probably a hardware problem. /* */
- ; /* */
- ; Changing the Mach64 test itself would probably /* */
- ; not help get past this problem, since /* */
- ; we would still have to write to SOME port! /* */
- ; /* */
- ; Fortunately, we already know that the Mach64 /* */
- ; does not pass the test for a Mach32 or Mach8! /* */
- ; /* */
- call ATIMach64 ;Is it a Mach 64?
- .if < z > ;If ATI Mach 64:
- mov dx, 052ech ;MEM_CTRL reg addr.
- call InpwDelay ;Read the current value.
- and ax, 007h ;Get memory size bits.
- test al, 004h
- .if < nz > ;If below boundary:
- mov cl, al ;
- mov ax, 00008h ;Set for 64K*8=512K.
- shl ax, cl ;Shift to actual size.
- .else ;Else above boundary:
- dec ax ;Get count of 2M units.
- shl ax, 005h ;Shift to 64K units.
- .endif ;
- mov word ptr [_sSVGA.Memory][1*word], ax ;
- mov ax, ATI_88800_CHIP ;
- .else ;Else NOT ATI Mach 64:
- call WhichATIUnaccelerated ; /* */
- .endif ;
- .endif ;
- ret
- ; ; end
- WhichATI ENDP ;
-
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = WhichCirrus
- ;*
- ;* DESCRIPTION = Cirrus chips: GD5422, GD5424, GD5426, GD5428, etc.
- ;*
- ;* INPUT = NONE
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = 0 - any other Cirrus chip, not supported by SVGA
- ;* 1 - GD5420 chip
- ;* 2 - GD5422 chip
- ;* 3 - GD5424 chip
- ;* 4 - GD5426 chip
- ;* 5 - GD5428 chip
- ;* 6 - GD5429 chip
- ;* 7 - GD543X chip
- ;* 8 - GD5434 chip
- ;*
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
- ;
- WhichCirrus PROC Near
- PUBLIC WhichCirrus
-
- enter STACKBLOCK, 0 ;
- mov dx, 03c4h ;SEQ index address (3c4)/* */
- call GetSave1 ;Read original index & save it.
- mov ax, 01206h ; sr6 register index and unlock.
- mov [SaveReg2], dx ; /* */
- mov [SaveIndex2], al
- call OutpIdxChkXchgData ;Try setting SEQ SR6. /* */
- mov [SaveValue2], al ;Save old value. /* */
- mov ah, 0 ; set return to 0
- jne cirrus_exit ; Unable to unlock, assume GD5401
- call GetCrtcBase ;(3d4) /* */
- ;* OUTPUT = DX = 003x4 (CRTC index address)
- mov al, 27h ; Chip ID register index
- call OutpIdxInpData ;Read indexed reg /* */
- mov dx, 03c4h ;SEQ index address (3c4)/* */
- ; mov ah, 0 ; asuume one of the older ones
- ; cmp al, 8ah ; GD5420
- ; je cirrus_exit
- shr al, 1
- shr al, 1
- mov ah, CIRRUS_5420_CHIP ; 1
- cmp al, 022h ; GD5420
- je Mem2x ;
- mov ah, CIRRUS_5422_CHIP ;2 /* */
- cmp al, 23h ; GD5422
- je Mem2x ;
- mov ah, CIRRUS_5424_CHIP ;3 /* */
- cmp al, 25h ; GD5424
- je Mem2x ;
- mov ah, CIRRUS_5426_CHIP ;4 /* */
- cmp al, 24h ; GD5426
- je Mem2x ;
- mov ah, CIRRUS_5428_CHIP ;5 ; ; * */
- cmp al, 26h ; GD5428
- je Mem2x ;
- mov ah, CIRRUS_5429_CHIP ; 6
- cmp al, 027h ; GD5429
- je Mem2x ;
- mov ah, CIRRUS_5434_CHIP ; 8
- cmp al, 02Ah ; GD5434
- je Mem3x ;
- mov ah, CIRRUS_543X_CHIP ; 7
- cmp al, 028h ; GD5430
- je Mem3x ;
- cmp al, 029h ; GD5430-like
- je Mem3x ;
- mov ah, 0 ; none of the above
- jmp short cirrus_exit ; exit
- Mem2x: ;
- mov al, 0ah ; memory reg for 2x
- call OutpIdxInpData ; get memory value
- shr al, 03h ; shift bits 3,4 to end
- and al, 03h ; only look at bits 3,4
- jmp short GetCirrusMem ; get memory
- Mem3x: ;
- mov al, 015h ; memory reg for 3x
- call OutpIdxInpData ; get memory value
- and al, 00fh ; mask lower nibble
- GetCirrusMem: ;
- .if <al ne 002h> ;1 Meg ?
- mov dx, 010h ;Get default mem size=1M
- .if <al e 001h> ;512K ?
- shr dx, 1 ;adjust mem to 512k
- .endif ;
- .if <al e 003h> ;2 Meg ?
- shl dx, 1 ;adjust mem to 2 Meg
- .endif ;
- .if <al e 004h> ;4 Meg ?
- shl dx, 2 ;adjust mem to 4 Meg
- .endif ;
- mov word ptr [_sSVGA.Memory][1*word], dx ;save it
- .endif ;
- cirrus_exit:
- mov al, ah
- cbw
- call RestoreSave2 ;Restore the original values.
- leave ;
- ret
-
- WhichCirrus ENDP
-
- ;/***************************************************************** ;
- ;*
- ;* FUNCTION NAME = WhichS3
- ;*
- ;* DESCRIPTION = S3: xxxxxx, xxxxxx, xxxxxx
- ;*
- ;* INPUT = NONE
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = 0 - any other S3 chip, not supported by SVGA
- ;* 1 - xxxxxx chip
- ;* 2 - xxxxxx chip
- ;* 3 - xxxxxx chip
- ;*
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
- WhichS3 PROC Near ;
- PUBLIC WhichS3
-
- ;!!Need to adjust memory sizes!
- enter STACKBLOCK, 0 ;
- mov ax, 04838h ;Unlock extensions.
- call GetCrtcBaseSave2 ;(3d4) /* */
- ;* OUTPUT = DX = 003x4 (CRTC index address)
- ; mov ax, 0a039h ;unlock r39 /* */
- ; call OutpIdxXchgData ;Not needed for reads! /* */
- ; mov ah, al ; /* */
- ; push ax ;Save original lock /* */
- mov al, 030h ;Chip ID/Rev index /* */
- call OutpIdxInpData ;Read indexed reg /* */
- and al, 0f0h ;mask out lower nibble /* */
- mov cl, al ;Save chip id /* */
- mov al, 036h ;Configuration Reg 1 index
- call OutpIdxInpData ;Read indexed reg /* */
- and al, 0e0h
- .if <cl e 080h> ;If 911/924: /* */
- or al, 0c0h ;Insure high bits set /* */
- .endif ; /* */
- .if <al ne 0c0h> ;1 Meg ? /* */
- mov dx, 010h ;Get default mem size=1M/* */
- .if <al e 0e0h> ;512K ? /* */
- shr dx, 1 ;adjust mem to 512k
- .endif /*@V2.1MNH13*/
- .if <al e 080h> ;2 Meg ? /* */
- shl dx, 1 ;adjust mem to 2 Meg
- .endif /*@V2.1MNH13*/
- .if <al e 040h> ;3 Meg ? /* */
- mov bx, dx ;adjust mem to 3 Meg
- shl dx, 1
- or dx, bx
- .endif /*@V2.1MNH13*/
- .if <zero al> ;4 Meg ? /* */
- shl dx, 2 ;adjust mem to 4 Meg
- .endif /*@V2.1MNH13*/
- ; ;Save mem size: /* */
- mov word ptr [_sSVGA.Memory][1*word], dx ; /* */
- .endif /*@V2.1MNH13*/
- determine_S3:
- mov al, S3_86C805_CHIP ; /* */
- cmp cl, 0a0h ;801/805
- je S3_exit ; /* */
- mov al, S3_86C911_CHIP ; /* */
- cmp cl, 080h ;
- je S3_exit ; /* */
- mov al, S3_86C928_CHIP ; /* */
- cmp cl, 090h ;928
- je S3_exit ; /* */
- cmp cl, 0b0h ;928 PCI
- je S3_exit ; /* */
- mov al, S3_86C864_CHIP ; /* */
- cmp cl, 0c0h ;Vision 864
- je S3_exit ; /* */
- mov al, S3_86C964_CHIP ; /*@V3.0YEE01*/
- cmp cl, 0d0h ;Vision 964 @V3.0YEE01
- je S3_exit ; /*@V3.0YEE01*/
- xor al, al ; /* */
- S3_exit:
- cbw
- S3found:
- ; mov cx, ax ; /* */
- ; pop ax ;Restore original lock. /* */
- ; mov al, 039h ;Not needed for reads! /* */
- ; call OutpwDelay ;Write the new value. /* */
- call RestoreSave2 ;Restore original value.
- ; mov ax, cx ; /* */
- leave ;
- ret
-
- WhichS3 ENDP
-
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = WhichTrident
- ;*
- ;* DESCRIPTION =
- ;*
- ;* read Chip Version Register
- ;* value in AL >= 3 8900 chip version
- ;*
- ;* convert AL to: AL = 1 => 8800
- ;* AL = 2 => 8900
- ;*
- ;* Check memory on 8900 from 'Software Programming' register
- ;*
- ;* INPUT = NONE
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = NONE
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- WhichTrident PROC Near
- PUBLIC WhichTrident
-
- mov dx, 03c4h ;SEQ index address (3c4)/* */
- mov ax, 0bh ;write 0 to version reg (0bh)
- call OutpIdxInpData ;Read indexed reg /* */
- cmp al, 003h ; /* */
- mov ax, TRIDENT_8800_CHIP ;assume 8800 /* */
- jl short @F ; /* */
- call GetCrtcBase ;(3d4) /* */
- ;* OUTPUT = DX = 003x4 (CRTC index address)
- mov al, 01fh ;Set up to read 'software programming'
- ; reg w/two bits w/amount of video memory.
- call OutpIdxInpData ;Read indexed reg /* */
- and al, 003h ;Isolate # 256K blks - 1/* */
- inc al ;al = # 256K blks /* */
- shl al, 002h ;al = # 64K blks /* */
- mov byte ptr [_sSVGA.Memory][1*word], al ; /* */
- mov ax, TRIDENT_8900_CHIP ;make it 8900 /* */
- @@: ret
-
- WhichTrident ENDP
-
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = _IdentifyCPU
- ;*
- ;* DESCRIPTION = figure out what type of Intel 80x8x is in use
- ;*
- ;*
- ;*
- ;* ENTRY POINT: _IdentifyProcessorType
- ;* LINKAGE: Call Far
- ;*
- ;* INPUT:
- ;* DS = DGROUP
- ;*
- ;* EXIT-NORMAL: AX = processor type
- ;* EXIT-ERROR: NONE
- ;*
- ;* EFFECTS:
- ;* AX
- ;*
- ;* USES ROUTINES:
- ;*
- ;* CALLED BY ROUTINES:
- ;* INIT
- ;*
- ;* INPUT = NONE
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = ax = processor type
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
-
-
- ;JWK22
-
- ; The following procedure determines the type of processor present in the
- ; system it is running on. This procedure was documented by INTEL in an
- ; APPLICATION NOTE (AP-485) as the 'official' way to determine processor
- ; type. Additionally note that if processor is not made by Intel, or by a
- ; vendor licensed to used Intel's masks, the results may not be valid.
- ;
- ; Returns:
- ; 10h - 8088 processor \ the code to distinguish 8086 from 8088
- ; 11h - 8086 processor / is NOT from Intel
- ; 20h - Intel 286 processor
- ; 30h - Intel386(TM) processor
- ; 40h - Intel486(TM) processor
- ; 50h - Pentium(TM) processor
- ;
-
-
- NULPROC equ 0h
- PROCV20 equ 8h
- PROC808x equ 10h
- PROC8088 equ 10h
- PROC8086 equ 11h
- PROC8018x equ 18h
- PROC80188 equ 18h
- PROC80186 equ 19h
- PROC80286 equ 20h
- PROC80386 equ 30h
- PROC80386SX equ 38h
- PROC80386SLC equ 39h
- PROC80386SL equ 3ah
- PROC80486 equ 40h
- PROC80486DX equ 40h
- PROC80486DX2 equ 41h
- PROC80486DX3 equ 42h
- PROC80486SX equ 45h
- PROC80486SX2 equ 46h
- PROC80486SX3 equ 47h
- PROC80486SL equ 49h
- PROC80486SLC equ 4ah
- PROC80486SLC2 equ 4bh
- PROC80486SLC3 equ 4ch
- PROC80486BL2 equ 4dh
- PROC80486BL3 equ 4eh
- PROCPentium equ 50h
- PROCCYRIXDR2 equ 0c6h
-
- CPUID MACRO
- db 0fh ; opcode for CPUID instruction
- db 0a2h
- ENDM
-
- MPUSHFD MACRO
- db 066h ; opcode for pushfd instruction
- db 09ch
- ENDM
-
- MPOPFD MACRO
- db 066h ; opcode for popfd instruction
- db 09dh
- ENDM
-
- MPUSHEAX MACRO
- db 066h ; opcode for pusheax instruction
- db 050h
- ENDM
-
- MPOPEAX MACRO
- db 066h ; opcode for pusheax instruction
- db 058h
- ENDM
-
-
- FAMILY_MASK equ 0f00h
- FAMILY_SHIFT equ 8
- MODEL_MASK equ 0f0h
- MODEL_SHIFT equ 4
- STEPPING_MASK equ 0fh
-
-
- cpuid_step EQU <BYTE PTR [bp-06h]> ; byte
- cpuid_model EQU <BYTE PTR [bp-08h]> ; byte
- cpuid_type EQU <BYTE PTR [bp-0ah]> ; byte
- IDENTIFYCPUSTACKBLOCK EQU 0ah
-
-
-
-
- IdentifyCPU PROC ;JWK22
-
- enter IDENTIFYCPUSTACKBLOCK,0
- push ds
-
- push dx
- push cx
- push bx
-
-
-
- pushf ; save flags
- xor ax,ax ; clear AX
- push ax ; push it on the stack
- popf ; zero the flags
- pushf ; try to zero flag bits 12-15
- pop ax ; recover flags
- and ax,0f000h ; if flag bits 12-15 are 1
- cmp ax,0f000h ; then processor is
- jz is_0_1 ; 8018x or 808x
- mov ax,07000h ; try to set flag bits 12-14
- push ax
- popf
- pushf
- pop ax
- mov dx,PROC80386 ; load 386 value
- and ax,07000h ; if 12-14 are 0
- jz is_80286 ; processor is 80286
-
- ; allow 386 instructions
- .386
-
- ;;pushfd ; save all flags
- MPUSHFD
-
- mov ax,0000fh ; turn all upper bits on
- push ax ; of EFLAGS.
- xor ax,ax ; turn off all lower bits of EFLAGS.
- push ax ; put flags on stack
-
- ;;popfd ; pop back into flags
- MPOPFD
-
- ;;pushfd ; push flags back to stack
- MPUSHFD
-
- pop ax ; throw away lower part
- pop ax ; we can see results in AX
- cmp ax,0 ; if AX == 0 then we have a 386
- jz SHORT finishpop ; otherwise we have a 486 or higher
-
- mov dx,PROC80486 ; store a 486 value
-
- ;;pushfd ; push original EFLAGS
- MPUSHFD
-
- ;;pop eax ; get original EFLAGS in EAX
- MPOPEAX
-
- mov ecx,eax ; save original EFLAGS in ECX
- xor eax,200000h ; flip ID bit in EFLAGS
-
- ;;push eax ; save for EFLAGS
- MPUSHEAX
-
- ;;popfd ; copy to EFLAGS
- MPOPFD
-
- ;;pushfd ; push EFLAGS
- MPUSHFD
-
- ;;pop eax ; get new EFLAGS value
- MPOPEAX
-
- xor eax,ecx
- jz SHORT finishpop ; if ID bit cannot be changed,
- ; CPU = Intel486 without CPUID
- ; instruction functionality
- ;
- ; Otherwise, execute CPUID instruction to determine family.
- ;
- cpuid_data:
- mov eax,1
- CPUID
- mov cpuid_step,al ; isolate stepping info
- and cpuid_step,STEPPING_MASK
-
- and al,MODEL_MASK ; isolate model info
- shr al,MODEL_SHIFT
- mov cpuid_model,al
-
- and ax,FAMILY_MASK ; mask everything but family
- shr ax,FAMILY_SHIFT
- mov cpuid_type,al
- mov cx,16 ; move 16 to CX
- mul cx ; multiply AX by 16
- mov dx,ax ; set cpu_type with family
-
- finishpop:
- mov ax, dx ; get return value
-
- ;;popfd ; restore extended flags
- MPOPFD
-
-
- ; restore processor instructions allowed
-
- ifdef SVGAUTIL
- .286
- else ;/* SVGAUTIL */
- .386p
- endif ;/* SVGAUTIL */
-
-
- mov dx,ax ;
- jmp short IdentifyCPUdone
-
- is_80286:
- mov dx,PROC80286 ; point to processor id string
- jmp short IdentifyCPUdone
-
- is_0_1:
- push cx ; save CX for test of shift
- mov ax,0ffffh ; set all AX bits
- mov cl,33 ; will shift only once on 80186
- shl ax,cl ; or 33 times on 8086
- pop cx ; restore CX
- jnz is_80186 ; non-zero means 80186
-
- is_8086:
- ; Is it an 8086?
- ; Returns ax == 0 for 8088, ax == 1 for 8086
- ; Code takes advantage of the 8088's 4-byte prefetch queues and 8086's
- ; 6-byte prefetch queues. By self-modifying the code at location exactly
- ; 5 bytes away from IP, and determining if the modification took effect,
- ; you can differentiate between 8088s and 8086s.
- ; Note this code was taken from Dr. Dobb's Journal, June 1993.
- mov ax,cs ; ES == code segment
- mov es,ax
-
- std ; cause stosb to count backwards
-
- mov dx,1 ; DX is flag and we'll start at 1
- mov di,OFFSET IdentifyCPUEndLabel ; DI == offset of code tail to modify
- mov al,090h ; AL == nop instruction opcode
- mov cx,3 ; set for 3 repetitions
- REP stosb ; store the bytes
-
- cld ; clear the direction flag
- nop ; three nops in a row
- nop ; provide dummy instructions
- nop
- dec dx ; decrement flag (only with 8088)
- nop ; dummy instruction--6 bytes
- IdentifyCPUEndLabel:
- nop
-
- mov ax,dx ; get value in AX
- mov dx,PROC8088 ; indicate 8088
- cmp ax,0 ; if AX == 0 then we have a 8088
- jz is_8086_done ; otherwise we have a 8086
- mov dx,PROC8086 ; indicate 8086
-
- is_8086_done:
- jmp short IdentifyCPUdone
-
- is_80186:
- mov dx,PROC8018x
-
- IdentifyCPUdone:
- popf ; restore original flags
- mov ax,dx ; put processor type into AX
- pop bx
- pop cx
- pop dx
- pop ds
- leave
- ret
-
- IdentifyCPU ENDP ; JWK22
-
-
- _IdentifyCPU PROC far ;JWK22
- PUBLIC _IdentifyCPU
-
- call IdentifyCPU
- ret
-
- _IdentifyCPU ENDP ; JWK22
-
-
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = TsengGetVRAMSize /* */
- ;* ;;JWK07 replace entire routine to use
- ;* ;; iodelay, correct unlock, use write to flush cache
- ;* ;; needed for PCI and VLB
- ;* DESCRIPTION = Determine how much VRAM is installed by read/write of VRAM
- ;*
- ;* INPUT = AX = chiptype
- ;* DX = CRTC index (3c4 or 3b4)
- ;* OUTPUT = AX = number of VRAM 64k blocks
- ;* all other registers restored
- ;* RETURN-NORMAL = AX = number of VRAM 64k blocks
- ;* RETURN-ERROR = AX = 0
- ;*
- ;* CALLED BY WhichTseng
- ;*
- ;* ASSUMPTIONS 1) tseng already 'found'
- ;* 2) extended registers enabled
- ;*
- ;****************************************************************************/
-
- TTESTA equ 00000h
- TTESTB equ 0aaaah
- TTESTC equ 0f0f0h
- TTESTD equ 00707h
-
- WBINVD MACRO ; JWK22
- local skiplabel
- cmp Tcpu_id, PROC80486 ; invalid opcode if < 486
- jl short skiplabel
- db 0fh ; write back and invalidate cache command
- db 09h ;
- skiplabel:
- ENDM
-
- Tsave0 EQU <WORD PTR [bp-02h]> ; WORD
- Tsave1 EQU <WORD PTR [bp-04h]> ; WORD
- Tsave2 EQU <WORD PTR [bp-06h]> ; WORD
- Tsave3 EQU <WORD PTR [bp-08h]> ; WORD
- Ttest0 EQU <WORD PTR [bp-0ah]> ; WORD
- Ttest1 EQU <WORD PTR [bp-0ch]> ; WORD
- Ttest2 EQU <WORD PTR [bp-0eh]> ; WORD
- Ttest3 EQU <WORD PTR [bp-10h]> ; WORD
- Tpeek0 EQU <WORD PTR [bp-12h]> ; WORD
- Tpeek1 EQU <WORD PTR [bp-14h]> ; WORD
- Tpeek2 EQU <WORD PTR [bp-16h]> ; WORD
- Tpeek3 EQU <WORD PTR [bp-18h]> ; WORD
- Tchiptype EQU <WORD PTR [bp-1ah]> ; WORD
- TCRTCIndex EQU <WORD PTR [bp-1ch]> ; WORD
- Tseg EQU <WORD PTR [bp-1eh]> ; WORD
- Tseg_3cd EQU <WORD PTR [bp-20h]> ; WORD
- Tseg_3cb EQU <WORD PTR [bp-22h]> ; WORD
- Tcpu_id EQU <WORD PTR [bp-24h]> ; WORD
- Tmap EQU <BYTE PTR [bp-26h]> ; BYTE
- Tsave_3cb EQU <BYTE PTR [bp-28h]> ; BYTE
- Tsave_3cd EQU <BYTE PTR [bp-2ah]> ; BYTE
- TSENGSTACKBLOCK EQU 2ah
-
-
- TsengGetVRAMSize PROC Near
- PUBLIC TsengGetVRAMSize
-
-
- enter TSENGSTACKBLOCK, 0
-
- push si
- push bx
- push cx
- push es
- push ds
-
- mov Ttest0, TTESTA
- mov Ttest1, TTESTB
- mov Ttest2, TTESTC
- mov Ttest3, TTESTD
- mov Tchiptype, ax
- mov TCRTCIndex,dx
- mov Tseg, 0 ; preset return value
- mov Tcpu_id, 0 ; clear cpu id
-
-
- call IdentifyCPU ; get cpu type in AX
-
- mov Tcpu_id, ax ; save cpu type
-
-
- ; Set the 'key' (ie, unlock)
- mov dx, 03bfh
- mov al, 03h
- call OutpDelay
- mov dx, 03b8h
- mov al, 0a0h
- call OutpDelay
- mov dx, 03d8h
- mov al, 0a0h
- call OutpDelay
-
-
- ; Save the state of the TS GDC and CRTC36 registers so we can restore after
- ; setting up linear mapping.
- ;
- ; just push save on stack
-
- mov cx, 1
- SaveTS:
- mov dx, 03C4h
- mov ax, cx
- call OutpIdxInpData
- push ax
- inc cx
- cmp cx, 6
- jle SaveTS
-
- mov cx, 0
- SaveGDC:
- mov dx, 03CEh
- mov ax, cx
- call OutpIdxInpData
- push ax
- inc cx
- cmp cx, 8
- jle SaveGDC
-
- SaveCRTC36:
- mov dx, 03D4h
- mov ax, 036h
- call OutpIdxInpData
- push ax
- SaveCRTC34:
- mov dx, 03D4h
- mov ax, 034h
- call OutpIdxInpData
- push ax
-
-
- ; Set up for linear access.
- ; Enable writes to all planes.
-
- mov dx, 03C4h
- mov al, 02h
- call OutpIdxInpData ;;out dx, al
- or al, 0fh
- inc dx
- call OutpDelay ;;out dx, al
-
-
- ; blank the screen to enable fast host VRAM access
-
- mov dx, 03C4h
- mov al, 01h
- call OutpIdxInpData
- or al, 20h
- inc dx
- call OutpDelay
-
-
- ; set write plane mask for all planes
-
- mov dx, 03C4h
- mov al, 02h
- call OutpIdxInpData
- or al, 0fh
- inc dx
- call OutpDelay
-
-
- ; set Chain 4 mode, disable font selection
-
- mov dx, 03C4h
- mov al, 04h
- call OutpIdxInpData
- or al, 0ch
- and al, 0fdh
- inc dx
- call OutpDelay
-
- ; make sure fast r/w disabled
- ;JWK11
- mov dx, 03C4h ;JWK11
- mov al, 06h ;JWK11
- call OutpIdxInpData ;JWK11
- and al, 0cfh ; disable 'early address info' ;JWK11
- or al, 040h ; disable zero wait state ;JWK11
- inc dx ;JWK11
- call OutpDelay ;JWK11
-
- ; Disable set/reset
-
- mov dx, 03CEh
- mov al, 01h
- call OutpIdxInpData
- and al, 0f0h
- inc dx
- call OutpDelay
-
-
- ; No rop or rotate.
-
- mov dx, 03CEh
- mov al, 03h
- call OutpIdxInpData
- and al, 0e0h
- inc dx
-
- ; select plane 0
-
- mov dx, 03CEh
- mov al, 04h
- call OutpIdxInpData
- and al, 0fch
- inc dx
- call OutpDelay
-
- ; Normal read/write modes
-
- mov dx, 03CEh
- mov al, 05h
- call OutpIdxInpData
- and al, 0e4h
- inc dx
- call OutpDelay
-
-
-
- ; disable PCI Memory Burst
-
- mov dx, 03D4h ;jwk11
- mov al, 34h ;jwk11
- call OutpIdxInpData ;jwk11
- and al, 0efh ;jwk11
- inc dx ;jwk11
- call OutpDelay ;jwk11
-
- ; disable MMU and linear flat addressing
-
- mov dx, 03D4h
- mov al, 36h
- call OutpIdxInpData
- and al, 0c7h ;jwk11 was c3 WRONG
- inc dx
- call OutpDelay
-
-
- ; Use existing mapping
- ; Disable odd/even
-
- mov dx, 03CEh
- mov al, 06h
- call OutpIdxInpData
- mov Tmap, al
- and al, 0fdh
- inc dx
- call OutpDelay
-
-
- ; Enable all bits
-
- mov dx, 03CEh
- mov al, 08h
- call OutpIdxInpData
- mov al, 0ffh
- inc dx
- call OutpDelay
-
-
- ; Address where the VGA memory happens to be mapped
-
- mov al, Tmap
- shr al, 2
- and al, 03h
-
- cmp al, 03h
- jnz @f
- mov ax, 000Bh
- mov bx, 8000h
- jmp SHORT BreakMapSwitch
- @@:
- cmp al, 02
- jnz @f
- mov ax, 000Bh
- mov bx, 0000h
- jmp SHORT BreakMapSwitch
- @@: ;; must be 0 or 1
- mov ax, 000Ah
- mov bx, 0000h
-
- BreakMapSwitch:
-
- mov cx, 16*1024 ; request 16k memory
-
- push ds
- pop es
- ASSUME DS:NOTHING, ES:DGROUP
-
- push ds ;save values for unphystovirt
- push ax ;save values for unphystovirt
- push bx
- push cx
- call SVGAPhysToVirt ;Get virtual address into DS:SI.
- jnc @f
- jmp breaktestloop
- @@:
-
-
- ; Save the GDC segment select registers
-
- mov dx, 03CBh
- in al, dx
- mov Tsave_3cb, al
- mov dx, 03CDh
- in al, dx
- mov Tsave_3cd, al
-
- ; Select the first segment and save what we find there
-
- ;flush cach
- WBINVD ;WBINVD write-back and invalidate cach
-
- xor al, al
- mov dx, 03CBh
- call OutpDelay
- mov dx, 03CDh
- xor al, al
- call OutpDelay
-
-
- ;flush cach
- WBINVD ;WBINVD write-back and invalidate cach ;JWK22
-
-
- ; force fifo empty read ;JWK08
- ; force fifo empty read ;JWK08
- ;JWK08
- push cx ;JWK08
- ;JWK08
- mov cx, 512 ;JWK08
- mov bx, 100 ;offset 100 bytes so we flush 'elsewhere'
- loopa1: ;JWK08
- mov ax, WORD PTR ds:[si+bx] ;JWK08
- add bx, 2 ;JWK08
- loop loopa1 ;JWK08
- ;JWK08
- ;JWK08
- pop cx ;JWK08
- ;JWK08
-
- ; read inital values to be restored later
-
- mov ax, WORD PTR ds:[si+0]
- mov Tsave0, ax
- mov ax, WORD PTR ds:[si+2]
- mov Tsave1, ax
- mov ax, WORD PTR ds:[si+4]
- mov Tsave2, ax
- mov ax, WORD PTR ds:[si+6]
- mov Tsave3, ax
-
- ; set the initial values of the first segment
- ; these should not change unless a wrap occurred
-
- mov ax, Ttest0
- mov WORD PTR ds:[si+0], ax
- mov ax, Ttest1
- mov WORD PTR ds:[si+2], ax
- mov ax, Ttest2
- mov WORD PTR ds:[si+4], ax
- mov ax, Ttest3
- mov WORD PTR ds:[si+6], ax
-
- ;flush cach
- WBINVD ;WBINVD write-back and invalidate cach ;JWK22
-
-
- ; force fifo empty read ;JWK08
- ;JWK08
- push cx ;JWK08
- ;JWK08
- mov cx, 512 ;JWK08
- mov bx, 100 ;offset 100 bytes so we flush 'elsewhere'
- loopb1: ;JWK08
- mov ax, WORD PTR ds:[si+bx] ;JWK08
- add bx, 2 ;JWK08
- loop loopb1 ;JWK08
- ;JWK08
- ;JWK08
- pop cx ;JWK08
-
-
-
- ; Probe memory in 128k increments
-
- xor cx, cx
- ForSegLoop:
-
- ;
- ; Construct the GDC segment selector values for the segment
- ; seg_3cd = seg & 0x0F;
- ; seg_3cd |= seg_3cd << 4;
- ; seg_3cb = seg & 0x30;
- ; seg_3cb |= seg_3cb >> 4;
-
- mov bx, cx ; cx has current segment
- and bx, 0fh
- mov ax, bx
- shl bx, 4
- or ax, bx
- mov Tseg_3cd, ax
-
- mov bx, cx
- and bx, 30h
- mov ax, bx
- shr bx, 4
- or ax, bx
- mov Tseg_3cb, ax
-
-
- ;flush cach
- WBINVD ;WBINVD write-back and invalidate cach ;JWK22
-
-
- ; force fifo empty read ;JWK08
- ;JWK08
- push cx ;JWK08
- ;JWK08
- mov cx, 512 ;JWK08
- mov bx, 100 ;offset 100 bytes so we flush 'elsewhere'
- loopc1: ;JWK08
- mov ax, WORD PTR ds:[si+bx] ;JWK08
- add bx, 2 ;JWK08
- loop loopc1 ;JWK08
- ;JWK08
- ;JWK08
- pop cx ;JWK08
-
- ; Select the 64k segment to test
-
- mov dx, 03CDh
- mov ax, Tseg_3cd
- call OutpDelay
-
- mov dx, 03CBh
- mov ax, Tseg_3cb
- call OutpDelay
-
- ;flush cach
- WBINVD ;WBINVD write-back and invalidate cach ;JWK22
-
-
- ; force fifo empty read ;JWK08
- ;JWK08
- push cx ;JWK08
- ;JWK08
- mov cx, 512 ;JWK08
- mov bx, 100 ;offset 100 bytes so we flush 'elsewhere'
- loopd1: ;JWK08
- mov ax, WORD PTR ds:[si+bx] ;JWK08
- add bx, 2 ;JWK08
- loop loopd1 ;JWK08
- ;JWK08
- ;JWK08
- pop cx ;JWK08
- ;JWK08
- ;JWK08
- ; read current VRAM values so we can restore
-
- mov ax, WORD PTR ds:[si+0]
- mov Tpeek0, ax
- mov ax, WORD PTR ds:[si+2]
- mov Tpeek1, ax
- mov ax, WORD PTR ds:[si+4]
- mov Tpeek2, ax
- mov ax, WORD PTR ds:[si+6]
- mov Tpeek3, ax
-
-
- ; Write the test values
-
- mov ax, Ttest0
- mov WORD PTR ds:[si+0], ax
- mov ax, Ttest1
- mov WORD PTR ds:[si+2], ax
- mov ax, Ttest2
- mov WORD PTR ds:[si+4], ax
- mov ax, Ttest3
- mov WORD PTR ds:[si+6], ax
-
- ;flush cach
- WBINVD ;WBINVD write-back and invalidate cach ;JWK22
-
-
- ; force fifo empty read ;JWK08
- ;JWK08
- push cx ;JWK08
- ;JWK08
- mov cx, 512 ;JWK08
- mov bx, 100 ;offset 100 bytes so we flush 'elsewhere'
- loope1: ;JWK08
- mov ax, WORD PTR ds:[si+bx] ;JWK08
- add bx, 2 ;JWK08
- loop loope1 ;JWK08
- ;JWK08
- ;JWK08
- pop cx ;JWK08
-
-
- ; Make sure data in segment 0 is still valid (no wrap)
-
- xor al, al
- mov dx, 03CBh
- call OutpDelay
- mov dx, 03CDh
- xor al, al
- call OutpDelay
-
- ;flush cach
- WBINVD ;WBINVD write-back and invalidate cach ;JWK22
-
-
- ; force fifo empty read ;JWK08
- ;JWK08
- push cx ;JWK08
- ;JWK08
- mov cx, 512 ;JWK08
- mov bx, 100 ;offset 100 bytes so we flush 'elsewhere'
- loopf1: ;JWK08
- mov ax, WORD PTR ds:[si+bx] ;JWK08
- add bx, 2 ;JWK08
- loop loopf1 ;JWK08
- ;JWK08
- ;JWK08
- pop cx ;JWK08
-
- ; check test values
-
- mov ax, WORD PTR ds:[si+0]
- cmp ax, TTESTA
- jz @f
- jmp breaktestloop
- @@:
- mov ax, WORD PTR ds:[si+2]
- cmp ax, TTESTB
- jz @f
- jmp breaktestloop
- @@:
- mov ax, WORD PTR ds:[si+4]
- cmp ax, TTESTC
- jz @f
- jmp breaktestloop ;short fails on screendd
- @@:
- mov ax, WORD PTR ds:[si+6]
- cmp ax, TTESTD
- jz @f
- jmp breaktestloop ;short fails on screendd
- @@:
-
-
- ; Try to read back the test values in the test segment
-
- ;flush cach
- WBINVD ;WBINVD write-back and invalidate cach ;JWK22
-
-
- ; force fifo empty read ;JWK08
- ;JWK08
- push cx ;JWK08
- ;JWK08
- mov cx, 512 ;JWK08
- mov bx, 100 ;offset 100 bytes so we flush 'elsewhere'
- loopg1: ;JWK08
- mov ax, WORD PTR ds:[si+bx] ;JWK08
- add bx, 2 ;JWK08
- loop loopg1 ;JWK08
- ;JWK08
- ;JWK08
- pop cx ;JWK08
-
- mov dx, 03CDh
- mov ax, Tseg_3cd
- ;;out dx, al
- call OutpDelay
-
- mov dx, 03CBh
- mov ax, Tseg_3cb
- ;;out dx, al
- call OutpDelay
-
- ;flush cach
- WBINVD ;WBINVD write-back and invalidate cach ;JWK22
-
-
- ; force fifo empty read ;JWK08
- ;JWK08
- push cx ;JWK08
- ;JWK08
- mov cx, 512 ;JWK08
- mov bx, 100 ;offset 100 bytes so we flush 'elsewhere'
- looph1: ;JWK08
- mov ax, WORD PTR ds:[si+bx] ;JWK08
- add bx, 2 ;JWK08
- loop looph1 ;JWK08
- ;JWK08
- ;JWK08
- pop cx ;JWK08
-
- ; test the new values (end if not same as written)
-
- mov ax, WORD PTR ds:[si+0]
- cmp ax, Ttest0
- jnz breaktestloop
- mov ax, WORD PTR ds:[si+2]
- cmp ax, Ttest1
- jnz breaktestloop
-
- mov ax, WORD PTR ds:[si+4]
- cmp ax, Ttest2
- jnz breaktestloop
- mov ax, WORD PTR ds:[si+6]
- cmp ax, Ttest3
- jnz breaktestloop
-
-
- ; restore peeked values since we altered them
-
- mov ax, Tpeek0
- mov WORD PTR ds:[si+0], ax
- mov ax, Tpeek1
- mov WORD PTR ds:[si+2], ax
- mov ax, Tpeek2
- mov WORD PTR ds:[si+4], ax
- mov ax, Tpeek3
- mov WORD PTR ds:[si+6], ax
-
- ;flush cach
- WBINVD ;WBINVD write-back and invalidate cach ;JWK22
-
-
- ; force fifo empty read ;JWK08
- ;JWK08
- push cx ;JWK08
- ;JWK08
- mov cx, 512 ;JWK08
- mov bx, 100 ;offset 100 bytes so we flush 'elsewhere'
- loopi1: ;JWK08
- mov ax, WORD PTR ds:[si+bx] ;JWK08
- add bx, 2 ;JWK08
- loop loopi1 ;JWK08
- ;JWK08
- ;JWK08
- pop cx ;JWK08
-
- ; Use a new test pattern for the next location.
-
-
- mov ax, Ttest2
- add ax, 03h
- mov Ttest2, ax
-
- mov ax, Ttest3
- add ax, 07h
- mov Ttest3, ax
-
- add cx, 4 ; 256k increments
- mov Ttest0, cx ; low order word = segment number
- mov Tseg, cx ; update successful block count
-
- cmp cx, 64 ; support up to 4 meg
- jg @f
- jmp ForSegLoop
- @@:
- breaktestloop: ; seg has last valid value
-
- ; Restore the values in the first segment
-
- ;flush cach
- WBINVD ;WBINVD write-back and invalidate cach ;JWK22
-
- xor al ,al
- mov dx, 03CBh
- call OutpDelay
- xor al ,al
- mov dx, 03CDh
- call OutpDelay
-
-
- mov ax, Tsave0
- mov WORD ptr ds:[si+0], ax
- mov ax, Tsave1
- mov WORD ptr ds:[si+2], ax
- mov ax, Tsave2
- mov WORD ptr ds:[si+4], ax
- mov ax, Tsave3
- mov WORD ptr ds:[si+6], ax
-
- ;flush cach
- WBINVD ;WBINVD write-back and invalidate cach ;JWK22
-
-
- ; Restore the segment selector values
-
- mov dx, 03CBh
- mov al, Tsave_3cb
- ;;out dx, al
- call OutpDelay
- mov dx, 03CDh
- mov al, Tsave_3cd
- ;;out dx, al
- call OutpDelay
-
- pop cx ; restore virttophys registers
- pop bx
- pop ax
- pop ds
- ASSUME DS:DGROUP, ES:NOTHING
-
- call SVGAUnPhysToVirt ;Unmap AX:BX.
-
-
- ; Restore CR0
- ; pop eax
- ; mov CR0, eax
-
-
- ; Restore the state of the TS CRTC36 and GDC registers
- ; just pop off the stack and write in reverse order of how we saved
-
-
- RestoreCRTC34:
- mov dx, 03D4h
- mov ax, 034h
- call OutpDelay
- pop ax
- inc dx
- call OutpDelay
-
- RestoreCRTC36:
- mov dx, 03D4h
- mov ax, 036h
- call OutpDelay
- pop ax
- inc dx
- call OutpDelay
-
- mov cx, 8
- RestoreGDC:
- mov dx, 03CEh
- mov ax, cx
- ;;out dx, al
- call OutpDelay
- pop ax
- ;;out dx, al
- inc dx
- call OutpDelay
- dec cx
- cmp cx, 0
- jge RestoreGDC
-
- mov cx, 6
- RestoreTS:
- mov dx, 03C4h
- mov ax, cx
- ;;out dx, al
- call OutpDelay
- pop ax
- ;;out dx, al
- inc dx
- call OutpDelay
- dec cx
- cmp cx, 1
- jge RestoreTS
-
- ; Return the size based on the last segment write/read passed
-
- mov ax, Tseg
-
- ; Restore calling register values
-
- pop ds
- pop es
- pop cx
- pop bx
- pop si
-
- leave
- ret
-
-
- TsengGetVRAMSize ENDP
-
-
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = WhichTseng
- ;*
- ;* DESCRIPTION = Determine which Tseng chip we're using ET3000/ET4000
- ;* Distinguish the two by availability of Extended Start Addr.
- ;* Register (CRTC index 33h) which only exists on ET4000.
- ;*
- ;* INPUT = NONE
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = NONE
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- ;!! Actually, this should be 0210ah + IOD<2:0>*010h:
- TSENG_CRTCB_ADDRESS equ 0217ah ;Index port for W32 CRTCB regs
- TSENG_CRTCB_ROW_OFF_HI equ 0ech ;CRTCB/Sprite Row Offset High Reg
-
- WhichTseng PROC Near
- PUBLIC WhichTseng
-
- enter STACKBLOCK, 0 ; /* */
- call TsengEnableExt ;enable extended regs /* */
- call GetCrtcBase ;(3d4) /* */
- ;* OUTPUT = DX = 003x4 (CRTC index address)
- ; mov bx, dx ;keep copy /* */
- mov al, 037h ;Video System Config 2
- call OutpIdxInpData ;Read indexed reg /* */
- ; ;Can determine mem size /* */
- ; ;only AFTER know chip /* */
- mov bl, al ;Save memory config /* */
- mov al, 033h ;CRTC reg index 33h
- call OutpDelay ;Write the new index value.
- inc dx ;Point to the data register.
- mov al, 0ffh ;All bits first. /* */
- call SaveXORChk ;Test for read/writable./* */
- .if < z > ;If read/writable: /* */
- mov dx, TSENG_CRTCB_ADDRESS ; /* */
- call GetSave1 ; /* */
- mov al, TSENG_CRTCB_ROW_OFF_HI ; /* */
- call OutpIdxInpData ; /* */
- and al, 0f0h ;Extract Chip revision /* */
- .if < z > ; /* */
- mov ax, TSENG_ET4000W32_CHIP ; /* */
- .elseif <al eq 010h>,short ; /* */
- mov ax, TSENG_ET4000W32I_CHIP ; /* */
- .elseif <al eq 020h>,short ; /* */
- mov ax, TSENG_ET4000W32PA_CHIP ; /* */
- .elseif <al eq 030h>,short ; /* */
- mov ax, TSENG_ET4000W32IB_CHIP ; /* */
- .elseif <al eq 050h>,short ; /* */
- mov ax, TSENG_ET4000W32PB_CHIP ; /* */
- .elseif <al eq 060h>,short ; /* */
- mov ax, TSENG_ET4000W32PD_CHIP ; /* */
- .elseif <al eq 070h>,short ; /* */
- mov ax, TSENG_ET4000W32PC_CHIP ; /* */
- .elseif <al eq 0B0h>,short ; /* */
- mov ax, TSENG_ET4000W32IC_CHIP ; /* */
- .else ,short ; /* */
- ;;JWK23 Tseng has assured us that there will be no new W32I chips
- ;;JWK23 and that all future revisions will be W32P Rev C compatable.
- ;;JWK23 Handle Unknown chips as W32Pc. No need to identify new revisions
- ;;JWK23 accept to support some new function.
- ;;JWK23
- ;;JWK23 mov ax, UNKNOWN_CHIP; JWK07 /* */
- mov ax, TSENG_ET4000W32PX_CHIP; JWK23
- .endif ; /* */
- call RestoreSave1 ; /* */
- .else ; /* */
- mov al, 00fh ;Low 4 bits next. /* */
- call SaveXORChk ;Test for read/writable./* */
- .if < z > ;If read/writable: /* */
- mov ax, TSENG_ET4000_CHIP ; /* */
- .else ; /* */
- mov ax, TSENG_ET3000_CHIP ; /* */
- WT3000: ;
- pushf ;
- push ax ;
- mov al, 6 ;set up index port to zoom reg
- mov dl, 0c4h ;SEQ index address (3c4)/* */
- call OutpIdxInpData ;Read indexed reg /* */
- and al, 01111111B ;
- call OutpData ;Turn off zoom enable bit.
- pop ax ;
- popf ;
- .endif ; /* */
- .endif ; /* */
- WTExit: ;
- ; ;Can determine mem size /* */
- ; ;only AFTER know chip /* */
-
- push ax ; /* */
- call TsengGetVRAMSize ;Try VRAM Search ; /* */
- .if <ax ne 0> ;if value, use it ; /* */
- mov word ptr [_sSVGA.Memory][word], ax ; /* */
- pop ax ; /* */
- .else ;else try old method /* */
- pop ax ; /* */
- .if <ax b TSENG_ET4000W32_CHIP> ;ET4000/3000 /* */
- test bl, 081h ;VRAM=1/DRAM=0 :7,1M :0./* */
- .if < z > ;If can determine memory/* */
- ; ;Adjust mem to 512k /* */
- shr word ptr [_sSVGA.Memory][word], 1 ; /* */
- .endif ; /* */
- .elseif < e > ;ET4000W32 /* */
- test bl, 001h ;No VRAM/DRAM bit /* */
- .if < z > ;Bus width? /* */
- ; ;Adjust mem to 512k /* */
- shr word ptr [_sSVGA.Memory][word], 1 ; /* */
- .endif /*@V2.1JWK01*/
- .else ;< a > ET4000W32I/W32P /* */
- test bl, 008h ;Ram length 1M or 256K /* */
- .if < z > ;If 1M: /* */
- shl word ptr [_sSVGA.Memory][word], 001h ; /* */
- .endif ; /* */
- test bl, 001h ;Bus width 16 or 32? /* */
- .if < nz > ;If 32: /* */
- shl word ptr [_sSVGA.Memory][word], 001h ; /* */
- .endif ; /* */
- .endif ;
- .endif ;end if ax /* */
- call TsengDisableExt ;disable extended regs /* */
- leave ; /* */
- ret
-
- WhichTseng ENDP
-
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = WhichVideo7
- ;*
- ;* DESCRIPTION =
- ;* Determine which chip we're using
- ;*
- ;* Chip Revision Register contents
- ;* HT205 71H up to 800x600x16
- ;* HT208 42H 0111xxxxB up to 1024x768x16
- ;* HT209 52H/51H 0101xxxxB up to 1024x768x256 (1Meg memory)
- ;*
- ;* Determining amount of video memory on Video7 adapter.
- ;* Requires the folllowing procedure:
- ;*
- ;* o Set card into a planar mode.
- ;* o Ensure all planes enabled
- ;* o Force card into 32-bit memory width (ext reg 0xcc)
- ;* o Write pattern to %%A0000 (say 5Ah)
- ;* o Enable read from plane 3 (reg 03ceh)
- ;* o Read back value
- ;* o If value is same, we have 1Meg Memory
- ;* o Otherwise set 16-bit memory width
- ;* o Read back same value
- ;* o If value is same, we have 512k Memory
- ;* o Otherwise default to 256k
- ;*
- ;* INPUT = NONE
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = NONE
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- WhichVideo7 PROC Near
- PUBLIC WhichVideo7
-
- enter STACKBLOCK, 0 ; /* */
- mov al, [SEQ06] ;Use Video7 lock restore/* */
- ; Since bit 0 goes on when unlocked, reread != ea! /* */
- and al, 001h ;0=locked, 1=unlocked /* */
- mov al, 0eah ;Assume unlocked /* */
- .if < z > /*@V2.1MNH21*/
- mov al, 0aeh ;Locked instead /* */
- .endif ;0aeh=lock, 0eah=unlock /* */
- mov [SEQ06], al ;Instead of value read /* */
- call Video7EnableExt ;enable extended registers
- mov al, 08eh ;
- ; mov dl, 0c4h ;SEQ index address (3c4)/* */
- call OutpIdxInpData ;Read indexed reg /* */
- shr al, 4 ;has value 04h to 0fh
- mov bl, al ;
- mov ax, VIDEO7_HT205_CHIP ;AX = 1 (HT205) label miss.
- cmp bl, 7 ;
- je WhichV7Exit ;
- inc ax ;AX = 2 (HT208)
- cmp bl, 4 ;
- je WhichV7Exit ;
- inc ax ;AX = 3 (HT209)
- cmp bl, 5 ;
- je WhichV7Exit ;
- ; inc ax ;AX = 4 (HT216) /* */
- ; cmp bl, 6 ;
- ; je WhichV7Exit ;
- xor ax, ax ;AX = 0 (don't know)
- WhichV7Exit:
- mov dx, 2 ;
- mov cl, al ;
- shl dx, cl ;
- mov word ptr [_sSVGA.Memory][1*word], dx ; /* */
- push ax
- cmp al, al ;Indicate IS Video7 /* */
- call Video7DisableExt ;disable extended registers
- pop ax
- leave ; /* */
- ret
-
- WhichVideo7 ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = WhichWeitek
- ;*
- ;* DESCRIPTION = Determine which Weitek SVGA chip we're using.
- ;*
- ;* INPUT = NONE
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = NONE
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- WhichWeitek PROC Near
- PUBLIC WhichWeitek
-
- enter STACKBLOCK, 0
- mov dx, 03c4h ;SEQ index address (3c4)/* */
- call GetSave1 ;Read original index & save it.
- mov al, 007h ;SEQ W5x86 Revision Reg
- call OutpIdxInpData ;Read W5x86 Revision Reg.
- shr al, 5 ;Get Device ID bits low.
- and al, 007h ;Extract just Device ID bits.
- .if < nz > AND
- .if <al be 002h>
- inc al
- .else ;Else W5086 or unknown W5x86.
- xor al, al
- .endif
- cbw ;Extend to word.
- call RestoreSave1 ;Restore the original values.
- leave
- ret
-
- WhichWeitek ENDP
-
-
- ifndef SVGAUTIL
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = WeitekMemConfig
- ;*
- ;* DESCRIPTION = Set Weitek MemConfig register.
- ;* Currently just determine the memory size.
- ;*
- ;* INPUT = AX = new MemConfig register value.
- ;* OUTPUT = AX = old MemConfig register value.
- ;*
- ;* RETURN-NORMAL = NONE
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- WeitekMemConfig PROC Near
- PUBLIC WeitekMemConfig
-
- push es
- push bx
- push cx
- push ax
- mov ax, word ptr [SvgaBaseAddr][word] ;Get base address.
- add ax, WEITEK_P9000_REGISTERS ;High word of physical addr.
- xor bx, bx ;Low word of physical address.
- mov cx, WEITEK_P9000_REGLENGTH ;Length of area selected
- call SVGAPhysToUVirt
- pop ax ;Get back new value.
- .if < nc > ;If selector returned:
- xchg ax, word ptr es:[bx][WEITEK_P9000_MEMCONFIG]
- call SVGAUnPhysToUVirt ;ES=selector to free.
- .endif ;Endif selector returned.
- pop cx
- pop bx
- pop es
- ret
-
- WeitekMemConfig ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = WeitekVRAMMap
- ;*
- ;* DESCRIPTION = Map first word at selected address.
- ;*
- ;* INPUT = AX = selected frame buffer offset high bits.
- ;* = BX = selected frame buffer offset low bits.
- ;* OUTPUT = ES:BX = pointer to frame buffer word.
- ;*
- ;* RETURN-NORMAL = NC if no errors.
- ;* RETURN-ERROR = CR if errors.
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- WeitekVRAMMap PROC Near
- PUBLIC WeitekVRAMMap
-
- push ax ;Save offset high.
- add ax, word ptr [SvgaBaseAddr][word] ;Get base address.
- add ax, WEITEK_P9000_VRAM ;High word of physical addr.
- push cx
- xor cx, cx ;Whole segment.
- sub cx, bx ;Less low bits.
- call SVGAPhysToUVirt
- pop cx
- pop ax ;Restore offset high.
- ret
-
- WeitekVRAMMap ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = WeitekGetSelWord
- ;*
- ;* DESCRIPTION = Get word at selected address.
- ;*
- ;* INPUT = AX = selected frame buffer offset high bits.
- ;* = BX = selected frame buffer offset low bits.
- ;* OUTPUT = DX = word at selected address.
- ;*
- ;* RETURN-NORMAL = NC if no errors.
- ;* RETURN-ERROR = CR if errors.
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- WeitekGetSelWord PROC Near
- PUBLIC WeitekGetSelWord
-
- push es
- push bx
- call WeitekVRAMMap ;Map the word.
- .if < nc > ;If selector returned:
- mov dx, word ptr es:[bx]
- call SVGAUnPhysToUVirt ;ES=selector to free.
- .endif ;Endif selector returned.
- pop bx
- pop es
- ret
-
- WeitekGetSelWord ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = WeitekSetSelWord
- ;*
- ;* DESCRIPTION = Set word at selected address.
- ;*
- ;* INPUT = AX = selected frame buffer offset high bits.
- ;* = BX = selected frame buffer offset low bits.
- ;* DX = word to set at selected address.
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = NC if no errors.
- ;* RETURN-ERROR = CR if errors.
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- WeitekSetSelWord PROC Near
- PUBLIC WeitekSetSelWord
-
- push es
- push bx
- call WeitekVRAMMap ;Map the word.
- .if < nc > ;If selector returned:
- mov word ptr es:[bx], dx
- call SVGAUnPhysToUVirt ;ES=selector to free.
- .endif ;Endif selector returned.
- pop bx
- pop es
- ret
-
- WeitekSetSelWord ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = WeitekGet1stWord
- ;*
- ;* DESCRIPTION = Get first word from frame buffer.
- ;*
- ;* INPUT = NONE
- ;* OUTPUT = DX = word at selected address.
- ;*
- ;* RETURN-NORMAL = NC if no errors.
- ;* RETURN-ERROR = CR if errors.
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- WeitekGet1stWord PROC Near
- PUBLIC WeitekGet1stWord
-
- push ax
- push bx
- xor ax, ax ;Get buffer start selector.
- xor bx, bx ;Get buffer first word.
- call WeitekGetSelWord
- pop bx
- pop ax
- ret
-
- WeitekGet1stWord ENDP
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = WeitekChkSelWord
- ;*
- ;* DESCRIPTION = Check read/writability of word at selected address.
- ;*
- ;* INPUT = AX = selected frame buffer offset high bits.
- ;* = BX = selected frame buffer offset low bits.
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = (zr if reads match writes)
- ;* RETURN-ERROR = (nz if reads do NOT match writes)
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- WeitekChkSelWord PROC Near
- PUBLIC WeitekChkSelWord
-
- call WeitekGetSelWord ;Get word original value.
- push dx ;Save original value.
- .if <nc> AND ;If no mapping errors:
- call WeitekGet1stWord
- .if <nc> AND ;If no mapping errors:
- xor dx, 0aaaah ;Toggle half the bits.
- mov cx, dx ;Save new value.
- call WeitekSetSelWord
- call WeitekGet1stWord ;Force actual memory read.
- .if <dx ne cx> ;If starting word did not change:
- call WeitekGetSelWord ;See if word changed as set.
- cmp dx, cx ;Not floating, high, or low.
- .else ;Else wrap occured!
- or cx, 00001h ;Set NZ for failure.
- .endif
- pop dx ;Restore original value.
- pushf ;Save success indicator.
- call WeitekSetSelWord
- popf ;Restore success indicator.
- ret
-
- WeitekChkSelWord ENDP
-
- endif ;/* SVGAUTIL */
-
- ;* /* */
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = WhichWeitekP9x00
- ;*
- ;* DESCRIPTION = Determine which Weitek chip were using.
- ;* Currently just determine the memory size.
- ;*
- ;* INPUT = NONE
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = NONE
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- WhichWeitekP9x00 PROC Near
- PUBLIC WhichWeitekP9x00
-
- enter STACKBLOCK, 0 ; /* */
-
- ifdef TSU02 ;
-
- ifndef SVGAUTIL
- mov ax, 00002h ;Set for 2 banks.
- call WeitekMemConfig
- push ax ;Save original memory configuration.
- ;*
- ;* Now find chip length by testing for
- ;* address wrap or end of chip at high addresses.
- ;* Assume chips are at least 64K/4=16K bits long.
- ;!!Should there be an assumed length for REAL DOS? =256K? =1M? /* */
- ;* Starting value here determines "default" size given under real DOS
- ;* Size will be 1/2 of first test, since first (and any) test fails.
- ;*
- mov ax, 00008h ;Start with 128K bits long=512K buffer.
- xor bx, bx ;Offset low is always zero.
- .repeat
- push ax
- shr ax, 1 ;Test wrap after previous chip size.
- call WeitekChkSelWord ;Check for word read/writable.
- pop ax
- .until < nz > or ;Until memory test fails or...
- shl ax, 1 ;Get next chip size.
- .until <ax a 00010h> ;Until > largest possible length=256K.
- shr ax, 1 ;Failed at this size, but not prev=1/2!
- mov word ptr [_sSVGA.Memory][1*word], ax ; /* */
- ;*
- ;* Now find out how many banks by testing
- ;* bank bits (2:3) in addresses in 4 bank mode.
- ;*
- mov ax, 00004h ;Set for 4 banks.
- call WeitekMemConfig
- xor ax, ax ;High word of physical address.
- mov bx, dword ;Check second bank.
- call WeitekChkSelWord ;Check for word read/writable.
- .if < z > ;If at least two banks:
- shl word ptr [_sSVGA.Memory][word], 1 ; /* */
- shl bx, 1 ;Check third bank.
- call WeitekChkSelWord ;Check for word read/writable.
- .if < z > ;If at least three(&four) banks:
- shl word ptr [_sSVGA.Memory][word], 1 ; /* */
- .endif
- .endif
- ;*
- pop ax ;Restore original memory configuration.
- call WeitekMemConfig
-
- else ;/* SVGAUTIL */
- ;* Leave default memory size at 1M
- endif ;/* SVGAUTIL */
-
- endif ;
-
- mov di, word ptr [SvgaBaseAddr][word] ;Get presumed base address.
-
- ifndef SVGAUTIL ; /*@V3.0MNH04*/
- call WeitekP9000Chk ; /*@V3.0MNH04*/
- .if < nz > ;If not P9000 base: /*@V3.0MNH04*/
- mov di, 00000h+WEITEK_P9000_REGISTERS ;Hunt! /*@V3.0MNH04*/
- .repeat ; /*@V3.0MNH04*/
- call WeitekP9000Chk ; /*@V3.0MNH04*/
- .leave < z > ; /*@V3.0MNH04*/
- add di, WEITEK_P9000_INCREMENT ;Leaves nz! /*@V3.0MNH04*/
- .until < c > ;Until addr hi word wrap/*@V3.0MNH04*/
- .endif ; /*@V3.0MNH04*/
- mov ax, WEITEK_P9000_CHIP ; 1 /* */
- .if < nz > ;No 9000 found: /*@V3.0MNH04*/
- mov ax, WEITEK_P9100_CHIP ; 4 /*@V3.0MNH04*/
- .endif ; /*@V3.0MNH04*/
- else ;/* SVGAUTIL */ ; /*@V3.0MNH04*/
- ;* /*@V3.0MNH04*/
- ;* We do not have a way to use 32 bit addr's in real DOS! /*@V3.0MNH04*/
- ;* So we can only guess... /*@V3.0MNH04*/
- ;* /*@V3.0MNH04*/
- mov ax, WEITEK_P9000_CHIP ; 1 /* */
- endif ;/* SVGAUTIL */ ; /*@V3.0MNH04*/
-
- and di, not WEITEK_P9000_REGISTERS ;Remove register part, leave base.
- mov word ptr [SvgaBaseAddr][word], di ;Save base address.
-
- leave ; /* */
- ret
-
- WhichWeitekP9x00 ENDP
-
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = WhichWesternDig
- ;*
- ;* DESCRIPTION =
- ;* At index 30 thru 3f, the WD90cxx chips have an encoded device id.
- ;* Certain unlocks must be done to allow it to be read.
- ;* This is NOT documented in ALL of their data books.
- ;* It IS documented in the data book for the WD90C26.
- ;* It IS hinted at ("reserved") in other data books.
- ;*
- ;* 3333333333333333
- ;* 0123456789ABCDEF
- ;* PVGA1A ->################ #=0ffh or 000h
- ;* WD90c00 ->COPYRIGHT1989WDC
- ;* WD90c24 ->#WD90C24REVC0892 #=varies Toshiba T4700CT
- ;* WD90c24a2a->#WD90C24AREVA293 #=varies z=000h WD90C24 Demo Board
- ;* WD90c24a2b->#WD90C24AREVB293 #=varies z=000h IBM ThinkPad
- ;* WD90c24a2c->#WD90C24AREVC### #=varies WD program checks this!
- ;* WD90c26 ->#WD90C26REV#199# #=varies WD ref documents this!
- ;* WD90c31 ->#WD90C310200zzzz #=varies z=000h WD program checks this!
- ;* WD90c31A ->#WD90C31050zzzzz #=varies z=000h WD program checks this!
- ;* WD90c33 ->#WD90C33######## #=varies z=000h WD program checks this!
- ;* WD90c34 ->#WD90C34######## #=varies z=000h WD program checks this!
- ;* WD90cxx ->#WD90Cxx######## #=varies x=chip
- ;*
- ;* INPUT = NONE
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = NONE
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- WhichWesternDig PROC Near
- PUBLIC WhichWesternDig
-
- enter STACKBLOCK, 0 ; /* */
- mov dx, 03c4h ;SEQ index address (3c4)/* */
- call InpDelay ;Read original index /* */
- push ax ;Save original index /* */
- mov ax, 04806h ;Everyone's fav lock! /* */
- call OutpwDelay ;Unlock /* */
- call WDEnableExt ;Unlock needed registers.
- ;* OUTPUT = DX = 003x4 (CRTC index address)
- mov al, 036h
- call WDRegPairString ;Read chip id char pair for 90cxx
- mov bx, WESTERNDIG_PVGA1A_CHIP ;BX has value to return
- cmp ax, 0ffffh ;Registers do not exist!
- jz WhichWDEasy ;It's a PVGA1A
- cmp ax, 00000h ;Registers do not exist!
- jz WhichWDEasy ;It's a PVGA1A
- inc bx ;Assume WD90c00
- cmp ax, 04748h ;"GH"
- jz WhichWDEasy ;It's a WD90c00
- and ax, 00f0fh
- mov cl, 004h
- shl ah, cl
- or al, ah
- cmp al, 000h
- jz WhichWDEasy ;It's a WD90c00
- cmp al, 020h
- jz WhichWDEasy ;It's a WD90c00
- cmp al, 022h
- jz WhichWDEasy ;It's a WD90c00
- inc bx ;Assume WD90c11
- cmp al, 011h
- jz WhichWDEasy ;It's a WD90c11
- inc bx ;Assume WD90c30
- cmp al, 030h
- jz WhichWDEasy ;It's a WD90c30
- inc bx ;Assume WD90c26
- cmp al, 026h
- jz WhichWDEasy ;It's a WD90c26
- inc bx ;Assume WD90c27
- cmp al, 027h
- jz WhichWDEasy ;It's a WD90c27
- inc bx ;Assume WD90c31
- cmp al, 031h
- jz WhichWDEasy ;It's a WD90c31
- inc bx ;Assume WD90c24
- cmp al, 024h
- jz WhichWDEasy ;It's a WD90c24
- inc bx ;Assume WD90c33
- cmp al, 033h
- jz WhichWDEasy ;It's a WD90c33
- jmp short @F
- WhichWDEasy:
- ifdef SVGAUTIL
- jmp short WhichWDExit1
- else ;/* SVGAUTIL */
- jmp WhichWDExit1
- endif ;/* SVGAUTIL */
- @@:
- ;!! I doubt that the following tests will remain necessary! /* */
- ; mov bx, WESTERNDIG_WD9000_CHIP ;Assume WD90c00
- ; mov dl, 0c4h ;SEQ index address (3c4)/* */
- ; mov [SaveReg4], dx
- ; call InpDelay ;Read the original index.
- ; mov [SaveIndex4], al
- ; mov ax, 04806h ;extended sequencers.
- ; call OutpwDelay ;Write the new value.
- ; ;Distinguish between
- ; mov al, 012h ; WD90c00 and WD90c11 & later
- ; call OutpIdxInpData ;Read indexed reg /* */
- ; ; by using bit 6 of Misc Control Reg
- ; ;If chip doesn't respond to changes
- ; ; in the bit, its a WD90c00
- ; mov ah, al ;
- ; and al, NOT 01000000B ;
- ; call OutpData ;Replace with bit 6 set to 0.
- ; call InpData ;Read the value back.
- ; xchg al, ah ;
- ; call OutpData ;Write the original value.
- ; xchg ah, al ;
- ; test al, 01000000B ;if bit IS NOT zero,
- ; jnz WhichWDExit2 ; its a 90c00
- ; or al, 01000000B ;
- ; call OutpData ;Replace with bit 6 set to 1.
- ; call InpData ;Read the value back.
- ; xchg al, ah ;
- ; call OutpData ;Write back the original value.
- ; xchg ah, al ;
- ; test al, 01000000B ;if bit IS zero,
- ; jz WhichWDExit2 ; its a 90c00
- ; inc bx ;Assume WD90c11
- ; mov dl, 0c4h ;SEQ index address (3c4)/* */
- ; ;Look for scratch pad reg
- ; mov ax, 0aa09h ; at index 09h, found on
- ; call SaveOutpwChk ; 90c30, not 90c11
- ; jnz WhichWDExit2 ;Its probably a 90c11
- ; inc bx ;Call it at least a WD90c30...
- ; mov dx, 023c0h ;Check for extended index control reg
- ; mov al, 0ffh ;Value to XOR with for test.
- ; call SaveXORChk ;
- ; jnz WhichWDExit2 ;Its probably a 90c30.
- ; mov bx, WESTERNDIG_WD9031_CHIP ;Call it at least a WD90c31.
- WhichWDExit2:
- ; mov dx, [SaveReg4]
- ; mov al, [SaveIndex4]
- ; out dx, al
- WhichWDExit1:
- .if <bx e WESTERNDIG_WD9024_CHIP> ; /* */
- mov al, 03ch ;Id string byte /* */
- call OutpIdxInpData ;Read indexed reg /* */
- ; /* */
- ; Because of STN displays only capable of using 1/2M /* */
- ; even on the newer chips, memory path is a better /* */
- ; indication of usable display memory. /* */
- ; /* */
- ; .if <al ae 'C'> ; /* */
- ; mov al, 02ah ;PR11 EGA Switches /* */
- ; .else ;Else not WD90C24C: /* */
- ; /* */
- ; Yes, strangely 32 bit path implies 1/2M! /* */
- ; And 16 bit path implies 1M! /* */
- ; /* */
- mov dl, 0c4h ;SEQ index address (3c4)/* */
- mov al, 010h ; /* */
- ; .endif ; /* */
- call OutpIdxInpData ;Read indexed reg /* */
- not al ;Extra mem if bit 5 OFF /* */
- and al, 020h ;Was bit 5 OFF? now ON? /* */
- shr al, 2 ;512K Extra (1M Total) /* */
- add al, 008h ;512K Otherwise /* */
- .else ;Else not WD90C24: /* */
- xor al, al ;Assume size not found /* */
- ;*
- ;* WARNING: /* */
- ;* PR18 for LCD/FLAT PANELS is 3x5.31 Flat Panel Status (C24)
- ;* PR18 for desktops is 3x5.3e Vertical Timing Overflow (C31/C33)
- ;* PR18A for LCD/FLAT PANELS is 3x5.3d Vertical Timing Overflow (C24)
- ;*
- ;* WARNING: /* */
- ;* 3x5.3e is PR18 Vertical Timing Overflow for desktops (C31/C33)
- ;* 3x5.3e is PR39 Flat Panel Blinking for LCD/FLAT PANELS (C24)
- ;*
- ;* So we cannot just read 3x5.3e and expect the Vertical
- ;* Timing Overflow, without knowing which chip we have!
- ;*
- .if <bx e WESTERNDIG_WD9033_CHIP> ; /* */
- mov al, 03eh ;PR18 Vert Timing Ovrflw/* */
- call OutpIdxInpData ;Read indexed reg /* */
- and al, 080h ;Get 90C33 2M bit /* */
- shr al, 2 ;Shift to 2M position /* */
- .endif ;Else not WD90C33: /* */
- .if <zero al> ;If not 2M then what? /* */
- mov dl, 0ceh ;Determine on-board memory
- mov al, 00bh ;Memory size
- call OutpIdxInpData ;Read indexed reg /* */
- shr al, 006h ;top 2 bits have mem size;
- .if < nz > ;zero means 256k /* */
- dec al ;make count zero-based /* */
- .endif /*@V2.1MNH01*/
- mov cl, al ; /* */
- mov al, 0100B ;256KB with no shift /* */
- shl al, cl ;Shift to correct size. /* */
- .endif ;Endif not 2M. /* */
- .endif ;Endif not WD90C24 /* */
- cbw ;Extend to fullword /* */
- mov word ptr [_sSVGA.Memory][word], ax ; /* */
- mov al, 006h ;Everyone's fav lock! /* */
- mov ah, [SEQ06WD] ;Use WD lock restore /* */
- mov [SEQ06], ah ;Instead of value read /* */
- mov dl, 0c4h ;SEQ index address (3c4)/* */
- call OutpwDelay ;Restore original lock /* */
- pop ax ;Restore original index /* */
- call OutpDelay ;Restore original index /* */
- push bx ;Save return code /* */
- call WDDisableExt ; /* */
- pop ax ;Get return code /* */
- leave ; /* */
- ret
-
- WhichWesternDig ENDP
-
- ifndef SVGAUTIL
-
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = IdentifyPCIAdapter
- ;*
- ;* DESCRIPTION =
- ;* Process the array of identified PCI video devices and find the preffered
- ;* one (supported) and assign it our private device id. If none found, return
- ;* generic_pci_adapter as the SVGA type.
- ;*
- ;*
- ;* INPUT = NONE
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = _sSVGA and SvgaOEMInfo structures are set.
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY IdentifyAdapter
- ;*
- ;****************************************************************************/
-
- IdentifyPCIAdapter PROC near
- mov [_sSVGA.AdapterType], UNKNOWN_ADAPTER ; 0 ; /* */
- mov [_sSVGA.ChipType], UNKNOWN_CHIP ; 0 ; /* */
- mov word ptr [_sSVGA.Memory][0*word], 0 ; /* */
- mov word ptr [_sSVGA.Memory][1*word], 0010h ; /* */
- mov [SvgaOEMInfo.Manufacturer], UNKNOWN_MANUFACTURER ; 0 ;
- mov cx, PCI_Num
- device_loop:
- dec cx
- mov si, offset PCI_DeviceTbl ;ulong hw: Vendor ID, lw Device ID
- mov ax, cx
- shl ax, 2
- add si, ax
- mov ax, word ptr ds:[si]
- cmp ax, 01002h ;ATI
- jnz short @F
- call IsATI ;
- jnz BadDetection ;
- mov [_sSVGA.AdapterType], ATI_ADAPTER ;
- call WhichATI
- jmp DonePCI
-
- @@:
- cmp ax, 0100ch ;TSENG
- jnz short @F
- call IsTseng ;
- jnz BadDetection ;
- mov [_sSVGA.AdapterType], TSENG_ADAPTER ;
- call WhichTseng
- jmp DonePCI
-
- @@:
- cmp ax, 010beh ;TSENG
- jnz short @F
- call IsTseng ;
- jnz BadDetection ;
- mov [_sSVGA.AdapterType], TSENG_ADAPTER ;
- call WhichTseng
- jmp DonePCI
-
- @@:
- cmp ax, 0100eh ;WEITEK
- jnz short @F
- ; call IsWeitek
- ; jnz BadDetection
- mov [_sSVGA.AdapterType], WEITEK_ADAPTER ;
- mov si, offset PCI_DeviceTbl ;ulong hw: Vendor ID, lw Device ID
- mov ax, cx
- shl ax, 2
- add ax, 2
- add si, ax
- mov ax, word ptr ds:[si]
- cmp ax, 09100h ; device ID for 9100
- jnz NextWTChip
- mov ax, WEITEK_P9100_CHIP
- jmp DonePCI
- NextWTChip:
- cmp ax, 09001h ; device ID for 9000
- jnz NextDevice
- mov ax, WEITEK_P9000_CHIP
- jmp SHORT DonePCI
-
- @@:
- cmp ax, 0101ch ;WD
- jnz short @F
- call IsWesternDig ;
- jnz short BadDetection ;
- mov [_sSVGA.AdapterType], WESTERNDIG_ADAPTER ;
- call WhichWesternDig ;
- jmp SHORT DonePCI
-
- @@:
- cmp ax, 01013h ;Cirrus
- jnz short @F
- call IsCirrus ;
- jnz short BadDetection ;
- mov [_sSVGA.AdapterType], CIRRUS_ADAPTER ;
- call WhichCirrus ;
- jmp SHORT DonePCI
-
- @@:
- cmp ax, 05333h ;S3
- jnz short @F
- call IsS3 ;
- jnz short BadDetection ;
- mov [_sSVGA.AdapterType], S3_ADAPTER ;
- call WhichS3 ;
- jmp SHORT DonePCI
-
- @@:
- cmp ax, 01023h ;TRIDENT
- jnz short @F
- call IsTrident ;
- jnz short BadDetection ;
- mov [_sSVGA.AdapterType], TRIDENT_ADAPTER ;
- call WhichTrident ;
- jmp SHORT NextDevice
-
- @@:
- cmp ax, 01005h ;AVANCE
- jnz short @F
- ; mov [_sSVGA.AdapterType], GENERIC_PCISVGA_ADAPTER
- mov [_sSVGA.AdapterType], UNKNOWN_ADAPTER ;
- mov ax, 02301h
- jmp SHORT NextDevice
-
- @@:
- cmp ax, 0102ch ;C&T
- jnz short @F
- mov [_sSVGA.AdapterType], CHIPS_ADAPTER ;
- mov ax, CHIPS_FIRST_CHIP ; return a chiptype
-
- @@:
- NextDevice:
- jcxz DonePCI
- jmp device_loop
- DonePCI:
- mov [_sSVGA.ChipType], ax
- ret
- BadDetection: ;
- mov ax, 0ffh ;
- ret ;
- IdentifyPCIAdapter ENDP
-
- endif
-
- ;/****************************************************************************
- ;*
- ;* FUNCTION NAME = _IdentifySVGA
- ;*
- ;* DESCRIPTION =
- ;*
- ;* Identify SVGA and its VRAM size from:
- ;*
- ;* Return in AH AL
- ;* o Indeterminate chip set 0 0
- ;*
- ;* o Headland/Video 7 HT205 1 1
- ;* HT208 1 2
- ;* HT209 1 3
- ;*
- ;* o Trident Microsystems 8800 2 1
- ;* 8900 2 2
- ;*
- ;* o Tseng ET3000 3 1
- ;* ET4000 3 2
- ;* ET4000/W32 3 3
- ;* ET4000/W32i 3 4/* */
- ;* ET4000/W32p 3 5/* */
- ;*
- ;* o Western Digital PVGA1A 4 1
- ;* WD90c00 4 2
- ;* WD90c11 4 3
- ;* WD90c30 4 4
- ;* WD90c26 4 5/* */
- ;* WD90c27 4 6/* */
- ;* WD90c31 4 7/* */
- ;* WD90c24 4 8/* */
- ;* WD90c33 4 9/* */
- ;*
- ;* o ATI ATI18800 5 1
- ;* ATI28800 5 2
- ;* ATI38800==MACH8 5 3/* */
- ;* ATI68800==MACH32 5 4/* */
- ;* ATI68800AX 5 5/* */
- ;* ATI68800GX 5 6/* */
- ;*
- ;* o IBM Speedway VGA-256C 6 1
- ;*
- ;*
- ;* o CIRRUS GD5422 7 1
- ;* GD5424 7 2
- ;* GD5426 7 3
- ;* GD5428 7 4/* */
- ;*
- ;* o S3 801, 805 8 1
- ;* 928 8 2
- ;* 864 8 3/* */
- ;* 964 8 4/* */
- ;* 911 8 5/* */
- ;*
- ;* o CHIPS&TECHNOLOGY 9 /* */
- ;*
- ;* o WEITEK P9000 10 1/* */
- ;* W5186 10 2/* */
- ;* W5286 10 3/* */
- ;*
- ;* ENTRY POINT: _IdentifySVGA
- ;* LINKAGE: Call Far
- ;*
- ;* INPUT:
- ;* ES:BX = request packet address
- ;* DS = DGROUP
- ;*
- ;* EXIT-NORMAL: AX = Status to return to OS
- ;* EXIT-ERROR: NONE
- ;*
- ;* EFFECTS:
- ;* AX
- ;*
- ;* USES ROUTINES:
- ;*
- ;* CALLED BY ROUTINES:
- ;* INIT
- ;*
- ;* INPUT = NONE
- ;* OUTPUT = NONE
- ;*
- ;* RETURN-NORMAL = adapter type and chip type.
- ;* RETURN-ERROR = NONE
- ;*
- ;* CALLED BY
- ;*
- ;****************************************************************************/
-
- _IdentifySVGA PROC far ;to far /* */
- PUBLIC _IdentifySVGA ; /* */
-
- enter 0,0 ; /* */
- pusha ; /* */
- push ds ; /* */
- ifndef SVGAUTIL
- cmp word ptr PCI_Num, 0 ;@senja
- jz short @F ;@senja
- call IdentifyPCIAdapter ;will set both _sSVGA and SvgaOEMInfo structures
- cmp ax, 0ffh ;
- jnz IdentifyExit ;
- @@:
- endif
- mov [_sSVGA.AdapterType], UNKNOWN_ADAPTER ; 0 ; /* */
- mov [_sSVGA.ChipType], UNKNOWN_CHIP ; 0 ; /* */
- mov word ptr [_sSVGA.Memory][0*word], 0 ; /* */
- mov word ptr [_sSVGA.Memory][1*word], 0010h ; /* */
- mov [SvgaOEMInfo.Manufacturer], UNKNOWN_MANUFACTURER ; 0 ;
- mov dx, 03c4h ;SEQ index address (3c4)/* */
- call InpDelay ;Read original index /* */
- push ax ;Save original index /* */
- mov al, 048h ; /* */
- call OutpInp ;Test WD PR20 lock state/* */
- or al, 040h ;Create WD lock restore /* */
- mov [SEQ06WD], al ;Save just in case WD! /* */
- mov al, 006h ;Everyone's fav lock! /* */
- call OutpIdxInpData ;Read original value. /* */
- mov [SEQ06], al ;Save in case not WD! /* */
- pop ax ;Restore original index /* */
- call OutpDelay ;Restore original index /* */
- @@: ; /* */
- call IsSpeedWay
- jnz @F
- mov [_sSVGA.AdapterType], IBM_ADAPTER ; 6 /* */
- mov ax, IBM_SVGA_CHIP ;1 ; /* */
- jmp SetChipType ; /* */
-
- @@: call IsVideo7 ;
- jnz short @F ;
- mov [_sSVGA.AdapterType], VIDEO7_ADAPTER ;1 /* */
- call WhichVideo7 ;
- jmp SetChipType
-
- @@: call IsTrident ;
- jnz short @F ;
- mov [_sSVGA.AdapterType], TRIDENT_ADAPTER ;2 /* */
- call WhichTrident ;
- jmp short SetChipType
-
- @@: call IsTseng ;
- jnz short @F ;
- mov [_sSVGA.AdapterType], TSENG_ADAPTER ;3 /* */
- call WhichTseng ;
- jmp short SetChipType
-
- @@: call IsWesternDig ;
- jnz short @F ;
- mov [_sSVGA.AdapterType], WESTERNDIG_ADAPTER ;4 /* */
- call WhichWesternDig ;
- jmp short SetChipType
-
- @@: call IsATI ;
- jnz short @F ;
- mov [_sSVGA.AdapterType], ATI_ADAPTER ;5 /* */
- call WhichATI ;
- jmp short SetChipType
-
- @@: call IsCirrus ; /* */
- jnz short @F ;
- mov [_sSVGA.AdapterType], CIRRUS_ADAPTER ;7 /* */
- call WhichCirrus ;
- jmp short SetChipType
-
- @@: call IsS3 ; /* */
- jnz short @F ;
- mov [_sSVGA.AdapterType], S3_ADAPTER ;8 /* */
- call WhichS3 ;
- jmp short SetChipType
-
- @@: call IsChips ; /* */
- jnz short @F ;
- mov [_sSVGA.AdapterType], CHIPS_ADAPTER ;9
- mov ax, CHIPS_FIRST_CHIP ; return a chiptype
- jmp short SetChipType
-
- @@: call IsWeitek ; /* */
- jnz short @F ; /* */
- mov [_sSVGA.AdapterType], WEITEK_ADAPTER ; 10 /* */
- call WhichWeitek ; /* */
- jmp short SetChipType ; /* */
-
- @@: call LastAttempt ; /* */
- or ax, ax
- jz SVGAExit ;AX is 0 if adapter not identified.
- ;if successful ax= adapter, bx=chiptype.
- mov [_sSVGA.AdapterType], ax ; /* */
- mov ax, bx
- SetChipType: ; /* */
- mov [_sSVGA.ChipType], ax ; /* */
- SVGAExit:
- ;* /* */
- ;* Since WEITEK P9000 can be married to any VGA,
- ;* we test for it last and if we find it,
- ;* we move the current adapter and chip type to SvgaOEMInfo
- ;*
- @@: call IsWeitekP9x00 ; /*@V3.0MNH04*/
- jnz short IdentifyExit ;@senja
- mov ax, [_sSVGA.AdapterType] ; /* */
- mov word ptr [SvgaOEMInfo.ManufacturerData][0*word], ax ;
- mov ax, [_sSVGA.ChipType] ; /* */
- mov word ptr [SvgaOEMInfo.ManufacturerData][1*word], ax ;
- mov [_sSVGA.AdapterType], WEITEK_ADAPTER ; 10 /* */
- call WhichWeitekP9x00 ; /*@V3.0MNH04*/
- mov [_sSVGA.ChipType], ax ; /* */
- IdentifyExit:
- pop ds ; /* */
- popa ; /* */
- leave ; /* */
- ret ; /* */
-
- _IdentifySVGA ENDP ; /* */
-
- BiosSeg ends
-
- end
- ;*
- ;* CHANGE ACTIVITY =
- ;* DATE FLAG APAR CHANGE DESCRIPTION
- ;* -------- ---------- ----- --------------------------------------
- ;* mm/dd/yy @Vr.mpppxx xxxxx xxxxxxx
- ;* 11/12/92 Dale More specific Speedway detection.
- ;* 12/28/92 Senja Cirrus Logic support.
- ;* 01/20/93 Senja WD detection logic enhanced.
- ;* 01/21/93 XGA doesn't boot because Aperture Index gets trashed.
- ;* 02/10/93 Manufacturer info IOCTL.
- ;* 02/18/93 UpdateMemoryInfo IOCTL.
- ;* 03/05/93 Do not identify XGA as Speedway.
- ;* 03/10/93 Identification of MC Orchid.
- ;* 03/12/93 Changed BANK packet interface to be more consistent.
- ;* 03/16/93 Making SCREENDD more consistent.
- ;* 03/23/93 Fixing bank packet validation.
- ;* 04/03/93 Attach to OEMHLP.
- ;* 04/14/92 If XGA detected, do not proceed with the detection.
- ;* 05/02/93 68723 Improve Speedway checks
- ;* 06/03/93 69461 Lock the extended sequencer before exit
- ;* 06/03/93 63910 ACER M3125 SVGA fix
- ;* 06/04/93 F69306 Add support for S3
- ;* 08/12/93 72760 Enhance S3 chip detection
- ;* 08/30/93 73465 Only need 1 manufacturer value for Diamond
- ;* 08/31/93 Recognize Cirrus Logic GD5428 chip
- ;* 10/06/93 72687 Support Number Nine adapters with S3
- ;* 10/13/93 74175 Fix SVGA conflict on Gateway VLB
- ;* 11/01/93 D75458 Merge r206v, r205, r206, r207 S3 code
- ;* 11/19/93 D74047 Add support for S3 911/924
- ;* 02/24/94 D79562 Recognize additional WD chipsets
- ;* 03/17/94 D80921 Fix WD DOS started in background
- ;* 03/18/94 D Fix WD DOS started in background
- ;* 04/26/94 D82003 WD90C24 preserve locks for BIOS setmodes
- ;* 05/13/94 F74819 ATI Mach8/32 check in files
- ;* 05/14/94 Support more Cirrus chipsets
- ;* 05/17/94 Support S3 Vision 864/964
- ;* 06/14/94 Make Video7 lock check not affect Cirrus
- ;* 06/15/94 Add ATI Mach 64 Identification
- ;* 07/15/94 enhance Tseng VRAM size determination
- ;* 07/16/94 ATI Mach64 detection clear RS2 & restore
- ;* 07/16/94 D89152 WD/Video7/Cirrus SEQ06 lock preservation
- ;* 07/28/94 88172 Detect Chips and Technologies adapter
- ;* 08/04/94 92358 Set zero flag off if CHIPS not found
- ;* 08/12/94 92809 Tseng MemorySize determination not always correct (VLB, PCI)
- ;* 08/16/94 D93790 Fix WD C24 memory detection
- ;* 08/18/94 82945 Enable TSENGW32 with Diamond
- ;* 08/26/94 D93217 Fix ATI Mach32 memory detection
- ;* 08/25/94 D Add PCI detection via a BIOS call.
- ;* 09/19/94 92593 Actix S3864 returns vender ID
- ;* 09/22/94 99400 Avance card causes trap in DOS full screen
- ;* 09/22/94 Strengthen CHIPS test
- ;* 09/23/94 Detect memory size for Cirrus
- ;* 09/25/94 99760 Compudyne w/ Weitek IPE during installation
- ;* 10/20/94 Add write back invalidate cache commands
- ;* 10/25/94 103192 TSENG Rev D wont install
- ;* 11/16/94 @V3.0JLO01 104565 ATI Mach32 microchannel version not recognized
- ;* 11/30/94 @V3.0YEE01 105950 Support S3 964
- ;* 01/12/95 @V3.0MNH04 102314 Put back Weitek Hunt to id 9000 vs 9100
-