I tried what you said and it didn't worked :'(
But then I got something really strage from some more testing.
First of all I swapped the red and blue component and said red=color&0xFF and blue=(color>>16)&0xFF but it should be the other way around.
Code: Select all
#define setpix(i,j,color)\
{\
UBYTE* cTemp = &lfb[i*(mode_info->bpp>>3) + j*mode_info->pitch];\
cTemp[mode_info->red_field_pos>>3] = (color>>16) & 0xff;\
cTemp[mode_info->green_field_pos>>3] = (color>>8) & 0xff;\
cTemp[mode_info->blue_field_pos>>3] = color & 0xff;\
}
UBYTE* lfb = mode_info->physbase;
setpix(0, 0, 0xFF0000);
setpix(2, 0, 0xFF0000);
And now the strange thing is this:
So it sets both pixels correctly... but they are really wide...
I don't think thats right...
And even stranger:
Code: Select all
for (UINT i = 0; i < mode_info->width; i += 2) {
setpix(i, 0, 0xFF0000);
}
for (UINT i = 0; i < mode_info->width; i += 2) {
setpix(i, 1, 0x00FF00);
}
turns into this:
Now I'm totally confused but I can say:
- 1 row has 80 of these too big pixels
- when I'm still in the row but >=80 it wraps to the next row
- y gets me into the next of these big rows
This is so confusing. Is it a QEMU bug, is it a damn simple bug in my code or is vesa so confusing? I'm not getting it. Please help me guys
cbOP_
EDIT:
My next thought was that it could be a bug in my initialization code:
Code: Select all
ModuleVesaSetMode(mode | 0x4000);
ModuleVesaGetModeInfo(mode, mode_info);
I'm searching for the best mode, setting it like this and drawing it into the buffer. Is there something missing?
These functions are declared as:
Code: Select all
static inline VOID ProtectedToRealPointer(UPTR ptr, USHORT* seg, USHORT* off) {
*seg = ptr >> 4;
*off = ptr & 0xF;
}
USHORT ModuleVesaGetModeInfo(USHORT mode, VESA_MODE_INFO info) {
DREGISTERS16 regs;
regs.ax = 0x4F01;
regs.cx = mode;
ProtectedToRealPointer(info, ®s.es, ®s.di);
KernelInterrupt(0x10, ®s);
return regs.ax;
}
USHORT ModuleVesaSetMode(USHORT mode) {
DREGISTERS16 regs;
regs.ax = 0x4F02;
regs.cx = mode;
KernelInterrupt(0x10, ®s);
return regs.ax;
}
KernelInterrupt() does work 100% (it's a renamed version of int32())