Reputation: 1395
I'm developing a simple OS' kernel and I am trying to make a working video library so I can use it later. (VBE version 3.0, 1920 * 1080px, 32bpp).
I wrote a pixel plotting function in C which seems to be working fine:
void putPixelRGB(struct MODEINFOBLOCK mib, short x, short y, int color) {
int *pos = (char *)mib.framebuffer + x * 4 + y * 7680;
*pos = color;
}
Then I tried to fill the whole screen using this function and two for
loops:
for(int i = 0; i < 1920; i++) {
for(int j = 0; j < 1080; j++) {
putPixelRGB(mib, i, j, 0xFFFFFF);
}
}
This is the result that I ended up with so far:
dloop:
mov byte[eax], 0xFF ;eax contains the address of the FB memory.
inc eax
cmp eax, 829440 ;829440 = 1920 * 1080 * 4
jg done
jmp dloop
done:
hlt
Any idea why this doesn't work? Did I access memory the wrong way?
The MODEINFOBLOCK
structure:
struct MODEINFOBLOCK {
int attributes;
char windowA, windowB;
int granularity;
int windowSize;
int segmentA, segmentB;
long winFuncPtr;
int pitch;
int resolutionX, resolutionY;
char wChar, yChar, planes, bpp, banks;
char memoryModel, bankSize, imagePages;
char reserved0;
char readMask, redPosition;
char greenMask, greenPosition;
char blueMask, bluePosition;
char reservedMask, reservedPosition;
char directColorAttributes;
char* framebuffer;
long offScreenMemOff;
int offScreenMemSize;
char reserved1 [206];
};
Upvotes: 1
Views: 94
Reputation: 37232
You probably didn't enable the A20 gate.
With A20 gate disabled, the 21st bit of physical addresses is ignored/masked to zero (to help emulate an old 8086 CPU where there were only 20 address lines). The result is that when you try to fill the frame buffer; the first 1 MiB of pixels works, then the second 1 MiB of pixels overwrites the first 1 MiB of pixels (leaving an unfilled black band), then the third 1 MiB of pixels works but gets overwritten by the fourth 1 MiB of pixels, and so on.
This creates "filled and not filled" horizontal bands. If you do the math, ("1 MiB / 1920 / 4") you'd expect the horizontal bands to be about 136.5 pixels tall; so there'd be slightly more than 7 bands ("1000 / 136.5"); which is what you're getting.
To enable the A20 gate; see https://wiki.osdev.org/A20_Line .
Upvotes: 3