home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mega A/V
/
mega_av.zip
/
mega_av
/
GRAPHUTL
/
VESA_TSR.ZIP
/
C&T
/
VESA452.ASM
< prev
next >
Wrap
Assembly Source File
|
1990-04-18
|
24KB
|
908 lines
page 70, 132
;----------------------------------------------------------------------
; Module Name :VESA452.asm
; Program Name :VESA452.com
; Description :This program traps Video BIOS Fuction calls made from an
; Application program. It is a TSR(Terminate & Stay Resident)
; program.
; Date :February 26, 1990
; Version :1.0
; Programmer :Rakesh K. Jain
; Copyright (C) Chips and Technologies, Inc. 1990
;----------------------------------------------------------------------
include vesa.inc ; to include VESA structures & constants
include vesa452.inc ; 452 related stuff
;
; Code Segment Starts
;
code segment
assume cs:code, ds:code, ss:code, es:code
org 100h ;for making the program .COM type
begin :
jmp main ; jump to the initialization part
;------------------------------------------------------------------
; This routine stores BIOS Video Function Number into a Buffer
; and then calls BIOS fuction.
;------------------------------------------------------------------
VideoHandler proc near
; look for functions to be implemented here
cmp ah, VESA_FUNCTIONS
jnz VHNotVGACntlFun
; Its a VESA function
call VESAFunctions
iret
VHNotVGACntlFun:
pushf ;Push Flags to compensate for IRET
callfar
oldvect dw 0
dw 0 ;Old Video Interrupt Vector
iret
VideoHandler endp
VESAFunctions proc near
cmp al, MAX_FUNCTIONS
ja VESAFNotAValidFunction
cmp al,5 ; Window Control function
jnz @F
push cs
call near ptr SuperVGASetCPUMemWin ; This is far call
ret
@@:
pushem <es,ds,di,si,dx,cx,ax,bx> ; dont change ax, bx order
xor ah, ah
shl ax, 1 ; ax = function index
xchg ax, bx
mov bx, cs:DispatchTable[bx] ; function ptr in bx
xchg ax, bx
call ax
DirectReturn:
popem <bx,ax,cx,dx,si,di,ds,es> ; dont change ax, bx order
mov ax, cs:Status
ret
VESAFNotAValidFunction:
cmp al, 70h
jne @f
call SetChipsWindowSize
mov ax, 704fh
ret
@@:
cmp al, 71h
jne @f
call GetChipsWindowSize
mov ax, 714fh
ret
@@:
xor al, al ; function not supported
ret
VESAFunctions endp
SuperVGAInfo proc near
;
; copy our info structure
;
cld ; play it safe, don't assume things
mov ax, cs
mov ds, ax ; Set our data segment
mov si, OFFSET VGAInfo
mov cx, (SIZE VGAInfoBlock) / 2
rep movsw
IF (SIZE VGAInfoBlock) AND 1
movsb
ENDIF
if 0 ;** we assume that 82C452 presence is already been checked, when we installed this TSR
;
; Look for 82C452 (CHIPS Super VGA)
;
call ReadChipsVGAId ; Id is returned in ah
;
; if VGA is identified as Chips product then look for specific VGA
; look for Chips Id
;
cmp ah, CHIPS_ID ; is it chips Id?
jnz VGACError00 ; non Chips VGA/EGA
;
; VGA is identified as Chips VGA
;
mov ah, 80H ; open extended registers at 3d6/3d7H
call ExtRegs
call ReadVGATypeNRev
mov bl, ah ; place this info to proper reg
and ah, 0F0H ; test VGA type
cmp ah, CHIPSVGA_452
jnz VGACFNot452
;
; 82C452 is found, return success
;
endif ;**0
mov Status, SUCCESS SHL 8 + VESA_FUNCTIONS
ret
if 0 ;** Presence of 82c452 is alraedy been checked
VGACError00:
VGACFNot452:
mov Status, FAILURE SHL 8 + VESA_FUNCTIONS
ret
endif ;** 0
SuperVGAInfo endp
SuperVGAModeInfo proc near
cld ; play it safe
mov ax, cs
mov ds, ax ; Set our data segment
mov si, OFFSET ModeInfo
mov ax, cx ; VESA Mode No ****** to be changed to bx
mov dx, di ; save di in dx
mov bx, es ; save es in bx
call VESAToInternalMode
call InternalModeToIndex
mov ax, di ; al = Mode Index
mov ah, SIZE ModeInfoBlock
mul ah ; ax = +(SIZE ModeInfoBlock)*Index
add si, ax ; si = ModeInfo+(SIZE ModeInfoBlock)*Index
mov di, dx ; restore di
mov es, bx ; restore es
mov cx, OBLG_INFO_SIZE
test [si].ModeAttributes, MA_EXT_INFO
jz @F
add cx, EXT_INFO_SIZE
@@:
push di ; save start address
rep movsb
pop di ; restore start adress
mov ax, word ptr ChipsNoOfWindows
; al = # of Windows, ah = Window Size
cmp al, 1 ; Is there only 1 windows supported
jz @F ; By default we enable only one window
mov es:[di].WinBAttributes,WIN_ATTR ; Enable second window also
cmp ah, 64 ; Is it Dual page 64K ?
jz @F ; Yes, we are all set
mov es:[di].WinBSegment, WINB_NADDR ; change selector to dual page 32K windows
@@:
mov byte ptr es:[di].WinSize, ah ; copy size of the window
mov cs:Status, SUCCESS SHL 8 + VESA_FUNCTIONS
ret
SuperVGAModeInfo endp
SuperVGASetMode proc near
mov ax, bx ; ax = VESA Mode
call VESAToInternalMode ; ax = Internal Mode (BIOS Mode)
mov bx, ax ; save internal mode
and ah, ah ; see if ah = 0
jnz SVSMError
int 10H ; call BIOS to set mode
; did BIOS set the mode ?
mov ax, 40h
mov ds, ax
mov di, 49h
and bl, NOT 80H ; Clear Not-clear-memory bit
cmp [di], bl
jnz SVSMError
;
; find out what value is to be programmed in the GR06 and XR0B to select
; proper CPU address window. We have table of these value so we have
; to compute index to the table first. There are 4 entries in the table.
; NumberOfWin SizeofWin XR0B GR06 (Low)
; 1 64 K 0 4
; 1 128K 0 0
; 2 32 K 2 4
; 2 64 K 2 0
; We assume that # of windows and windows size will always have these values
;
cmp bl, 6ah ; For all standard modes and 132 column modes
jb StandardModes ; don't bother about paging etc
mov bx, word ptr cs:ChipsNoOfWindows
; bl = # of Windows, bh = Window Size
mov cl, 6 ; # of bits to be shifted
shr bl, 1 ; 'C' if bl = 1, bl = 0/1
adc cl, 0 ; cl = 6/5
shr bh, cl ; bl = 0/1
shl bl, 1
add bl, bh
xor bh, bh ; bx = index into the table
shl bx, 1 ; each entry is one word
mov dx, 3ceh ; dx = Graphics Controller addr
mov al, 6
out dx, al
inc dx
in al, dx
and al, 11110011b ; clear memory size bits
or al, cs:WinRegTable[bx] ; GR06 value
out dx, al
mov ah, 80h ; Open extended registers
call ExtRegs
mov dx, EGA_BASE + EXTR_ADDR
mov al, 0bh
out dx, al
inc dx
in al, dx ; read current value
and al, 11111101b ; clear dual page bit
or al, cs:WinRegTable[bx+1] ; XR0B value
out dx, al
StandardModes:
mov cs:Status, SUCCESS SHL 8 + VESA_FUNCTIONS
ret
SVSMError:
mov cs:Status, FAILURE SHL 8 + VESA_FUNCTIONS
ret
SuperVGASetMode endp
SuperVGAGetMode proc near
mov ax, 0F00H
int 10H
xor ah, ah
mov bx, ax ; save this info in bx
call InternalModeToVesa
jnc @F
xchg ax, bx
@@:
pop dx ; get return addr
pop ax ; pop bx in ax *******
push bx ; push mode to be returned
push dx ;
mov cs:Status, SUCCESS SHL 8 + VESA_FUNCTIONS
ret
SuperVGAGetMode endp
SuperVGAVideoState proc near
mov ah, 1cH ; ah = BIOS function to save/restore VIDEO state
mov al, dl ; al = subfunction
push ax ; save function
push cx
test cx, VS_SUPERVGA_STATE
jz SVVSNotSuperVGA0
;
; Super VGA state
;
cmp al, VS_GET_BUFSIZE
jnz SVVSNotBufSize
;
; get buf size function
;
cmp cx, VS_SUPERVGA_STATE ; if it is SUPERVGA_STATE only
jnz @F ; save cx, ax and call BIOS
; only SUPERVGA_STATE
mov bx, SUPERVGA_SIZE
pop cx
pop ax ; restore sunfunction
jmp SVVSNotSuperVGA1 ; don't call BIOS
SVVSNotBufSize:
cmp al, VS_SAVE_STATE
jnz SVVSNotSaveState
;
; save state function
; es:bx --> pointer to buffer, bx will be updated by routine
;
call SaveSuperVGAState
jmp short @F
SVVSNotSaveState:
cmp al, VS_RESTORE_STATE
jnz SVVSNotRestoreState
;
; restore state function
; es:bx --> pointer to buffer, bx will be updated by routine
;
call RestoreSuperVGAState
SVVSNotRestoreState:
SVVSNotSuperVGA0:
@@:
int 10H
pop cx ; restore requested state
pop ax ; restore subfunction function
test cx, VS_SUPERVGA_STATE
jz SVVSNotSuperVGA1
; super vga function
cmp al, VS_GET_BUFSIZE ; is it GET_BUFSIZE function ?
jnz @F ; no
add bx, SUPERVGA_SIZE ; add # of full block
SVVSNotSuperVGA1:
pop dx ; pop return address
pop ax ; pop bx in ax *******
push bx ; put bx on stack
push dx ; push new address
@@:
mov cs:Status, SUCCESS SHL 8 + VESA_FUNCTIONS
ret
SuperVGAVideoState endp
SuperVGASetCPUMemWin proc far
cmp bh,01
je SuperVGAMapVideoMem
push dx ; save page
mov ah, 80h
call ExtRegs
pop dx ; restore page
mov ah, dl ; ah = page #
mov al, PAGE_REG_A
and bl, 01 ; consider only LSB
add al, bl
;** push dx ; Save dx
mov dx, EGA_BASE+EXTR_ADDR
out dx, ax
mov cs:Status, SUCCESS SHL 8 + VESA_FUNCTIONS
;** pop dx ; Restore dx
ret
SuperVGASetCPUMemWin endp
SuperVGAMapVideoMem proc near
mov ah, 80h
call ExtRegs
mov al, PAGE_REG_A
and bl, 01 ; consider only LSB
add al, bl
mov dx, EGA_BASE+EXTR_ADDR
out dx,al
inc dx
in al,dx
xor ah,ah
mov dx,ax
mov cs:Status, SUCCESS SHL 8 + VESA_FUNCTIONS
ret
SuperVGAMapVideoMem endp
SuperVGADACCntl proc near
ret
SuperVGADACCntl endp
;----------------------------------------------------------------------
; This routine saves extended registers into a buffer.
; 2 bytes per register are saved. High byte contains reg value and low
; byte reg index.
;
; Entry:
; es:bx --> pointer to buffer (2 bytes per extended reg)
; Destroyed:
; ds, si, di, dx & flags
; Preseeved:
; ax, cx, and bx updated, to be used by BIOS later
;-----------------------------------------------------------------------
SaveSuperVGAState proc near
push cx
push ax ; save important regs
mov ah, 80H
call ExtRegs ; Open extended registers
mov ax, cs
mov ds, ax ; ds = cs (our data seg)
mov si, OFFSET ExtRegIndex ; pointer to ext reg indices table
mov di, bx ; buffer pointer
mov dx, EGA_BASE+EXTR_ADDR
mov cx, NEXTREGS ; # of ext regs to be saved
SAVSLoop:
lodsb ; load ext reg index in al
mov ah, al ; ah = al = index
out dx, al ; index the port
inc dx ; dx = data port (3d7)
in al, dx ; read value
dec dx ; dx = address port
xchg al, ah ; ah = value, al = index
stosw ; store it
loop SAVSLoop ; do till all regs are over
add bx, 2*NEXTREGS ; increment pointer for BIOS fuction
pop ax
pop cx ; restore important regs
ret
SaveSuperVGAState endp
;----------------------------------------------------------------------
; This routine restores extended registers from user buffer
; Entry:
; es:bx --> pointer to buffer (2 bytes per extended reg)
; Destroyed:
; ds, si, dx & flags
; Preseeved:
; ax, cx, and bx updated, to be used by BIOS later
;-----------------------------------------------------------------------
RestoreSuperVGAState proc near
push cx
push ax ; save important regs
mov ah, 80H
call ExtRegs ; Open extended registers
mov ax, es
mov ds, ax
mov si, bx ; ds:si --> pointer to save regs
mov dx, EGA_BASE+EXTR_ADDR
mov cx, NEXTREGS
RSVSLoop:
lodsw
out dx, ax ; output value to appropriate port
loop RSVSLoop
add bx, 2*NEXTREGS ; increment pointer for BIOS fuction
pop ax ; restore important regs
pop cx
ret
RestoreSuperVGAState endp
;---------------------------------------------------------------------
; This routine converts user given mode into a 82C452 BIOS mode number
; Entry:
; ax = VESA mode
; Exit:
; if 'C' is clear, ax = internal mode (60H to 7BH)
; else Error... ax not changed
; Destroyed:
; es, cx, di
;----------------------------------------------------------------------
VESAToInternalMode proc near
mov di, cs
mov es, di
mov di, OFFSET VESAModeTable
mov cx, NMODES
push ax
and ah, NOT 80h ; clear memory-not-clear bit
repnz scasw ; scan til value matches
jnz VESATIMInvalidMode
sub di, OFFSET VESAModeTable
shr di, 1 ; Offset to byte table
mov al, cs:InternalModeTable[di-1]
xor ah, ah
pop cx ; pop the original mode number
and ch,80h ; extract 15th bit
or al,ch ; and OR it to mode number
clc ; cheer on success
ret
VESATIMInvalidMode:
pop cx ; balance the stack
stc ; weep on failuare
ret
VESAToInternalMode endp
;---------------------------------------------------------------------
; This routine converts internal mode into a VESA given mode number
; Entry:
; ax = internal mode
; Exit:
; if 'C' is clear, ax = internal mode (60H to 7BH)
; else Error...
; Destroyed:
; es, cx, di
;----------------------------------------------------------------------
InternalModeToVESA proc near
mov di, cs
mov es, di
mov di, OFFSET InternalModeTable
mov cx, NMODES
repnz scasb ; scan til value matches
jnz IMTVESAInvalidMode
sub di, OFFSET InternalModeTable
shl di, 1 ; Offset to word table
mov al, cs:InternalModeTable[di-2]
clc ; cheer on success
ret
IMTVESAInvalidMode:
stc ; weep on failuare
ret
InternalModeToVESA endp
;---------------------------------------------------------------------
; This routine converts an Internal mode into an index (0 to NMODES-1)
; Entry:
; ax = Internal mode
; Exit:
; if 'C' is clear, di = index of internal mode table (0 to NMODES -1)
; else Error...
; Destroyed:
; es, cx, di
;----------------------------------------------------------------------
InternalModeToIndex proc near
mov di, cs
mov es, di
mov di, OFFSET InternalModeTable
mov cx, NMODES
repnz scasb ; scan til value matches
jnz IMTIInvalidMode
sub di, OFFSET InternalModeTable+1
clc ; cheer on success
ret
IMTIInvalidMode:
stc ; weep on failuare
ret
InternalModeToIndex endp
ExtRegs proc near
;---------------------------------------------------------------------
; Opens extended register space at 3d6/3d7H
; Entry:
; ah = 80/40H to open extended register space at 3d6/3b6H
; ah = 0 to close extended register space
; Destroyed:
; ax, dx
; Output:
; None
;---------------------------------------------------------------------
; place VGA in setup mode
mov dx, cs:SetupAddr
mov al, byte ptr cs:SetupData[0] ; value to place vga in setup mode
cli ; Disable interrupts
out dx, al
; enable/disable extended registers
push dx ; save setup address
mov dx, 103h
mov al, ah ; open extended register at 3d6/3d7H
out dx, al
pop dx ; restore setup address
; take VGA out of setup mode
mov al, byte ptr cs:SetupData[1] ; value to take vga out of setup mode
out dx, al
sti ; Enable interrupt
ret
ExtRegs endp
;------------------------------------------------------------------------
SetChipsWindowSize proc near
mov word ptr cs:ChipsNoOfWindows, dx
;** .ERRNZ OFFSET ChipsWindowSize - OFFSET ChipsNoOfWindows -1
ret
SetChipsWindowSize endp
;------------------------------------------------------------------------
GetChipsWindowSize proc near
mov dx, word ptr cs:ChipsNoOfWindows
;** .ERRNZ OFFSET ChipsWindowSize - OFFSET ChipsNoOfWindows -1
ret
GetChipsWindowSize endp
;---------------------------------------------------------------------
; Resident Data Declaration
;---------------------------------------------------------------------
marker db 'VESA for 82C452'
marklen EQU $ - marker
msg1 db 'VESA Program already installed', NL, EOS
DispatchTable dw OFFSET SuperVGAInfo
dw OFFSET SuperVGAModeInfo
dw OFFSET SuperVGASetMode
dw OFFSET SuperVGAGetMode
dw OFFSET SuperVGAVideoState
dw OFFSET SuperVGASetCPUMemWin
dw OFFSET SuperVGAMapVideoMem
dw OFFSET SuperVGADACCntl
Status dw 0 ; status of every call
SetupAddr dw 46e8h ; setup port for PC/AT
SetupData dw 0e1eh ; setup data for PC/AT
ChipsNoOfWindows db 1 ;** for two undocumented functions
ChipsWindowSize db 64 ;** for two undocumented functions
.ERRNZ OFFSET ChipsWindowSize - ChipsNoOfWindows -1 ; don't break sequence
WinRegTable db 04, 00 ; values for GR06 bit 3,2 and XR0B bit 1
db 00, 00
db 04, 02
db 00, 02
ExtRegIndex LABEL BYTE
defextregs <02H,05H,0AH,0BH,0CH,0DH,0EH,10H,11H,20H,21H,22H,23H,24H>
defextregs <28H,2BH,30H,31H,32H,33H,34H,35H,36H,37H,38H,39H,3AH>
;;****** db XR04,XR06,XR14,XR15,XR16,XR18,XR19,XR1A,XR1B,XR1C,XR1D,XR1E
NEXTREGS equ $ - ExtRegIndex
IF (2*NEXTREGS) AND BLOCKSIZE -1
PARTIAL_BLOCK equ 1 ; if partial block add one more block
ELSE
PARTIAL_BLOCK equ 0
ENDIF
SUPERVGA_SIZE equ (((2*NEXTREGS)/BLOCKSIZE) + PARTIAL_BLOCK)
VESAModeTable dw 102h,71h,104h,100h,101h,7Ah,END_OF_MODES
; This table hold VESA mode numbers.
; This the one which is passed to the user in VGAInfo
VESAModeTableLen equ ($ - VESAModeTable -2)/2
InternalModeTable db 70h,71h,72h,78h,79h,7Ah
; This table holds internal modes corresponding to VESA modes.
; Like VESA mode 100 is mapped to internal (BIOS) mode 70H
; If any new VESA mode is added, the Internal Mode Table
; should be reordered so that new VESA mode and Internal
; Mode are in same position in the respective tables and
; also parameter sequence in InitModeInfo macro should be
; changed correspondingly
NMODES equ $ - InternalModeTable
.ERRNZ NMODES - VESAModeTableLen
; give error on size missmatch of two tables
ModeInfo label ModeInfoBlock
InitModeInfo <<Mode70>,<Mode71>,<Mode72>,<Mode78>,<Mode79>,<Mode7A>>
VGAInfo VGAInfoBlock <> ; use default values
ChipsString db 'CHIPS 82C452, the Super VGA', 0
ProgSize label word ;Create Label to get Size of the Program
;----------------------------------------------------------------------
; ************************ End of Resident Code *********************
;----------------------------------------------------------------------
main proc near
getvector VideoInt
mov ax, OFFSET marker - OFFSET VideoHandler
mov cx, marklen
mov di, bx
add di, ax ; es:[di] Pointer to Previous Marker String
mov si, OFFSET marker
cld
repe cmpsb
jcxz AlreadyLoaded
jmp short start
AlreadyLoaded :
print msg1
int 20h ;Exit to DOS
start :
;
; Look for 82C452 VGA
;
call ReadChipsVGAId
cmp ah, CHIPS_ID ; is it chips Id?
jnz error_exit ; Chis VGA is not present
mov ah, 80h ; open extended reg at 3d6/3d7
call ExtRegs
call ReadVGATypeNRev
and ah, 0f0h ; extract upper nibble
cmp ah, CHIPSVGA_452
jz ChipsVGAPresent ; Chips 82C452 is present
error_exit:
print msg4
int 20h ;Exit to DOS
ChipsVGAPresent: ; our VGA is present
print msg0 ;Initial Message
;
; Look for command line parameter for monitor
; es, ds, and cs are same
;
mov ax, cs
mov es, ax ; es = ds = cs
mov di, 80H ; offset of command trail area
mov cl, [di] ; al = # of chars in command trail
and cl, cl
jz MainDefaultMonitor
inc di
mov al, '+' ; For MultiSync + monitor
xor ch, ch ; cx = n chars
repnz scasb ; read first char
jnz MainDefaultMonitor
;
; MultiSync Plus Monitor
;
inc monitor
print msg3
.errnz MULTISYNC_PLUS -1
MainDefaultMonitor: ; by default 'monitor' is 0 for MultiSync II
;
; Initialize VGAInfo structure
;
mov si, OFFSET VGAInfo
mov ax, OFFSET ChipsString
mov WORD PTR [si].OEMString, ax
mov WORD PTR [si].OEMString+2, ds
mov ax, OFFSET VESAModeTable
mov WORD PTR [si].VideoModePtr, ax
mov WORD PTR [si].VideoModePtr+2, ds
;
; Initialize ModeInfo structure tables
;
mov cx, NMODES ; # of modes table support
mov si, OFFSET ModeInfo
xor bx, bx ; bx = index
mov dl, monitor ; monitor type
MainModeInfoLoop:
mov al, InternalModeTable[bx] ; al = internal mode
; according to table
cmp dl, MULTISYNC_PLUS
jz MainMultiSyncPlus
;
; not a MultiSync Plus monitor. Disable Mode 71H, & 72H
;
cmp al, 71H
jb MainCommon ; Not 960x720 1024x768 16 col mode
cmp al, 72H
ja MainCommon ; if(mode > 72H)
;
; mode 71H & 72H can not be handled by MultiSyncII. Disable them.
;
and [si].ModeAttributes, NOT MA_HW_SUPP
jmp short MainCommon ; done
;** jmp short @F ; do it down
MainMultiSyncPlus: ; all modes are supported
;** cmp al, 70H
;** jz @F ; MultiSyncPlus can not handle at 40MHz
;** cmp al, 79H
;** jbe MainCommon
;**;
;**; modes 70, 7a, 7b can not be handled by MultiSyncPlus. Diasable them.
;**;
;**@@:
;** and [si].ModeAttributes, NOT MA_BIOS_INIT
MainCommon:
mov ax, OFFSET SuperVGASetCPUMemWin
mov WORD PTR [si].WinFuncPtr, ax
mov WORD PTR [si].WinFuncPtr+2, ds
inc bx ; increase index
add si, SIZE ModeInfoBlock
loop MainModeInfoLoop
;
; Install interrupt handler
;
call ChgVdoVector ;Save Current Video Vector and
;Change it to New Handler
;
; Terminate But Stay Resident
;
mov ah, TSR ;TSR Function Number
mov al, 0 ;Return code
mov dx, OFFSET ProgSize ;Size of the program in bytes
mov cl, 4
shr dx, cl ;dx = ProgSize/16 (Size in Paragraphs)
inc dx
int 21h
main endp
;------------------------------------------------------------------
; This routine saves current Video Vector
; and initialize it with New Video Interrupt Handler
;------------------------------------------------------------------
ChgVdoVector proc near
getvector VideoInt
mov oldvect, bx
mov oldvect+2, es ;Save Old Vector
; Set Video Vector to New Handler
setvector VideoInt, VideoHandler
ret
ChgVdoVector endp
ReadChipsVGAId proc near
;---------------------------------------------------------------------
; read chips global Id register
; Entry:
; None
; Destroyed:
; ax, dx
; Output:
; ah = CHIPS Id (0A5H if successful)
;----------------------------------------------------------------------
; Find which machine Microchannel/AT
mov ah,0c0h ; Find out system configuration
int 15H ; Microchannel or AT
mov dx,46e8h ; Assume VGA Setup Port for PC/AT
mov ax,0e1eh ; al = 1eH to put VGA in Setup Mode
; ah = 0eH to place VGA in normal mode
jc @F ; call not successful, assume PC/AT
test byte ptr es:[bx+5],2 ; Is it Microchannel Machine ?
jz @F ; No, We already have proper values
mov dx,094h ; Yes, Microchannel values
mov ax,0ffdfh ; al = df, ah = ff for microchannel
@@:
mov cs:SetupAddr, dx ; save it for use in GrOpenExtRegs
mov cs:SetupData, ax ; save it for use in GrOpenExtRegs
cli ; Don't interrupt while doing serious business
out dx,al
push dx ; save port
mov dx,104h ; CHIPS ID Port
in al,dx
pop dx ; CHIPS VGA Setup Port
xchg al,ah ; Save ID in ah, al = value to get outof setup port
out dx,al
sti ; Serious business is over
ret
ReadChipsVGAId endp
ReadVGATypeNRev proc near
;----------------------------------------------------------------------
; read chip type and rev no
; Entry:
; None
; Destroyed:
; ax, dx
; Output:
; ah = Chips type and revision no
;----------------------------------------------------------------------
mov dx, EGA_BASE+EXTR_ADDR
xor al, al ; al = XR00
out dx, al
inc dx
in al, dx ; al = chips type and rev no
mov ah, al ; return the info in ah
ret
ReadVGATypeNRev endp
;----------------------------------------------------------------------
; Transient data declaration
;----------------------------------------------------------------------
msg0 db 'VESA452 - VESA BIOS Extension Version 1.0 for 82C452 Super VGA Controller', NL
db 'Release Version 0.2',NL,NL
db 'Copyright (C) Chips and Technologies, Inc. 1990. ',NL
db NL
db 'A "+" on command line enables all the modes supported by the video BIOS.',NL
db 'Default is NEC MultiSync II or equivalent monitor supported modes.',NL
db NL,EOS
msg3 db 'Monitor supported is MultiSync Plus',NL,EOS
msg4 db 'Chips and Technologies Super VGA 82C452 is not present.',NL
db TAB, 'VESA driver is not installed.',NL,EOS
monitor db MULTISYNC_II ; default for MultiSync II
code ends
end begin