EarthWeb   
   datamation.com Brought to you by EarthWeb

HomeSubscribeSearchFAQSitemapContact Us
     

   

  Search Tips
  Advanced Search
   
  

  
Go to ITKnowledge Enterprise

Zen of Graphics Programming, 2nd Edition Zen of Graphics Programming, 2nd Edition
by Michael Abrash
Coriolis, The Coriolis Group
ISBN: 1883577896   Pub Date: 04/01/96

Search this book:
 
Previous Table of Contents Next


When all Planes “Don’t Care”

Still and all, there aren’t all that many uses for basic color compare operations. There is, however, a genuinely odd application of read mode 1 that’s worth knowing about; but in order to understand that, we must first look at the “don’t care” aspect of color compare operation.

As described above, during read mode 1 reads the color stored in the Color Compare register is compared to each of the 8 pixels at a given address in VGA memory. But—and it’s a big but—any plane for which the corresponding bit in the Color Don’t Care register is a 0 is always considered a color compare match, regardless of the values of that plane’s bits in the pixels and in the Color Compare register

Let’s look at this another way. A given pixel is controlled by four bits, one in each plane. Normally (when the Color Don’t Care register is 0FH), the color in the Color Compare register is compared to the four bits of each pixel; bit 0 of the Color Compare register is compared to the plane 0 bit of each pixel, bit 1 of the Color Compare register is compared to the plane 1 bit of each pixel, and so on. That is, when the lower four bits of the Color Don’t Care register are all set to 1, then all four bits of a given pixel must match the Color Compare register in order for a read mode 1 read to return a 1 for that pixel to the CPU.

However, if any bit of the Color Don’t Care register is 0, then the corresponding bit of each pixel is unconditionally considered to match the corresponding bit of the Color Compare register. You might think of the Color Don’t Care register as selecting exactly which planes should matter in a given read mode 1 read. At the extreme, if all bits of the Color Don’t Care register are 0, then read mode 1 reads will always return 0FFH, since all planes are considered to match all bits of all pixels.

Now, we’re all prone to using tools the “right” way—that is, in the way in which they were intended to be used. By that token, the Color Don’t Care register is clearly intended to mask one or more planes out of a color comparison, and as such, has limited use. However, the Color Don’t Care register becomes far more interesting in exactly the “extreme” case described above, where all planes become “don’t care” planes.

Why? Well, as I’ve said, when all planes are “don’t care” planes, read mode 1 reads always return 0FFH. Now, when you AND any value with 0FFH, the value remains unchanged, and that can be awfully handy when you’re using the bit mask to modify selected pixels in VGA memory. Recall that you must always read VGA memory to load the latches before writing to VGA memory when you’re using the bit mask. Traditionally, two separate instructions—a read followed by a write—are used to perform this task. The code in Listing 6.2 uses this approach. Suppose, however, that you’ve set the VGA to read mode 1, with the Color Don’t Care register set to 0 (meaning all reads of VGA memory will return 0FFH). Under these circumstances, you can use a single AND instruction to both read and write VGA memory, since ANDing any value with 0FFH leaves that value unchanged.

Listing 6.3 illustrates an efficient use of write mode 3 in conjunction with read mode 1 and a Color Don’t Care register setting of 0. The mask in AL is passed directly to the VGA’s bit mask (that’s how write mode 3 works—see Chapter 4 for details). Because the VGA always returns 0FFH, the single AND instruction loads the latches, and writes the value in AL, unmodified, to the VGA, where it is used to generate the bit mask. This is more compact and register-efficient than using separate instructions to read and write, although it is not necessarily faster by cycle count, because on a 486 or a Pentium MOV is a 1-cycle instruction, but AND with memory is a 3-cycle instruction. However, given display memory wait states, it is often the case that the two approaches run at the same speed, and the register that the above approach frees up can frequently be used to save one or more cycles in any case.

LISTING 6.3 L6-3.ASM

; Program that draws a diagonal line to illustrate the use of a
; Color Don't Care register setting of 0FFH to support fast
; read-modify-write operations to VGA memory in write mode 3 by
; drawing a diagonal line.
;
; Note: Works on VGAs only.
;
; By Michael Abrash
;
stack   segment word stack  'STACK'
         db       512 dup (?)
