Page 1 of 1

[SOLVED] VESA/VBE, VMware won't switch modes!

Posted: Sun Oct 05, 2008 1:15 am
by TyrelHaveman
Hi Guys,

I've got a bunch of assembly code that finds a good VBE mode to use. On VMware Server, the mode it's finding is 0x117, which is what I want, so that's good.
Then I try to switch to that mode, essentially executing the following (the mode number actually comes from memory of course):

Code: Select all

	mov	bx, 0x117 ; get the video mode
	or	bh, 0x40 ; want linear model, clear screen
	mov	ax, 0x4F02 ; change mode
	int	0x10 ; go

	cmp	al, 0x4F
	jne	vesafail

	cmp	ah, 0x00
	jne	vesafail

	; If we get here, WE ARE NOW IN A NEW VIDEO MODE
	
	jmp	identify_cpu
The result in VMware is that it appears to succeed -- the values in AX do not indicate an error. However VMware does not change the mode to what I've asked of it. I enabled as much debugging as I could in VMware (not much), and it indicates that it has enabled SVGA. But the picture I'm seeing is still the 80x25 text screen, not 1024x768 like I asked it for.

This same code does work in Bochs.

Any ideas?

Thanks,
Tyrel

Re: VESA/VBE, VMware won't switch modes!

Posted: Sun Oct 05, 2008 4:34 pm
by cr2
Bochs does behave differently than other emulators. http://forum.osdev.org/viewtopic.php?f=1&t=18005

