331 lines
12 KiB
HTML
331 lines
12 KiB
HTML
<HTML>
|
|
<HEAD>
|
|
<META name=vsisbn content="1576101746">
|
|
<META name=vstitle content="Michael Abrash's Graphics Programming Black Book, Special Edition">
|
|
<META name=vsauthor content="Michael Abrash">
|
|
<META name=vspublisher content="The Coriolis Group">
|
|
<META name=vspubdate content="07/01/97">
|
|
<META name=vscategory content="Web and Software Development: Game Development,Web and Software Development: Graphics and Multimedia Development">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<TITLE>Michael Abrash's Graphics Programming Black Book Special Edition: Higher 256-Color Resolution on the VGA</TITLE>
|
|
|
|
<!-- HEADER -->
|
|
<!-- Empty Reference Subhead -->
|
|
|
|
<!--ISBN=1576101746//-->
|
|
<!--TITLE=Michael Abrash's Graphics Programming Black Book Special Edition//-->
|
|
<!--AUTHOR=Michael Abrash//-->
|
|
<!--PUBLISHER=The Coriolis Group, Inc.//-->
|
|
<!--CHAPTER=31//-->
|
|
<!--PAGES=600-605//-->
|
|
<!--UNASSIGNED1//-->
|
|
<!--UNASSIGNED2//--></HEAD><BODY LINK=#0000FF ALINK=#000099 VLINK=#0000FF BGCOLOR=#FFFFFF>
|
|
|
|
<CENTER>
|
|
<TABLE BORDER>
|
|
<TR>
|
|
<TD><A HREF="31-04.html">Previous</A></TD>
|
|
<TD><A HREF="index.html">Table of Contents</A></TD>
|
|
<TD><A HREF="32-01.html">Next</A></TD>
|
|
</TR>
|
|
</TABLE>
|
|
</CENTER>
|
|
<P><BR></P>
|
|
<P><B>LISTING 31.2 L31-2.ASM</B></P>
|
|
<!-- CODE //-->
|
|
<PRE>
|
|
; Program to demonstrate the two pages available in 320x400
|
|
; 256-color modes on a VGA. Draws diagonal color bars in all
|
|
; 256 colors in page 0, then does the same in page 1 (but with
|
|
; the bars tilted the other way), and finally draws vertical
|
|
; color bars in page 0.
|
|
;
|
|
VGA_SEGMENT equ 0a000h
|
|
SC_INDEX equ 3c4h ;Sequence Controller Index register
|
|
GC_INDEX equ 3ceh ;Graphics Controller Index register
|
|
CRTC_INDEX equ 3d4h ;CRT Controller Index register
|
|
MAP_MASK equ 2 ;Map Mask register index in SC
|
|
MEMORY_MODE equ 4 ;Memory Mode register index in SC
|
|
MAX_SCAN_LINE equ 9 ;Maximum Scan Line reg index in CRTC
|
|
START_ADDRESS_HIGH equ 0ch ;Start Address High reg index in CRTC
|
|
UNDERLINE equ 14h ;Underline Location reg index in CRTC
|
|
MODE_CONTROL equ 17h ;Mode Control register index in CRTC
|
|
GRAPHICS_MODE equ 5 ;Graphics Mode register index in GC
|
|
MISCELLANEOUS equ 6 ;Miscellaneous register index in GC
|
|
SCREEN_WIDTH equ 320 ;# of pixels across screen
|
|
SCREEN_HEIGHT equ 400 ;# of scan lines on screen
|
|
WORD_OUTS_OK equ 1 ;set to 0 to assemble for
|
|
; computers that can't handle
|
|
; word outs to indexed VGA registers
|
|
;
|
|
stack segment para stack 'STACK'
|
|
db 512 dup (?)
|
|
stack ends
|
|
;
|
|
; Macro to output a word value to a port.
|
|
;
|
|
OUT_WORDmacro
|
|
if WORD_OUTS_OK
|
|
outdx,ax
|
|
else
|
|
out dx,al
|
|
inc dx
|
|
xch gah,al
|
|
out dx,al
|
|
dec dx
|
|
xch gah,al
|
|
endif
|
|
endm
|
|
;
|
|
; Macro to output a constant value to an indexed VGA register.
|
|
;
|
|
CONSTANT_TO_INDEXED_REGISTERmacroADDRESS, INDEX, VALUE
|
|
mov dx,ADDRESS
|
|
mov ax,(VALUE shl 8) + INDEX
|
|
OUT_WORD
|
|
endm
|
|
;
|
|
Code segment
|
|
assume cs:Code
|
|
Start proc near
|
|
;
|
|
; Set 320x400 256-color mode.
|
|
;
|
|
callSet320By400Mode
|
|
;
|
|
; We're in 320x400 256-color mode, with page 0 displayed.
|
|
; Let's fill page 0 with color bars slanting down and to the right.
|
|
;
|
|
sub di,di ;page 0 starts at address 0
|
|
mov bl,1 ;make color bars slant down and
|
|
; to the right
|
|
call ColorBarsUp ;draw the color bars
|
|
;
|
|
; Now do the same for page 1, but with the color bars
|
|
; tilting the other way.
|
|
;
|
|
mov di,8000h ;page 1 starts at address 8000h
|
|
mov bl,-1 ;make color bars slant down and
|
|
; to the left
|
|
call ColorBarsUp ;draw the color bars
|
|
;
|
|
; Wait for a key and flip to page 1 when one is pressed.
|
|
;
|
|
callGetNextKey
|
|
CONSTANT_TO_INDEXED_REGISTER CRTC_INDEX,START_ADDRESS_HIGH,80h
|
|
;set the Start Address High register
|
|
; to 80h, for a start address of 8000h
|
|
;
|
|
; Draw vertical bars in page 0 while page 1 is displayed.
|
|
;
|
|
sub di,di ;page 0 starts at address 0
|
|
sub bl,bl ;make color bars vertical
|
|
call ColorBarsUp ;draw the color bars
|
|
;
|
|
; Wait for another key and flip back to page 0 when one is pressed.
|
|
;
|
|
callGetNextKey
|
|
CONSTANT_TO_INDEXED_REGISTER CRTC_INDEX,START_ADDRESS_HIGH,00h
|
|
;set the Start Address High register
|
|
; to 00h, for a start address of 0000h
|
|
;
|
|
; Wait for yet another key and return to text mode and end when
|
|
; one is pressed.
|
|
;
|
|
call GetNextKey
|
|
mov ax,0003h
|
|
int 10h ;text mode
|
|
mov ah,4ch
|
|
int 21h ;done
|
|
;
|
|
Start endp
|
|
;
|
|
; Sets up 320x400 256-color modes.
|
|
;
|
|
; Input: none
|
|
;
|
|
; Output: none
|
|
;
|
|
Set320By400Modeprocnear
|
|
;
|
|
; First, go to normal 320x200 256-color mode, which is really a
|
|
; 320x400 256-color mode with each line scanned twice.
|
|
;
|
|
mov ax,0013h ;AH = 0 means mode set, AL = 13h selects
|
|
; 256-color graphics mode
|
|
int 10h ;BIOS video interrupt
|
|
;
|
|
; Change CPU addressing of video memory to linear (not odd/even,
|
|
; chain, or chain 4), to allow us to access all 256K of display
|
|
; memory. When this is done, VGA memory will look just like memory
|
|
; in modes 10h and 12h, except that each byte of display memory will
|
|
; control one 256-color pixel, with 4 adjacent pixels at any given
|
|
; address, one pixel per plane.
|
|
;
|
|
mov dx,SC_INDEX
|
|
mov al,MEMORY_MODE
|
|
out dx,al
|
|
inc dx
|
|
ina l,dx
|
|
and al,not 08h ;turn off chain 4
|
|
ora l,04h ;turn off odd/even
|
|
out dx,al
|
|
mov dx,GC_INDEX
|
|
mov al,GRAPHICS_MODE
|
|
out dx,al
|
|
inc dx
|
|
ina l,dx
|
|
and al,not 10h ;turn off odd/even
|
|
out dx,al
|
|
dec dx
|
|
mov al,MISCELLANEOUS
|
|
out dx,al
|
|
inc dx
|
|
ina l,dx
|
|
and al,not 02h ;turn off chain
|
|
out dx,al
|
|
;
|
|
; Now clear the whole screen, since the mode 13h mode set only
|
|
; cleared 64K out of the 256K of display memory. Do this before
|
|
; we switch the CRTC out of mode 13h, so we don't see garbage
|
|
; on the screen when we make the switch.
|
|
;
|
|
CONSTANT_TO_INDEXED_REGISTER SC_INDEX,MAP_MASK,0fh
|
|
; enable writes to all planes, so
|
|
; we can clear 4 pixels at a time
|
|
mov ax,VGA_SEGMENT
|
|
mov es,ax
|
|
sub di,di
|
|
mov ax,di
|
|
mov cx,8000h ;# of words in 64K
|
|
cld
|
|
rep stosw ;clear all of display memory
|
|
;
|
|
; Tweak the mode to 320x400 256-color mode by not scanning each
|
|
; line twice.
|
|
;
|
|
mov dx,CRTC_INDEX
|
|
mov al,MAX_SCAN_LINE
|
|
out dx,al
|
|
inc dx
|
|
in al,dx
|
|
and al,not 1fh ;set maximum scan line = 0
|
|
out dx,al
|
|
dec dx
|
|
;
|
|
; Change CRTC scanning from doubleword mode to byte mode, allowing
|
|
; the CRTC to scan more than 64K of video data.
|
|
;
|
|
mov al,UNDERLINE
|
|
out dx,al
|
|
inc dx
|
|
ina l,dx
|
|
and al,not40h ;turn off doubleword
|
|
out dx,al
|
|
dec dx
|
|
mov al,MODE_CONTROL
|
|
out dx,al
|
|
inc dx
|
|
in al,dx
|
|
or al,40h ;turn on the byte mode bit, so memory is
|
|
; scanned for video data in a purely
|
|
; linear way, just as in modes 10h and 12h
|
|
out dx,al
|
|
ret
|
|
Set320By400Mode endp
|
|
;
|
|
; Draws a full screen of slanting color bars in the specified page.
|
|
;
|
|
; Input:
|
|
; DI = page start address
|
|
; BL = 1 to make the bars slant down and to the right, -1 to
|
|
; make them slant down and to the left, 0 to make
|
|
; them vertical.
|
|
;
|
|
ColorBarsUpprocnear
|
|
mov ax,VGA_SEGMENT
|
|
mov es,ax ;point to display memory
|
|
sub bh,bh ;start with color 0
|
|
mov si,SCREEN_HEIGHT ;# of rows to do
|
|
mov dx,SC_INDEX
|
|
mov al,MAP_MASK
|
|
out dx,al ;point the SC Index reg to the Map Mask reg
|
|
inc dx ;point DX to the SC Data register
|
|
RowLoop:
|
|
mov cx,SCREEN_WIDTH/4
|
|
;4 pixels at each address, so
|
|
; each 320-pixel row is 80 bytes wide
|
|
; in each plane
|
|
pus h bx ;save the row-start color
|
|
ColumnLoop:
|
|
MAP_SELECT = 1
|
|
rept 4 ;do all 4 pixels at this address with
|
|
; in-line code
|
|
mov al,MAP_SELECT
|
|
out dx,al ;select planes 0, 1, 2, and 3 in turn
|
|
mov es:[di],bh ;write this plane's pixel
|
|
inc bh ;set the color for the next pixel
|
|
MAP_SELECT = MAP_SELECT shl 1
|
|
endm
|
|
inc di ;point to the address containing the next
|
|
; 4 pixels
|
|
loop ColumnLoop ;do any remaining pixels on this line
|
|
pop bx ;get back the row-start color
|
|
add bh,bl ;select next row-start color (controls
|
|
; slanting of color bars)
|
|
dec si ;count down lines on the screen
|
|
jnz RowLoop
|
|
ret
|
|
ColorBarsUpendp
|
|
;
|
|
; Waits for the next key and returns it in AX.
|
|
;
|
|
GetNextKeyprocnear
|
|
WaitKey:
|
|
mov ah,1
|
|
int 16h
|
|
jz WaitKey ;wait for a key to become available
|
|
sub ah,ah
|
|
int 16h ;read the key
|
|
ret
|
|
GetNextKey endp
|
|
;
|
|
Codeends
|
|
;
|
|
endStart
|
|
</PRE>
|
|
<!-- END CODE //-->
|
|
<P>When you run Listing 31.2, note the extremely smooth edges and fine gradations of color, especially in the screens with slanting color bars. The displays produced by Listing 31.2 make it clear that 320×400 256-color mode can produce effects that are simply not possible in any 16-color mode.
|
|
</P>
|
|
<H3><A NAME="Heading8"></A><FONT COLOR="#000077">Something to Think About</FONT></H3>
|
|
<P>You can, if you wish, use the display memory organization of 320×400 mode in 320×200 mode by modifying <B>Set320×400Mode</B> to leave the maximum scan line setting at 1 in the mode set. (The version of <B>Set320×400Mode</B> in Listings 31.1 and 31.2 forces the maximum scan line to 0, doubling the effective resolution of the screen.) Why would you want to do that? For one thing, you could then choose from not two but <I>four</I> 320×200 256-color display pages, starting at offsets 0, 4000H, 8000H, and 0C000H in display memory. For another, having only half as many pixels per screen can as much as double drawing speeds; that’s one reason that many games run at 320×200, and even then often limit the active display drawing area to only a portion of the screen.</P><P><BR></P>
|
|
<CENTER>
|
|
<TABLE BORDER>
|
|
<TR>
|
|
<TD><A HREF="31-04.html">Previous</A></TD>
|
|
<TD><A HREF="index.html">Table of Contents</A></TD>
|
|
<TD><A HREF="32-01.html">Next</A></TD>
|
|
</TR>
|
|
</TABLE>
|
|
</CENTER>
|
|
|
|
<hr width="90%" size="1" noshade>
|
|
<div align="center">
|
|
<font face="Verdana,sans-serif" size="1">Graphics Programming Black Book © 2001 Michael Abrash</font>
|
|
</div>
|
|
<!-- all of the reference materials (books) have the footer and subfoot reveresed -->
|
|
<!-- reference_subfoot = footer -->
|
|
<!-- reference_footer = subfoot -->
|
|
|
|
<!-- BEGIN SUB FOOTER -->
|
|
</BODY>
|
|
</HTML>
|
|
|
|
<!-- END FOOTER -->
|
|
|
|
|