stack   ends
;
VGA_SEGMENT                EQU     0a000h
SCREEN_WIDTH               EQU     80       ;in bytes
GC_INDEX                   EQU     3ceh    ;Graphics Controller Index
                                           register
SET_RESET                  EQU     0        ;Set/Reset register index in
                                            GC
ENABLE_SET_RESET        EQU     1        ;Enable Set/Reset register index
                                         in GC
GRAPHICS_MODE           EQU     5         ;Graphics Mode register index in
                                          GC
COLOR_DONT_CARE         EQU     7        ;Color Don't Care register index
                                         in GC
;
code    segment word 'CODE'
         assume  cs:code
Start   proc    near
;
; Select graphics mode 12h.
;
         mov      ax,12h
         int      10h
;
; Select write mode 3 and read mode 1.
;
         mov      dx,GC_INDEX
         mov      al,GRAPHICS_MODE
         out      dx,al
         inc      dx
         in       al,dx             ;VGA registers are readable, bless
                                    them!
         or       al,00001011b     ;bit 3=1 selects read mode 1, and
                                      ; bits 1 & 0=11 selects write mode 3
         jmp      $+2                 ;delay between IN and OUT to same
                                      port
         out      dx,al
         dec      dx
;
; Set up set/reset to always draw in white.
;
         mov      al,SET_RESET
         out      dx,al
         inc      dx
         mov      al,0fh
         out      dx,al
         dec      dx
         mov      al,ENABLE_SET_RESET
         out      dx,al
         inc      dx
         mov      al,0fh
         out      dx,al
         dec      dx
;
; Set Color Don't Care to 0, so reads of VGA memory always return 0FFH.
;
         mov      al,COLOR_DONT_CARE
         out      dx,al
         inc      dx
         sub      al,al
         out      dx,al
;
; Set up the initial memory pointer and pixel mask.
;
         mov      ax,VGA_SEGMENT
         mov      ds,ax
         sub      bx,bx
         mov      al,80h
;
; Draw 400 points on a diagonal line sloping down and to the right.
;
         mov      cx,400
DrawDiagonalLoop:
         and      [bx],al          ;reads display memory, loading the
                                     ; latches, then writes AL to
                                     ; the VGA. AL becomes the
                                     ; bit mask, and set/reset provides
                                     ; the actual data written
         add      bx,SCREEN_WIDTH
                                      ; point to the next scan line
         ror      al,1                ;move the pixel mask one pixel to
                                      the right
         adc      bx,0     ;advance to the next byte if the pixel mask
                           wrapped
         loop     DrawDiagonalLoop
;
; Wait for a key to be pressed to end, then return to text mode and
; return to DOS.
;
WaitKeyLoop:
         mov      ah,1
         int      16h
         jz       WaitKeyLoop
         sub      ah,ah
         int      16h                ;clear the key
         mov      ax,3
         int      10h                ;return to text mode
         mov      ah,4ch
         int      21h                ;done
Start   endp
code    ends
         end     Start

I hope I’ve given you a good feel for what color compare mode is and what it might be used for. Color compare mode isn’t particularly easy to understand, but it’s not that complicated in actual operation, and it’s certainly useful at times; take some time to study the sample code and perform a few experiments of your own, and you may well find useful applications for color compare mode in your graphics code.

A final note: The Read Map register has no effect in read mode 1, and the Color Compare and Color Don’t Care registers have no effect either in read mode 0 or when writing to VGA memory. And with that, by gosh, we’re actually done with the basics of accessing VGA memory!

Not to worry—that still leaves us a slew of interesting VGA topics, including smooth panning and scrolling, the split screen, color selection, page flipping, and Mode X. And that’s not to mention actual uses to which the VGA’s hardware can be put, including lines, circles, polygons, and my personal favorite, animation. We’ve covered a lot of challenging and rewarding ground—and we’ve only just begun.

By the way, Listing 6.3 illustrates how write mode 3 can make for excellent pixel- and line-drawing code.


Previous Table of Contents Next

homesubscribesearchfaqsitemapcontactus
Products |  Contact Us |  About Us |  Privacy  |  Ad Info  |  Home

Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc. All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.