Move everything into one directory, update links
This commit is contained in:
parent
b946ff9e70
commit
4eef8b2919
680 changed files with 1638 additions and 1638 deletions
322
34-03.html
Normal file
322
34-03.html
Normal file
|
|
@ -0,0 +1,322 @@
|
|||
<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: Changing Colors without Writing Pixels</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=34//-->
|
||||
<!--PAGES=643-648//-->
|
||||
<!--UNASSIGNED1//-->
|
||||
<!--UNASSIGNED2//--></HEAD><BODY LINK=#0000FF ALINK=#000099 VLINK=#0000FF BGCOLOR=#FFFFFF>
|
||||
|
||||
<CENTER>
|
||||
<TABLE BORDER>
|
||||
<TR>
|
||||
<TD><A HREF="34-02.html">Previous</A></TD>
|
||||
<TD><A HREF="index.html">Table of Contents</A></TD>
|
||||
<TD><A HREF="34-04.html">Next</A></TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
</CENTER>
|
||||
<P><BR></P>
|
||||
<H3><A NAME="Heading7"></A><FONT COLOR="#000077">A Test Program for Color Cycling</FONT></H3>
|
||||
<P>Anyway, the choice of how to load the DAC is yours. Given that I’m not providing you with any hard-and-fast rules (mainly because there don’t seem to be any), what you need is a tool so that you can experiment with various DAC-loading approaches for yourself, and that’s exactly what you’ll find in Listing 34.1.
|
||||
</P>
|
||||
<P>Listing 34.1 draws a band of vertical lines, each one pixel wide, across the screen. The attribute of each vertical line is one greater than that of the preceding line, so there’s a smooth gradient of attributes from left to right. Once everything is set up, the program starts cycling the colors stored in however many DAC locations are specified by the <B>CYCLE_SIZE</B> equate; as many as all 256 DAC locations can be cycled. (Actually, <B>CYCLE_SIZE</B>-1 locations are cycled, because location 0 is kept constant in order to keep the background and border colors from changing, but <B>CYCLE_SIZE</B> locations are <I>loaded</I>, and it’s the number of locations we can load without problems that we’re interested in.)</P>
|
||||
<P><B>LISTING 34.1 L34-1.ASM</B></P>
|
||||
<!-- CODE //-->
|
||||
<PRE>
|
||||
; Fills a band across the screen with vertical bars in all 256
|
||||
; attributes, then cycles a portion of the palette until a key is
|
||||
; pressed.
|
||||
; Assemble with MASM or TASM
|
||||
|
||||
USE_BIOS equ 1 ;set to 1 to use BIOS functions to access the
|
||||
; DAC, 0 to read and write the DAC directly
|
||||
GUARD_AGAINST_INTS equ 1 ;1 to turn off interrupts and set write index
|
||||
; before loading each DAC location, 0 to rely
|
||||
; on the DAC auto-incrementing
|
||||
WAIT_VSYNC equ 1 ;set to 1 to wait for the leading edge of
|
||||
; vertical sync before accessing the DAC, 0
|
||||
; not to wait
|
||||
NOT_8088 equ 0 ;set to 1 to use REP INSB and REP OUTSB when
|
||||
; accessing the DAC directly, 0 to use
|
||||
; IN/STOSB and LODSB/OUT
|
||||
CYCLE_SIZE equ 256 ;# of DAC locations to cycle, 256 max
|
||||
SCREEN_SEGMENT equ 0a000h ;mode 13h display memory segment
|
||||
SCREEN_WIDTH_IN_BYTES equ 320 ;# of bytes across the screen in mode 13h
|
||||
INPUT_STATUS_1 equ 03dah ;input status 1 register port
|
||||
DAC_READ_INDEX equ 03c7h ;DAC Read Index register
|
||||
DAC_WRITE_INDEX equ 03c8h ;DAC Write Index register
|
||||
DAC_DATA equ 03c9h ;DAC Data register
|
||||
|
||||
if NOT_8088
|
||||
.286
|
||||
endif ;NOT_8088
|
||||
|
||||
.model small
|
||||
.stack 100h
|
||||
.data
|
||||
;Storage for all 256 DAC locations, organized as one three-byte
|
||||
; (actually three 6-bit values; upper two bits of each byte aren't
|
||||
; significant) RGB triplet per color.
|
||||
PaletteTempdb 256*3 dup(?)
|
||||
.code
|
||||
start:
|
||||
mov ax,@data
|
||||
mov ds,ax
|
||||
|
||||
;Select VGA's standard 256-color graphics mode, mode 13h.
|
||||
mov ax,0013h ;AH = 0: set mode function,
|
||||
int 10h ; AL = 13h: mode # to set
|
||||
|
||||
;Read all 256 DAC locations into PaletteTemp (3 6-bit values, one
|
||||
; each for red, green, and blue, per DAC location).
|
||||
|
||||
if WAIT_VSYNC
|
||||
;Wait for the leading edge of the vertical sync pulse; this ensures
|
||||
; that we read the DAC starting during the vertical non-display
|
||||
; period.
|
||||
mov dx,INPUT_STATUS_1
|
||||
WaitNotVSync: ;wait to be out of vertical sync
|
||||
in al,dx
|
||||
and al,08h
|
||||
jnz WaitNotVSync
|
||||
WaitVSync: ;wait until vertical sync begins
|
||||
in al,dx
|
||||
and al,08h
|
||||
jz WaitVSync
|
||||
endif ;WAIT_VSYNC
|
||||
|
||||
if USE_BIOS
|
||||
mov ax,1017h ;AH = 10h: set DAC function,
|
||||
; AL = 17h: read DAC block subfunction
|
||||
sub bx,bx ;start with DAC location 0
|
||||
mov cx,256 ;read out all 256 locations
|
||||
mov dx,seg PaletteTemp
|
||||
mov es,dx
|
||||
mov dx,offset PaletteTemp ;point ES:DX to array in which
|
||||
; the DAC values are to be stored
|
||||
int 10h ;read the DAC
|
||||
else ;!USE_BIOS
|
||||
if GUARD_AGAINST_INTS
|
||||
mov cx,CYCLE_SIZE ;# of DAC locations to load
|
||||
mov di,seg PaletteTemp
|
||||
mov es,di
|
||||
mov di,offset PaletteTemp ;dump the DAC into this array
|
||||
sub ah,ah ;start with DAC location 0
|
||||
DACStoreLoop:
|
||||
mov dx,DAC_READ_INDEX
|
||||
mov al,ah
|
||||
cli
|
||||
out dx,al ;set the DAC location #
|
||||
mov dx,DAC_DATA
|
||||
in al,dx ;get the red component
|
||||
stosb
|
||||
in al,dx ;get the green component
|
||||
stosb
|
||||
in al,dx ;get the blue component
|
||||
stosb
|
||||
sti
|
||||
inc ah
|
||||
loopDACStoreLoop
|
||||
else;!GUARD_AGAINST_INTS
|
||||
mov dx,DAC_READ_INDEX
|
||||
sub al,al
|
||||
out dx,al ;set the initial DAC location to 0
|
||||
mov di,seg PaletteTemp
|
||||
mov es,di
|
||||
mov di,offset PaletteTemp ;dump the DAC into this array
|
||||
mov dx,DAC_DATA
|
||||
if NOT_8088
|
||||
mov cx,CYCLE_SIZE*3
|
||||
rep insb ;read CYCLE_SIZE DAC locations at once
|
||||
else;!NOT_8088
|
||||
mov cx,CYCLE_SIZE ;# of DAC locations to load
|
||||
DACStoreLoop:
|
||||
in al,dx ;get the red component
|
||||
stosb
|
||||
in al,dx ;get the green component
|
||||
stosb
|
||||
in al,dx ;get the blue component
|
||||
stosb
|
||||
loop DACStoreLoop
|
||||
endif ;NOT_8088
|
||||
endif ;GUARD_AGAINST_INTS
|
||||
endif ;USE_BIOS
|
||||
|
||||
;Draw a series of 1-pixel-wide vertical bars across the screen in
|
||||
; attributes 1 through 255.
|
||||
mov ax,SCREEN_SEGMENT
|
||||
mov es,ax
|
||||
mov di,50*SCREEN_WIDTH_IN_BYTES ;point ES:DI to the start
|
||||
; of line 50 on the screen
|
||||
cld
|
||||
mov dx,100 ;draw 100 lines high
|
||||
RowLoop:
|
||||
mov al,1 ;start each line with attr 1
|
||||
mov cx,SCREEN_WIDTH_IN_BYTES ;do a full line across
|
||||
ColumnLoop:
|
||||
stosb ;draw a pixel
|
||||
add al,1 ;increment the attribute
|
||||
ad cal,0 ;if the attribute just turned
|
||||
; over to 0, increment it to 1
|
||||
; because we're not going to
|
||||
; cycle DAC location 0, so
|
||||
; attribute 0 won't change
|
||||
loop ColumnLoop
|
||||
dec dx
|
||||
jnz RowLoop
|
||||
|
||||
;Cycle the specified range of DAC locations until a key is pressed.
|
||||
CycleLoop:
|
||||
;Rotate colors 1-255 one position in the PaletteTemp array;
|
||||
; location 0 is always left unchanged so that the background
|
||||
; and border don't change.
|
||||
push word ptr PaletteTemp+(1*3) ;set aside PaletteTemp
|
||||
push word ptr PaletteTemp+(1*3)+2; setting for attr 1
|
||||
mov cx,254
|
||||
mov si,offset PaletteTemp+(2*3)
|
||||
mov di,offset PaletteTemp+(1*3)
|
||||
mov ax,ds
|
||||
mov es,ax
|
||||
mov cx,254*3/2
|
||||
rep movsw ;rotate PaletteTemp settings
|
||||
; for attrs 2 through 255 to
|
||||
; attrs 1 through 254
|
||||
pop bx ;get back original settings
|
||||
pop ax ; for attribute 1 and move
|
||||
stosw ; them to the PaletteTemp
|
||||
mov es:[di],bl ; location for attribute 255
|
||||
|
||||
if WAIT_VSYNC
|
||||
;Wait for the leading edge of the vertical sync pulse; this ensures
|
||||
; that we reload the DAC starting during the vertical non-display
|
||||
; period.
|
||||
mov dx,INPUT_STATUS_1
|
||||
WaitNotVSync2: ;wait to be out of vertical sync
|
||||
in al,dx
|
||||
and al,08h
|
||||
jnz WaitNotVSync2
|
||||
WaitVSync2: ;wait until vertical sync begins
|
||||
in al,dx
|
||||
and al,08h
|
||||
jz WaitVSync2
|
||||
endif ;WAIT_VSYNC
|
||||
|
||||
if USE_BIOS
|
||||
;Set the new, rotated palette.
|
||||
mov ax,1012h ;AH = 10h: set DAC function,
|
||||
; AL = 12h: set DAC block subfunction
|
||||
sub bx,bx ;start with DAC location 0
|
||||
mov cx,CYCLE_SIZE ;# of DAC locations to set
|
||||
mov dx,seg PaletteTemp
|
||||
mov es,dx
|
||||
mov dx,offset PaletteTemp ;point ES:DX to array from which
|
||||
; to load the DAC
|
||||
int 10h ;load the DAC
|
||||
else ;!USE_BIOS
|
||||
if GUARD_AGAINST_INTS
|
||||
mov cx,CYCLE_SIZE ;# of DAC locations to load
|
||||
mov si,offset PaletteTemp ;load the DAC from this array
|
||||
sub ah,ah ;start with DAC location 0
|
||||
DACLoadLoop:
|
||||
mov dx,DAC_WRITE_INDEX
|
||||
mov al,ah
|
||||
cli
|
||||
out dx,al ;set the DAC location #
|
||||
mov dx,DAC_DATA
|
||||
lodsb
|
||||
out dx,al ;set the red component
|
||||
lodsb
|
||||
out dx,al ;set the green component
|
||||
lodsb
|
||||
out dx,al ;set the blue component
|
||||
sti
|
||||
inc ah
|
||||
loop DACLoadLoop
|
||||
else;!GUARD_AGAINST_INTS
|
||||
mov dx,DAC_WRITE_INDEX
|
||||
sub al,al
|
||||
out dx,al ;set the initial DAC location to 0
|
||||
mov si,offset PaletteTemp ;load the DAC from this array
|
||||
mov dx,DAC_DATA
|
||||
if NOT_8088
|
||||
mov cx,CYCLE_SIZE*3
|
||||
rep outsb ;load CYCLE_SIZE DAC locations at once
|
||||
else;!NOT_8088
|
||||
mov cx,CYCLE_SIZE ;# of DAC locations to load
|
||||
DACLoadLoop:
|
||||
lodsb
|
||||
out dx,al ;set the red component
|
||||
lodsb
|
||||
out dx,al ;set the green component
|
||||
lodsb
|
||||
out dx,al ;set the blue component
|
||||
loop DACLoadLoop
|
||||
endif;NOT_8088
|
||||
endif;GUARD_AGAINST_INTS
|
||||
endif;USE_BIOS
|
||||
|
||||
;See if a key has been pressed.
|
||||
mov ah,0bh ;DOS check standard input status fn
|
||||
int 21h
|
||||
and al,al ;is a key pending?
|
||||
jz CycleLoop ;no, cycle some more
|
||||
|
||||
;Clear the keypress.
|
||||
mov ah,1 ;DOS keyboard input fn
|
||||
int 21h
|
||||
|
||||
;Restore text mode and done.
|
||||
mov ax,0003h ;AH = 0: set mode function,
|
||||
int 10h ; AL = 03h: mode # to set
|
||||
mov ah,4ch ;DOS terminate process fn
|
||||
int 21h
|
||||
|
||||
endstart
|
||||
</PRE>
|
||||
<!-- END CODE //-->
|
||||
<P><BR></P>
|
||||
<CENTER>
|
||||
<TABLE BORDER>
|
||||
<TR>
|
||||
<TD><A HREF="34-02.html">Previous</A></TD>
|
||||
<TD><A HREF="index.html">Table of Contents</A></TD>
|
||||
<TD><A HREF="34-04.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 -->
|
||||
|
||||
|
||||
Loading…
Reference in a new issue