mirror of
https://github.com/reactos/reactos.git
synced 2025-01-01 12:04:51 +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;
|
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 */
|
/* Keyboard intercept */
|
||||||
case 0x4F:
|
case 0x4F:
|
||||||
{
|
{
|
||||||
|
@ -303,11 +386,12 @@ static VOID WINAPI BiosMiscService(LPWORD Stack)
|
||||||
/* The amount of memory above 16M, in 64K blocks */
|
/* The amount of memory above 16M, in 64K blocks */
|
||||||
ULONG Above16M = (MAX_ADDRESS > 0x01000000) ? (MAX_ADDRESS - 0x01000000) >> 16: 0;
|
ULONG Above16M = (MAX_ADDRESS > 0x01000000) ? (MAX_ADDRESS - 0x01000000) >> 16: 0;
|
||||||
|
|
||||||
setCF(0);
|
|
||||||
setAX(Above1M);
|
setAX(Above1M);
|
||||||
setBX(Above16M);
|
setBX(Above16M);
|
||||||
setCX(Above1M);
|
setCX(Above1M);
|
||||||
setDX(Above16M);
|
setDX(Above16M);
|
||||||
|
|
||||||
|
Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
|
||||||
}
|
}
|
||||||
else if (getAL() == 0x20 && getEDX() == 'SMAP')
|
else if (getAL() == 0x20 && getEDX() == 'SMAP')
|
||||||
{
|
{
|
||||||
|
|
|
@ -107,6 +107,7 @@ static VOID WINAPI BiosKeyboardService(LPWORD Stack)
|
||||||
|
|
||||||
BiosKbdBufferPop();
|
BiosKbdBufferPop();
|
||||||
setAX(Character);
|
setAX(Character);
|
||||||
|
setCF(0);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,9 +40,10 @@ static BYTE Int16To32[] =
|
||||||
/* Push the value of the interrupt to be called */
|
/* Push the value of the interrupt to be called */
|
||||||
0x6A, 0xFF, // push i (patchable to 0x6A, 0xIntNum)
|
0x6A, 0xFF, // push i (patchable to 0x6A, 0xIntNum)
|
||||||
|
|
||||||
|
0xF8, // clc
|
||||||
|
|
||||||
/* The BOP Sequence */
|
/* The BOP Sequence */
|
||||||
// BOP_SEQ:
|
// BOP_SEQ:
|
||||||
0xF8, // clc
|
|
||||||
BOP(BOP_CONTROL), // Control BOP
|
BOP(BOP_CONTROL), // Control BOP
|
||||||
BOP_CONTROL_INT32, // 32-bit Interrupt dispatcher
|
BOP_CONTROL_INT32, // 32-bit Interrupt dispatcher
|
||||||
|
|
||||||
|
@ -52,7 +53,7 @@ static BYTE Int16To32[] =
|
||||||
|
|
||||||
0xF4, // hlt
|
0xF4, // hlt
|
||||||
|
|
||||||
0xEB, 0xF5, // jmp BOP_SEQ (offset -11)
|
0xEB, 0xF6, // jmp BOP_SEQ (offset -10)
|
||||||
|
|
||||||
// EXIT:
|
// EXIT:
|
||||||
0x44, 0x44, // inc sp, inc sp
|
0x44, 0x44, // inc sp, inc sp
|
||||||
|
|
Loading…
Reference in a new issue