Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

716 lines
19 KiB

page ,132
;-----------------------------Module-Header-----------------------------;
; Module Name: MVGAXX.ASM
;
; This module contains functions for dealing with the following VGA
; 256 color (modex) modes.
;
; 320x200x8
; 320x400x8
; 320x240x8
;
; Created: 03-20-90
; Author: Todd Laney [ToddLa]
;
; 15-Dec-96 jeffno Made ScreenOffset and ScreenDisplay public so modex.c's
; new mode-set code can get at them. Also added cdwScreenWidthInDWORDS
; to enable PixBlt to operate correctly with 360x modes.
;
; Copyright (c) 1984-1995 Microsoft Corporation
;
;-----------------------------------------------------------------------;
?PLM = 1
?WIN = 0
.386
.xlist
include cmacros.inc
include mvgaxx.inc
.list
externA __A000h
; size for one 320x240x8 page (in mode X)
;-------------
; This is no longer accurate for x350 etc modex...
; turn it into a WORD and make it public so modex.c can
; set it properly.
;ScreenPageSize equ ((80 * 240 + 255) and (not 255))
sBegin Data
ScreenSel dw __A000h
;-------------------------------- Public Data ----------------------------------------
;
; The following three WORDS (ScreenOffset, ScreenDisplay and cdwScreenWidthInDWORDS
; and ScreenPageSize) MUST remain in sync with the extern declarations in modex.c
;
_ScreenOffset label word
ScreenOffset dw 0
_ScreenDisplay label word
ScreenDisplay dw 0
_cdwScreenWidthInDWORDS label word
cdwScreenWidthInDWORDS dw 0
_cbScreenPageSize label word
cbScreenPageSize dw ((80 * 240 + 255) and (not 255))
;expose these so modex.c can set 'em
public _ScreenOffset
public _ScreenDisplay
public _cdwScreenWidthInDWORDS
public _cbScreenPageSize
;
;
;-------------------------------------------------------------------------------------
sEnd Data
ifndef SEGNAME
SEGNAME equ <MODEX_TEXT>
endif
createSeg %SEGNAME, CodeSeg, word, public, CODE
sBegin CodeSeg
assumes cs,CodeSeg
assumes ds,Data
assumes es,nothing
; Manually perform "push" dword register instruction to remove warning
PUSHD macro reg
db 66h
push reg
endm
; Manually perform "pop" dword register instruction to remove warning
POPD macro reg
db 66h
pop reg
endm
;---------------------------Public-Routine------------------------------;
; FlipPage
;
; display the current draw page and select another draw page
;
; Entry:
;
; Returns:
; none
; Error Returns:
; None
; Registers Preserved:
; BP,DS,SI,DI
; Registers Destroyed:
; AX,BX,CX,DX,FLAGS
; Calls:
; none
; History:
; Wed 04-Jan-1990 13:45:58 -by- Todd Laney [ToddLa]
; Created.
;-----------------------------------------------------------------------;
assumes ds,Data
assumes es,nothing
cProc FlipPage, <NEAR, PUBLIC>, <>
cBegin
; we only program the high byte of the offset.
; so the page size must be a multiple of 256
; *** This compile-time assert can't be used anymore since cbScreenPageSize
; *** is now a static word. There are corresponding asserts in modex.c
; *** at the top of SetVGAForModeX().
;errnz <cbScreenPageSize and 255>
mov ax,ScreenOffset
mov ScreenDisplay,ax
mov al,0Ch
mov dx,CRT_INDEX
out dx,ax
; NOTE. This routine will actually do triple buffering if a page is less
; than 64k/3. We might want to revisit this if we allow apps to specify a
; dirty subrect to be copied on a flip: if they don't know the difference
; double and triple-buffered they'll get all out of sync.
mov ax,cbScreenPageSize
add ScreenOffset,ax
neg ax
cmp ScreenOffset,ax
jbe FlipPage13XExit
mov ScreenOffset,0
FlipPage13XExit:
cEnd
;---------------------------Public-Routine------------------------------;
; SetPalette
;
; setup the palette
;
; Entry:
; start - first palette index to set
; count - count of palette index's
; pPal - points to array of RGBQUADs containg colors
;
; Returns:
; None
; Error Returns:
; None
; Registers Preserved:
; BP,DS,SI,DI
; Registers Destroyed:
; AX,BX,CX,DX,FLAGS
; Calls:
; setramdac
; History:
;
; Wed 04-Jan-1990 13:45:58 -by- Todd Laney [ToddLa]
; Created.
;-----------------------------------------------------------------------;
assumes ds,nothing
assumes es,nothing
cProc SetPalette, <NEAR, PUBLIC>, <ds,si,di>
parmW start
parmW count
parmD pPal
localV pal, %(3 * 256)
cBegin
lds si,pPal
mov bx,start ; get start pal index
mov cx,count ; get count
mov ax,bx
add ax,cx
sub ax,256 ; see if the count goes beyond the end
jle @f ; No, valid range
sub cx,ax ; Yes, clip it
mov count,cx
@@:
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; convert the palette from a array of RGBQUADs (B,G,R,X) to a array of
; VGA RGBs (R>>2,G>>2,B>>2)
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
lea di,pal ; ES:DI --> pal array on stack
mov ax,ss
mov es,ax
convert_pal_loop:
lodsw ; al=blue, ah=green
mov dx,ax ; dl=blue, dh=green
lodsw ; al=red
shr al,2 ; map from 0-255 into 0-63
shr dl,2
shr dh,2
xchg al,dl
stosb ; write red
xchg dl,dh ; switch blue,green
mov ax,dx
stosw ; write green,blue
loop convert_pal_loop
lea si,pal ; DS:SI --> converted RGBs
mov ax,ss
mov ds,ax
mov cx,count ; re-load count
call setramdac ; set the physical palette
cEnd
;---------------------------------------------------------------------------
; setramdac - initialize the ramdac to the values stored in
; a color table composed of double words
;
; entry:
; bx - index to 1st palette entry
; cx - count of indices to program
; ds:si -> array of RGBs
;
; exit:
; palette has been loaded
;
; Registers destroyed:
; al,cx,dx,si
;
;---------------------------------------------------------------------------
assumes ds,nothing
assumes es,nothing
public setramdac
setramdac proc near
mov ax,bx
mov dx,3c8h ;Color palette write mode index reg.
out dx,al
mov dx,3c9h ;Color palette data reg.
mov bx,cx ;CX *= 3
add cx,cx ;
add cx,bx ;
if 0
rep outsb ;Set the palette all at once!
else
@@: lodsb
out dx,al
pause
loop @b
endif
ret
setramdac endp
;---------------------------Public-Routine------------------------------;
; PixBlt
;
; copy a bitmap to the screen
;
; Entry:
; x - (x,y) pos of lower left of rect
; y
; xExt - width and height of rect
; yExt
; pBits - pointer to bits
; BitsOffset - pointer offset to start at.
; WidthBytes - width of a bitmap scan
;
; IMPORTANT: SEE WIDTH RESTRICTIONS AS DOCUMENTED WITHIN ROUTINE
; Note reference to cdwScreenWidthInDWORDS.
;
; Returns:
; none
; Error Returns:
; None
; Registers Preserved:
; BP,DS,SI,DI
; Registers Destroyed:
; AX,BX,CX,DX,FLAGS
; History:
;
; Wed 04-Jan-1990 13:45:58 -by- Todd Laney [ToddLa]
; Created.
; 15-Dec-96 jeffno Allowed pitch other than 320, extended inner loop
; to handle multiples of 320 with remainder 8 pixels
; (for 360x modes)
;-----------------------------------------------------------------------;
assumes ds,Data
assumes es,nothing
cProc PixBlt, <NEAR, PUBLIC>, <ds>
ParmW xExt ;14
ParmW yExt ;12
ParmD pBits ;8 10
ParmD BitsOffset ;4 6
ParmW WidthBytes ;2
;0
localW next_dst_scan
localD next_src_scan
cBegin
.386
PUSHD si ; push esi
PUSHD di ; push edi
xor esi,esi
xor edi,edi
xor ebx,ebx
; this routine only handles images in multiles of 32 pixels
; and they must start 4 pixel aligned
; But JeffNo added an extra loop to extend to either a multiple
; of 32 (320x) or a multiple of 32 plus 8 extra pixels (360x).
; An assert has been added in modex.c to ensure one of these cases.
; and xExt,not 31
;; and x,not 3
mov es,ScreenSel
mov ax,cdwScreenWidthInDWORDS
mov next_dst_scan,ax
mov ax,WidthBytes
sub ax,4
movsx eax,ax
mov next_src_scan,eax
mov di,ScreenOffset ; es:di -> top-left screen
lds si,pBits
add esi,BitsOffset
assumes ds,nothing
mov al,SC_MAP_MASK
mov dx,SC_INDEX
out dx,al
align 4
PixBltXLoop:
;-----------------------------------------------------------------;
; ax - free
; bx - index into dest es:[edi+ebx] index into source [esi+ebx*4]
; cx - loop count
; dl - mask
; dh - free
; si - source pointer (does not change)
; di - dest pointer (does not change)
mov cx,xExt
shr cx,2
and cx,0fff8h ; a left over would give an extra loop at 360x
mov dl,11h ; dh = mask
align 4
PixBltXPhaseLoop:
mov bx,dx ; set the mask
mov al,dl
mov dx,SC_INDEX+1
out dx,al
mov dx,bx
xor bx,bx ; start at zero
align 4
PixBltXPixelLoop:
mov al,[esi+ebx*4]
mov ah,[esi+ebx*4+4]
mov es:[di+bx],ax
mov al,[esi+ebx*4+8]
mov ah,[esi+ebx*4+12]
mov es:[di+bx+2],ax
mov al,[esi+ebx*4+16]
mov ah,[esi+ebx*4+20]
mov es:[di+bx+4],ax
mov al,[esi+ebx*4+24]
mov ah,[esi+ebx*4+28]
mov es:[di+bx+6],ax
add bx,8
cmp bx,cx
jl short PixBltXPixelLoop
PixBltXNext:
inc esi
shl dl,1
jnc short PixBltXPhaseLoop
;-----------------------------------------------------------------;
; extra stuff to tack on the extra 2 chains to go from 352 to 360
; Note this little chunk relies on the xExt being a multiple of
; 8 pixels. If xExt is 320, we'll skip this part, and if it's
; 360, we'll do it
;
test xExt,08h
je short NoExtras ;branch taken implies width is 320, else 360
mov dx,SC_INDEX+1
mov al,011h ;the plane bits
out dx,al ;select plane.
mov bx,xExt ; point to the last 8 columns
sub bx,8
shr bx,2
mov cl,[esi+ebx*4-4] ; -4 because esi is 4 greater than start of row
mov ch,[esi+ebx*4]
mov es:[di+bx],cx
shl al,1
out dx,al ;select plane.
mov cl,[esi+ebx*4-3]
mov ch,[esi+ebx*4+1]
mov es:[di+bx],cx
shl al,1
out dx,al ;select plane.
mov cl,[esi+ebx*4-2]
mov ch,[esi+ebx*4+2]
mov es:[di+bx],cx
shl al,1
out dx,al ;select plane.
mov cl,[esi+ebx*4-1]
mov ch,[esi+ebx*4+3]
mov es:[di+bx],cx
NoExtras:
;-----------------------------------------------------------------;
add di,next_dst_scan ;no changes to these to support 360x, since this
add esi,next_src_scan ;assume looped over multiple of 320, and the extra
;loop didn't change di and esi.
dec yExt
jnz PixBltXLoop ;not a short by just 3 bytes!
PixBltXExit:
POPD di ; pop edi
POPD si ; pop esi
cEnd
;---------------------------Private-Routine------------------------------;
; SetMode320x200x8
;
; VGA 320x200x8 graphics mode is entered (plain ol' MODE 13h)
;
; Entry:
;
; Returns:
; 360x200x8 graphics mode is entered
; Error Returns:
; None
; Registers Preserved:
; BP,DS,SI,DI
; Registers Destroyed:
; AX,BX,CX,DX,FLAGS
; Calls:
; INT 10h
; History:
;
; Wed 04-Jan-1990 13:45:58 -by- Todd Laney [ToddLa]
; Created.
;-----------------------------------------------------------------------;
assumes ds,Data
assumes es,nothing
cProc SetMode320x200x8, <NEAR, PUBLIC>, <ds,si,di>
cBegin
mov ScreenOffset,0 ; make sure this is zero
mov ScreenDisplay,0 ; make sure this is zero too.
mov ax,13h ; set display mode 320x200x8
int 10h
mov dx,SC_INDEX ; alter sequencer registers
mov ax,0604h
out dx,ax ;disable chain4 mode
mov dx,CRT_INDEX
mov ax,0E317h
out dx, ax
mov ax, 014h
out dx, ax
cEnd
;---------------------------Private-Macro--------------------------------;
; SLAM port, regs
;
; Sets a range of VGA registers
;
; Entry:
; port port index register
; regs table of register values
;
; History:
; Wed 04-Jan-1990 13:45:58 -by- Todd Laney [ToddLa]
; Created.
;-----------------------------------------------------------------------;
SLAM macro port, regs
local slam_loop
local slam_exit
mov cx,(&regs&_end - regs) / 2
mov dx,port
mov si,offset regs
jcxz slam_exit
slam_loop:
lodsw
out dx,ax
pause
loop slam_loop
slam_exit:
endm
;---------------------------Private-Routine------------------------------;
; SetMode320x400x8
;
; VGA 320x400x8 graphics mode is entered
;
; Entry:
;
; Returns:
; 320x400x8 graphics mode is entered
; Error Returns:
; None
; Registers Preserved:
; BP,DS,SI,DI
; Registers Destroyed:
; AX,BX,CX,DX,FLAGS
; Calls:
; INT 10h
; History:
;
; Wed 04-Jan-1990 13:45:58 -by- Todd Laney [ToddLa]
; Created.
;-----------------------------------------------------------------------;
assumes ds,Data
assumes es,nothing
seq_320x400:
;dw 00801h ; Dot Clock * 2
dw 00604h ; Disable chain 4
seq_320x400_end:
crt_320x400:
dw 04009h ; cell height
dw 00014h ; turn off dword mode
dw 0e317h ; turn on byte mode
crt_320x400_end:
assumes ds,Data
assumes es,nothing
cProc SetMode320x400x8, <NEAR, PUBLIC>, <ds,si,di>
cBegin
mov ScreenOffset,0 ; make sure this is zero
mov ScreenDisplay,0 ; make sure this is zero too.
mov ax,12h
int 10h ; have BIOS clear memory
mov ax,13h ; set display mode 320x200x8
int 10h
mov ax,cs ; get segment for data
mov ds,ax
;
; Set the CRT regs
;
SLAM CRT_INDEX, crt_320x400
;
; Set the SEQ regs
;
SLAM SC_INDEX, seq_320x400
cEnd
;---------------------------Private-Routine------------------------------;
; SetMode320x240x8
;
; VGA 320x240x8 graphics mode is entered
;
; Entry:
;
; Returns:
; 320x240x8 graphics mode is entered
; Error Returns:
; None
; Registers Preserved:
; BP,DS,SI,DI
; Registers Destroyed:
; AX,BX,CX,DX,FLAGS
; Calls:
; INT 10h
; History:
;
; Wed 04-Jan-1990 13:45:58 -by- Todd Laney [ToddLa]
; Created.
;-----------------------------------------------------------------------;
assumes ds,Data
assumes es,nothing
seq_320x240:
dw 00604h ; Disable chain 4
seq_320x240_end:
crt_320x240:
; dw 00611h ; un-protect cr0-cr7
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
crt_320x240_end:
cProc SetMode320x240x8, <NEAR, PUBLIC>, <ds,si,di>
cBegin
mov ScreenOffset,0 ; make sure this is zero
mov ScreenDisplay,0 ; make sure this is zero too.
mov ax,13h ; set display mode 320x200x8
int 10h
mov ax,cs ; get segment for data
mov ds,ax
assumes ds,Code
mov dx,CRT_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,7fh ;remove write protect on various
out dx,al ; CRTC registers
dec dx ;CRT Controller Index
;
; Set the CRT regs
;
SLAM CRT_INDEX, crt_320x240
mov dx,SC_INDEX ; alter sequencer registers
mov ax,0604h
out dx,ax ;disable chain4 mode
;
; Select a 25 mHz crystal
;
cli
; mov dx,SC_INDEX ; alter sequencer registers
mov ax,0100h ; synchronous reset
out dx,ax ; asserted
pause
mov dx,MISC_OUTPUT ; misc output
mov al,0e3h ; use 25 mHz dot clock
out dx,al ; select it
pause
mov dx,SC_INDEX ; sequencer again
mov ax,0300h ; restart sequencer
out dx,ax ; running again
pause
sti
;
; now clear the memory.
;
mov ax,DataBASE
mov ds,ax
assumes ds,Data
mov ax,ScreenSel
mov es,ax
xor di,di
mov ax,SC_MAP_MASK + 0F00h
mov dx,SC_INDEX
out dx,ax
xor ax,ax
mov cx,8000h
rep stosw
cEnd
sEnd CodeSeg
end