🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.sys.ibm.pc
Article #42125

Re: VGA - direct memory access question

#42125
From: Bill Ives
Date: Fri, 09 Feb 1990 15:42
99 lines
4727 bytes
>/ hpctdls:comp.sys.ibm.pc / IAP@psuvm.psu.edu (Kirk Hanawalt) /  7:17 am  Feb  8, 1990 /

>    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.

>Kirk Hanawalt     |                                        |
>Chem. Eng. Dept.  |  BITNET:  IAP @ PSUVM                  |
>jPenn. St. Univ.   |   OTHER:  ...!psuvax1!iap@psuvm.bitnet |


   You are correct -- you cannot directly access the entire screen
   the way you are currently.  The EGA and VGA ( in color graphics
   modes ) screen is made up of bit planes.  Thus in 640 by 480 16 color
   graphics -- there are 4 bit planes.  Your technique reads only the
   currently active bit plane -- probably plane 0 .

   Now, there are two techniques to actually read the screen memory.
   
   1) use BIOS read pixel function -- this will work but is probably
      not the most optimal.
   2) talk directly to the video hardware -- this is faster but
      requires more work.  Thus you should really get a good
      EGA/VGA h/w reference book for all the details.  For now, I
      will try to give an outline for what you have to do to
      read the entire screen ( since I have also written a graphics
      dump program for the Laserjet/PaintJet/ThinkJet series as you
      are now trying to do)
      First some terminology - since there are 4 bit planes
      there has to be a way of selecting which bit plane is
      currently active.  The graphics controller register
      Read Map Select Register (Index 4) does this function.
   
      Thus the graphics controller index register is at port 3ceh
      and the Read Map Select Register is selected to be at port
      3cfh by writing 4 to the graphics controller index reg:

        mov dx, 3ceh ; set DX to GC index register
        mov al,4 ;
        out dx,al ; select register index 4 -- the Read Map Select Register

        mov al,3  ; let's select bit plane 3
        inc dx
        out dx,al

      Selecting the bit plane is not all that has to be done to
      read the pixels from a particular bit plane.  You must also
      use the Bit Mask Register.  This tells the adaptor which bits
      in a particular byte you are interested in.  For reading the
      entire screen, you want to read all the bits for each byte.

        mov dx,3ceh ; set DX to GC index register
        mov al,8    ; Bit Mask Register is at index 8
        out dx,al   ; select bit mask register
        mov al,0ffh ; set bit mask to all 1's .
        inc dx
        out dx,al

      Now, you also have to make sure you are in read mode 0 for this
      to work.  SInce this is the default for BIOS don't worry about
      it until you get to more advanced functions.  Now to read
      an entire bit plane from bit plane 3 to ES:DI you would loop
      640 * 480 /8 bytes or 38400 times.

        cld
        mov ax,0a000  ; set ds:si to bit plane start
        mov ds,ax
        mov si,0
        mov dx,3ceh
        mov ax,08ffh ; set bit mask reg to all 1's
        out dx,ax
        mov ax,0403h ; select bit plane 3
        out dx,ax
        mov cx,38400 ; set loop count.
        rep movsb

      I hope this helps. I did the algorithm above from memory so
      there may be minor mistakes - hey no one's perfect.  But the
      algorithm is essentially correct in how to read screen memory.

      Bill Ives
      HP CTD
      #include <standard disclaimer here>
Technical Details
Message-ID: <2010022@hpctdls.HP.COM>
Path: arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!cs.utexas.edu!tut.cis.ohio-state.edu!snorkelwacker!mit-eddie!uw-beaver!Teknowledge.COM!unix!hplabs!hpfcso!hpldola!hpctdlb!hpctdls!wei
References: <90039.091705IAP@PSUVM.BITNET>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!cs.utexas.edu!tut.cis.ohio-state.edu!snorkelwacker!mit-eddie!uw-beaver!Teknowledge.COM!unix!hplabs!hpfcso!hpldola!hpctdlb!hpctdls!wei
From: wei@hpctdls.HP.COM (Bill Ives)
Newsgroups: comp.sys.ibm.pc
Subject: Re: VGA - direct memory access question
Message-ID: <2010022@hpctdls.HP.COM>
Date: 9 Feb 90 15:42:44 GMT
References: <90039.091705IAP@PSUVM.BITNET>
Organization: Hewlett-Packard CTD, Colo. Spgs.
Lines: 99