home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Graphics Programming Black Book (Special Edition)
/
BlackBook.bin
/
disk1
/
source
/
chapter34
/
l34-1.asm
next >
Wrap
Assembly Source File
|
1997-06-18
|
7KB
|
254 lines
;
; 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.
;
; Assembled with TASM 4.0, linked with TLINK 6.10
; Checked by Jim Mischel 11/21/94
;
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.
PaletteTemp db 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
loop DACStoreLoop
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
adc al,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
end start