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
This commit is contained in:
Aleksandar Andrejevic 2013-07-23 19:31:00 +00:00
parent 7bcfe7b2a8
commit 6be35ef0bb
3 changed files with 57 additions and 31 deletions

View file

@ -374,20 +374,19 @@ BOOLEAN BiosInitialize()
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
}

View 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;
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
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
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
/* 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 */
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)
@ -275,9 +273,21 @@ static VOID EmulatorSoftwareInt(PVOID Context, BYTE Number)
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 */
@ -445,14 +455,30 @@ VOID EmulatorClearFlag(ULONG Flag)
#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);
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))
{
@ -464,7 +490,7 @@ VOID EmulatorStep()
#endif
}
VOID EmulatorCleanup()
VOID EmulatorCleanup(VOID)
{
/* Free the memory allocated for the 16-bit address space */
if (BaseAddress != NULL) HeapFree(GetProcessHeap(), 0, BaseAddress);

View file

@ -70,7 +70,8 @@
#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
{