[NTVDM]
authorAleksandar Andrejevic <aandrejevic@reactos.org>
Tue, 23 Jul 2013 19:31:00 +0000 (19:31 +0000)
committerAleksandar Andrejevic <aandrejevic@reactos.org>
Tue, 23 Jul 2013 19:31:00 +0000 (19:31 +0000)
Remove the old "INT 0xFF" hack and instead use an invalid opcode sequence for emulator operations.
Fix the flags register update bug.

svn path=/branches/ntvdm/; revision=59565

subsystems/ntvdm/bios.c
subsystems/ntvdm/emulator.c
subsystems/ntvdm/emulator.h

index 6a99625..3b9c99b 100644 (file)
@@ -374,20 +374,19 @@ BOOLEAN BiosInitialize()
         IntVecTable[i * 2] = Offset;
         IntVecTable[i * 2 + 1] = BIOS_SEGMENT;
 
         IntVecTable[i * 2] = Offset;
         IntVecTable[i * 2 + 1] = BIOS_SEGMENT;
 
-        if (i != SPECIAL_INT_NUM)
-        {
-            BiosCode[Offset++] = 0xFA; // cli
+        BiosCode[Offset++] = 0xFA; // cli
 
 
-            BiosCode[Offset++] = 0x6A; // push i
-            BiosCode[Offset++] = (BYTE)i;
+        BiosCode[Offset++] = 0x6A; // push i
+        BiosCode[Offset++] = (BYTE)i;
 
 
-            BiosCode[Offset++] = 0xCD; // int SPECIAL_INT_NUM
-            BiosCode[Offset++] = SPECIAL_INT_NUM;
+        BiosCode[Offset++] = LOBYTE(EMULATOR_BOP); // BOP sequence
+        BiosCode[Offset++] = HIBYTE(EMULATOR_BOP);
+        BiosCode[Offset++] = LOBYTE(EMULATOR_INT_BOP);
+        BiosCode[Offset++] = HIBYTE(EMULATOR_INT_BOP);
 
 
-            BiosCode[Offset++] = 0x83; // add sp, 2
-            BiosCode[Offset++] = 0xC4;
-            BiosCode[Offset++] = 0x02;
-        }
+        BiosCode[Offset++] = 0x83; // add sp, 2
+        BiosCode[Offset++] = 0xC4;
+        BiosCode[Offset++] = 0x02;
 
         BiosCode[Offset++] = 0xCF; // iret
     }
 
         BiosCode[Offset++] = 0xCF; // iret
     }
index c328f16..6a2a0ca 100644 (file)
@@ -165,34 +165,32 @@ static VOID EmulatorWriteIo(PVOID Context, UINT Address, LPBYTE Buffer, INT Size
     }
 }
 
     }
 }
 
-static VOID EmulatorSoftwareInt(PVOID Context, BYTE Number)
+static VOID EmulatorBop(WORD Code)
 {
     WORD StackSegment, StackPointer, CodeSegment, InstructionPointer;
     BYTE IntNum;
 {
     WORD StackSegment, StackPointer, CodeSegment, InstructionPointer;
     BYTE IntNum;
+    LPWORD Stack;
 
 
-    /* Check if this is the special interrupt */
-    if (Number == SPECIAL_INT_NUM)
-    {
-        /* Get the SS:SP */
+    /* Get the SS:SP */
 #ifndef NEW_EMULATOR
 #ifndef NEW_EMULATOR
-        StackSegment = EmulatorContext.state->segment_reg[SX86_SREG_SS].val;
-        StackPointer = EmulatorContext.state->general_reg[SX86_REG_SP].val;
+    StackSegment = EmulatorContext.state->segment_reg[SX86_SREG_SS].val;
+    StackPointer = EmulatorContext.state->general_reg[SX86_REG_SP].val;
 #else
 #else
-        StackSegment = EmulatorContext.Registers[EMULATOR_REG_SS].LowWord;
-        StackPointer = EmulatorContext.Registers[EMULATOR_REG_SP].LowWord;
+    StackSegment = EmulatorContext.Registers[EMULATOR_REG_SS].LowWord;
+    StackPointer = EmulatorContext.Registers[EMULATOR_REG_SP].LowWord;
 #endif
 
 #endif
 
-        /* Get the interrupt number */
-        IntNum = *(LPBYTE)((ULONG_PTR)BaseAddress + TO_LINEAR(StackSegment, StackPointer));
+    /* Get the stack */
+    Stack = (LPWORD)((ULONG_PTR)BaseAddress + TO_LINEAR(StackSegment, StackPointer));
 
 
-        /* Move the stack pointer forward one word to skip the interrupt number */
-        StackPointer += sizeof(WORD);
+    if (Code == EMULATOR_INT_BOP)
+    {
+        /* Get the interrupt number */
+        IntNum = LOBYTE(Stack[0]);
 
         /* Get the CS:IP */
 
         /* Get the CS:IP */
-        InstructionPointer = *(LPWORD)((ULONG_PTR)BaseAddress
-                             + TO_LINEAR(StackSegment, StackPointer));
-        CodeSegment = *(LPWORD)((ULONG_PTR)BaseAddress
-                      + TO_LINEAR(StackSegment, StackPointer + sizeof(WORD)));
+        InstructionPointer = Stack[1];
+        CodeSegment = Stack[2];
 
         /* Check if this was an exception */
         if (IntNum < 8)
 
         /* Check if this was an exception */
         if (IntNum < 8)
@@ -275,9 +273,21 @@ static VOID EmulatorSoftwareInt(PVOID Context, BYTE Number)
                 break;
             }
         }
                 break;
             }
         }
+
+        /* Update the flags on the stack */
+#ifndef NEW_EMULATOR
+        Stack[3] = EmulatorContext.state->reg_flags.val;
+#else
+        Stack[3] = EmulatorContext.Flags.LowWord;
+#endif
     }
 }
 
     }
 }
 
+static VOID EmulatorSoftwareInt(PVOID Context, BYTE Number)
+{
+    /* Do nothing */
+}
+
 static VOID EmulatorHardwareInt(PVOID Context, BYTE Number)
 {
     /* Do nothing */
 static VOID EmulatorHardwareInt(PVOID Context, BYTE Number)
 {
     /* Do nothing */
@@ -445,14 +455,30 @@ VOID EmulatorClearFlag(ULONG Flag)
 #endif
 }
 
 #endif
 }
 
-VOID EmulatorStep()
+VOID EmulatorStep(VOID)
 {
 {
+    LPWORD Instruction;
+
 #ifndef NEW_EMULATOR
     /* Print the current position - useful for debugging */
     DPRINT("Executing at CS:IP = %04X:%04X\n",
            EmulatorGetRegister(EMULATOR_REG_CS),
            EmulatorContext.state->reg_ip);
 
 #ifndef NEW_EMULATOR
     /* Print the current position - useful for debugging */
     DPRINT("Executing at CS:IP = %04X:%04X\n",
            EmulatorGetRegister(EMULATOR_REG_CS),
            EmulatorContext.state->reg_ip);
 
+    Instruction = (LPWORD)((ULONG_PTR)BaseAddress
+                           + TO_LINEAR(EmulatorGetRegister(EMULATOR_REG_CS),
+                           EmulatorContext.state->reg_ip));
+
+    /* Check for the BIOS operation (BOP) sequence */
+    if (Instruction[0] == EMULATOR_BOP)
+    {
+        /* Skip the opcodes */
+        EmulatorContext.state->reg_ip += 4;
+
+        /* Call the BOP handler */
+        EmulatorBop(Instruction[1]);
+    }
+
     /* Call the softx86 API */
     if (!softx86_step(&EmulatorContext))
     {
     /* Call the softx86 API */
     if (!softx86_step(&EmulatorContext))
     {
@@ -464,7 +490,7 @@ VOID EmulatorStep()
 #endif
 }
 
 #endif
 }
 
-VOID EmulatorCleanup()
+VOID EmulatorCleanup(VOID)
 {
     /* Free the memory allocated for the 16-bit address space */
     if (BaseAddress != NULL) HeapFree(GetProcessHeap(), 0, BaseAddress);
 {
     /* Free the memory allocated for the 16-bit address space */
     if (BaseAddress != NULL) HeapFree(GetProcessHeap(), 0, BaseAddress);
index 69471a1..f1a6256 100644 (file)
@@ -70,7 +70,8 @@
 #define EMULATOR_NUM_CONTROL_REGS 8
 #define EMULATOR_NUM_DEBUG_REGS 8
 #define MAX_GDT_ENTRIES 8192
 #define EMULATOR_NUM_CONTROL_REGS 8
 #define EMULATOR_NUM_DEBUG_REGS 8
 #define MAX_GDT_ENTRIES 8192
-#define SPECIAL_INT_NUM 0xFF
+#define EMULATOR_BOP 0xC4C4
+#define EMULATOR_INT_BOP 0xBEEF
 
 enum
 {
 
 enum
 {