...and VMWare does have issues with SVGA. :(

Re: VESA/VBE, VMware won't switch modes!

Posted: Sun Oct 05, 2008 5:53 pm
by neon
That should work, but you should take into consideration that not all emulators or hardware may support linear frame buffer mode. For example, in my case, Bochs supports LFB mode but VirtualPC and the test machines I used doesnt.

That is, try modes 0x4117 (with LFB) and 0x117 (without LFB) and see what is if any works. This doesnt explain why VMWare doesnt report an error though...

Re: VESA/VBE, VMware won't switch modes!

Posted: Sun Oct 05, 2008 7:56 pm
by TyrelHaveman
neon wrote:That should work, but you should take into consideration that not all emulators or hardware may support linear frame buffer mode. For example, in my case, Bochs supports LFB mode but VirtualPC and the test machines I used doesnt.

That is, try modes 0x4117 (with LFB) and 0x117 (without LFB) and see what is if any works. This doesnt explain why VMWare doesnt report an error though...
Yeah, I did try with and without the LFB bit set prior to posting. It made no difference. The list of modes from the device is reporting that this mode supports a LFB anyway, so I'd expect that it would support it (though who knows). I also tried with and without the clear-screen bit, and that also made no difference. Finally, I tried different modes (different color depths and pixel resolutions) and none seemed to have any affect whatsoever.

Tyrel

Re: VESA/VBE, VMware won't switch modes!

Posted: Mon Oct 06, 2008 12:28 am
by xyzzy
Which VMware version? I can use mode 0x117 in LFB mode fine on 6.5 Beta.

Re: VESA/VBE, VMware won't switch modes!

Posted: Mon Oct 06, 2008 12:37 pm
by bontanu
I can also use VESA with LFB just fine in Virtual PC and Bochs and QEMU and VMWare and real hardware... and other emulators.

It must be an error or an assumption in your code.

Re: VESA/VBE, VMware won't switch modes!

Posted: Wed Oct 08, 2008 7:56 pm
by TyrelHaveman
AlexExtreme wrote:Which VMware version? I can use mode 0x117 in LFB mode fine on 6.5 Beta.
Aha! I am using VMware Server 1.0.4 on Linux. I tried VMware Workstation 6.5 on Windows, and do get a screen resolution change there.

I will try upgrading VMware Server to the latest version and see if that makes a difference. Otherwise I can copy my OS image between computers for now, or use Cygwin to compile it -- to get the results I need.

Thanks,
Tyrel

Re: [SOLVED] VESA/VBE, VMware won't switch modes!

Posted: Sat Oct 11, 2008 12:01 pm
by djsilence
Hi, anyone!

Wanna tell you: (if you don't know) starting from VESA 2.0 there are no more standard video numbers! So, I'm using VWare too. (I've got VMWare Workstation 6.0.3) And as I know VMWare has VBE3!

I use this code to determinate what mode number do I need:

Code: Select all

	BITS 16
	
global _findGraphicMode

_findGraphicMode:
	;; The VESA 2.0 specification states that they will no longer
	;; create standard video mode numbers, and video card vendors are
	;; no longer required to support the old numbers.  This routine
	;; will dynamically find a supported mode number from the VIDEO BIOS,
	;; according to the desired resolutions, etc.
	
	;; The function takes parameters that describe the desired graphic
	;; mode, (X resolution, Y resolution, and Bits Per Pixel) and returns
	; the VESA mode number in EAX, if found.  Returns 0 on error.
	
	;; The C prototype for this function would look like the following:
	;; int findGraphicMode(short int x_res, short int y_res, 
	;;                     short int bpp);
	;; (Push bpp, then y_res, then x_res onto the 16-bit stack before
	;; calling.  Caller pops them off again after the call.)

	;; Save space on the stack for the mode number we're returning
	sub SP, 2

	;; Save regs
	pusha

	;; Save the stack pointer
	mov BP, SP

	;; By default, return the value 0 (failure)
	mov word [SS:(BP + 16)], 0

	;; Get the VESA info block.  Save ES, since this call could
	;; destroy it
        push ES
        mov DI, VESAINFO
        mov AX, 4F00h
        int 10h
        ;; Restore ES
        pop ES

        cmp AX, 004Fh
	;; Fail
        jne .done
	
	;; We need to get a far pointer to a list of graphics mode numbers
	;; from the VESA info block we just retrieved.  Get the offset now,
	;; and the segment inside the loop.
	mov SI, [VESAINFO + 0Eh]

	;; Do a loop through the supported modes
	.modeLoop:
	
	;; Save ES
	push ES

	;; Now get the segment of the far pointer, as mentioned above
	mov AX, [VESAINFO + 10h]
	mov ES, AX

	;; ES:SI is now a pointer to the next supported mode.  The list
	;; terminates with the value FFFFh

	;; Get the first/next mode number
	mov DX, word [ES:SI]

	;; Restore ES
	pop ES

	;; Is it the end of the mode number list?
	cmp DX, 0FFFFh
	je near .done

	;; Increment the pointer for the next loop
	add SI, 2

	;; We have a mode number.  Now we need to do a VBE call to
	;; determine whether this mode number suits our needs.
	;; This call will put a bunch of info in the buffer pointed to
	;; by ES:DI

	mov CX, DX
	mov AX, 4F01h
	mov DI, _modeinfo
	int 10h

	;; Make sure the function call is supported
	cmp AL, 4Fh
	;; Fail
	jne near .done
	
	;; Is the mode supported by this call? (sometimes, they're not)
	cmp AH, 00h
	jne .modeLoop

	;; We need to look for a few features to determine whether this
	;; is the mode we want.  First, it needs to be supported, and it
	;; needs to be a graphics mode.  Next, it needs to match the
	;; requested attributes of resolution and BPP

	;; Get the first word of the buffer
	mov AX, word [_modeinfo]
	
	;; Is the mode supported?
	bt AX, 0
	jnc .modeLoop

	;; Is this mode a graphics mode?
	bt AX, 4
	jnc .modeLoop

	%if REQUIRELFB
	;; Does this mode support a linear frame buffer?
	bt AX, 7
	jnc .modeLoop
	%endif

	;; Does the horizontal resolution of this mode match the requested
	;; number?
	mov AX, word [_modeinfo + 12h]
	cmp AX, word [SS:(BP + 20)]
	jne near .modeLoop

	;; Does the vertical resolution of this mode match the requested
	;; number?
	mov AX, word [_modeinfo + 14h]
	cmp AX, word [SS:(BP + 22)]
	jne near .modeLoop

	;; Do the Bits Per Pixel of this mode match the requested number?
	xor AX, AX
	mov AL, byte [_modeinfo + 19h]
	cmp AX, word [SS:(BP + 24)]
	jne near .modeLoop

	;; If we fall through to here, this is the mode we want.
	mov word [SS:(BP + 16)], DX
	
	.done:
	popa
	;; Return the mode number
	xor EAX, EAX
	pop AX
	ret


;;
;; The data segment
;;

	SEGMENT .data
	ALIGN 4

VESAINFO  	db 'VBE2'		;; Space for info ret by vid BIOS
		times 508  db 0
global		_modeinfo
_modeinfo	times 256 db 0
and then I call it:

Code: Select all

%define bpp  32
%define y_res  1024
%define x_res  1280
...
global _mode_no
_mode_no dd 0
start:
             ...
	push word bpp
	push word y_res
	push word x_res
	call _findGraphicMode
	mov [_mode_no], eax

	or [_mode_no], word 0x4000	                        //if I want to use LFB.
	mov ax, 0x4F02
	mov bx, [_mode_no]
	int 0x10
This function works well in VMWare, in M$ VirtualPC, and even in my real PC with Radeon 9200.

Try this. Hope, help!

Daniel.