[comp.graphics] VGA - direct memory access question

IAP@psuvm.psu.edu (Kirk Hanawalt) (02/08/90)

    I'm trying to write a program (TurboC 2.0, IBM PS/2 Model 50
with VGA adapter, HP LaserJet II) to dump a bitmap image of the
high resolution VGA screen to a LaserJet printer.  Using the
TurboC getpixel function, the 640x480 graphics screen can be
dumped in about 35 seconds.  I would like to access memory
directly, and dispense with getpixel() altogether.
Unfortunately, I can't figure out how the pixels are mapped in
memory.

    Starting at address A000:0000, each byte in memory seems to
indicate the on/off state of 8 pixels on the screen.  For
example, the statement:

        *((unsigned char far *) 0xa0000000L) = 0x80;

turns the first pixel in the first row of the graphics screen
on.  I can use this method to get monochrome graphics.
Obviously, 16 color graphics requires 4 bits to specify pixel
color.

    The problem is this:  when using this method to read pixels
from the screen, I only get the odd color pixels (for the
default EGA/VGA palette 1=blue, 3=cyan,...,15=white).  The even
color pixels do not have a bit set.  The following pseudo-code
works only for odd colors, the even colors aren't printed.

     ptr=(unsigned char huge *) 0xa0000000L;
     for (j=0; j<=MaxY; j++)
       for (i=0; i < (MaxX+1)/8; i++)
         Send_To_Printer(*ptr++);  /* send byte = 8 pixels */

This method dumps the screen to the LaserJet in about 15
seconds, so I would like to use it.  However, getting only
half of the displayed colors printed is a drawback :-).

    My question is this: where in the heck are the pixel values
stored in memory for the VGA adapter in 640x480 16 color mode?
Every book I've seen covers only monochrome graphics and uses
the method above to write/read pixels.
-------
Kirk Hanawalt     |                                        |
Chem. Eng. Dept.  |  BITNET:  IAP @ PSUVM                  |
Penn. St. Univ.   |   OTHER:  ...!psuvax1!iap@psuvm.bitnet |

zmact61@tsun4.doc.ic.ac.uk.doc.ic.ac.uk (D Spinellis) (02/09/90)

In article <90039.091705IAP@PSUVM.BITNET> IAP@psuvm.psu.edu (Kirk Hanawalt) writes:
>
>    I'm trying to write a program (TurboC 2.0, IBM PS/2 Model 50
>with VGA adapter, HP LaserJet II) to dump a bitmap image of the
>high resolution VGA screen to a LaserJet printer.
[...]
>Unfortunately, I can't figure out how the pixels are mapped in
>memory.
[...]
The EGA and VGA cards have all the color planes mapped into the same 
memory address.  You specify from which color plane you want to read
or write by outputing appropriate values to the various card controller
registers.  Different read and write modes give you the ability to access
the planes together; naturally with some restrictions.  For example you can
write a color value to a specified pixel, or you can set all color planes
to the same value.  The Technical Reference Manual for the PS/2 systems
covers these things.

>    The problem is this:  when using this method to read pixels
>from the screen, I only get the odd color pixels
>The following pseudo-code
>works only for odd colors, the even colors aren't printed.
>
>     ptr=(unsigned char huge *) 0xa0000000L;
>     for (j=0; j<=MaxY; j++)
>       for (i=0; i < (MaxX+1)/8; i++)
>         Send_To_Printer(*ptr++);  /* send byte = 8 pixels */
>
[...]
You need to modify your code to access the four color planes.  Register 4
in address 0x3cf can be set to specify which plane you want to read.  You
must set the index register in address 0x3ce to 4 to point to the correct
register.  The following code should work:

     outp(0x3c4, 4);			/* Set index register */
     ptr=(unsigned char huge *) 0xa0000000L;
     for (j=0; j<=MaxY; j++)
       for (i=0; i < (MaxX+1)/8; i++, ptr++)
	 for (k = 0; k < 4; k++) {
	   outp(0x3cf, k);		/* Specify color plane */
           Send_To_Printer(*ptr, k);	/* send byte = 8 pixels */
	 }

Diomidis
--
Diomidis Spinellis                  Internet:                 dds@cc.ic.ac.uk
Department of Computing             BITNET:                   dds@cc.ic.ac.uk
Imperial College                    UUCP:   ...!cernvax!cc.imperial.ac.uk!dds
London SW7 2BZ                      JANET:                    dds@uk.ac.ic.cc

scjones@sdrc.UUCP (Larry Jones) (02/10/90)

In article <90039.091705IAP@PSUVM.BITNET>, IAP@psuvm.psu.edu (Kirk Hanawalt) writes:
>     I'm trying to write a program (TurboC 2.0, IBM PS/2 Model 50
> with VGA adapter, HP LaserJet II) to dump a bitmap image of the
> high resolution VGA screen to a LaserJet printer.  Using the
> TurboC getpixel function, the 640x480 graphics screen can be
> dumped in about 35 seconds.  I would like to access memory
> directly, and dispense with getpixel() altogether.
> Unfortunately, I can't figure out how the pixels are mapped in
> memory.

Both the EGA and VGA need more memory than there is room for in
the reserved address space.  To get around the problem, they have
a number of different mapping schemes which allow access to some
of the bits at a time.  Precisely which bits and where in memory
they are depends on the particular mapping scheme which has been
invoked.  I suggest you get a good book such as Programmer's
Guide to PC and PS/2 Video Systems (Microsoft Press, if I
remember correctly) and study it.  The mapping schemes are
incredibly complex.
----
Larry Jones                         UUCP: uunet!sdrc!scjones
SDRC                                      scjones@SDRC.UU.NET
2000 Eastman Dr.                    BIX:  ltl
Milford, OH  45150-2789             AT&T: (513) 576-2070
"You know how Einstein got bad grades as a kid?  Well MINE are even WORSE!"
-Calvin

lorena@infmx.UUCP (Lon Anderson) (02/13/90)

The VGA adapter uses a concept knows as memory planes.  These memory
planes map th the same location in memory and hold the "other" bits
associated with a pixel in the color modes.  You need to toggle the
planes on and off to read the individual bits that make up the 4 bits
of the pixel.  This is done by manipulating the VGA registers.

The code to do this is available in a number of books on VGA
programming.  Two I would recomend are Programmers guide to the EGA
and VGA and Programming the VGA adapter by Brady.  These are available
at most good computer book stores.

greg@bluemtn.uucp (Greg Richter (2XS)) (02/14/90)

I recommend you take a look at "Programmer's Guide to the EGA/VGA"  it 
explains these matters clearly, and in sufficient detail to be useful.

At most bookstores, about 15 bucks.

-GR

news@nems.dt.navy.mil (USENET News System) (02/26/90)

From: flitter@dtrc.dt.navy.mil (Flitter)
Path: dtrc!flitter

>    My question is this: where in the heck are the pixel values
>stored in memory for the VGA adapter in 640x480 16 color mode?
>Every book I've seen covers only monochrome graphics and uses
>the method above to write/read pixels.

  In 16 color mode there are four bit planes each of which are mapped into the
  same address space: A0000 - AFFFF. In order to get the value of a pixel you
  have to use the segment registers so you get all four bit planes. You will
  want to AND them together to find whether the monochrome pixel is on or off.
  I don't remember the proper settings off the top of my head. If you still
  need them write me a message and I'll look it up.