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:
Image

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:
Image

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:
Image

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:
Image

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, &regs.es, &regs.di);
	KernelInterrupt(0x10, &regs);
	return regs.ax;
}

USHORT ModuleVesaSetMode(USHORT mode) {
	DREGISTERS16 regs;
	regs.ax = 0x4F02;
	regs.cx = mode;
	KernelInterrupt(0x10, &regs);
	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.

Image

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:
Image
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

Code: Select all

typedef unsigned char UBYTE;

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_