Page 1 of 1
Strange behavior with VESA
Posted: Mon Nov 23, 2015 9:40 am
by cbOP
Hey OSDev guys
I'm currently working on a small kernel and, more precisly, on the VESA driver.
This is my test code:
(It should draw 1/3 red, 1/3 green, 1/3 blue in this exact order)
Code: Select all
UBYTE* lfb = mode_info->physbase;
for (UINT i = 0; i < mode_info->width; i++) {
for (UINT j = 0; j < mode_info->height; j++) {
UINT _1of3 = mode_info->width / 3;
UINT color = (i >= 2*_1of3) ? 0xFF0000FF : (i >= _1of3) ? 0xFF00FF00 : 0xFFFF0000;
UINT x = i;
UINT y = j;
UBYTE* cTemp = &lfb[x*(mode_info->bpp>>3) + y*mode_info->pitch];
cTemp[mode_info->red_field_pos>>3] = color & 0xff;
cTemp[mode_info->green_field_pos>>3] = (color>>8) & 0xff;
cTemp[mode_info->blue_field_pos>>3] = (color>>16) & 0xff;
}
}
But I'm getting this strange output:
You can see that after the red and after the green part there is a mixed line, so I think the framebuffer is drawn vertically several times and I don't get why :/
The display mode is 2560x1600x32. (I think memory_model==6 and attributes&0x90!=0x90 but I'm not 100% sure)
I hope you guys are better than me
cbOP_
EDIT:
On 320x200x24 the behavior is even stranger:
Re: Strange behavior with VESA
Posted: Tue Nov 24, 2015 2:00 am
by sebihepp
Could you please try the following:
exchange x and y (or i and j)
if that doesn't work, then additionally divide width and height by. (bpp>>3)
I don't know, but I have a suspicion...
Re: Strange behavior with VESA
Posted: Tue Nov 24, 2015 3:46 pm
by cbOP
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())
Re: Strange behavior with VESA
Posted: Tue Nov 24, 2015 4:43 pm
by jnc100
Are you able to dump all the members of the mode_info struct anywhere? e.g. to text mode before actually performing the mode switch or to a serial port or emulator debug port etc? I'd imagine the answer will lie in there somewhere.
Regards,
John.
Re: Strange behavior with VESA
Posted: Wed Nov 25, 2015 11:47 am
by cbOP
So I dumped all data and don't know whats going on. I don't see anything wrong.
cbOP_
Re: Strange behavior with VESA
Posted: Fri Nov 27, 2015 5:18 am
by sebihepp
I don't see any field called "WinFuncPtr". Could you please check if your mode_info structure is correct?
And could you also print Headers of VBE2.0?
Edit: Does it only happen in QEmu? What happens in Bochs? What on real hardware?
Re: Strange behavior with VESA
Posted: Fri Nov 27, 2015 5:36 am
by cbOP
win_func_ptr exists I just didn't print it out but here is the complete structure:
I wanted to make it cleaner but that didn't fit into the window.
cbOP_
Re: Strange behavior with VESA
Posted: Fri Nov 27, 2015 6:02 am
by jnc100
Your width/height/pitch etc seem reasonable. Out of interest, how is your UBYTE typedef'd?
Regards,
John.
Re: Strange behavior with VESA
Posted: Fri Nov 27, 2015 6:23 am
by cbOP
My UBYTE is an unsigned char, so
Re: Strange behavior with VESA
Posted: Fri Nov 27, 2015 6:51 am
by sebihepp
Could you please define lfb as volatile unsigned char*? (Or volatile UBYTE*)
As I don't see anything wrong with mode_info, I think the problem must be in the code describing not what we really want. (such as missing volatile, etc.)
I would also like to see an assembler listing of putpixel and the two loops.
Re: Strange behavior with VESA
Posted: Fri Nov 27, 2015 7:26 am
by cbOP
I'm not that good at assembler but I think thats the part:
Code: Select all
.LVL138:
.LBB101:
.loc 2 243 0
addl $16, %esp
.cfi_def_cfa_offset 80
cmpw $0, 12306
.LBE101:
.loc 2 242 0
movl 12328, %ecx
.LVL139:
.LBB102:
.loc 2 243 0
je .L63
.LVL140:
.align 16
.L68:
.LBB99:
.loc 2 244 0 discriminator 3
movzbl 12313, %eax
movzbl 12320, %edx
shrb $3, %al
shrb $3, %dl
movzbl %al, %eax
movzbl %dl, %edx
imull %ebx, %eax
.LBE99:
.loc 2 243 0 discriminator 3
addl $2, %ebx
.LVL141:
.LBB100:
.loc 2 244 0 discriminator 3
addl %ecx, %eax
.LVL142:
addl %eax, %edx
movb $-1, (%edx)
movzbl 12322, %edx
shrb $3, %dl
movzbl %dl, %edx
addl %eax, %edx
movb $0, (%edx)
movzbl 12324, %edx
shrb $3, %dl
movzbl %dl, %edx
addl %edx, %eax
.LVL143:
movb $0, (%eax)
.LBE100:
.loc 2 243 0 discriminator 3
movzwl 12306, %edx
cmpl %ebx, %edx
ja .L68
.LVL144:
.LBE102:
.LBB103:
.loc 2 246 0 discriminator 1
testw %dx, %dx
je .L63
.loc 2 246 0 is_stmt 0 discriminator 3
xorl %ebx, %ebx
.LVL145:
.align 16
.L64:
.LBB104:
.loc 2 247 0 is_stmt 1 discriminator 3
movzbl 12313, %eax
movzwl 12304, %edx
shrb $3, %al
movzbl %al, %eax
imull %ebx, %eax
.LBE104:
.loc 2 246 0 discriminator 3
addl $2, %ebx
.LVL146:
.LBB105:
.loc 2 247 0 discriminator 3
addl %edx, %eax
leal (%ecx,%eax), %edx
.LVL147:
movzbl 12320, %eax
shrb $3, %al
movzbl %al, %eax
addl %edx, %eax
movb $0, (%eax)
movzbl 12322, %eax
shrb $3, %al
movzbl %al, %eax
addl %edx, %eax
movb $-1, (%eax)
movzbl 12324, %eax
shrb $3, %al
movzbl %al, %eax
addl %edx, %eax
movb $0, (%eax)
.LBE105:
.loc 2 246 0 discriminator 3
movzwl 12306, %eax
cmpl %ebx, %eax
ja .L64
.LVL148:
.L63:
Generated via gcc with flags -S and -g
cbOP_
Re: Strange behavior with VESA
Posted: Fri Nov 27, 2015 7:48 am
by sebihepp
Really with -g? All the Labels are screwed up.
Edit: Could you upload your complete sourcecode anywhere? (Please don't post it directly in here, because that would be to much)
Re: Strange behavior with VESA
Posted: Fri Nov 27, 2015 10:09 am
by cbOP
sebihepp wrote:Really with -g? All the Labels are screwed up.
Edit: Could you upload your complete sourcecode anywhere? (Please don't post it directly in here, because that would be to much)
I don't know what -g does I found it on google so sorry for that
Is the whole VESA code enough or do you really mean the WHOLE SOURCE CODE?
Re: Strange behavior with VESA
Posted: Fri Nov 27, 2015 1:39 pm
by sebihepp
I think SourceCode of VESA is enough.
And -g was right, but it didn't seems to work...
Re: Strange behavior with VESA
Posted: Fri Nov 27, 2015 2:07 pm
by cbOP
kmemory.h
System.h
vesatest.c
Please ignore the VESA_IMG for now.
cbOP_