OSDev.org

The Place to Start for Operating System Developers
It is currently Tue Mar 28, 2017 3:38 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 4 posts ] 
Author Message
 Post subject: VGA Artefacts & understanding planes
PostPosted: Thu Mar 02, 2017 1:09 am 
Offline

Joined: Sat Apr 04, 2015 9:35 am
Posts: 11
Location: Windsor, UK
Hey,

Recently I've been trying to get VGA drawing working (640x480 16-colours) and have been drawing from the VGA Hardware page on the wiki, Chris Giese's example code and osdever.net for help learning and understanding everything. My first attempts were at drawing single pixels to the screen using the method shown in Chris Giese's demo, but obviously that was hilariously slow and more of a demo of how the memory is addressed. So I began taking what I had learnt there and from other places and began putting together something. It mostly works, but there is an issue:

Image

There are artefacts showing in the image. I've tried inspecting the appropriate memory locations in BOCHS and everything appears to be what I expected, but this is where I'm not sure my understanding of the planes is quite correct.

Plane 0 (0xA0000 - 0xAFFFF) is where bit 4 of the colour goes (brightness)
Plane 1 (also 0xA0000 - 0xAFFFF) is where bit 3 of the colour goes (red)
Plane 2 (also 0xB0000 - 0xB7FFF) is where bit 2 of the colour goes (green)
Plane 3 (also 0xB8000 - 0xBFFFF) is where bit 1 of the colour goes (blue)

The problem is I can quite understand what is going on with Plane 0 and Plane 1? Surely plane 1 should be at 0xa8000. However that just makes the situation worse. I also clear all of VGA memory before re-enabling the display, so I'm pretty certain its my code generating this noise.

What I'm doing is working in an offscreen buffer, where each pixel is 1 byte (wasteful I know, but more interested in getting it functional for now). Currently I'm trying to blit the entire thing to VGA memory at once (operating on runs of 8 pixels at a time.) The code is below:

Code:
static inline vga_set_plane(uint8_t p)
{
   p &= 3;
   uint8_t pmask = 1 << p;
   outb(VGA_GC_INDEX, 4);
   outb(VGA_GC_DATA, p);
   outb(VGA_SEQ_INDEX, 2);
   outb(VGA_SEQ_DATA, pmask);
}

static inline vga_blit_buffer_full(struct display *display)
{
   static uint32_t plane_offsets[] = {0xa0000, 0xa8000, 0xb0000, 0xb8000};
   static uint8_t c_mask[] = {0x1, 0x2, 0x4, 0x8};
   static uint8_t c_shift[] = {0, 1, 2, 3};

   uint32_t width_in_bytes = display->width / 8;
   uint32_t buffer_offset = (uint32_t)display->buffer;
   for (uint32_t y = 0; y < display->height; ++y) {
      for (uint32_t x = 0; x < display->width; x += 8) {

         uint8_t *pixel = (uint8_t *)buffer_offset;
         uint32_t vga_offset = (width_in_bytes) * y + x / 8;

         for (uint8_t p = 0; p < 4; ++p) {
            vga_set_plane(p);
            uint8_t chunk = 0;
            uint8_t mask = 0x80;
            for (uint32_t i = 0; i < 8; ++i) {
               uint8_t c = ((*(pixel + i) & c_mask[p]) >> c_shift[p]);
               if (c) {
                  chunk |= mask;
               }
               mask >>= 1;
            }
            *((uint8_t *)(plane_offsets[p] + vga_offset)) = chunk & 0xFF;
         }

         buffer_offset++;
      }
   }
}


The display struct is just a structure in which I keep some properties about the current state of the display, dimensions, off screen buffer and such. I'm pretty certain it's probably my understanding of VGA planes that is causing the issue. If anyone could point me in the right direction that would be appreciated.

Edit
I've just tried setting the screen to be red and this is the result that I get

Image

_________________
I'm writing a series of Novels, making a toy Operating System and experimental compiler... I seemingly hate free time (not true) and trying to destroy it with as many large projects as possible.


Top
 Profile  
 
 Post subject: Re: VGA Artefacts & understanding planes
PostPosted: Thu Mar 02, 2017 1:41 am 
Offline
Member
Member
User avatar

Joined: Sun Nov 20, 2016 7:26 am
Posts: 113
Location: At somewhere in universe
I can be wrong as I didn't use VGA for years, but maybe it worth trying.

I remember write addresses doesn't change by changing planes, it is always 0xA0000. VGA addresses are memory-mapped, so changing plane will make new plane point at 0xA0000.

Again, I can be wrong, as I forgot VGA.


Top
 Profile  
 
 Post subject: Re: VGA Artefacts & understanding planes
PostPosted: Thu Mar 02, 2017 1:44 am 
Offline

Joined: Sat Apr 04, 2015 9:35 am
Posts: 11
Location: Windsor, UK
Agola wrote:
I can be wrong as I didn't use VGA for years, but maybe it worth trying.

I remember write addresses doesn't change by changing planes, it is always 0xA0000. VGA addresses are memory-mapped, so changing plane will make new plane point at 0xA0000.

Again, I can be wrong, as I forgot VGA.


However in this case you are very correct! That seems to have fixed the issue. I knew there had to be something I was missing with regards to those planes.

Thanks a lot!

_________________
I'm writing a series of Novels, making a toy Operating System and experimental compiler... I seemingly hate free time (not true) and trying to destroy it with as many large projects as possible.


Top
 Profile  
 
 Post subject: Re: VGA Artefacts & understanding planes
PostPosted: Thu Mar 02, 2017 1:51 am 
Offline
Member
Member
User avatar

Joined: Sat Jan 15, 2005 12:00 am
Posts: 7745
Location: At his keyboard!
Hi,

snijj wrote:
Plane 0 (0xA0000 - 0xAFFFF) is where bit 4 of the colour goes (brightness)
Plane 1 (also 0xA0000 - 0xAFFFF) is where bit 3 of the colour goes (red)
Plane 2 (also 0xB0000 - 0xB7FFF) is where bit 2 of the colour goes (green)
Plane 3 (also 0xB8000 - 0xBFFFF) is where bit 1 of the colour goes (blue)


No; there's a "plane select register" that controls which plane you're writing to, and it's actually like this:
    Plane 0 (0xA0000 - 0xA7FFF) is where bit 3 of the colour goes (brightness)
    Plane 1 (also 0xA0000 - 0xA7FFF) is where bit 2 of the colour goes (red)
    Plane 2 (also 0xA0000 - 0xA7FFF) is where bit 1 of the colour goes (green)
    Plane 3 (also 0xA0000 - 0xA7FFF) is where bit 0 of the colour goes (blue)

However it's not that simple because there's also different "write modes", and it could be completely different, and there's other registers (masks, etc) that can confuse everything more.

My advice is to set the mask to "mask nothing" and make sure the write mode is sane immediately after setting the video mode and never touch any of them ever again. Then build the frame in RAM organised as "all bits for plane0, then all bits for plane1, etc"; then select plane0 and write bit0 for all pixels at once, then select plane1 and write bit1 for all pixels at once, etc.


Cheers,

Brendan

_________________
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot], DropDemBits, Google [Bot], MSNbot Media and 5 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group