From 44c816e20cc7586a547b74dac21fde2020c2b5a6 Mon Sep 17 00:00:00 2001 From: Aleksandar Andrejevic Date: Sat, 3 Jan 2015 15:16:41 +0000 Subject: [PATCH] [FAST486][NTVDM] Use an external interrupt for the FPU when the NE bit of CR0 is cleared. svn path=/trunk/; revision=65961 --- reactos/include/reactos/libs/fast486/fast486.h | 9 +++++++++ reactos/lib/fast486/fast486.c | 10 ++++++++++ reactos/lib/fast486/opcodes.c | 12 ++++++++++-- reactos/subsystems/ntvdm/cpu/cpu.c | 1 + reactos/subsystems/ntvdm/emulator.c | 6 ++++++ reactos/subsystems/ntvdm/emulator.h | 5 +++++ 6 files changed, 41 insertions(+), 2 deletions(-) diff --git a/reactos/include/reactos/libs/fast486/fast486.h b/reactos/include/reactos/libs/fast486/fast486.h index e31cce121b6..6af6d8f294b 100644 --- a/reactos/include/reactos/libs/fast486/fast486.h +++ b/reactos/include/reactos/libs/fast486/fast486.h @@ -227,6 +227,13 @@ UCHAR PFAST486_STATE State ); +typedef +VOID +(NTAPI *FAST486_FPU_PROC) +( + PFAST486_STATE State +); + typedef union _FAST486_REG { union @@ -473,6 +480,7 @@ struct _FAST486_STATE FAST486_IO_WRITE_PROC IoWriteCallback; FAST486_BOP_PROC BopCallback; FAST486_INT_ACK_PROC IntAckCallback; + FAST486_FPU_PROC FpuCallback; FAST486_REG GeneralRegs[FAST486_NUM_GEN_REGS]; FAST486_SEG_REG SegmentRegs[FAST486_NUM_SEG_REGS]; FAST486_REG InstPtr, SavedInstPtr; @@ -514,6 +522,7 @@ Fast486Initialize(PFAST486_STATE State, FAST486_IO_WRITE_PROC IoWriteCallback, FAST486_BOP_PROC BopCallback, FAST486_INT_ACK_PROC IntAckCallback, + FAST486_FPU_PROC FpuCallback, PULONG Tlb); VOID diff --git a/reactos/lib/fast486/fast486.c b/reactos/lib/fast486/fast486.c index bc9748d5791..f03a99b6660 100644 --- a/reactos/lib/fast486/fast486.c +++ b/reactos/lib/fast486/fast486.c @@ -179,6 +179,12 @@ Fast486IntAckCallback(PFAST486_STATE State) return 0x01; } +static VOID NTAPI +Fast486FpuCallback(PFAST486_STATE State) +{ + UNREFERENCED_PARAMETER(State); +} + /* PUBLIC FUNCTIONS ***********************************************************/ VOID @@ -190,6 +196,7 @@ Fast486Initialize(PFAST486_STATE State, FAST486_IO_WRITE_PROC IoWriteCallback, FAST486_BOP_PROC BopCallback, FAST486_INT_ACK_PROC IntAckCallback, + FAST486_FPU_PROC FpuCallback, PULONG Tlb) { /* Set the callbacks (or use default ones if some are NULL) */ @@ -199,6 +206,7 @@ Fast486Initialize(PFAST486_STATE State, State->IoWriteCallback = (IoWriteCallback ? IoWriteCallback : Fast486IoWriteCallback ); State->BopCallback = (BopCallback ? BopCallback : Fast486BopCallback ); State->IntAckCallback = (IntAckCallback ? IntAckCallback : Fast486IntAckCallback ); + State->FpuCallback = (FpuCallback ? FpuCallback : Fast486FpuCallback ); /* Set the TLB (if given) */ State->Tlb = Tlb; @@ -220,6 +228,7 @@ Fast486Reset(PFAST486_STATE State) FAST486_IO_WRITE_PROC IoWriteCallback = State->IoWriteCallback; FAST486_BOP_PROC BopCallback = State->BopCallback; FAST486_INT_ACK_PROC IntAckCallback = State->IntAckCallback; + FAST486_FPU_PROC FpuCallback = State->FpuCallback; PULONG Tlb = State->Tlb; /* Clear the entire structure */ @@ -273,6 +282,7 @@ Fast486Reset(PFAST486_STATE State) State->IoWriteCallback = IoWriteCallback; State->BopCallback = BopCallback; State->IntAckCallback = IntAckCallback; + State->FpuCallback = FpuCallback; State->Tlb = Tlb; } diff --git a/reactos/lib/fast486/opcodes.c b/reactos/lib/fast486/opcodes.c index 662a5fb459a..325590c7ec5 100644 --- a/reactos/lib/fast486/opcodes.c +++ b/reactos/lib/fast486/opcodes.c @@ -4125,8 +4125,16 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeWait) || (!State->FpuControl.Dm && State->FpuStatus.De) || (!State->FpuControl.Im && State->FpuStatus.Ie)) { - /* Call the #MF handler */ - Fast486Exception(State, FAST486_EXCEPTION_MF); + if (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_NE) + { + /* Call the #MF handler */ + Fast486Exception(State, FAST486_EXCEPTION_MF); + } + else + { + /* Use the external interrupt */ + State->FpuCallback(State); + } } #endif diff --git a/reactos/subsystems/ntvdm/cpu/cpu.c b/reactos/subsystems/ntvdm/cpu/cpu.c index 6666978cf2a..b8354426c88 100644 --- a/reactos/subsystems/ntvdm/cpu/cpu.c +++ b/reactos/subsystems/ntvdm/cpu/cpu.c @@ -165,6 +165,7 @@ BOOLEAN CpuInitialize(VOID) EmulatorWriteIo, EmulatorBiosOperation, EmulatorIntAcknowledge, + EmulatorFpu, NULL /* TODO: Use a TLB */); /* Initialize the software callback system and register the emulator BOPs */ diff --git a/reactos/subsystems/ntvdm/emulator.c b/reactos/subsystems/ntvdm/emulator.c index 004418a0205..bea6de83803 100644 --- a/reactos/subsystems/ntvdm/emulator.c +++ b/reactos/subsystems/ntvdm/emulator.c @@ -212,6 +212,12 @@ UCHAR WINAPI EmulatorIntAcknowledge(PFAST486_STATE State) return PicGetInterrupt(); } +VOID WINAPI EmulatorFpu(PFAST486_STATE State) +{ + /* The FPU is wired to IRQ 13 */ + PicInterruptRequest(13); +} + VOID EmulatorException(BYTE ExceptionNumber, LPWORD Stack) { WORD CodeSegment, InstructionPointer; diff --git a/reactos/subsystems/ntvdm/emulator.h b/reactos/subsystems/ntvdm/emulator.h index 493cfa64340..e2da04cb44f 100644 --- a/reactos/subsystems/ntvdm/emulator.h +++ b/reactos/subsystems/ntvdm/emulator.h @@ -92,6 +92,11 @@ UCHAR WINAPI EmulatorIntAcknowledge PFAST486_STATE State ); +VOID WINAPI EmulatorFpu +( + PFAST486_STATE State +); + VOID EmulatorException(BYTE ExceptionNumber, LPWORD Stack); VOID EmulatorTerminate(VOID);