[NTVDM]
authorAleksandar Andrejevic <aandrejevic@reactos.org>
Sun, 10 May 2015 01:42:39 +0000 (01:42 +0000)
committerAleksandar Andrejevic <aandrejevic@reactos.org>
Sun, 10 May 2015 01:42:39 +0000 (01:42 +0000)
- Modify the int32 dispatch to clear the CF only on entry, so that we can
track in our handlers whether it was the first time the BOP executed.
- Implement INT 15h, AH = 41h (Wait On External Event).
- Fix INT 15h, AX = E801h - modify the stack CF instead of the handler CF.
- Make INT 16h AH = 00h clear CF when there is a character, so that the BOP doesn't
repeat.

svn path=/trunk/; revision=67612

reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32.c
reactos/subsystems/mvdm/ntvdm/bios/bios32/kbdbios32.c
reactos/subsystems/mvdm/ntvdm/int32.c

index 4f82dd0..0525ee3 100644 (file)
@@ -164,6 +164,89 @@ static VOID WINAPI BiosMiscService(LPWORD Stack)
             break;
         }
 
+        /* Wait On External Event */
+        case 0x41:
+        {
+            BYTE Value;
+            BOOLEAN Return;
+            static DWORD StartingCount;
+
+            /* Check if this is the first time this BOP occurred */
+            if (!getCF())
+            {
+                /* Set the starting count */
+                StartingCount = Bda->TickCounter;
+            }
+
+            if (getBL() != 0 && (Bda->TickCounter - StartingCount) >= getBL())
+            {
+                /* Timeout expired */
+                break;
+            }
+
+            if (getAL() & (1 << 4))
+            {
+                /* Read from the I/O port */
+                Value = IOReadB(getDX());
+            }
+            else
+            {
+                /* Read from the memory */
+                Value = *(LPBYTE)SEG_OFF_TO_PTR(getES(), getDI());
+            }
+
+            switch (getAL() & 7)
+            {
+                /* Any external event */
+                case 0:
+                {
+                    /* Return if this is not the first time the BOP occurred */
+                    Return = getCF();
+                    break;
+                }
+
+                /* Compare and return if equal */
+                case 1:
+                {
+                    Return = Value == getBH();
+                    break;
+                }
+
+                /* Compare and return if not equal */
+                case 2:
+                {
+                    Return = Value != getBH();
+                    break;
+                }
+
+                /* Test and return if not zero */
+                case 3:
+                {
+                    Return = (Value & getBH()) != 0;
+                    break;
+                }
+                
+                /* Test and return if zero */
+                case 4:
+                {
+                    Return = (Value & getBH()) == 0;
+                    break;
+                }
+
+                default:
+                {
+                    DPRINT1("INT 15h, AH = 41h - Unknown condition type: %u\n", getAL() & 7);
+                    Return = TRUE;
+                    break;
+                }
+            }
+
+            /* Repeat the BOP if we shouldn't return */
+            setCF(!Return);
+
+            break;
+        }
+
         /* Keyboard intercept */
         case 0x4F:
         {
@@ -303,11 +386,12 @@ static VOID WINAPI BiosMiscService(LPWORD Stack)
                 /* The amount of memory above 16M, in 64K blocks */
                 ULONG Above16M = (MAX_ADDRESS > 0x01000000) ? (MAX_ADDRESS - 0x01000000) >> 16: 0;
 
-                setCF(0);
                 setAX(Above1M);
                 setBX(Above16M);
                 setCX(Above1M);
                 setDX(Above16M);
+
+                Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
             }
             else if (getAL() == 0x20 && getEDX() == 'SMAP')
             {
index bb12c3d..bec4fde 100644 (file)
@@ -107,6 +107,7 @@ static VOID WINAPI BiosKeyboardService(LPWORD Stack)
 
             BiosKbdBufferPop();
             setAX(Character);
+            setCF(0);
 
             break;
         }
index a111270..79c122a 100644 (file)
@@ -40,9 +40,10 @@ static BYTE Int16To32[] =
     /* Push the value of the interrupt to be called */
     0x6A, 0xFF,         // push i (patchable to 0x6A, 0xIntNum)
 
+    0xF8,               // clc
+
     /* The BOP Sequence */
 // BOP_SEQ:
-    0xF8,               // clc
     BOP(BOP_CONTROL),   // Control BOP
     BOP_CONTROL_INT32,  // 32-bit Interrupt dispatcher
 
@@ -52,7 +53,7 @@ static BYTE Int16To32[] =
 
     0xF4,               // hlt
 
-    0xEB, 0xF5,         // jmp BOP_SEQ (offset -11)
+    0xEB, 0xF6,         // jmp BOP_SEQ (offset -10)
 
 // EXIT:
     0x44, 0x44,         // inc sp, inc sp