typedef
VOID
-(NTAPI *FAST486_MEM_READ_PROC)
+(FASTCALL *FAST486_MEM_READ_PROC)
(
PFAST486_STATE State,
ULONG Address,
typedef
VOID
-(NTAPI *FAST486_MEM_WRITE_PROC)
+(FASTCALL *FAST486_MEM_WRITE_PROC)
(
PFAST486_STATE State,
ULONG Address,
typedef
VOID
-(NTAPI *FAST486_IO_READ_PROC)
+(FASTCALL *FAST486_IO_READ_PROC)
(
PFAST486_STATE State,
USHORT Port,
typedef
VOID
-(NTAPI *FAST486_IO_WRITE_PROC)
+(FASTCALL *FAST486_IO_WRITE_PROC)
(
PFAST486_STATE State,
USHORT Port,
typedef
VOID
-(NTAPI *FAST486_BOP_PROC)
+(FASTCALL *FAST486_BOP_PROC)
(
PFAST486_STATE State,
UCHAR BopCode
typedef
UCHAR
-(NTAPI *FAST486_INT_ACK_PROC)
+(FASTCALL *FAST486_INT_ACK_PROC)
(
PFAST486_STATE State
);
typedef
VOID
-(NTAPI *FAST486_FPU_PROC)
+(FASTCALL *FAST486_FPU_PROC)
(
PFAST486_STATE State
);
/* PRIVATE FUNCTIONS **********************************************************/
-#if 0
-static inline VOID
-NTAPI
+FORCEINLINE
+VOID
+FASTCALL
Fast486ExecutionControl(PFAST486_STATE State, FAST486_EXEC_CMD Command)
{
UCHAR Opcode;
FAST486_OPCODE_HANDLER_PROC CurrentHandler;
INT ProcedureCallCount = 0;
+ BOOLEAN Trap;
/* Main execution loop */
do
{
-NextInst:
- /* Check if this is a new instruction */
- if (State->PrefixFlags == 0) State->SavedInstPtr = State->InstPtr;
+ Trap = State->Flags.Tf;
- /* Perform an instruction fetch */
- if (!Fast486FetchByte(State, &Opcode))
+ if (!State->Halted)
{
- /* Exception occurred */
- State->PrefixFlags = 0;
- continue;
- }
+NextInst:
+ /* Check if this is a new instruction */
+ if (State->PrefixFlags == 0)
+ {
+ State->SavedInstPtr = State->InstPtr;
+ State->SavedStackPtr = State->GeneralRegs[FAST486_REG_ESP];
+ }
- // TODO: Check for CALL/RET to update ProcedureCallCount.
+ /* Perform an instruction fetch */
+ if (!Fast486FetchByte(State, &Opcode))
+ {
+ /* Exception occurred */
+ State->PrefixFlags = 0;
+ continue;
+ }
- /* Call the opcode handler */
- CurrentHandler = Fast486OpcodeHandlers[Opcode];
- CurrentHandler(State, Opcode);
+ // TODO: Check for CALL/RET to update ProcedureCallCount.
- /* If this is a prefix, go to the next instruction immediately */
- if (CurrentHandler == Fast486OpcodePrefix) goto NextInst;
+ /* Call the opcode handler */
+ CurrentHandler = Fast486OpcodeHandlers[Opcode];
+ CurrentHandler(State, Opcode);
- /* A non-prefix opcode has been executed, reset the prefix flags */
- State->PrefixFlags = 0;
+ /* If this is a prefix, go to the next instruction immediately */
+ if (CurrentHandler == Fast486OpcodePrefix) goto NextInst;
+
+ /* A non-prefix opcode has been executed, reset the prefix flags */
+ State->PrefixFlags = 0;
+ }
/*
* Check if there is an interrupt to execute, or a hardware interrupt signal
* while interrupts are enabled.
*/
- if (State->Flags.Tf)
+ if (State->DoNotInterrupt)
{
- /* Perform the interrupt */
- Fast486PerformInterrupt(State, 0x01);
-
- /*
- * Flags and TF are pushed on stack so we can reset TF now,
- * to not break into the INT 0x01 handler.
- * After the INT 0x01 handler returns, the flags and therefore
- * TF are popped back off the stack and restored, so TF will be
- * automatically reset to its previous state.
- */
- State->Flags.Tf = FALSE;
+ /* Clear the interrupt delay flag */
+ State->DoNotInterrupt = FALSE;
}
- else if (State->IntStatus == FAST486_INT_EXECUTE)
+ else if (Trap && !State->Halted)
{
/* Perform the interrupt */
- Fast486PerformInterrupt(State, State->PendingIntNum);
-
- /* Clear the interrupt status */
- State->IntStatus = FAST486_INT_NONE;
+ Fast486PerformInterrupt(State, FAST486_EXCEPTION_DB);
}
- else if (State->Flags.If && (State->IntStatus == FAST486_INT_SIGNAL))
+ else if (State->Flags.If && State->IntSignaled)
{
- /* Acknowledge the interrupt to get the number */
- State->PendingIntNum = State->IntAckCallback(State);
+ /* No longer halted */
+ State->Halted = FALSE;
- /* Set the interrupt status to execute on the next instruction */
- State->IntStatus = FAST486_INT_EXECUTE;
- }
- else if (State->IntStatus == FAST486_INT_DELAYED)
- {
- /* Restore the old state */
- State->IntStatus = FAST486_INT_EXECUTE;
+ /* Acknowledge the interrupt and perform it */
+ Fast486PerformInterrupt(State, State->IntAckCallback(State));
+
+ /* Clear the interrupt status */
+ State->IntSignaled = FALSE;
}
}
while ((Command == FAST486_CONTINUE) ||
(Command == FAST486_STEP_OVER && ProcedureCallCount > 0) ||
(Command == FAST486_STEP_OUT && ProcedureCallCount >= 0));
}
-#else
-VOID
-NTAPI
-Fast486ExecutionControl(PFAST486_STATE State, FAST486_EXEC_CMD Command);
-#endif
/* PUBLIC FUNCTIONS ***********************************************************/
#include "opcodes.h"
#include "fpu.h"
-/* DEFINES ********************************************************************/
-
-typedef enum
-{
- FAST486_STEP_INTO,
- FAST486_STEP_OVER,
- FAST486_STEP_OUT,
- FAST486_CONTINUE
-} FAST486_EXEC_CMD;
-
-/* PRIVATE FUNCTIONS **********************************************************/
-
-VOID
-NTAPI
-Fast486ExecutionControl(PFAST486_STATE State, FAST486_EXEC_CMD Command)
-{
- UCHAR Opcode;
- FAST486_OPCODE_HANDLER_PROC CurrentHandler;
- INT ProcedureCallCount = 0;
- BOOLEAN Trap;
-
- /* Main execution loop */
- do
- {
- Trap = State->Flags.Tf;
-
- if (!State->Halted)
- {
-NextInst:
- /* Check if this is a new instruction */
- if (State->PrefixFlags == 0)
- {
- State->SavedInstPtr = State->InstPtr;
- State->SavedStackPtr = State->GeneralRegs[FAST486_REG_ESP];
- }
-
- /* Perform an instruction fetch */
- if (!Fast486FetchByte(State, &Opcode))
- {
- /* Exception occurred */
- State->PrefixFlags = 0;
- continue;
- }
-
- // TODO: Check for CALL/RET to update ProcedureCallCount.
-
- /* Call the opcode handler */
- CurrentHandler = Fast486OpcodeHandlers[Opcode];
- CurrentHandler(State, Opcode);
-
- /* If this is a prefix, go to the next instruction immediately */
- if (CurrentHandler == Fast486OpcodePrefix) goto NextInst;
-
- /* A non-prefix opcode has been executed, reset the prefix flags */
- State->PrefixFlags = 0;
- }
-
- /*
- * Check if there is an interrupt to execute, or a hardware interrupt signal
- * while interrupts are enabled.
- */
- if (State->DoNotInterrupt)
- {
- /* Clear the interrupt delay flag */
- State->DoNotInterrupt = FALSE;
- }
- else if (Trap && !State->Halted)
- {
- /* Perform the interrupt */
- Fast486PerformInterrupt(State, FAST486_EXCEPTION_DB);
- }
- else if (State->Flags.If && State->IntSignaled)
- {
- /* No longer halted */
- State->Halted = FALSE;
-
- /* Acknowledge the interrupt and perform it */
- Fast486PerformInterrupt(State, State->IntAckCallback(State));
-
- /* Clear the interrupt status */
- State->IntSignaled = FALSE;
- }
- }
- while ((Command == FAST486_CONTINUE) ||
- (Command == FAST486_STEP_OVER && ProcedureCallCount > 0) ||
- (Command == FAST486_STEP_OUT && ProcedureCallCount >= 0));
-}
-
/* DEFAULT CALLBACKS **********************************************************/
static VOID
-NTAPI
+FASTCALL
Fast486MemReadCallback(PFAST486_STATE State, ULONG Address, PVOID Buffer, ULONG Size)
{
UNREFERENCED_PARAMETER(State);
}
static VOID
-NTAPI
+FASTCALL
Fast486MemWriteCallback(PFAST486_STATE State, ULONG Address, PVOID Buffer, ULONG Size)
{
UNREFERENCED_PARAMETER(State);
}
static VOID
-NTAPI
+FASTCALL
Fast486IoReadCallback(PFAST486_STATE State, USHORT Port, PVOID Buffer, ULONG DataCount, UCHAR DataSize)
{
UNREFERENCED_PARAMETER(State);
}
static VOID
-NTAPI
+FASTCALL
Fast486IoWriteCallback(PFAST486_STATE State, USHORT Port, PVOID Buffer, ULONG DataCount, UCHAR DataSize)
{
UNREFERENCED_PARAMETER(State);
}
static VOID
-NTAPI
+FASTCALL
Fast486BopCallback(PFAST486_STATE State, UCHAR BopCode)
{
UNREFERENCED_PARAMETER(State);
}
static UCHAR
-NTAPI
+FASTCALL
Fast486IntAckCallback(PFAST486_STATE State)
{
UNREFERENCED_PARAMETER(State);
return 0x01;
}
-static VOID NTAPI
+static VOID
+FASTCALL
Fast486FpuCallback(PFAST486_STATE State)
{
UNREFERENCED_PARAMETER(State);
#include "emulator.h"
#include "cpu/cpu.h"
#include "cpu/bop.h"
+#include "memory.h"
#include "bios.h"
// #include "vidbios.h"
BopProc[BopCode] = BopHandler;
}
-VOID WINAPI EmulatorBiosOperation(PFAST486_STATE State, UCHAR BopCode)
+VOID FASTCALL EmulatorBiosOperation(PFAST486_STATE State, UCHAR BopCode)
{
WORD StackSegment, StackPointer;
LPWORD Stack;
typedef VOID (WINAPI *EMULATOR_BOP_PROC)(LPWORD Stack);
VOID RegisterBop(BYTE BopCode, EMULATOR_BOP_PROC BopHandler);
-VOID WINAPI EmulatorBiosOperation(PFAST486_STATE State, UCHAR BopCode);
+VOID FASTCALL EmulatorBiosOperation(PFAST486_STATE State, UCHAR BopCode);
#endif // _BOP_H_
if (ReadFile(Descriptor->Win32Handle, LocalBuffer, Count, &BytesRead32, NULL))
{
/* Write to the memory */
- MemWrite(TO_LINEAR(HIWORD(Buffer), LOWORD(Buffer)), LocalBuffer, LOWORD(BytesRead32));
+ EmulatorWriteMemory(&EmulatorContext,
+ TO_LINEAR(HIWORD(Buffer), LOWORD(Buffer)),
+ LocalBuffer,
+ LOWORD(BytesRead32));
/* Update the position */
Descriptor->Position += BytesRead32;
ASSERT(LocalBuffer != NULL);
/* Read from the memory */
- MemRead(TO_LINEAR(HIWORD(Buffer), LOWORD(Buffer)), LocalBuffer, Count);
+ EmulatorReadMemory(&EmulatorContext,
+ TO_LINEAR(HIWORD(Buffer),
+ LOWORD(Buffer)),
+ LocalBuffer,
+ Count);
/* Write the file */
if (WriteFile(Descriptor->Win32Handle, LocalBuffer, Count, &BytesWritten32, NULL))
#include "ntvdm.h"
#include "emulator.h"
#include "cpu/bop.h"
+#include "../../memory.h"
#include "io.h"
#include "hardware/ps2.h"
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
*/
-#ifndef _MEMORY_H_
-#define _MEMORY_H_
+#ifndef _DOS_MEMORY_H_
+#define _DOS_MEMORY_H_
/* TYPEDEFS *******************************************************************/
BOOLEAN DosUnlinkUmb(VOID);
VOID DosChangeMemoryOwner(WORD Segment, WORD NewOwner);
-#endif // _MEMORY_H_
+#endif // _DOS_MEMORY_H_
/* EOF */
#include "bios/bios.h"
#include "bios/bios32/bios32p.h"
+#include "memory.h"
#include "io.h"
#include "dos32krnl/dos.h"
LPVOID BaseAddress = NULL;
BOOLEAN VdmRunning = TRUE;
-static BOOLEAN A20Line = FALSE;
-
static HANDLE InputThread = NULL;
LPCWSTR ExceptionName[] =
/* PRIVATE FUNCTIONS **********************************************************/
-VOID WINAPI EmulatorReadMemory(PFAST486_STATE State, ULONG Address, PVOID Buffer, ULONG Size)
-{
- UNREFERENCED_PARAMETER(State);
-
- /* Mirror 0x000FFFF0 at 0xFFFFFFF0 */
- if (Address >= 0xFFFFFFF0) Address -= 0xFFF00000;
-
- /* If the A20 line is disabled, mask bit 20 */
- if (!A20Line) Address &= ~(1 << 20);
-
- if ((Address + Size - 1) >= MAX_ADDRESS)
- {
- ULONG ExtraStart = (Address < MAX_ADDRESS) ? MAX_ADDRESS - Address : 0;
-
- /* Fill the memory that was above the limit with 0xFF */
- RtlFillMemory((PVOID)((ULONG_PTR)Buffer + ExtraStart), Size - ExtraStart, 0xFF);
-
- if (Address < MAX_ADDRESS) Size = MAX_ADDRESS - Address;
- else return;
- }
-
- /* Read while calling fast memory hooks */
- MemRead(Address, Buffer, Size);
-}
-
-VOID WINAPI EmulatorWriteMemory(PFAST486_STATE State, ULONG Address, PVOID Buffer, ULONG Size)
-{
- UNREFERENCED_PARAMETER(State);
-
- /* If the A20 line is disabled, mask bit 20 */
- if (!A20Line) Address &= ~(1 << 20);
-
- if (Address >= MAX_ADDRESS) return;
- Size = min(Size, MAX_ADDRESS - Address);
-
- /* Write while calling fast memory hooks */
- MemWrite(Address, Buffer, Size);
-}
-
-UCHAR WINAPI EmulatorIntAcknowledge(PFAST486_STATE State)
+UCHAR FASTCALL EmulatorIntAcknowledge(PFAST486_STATE State)
{
UNREFERENCED_PARAMETER(State);
return PicGetInterrupt();
}
-VOID WINAPI EmulatorFpu(PFAST486_STATE State)
+VOID FASTCALL EmulatorFpu(PFAST486_STATE State)
{
/* The FPU is wired to IRQ 13 */
PicInterruptRequest(13);
Fast486InterruptSignal(&EmulatorContext);
}
-VOID EmulatorSetA20(BOOLEAN Enabled)
-{
- A20Line = Enabled;
-}
-
-BOOLEAN EmulatorGetA20(VOID)
-{
- return A20Line;
-}
-
static VOID WINAPI EmulatorDebugBreakBop(LPWORD Stack)
{
DPRINT1("NTVDM: BOP_DEBUGGER\n");
EMULATOR_EXCEPTION_PAGE_FAULT
};
-// extern FAST486_STATE EmulatorContext;
+extern FAST486_STATE EmulatorContext;
extern LPVOID BaseAddress;
extern BOOLEAN VdmRunning;
VOID DumpMemory(BOOLEAN TextFormat);
-VOID WINAPI EmulatorReadMemory
-(
- PFAST486_STATE State,
- ULONG Address,
- PVOID Buffer,
- ULONG Size
-);
-
-VOID WINAPI EmulatorWriteMemory
-(
- PFAST486_STATE State,
- ULONG Address,
- PVOID Buffer,
- ULONG Size
-);
-
-UCHAR WINAPI EmulatorIntAcknowledge
+UCHAR FASTCALL EmulatorIntAcknowledge
(
PFAST486_STATE State
);
-VOID WINAPI EmulatorFpu
+VOID FASTCALL EmulatorFpu
(
PFAST486_STATE State
);
VOID EmulatorTerminate(VOID);
VOID EmulatorInterruptSignal(VOID);
-VOID EmulatorSetA20(BOOLEAN Enabled);
-BOOLEAN EmulatorGetA20(VOID);
BOOLEAN EmulatorInitialize(HANDLE ConsoleInput, HANDLE ConsoleOutput);
VOID EmulatorCleanup(VOID);
if (Increment)
{
- MemWrite(CurrAddress, dmabuf, length);
+ EmulatorWriteMemory(&EmulatorContext, CurrAddress, dmabuf, length);
}
else
{
for (i = 0; i < length; i++)
{
- MemWrite(CurrAddress - i, dmabuf + i, sizeof(BYTE));
+ EmulatorWriteMemory(&EmulatorContext, CurrAddress - i, dmabuf + i, sizeof(BYTE));
}
}
if (Increment)
{
- MemRead(CurrAddress, dmabuf, length);
+ EmulatorReadMemory(&EmulatorContext, CurrAddress, dmabuf, length);
}
else
{
for (i = 0; i < length; i++)
{
- MemRead(CurrAddress - i, dmabuf + i, sizeof(BYTE));
+ EmulatorReadMemory(&EmulatorContext, CurrAddress - i, dmabuf + i, sizeof(BYTE));
}
}
#include "emulator.h"
#include "ps2.h"
+#include "memory.h"
#include "io.h"
#include "pic.h"
#include "clock.h"
RtlZeroMemory(&IoPortProc[Port], sizeof(IoPortProc[Port]));
}
-VOID WINAPI
+VOID FASTCALL
EmulatorReadIo(PFAST486_STATE State,
USHORT Port,
PVOID Buffer,
}
}
-VOID WINAPI
+VOID FASTCALL
EmulatorWriteIo(PFAST486_STATE State,
USHORT Port,
PVOID Buffer,
VOID UnregisterIoPort(USHORT Port);
-VOID WINAPI EmulatorReadIo
+VOID FASTCALL EmulatorReadIo
(
PFAST486_STATE State,
USHORT Port,
UCHAR DataSize
);
-VOID WINAPI EmulatorWriteIo
+VOID FASTCALL EmulatorWriteIo
(
PFAST486_STATE State,
USHORT Port,
static LIST_ENTRY HookList;
static PMEM_HOOK PageTable[TOTAL_PAGES] = { NULL };
+static BOOLEAN A20Line = FALSE;
/* PRIVATE FUNCTIONS **********************************************************/
/* PUBLIC FUNCTIONS ***********************************************************/
-VOID
-MemRead(ULONG Address, PVOID Buffer, ULONG Size)
+VOID FASTCALL EmulatorReadMemory(PFAST486_STATE State, ULONG Address, PVOID Buffer, ULONG Size)
{
ULONG i, Offset, Length;
- ULONG FirstPage = Address >> 12;
- ULONG LastPage = (Address + Size - 1) >> 12;
+ ULONG FirstPage, LastPage;
+
+ UNREFERENCED_PARAMETER(State);
+
+ /* Mirror 0x000FFFF0 at 0xFFFFFFF0 */
+ if (Address >= 0xFFFFFFF0) Address -= 0xFFF00000;
+
+ /* If the A20 line is disabled, mask bit 20 */
+ if (!A20Line) Address &= ~(1 << 20);
+
+ if ((Address + Size - 1) >= MAX_ADDRESS)
+ {
+ ULONG ExtraStart = (Address < MAX_ADDRESS) ? MAX_ADDRESS - Address : 0;
+
+ /* Fill the memory that was above the limit with 0xFF */
+ RtlFillMemory((PVOID)((ULONG_PTR)Buffer + ExtraStart), Size - ExtraStart, 0xFF);
+
+ if (Address < MAX_ADDRESS) Size = MAX_ADDRESS - Address;
+ else return;
+ }
+
+ FirstPage = Address >> 12;
+ LastPage = (Address + Size - 1) >> 12;
if (FirstPage == LastPage)
{
}
}
-VOID
-MemWrite(ULONG Address, PVOID Buffer, ULONG Size)
+VOID FASTCALL EmulatorWriteMemory(PFAST486_STATE State, ULONG Address, PVOID Buffer, ULONG Size)
{
ULONG i, Offset, Length;
- ULONG FirstPage = Address >> 12;
- ULONG LastPage = (Address + Size - 1) >> 12;
+ ULONG FirstPage, LastPage;
+
+ UNREFERENCED_PARAMETER(State);
+
+ /* If the A20 line is disabled, mask bit 20 */
+ if (!A20Line) Address &= ~(1 << 20);
+
+ if (Address >= MAX_ADDRESS) return;
+ Size = min(Size, MAX_ADDRESS - Address);
+
+ FirstPage = Address >> 12;
+ LastPage = (Address + Size - 1) >> 12;
if (FirstPage == LastPage)
{
}
}
+VOID EmulatorSetA20(BOOLEAN Enabled)
+{
+ A20Line = Enabled;
+}
+
+BOOLEAN EmulatorGetA20(VOID)
+{
+ return A20Line;
+}
+
VOID
MemExceptionHandler(ULONG FaultAddress, BOOLEAN Writing)
{
VOID MemExceptionHandler(ULONG FaultAddress, BOOLEAN Writing);
VOID
-MemRead
+FASTCALL
+EmulatorReadMemory
(
+ PFAST486_STATE State,
ULONG Address,
PVOID Buffer,
ULONG Size
);
VOID
-MemWrite
+FASTCALL
+EmulatorWriteMemory
(
+ PFAST486_STATE State,
ULONG Address,
PVOID Buffer,
ULONG Size
);
+VOID EmulatorSetA20(BOOLEAN Enabled);
+BOOLEAN EmulatorGetA20(VOID);
+
BOOL
MemInstallFastMemoryHook
(