Strange behavior with VESA

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
cbOP
Posts: 8
Joined: Mon Nov 23, 2015 9:30 am

Strange behavior with VESA

Post 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
sebihepp
Member
Member
Posts: 190
Joined: Tue Aug 26, 2008 11:24 am
GitHub: https://github.com/sebihepp

Re: Strange behavior with VESA

Post 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...
cbOP
Posts: 8
Joined: Mon Nov 23, 2015 9:30 am

Re: Strange behavior with VESA

Post 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())
jnc100
Member
Member
Posts: 775
Joined: Mon Apr 09, 2007 12:10 pm
Location: London, UK
Contact:

Re: Strange behavior with VESA

Post 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.
cbOP
Posts: 8
Joined: Mon Nov 23, 2015 9:30 am

Re: Strange behavior with VESA

Post by cbOP »

So I dumped all data and don't know whats going on. I don't see anything wrong.

Image

cbOP_
sebihepp
Member
Member
Posts: 190
Joined: Tue Aug 26, 2008 11:24 am
GitHub: https://github.com/sebihepp

Re: Strange behavior with VESA

Post 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?
cbOP
Posts: 8
Joined: Mon Nov 23, 2015 9:30 am

Re: Strange behavior with VESA

Post 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_
jnc100
Member
Member
Posts: 775
Joined: Mon Apr 09, 2007 12:10 pm
Location: London, UK
Contact:

Re: Strange behavior with VESA

Post by jnc100 »

Your width/height/pitch etc seem reasonable. Out of interest, how is your UBYTE typedef'd?

Regards,
John.
cbOP
Posts: 8
Joined: Mon Nov 23, 2015 9:30 am

Re: Strange behavior with VESA

Post by cbOP »

My UBYTE is an unsigned char, so

Code: Select all

typedef unsigned char UBYTE;
sebihepp
Member
Member
Posts: 190
Joined: Tue Aug 26, 2008 11:24 am
GitHub: https://github.com/sebihepp

Re: Strange behavior with VESA

Post 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.
cbOP
Posts: 8
Joined: Mon Nov 23, 2015 9:30 am

Re: Strange behavior with VESA

Post 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_
sebihepp
Member
Member
Posts: 190
Joined: Tue Aug 26, 2008 11:24 am
GitHub: https://github.com/sebihepp

Re: Strange behavior with VESA

Post 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)
cbOP
Posts: 8
Joined: Mon Nov 23, 2015 9:30 am

Re: Strange behavior with VESA

Post 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?
sebihepp
Member
Member
Posts: 190
Joined: Tue Aug 26, 2008 11:24 am
GitHub: https://github.com/sebihepp

Re: Strange behavior with VESA

Post by sebihepp »

I think SourceCode of VESA is enough.

And -g was right, but it didn't seems to work...
cbOP
Posts: 8
Joined: Mon Nov 23, 2015 9:30 am

Re: Strange behavior with VESA

Post by cbOP »

kmemory.h
System.h
vesatest.c

Please ignore the VESA_IMG for now.

cbOP_
Post Reply