mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +00:00
[NTVDM]
- 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
This commit is contained in:
parent
8872cfb339
commit
4113fbb5a3
3 changed files with 89 additions and 3 deletions
|
@ -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')
|
||||
{
|
||||
|
|
|
@ -107,6 +107,7 @@ static VOID WINAPI BiosKeyboardService(LPWORD Stack)
|
|||
|
||||
BiosKbdBufferPop();
|
||||
setAX(Character);
|
||||
setCF(0);
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue