[haiku-development] Re: Anyone seen this - Vesa delay

  • From: Jan Klötzke <jan.kloetzke@xxxxxxxxxx>
  • To: haiku-development@xxxxxxxxxxxxx
  • Date: Tue, 8 Jul 2008 19:17:12 +0200

Jan Klötzke <jan.kloetzke@xxxxxxxxxx> wrote:
> Stephan Assmus <superstippi@xxxxxx> wrote:
> > I know that Ingo is experiencing the same behavior. On my system, I just
> > get "General System Error" when I try to change resolution (VESA also)
> > during runtime. But I think if I have a vesa kernel settings file with
> > anything different than the native resolution, my system does not boot. I
> > am not sure, but I thought for the behavior you describe, there is a bug
> > report, but I could be wrong.
> >
> > Jan, any ideas?
>
> Unfortunately not really. I suspect that there is an error in the
> instruction emulation part of the vm86 stuff which confuses the BIOS. Just
> a wild guess. I was not able yet to reproduce it on any of my systems here.
>
> What makes it really interesting and what is new to me is that you get
> a "General System Error". Would you mind to enable TRACE_VM86 in
> src/system/kernel/arch/x86/vm86.cpp and capture the output? Maybe I can
> spot something there because the traces I've got so far did not contain
> anything suspicious...

Wait a minute... I found something. The PUSHF/POPF instructions were not 
emulated correctly! The attached patch should fix that. Hope that solves the 
problems. At least it should be applied nonetheless.

/Jan
diff --git a/src/system/kernel/arch/x86/vm86.cpp 
b/src/system/kernel/arch/x86/vm86.cpp
index dbadced..5e41a9b 100644
--- a/src/system/kernel/arch/x86/vm86.cpp
+++ b/src/system/kernel/arch/x86/vm86.cpp
@@ -44,8 +44,8 @@
 #define PUSHF   0x9c
 #define STI     0xfb
 
-#define I_FLAG          (1 << 9)
-#define DIRECTION_FLAG  (1 << 10)
+#define I_FLAG          (1u << 9)
+#define DIRECTION_FLAG  (1u << 10)
 
 #define CSEG 0x2e
 #define SSEG 0x36
@@ -442,7 +442,7 @@ emulate(struct vm86_state *state)
                                uint16 flags = state->regs.flags;
 
                                /* store real IF */
-                               flags &= I_FLAG;
+                               flags &= ~I_FLAG;
                                flags |= (uint16)state->if_flag << 9;
 
                                pushw(&state->regs, flags);
@@ -475,10 +475,11 @@ emulate(struct vm86_state *state)
                case PUSHF:
                {
                        TRACE_NP("PUSHF");
-                       uint16 flags = state->regs.flags & I_FLAG;
+                       uint32 flags = state->regs.flags;
 
                        /* store real IF */
-                       flags |= (uint16)state->if_flag << 9;
+                       flags &= ~I_FLAG;
+                       flags |= (uint32)state->if_flag << 9;
                        if (prefix.size)
                                pushl(&state->regs, flags);
                        else

Other related posts: