Code reorganization: Move CPU code to specific files for modularity (prepares ground for some future work).
We reintroduce also int32.c in which all the int32 handling code is moved to.
Part 1/2

svn path=/trunk/; revision=64429
This commit is contained in:
Hermès Bélusca-Maïto 2014-09-30 23:47:23 +00:00
parent 87ad3a5ac5
commit e9190ef591
28 changed files with 662 additions and 593 deletions

View file

@ -14,6 +14,9 @@ list(APPEND SOURCE
bios/kbdbios.c
bios/rom.c
bios/vidbios.c
cpu/bop.c
cpu/callback.c
cpu/cpu.c
hardware/cmos.c
hardware/keyboard.c
hardware/mouse.c
@ -27,10 +30,9 @@ list(APPEND SOURCE
dos/dos32krnl/dosfiles.c
dos/mouse32.c
dos/dem.c
bop.c
callback.c
clock.c
emulator.c
int32.c
io.c
registers.c
utils.c

View file

@ -11,8 +11,8 @@
#define NDEBUG
#include "emulator.h"
#include "callback.h"
#include "bop.h"
#include "cpu/callback.h"
#include "cpu/bop.h"
#include "bios.h"
#include "bios32/bios32.h"

View file

@ -14,8 +14,9 @@
#include <reactos/buildno.h>
#include "emulator.h"
#include "callback.h"
#include "bop.h"
#include "cpu/cpu.h" // for EMULATOR_FLAG_CF
#include "int32.h"
// #include "bop.h"
#include "../bios.h"
#include "../rom.h"

View file

@ -14,7 +14,7 @@
#include "ntvdm.h"
#include "../bios.h"
/**/ #include "callback.h" /**/
/**/ #include "int32.h" /**/
/* DEFINES ********************************************************************/

View file

@ -11,7 +11,8 @@
#define NDEBUG
#include "emulator.h"
#include "callback.h"
#include "cpu/cpu.h" // for EMULATOR_FLAG_ZF
#include "int32.h"
#include "kbdbios32.h"
#include "../kbdbios.h"

View file

@ -11,7 +11,6 @@
#define NDEBUG
#include "emulator.h"
#include "callback.h"
#include "moubios32.h"
#include "bios32p.h"

View file

@ -13,7 +13,7 @@
#define NDEBUG
#include "emulator.h"
#include "callback.h"
#include "int32.h"
#include "vidbios32.h"
#include "../vidbios.h"

View file

@ -11,8 +11,7 @@
#define NDEBUG
#include "emulator.h"
#include "callback.h"
#include "bop.h"
#include "cpu/bop.h"
#include "bios.h"
// #include "kbdbios.h"

View file

@ -11,7 +11,7 @@
#define NDEBUG
#include "emulator.h"
#include "callback.h"
#include "cpu/callback.h"
#include "utils.h"
#include "rom.h"

View file

@ -12,8 +12,8 @@
#define NDEBUG
#include "emulator.h"
#include "callback.h"
#include "bop.h"
#include "cpu/cpu.h"
#include "cpu/bop.h"
#include "bios.h"
// #include "vidbios.h"

View file

@ -1,310 +0,0 @@
/*
* COPYRIGHT: GPL - See COPYING in the top level directory
* PROJECT: ReactOS Virtual DOS Machine
* FILE: callback.c
* PURPOSE: 16 and 32-bit Callbacks Support
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
*/
/******************************************************************************\
| WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING!
|
| Callbacks support supposes implicitely that the callbacks are used
| in the SAME thread as the CPU thread, otherwise messing in parallel
| with the CPU registers is 100% prone to bugs!!
\******************************************************************************/
/* INCLUDES *******************************************************************/
#define NDEBUG
#include "emulator.h"
#include "callback.h"
#include "bop.h"
#include <isvbop.h>
/* PRIVATE VARIABLES **********************************************************/
/*
* This is the list of registered 32-bit Interrupt handlers.
*/
static EMULATOR_INT32_PROC Int32Proc[EMULATOR_MAX_INT32_NUM] = { NULL };
/* BOP Identifiers */
#define BOP_CONTROL 0xFF // Control BOP Handler
#define BOP_CONTROL_DEFFUNC 0x00 // Default Control BOP Function
#define BOP_CONTROL_INT32 0xFF // 32-bit Interrupt dispatcher
// function code for the Control BOP Handler
#define BOP(num) LOBYTE(EMULATOR_BOP), HIBYTE(EMULATOR_BOP), (num)
#define UnSimulate16(trap) \
do { \
*(PUSHORT)(trap) = EMULATOR_BOP; \
(trap) += sizeof(USHORT); \
*(trap) = BOP_UNSIMULATE; \
} while(0)
// #define UnSimulate16 MAKELONG(EMULATOR_BOP, BOP_UNSIMULATE) // BOP(BOP_UNSIMULATE)
#define CALL16_TRAMPOLINE_SIZE (1 * sizeof(ULONGLONG))
#define INT16_TRAMPOLINE_SIZE (1 * sizeof(ULONGLONG))
//
// WARNING WARNING!!
//
// If you modify the code stubs here, think also
// about updating them in int32.c too!!
//
/* 16-bit generic interrupt code for calling a 32-bit interrupt handler */
static BYTE Int16To32[] =
{
0xFA, // cli
/* Push the value of the interrupt to be called */
0x6A, 0xFF, // push i (patchable to 0x6A, 0xIntNum)
/* The BOP Sequence */
// BOP_SEQ:
0xF8, // clc
BOP(BOP_CONTROL), // Control BOP
BOP_CONTROL_INT32, // 32-bit Interrupt dispatcher
0x73, 0x04, // jnc EXIT (offset +4)
0xFB, // sti
// HACK: The following instruction should be HLT!
0x90, // nop
0xEB, 0xF5, // jmp BOP_SEQ (offset -11)
// EXIT:
0x44, 0x44, // inc sp, inc sp
0xCF, // iret
};
const ULONG Int16To32StubSize = sizeof(Int16To32);
/* PUBLIC FUNCTIONS ***********************************************************/
VOID
InitializeContext(IN PCALLBACK16 Context,
IN USHORT Segment,
IN USHORT Offset)
{
Context->TrampolineFarPtr = MAKELONG(Offset, Segment);
Context->TrampolineSize = max(CALL16_TRAMPOLINE_SIZE,
INT16_TRAMPOLINE_SIZE);
Context->Segment = Segment;
Context->NextOffset = Offset + Context->TrampolineSize;
}
VOID
Call16(IN USHORT Segment,
IN USHORT Offset)
{
/* Save CS:IP */
USHORT OrgCS = getCS();
USHORT OrgIP = getIP();
/* Set the new CS:IP */
setCS(Segment);
setIP(Offset);
DPRINT("Call16(%04X:%04X)\n", Segment, Offset);
/* Start CPU simulation */
EmulatorSimulate();
/* Restore CS:IP */
setCS(OrgCS);
setIP(OrgIP);
}
ULONG
RegisterCallback16(IN ULONG FarPtr,
IN LPBYTE CallbackCode,
IN SIZE_T CallbackSize,
OUT PSIZE_T CodeSize OPTIONAL)
{
LPBYTE CodeStart = (LPBYTE)FAR_POINTER(FarPtr);
LPBYTE Code = CodeStart;
SIZE_T OurCodeSize = CallbackSize;
if (CallbackCode == NULL) CallbackSize = 0;
if (CallbackCode)
{
/* 16-bit interrupt code */
RtlCopyMemory(Code, CallbackCode, CallbackSize);
Code += CallbackSize;
}
/* Return the real size of the code if needed */
if (CodeSize) *CodeSize = OurCodeSize; // == (ULONG_PTR)Code - (ULONG_PTR)CodeStart;
// /* Return the entry-point address for 32-bit calls */
// return (ULONG_PTR)(CodeStart + CallbackSize);
return OurCodeSize;
}
VOID
RunCallback16(IN PCALLBACK16 Context,
IN ULONG FarPtr)
{
PUCHAR TrampolineBase = (PUCHAR)FAR_POINTER(Context->TrampolineFarPtr);
PUCHAR Trampoline = TrampolineBase;
UCHAR OldTrampoline[CALL16_TRAMPOLINE_SIZE];
/* Save the old trampoline */
((PULONGLONG)&OldTrampoline)[0] = ((PULONGLONG)TrampolineBase)[0];
DPRINT1("RunCallback16(0x%p)\n", FarPtr);
/* Build the generic entry-point for 16-bit far calls */
*Trampoline++ = 0x9A; // Call far seg:off
*(PULONG)Trampoline = FarPtr;
Trampoline += sizeof(ULONG);
UnSimulate16(Trampoline);
/* Perform the call */
Call16(HIWORD(Context->TrampolineFarPtr),
LOWORD(Context->TrampolineFarPtr));
/* Restore the old trampoline */
((PULONGLONG)TrampolineBase)[0] = ((PULONGLONG)&OldTrampoline)[0];
}
ULONG
RegisterInt16(IN ULONG FarPtr,
IN BYTE IntNumber,
IN LPBYTE CallbackCode,
IN SIZE_T CallbackSize,
OUT PSIZE_T CodeSize OPTIONAL)
{
/* Get a pointer to the IVT and set the corresponding entry (far pointer) */
LPDWORD IntVecTable = (LPDWORD)SEG_OFF_TO_PTR(0x0000, 0x0000);
IntVecTable[IntNumber] = FarPtr;
/* Register the 16-bit callback */
return RegisterCallback16(FarPtr,
CallbackCode,
CallbackSize,
CodeSize);
}
ULONG
RegisterInt32(IN ULONG FarPtr,
IN BYTE IntNumber,
IN EMULATOR_INT32_PROC IntHandler,
OUT PSIZE_T CodeSize OPTIONAL)
{
/* Array for holding our copy of the 16-bit interrupt callback */
BYTE IntCallback[sizeof(Int16To32)/sizeof(BYTE)];
/* Check whether the 32-bit interrupt was already registered */
#if 0
if (Int32Proc[IntNumber] != NULL)
{
DPRINT1("RegisterInt32: Interrupt 0x%02X already registered!\n", IntNumber);
return 0;
}
#endif
/* Register the 32-bit interrupt handler */
Int32Proc[IntNumber] = IntHandler;
/* Copy the generic 16-bit interrupt callback and patch it */
RtlCopyMemory(IntCallback, Int16To32, sizeof(Int16To32));
IntCallback[2] = IntNumber;
/* Register the 16-bit interrupt callback */
return RegisterInt16(FarPtr,
IntNumber,
IntCallback,
sizeof(IntCallback),
CodeSize);
}
VOID
Int32Call(IN PCALLBACK16 Context,
IN BYTE IntNumber)
{
PUCHAR TrampolineBase = (PUCHAR)FAR_POINTER(Context->TrampolineFarPtr);
PUCHAR Trampoline = TrampolineBase;
UCHAR OldTrampoline[INT16_TRAMPOLINE_SIZE];
DPRINT("Int32Call(0x%02X)\n", IntNumber);
/* Save the old trampoline */
((PULONGLONG)&OldTrampoline)[0] = ((PULONGLONG)TrampolineBase)[0];
/* Build the generic entry-point for 16-bit calls */
if (IntNumber == 0x03)
{
/* We are redefining for INT 03h */
*Trampoline++ = 0xCC; // Call INT 03h
/** *Trampoline++ = 0x90; // nop **/
}
else
{
/* Normal interrupt */
*Trampoline++ = 0xCD; // Call INT XXh
*Trampoline++ = IntNumber;
}
UnSimulate16(Trampoline);
/* Perform the call */
Call16(HIWORD(Context->TrampolineFarPtr),
LOWORD(Context->TrampolineFarPtr));
/* Restore the old trampoline */
((PULONGLONG)TrampolineBase)[0] = ((PULONGLONG)&OldTrampoline)[0];
}
VOID WINAPI Int32Dispatch(LPWORD Stack)
{
/* Get the interrupt number */
BYTE IntNum = LOBYTE(Stack[STACK_INT_NUM]);
/* Call the 32-bit Interrupt handler */
if (Int32Proc[IntNum] != NULL)
Int32Proc[IntNum](Stack);
else
DPRINT1("Unhandled 32-bit interrupt: 0x%02X, AX = 0x%04X\n", IntNum, getAX());
}
static VOID WINAPI ControlBop(LPWORD Stack)
{
/* Get the Function Number and skip it */
BYTE FuncNum = *(PBYTE)SEG_OFF_TO_PTR(getCS(), getIP());
setIP(getIP() + 1);
switch (FuncNum)
{
case BOP_CONTROL_INT32:
Int32Dispatch(Stack);
break;
default:
// DPRINT1("Unassigned Control BOP Function: 0x%02X\n", FuncNum);
DisplayMessage(L"Unassigned Control BOP Function: 0x%02X", FuncNum);
break;
}
}
VOID InitializeCallbacks(VOID)
{
/* Register the Control BOP */
RegisterBop(BOP_CONTROL, ControlBop);
}
/* EOF */

View file

@ -12,6 +12,7 @@
#define NDEBUG
#include "emulator.h"
#include "cpu/cpu.h"
// #include "clock.h"
@ -62,7 +63,7 @@ UINT Irq12Counter = 0;
VOID ClockUpdate(VOID)
{
extern BOOLEAN CpuSimulate;
extern BOOLEAN CpuRunning;
UINT i;
#ifdef WORKING_TIMER
@ -137,9 +138,9 @@ VOID ClockUpdate(VOID)
VgaHorizontalRetrace();
/* Continue CPU emulation */
for (i = 0; VdmRunning && CpuSimulate && (i < STEPS_PER_CYCLE); i++)
for (i = 0; VdmRunning && CpuRunning && (i < STEPS_PER_CYCLE); i++)
{
EmulatorStep();
CpuStep();
#ifdef IPS_DISPLAY
Cycles++;
#endif

View file

@ -0,0 +1,143 @@
/*
* COPYRIGHT: GPL - See COPYING in the top level directory
* PROJECT: ReactOS Virtual DOS Machine
* FILE: callback.c
* PURPOSE: 16 and 32-bit Callbacks Support
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
*/
/******************************************************************************\
| WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING!
|
| Callbacks support supposes implicitely that the callbacks are used
| in the SAME thread as the CPU thread, otherwise messing in parallel
| with the CPU registers is 100% prone to bugs!!
\******************************************************************************/
/* INCLUDES *******************************************************************/
#define NDEBUG
#include "cpu.h"
#include "callback.h"
#include "emulator.h"
#include "bop.h"
#include <isvbop.h>
/* PRIVATE VARIABLES **********************************************************/
#define TRAMPOLINE_SIZE sizeof(ULONGLONG)
static BYTE Yield[] =
{
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // 13x nop
BOP(BOP_UNSIMULATE), // UnSimulate16 BOP
};
C_ASSERT(sizeof(Yield) == 16 * sizeof(BYTE));
/* PUBLIC FUNCTIONS ***********************************************************/
VOID
InitializeContextEx(IN PCALLBACK16 Context,
IN ULONG TrampolineSize,
IN USHORT Segment,
IN USHORT Offset)
{
Context->TrampolineFarPtr = MAKELONG(Offset, Segment);
Context->TrampolineSize = max(TRAMPOLINE_SIZE, TrampolineSize);
Context->Segment = Segment;
Context->NextOffset = Offset + Context->TrampolineSize;
}
VOID
InitializeContext(IN PCALLBACK16 Context,
IN USHORT Segment,
IN USHORT Offset)
{
InitializeContextEx(Context,
TRAMPOLINE_SIZE,
Segment,
Offset);
}
VOID
Call16(IN USHORT Segment,
IN USHORT Offset)
{
/* Save CS:IP */
USHORT OrgCS = getCS();
USHORT OrgIP = getIP();
/* Set the new CS:IP */
setCS(Segment);
setIP(Offset);
DPRINT("Call16(%04X:%04X)\n", Segment, Offset);
/* Start CPU simulation */
CpuSimulate();
/* Restore CS:IP */
setCS(OrgCS);
setIP(OrgIP);
}
VOID
RunCallback16(IN PCALLBACK16 Context,
IN ULONG FarPtr)
{
PUCHAR TrampolineBase = (PUCHAR)FAR_POINTER(Context->TrampolineFarPtr);
PUCHAR Trampoline = TrampolineBase;
UCHAR OldTrampoline[TRAMPOLINE_SIZE];
/* Save the old trampoline */
((PULONGLONG)&OldTrampoline)[0] = ((PULONGLONG)TrampolineBase)[0];
DPRINT("RunCallback16(0x%p)\n", FarPtr);
/* Build the generic entry-point for 16-bit far calls */
*Trampoline++ = 0x9A; // Call far seg:off
*(PULONG)Trampoline = FarPtr;
Trampoline += sizeof(ULONG);
UnSimulate16(Trampoline);
/* Perform the call */
Call16(HIWORD(Context->TrampolineFarPtr),
LOWORD(Context->TrampolineFarPtr));
/* Restore the old trampoline */
((PULONGLONG)TrampolineBase)[0] = ((PULONGLONG)&OldTrampoline)[0];
}
ULONG
RegisterCallback16(IN ULONG FarPtr,
IN LPBYTE CallbackCode,
IN SIZE_T CallbackSize,
OUT PSIZE_T CodeSize OPTIONAL)
{
LPBYTE CodeStart = (LPBYTE)FAR_POINTER(FarPtr);
LPBYTE Code = CodeStart;
SIZE_T OurCodeSize = CallbackSize;
if (CallbackCode == NULL) CallbackSize = 0;
if (CallbackCode)
{
/* 16-bit interrupt code */
RtlCopyMemory(Code, CallbackCode, CallbackSize);
Code += CallbackSize;
}
/* Return the real size of the code if needed */
if (CodeSize) *CodeSize = OurCodeSize; // == (ULONG_PTR)Code - (ULONG_PTR)CodeStart;
// /* Return the entry-point address for 32-bit calls */
// return (ULONG_PTR)(CodeStart + CallbackSize);
return OurCodeSize;
}
/* EOF */

View file

@ -12,8 +12,14 @@
/* DEFINES ********************************************************************/
/* 32-bit Interrupt Identifiers */
#define EMULATOR_MAX_INT32_NUM 0xFF + 1
#define BOP(num) LOBYTE(EMULATOR_BOP), HIBYTE(EMULATOR_BOP), (num)
#define UnSimulate16(trap) \
do { \
*(PUSHORT)(trap) = EMULATOR_BOP; \
(trap) += sizeof(USHORT); \
*(trap) = BOP_UNSIMULATE; \
} while(0)
// #define UnSimulate16 MAKELONG(EMULATOR_BOP, BOP_UNSIMULATE) // BOP(BOP_UNSIMULATE)
typedef struct _CALLBACK16
{
@ -23,11 +29,23 @@ typedef struct _CALLBACK16
USHORT NextOffset;
} CALLBACK16, *PCALLBACK16;
extern const ULONG Int16To32StubSize;
//
// WARNING WARNING!!
// If you're changing the indices here, you then need to
// also fix the BOP code in callback.c !!!!!!!!!!!!!!!!!
//
#define STACK_INT_NUM 0
#define STACK_IP 1
#define STACK_CS 2
#define STACK_FLAGS 3
/* FUNCTIONS ******************************************************************/
typedef VOID (WINAPI *EMULATOR_INT32_PROC)(LPWORD Stack);
VOID
InitializeContextEx(IN PCALLBACK16 Context,
IN ULONG TrampolineSize,
IN USHORT Segment,
IN USHORT Offset);
VOID
InitializeContext(IN PCALLBACK16 Context,
@ -38,36 +56,16 @@ VOID
Call16(IN USHORT Segment,
IN USHORT Offset);
VOID
RunCallback16(IN PCALLBACK16 Context,
IN ULONG FarPtr);
ULONG
RegisterCallback16(IN ULONG FarPtr,
IN LPBYTE CallbackCode,
IN SIZE_T CallbackSize,
OUT PSIZE_T CodeSize OPTIONAL);
VOID
RunCallback16(IN PCALLBACK16 Context,
IN ULONG FarPtr);
ULONG
RegisterInt16(IN ULONG FarPtr,
IN BYTE IntNumber,
IN LPBYTE CallbackCode,
IN SIZE_T CallbackSize,
OUT PSIZE_T CodeSize OPTIONAL);
ULONG
RegisterInt32(IN ULONG FarPtr,
IN BYTE IntNumber,
IN EMULATOR_INT32_PROC IntHandler,
OUT PSIZE_T CodeSize OPTIONAL);
VOID
Int32Call(IN PCALLBACK16 Context,
IN BYTE IntNumber);
VOID WINAPI Int32Dispatch(LPWORD Stack);
VOID InitializeCallbacks(VOID);
#endif // _CALLBACK_H_
/* EOF */

View file

@ -0,0 +1,191 @@
/*
* COPYRIGHT: GPL - See COPYING in the top level directory
* PROJECT: ReactOS Virtual DOS Machine
* FILE: emulator.c
* PURPOSE: Minimal x86 machine emulator for the VDM
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
*/
/* INCLUDES *******************************************************************/
#define NDEBUG
#include "cpu.h"
#include "emulator.h"
#include "callback.h"
#include "bop.h"
#include <isvbop.h>
#include "clock.h"
#include "bios/rom.h"
#include "hardware/cmos.h"
#include "hardware/keyboard.h"
#include "hardware/mouse.h"
#include "hardware/pic.h"
#include "hardware/ps2.h"
#include "hardware/speaker.h"
#include "hardware/timer.h"
#include "hardware/vga.h"
#include "io.h"
/* PRIVATE VARIABLES **********************************************************/
FAST486_STATE EmulatorContext;
BOOLEAN CpuRunning = FALSE;
/* No more than 'MaxCpuCallLevel' recursive CPU calls are allowed */
static const INT MaxCpuCallLevel = 32;
static INT CpuCallLevel = 0;
// BOOLEAN VdmRunning = TRUE;
#if 0
LPCWSTR ExceptionName[] =
{
L"Division By Zero",
L"Debug",
L"Unexpected Error",
L"Breakpoint",
L"Integer Overflow",
L"Bound Range Exceeded",
L"Invalid Opcode",
L"FPU Not Available"
};
#endif
// /* BOP Identifiers */
// #define BOP_DEBUGGER 0x56 // Break into the debugger from a 16-bit app
/* PRIVATE FUNCTIONS **********************************************************/
#if 0
VOID EmulatorException(BYTE ExceptionNumber, LPWORD Stack)
{
WORD CodeSegment, InstructionPointer;
PBYTE Opcode;
ASSERT(ExceptionNumber < 8);
/* Get the CS:IP */
InstructionPointer = Stack[STACK_IP];
CodeSegment = Stack[STACK_CS];
Opcode = (PBYTE)SEG_OFF_TO_PTR(CodeSegment, InstructionPointer);
/* Display a message to the user */
DisplayMessage(L"Exception: %s occured at %04X:%04X\n"
L"Opcode: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X",
ExceptionName[ExceptionNumber],
CodeSegment,
InstructionPointer,
Opcode[0],
Opcode[1],
Opcode[2],
Opcode[3],
Opcode[4],
Opcode[5],
Opcode[6],
Opcode[7],
Opcode[8],
Opcode[9]);
/* Stop the VDM */
EmulatorTerminate();
return;
}
#endif
// FIXME: This function assumes 16-bit mode!!!
VOID CpuExecute(WORD Segment, WORD Offset)
{
/* Tell Fast486 to move the instruction pointer */
Fast486ExecuteAt(&EmulatorContext, Segment, Offset);
}
VOID CpuStep(VOID)
{
/* Dump the state for debugging purposes */
// Fast486DumpState(&EmulatorContext);
/* Execute the next instruction */
Fast486StepInto(&EmulatorContext);
}
VOID CpuSimulate(VOID)
{
if (CpuCallLevel > MaxCpuCallLevel)
{
DisplayMessage(L"Too many CPU levels of recursion (%d, expected maximum %d)",
CpuCallLevel, MaxCpuCallLevel);
/* Stop the VDM */
EmulatorTerminate();
return;
}
CpuCallLevel++;
CpuRunning = TRUE;
while (VdmRunning && CpuRunning) ClockUpdate();
CpuCallLevel--;
if (CpuCallLevel < 0) CpuCallLevel = 0;
/* This takes into account for reentrance */
CpuRunning = TRUE;
}
VOID CpuUnsimulate(VOID)
{
/* Stop simulation */
CpuRunning = FALSE;
}
static VOID WINAPI CpuUnsimulateBop(LPWORD Stack)
{
CpuUnsimulate();
}
#if 0
VOID EmulatorTerminate(VOID)
{
/* Stop the VDM */
VdmRunning = FALSE;
}
#endif
/* PUBLIC FUNCTIONS ***********************************************************/
BOOLEAN CpuInitialize(VOID)
{
// /* Initialize the internal clock */
// if (!ClockInitialize())
// {
// wprintf(L"FATAL: Failed to initialize the clock\n");
// return FALSE;
// }
/* Initialize the CPU */
Fast486Initialize(&EmulatorContext,
EmulatorReadMemory,
EmulatorWriteMemory,
EmulatorReadIo,
EmulatorWriteIo,
NULL,
EmulatorBiosOperation,
EmulatorIntAcknowledge,
NULL /* TODO: Use a TLB */);
/* Initialize the software callback system and register the emulator BOPs */
// RegisterBop(BOP_DEBUGGER , EmulatorDebugBreakBop);
RegisterBop(BOP_UNSIMULATE, CpuUnsimulateBop);
return TRUE;
}
VOID CpuCleanup(VOID)
{
// Fast486Cleanup();
}
/* EOF */

View file

@ -0,0 +1,79 @@
/*
* COPYRIGHT: GPL - See COPYING in the top level directory
* PROJECT: ReactOS Virtual DOS Machine
* FILE: emulator.h
* PURPOSE: Minimal x86 machine emulator for the VDM
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
*/
#ifndef _CPU_H_
#define _CPU_H_
/* INCLUDES *******************************************************************/
#include "ntvdm.h"
#include <fast486.h>
/* DEFINES ********************************************************************/
/* FLAGS */
#define EMULATOR_FLAG_CF (1 << 0)
#define EMULATOR_FLAG_PF (1 << 2)
#define EMULATOR_FLAG_AF (1 << 4)
#define EMULATOR_FLAG_ZF (1 << 6)
#define EMULATOR_FLAG_SF (1 << 7)
#define EMULATOR_FLAG_TF (1 << 8)
#define EMULATOR_FLAG_IF (1 << 9)
#define EMULATOR_FLAG_DF (1 << 10)
#define EMULATOR_FLAG_OF (1 << 11)
#define EMULATOR_FLAG_NT (1 << 14)
#define EMULATOR_FLAG_RF (1 << 16)
#define EMULATOR_FLAG_VM (1 << 17)
#define EMULATOR_FLAG_AC (1 << 18)
#define EMULATOR_FLAG_VIF (1 << 19)
#define EMULATOR_FLAG_VIP (1 << 20)
#define EMULATOR_FLAG_ID (1 << 21)
#if 0
enum
{
EMULATOR_EXCEPTION_DIVISION_BY_ZERO,
EMULATOR_EXCEPTION_DEBUG,
EMULATOR_EXCEPTION_NMI,
EMULATOR_EXCEPTION_BREAKPOINT,
EMULATOR_EXCEPTION_OVERFLOW,
EMULATOR_EXCEPTION_BOUND,
EMULATOR_EXCEPTION_INVALID_OPCODE,
EMULATOR_EXCEPTION_NO_FPU,
EMULATOR_EXCEPTION_DOUBLE_FAULT,
EMULATOR_EXCEPTION_FPU_SEGMENT,
EMULATOR_EXCEPTION_INVALID_TSS,
EMULATOR_EXCEPTION_NO_SEGMENT,
EMULATOR_EXCEPTION_STACK_SEGMENT,
EMULATOR_EXCEPTION_GPF,
EMULATOR_EXCEPTION_PAGE_FAULT
};
#endif
extern FAST486_STATE EmulatorContext;
// extern BOOLEAN VdmRunning;
/* FUNCTIONS ******************************************************************/
#if 0
VOID EmulatorException(BYTE ExceptionNumber, LPWORD Stack);
#endif
VOID CpuExecute(WORD Segment, WORD Offset);
VOID CpuStep(VOID);
VOID CpuSimulate(VOID);
VOID CpuUnsimulate(VOID);
#if 0
VOID EmulatorTerminate(VOID);
#endif
BOOLEAN CpuInitialize(VOID);
VOID CpuCleanup(VOID);
#endif // _CPU_H_
/* EOF */

View file

@ -18,7 +18,7 @@
#include "utils.h"
#include "dem.h"
#include "bop.h"
#include "cpu/bop.h"
#include "bios/bios.h"
#include "mouse32.h"

View file

@ -11,7 +11,7 @@
#define NDEBUG
#include "emulator.h"
#include "callback.h"
#include "int32.h"
#include "dos.h"

View file

@ -13,7 +13,7 @@
#include "ntvdm.h"
/**/ #include "callback.h" /**/
/**/ #include "int32.h" /**/
/* DEFINES ********************************************************************/

View file

@ -11,7 +11,8 @@
#define NDEBUG
#include "emulator.h"
#include "callback.h"
#include "cpu/cpu.h"
#include "int32.h"
#include "mouse32.h"
#include "bios/bios.h"

View file

@ -11,7 +11,13 @@
#define NDEBUG
#include "emulator.h"
#include "callback.h"
#include "cpu/callback.h"
#include "cpu/cpu.h"
#include "cpu/bop.h"
#include <isvbop.h>
#include "int32.h"
#include "clock.h"
#include "bios/rom.h"
@ -24,21 +30,11 @@
#include "hardware/timer.h"
#include "hardware/vga.h"
#include "bop.h"
#include "vddsup.h"
#include "io.h"
#include <isvbop.h>
/* PRIVATE VARIABLES **********************************************************/
FAST486_STATE EmulatorContext;
BOOLEAN CpuSimulate = FALSE;
/* No more than 'MaxCpuCallLevel' recursive CPU calls are allowed */
static const INT MaxCpuCallLevel = 32;
static INT CpuCallLevel = 0;
LPVOID BaseAddress = NULL;
BOOLEAN VdmRunning = TRUE;
@ -176,51 +172,6 @@ VOID EmulatorException(BYTE ExceptionNumber, LPWORD Stack)
return;
}
// FIXME: This function assumes 16-bit mode!!!
VOID EmulatorExecute(WORD Segment, WORD Offset)
{
/* Tell Fast486 to move the instruction pointer */
Fast486ExecuteAt(&EmulatorContext, Segment, Offset);
}
VOID EmulatorStep(VOID)
{
/* Dump the state for debugging purposes */
// Fast486DumpState(&EmulatorContext);
/* Execute the next instruction */
Fast486StepInto(&EmulatorContext);
}
VOID EmulatorSimulate(VOID)
{
if (CpuCallLevel > MaxCpuCallLevel)
{
DisplayMessage(L"Too many CPU levels of recursion (%d, expected maximum %d)",
CpuCallLevel, MaxCpuCallLevel);
/* Stop the VDM */
EmulatorTerminate();
return;
}
CpuCallLevel++;
CpuSimulate = TRUE;
while (VdmRunning && CpuSimulate) ClockUpdate();
CpuCallLevel--;
if (CpuCallLevel < 0) CpuCallLevel = 0;
/* This takes into account for reentrance */
CpuSimulate = TRUE;
}
VOID EmulatorUnsimulate(VOID)
{
/* Stop simulation */
CpuSimulate = FALSE;
}
VOID EmulatorTerminate(VOID)
{
/* Stop the VDM */
@ -250,11 +201,6 @@ static VOID WINAPI EmulatorDebugBreakBop(LPWORD Stack)
DebugBreak();
}
static VOID WINAPI EmulatorUnsimulateBop(LPWORD Stack)
{
EmulatorUnsimulate();
}
static BYTE WINAPI Port61hRead(ULONG Port)
{
return Port61hState;
@ -559,6 +505,8 @@ BOOLEAN EmulatorInitialize(HANDLE ConsoleInput, HANDLE ConsoleOutput)
/* Initialize I/O ports */
/* Initialize RAM */
/* Initialize the CPU */
/* Initialize the internal clock */
if (!ClockInitialize())
{
@ -567,15 +515,16 @@ BOOLEAN EmulatorInitialize(HANDLE ConsoleInput, HANDLE ConsoleOutput)
}
/* Initialize the CPU */
Fast486Initialize(&EmulatorContext,
EmulatorReadMemory,
EmulatorWriteMemory,
EmulatorReadIo,
EmulatorWriteIo,
NULL,
EmulatorBiosOperation,
EmulatorIntAcknowledge,
NULL /* TODO: Use a TLB */);
CpuInitialize();
// Fast486Initialize(&EmulatorContext,
// EmulatorReadMemory,
// EmulatorWriteMemory,
// EmulatorReadIo,
// EmulatorWriteIo,
// NULL,
// EmulatorBiosOperation,
// EmulatorIntAcknowledge,
// NULL /* TODO: Use a TLB */);
/* Initialize DMA */
@ -626,9 +575,9 @@ BOOLEAN EmulatorInitialize(HANDLE ConsoleInput, HANDLE ConsoleOutput)
}
/* Initialize the software callback system and register the emulator BOPs */
InitializeCallbacks();
InitializeInt32();
RegisterBop(BOP_DEBUGGER , EmulatorDebugBreakBop);
RegisterBop(BOP_UNSIMULATE, EmulatorUnsimulateBop);
// RegisterBop(BOP_UNSIMULATE, CpuUnsimulateBop);
/* Initialize VDD support */
VDDSupInitialize();
@ -651,7 +600,7 @@ VOID EmulatorCleanup(VOID)
// PitCleanup();
// PicCleanup();
// Fast486Cleanup();
CpuCleanup();
/* Free the memory allocated for the 16-bit address space */
if (BaseAddress != NULL) HeapFree(GetProcessHeap(), 0, BaseAddress);
@ -663,7 +612,7 @@ VOID
WINAPI
VDDSimulate16(VOID)
{
EmulatorSimulate();
CpuSimulate();
}
VOID

View file

@ -16,35 +16,6 @@
/* DEFINES ********************************************************************/
/* FLAGS */
#define EMULATOR_FLAG_CF (1 << 0)
#define EMULATOR_FLAG_PF (1 << 2)
#define EMULATOR_FLAG_AF (1 << 4)
#define EMULATOR_FLAG_ZF (1 << 6)
#define EMULATOR_FLAG_SF (1 << 7)
#define EMULATOR_FLAG_TF (1 << 8)
#define EMULATOR_FLAG_IF (1 << 9)
#define EMULATOR_FLAG_DF (1 << 10)
#define EMULATOR_FLAG_OF (1 << 11)
#define EMULATOR_FLAG_NT (1 << 14)
#define EMULATOR_FLAG_RF (1 << 16)
#define EMULATOR_FLAG_VM (1 << 17)
#define EMULATOR_FLAG_AC (1 << 18)
#define EMULATOR_FLAG_VIF (1 << 19)
#define EMULATOR_FLAG_VIP (1 << 20)
#define EMULATOR_FLAG_ID (1 << 21)
//
// WARNING WARNING!!
// If you're changing the indices here, you then need to
// also fix the BOP code in callback.c !!!!!!!!!!!!!!!!!
//
#define STACK_INT_NUM 0
#define STACK_IP 1
#define STACK_CS 2
#define STACK_FLAGS 3
/* Basic Memory Management */
#define MEM_ALIGN_UP(ptr, align) MEM_ALIGN_DOWN((ULONG_PTR)(ptr) + (align) - 1l, (align))
#define MEM_ALIGN_DOWN(ptr, align) (PVOID)((ULONG_PTR)(ptr) & ~((align) - 1l))
@ -92,7 +63,7 @@ enum
EMULATOR_EXCEPTION_PAGE_FAULT
};
extern FAST486_STATE EmulatorContext;
// extern FAST486_STATE EmulatorContext;
extern LPVOID BaseAddress;
extern BOOLEAN VdmRunning;
@ -123,10 +94,6 @@ UCHAR WINAPI EmulatorIntAcknowledge
VOID EmulatorException(BYTE ExceptionNumber, LPWORD Stack);
VOID EmulatorExecute(WORD Segment, WORD Offset);
VOID EmulatorStep(VOID);
VOID EmulatorSimulate(VOID);
VOID EmulatorUnsimulate(VOID);
VOID EmulatorTerminate(VOID);
VOID EmulatorInterrupt(BYTE Number);

View file

@ -14,25 +14,55 @@
#include "emulator.h"
#include "int32.h"
#include "bop.h"
#include "cpu/bop.h"
#include <isvbop.h>
/* PRIVATE VARIABLES **********************************************************/
/*
* This is the list of registered 32-bit Interrupt handlers.
*/
EMULATOR_INT32_PROC Int32Proc[EMULATOR_MAX_INT32_NUM] = { NULL };
static EMULATOR_INT32_PROC Int32Proc[EMULATOR_MAX_INT32_NUM] = { NULL };
/* BOP Identifiers */
#define BOP_CONTROL 0xFF // Control BOP Handler
#define BOP_CONTROL_DEFFUNC 0x00 // Default Control BOP Function
#define BOP_CONTROL_INT32 0xFF // 32-bit Interrupt dispatcher
/* 32-bit Interrupt dispatcher function code for the Control BOP Handler */
#define BOP_CONTROL_INT32 0xFF
#define INT16_TRAMPOLINE_SIZE sizeof(ULONGLONG) // == TRAMPOLINE_SIZE
/* 16-bit generic interrupt code for calling a 32-bit interrupt handler */
static BYTE Int16To32[] =
{
0xFA, // cli
/* Push the value of the interrupt to be called */
0x6A, 0xFF, // push i (patchable to 0x6A, 0xIntNum)
/* The BOP Sequence */
// BOP_SEQ:
0xF8, // clc
BOP(BOP_CONTROL), // Control BOP
BOP_CONTROL_INT32, // 32-bit Interrupt dispatcher
0x73, 0x04, // jnc EXIT (offset +4)
0xFB, // sti
// HACK: The following instruction should be HLT!
0x90, // nop
0xEB, 0xF5, // jmp BOP_SEQ (offset -11)
// EXIT:
0x44, 0x44, // inc sp, inc sp
0xCF, // iret
};
const ULONG Int16To32StubSize = sizeof(Int16To32);
/* PUBLIC FUNCTIONS ***********************************************************/
VOID WINAPI Int32Dispatch(LPWORD Stack)
static VOID WINAPI Int32Dispatch(LPWORD Stack)
{
/* Get the interrupt number */
BYTE IntNum = LOBYTE(Stack[STACK_INT_NUM]);
@ -41,88 +71,127 @@ VOID WINAPI Int32Dispatch(LPWORD Stack)
if (Int32Proc[IntNum] != NULL)
Int32Proc[IntNum](Stack);
else
DPRINT("Unhandled 32-bit interrupt: 0x%02X, AX = 0x%04X\n", IntNum, getAX());
DPRINT1("Unhandled 32-bit interrupt: 0x%02X, AX = 0x%04X\n", IntNum, getAX());
}
VOID WINAPI ControlBop(LPWORD Stack)
static VOID WINAPI ControlBop(LPWORD Stack)
{
/* Get the Function Number and skip it */
BYTE FuncNum = *(PBYTE)SEG_OFF_TO_PTR(getCS(), getIP());
setIP(getIP() + 1);
if (FuncNum == BOP_CONTROL_INT32)
Int32Dispatch(Stack);
else
DPRINT("Unassigned Control BOP Function: 0x%02X\n", FuncNum);
switch (FuncNum)
{
case BOP_CONTROL_INT32:
Int32Dispatch(Stack);
break;
default:
// DPRINT1("Unassigned Control BOP Function: 0x%02X\n", FuncNum);
DisplayMessage(L"Unassigned Control BOP Function: 0x%02X", FuncNum);
break;
}
}
VOID InitializeInt32(WORD BiosSegment)
ULONG
RegisterInt16(IN ULONG FarPtr,
IN BYTE IntNumber,
IN LPBYTE CallbackCode,
IN SIZE_T CallbackSize,
OUT PSIZE_T CodeSize OPTIONAL)
{
//
// WARNING WARNING!!
//
// If you modify the code stubs here, think also
// about updating them in callback.c too!!
//
/* Get a pointer to the IVT and set the corresponding entry (far pointer) */
LPDWORD IntVecTable = (LPDWORD)SEG_OFF_TO_PTR(0x0000, 0x0000);
IntVecTable[IntNumber] = FarPtr;
LPDWORD IntVecTable = (LPDWORD)BaseAddress;
LPBYTE BiosCode = (LPBYTE)SEG_OFF_TO_PTR(BiosSegment, 0);
USHORT i;
WORD BopSeqOffset, Offset = 0;
/* Register the 16-bit callback */
return RegisterCallback16(FarPtr,
CallbackCode,
CallbackSize,
CodeSize);
}
/* Generate ISR stubs and fill the IVT */
for (i = 0x00; i <= 0xFF; i++)
ULONG
RegisterInt32(IN ULONG FarPtr,
IN BYTE IntNumber,
IN EMULATOR_INT32_PROC IntHandler,
OUT PSIZE_T CodeSize OPTIONAL)
{
/* Array for holding our copy of the 16-bit interrupt callback */
BYTE IntCallback[sizeof(Int16To32)/sizeof(BYTE)];
/* Check whether the 32-bit interrupt was already registered */
#if 0
if (Int32Proc[IntNumber] != NULL)
{
Offset = INT_HANDLER_OFFSET + (i << 4);
IntVecTable[i] = MAKELONG(Offset, BiosSegment);
BiosCode[Offset++] = 0xFA; // cli
BiosCode[Offset++] = 0x6A; // push i
BiosCode[Offset++] = (UCHAR)i;
BopSeqOffset = COMMON_STUB_OFFSET - (Offset + 3);
BiosCode[Offset++] = 0xE9; // jmp near BOP_SEQ
BiosCode[Offset++] = LOBYTE(BopSeqOffset);
BiosCode[Offset++] = HIBYTE(BopSeqOffset);
DPRINT1("RegisterInt32: Interrupt 0x%02X already registered!\n", IntNumber);
return 0;
}
#endif
/* Write the common stub code */
Offset = COMMON_STUB_OFFSET;
/* Register the 32-bit interrupt handler */
Int32Proc[IntNumber] = IntHandler;
// BOP_SEQ:
BiosCode[Offset++] = 0xF8; // clc
/* Copy the generic 16-bit interrupt callback and patch it */
RtlCopyMemory(IntCallback, Int16To32, sizeof(Int16To32));
IntCallback[2] = IntNumber;
BiosCode[Offset++] = LOBYTE(EMULATOR_BOP); // BOP sequence
BiosCode[Offset++] = HIBYTE(EMULATOR_BOP);
BiosCode[Offset++] = BOP_CONTROL; // Control BOP
BiosCode[Offset++] = BOP_CONTROL_INT32; // 32-bit Interrupt dispatcher
/* Register the 16-bit interrupt callback */
return RegisterInt16(FarPtr,
IntNumber,
IntCallback,
sizeof(IntCallback),
CodeSize);
}
BiosCode[Offset++] = 0x73; // jnc EXIT (offset +4)
BiosCode[Offset++] = 0x04;
VOID
Int32Call(IN PCALLBACK16 Context,
IN BYTE IntNumber)
{
/*
* TODO: This function has almost the same code as RunCallback16.
* Something that may be nice is to have a common interface to
* build the trampoline...
*/
BiosCode[Offset++] = 0xFB; // sti
PUCHAR TrampolineBase = (PUCHAR)FAR_POINTER(Context->TrampolineFarPtr);
PUCHAR Trampoline = TrampolineBase;
UCHAR OldTrampoline[INT16_TRAMPOLINE_SIZE];
// HACK: The following instruction should be HLT!
BiosCode[Offset++] = 0x90; // nop
DPRINT("Int32Call(0x%02X)\n", IntNumber);
BiosCode[Offset++] = 0xEB; // jmp BOP_SEQ (offset -11)
BiosCode[Offset++] = 0xF5;
ASSERT(Context->TrampolineSize == INT16_TRAMPOLINE_SIZE);
// EXIT:
BiosCode[Offset++] = 0x44; // inc sp
BiosCode[Offset++] = 0x44; // inc sp
/* Save the old trampoline */
((PULONGLONG)&OldTrampoline)[0] = ((PULONGLONG)TrampolineBase)[0];
BiosCode[Offset++] = 0xCF; // iret
/* Build the generic entry-point for 16-bit calls */
if (IntNumber == 0x03)
{
/* We are redefining for INT 03h */
*Trampoline++ = 0xCC; // Call INT 03h
/** *Trampoline++ = 0x90; // nop **/
}
else
{
/* Normal interrupt */
*Trampoline++ = 0xCD; // Call INT XXh
*Trampoline++ = IntNumber;
}
UnSimulate16(Trampoline);
/* Perform the call */
Call16(HIWORD(Context->TrampolineFarPtr),
LOWORD(Context->TrampolineFarPtr));
/* Restore the old trampoline */
((PULONGLONG)TrampolineBase)[0] = ((PULONGLONG)&OldTrampoline)[0];
}
VOID InitializeInt32(VOID)
{
/* Register the Control BOP */
RegisterBop(BOP_CONTROL, ControlBop);
}
VOID RegisterInt32(BYTE IntNumber, EMULATOR_INT32_PROC IntHandler)
{
Int32Proc[IntNumber] = IntHandler;
}
/* EOF */

View file

@ -10,21 +10,39 @@
#ifndef _INT32_H_
#define _INT32_H_
/* INCLUDES *******************************************************************/
#include "cpu/callback.h"
/* DEFINES ********************************************************************/
/* 32-bit Interrupt Identifiers */
#define EMULATOR_MAX_INT32_NUM 0xFF + 1
#define INT_HANDLER_OFFSET 0x1000
#define COMMON_STUB_OFFSET 0x2000
extern const ULONG Int16To32StubSize;
/* FUNCTIONS ******************************************************************/
typedef VOID (WINAPI *EMULATOR_INT32_PROC)(LPWORD Stack);
VOID WINAPI Int32Dispatch(LPWORD Stack);
VOID InitializeInt32(WORD BiosSegment);
VOID RegisterInt32(BYTE IntNumber, EMULATOR_INT32_PROC IntHandler);
ULONG
RegisterInt16(IN ULONG FarPtr,
IN BYTE IntNumber,
IN LPBYTE CallbackCode,
IN SIZE_T CallbackSize,
OUT PSIZE_T CodeSize OPTIONAL);
ULONG
RegisterInt32(IN ULONG FarPtr,
IN BYTE IntNumber,
IN EMULATOR_INT32_PROC IntHandler,
OUT PSIZE_T CodeSize OPTIONAL);
VOID
Int32Call(IN PCALLBACK16 Context,
IN BYTE IntNumber);
VOID InitializeInt32(VOID);
#endif // _INT32_H_

View file

@ -11,24 +11,10 @@
#define NDEBUG
#include "emulator.h"
#include "cpu/cpu.h"
/* PUBLIC FUNCTIONS ***********************************************************/
static inline BOOLEAN EmulatorGetFlag(ULONG Flag)
{
return (EmulatorContext.Flags.Long & Flag) ? TRUE : FALSE;
}
static inline VOID EmulatorSetFlag(ULONG Flag)
{
EmulatorContext.Flags.Long |= Flag;
}
static inline VOID EmulatorClearFlag(ULONG Flag)
{
EmulatorContext.Flags.Long &= ~Flag;
}
VOID EmulatorSetStack(WORD Segment, DWORD Offset)
{
Fast486SetStack(&EmulatorContext, Segment, Offset);
@ -405,7 +391,7 @@ VOID
WINAPI
setEIP(ULONG Value)
{
EmulatorExecute(getCS(), Value);
CpuExecute(getCS(), Value);
}
USHORT
@ -419,7 +405,7 @@ VOID
WINAPI
setIP(USHORT Value)
{
EmulatorExecute(getCS(), Value);
CpuExecute(getCS(), Value);
}
@ -514,136 +500,112 @@ ULONG
WINAPI
getCF(VOID)
{
return EmulatorGetFlag(EMULATOR_FLAG_CF);
return EmulatorContext.Flags.Cf;
}
VOID
WINAPI
setCF(ULONG Flag)
{
if (Flag & 1)
EmulatorSetFlag(EMULATOR_FLAG_CF);
else
EmulatorClearFlag(EMULATOR_FLAG_CF);
EmulatorContext.Flags.Cf = !!(Flag & 1);
}
ULONG
WINAPI
getPF(VOID)
{
return EmulatorGetFlag(EMULATOR_FLAG_PF);
return EmulatorContext.Flags.Pf;
}
VOID
WINAPI
setPF(ULONG Flag)
{
if (Flag & 1)
EmulatorSetFlag(EMULATOR_FLAG_PF);
else
EmulatorClearFlag(EMULATOR_FLAG_PF);
EmulatorContext.Flags.Pf = !!(Flag & 1);
}
ULONG
WINAPI
getAF(VOID)
{
return EmulatorGetFlag(EMULATOR_FLAG_AF);
return EmulatorContext.Flags.Af;
}
VOID
WINAPI
setAF(ULONG Flag)
{
if (Flag & 1)
EmulatorSetFlag(EMULATOR_FLAG_AF);
else
EmulatorClearFlag(EMULATOR_FLAG_AF);
EmulatorContext.Flags.Af = !!(Flag & 1);
}
ULONG
WINAPI
getZF(VOID)
{
return EmulatorGetFlag(EMULATOR_FLAG_ZF);
return EmulatorContext.Flags.Zf;
}
VOID
WINAPI
setZF(ULONG Flag)
{
if (Flag & 1)
EmulatorSetFlag(EMULATOR_FLAG_ZF);
else
EmulatorClearFlag(EMULATOR_FLAG_ZF);
EmulatorContext.Flags.Zf = !!(Flag & 1);
}
ULONG
WINAPI
getSF(VOID)
{
return EmulatorGetFlag(EMULATOR_FLAG_SF);
return EmulatorContext.Flags.Sf;
}
VOID
WINAPI
setSF(ULONG Flag)
{
if (Flag & 1)
EmulatorSetFlag(EMULATOR_FLAG_SF);
else
EmulatorClearFlag(EMULATOR_FLAG_SF);
EmulatorContext.Flags.Sf = !!(Flag & 1);
}
ULONG
WINAPI
getIF(VOID)
{
return EmulatorGetFlag(EMULATOR_FLAG_IF);
return EmulatorContext.Flags.If;
}
VOID
WINAPI
setIF(ULONG Flag)
{
if (Flag & 1)
EmulatorSetFlag(EMULATOR_FLAG_IF);
else
EmulatorClearFlag(EMULATOR_FLAG_IF);
EmulatorContext.Flags.If = !!(Flag & 1);
}
ULONG
WINAPI
getDF(VOID)
{
return EmulatorGetFlag(EMULATOR_FLAG_DF);
return EmulatorContext.Flags.Df;
}
VOID
WINAPI
setDF(ULONG Flag)
{
if (Flag & 1)
EmulatorSetFlag(EMULATOR_FLAG_DF);
else
EmulatorClearFlag(EMULATOR_FLAG_DF);
EmulatorContext.Flags.Df = !!(Flag & 1);
}
ULONG
WINAPI
getOF(VOID)
{
return EmulatorGetFlag(EMULATOR_FLAG_OF);
return EmulatorContext.Flags.Of;
}
VOID
WINAPI
setOF(ULONG Flag)
{
if (Flag & 1)
EmulatorSetFlag(EMULATOR_FLAG_OF);
else
EmulatorClearFlag(EMULATOR_FLAG_OF);
EmulatorContext.Flags.Of = !!(Flag & 1);
}

View file

@ -13,8 +13,7 @@
#include "emulator.h"
#include "vddsup.h"
#include "bop.h"
#include "cpu/bop.h"
#include <isvbop.h>
typedef VOID (WINAPI *VDD_PROC)(VOID);