SVGA prob...

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
usb2killer
Posts: 15
Joined: Tue Nov 16, 2010 4:23 am

SVGA prob...

Post by usb2killer »

Im trying draw on the screen with 1024x768x24bit.
I'm trying to switch to 0x118 mode (its 1024x768x24bit) by doing (under realmode):

Code: Select all

mov ax, 4F02h
mov bx, 118h
int 10h
and I'm drawing to the screen in protected mode by doing:

Code: Select all

unsigned char *vidmem = (unsigned char *)0x0A000;
long loop;
char r=0,g=0,b=255;

// Clear visible video memory
for (loop=0; loop<1024*768; loop++) {
	*vidmem++ = r;
	*vidmem++ = g;
	*vidmem++ = b;
	r+=7;
	g-=2;
	b+=3;
}

for (;;);
But it looks like only the few first lines are effected (the end of the effected area is not in the end of the line). I don't know for sure but i think it indicates that banking is in use (I'm trying to use linear buffer)...
Im using Bochs 2.4.5.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: SVGA prob...

Post by Brendan »

Hi,

The legacy video area that you're using (from 0x000A0000 to 0x000AFFFF) is a total of 64 KiB. At 3 bytes per pixel (ignoring things like end of line padding, etc) that works out to a maximum of 21845 pixels, or (with 1024 pixels per line) a maximum of 21.33 lines.

Can you see how trying to write 2.25 MiB of data into a 64 KiB area might not work?
usb2killer wrote:I don't know for sure but i think it indicates that banking is in use (I'm trying to use linear buffer)...
If you're trying to use the linear frame buffer, then you need to get the 32-bit physical address of the frame buffer from VBE (using the "get video mode information" function), and you have to tell VBE to enable the LFB when you set the mode (the higher bits of BX are used as flags to enable features like this). You also should get the "bytes between screen lines for LFB" (and use that to avoid making wrong assumptions about the amount of padding at the end of screen lines). Before doing any of that, you have to check if the video mode actually supports LFB (e.g. while you're also checking if mode number 0x0118 actually is supported and actually is 1024 * 768 * 24-bpp, and if it's RGB or BGR or YUV or something else).

Basically, you probably should read the VBE specification...


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
M2004
Member
Member
Posts: 65
Joined: Sun Mar 07, 2010 2:12 am

Re: SVGA prob...

Post by M2004 »

usb2killer: You also need to check whether your monitor supports the mode you are trying to set.
In your case it seems to do so since you were able to draw something on screen. All modes reported by vbe may not be supported by monitor.

Have you enabled the a20 gate? Disabled a20 gate may cause problems too.

regards
Mac2004
User avatar
Chandra
Member
Member
Posts: 487
Joined: Sat Jul 17, 2010 12:45 am

Re: SVGA prob...

Post by Chandra »

And one more thing, you are using the vesa mode 0x0118 which is no longer one of the standard mode defined by VESA. For now, it is okay as Bochs supports it but once you get your graphics routines working, you need to query for available video modes then finally set the one you find appropriate.

For your acknowledgement, 0x0118 is 1024x768x32 Bpp under Virtual PC. So if you test your code under Virtual PC, it might feel surprising.
Programming is not about using a language to solve a problem, it's about using logic to find a solution !
usb2killer
Posts: 15
Joined: Tue Nov 16, 2010 4:23 am

Re: SVGA prob...

Post by usb2killer »

Ok... I changed the code according to your comments... (only the critical stuff)

so this is the realmode code:

Code: Select all

mov dx, 0

mov ax, 4F01h
mov cx, 0x118
mov di, vesa_info
int 10h
cmp ax, 4f00h
jne no_error

mov dx, 1

no_error:
;changing to 118h svga mode
mov ax, 4F02h
mov bx, 0x118
add bx, 0x4000  ;LBF
int 10h

;protected mode!	
mov eax, cr0            ; Copy the contents of CR0 into EAX
or eax, 1               ; Set bit 0
mov cr0, eax            ; Copy the contents of EAX into CR0

mov ebx, [PhysBasePtrl]
mov ecx, [PhysBasePtrh]

jmp 08h:clear_pipe

