Page 1 of 2

VBE with VirtualPC

Posted: Sat May 02, 2009 2:42 am
by Tomaka17
Hello,

I'm posting here to ask if someone already had the same problem as me
In BOCHS, Qemu and VMWare my VBE module switches mode and displays my GUI properly (except VirtualBox which doesn't support VBE)

But in VirtualPC it doesn't work at all

I call int0x10 with EAX=0x4F00 to get informations about the device ; I store a list of available modes
For each mode I call int0x10 with EAX=0x4F01 to get informations about it ; I filter the 8 bits/pixel modes and modes that don't support linear frame buffer

Then I try switching to mode 0x12e (but the mode doesn't matter), and here the strange thing happens:
VirtualPC's window gets resized to the size of the mode I chose... but the call fails (EAX = 0xFE at the end of interrupt 0x10)

If I simply ignore the errorcode and try writing to the framebuffer, I can't: if I write a byte to it and read it back, its value has not been modified
The content of the frame buffer is full of 0xFF bytes despite the screen being black (it should be white :P )

I know that's not the kind of problems where people on a forum can help you, but I'm stuck on this for a long time now and I just have no idea about what is going on :?
Who knows, maybe someone encountered the same problem and could help


Thanks

Re: VBE with VirtualPC

Posted: Sat May 02, 2009 4:33 am
by bontanu
I use VBE with Virtual PC in my SOLAR_OS and it works just fine (as expected). Hence it "must" be something wrong in your code.

One thing that I have encountered with emulators is that they do not emulate ALL encodings for instructions and hardware less used features. Also when they translate your code (for speed optimization) they can make mistakes in cases of self modifying code or complex code.

Hence if your assembler or compiler does generate "exotic" or less used opcodes in an attempt to optimize code then the code might not work as expected in an emulator.

This is one of the reasons why so many linux distributions do not work in Virtual PC: they either use "undocumented" / "exotic" opcodes or they attempt to use too advanced hardware features that are not emulated exactly and get unexpected results in emulator.

Re: VBE with VirtualPC

Posted: Sat May 02, 2009 6:12 am
by Tomaka17
bontanu wrote:Hence if your assembler or compiler does generate "exotic" or less used opcodes in an attempt to optimize code then the code might not work as expected in an emulator.
Well.. I'm compiling with -march=386 and -O0 (though I sometimes test with -O3 to see if it works) so I don't think GCC will generate exotic things

I'm jealous of all the sourceccodes I find ; they do exactly like mine (well, in fact mine does exactly like them :lol: ) but mine doesn't work for some obscure reason

Apparently the real mode code for interruption 0x10 uses interruption 0x6D ; first I thought my code (virtual manager) that handles this was wrong, but VMWare does the same and it works :-/

Re: VBE with VirtualPC

Posted: Mon May 04, 2009 1:16 am
by gedd
Tomaka17 wrote:Then I try switching to mode 0x12e (but the mode doesn't matter)
On virtual PC this is 1152*768*32, if no error. Try other too
Make sure you add 0x4000 to the mode number when you call "set mode" function, it ensure you enable LFB ...
Tomaka17 wrote:The content of the frame buffer is full of 0xFF bytes despite the screen being black (it should be white )
Are you sure that palette color define 0xFF value to white ?

I'm actually work on vesa driver , try the file "vesa.asm" in init project, loader directory , maybe usefull.

Re: VBE with VirtualPC

Posted: Mon May 04, 2009 3:42 am
by Tomaka17
Thanks for trying to help :p

I've tested modes 0x112, 0x114, 0x115 and 0x117 (and 0x12E) and none of them is working
They all return EAX = 0xFE and their memory cannot be overwritten

What is strange is that VirtualPC's window is resized to the good resolution, but it still returns an error
Make sure you add 0x4000 to the mode number when you call "set mode" function, it ensure you enable LFB ...
Yes I'm doing this
Are you sure that palette color define 0xFF value to white ?
If I'm right, only "packed pixel" modes use palettes (usually modes with 8 bits per pixel), no?
Anyway even if it was palette color, I should be able to modify the content of the video memory


I'm going to check your code to see if I forgot something

EDIT : hmm on your website the source code for the vesa driver is only a few lines long :s

Re: VBE with VirtualPC

Posted: Mon May 04, 2009 3:55 am
by gedd
init/loader/vesa.asm

- Detect VESA
- Get VESA info
- Check Width, heigh, bits per pixel, LFB
- Copie mode info block
- Set mode

Kernel use VESA and mode info block

Works on Virtual PC, Bochs, Virtualbox, VMWare, Qemu, real PC (nVidia 8400 GS)

Re: VBE with VirtualPC

Posted: Mon May 04, 2009 6:38 am
by jal
Tomaka17 wrote:The content of the frame buffer is full of 0xFF bytes
0xff is the usual value of you try to read memory that is not present. Since the call returns an error, the LFB address is not valid.


JAL

Re: VBE with VirtualPC

Posted: Mon May 04, 2009 6:43 am
by jal
Tomaka17 wrote:What is strange is that VirtualPC's window is resized to the good resolution, but it still returns an error
If I had to guess, the VirtualPC's routine is accepting the mode setting, sets up the screen to the desired resolution, then encounters some internal error and aborts, without properly resetting stuff. 0xFE for EAX seems like a very odd error code, I cannot find it in the specs. In fact, it should return AH = 01h in case the function call fails.


JAL

Re: VBE with VirtualPC

Posted: Mon May 04, 2009 7:09 am
by gedd
but the call fails (EAX = 0xFE at the end of interrupt 0x10)
VBE RETURN STATUS
AL == 4Fh: Function is supported
AL != 4Fh: Function is not supported
AH == 00h: Function call successful
AH == 01h: Function call failed
AH == 02h: Function is not supported in the current hardware configuration
AH == 03h: Function call invalid in current video mode

In your case : AL != 4Fh: Function is not supported

Re: VBE with VirtualPC

Posted: Mon May 04, 2009 7:56 am
by Tomaka17
gedd wrote:init/loader/vesa.asm
..oops I was looking at the wrong file :oops:

If I had to guess, the VirtualPC's routine is accepting the mode setting, sets up the screen to the desired resolution, then encounters some internal error and aborts, without properly resetting stuff. 0xFE for EAX seems like a very odd error code, I cannot find it in the specs. In fact, it should return AH = 01h in case the function call fails.
I agree with that, but why do other Operating Sytems using VESA work with VirtualPC? :|
In fact AL != 0x4F means function not supported, but I doubt that 0xFE as a return value is intended


Just in case I removed the whole mode detections thing (in case where previous int 0x10 would make the last one crash) but no change...

Here is my code (but I doubt it will help):

Code: Select all

	struct ivt_entry {
		uint16_t offset;
		uint16_t segment;
	} __attribute__((packed))* ivt = (struct ivt_entry*)0xC0000000;		// this offset is mapped to physical addr 0x0
	
	memory_context_t* memContext = memory_context_create();
	process_thread_t* thread = process_thread_createSystem(0, PROCESS_THREAD_FLAG_I386_VIRTUALMODE | PROCESS_THREAD_FLAG_NOAUTOSTART);
	process_thread_useMemoryContext(thread, memContext);
	
	process_thread_modifyRegister(thread, "eax", 0x4F02);
	process_thread_modifyRegister(thread, "ebx", vbeModeID | 0x4000);		// 0x4000 = use flat mode addressing
	process_thread_modifyRegister(thread, "cs", ivt[0x10].segment);
	process_thread_modifyRegister(thread, "eip", ivt[0x10].offset);
	
	process_thread_start(thread);
	while (process_thread_isStarted(thread))		// virtual thread automatically stops when encountering an 'IRET' with no corresponding 'INT'
		process_thread_sleepCurrentThread(50);
	
	unsigned int returnCode = process_thread_readRegister(thread, "eax");
	
	process_thread_delete(thread);
	memory_context_delete(memContext);
	
	if ((returnCode & 0xffff) != 0x4F) {
		printf("Mode changing failed! Return code: 0x%X\r", returnCode);
		return;
	}
You are going to say that there is a problem in the part of my O/S which handles threads and virtual mode, but I'd answer that my code is working on any other emulator :P

Re: VBE with VirtualPC

Posted: Mon May 04, 2009 8:24 am
by gedd
Let's take it by the beginning

1 - Get mode list by function 4F00
2 - Get information on each mode [choose the good one for you]
3 - Set only mode wich are present in list

It's the only way ....

Re: VBE with VirtualPC

Posted: Mon May 04, 2009 8:53 am
by Tomaka17
That's what I was doing


What I said in my last post is that I tried to directly switch to mode 0x12E, but it gives the same result

Re: VBE with VirtualPC

Posted: Mon May 04, 2009 1:30 pm
by jal
gedd wrote:
but the call fails (EAX = 0xFE at the end of interrupt 0x10)
VBE RETURN STATUS
AL == 4Fh: Function is supported
AL != 4Fh: Function is not supported
AH == 00h: Function call successful
AH == 01h: Function call failed
AH == 02h: Function is not supported in the current hardware configuration
AH == 03h: Function call invalid in current video mode

In your case : AL != 4Fh: Function is not supported
It doesn't explicitly say whether AH must be set if AL != 4Fh, or does it? I'd expect AH = 1. Also, most VBE implementation return 00h in AL on failure, iirc. 0xFE really sounds like an odd return value, expecially since the function call seems to be supported as the window size is already changed.


JAL

Re: VBE with VirtualPC

Posted: Mon May 04, 2009 3:26 pm
by purage
Have you already seen this link: DJGPP VBE 2.0 Graphics

Re: VBE with VirtualPC

Posted: Tue May 05, 2009 2:59 am
by Tomaka17
Ok I dumped VirtualPC's int0x10 handler (thank you serial port redirected to a file :D )

The main code is like:

Code: Select all

 pushfl
 pushal
 push %ds
 push %es
 push %fs
 push %gs

 call *%cs:0x11ae(%al * 2)

 movb $0x4f, 0x24(%bp)
 jb at 'movb $0x1' just below, the flags are certainly modified by the call just above
 movb $0x0, 0x25(%bp)
 jmp at 'pop %gs'
 movb $0x1, 0x25(%bp)
 jmp at 'pop %gs'

 pop %gs
 pop %fs
 pop %es
 pop %ds
 popal
 popfl
 iret
At %cs:0x11ae there is a table containing addresses of functions
Depending on AL, a different one is called

But when calling with AL = 2, the function modifies some memory offsets and finally jumps to a location where there is:

Code: Select all

 int 0x6D
 iret
According to Ralf Brown's interrupts list, interrupt 0x6D is the video BIOS entry point for many video cards

The handler for 0x6D then checks the value of AX
At the time of 'int 0x6D', AX already equals 0xFE

The value of AH is zero so it jumps to another routine which analyzes AL
But as AL is too large (0xFE), it IRETs without modifying the return code

So the problem is: AX shouldn't be equal to 0xFE at the time of 'int 0x6D'

Tomaka17 continuing investigations :P


EDITs : typos