.model small .586 .stack 100h .data MAXROW equ 200 MAXCOL equ 320 MAXPIX equ 16 VIDMOD equ 0Dh ;320x200 16 color ; MAXROW equ 480 ; MAXCOL equ 640 ; MAXPIX equ 16 ; VIDMOD equ 12h ; 640x480 16 color BANDSZE equ MAXROW/MAXPIX row dw 0 col dw 0 bandcnt db 0 pixel db 0 vmode db 0 ;; current video mode vpage db 0 ;; current video page ;; define a color palette ;; 16 entries each has a R, G, B value ;; leave border color alone ;; note that color zero is used for border ;; on many video cards in VGA mode, only 6 bits of precision so palette ;; routine ignores lower 2 bits. ;; in VGA mode!!!! palette1 db 255,0,0 ;color 0 db 0,255,0 ;color 1 db 0,0,255 ;color 2 db 0,0,0 ;color 3 db 255,255,255 ;color 4 db 255,255,0 ;color 5 db 0,255,255 ;color 6 db 255,0,255 ;color 7 db 255,0,0 ;color 8 db 0,0,255 ;color 9 db 0,255,0 ;color 10 db 255,127,0 ;color 11 db 127,255,0 ;color 12 db 0,255,127 ;color 13 db 127,0,127 ;color 14 db 0,127,127 ;color 15 ;; note that color zero is used for border palette2 db 127,0,127 db 0,127,127 db 127,127,0 db 190,190,190 db 63,63,63 db 0,0,127 db 0,127,0 db 127,0,0 db 255,0,255 db 0,255,255 db 255,255,0 db 255,255,255 db 0,0,0 db 0,0,255 db 0,255,0 db 255,0,0 .code main proc mov ax,@data mov ds,ax ;; read current video mode and save mov ah,0fh int 10h mov vmode,al mov vpage,bh ;; set video mode -- changing the video mode changes palette!! mov ah,0 mov al,VIDMOD int 10h ;; write a screen call scrntst ;; change the pallette mainlp: mov si,offset palette1 call sndpal mov ah,7 ;get a key, no echo int 21h ; get a key cmp al,20h je main_ex mov si,offset palette2 call sndpal mov ah,7 ;get a key, no echo int 21h ; get a key cmp al,20h jne mainlp main_ex: ;; restore old video mode mov bh,vpage mov al,vmode mov ah,0 int 10h Mov ax, 4c00h ;exit Int 21h Main endp ;; test the current mode by writing a band of colors scrntst proc xor ax,ax mov row,ax mov col,ax mov pixel,al mov bandcnt,al lp1: call wpixel inc col mov ax,col cmp ax,MAXCOL jne lp1 ;start new row xor ax,ax mov col,ax ;zero column value inc bandcnt mov al,bandcnt cmp al,bandsze jb nextrow inc pixel ;inc to next color value xor al,al mov bandcnt,al nextrow: inc row mov ax,row cmp ax,MAXROW jne lp1 doexit: mov ah,7 ;get a key, no echo int 21h ; get a key ret scrntst endp ;; send a new palette passed in SI ;; if 640x480 mode, have to send in different sequence sndpal proc call retrace xor al,al ; start at color 0 mov dx,3c8h ; port number for Video card out dx,al mov al,vidmod cmp al,12H ;; 640? je sndskip mov di,si ;save si mov cx,8 call palsub mov si,di mov cx,8 call palsub ;; because of the way the palette registers are arranged ;; send first 8 colors twice mov cx,8 mov di,si call palsub mov si,di mov cx,8 call palsub ret sndskip: mov cx,16 sndskplp: push cx push si mov cx,16 call palsub pop si pop cx loop sndskplp ret sndpal endp palsub proc sndlp1: mov dx,3c9h ; port number for Video card mov al,[si] ;get RED value shr al,2 out dx,al mov al,[si+1] ;get GREEN value shr al,2 out dx,al mov al,[si+2] ; get BLUE value shr al,2 out dx,al add si,3 ;point to next color loop sndlp1 ;send all colors ret palsub endp ; wait for vertical retrace retrace proc push dx push ax mov dx,03dah ;; wait for end of retrace lpwaitstart: in al,dx and al,08h jnz lpwaitstart mov dx,03dah ;; wait for start of retrace lpwaitend: in al,dx and al,08h jz lpwaitend pop ax pop dx ret retrace endp wpixel proc mov ah,0ch mov al, pixel mov bh,0 mov cx,col mov dx, row int 10h ret wpixel endp end main