;vars
vesa_info:
		ModeAttributes   	dw    	0; mode attributes
        WinAAttributes      db    	0; window A attributes
        WinBAttributes      db    	0; window B attributes
        WinGranularity      dw    	0; window granularity
        WinSize             dw    	0; window size
        WinASegment         dw    	0; window A start segment
        WinBSegment         dw    	0; window B start segment
        WinFuncPtr          dd   	0; pointer to window function
        BytesPerScanLine    dw    	0; bytes per scan line;

        XResolution         dw    	0; horizontal resolution
        YResolution         dw    	0; vertical resolution
        XCharSize           db    	0; character cell width
        YCharSize           db    	0; character cell height
        NumberOfPlanes      db    	0; number of memory planes
        BitsPerPixel        db    	0; bits per pixel
        NumberOfBanks       db    	0; number of banks
        MemoryModel         db    	0; memory model type
        BankSize            db    	0; bank size in kb
        NumberOfImagePages  db    	0; number of images
        Reserved            db    	0; reserved for page function

        RedMaskSize         db    	0; size of direct color red mask in bits
        RedFieldPosition    db    	0; bit position of LSB of red mask
        GreenMaskSize       db    	0; size of direct color green mask in bits
        GreenFieldPosition  db    	0; bit position of LSB of green mask
        BlueMaskSize        db    	0; size of direct color blue mask in bits
        BlueFieldPosition   db    	0; bit position of LSB of blue mask
        RsvdMaskSize        db    	0; size of direct color reserved mask in bits
        DirectColorModeInfo db    	0; Direct Color mode attributes
		;VESA 2.0
		PhysBasePtrl		dd		0;
		PhysBasePtrh		dd		0;
		OffScreenMemOffset	dd		0;
		OffScreenMemSize 	dw		0;

        times  206 db   0; remainder of ModeInfoBlock

[BITS 32]
clear_pipe:
	mov ax, 10h             ; Save data segment identifyer
	mov ds, ax              ; Move a valid data segment into the data segment register
	mov ss, ax              ; Move a valid data segment into the stack segment register
	mov esp, 090000h        ; Move the stack pointer to 0900000
	
	push ecx   ;pushing high physAddress
	push ebx   ;pushing low physAddress
        .... (jumping to main)

this is the protected mode code:

Code: Select all

void kmain(unsigned int physicalAddressl, unsigned int physicalAddressh)
{
	unsigned long physicalAddress = physicalAddressh;
	physicalAddress = physicalAddress << 32;
	physicalAddress = physicalAddress | physicalAddressl;
	unsigned char *vidmem = (unsigned char *)(physicalAddress);
	long loop;
	char r=0,g=0,b=255;

	// Clear visible video memory
	for (loop=0; loop<1024*768; loop++) {
		*vidmem++ = r;
		*vidmem++ = g;
		*vidmem++ = b;
		r+=7;
		g-=2;
		b+=3;
	}
	
	for (;;);
}
Have you enabled the a20 gate? Disabled a20 gate may cause problems too.
I did...


Im getting black screen...
what to do?
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: SVGA prob...

Post by Brendan »

Hi,

For the Return VBE Mode Information function, the ModeInfoBlock is copied to your buffer at ES:DI. This isn't just "DI" and isn't DS:DI. You haven't shown code that sets up segment registers (or stack, or...) so you'll need to check that ES is sane yourself.

The Return VBE Mode Information function may return "AX = 0x 4F00" (OK) to tell you it successfully filled your buffer with a ModeInfoBlock. This does not mean that the video mode is supported by the video card (only that a ModeInfoBlock was returned), and you need to check bit 0 in the ModeAttributes field to determine if the mode is supported by the video card. While doing this you should also check bit 7 in the ModeAttributes field to determine if the video mode supports LFB. If the video card doesn't support this video mode (and there's lots of video cards that don't support any 24-bpp modes) and bit 0 in the ModeAttributes field is clear, then you can't rely on any of the other fields (and can't assume the PhysBasePtr field is valid).

If the Return VBE Mode Information function doesn't return "AX = 0x 4F00" (OK), then setting DX to 1 and attempting to set the video mode anyway won't help. If the Set VBE Mode function doesn't return "AX = 0x 4F00" (OK), then ignoring the error and pretending the mode was set won't help.

For the VBE ModeInfoBlock, the PhyBasePtr field is a 32-bit physical address. It is not a 64-bit physical address, and you can't pretend that the Reserved field that follows it is the upper 32-bits of a 64-bit address (and shouldn't assume that the following Reserved field will contain zero either).

You do need to determine if the video card is VBE 1, VBE 2 or VBE 3 (by using the Return VBE Controller Information function). If the video card is VBE 1 then LFB isn't supported (and some of the fields in the ModeInfoBlock, including the PhyBasePtr field, shouldn't be relied on). For VBE 2 you need to use the BytesPerScanLine field in the ModeInfoBlock (for both bank switched and LFB modes). For VBE 3 the BytesPerScanLine field in the ModeInfoBlock is only used for bank switched video modes, and you have to use the LinBytesPerScanLine field in the ModeInfoBlock for LFB modes. In the same way, for VBE 3 the RedMaskSize, RedFieldPosition, etc fields should only be used for bank switched modes and you should use the LinRedMaskSize, LinRedFieldPosition, etc fields instead for LFB modes.
usb2killer wrote:what to do?
Did you use a debugger (e.g. like the one built into Bochs) to check that the address of the LFB you're using is sane, or see if the ModeInfoBlock is being returned, or do any simple checks to see what is going wrong?


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Post Reply