Programming the VGA
The Standard VGA mode 13h is the easiest and fastest color graphics programming. It uses a single long, linear bitmap, with each byte controlling one pixel. If I had a bitmap of 320x200 with 256 colors with each pixel represented by a single byte, I can quickly put that bitmap on the screen by copying it to memory location 0A000:0000h. This makes for extremely fast screen updates and flicker free animation. Also, if I have a small bitmap of 25x25 that I want to scroll across the screen, All I need to do is put the background on using the tech. above and then copy the 25x25 space of the background into a temp memory position, copy my 25x25 bitmap to that location, wait, copy the saved 25x25 background bitmap back into its place and move to the next position. This way I don't even touch the rest of background, and makes for even faster and better animation. I could even get better animation by rotating through 3 or more 25x25 bitmaps of a man walking while moving across the screen to give a better representation of animation.
Mode X is the undocumented mode of the VGA. It is very close to Mode 13h (320x200x256) except it has more vertical pixels (320x240x256) and we have to send our data to the VGA's registers rather than just putting it into 0A000:0000h
You can also program the VGA to have a resolution of 320x400 with 256 colors. This mode is still 13h but we now use 4 bitplanes. The standard VGA mode 13h is really a 320x400 res. mode, except the designers wanted to only use 64k so they made each line display twice, hence the 320x200 res mode. If we use 4 bitmaps, now we can take control of that second printed line.
In this discussion, I will include a source code listing for a small animation demo for the standard VGA mode 13h. You can get a copy of it here, or below, and unzip it (See my links page for PKUNZIP) in a directory of your choice, then view ANI.TXT for more info on running the demo and view the source code (MASM 5.1).
As far as the rest of the graphic modes described on this page, I suggest that you get a copy of the following book. It is a very good, source filled documentation on all the graphical modes of the CGA, EGA, VGA, MGA, MCGA, and many more. It includes a CD with all the code on it, and the complete text to his book, Zen of Assembly Language.
Michael Abrash's
ZEN of GRAPHICS PROGRAMMING
2nd Edition 1996
The Coriolis Group
ISBN 1-883577-89-6:
830+ pages of detailed documentation on programming graphics
See here for more books like this one.
ANI.ZIP (31k)
To see the demo, type ANI at the DOS prompt.
Here is an example of MODE 12h video graphics with 4 plains using Write Mode 2.
Simply draws a colorful line from (0,0) to (479,479) on the 640x480x16 screen.
; This code was assembled with NBASM
.model tiny
.code
.186
org 100h
mov ax,0012h ; set mode to 640x480x16
int 10h
mov ax,0A000h
mov es,ax
; start line from (0,0) to (639,479)
mov word X,0001h ; top most pixel (0,0)
mov word Y,0001h ;
mov byte Color,00h ; start with color 0
mov cx,480 ; 480 pixels
DrawLine: call putpixel ; put the pixel
inc word X ; move down a row and inc col
inc word Y ;
inc byte Color ; next color
and byte Color,0Fh ; 00h - 0Fh only
loop DrawLine ; do it
xor ah,ah ; wait for key press
int 16h
mov ax,0003 ; return to screen 3 (text)
int 10h
.exit ; exit to DOS
; on entry X,Y = location and C = color (0-15)
putpixel proc near uses ax bx cx dx
; byte offset = Y * (horz_res / 8) + int(X / 8)
mov ax,Y ; calculate offset
mov dx,80 ;
mul dx ; ax = y * 80
mov bx,X ;
mov cl,bl ; save low byte for below
shr bx,03 ; div by 8
add bx,ax ; bx = offset this group of 8 pixels
mov dx,03CEh ; set to video hardware controller
and cl,07h ; Compute bit mask from X-coordinates
xor cl,07h ; and put in ah
mov ah,01h ;
shl ah,cl ;
mov al,08h ; bit mask register
out dx,ax ;
mov ax,0205h ; read mode 0, write mode 2
out dx,ax ;
mov al,es:[bx] ; load to latch register
mov al,Color
mov es:[bx],al ; write to register
ret
putpixel endp
X dw 00h
Y dw 00h
Color db 00h
.end
Here is an "optical trick" you can do on a standard VGA in mode 13h, with 256 colors.
Sorry to those who's browsers don't view .BMP file formats. This was the only format that I could get to show this image with this much definition.
The middle bar is actually one color. Hold two pieces of paper up to the screen so you only see the middle bar.
This "trick" was found in:
More Tricks of the Game Programming Gurus, 1995, Sams Publishing
See here for more books like this one.
Here is the code to get this image.
; This code was assembled with NBASM
.model tiny
.code
org 100h
.start
push ds ; make sure ds=es
pop es
mov cx,64 ; set up our palette
xor ax,ax ; of 0.0.0, 1.1.1, 2,2,2, ...
mov di,offset Palette ;
PLoop: stosb ;
stosb ;
stosb ;
inc ax ;
loop PLoop ;
mov ax,0013h ; set video mode to 320x200x256
int 10h ;
mov dx,offset Palette ; set the palette (DAC)
xor bx,bx ;
mov cx,64 ;
mov ax,1012h ;
int 10h ;
mov ax,0A000h ; point to VGA memory
mov es,ax ;
mov di,14464 ; place image in center of screen
call Fade ; print top part
mov cx,10 ; print bar (10 lines)
mov al,32 ; middle color
ALoop: push cx ;
mov cx,128 ;
rep ;
stosb ;
add di,192 ;
pop cx ;
loop ALoop ;
call Fade ; print third part
xor ah,ah ; wait for key
int 16h
mov ax,0003h ; set screen back to text (80x25)
int 10h ;
.exit ; exit to DOS
Fade proc near ; print first and third parts
mov cx,50 ; 50 lines
PLoop1: push cx ;
mov cx,64 ; 64 colors
PLoop2: mov al,cl ;
dec al ;
stosb ; 2 columns each
stosb ;
loop PLoop2 ;
add di,192 ;
pop cx ;
loop PLoop1 ;
ret ;
Fade endp ;
Palette dup 768,? ; our palette buffer
.end ; done assembling