home *** CD-ROM | disk | FTP | other *** search
- TITLE VGAMove - intercept INT 10 mode change and reposition VGA display
- PAGE 55,132
-
- ; Version 1.0 Copyright (c) May 8, 1991
- ; by R. W. Babcock and WSS Division of DDC.
-
- ; ***************************************************************************
- ; Warning: this is a memory resident routine which stuffs new values into the
- ; VGA registers which control sweep and sync signals to your monitor. Bad
- ; values in these registers can make your monitor very unhappy, possibly
- ; even to the point of causing permanent hardware damage. Don't even think
- ; about using this routine until you have
-
- ; 1. Modified the accompanying VGAPOS.C program to work with your
- ; video board.
- ; 2. Used VGAPOS to generate a table of default and changed register
- ; values.
- ; 3. Carefully entered those values into the adjustment table in this
- ; routine and reassembled.
- ; 4. Thought about how to react if your monitor starts objecting (reset,
- ; turn off monitor power, etc.)
- ; ***************************************************************************
-
- ; Unlimited non-commercial use authorized. However, the author specifically
- ; disclaims any responsibility for any consequences. This program is
- ; distributed only as source code which you may, and if fact probabily must,
- ; modify for your configuration.
-
- ; Note: this program must be converted to a .COM file with EXE2BIN.
- ; Expect an warning message from LINK about no stack segment, or use
- ; TLINK to make a COM file directly.
-
- ; Robert W. Babcock
- ; WSS Division of DDC
- ; 4 Reeves Road
- ; Bedford, MA 01730
- ; 617-275-1183
-
- CR equ 13
- LF equ 10
-
- ; CRTC address register, lower byte (upper is 3)
-
- COLOR equ 0d4h
- MONO equ 0b4h
-
- ; CRTC register indexes, note SHR is an instruction,
- ; so use SHR_I to avoid confusion
-
- HT equ 0
- SHB equ 2
- EHB equ 3
- SHR_I equ 4
- EHR equ 5
- VRS equ 10h
- EVR equ 11h
- VBS equ 15h
- VBE equ 16h
-
- vga_seg segment para public 'code'
- assume cs:vga_seg,ds:nothing
- org 100h
-
- vgamove:
- jmp install
-
- ; this is the replacement interrupt 10h handler
-
- int10h: jmp short ovrid
- db 'VGAMove' ; this string marks previous install
- old10 dd ? ; save old int 10h handler address
- int10_a dw ? ; storage for ax returned by int 10h
-
- ; careful here, some int 10h functions return information in AX which must
- ; be preserved, and some functions seem to result in recursive interrupt calls,
- ; so static storage could be used twice.
-
- ovrid: push ax
- pushf ; preserve flags (for simulated interrupt)
- call cs:old10 ; simulate old interrupt
- mov cs:int10_a,ax ; save int 10h return value
- pop ax
-
- ; The following few lines of code recognize whether the int 10h call was for
- ; a mode change. It assumes that all mode changes are done by setting ah=0,
- ; al=mode number. I know that this is wrong for the VEGA VGA; it's probably
- ; wrong for some other boards as well.
-
- or ah,ah
- jz was_mode_change
- mov ax,int10_a
- iret
-
- was_mode_change:
- push bx
- push cx
- push dx
- push ds
-
- push cs
- pop ds
- assume ds:vga_seg
-
- mov bx,offset adjust_table
- search_table:
- cmp byte ptr [bx],0ffh
- je not_in_table
- cmp al,[bx]
- je found_in_table
- skip_table_data:
- add bx,2
- cmp byte ptr [bx],0ffh
- jne skip_table_data
- inc bx
- jmp short search_table
-
- found_in_table:
- mov dh,3 ; half of CRTC address
- inc bx
- mov dl,[bx] ; b4 for mono mode, d4 for color
-
- ; The BIOS state of the bit in the end horizontal retrace register which
- ; enables access to the lower 7 CRTC registers and the state of the bit in
- ; the end horizontal blanking register which enables access to the vertical
- ; retrace registers need to be saved for later restoration.
-
- mov al,EVR
- out dx,al
- inc dx
- in al,dx
- and al,80h
- mov cl,al ; EVR bit saved in cl
- dec dx
-
- mov al,EHB
- out dx,al
- inc dx
- in al,dx
- and al,80h
- mov ch,al ; EHB bit saved in ch
- dec dx
-
- register_adjust_loop:
- inc bx
- cmp byte ptr [bx],0ffh
- je adjustments_done
-
- ; enable access to lower 7 CRTC registers
-
- mov al,EVR
- out dx,al
- inc dx
- in al,dx
- and al,7fh
- out dx,al
- dec dx
-
- ; enable access to vertical retrace CRTC registers
-
- mov al,EHB
- out dx,al
- inc dx
- in al,dx
- or al,80h
- out dx,al
- dec dx
-
- mov al,[bx] ; register to adjust
- out dx,al
- inc dx
- inc bx
- mov al,[bx] ; new value
- out dx,al
- dec dx ; register select address
- jmp register_adjust_loop
-
- ; Any adjustments are completed, restore the BIOS state of the bits which
- ; protect VGA registers from accidental modification.
-
- adjustments_done:
-
- mov al,EVR
- out dx,al
- inc dx
- in al,dx
- and al,80h
- or al,cl ; EVR bit saved in cl
- dec dx
-
- mov al,EHB
- out dx,al
- inc dx
- in al,dx
- and al,80h
- or al,ch ; EHB bit was saved in ch
- dec dx
-
- ; set border color to blue
-
- add dl,6
- in al,dx
- mov dx,3c0h
- mov al,31h
- out dx,al
- mov al,1
- out dx,al
-
- not_in_table:
- pop ds
- pop dx
- pop cx
- pop bx
- mov ax,int10_a
- iret
-
- ; Table of adjustments.
- ; First value is mode. If no changes are needed for a mode,
- ; no entry should be made.
- ; Second value is 0xb4 for mono modes, 0xd4 for color modes.
- ; Following are pairs of CRTC register index and value to put into
- ; register. End list of pairs with a CRTC index of 0ffh (and no
- ; corresponding value).
- ; End the table with a mode of 0ffh (I hope no board uses such a mode).
-
- ; Values in this table are the ones I found appropriate for an ATI VGA Wonder
- ; driving a Princeton Ultra 14 monitor. Other boards and monitors are likely
- ; to require different numbers. If nothing else, other boards will likely use
- ; different mode numbers for the super VGA modes.
-
- adjust_table db 0,COLOR, SHR_I,2ch, VRS,0a1h, 0ffh
- db 1,COLOR, SHR_I,2ch, VRS,0a2h, 0ffh
- db 2,COLOR, SHR_I,56h, VRS,0a2h, 0ffh
- db 3,COLOR, SHR_I,56h, VRS,0a2h, 0ffh
- db 4,COLOR, SHR_I,2ch, VRS,0a2h, 0ffh
- db 5,COLOR, SHR_I,2ch, VRS,0a3h, 0ffh
- db 6,COLOR, SHR_I,55h, VRS,0a3h, 0ffh
- db 7,MONO, VRS,0a2h, 0ffh
- db 0dh,COLOR, SHR_I,2ch, VRS,0a2h, 0ffh
- db 0eh,COLOR, SHR_I,55h, VRS,0a3h, 0ffh
- db 0fh,MONO, SHR_I,56h, VRS,8ah, 0ffh
- db 10h,COLOR, SHR_I,56h, VRS,89h, 0ffh
- db 11h,COLOR, SHR_I,55h, VRS,0efh, 0ffh
- db 12h,COLOR, SHR_I,55h, VRS,0f0h, 0ffh
- db 13h,COLOR, SHR_I,55h, VRS,0a2h, 0ffh
- db 23h,COLOR, EHB,81h, EHR,82h, VRS,061h, VBE,6dh, 0ffh
- db 27h,MONO, EHB,80h, EHR,82h, 0ffh
- db 33h,COLOR, EHB,81h, EHR,82h, VRS,064h, VBS,64h, VBE,6fh, 0ffh
- db 37h,MONO, EHB,81h, EHR,82h, VRS,064h, 0ffh
- db 54h,COLOR, SHB,64h, SHR_I,68h, VRS,2eh, VBS,30h, VBE,37h, 0ffh
- db 61h,COLOR, VRS,0a0h, 0ffh
- db 62h,COLOR, VRS,0edh, 0ffh
- db 63h,COLOR, SHB,64h, SHR_I,67h, VBS,2fh, VBE,37h, 0ffh
- db 65h,COLOR, EHB,8dh, SHR_I,42h, VRS,0ch, 0ffh
- db 67h,COLOR, EHB,8dh, SHR_I,42h, VRS,0ah, VBS,0bh, 0ffh
- db 0ffh ; dummy entry marking end of table
-
- ; code past this point is not permanently resident
-
- install:
- push cs ; probably not necessary
- pop ds
- mov ax,3510h
- int 21h ; get INT 10h handler address
- mov di,bx
- mov si,offset int10h
- cld
- mov cx,7
-
- ; Test for multiple installations will fail if another routine is installed
- ; which also intercepts int 10h.
-
- repe cmpsb ; see if already installed
- jne notins
- mov dx,offset dupmsg
- mov ah,9
- int 21h ; display error message
- mov ax,4c00h
- int 21h ; terminate
-
- notins: mov word ptr old10,bx ; old vector is in ES:BX
- mov word ptr old10+2,es
-
- mov dx,offset int10h
- mov ax,2510h
- int 21h ; replace INT 10h handler
-
- mov dx,offset insmsg
- mov ah,9
- int 21h ; display successful installation msg
-
- ; free environment space and zero environment segment in PSP
-
- mov ax, ds:[2Ch]
- mov es, ax
- mov ah, 49h
- int 21h
- mov word ptr ds:[2Ch],0
-
- mov dx,offset install
- int 27h ; terminate but stay resident
-
- insmsg db 'VGAMove version 1.0 by WSS Division of DDC',CR,LF
- db 'Resident portion installed$'
- dupmsg db 'VGAMove already installed$'
-
- vga_seg ends
- end vgamove
-