[comp.sys.ibm.pc] VGA and Bit Mask Register: HEEEEEELP !

pyt@hprnd.HP.COM (Pierre-Yves Thoulon) (03/06/89)

I've been trying to play with my VGA card and I'm trying to use it in
write mode 2 and to write ot a given pixel after setting the bit mask
correctly.
From I understand, if the bit mask register is set to 0, nothing should
be happening when I write to the display memory, but every time I write
a byte, I see an nice 8 pixel long line appearing on my screen, half
green, half blue.
What am I doing wrong ? Is there any register other than the Mode and
Bit Mask registers that I need to program ?

My test program looks like this:

#define START	(char far *)0xa0000000
#define END	(char far *)0xa0009600
void main(void)
{
	union REGS regs;
	char far *Address;

	regs.h.ah = 0;
	regs.h.al = 0x12;
	int86(0x10, &regs, &regs);	/* set display mode 0x12 */

	outp(0x3ce, 5);	/* Mode register */
	outp(0x3cf, 2); /* Write Mode 2 */

	outp(0x3ce, 8); /* Bit Mask register */
	outp(0x3cf, 0); /* all bits masked */

	for (Address=START; Address < END; Address++)
		*Address = 4;	/* paint pixel Red */
}

I set the video mode to 0x12, but the same behavior occurs in mode 0x10.
Instead of a nice black-remaining screen, I get vertical green and blue
stripes.
If I set the bit mask to something else than 0, the unmasked pixels are
correctly painted, but the masked one are painted green or blue, depending
on where they are in the byte.

In a nutshell, I am unable to update a single pixel without trashing its
7 neighbors. What am I doing wrong ?

Any help VERY MUCH appreciated.

Desperately,
Pyt "starting to see green and blue stripes in bed at night...".
hplabs!hprnd!pyt

BTW: I noticed that if I use write mode 0 rather than write mode 2 in
the small program above, I still get these stupid green and blue stripes.

john@stiatl.UUCP (John DeArmond) (03/07/89)

In article <1040010@hprnd.HP.COM> pyt@hprnd.HP.COM (Pierre-Yves Thoulon) writes:
>I've been trying to play with my VGA card and I'm trying to use it in
>write mode 2 and to write ot a given pixel after setting the bit mask
>correctly.
>From I understand, if the bit mask register is set to 0, nothing should
>be happening when I write to the display memory, but every time I write
>a byte, I see an nice 8 pixel long line appearing on my screen, half
>green, half blue.

The problem here is very simple.  First you gotta remember that you are dealing
with IBM-designed hardware which is to say "it's straaaaange".

Normally, when you think of a 4 plane color video system (RGBI) you would think
the memory would be arranged so that adjacent bits in a byte would address
different color planes.  bit 0 is red, bit 1 is green, bit 2 is blue, etc
with perhaps 2 pixels per byte.  

Well, IBM did not do it that way.  The arranged 4 parallel sets of memory
so that each logical address can address any of 4 physical memory banks
depending on the setting of several registers in the controller.  Within
a plane, a byte represents 8 adjacent pixels (even this depends on the mode -
I'm assuming 640x350 right now).  You can either set up dot writes to 
a plane or you can use a {semi, poorly} documented mode whereby a plane is
mapped into the processor address space.  You then write one plane at a time.
To set or reset a specific pixel, you must retrieve the applicable byte
and mask the bit.

Sorry if i'm short on specifics but it's been awhile since I worked on 
this.  I'll be glad to scrounge some code up from home that implements 
this write and read VERY fast.

I'd also suggest you buy a book from Microsoft Press called "Programmers
guide to the IBM video adaptors" or something like that.  You can tell
it right away because the listings are printed in some of the worst 
icky green ink you ever tried to read.  There are some bugs in this book
but my code documents the ones I've found so the book should be of 
real value if you are really hacking an EGA/VGA card.

John

-- 
John De Armond, WD4OQC                     | Manual? ... What manual ?!? 
Sales Technologies, Inc.    Atlanta, GA    | This is Unix, My son, You 
...!gatech!stiatl!john                     | just GOTTA Know!!! 

chasm@killer.DALLAS.TX.US (Charles Marslett) (03/07/89)

In article <1040010@hprnd.HP.COM>, pyt@hprnd.HP.COM (Pierre-Yves Thoulon) writes:
:> I've been trying to play with my VGA card and I'm trying to use it in
:> write mode 2 and to write ot a given pixel after setting the bit mask
:> correctly.
:> . . .
:> My test program looks like this:
:> 
:> #define START	(char far *)0xa0000000
:> #define END	(char far *)0xa0009600
:> void main(void)
:> {
:> 	union REGS regs;
:> 	char far *Address;
:> 
:> 	regs.h.ah = 0;
:> 	regs.h.al = 0x12;
:> 	int86(0x10, &regs, &regs);	/* set display mode 0x12 */
:> 
:> 	outp(0x3ce, 5);	/* Mode register */
:> 	outp(0x3cf, 2); /* Write Mode 2 */
:> 
:> 	outp(0x3ce, 8); /* Bit Mask register */
:> 	outp(0x3cf, 0); /* all bits masked */
:> 
:> 	for (Address=START; Address < END; Address++)

To load the 32-bit latch register, insert a read operation here:
                junk = *Address; /* loads the latches so unmodified bits are OK */

:> 		*Address = 4;	/* paint pixel Red */
:> }
:> 

The effect you were seeing was the contents of the latches (left over from
long ago) being copied into the current byte in memory (bye-bye other 7 bits).

:> Desperately,
:> Pyt "starting to see green and blue stripes in bed at night...".
:> hplabs!hprnd!pyt

Charles Marslett
===========================================================================
Charles Marslett
STB Systems, Inc.  <== Apply all standard disclaimers
Wordmark Systems   <== No disclaimers required -- that's just me
chasm@killer.dallas.tx.us

pyt@hprnd.HP.COM (Pierre-Yves Thoulon) (03/08/89)

OK ! as usual, every time I post something to notes, I find the answer
by myself the day after... The solution is that I forgot to load the
internal VGA latch before doing the modify/write. The full stuff is
below:


#define START	(char far *)0xa0000000
#define END	(char far *)0xa0009600
void main(void)
{
	union REGS regs;
	char far *Address;
>>>>>>	char Dummy;

	regs.h.ah = 0;
	regs.h.al = 0x12;
	int86(0x10, &regs, &regs);	/* set display mode 0x12 */

	outp(0x3ce, 5);	/* Mode register */
	outp(0x3cf, 2); /* Write Mode 2 */

	outp(0x3ce, 8); /* Bit Mask register */
	outp(0x3cf, 0); /* all bits masked */

	for (Address=START; Address < END; Address++)
	{
>>>>>>>>	Dummy = *Address; /* dummy read */
		*Address = 4;	/* paint pixel Red */
	}
	
	pause();
	reset();
}

toma@tekgvs.LABS.TEK.COM (Tom Almy) (03/09/89)

In article <3552@stiatl.UUCP> john@stiatl.UUCP (John DeArmond) writes:
...
>I'd also suggest you buy a book from Microsoft Press called "Programmers
>guide to the IBM video adaptors" or something like that.  You can tell
>it right away because the listings are printed in some of the worst 
>icky green ink you ever tried to read.  
...

The most recent printing has the listings in black ink; accept no substitutes!
Also the title is "Programmers Guide to PC & PS/2 Video System" by Richard
Wilton.

Tom Almy
toma@tekgvs.labs.tek.com
Standard Disclaimers Apply