; Tweaked VGA (modeX)
.data
modex_size dd 0 ;size of each plane (physical size in RAM)
modex_plane_wr db 1 ;current plane # (if the plane # is altered in an
; IRQ handler it must be returned to this plane #
; before exiting IRQ handler)
modex_plane_rd db 1 ;current plane # (if the plane # is altered in an
; IRQ handler it must be returned to this plane #
; before exiting IRQ handler)
mx_mode db 0 ;last successful modex_getmode()
vga_ADDR_HIGH equ 0ch ;Index of Start Address High reg in CRTC
vga_ADDR_LOW equ 0dh ; Low
vga_CRTC_OFFSET equ 13h ; CRTC offset register index
vga_MAP_MASK equ 02h ;index in SC of Map Mask register
vga_READ_MAP equ 04h ;index in GC of the Read Map register
vga_AC_INDEX equ 03c0h ;Attribute controller index register
vga_MISC_OUTPUT equ 03c2h ;Miscellaneous Output register
vga_SC_INDEX equ 03c4h ;Sequence Controller Index
vga_GC_INDEX equ 03ceh ;Graphics controller Index
vga_CRTC_INDEX equ 03d4h ;CRT Controller Index
vga_DAC_READ_INDEX equ 03c7h ; write color #
vga_DAC_WRITE_INDEX equ 03c8h ; write color #
vga_DAC_DATA equ 03c9h ; write/read color #s (RGB)
vga_INPUT_STATUS_0 equ 03dah ;Input status 0 register
vga_PEL_PANNING equ 13h ; Pel panning register index in AC
.data
;data for modes
vga_X320Y200 label word
db 0e3h ; dot clock
db 02 ; Number of CRTC Registers to update
dw 00014h ; turn off dword mode
dw 0e317h ; turn on byte mode
dw 320 ; width
dw 200 ; height
vga_X320Y240 label word
db 0e3h ; dot clock
db 10 ; Number of CRTC Registers to update
dw 00d06h ; vertical total
dw 03e07h ; overflow (bit 8 of vertical counts)
dw 04109h ; cell height (2 to double-scan)
dw 0ea10h ; v sync start
dw 0ac11h ; v sync end and protect cr0-cr7
dw 0df12h ; vertical displayed
dw 00014h ; turn off dword mode
dw 0e715h ; v blank start
dw 00616h ; v blank end
dw 0e317h ; turn on byte mode
dw 320 ; width
dw 240 ; height
vga_X360Y200 label word
db 0e7h ; dot clock
db 08 ; Number of CRTC Registers to update
dw 06b00h ; horz total
dw 05901h ; horz displayed
dw 05a02h ; start horz blanking
dw 08e03h ; end horz blanking
dw 05e04h ; start h sync
dw 08a05h ; end h sync
dw 00014h ; turn off dword mode
dw 0e317h ; turn on byte mode
dw 360 ; width
dw 200 ; height
vga_X360Y240 label word
db 0e7h ; dot clock
db 17 ; Number of CRTC Registers to update
dw 06b00h ; horz total
dw 05901h ; horz displayed
dw 05a02h ; start horz blanking
dw 08e03h ; end horz blanking
dw 05e04h ; start h sync
dw 08a05h ; end h sync
dw 00d06h ; vertical total
dw 03e07h ; overflow (bit 8 of vertical counts)
dw 04109h ; cell height (2 to double-scan)
dw 0ea10h ; v sync start
dw 0ac11h ; v sync end and protect cr0-cr7
dw 0df12h ; vertical displayed
dw 02d13h ; offset;
dw 00014h ; turn off dword mode
dw 0e715h ; v blank start
dw 00616h ; v blank end
dw 0e317h ; turn on byte mode
dw 360
dw 240
vga_X376Y282 label word
db 0e7h
db 18
dw 06e00h ; horz total
dw 05d01h ; horz displayed
dw 05e02h ; start horz blanking
dw 09103h ; end horz blanking
dw 06204h ; start h sync
dw 08f05h ; end h sync
dw 06206h ; vertical total
dw 0f007h ; overflow
dw 06109h ; cell height
dw 0310fh ;
dw 03710h ; v sync start
dw 08911h ; v sync end and protect cr0-cr7
dw 03312h ; vertical displayed
dw 02f13h ; offset
dw 00014h ; turn off dword mode
dw 03c15h ; v blank start
dw 05c16h ; v blank end
dw 0e317h ; turn on byte mode
dw 376
dw 564
vga_X320Y400 label word
db 0e3h ; dot clock
db 03 ; Number of CRTC Registers to update
dw 04009h ; cell height
dw 00014h ; turn off dword mode
dw 0e317h ; turn on byte mode
dw 320 ; width
dw 400 ; height
vga_X320Y480 label word
db 0e3h ; dotclock
db 10 ; Number of CRTC Registers to update
dw 00d06h ; vertical total
dw 03e07h ; overflow (bit 8 of vertical counts)
dw 04009h ; cell height (2 to double-scan)
dw 0ea10h ; v sync start
dw 0ac11h ; v sync end and protect cr0-cr7
dw 0df12h ; vertical displayed
dw 00014h ; turn off dword mode
dw 0e715h ; v blank start
dw 00616h ; v blank end
dw 0e317h ; turn on byte mode
dw 320 ; width
dw 480 ; height
vga_X360Y400 label word
db 0e7h ; dot clock
db 09 ; Number of CRTC Registers to update
dw 06b00h ; horz total
dw 05901h ; horz displayed
dw 05a02h ; start horz blanking
dw 08e03h ; end horz blanking
dw 05e04h ; start h sync
dw 08a05h ; end h sync
dw 04009h ; cell height
dw 00014h ; turn off dword mode
dw 0e317h ; turn on byte mode
dw 360 ; width
dw 400 ; height
vga_X360Y480 label word
db 0e7h
db 17
dw 06b00h ; horz total
dw 05901h ; horz displayed
dw 05a02h ; start horz blanking
dw 08e03h ; end horz blanking
dw 05e04h ; start h sync
dw 08a05h ; end h sync
dw 00d06h ; vertical total
dw 03e07h ; overflow
dw 04009h ; cell height
dw 0ea10h ; v sync start
dw 0ac11h ; v sync end and protect cr0-cr7
dw 0df12h ; vertical displayed
dw 02d13h ; offset
dw 00014h ; turn off dword mode
dw 0e715h ; v blank start
dw 00616h ; v blank end
dw 0e317h ; turn on byte mode
dw 360
dw 480
vga_X360Y360 label word
db 0e7h
db 15
dw 06b00h ; horz total
dw 05901h ; horz displayed
dw 05a02h ; start horz blanking
dw 08e03h ; end horz blanking
dw 05e04h ; start h sync
dw 08a05h ; end h sync
dw 04009h ; cell height
dw 08810h ; v sync start
dw 08511h ; v sync end and protect cr0-cr7
dw 06712h ; vertical displayed
dw 02d13h ; offset
dw 00014h ; turn off dword mode
dw 06d15h ; v blank start
dw 0ba16h ; v blank end
dw 0e317h ; turn on byte mode
dw 360
dw 360
vga_X376Y308 label word
db 0e7h
db 18
dw 06e00h ; horz total
dw 05d01h ; horz displayed
dw 05e02h ; start horz blanking
dw 09103h ; end horz blanking
dw 06204h ; start h sync
dw 08f05h ; end h sync
dw 06206h ; vertical total
dw 00f07h ; overflow
dw 04009h ;
dw 0310fh ;
dw 03710h ; v sync start
dw 08911h ; v sync end and protect cr0-cr7
dw 03312h ; vertical displayed
dw 02f13h ; offset
dw 00014h ; turn off dword mode
dw 03c15h ; v blank start
dw 05c16h ; v blank end
dw 0e317h ; turn on byte mode
dw 376
dw 308
vga_X376Y564 label word
db 0e7h
db 18
dw 06e00h ; horz total
dw 05d01h ; horz displayed
dw 05e02h ; start horz blanking
dw 09103h ; end horz blanking
dw 06204h ; start h sync
dw 08f05h ; end h sync
dw 06206h ; vertical total
dw 0f007h ; overflow
dw 06009h ;
dw 0310fh ;
dw 03710h ; v sync start
dw 08911h ; v sync end and protect cr0-cr7
dw 03312h ; vertical displayed
dw 02f13h ; offset
dw 00014h ; turn off dword mode
dw 03c15h ; v blank start
dw 05c16h ; v blank end
dw 0e317h ; turn on byte mode
dw 376
dw 564
vga_LAST_X_MODE equ 11
vga_ModeTable label byte ; Mode X tweak table # pages
dd offset vga_X320Y200 ;mode # 0 4
dd offset vga_X320Y240 ;mode # 1 3
dd offset vga_X360Y200 ;mode # 2 2
dd offset vga_X360Y240 ;mode # 3 3
dd offset vga_X376Y282 ;mode # 4 2
dd offset vga_X320Y400 ;mode # 5 2
dd offset vga_X320Y480 ;mode # 6 1
dd offset vga_X360Y400 ;mode # 7 1
dd offset vga_X360Y480 ;mode # 8 1
dd offset vga_X360Y360 ;mode # 9 2 cool!
dd offset vga_X376Y308 ;mode # 10 2
dd offset vga_X376Y564 ;mode # 11 1
dd 0 ;end of list
.code
modex_getmode proc private,x:word,y:word
;does NOT preserve regs
mov esi,offset vga_ModeTable
mov cl,0 ;Mode #
mov bx,x
mov dx,y
mov getmode_bpsl,bx
xor eax,eax
top:
cmp [esi],dptr 0
jz bad
mov edi,[esi] ; FIX : v2.06 Beta #2
inc edi ;This whole x/y checker has been fixed
mov al,[edi] ;it twas not even closely working after these
inc edi ;grafix libs have been modified greatly in v2.02
shl al,1
add edi,eax
cmp bx,[edi]
jnz nomatch
cmp dx,[edi+2]
jnz nomatch
mov mx_mode,cl
xor eax,eax
ret
nomatch:
inc cl
add esi,4
jmp top
bad:
mov eax,ERROR
ret
modex_getmode endp
modex_setmode proc private
cmp mx_mode,vga_LAST_X_MODE
jbe @f
mov eax,ERROR
ret
@@:
mov ax,13h ; let the BIOS set standard 256-color
int 10h ; mode (320x200 linear)
mov dx,vga_SC_INDEX
mov ax,0604h
out dx,ax ; enable chain4 mode (now non-linear)
mov ax,0100h
out dx,ax ; synchronous reset while setting Misc
; Output for safety, even though clock
; unchanged
movzx ecx,mx_mode
mov ebx,offset vga_ModeTable
shl ecx,2
add ebx,ecx
mov esi,[ebx]
lodsb
mov dx,vga_MISC_OUTPUT
out dx,al ; select the dot clock and Horiz
mov dx,vga_SC_INDEX
mov ax,0300h
out dx,ax ; undo reset (restart sequencer)
mov dx,vga_CRTC_INDEX ; reprogram the CRT Controller
mov al,11h ; VSync End reg contains register write
out dx,al ; protect bit
inc dx ; CRT Controller Data register
in al,dx ; get current VSync End register setting
and al,07fh ; remove write protect on various
out dx,al ; CRTC registers
dec dx ; CRT Controller Index
xor cx,cx
lodsb
mov cl,al
@@:
lodsw ; get the next CRT Index/Data pair
out dx,ax ; set the next CRT Index/Data pair
loop @b
mov dx,vga_SC_INDEX
mov ax,0f02h
out dx,ax ; enable writes to all four planes
;set logical width to physical width
mov dx,vga_CRTC_INDEX
mov al,vga_CRTC_OFFSET
out dx,al
inc dx
lodsw
xor ebx,ebx
mov bx,ax
shr ax,3
out dx,al ;sets width (320,360, etc.)
;calculate modex_size for coping RAM to VRAM
shr bx,2
lodsw
mov wptr[_v_y],ax
xor dx,dx
mul bx
movzx eax,ax
mov modex_size,eax ;size of each plane
xor ax,ax
mov ecx,8000h
mov edi,0a0000h
rep stosw
xor eax,eax
ret ;all done!
modex_setmode endp
modex_offset proc,off:word
mov ax,off
mov bh,al
mov ch,ah
mov bl,vga_ADDR_LOW
mov cl,vga_ADDR_HIGH
mov dx,vga_INPUT_STATUS_0 ;Wait for trailing edge of Vsync pulse
@@:
in al,dx
test al,01h
jnz @b
mov dx,vga_CRTC_INDEX
mov ax,bx
out dx,ax ;start address low
mov ax,cx
out dx,ax ;start address high
; Now wait for vertical sync, so the other page will be invisible when
; we start drawing to it.
call g_waitvsync
ret
modex_offset endp