home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 December
/
simtel1292_SIMTEL_1292_Walnut_Creek.iso
/
msdos
/
progjorn
/
pj_7_1.arc
/
VGA71-L2.ASM
< prev
next >
Wrap
Assembly Source File
|
1988-10-16
|
7KB
|
264 lines
;
; *** Listing 2 ***
;
; 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_WORD macro
if WORD_OUTS_OK
out dx,ax
else
out dx,al
inc dx
xchg ah,al
out dx,al
dec dx
xchg ah,al
endif
endm
;
; Macro to output a constant value to an indexed VGA register.
;
CONSTANT_TO_INDEXED_REGISTER macro ADDRESS, 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.
;
call Set320By400Mode
;
; 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.
;
call GetNextKey
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.
;
call GetNextKey
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
;
Set320By400Mode proc near
;
; 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
in al,dx
and al,not 08h ;turn off chain 4
or al,04h ;turn off odd/even
out dx,al
mov dx,GC_INDEX
mov al,GRAPHICS_MODE
out dx,al
inc dx
in al,dx
and al,not 10h ;turn off odd/even
out dx,al
dec dx
mov al,MISCELLANEOUS
out dx,al
inc dx
in al,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
in al,dx
and al,not 40h ;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
; DL = 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.
;
ColorBarsUp proc near
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
;there are 4 pixels at each address, so
; each 320-pixel row is 80 bytes wide
; in each plane
push 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
ColorBarsUp endp
;
; Waits for the next key and returns it in AX.
;
GetNextKey proc near
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
;
Code ends
;
end Start