[comp.os.msdos.programmer] VGA screen, writemode 2, help needed.

zonker@diku.dk (Claus Engdahl) (06/07/91)

Hi.

I'm desperately seeking help from one of you VGA gurus out there. 

I am trying to write to screen, using writemode 2. I manage to get
something written, but the bitmask register seems to work in strange
and wonderous ways :-(

Having read "Programmers guide to the EGA and VGA cards", I managed to
cook up the following routine:

1. First setup screen, using bios interrupt (I use mode 0x12,
640x480x16, VGA only mode). 

2. Set WM field of MODE register (a Graphics Controller Register), to
writemode 2. 

3. Set Function Select field, of the "Data Rotate Register" to 0.

4. To enable writing to all 4 bitplanes, I set the Map Mask register (a
sequencer register), to 0x0F.

5. The last thing I do is set the Bit Mask register to a pattern
according to the pixels I want to write (in my case 0x01).


If I set BitMask to 0x01 (write the rightmost pixels in all bytes),
and then try to write a 0x0F to a byte in the screen mem, I would
assume that I would get a single white pixel on the screen. I get
several pixels, with different colours.

The strange thing is, that when I try to set the bitmask to 0xFF
(write to all pixels in byte), I get a line with the correct colour. 


Should the registers be setup, in a special order? 

Is there something missing?


Any help (and/or references to examples), would be appreciated.

Claus (zonker@diku.dk)
------------------------------------------------------------------
For completeness, my src (TC2.0) has been appended:

/* Set Graphics Controller Register writemode 2 */
outportb(0x03CE, 0x05); outportb(0x03CF, 0x02);

/* No data rotate, no function select, just let my data through (please) */
outportb(0x03CE, 0x03); outportb(0x03CF,0x00);

/* Enable all four bitplanes, set mapmask reg. to: 00001111 */
outportb(0x03C4, 0x02); outportb(0x03C5, 0x0F);

/* Now set bitmask to indicate which bits I want to modify */
outportb(0x03CE, 0x08); outportb(0x03CF, 0x01);

/* Try to draw some white dots */
for(i=0; i!=80; i++)
pokeb(0xA000, i, 0x0F);

/* Here I get some blue, green and white dots, when run once. When I */
/* try to run it again, I get some red dots.                         */



-- 
Edb-afdeligen     (staff@diku.dk)
V/ Claus Engdahl (zonker@diku.dk)

andy@bluemoon.uucp (Andy Vaught) (06/08/91)

zonker@diku.dk (Claus Engdahl) writes:

> Hi.
> 
> I'm desperately seeking help from one of you VGA gurus out there. 
> 
> I am trying to write to screen, using writemode 2. I manage to get
> something written, but the bitmask register seems to work in strange
> and wonderous ways :-(
> 
> Having read "Programmers guide to the EGA and VGA cards", I managed to
> cook up the following routine:
> 
Whoa! theres your problem right there-- lousy docs! I wasted my money on 
this book too. Information is duplicated through the whole book, with each 
duplication leaving something different out. I eventually ended up 
realising what was going on, but it took far more skull sweat than it 
should have. The way to fix your program is to do a "dummy read" of the 
location containing the pixels you want to change. This read has the 
effect of initializing the internal 32-bit latch to the contents of screen 
memory. During the write operation, the ALU operates on what is in the 
latch, not what is in the memory location in question. After the operation 
is complete, then the new contents of the latch are written to video 
memory.

------------------------------------------------------------------
 Andy Vaught (Fuzzy Andy)  ::  C Code. C Code Run. Run C code, Run...
 Grad Student on Vacation  ::  before I whip out my 12-Gauge
    andy@bluemoon.uucp     ::  Dynamic Debugging Tool!