VGA 640x480 Pixel Write....400 points!!!

Hello Everyone...
OK, so I can write to the VGA memory and get something on the screen, I get the write color and beginning position, but when I try to write only one pixel, I get what seems to be 4 pixels in a row. I have an idea of what it is, but I can seem to come up with a solution for it. Anyone care to help? I need to be able to write to one pixel, with a specified color.

Who is Participating?

Improve company productivity with a Business Account.Sign Up

MrT-RSIConnect With a Mentor Commented:
you have to select the right plane first:

This is something from a Pascal Mode-X library, but it should get you on the way:

  procedure putpixel(x,y : word;color : byte); assembler;

    { set plane }
    mov dx,$03c4 {VGA sequencer}
    mov al,$02 {index $02 -> set write plane register}
    mov cx,x
    and cl,00000011b {x mod 4}
    mov ah,1
    shl ah,cl {which plane}
    out dx,ax
    { calculate offset }
    mov di,x
    shr di,2 {x div 4}
    mov ax,y
    mov cl,mxsizeshift1
    shl ax,cl
    add di,ax
    mov ax,y
    mov cl,mxsizeshift2
    shl ax,cl
    add di,ax {offset}
    mov ax,$a000 {VGA segment}
    mov es,ax
    { put pixel }
    mov al,color
    mov es:[di],al

By putting 00001111b in ah you can write 4 pixels at once on all planes (as you already dicovered).

Size shifters 1 and 2 are used to multiply the y coord with the width of the screen.
In which Mode? 16 colors or 256 colors? pls post some of your code.

fastawdtsiAuthor Commented:
648x480 16 colors...


Sorry for my late response, I'm on the vacation..
Here is the code, although it's not a pure asm code, but it really can work, it works well in my windows WDM driver(both CRT and LCD)...
I think it's easy for you to convert it into assemble languange, if not, please tell me, I hope I can convert it for you.

void  outportb(short port, BYTE val)
            mov dx, port
            mov al, val
            out dx, al

gramMem is your VGA memory pointer. A000:0000
// x,y--> coordinates
// val--> color
// odd--> see WriteLine function, FIXME, this parameter could be optimized
void drawpixel16(int x, int y, BYTE val, BYTE odd)
      BYTE i = 3 - x % 4;
      BYTE temp;

      /*0 - means copy, 0x8 - AND, 0x10 - OR, 0x18 - XOR*/
      outportb(0x3ce, 0x03);
      outportb(0x3cf, 0x0);
      outportb(0x3ce, 0x05);
      outportb(0x3cf, 0x02);

      outportb(0x3C4, 2);
      outportb(0x3C5, 0xFF);

      /*ditermine which bit we want to change*/
      /*Bit Mask Register, enable/disable the bit modify with 0/1*/
      outportb(0x3ce, 0x08);
      if(x%8 < 4)
            outportb(0x3Cf, 1<<(i+4));
            outportb(0x3Cf, 1<<(i+0));

      temp = gramMem[y*80 + x/8];    // need to read it again! otherwise in you can't show anything, it's crazy!

      if(x%2 == 0)      
            gramMem[y*80 + x/8] = val>>(odd?0:4);
            gramMem[y*80 + x/8] = val>>(odd?4:0);

// how to draw a line
void WriteLine(int x, int y, BYTE* buffer, int nlen, int bitcount)
      case 4:
                  int i=0;
                  BYTE odd = x % 2;

                  while(i < nlen)
                        drawpixel16(x, y, *buffer, odd);

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.