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.