[FAST486][NTVDM]

Use FASTCALL instead of NTAPI. Merge EmulatorReadMemory with MemRead and
EmulatorWriteMemory with MemWrite.


svn path=/trunk/; revision=68109
This commit is contained in:
Aleksandar Andrejevic 2015-06-12 03:30:40 +00:00
parent 845fdcac41
commit c063145e96
18 changed files with 149 additions and 256 deletions

View file

@ -182,7 +182,7 @@ typedef enum _FAST486_EXCEPTIONS
typedef typedef
VOID VOID
(NTAPI *FAST486_MEM_READ_PROC) (FASTCALL *FAST486_MEM_READ_PROC)
( (
PFAST486_STATE State, PFAST486_STATE State,
ULONG Address, ULONG Address,
@ -192,7 +192,7 @@ VOID
typedef typedef
VOID VOID
(NTAPI *FAST486_MEM_WRITE_PROC) (FASTCALL *FAST486_MEM_WRITE_PROC)
( (
PFAST486_STATE State, PFAST486_STATE State,
ULONG Address, ULONG Address,
@ -202,7 +202,7 @@ VOID
typedef typedef
VOID VOID
(NTAPI *FAST486_IO_READ_PROC) (FASTCALL *FAST486_IO_READ_PROC)
( (
PFAST486_STATE State, PFAST486_STATE State,
USHORT Port, USHORT Port,
@ -213,7 +213,7 @@ VOID
typedef typedef
VOID VOID
(NTAPI *FAST486_IO_WRITE_PROC) (FASTCALL *FAST486_IO_WRITE_PROC)
( (
PFAST486_STATE State, PFAST486_STATE State,
USHORT Port, USHORT Port,
@ -224,7 +224,7 @@ VOID
typedef typedef
VOID VOID
(NTAPI *FAST486_BOP_PROC) (FASTCALL *FAST486_BOP_PROC)
( (
PFAST486_STATE State, PFAST486_STATE State,
UCHAR BopCode UCHAR BopCode
@ -232,14 +232,14 @@ VOID
typedef typedef
UCHAR UCHAR
(NTAPI *FAST486_INT_ACK_PROC) (FASTCALL *FAST486_INT_ACK_PROC)
( (
PFAST486_STATE State PFAST486_STATE State
); );
typedef typedef
VOID VOID
(NTAPI *FAST486_FPU_PROC) (FASTCALL *FAST486_FPU_PROC)
( (
PFAST486_STATE State PFAST486_STATE State
); );

View file

@ -43,91 +43,82 @@ typedef enum
/* PRIVATE FUNCTIONS **********************************************************/ /* PRIVATE FUNCTIONS **********************************************************/
#if 0 FORCEINLINE
static inline VOID VOID
NTAPI FASTCALL
Fast486ExecutionControl(PFAST486_STATE State, FAST486_EXEC_CMD Command) Fast486ExecutionControl(PFAST486_STATE State, FAST486_EXEC_CMD Command)
{ {
UCHAR Opcode; UCHAR Opcode;
FAST486_OPCODE_HANDLER_PROC CurrentHandler; FAST486_OPCODE_HANDLER_PROC CurrentHandler;
INT ProcedureCallCount = 0; INT ProcedureCallCount = 0;
BOOLEAN Trap;
/* Main execution loop */ /* Main execution loop */
do do
{ {
NextInst: Trap = State->Flags.Tf;
/* Check if this is a new instruction */
if (State->PrefixFlags == 0) State->SavedInstPtr = State->InstPtr;
/* Perform an instruction fetch */ if (!State->Halted)
if (!Fast486FetchByte(State, &Opcode))
{ {
/* Exception occurred */ 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; 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 * Check if there is an interrupt to execute, or a hardware interrupt signal
* while interrupts are enabled. * while interrupts are enabled.
*/ */
if (State->Flags.Tf) if (State->DoNotInterrupt)
{ {
/* Perform the interrupt */ /* Clear the interrupt delay flag */
Fast486PerformInterrupt(State, 0x01); State->DoNotInterrupt = FALSE;
/*
* 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;
} }
else if (State->IntStatus == FAST486_INT_EXECUTE) else if (Trap && !State->Halted)
{ {
/* Perform the interrupt */ /* Perform the interrupt */
Fast486PerformInterrupt(State, State->PendingIntNum); 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 */ /* Clear the interrupt status */
State->IntStatus = FAST486_INT_NONE; State->IntSignaled = FALSE;
}
else if (State->Flags.If && (State->IntStatus == FAST486_INT_SIGNAL))
{
/* Acknowledge the interrupt to get the number */
State->PendingIntNum = State->IntAckCallback(State);
/* 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;
} }
} }
while ((Command == FAST486_CONTINUE) || while ((Command == FAST486_CONTINUE) ||
(Command == FAST486_STEP_OVER && ProcedureCallCount > 0) || (Command == FAST486_STEP_OVER && ProcedureCallCount > 0) ||
(Command == FAST486_STEP_OUT && ProcedureCallCount >= 0)); (Command == FAST486_STEP_OUT && ProcedureCallCount >= 0));
} }
#else
VOID
NTAPI
Fast486ExecutionControl(PFAST486_STATE State, FAST486_EXEC_CMD Command);
#endif
/* PUBLIC FUNCTIONS ***********************************************************/ /* PUBLIC FUNCTIONS ***********************************************************/

View file

@ -31,98 +31,10 @@
#include "opcodes.h" #include "opcodes.h"
#include "fpu.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 **********************************************************/ /* DEFAULT CALLBACKS **********************************************************/
static VOID static VOID
NTAPI FASTCALL
Fast486MemReadCallback(PFAST486_STATE State, ULONG Address, PVOID Buffer, ULONG Size) Fast486MemReadCallback(PFAST486_STATE State, ULONG Address, PVOID Buffer, ULONG Size)
{ {
UNREFERENCED_PARAMETER(State); UNREFERENCED_PARAMETER(State);
@ -130,7 +42,7 @@ Fast486MemReadCallback(PFAST486_STATE State, ULONG Address, PVOID Buffer, ULONG
} }
static VOID static VOID
NTAPI FASTCALL
Fast486MemWriteCallback(PFAST486_STATE State, ULONG Address, PVOID Buffer, ULONG Size) Fast486MemWriteCallback(PFAST486_STATE State, ULONG Address, PVOID Buffer, ULONG Size)
{ {
UNREFERENCED_PARAMETER(State); UNREFERENCED_PARAMETER(State);
@ -138,7 +50,7 @@ Fast486MemWriteCallback(PFAST486_STATE State, ULONG Address, PVOID Buffer, ULONG
} }
static VOID static VOID
NTAPI FASTCALL
Fast486IoReadCallback(PFAST486_STATE State, USHORT Port, PVOID Buffer, ULONG DataCount, UCHAR DataSize) Fast486IoReadCallback(PFAST486_STATE State, USHORT Port, PVOID Buffer, ULONG DataCount, UCHAR DataSize)
{ {
UNREFERENCED_PARAMETER(State); UNREFERENCED_PARAMETER(State);
@ -149,7 +61,7 @@ Fast486IoReadCallback(PFAST486_STATE State, USHORT Port, PVOID Buffer, ULONG Dat
} }
static VOID static VOID
NTAPI FASTCALL
Fast486IoWriteCallback(PFAST486_STATE State, USHORT Port, PVOID Buffer, ULONG DataCount, UCHAR DataSize) Fast486IoWriteCallback(PFAST486_STATE State, USHORT Port, PVOID Buffer, ULONG DataCount, UCHAR DataSize)
{ {
UNREFERENCED_PARAMETER(State); UNREFERENCED_PARAMETER(State);
@ -160,7 +72,7 @@ Fast486IoWriteCallback(PFAST486_STATE State, USHORT Port, PVOID Buffer, ULONG Da
} }
static VOID static VOID
NTAPI FASTCALL
Fast486BopCallback(PFAST486_STATE State, UCHAR BopCode) Fast486BopCallback(PFAST486_STATE State, UCHAR BopCode)
{ {
UNREFERENCED_PARAMETER(State); UNREFERENCED_PARAMETER(State);
@ -168,7 +80,7 @@ Fast486BopCallback(PFAST486_STATE State, UCHAR BopCode)
} }
static UCHAR static UCHAR
NTAPI FASTCALL
Fast486IntAckCallback(PFAST486_STATE State) Fast486IntAckCallback(PFAST486_STATE State)
{ {
UNREFERENCED_PARAMETER(State); UNREFERENCED_PARAMETER(State);
@ -177,7 +89,8 @@ Fast486IntAckCallback(PFAST486_STATE State)
return 0x01; return 0x01;
} }
static VOID NTAPI static VOID
FASTCALL
Fast486FpuCallback(PFAST486_STATE State) Fast486FpuCallback(PFAST486_STATE State)
{ {
UNREFERENCED_PARAMETER(State); UNREFERENCED_PARAMETER(State);

View file

@ -15,6 +15,7 @@
#include "emulator.h" #include "emulator.h"
#include "cpu/cpu.h" #include "cpu/cpu.h"
#include "cpu/bop.h" #include "cpu/bop.h"
#include "memory.h"
#include "bios.h" #include "bios.h"
// #include "vidbios.h" // #include "vidbios.h"

View file

@ -29,7 +29,7 @@ VOID RegisterBop(BYTE BopCode, EMULATOR_BOP_PROC BopHandler)
BopProc[BopCode] = BopHandler; BopProc[BopCode] = BopHandler;
} }
VOID WINAPI EmulatorBiosOperation(PFAST486_STATE State, UCHAR BopCode) VOID FASTCALL EmulatorBiosOperation(PFAST486_STATE State, UCHAR BopCode)
{ {
WORD StackSegment, StackPointer; WORD StackSegment, StackPointer;
LPWORD Stack; LPWORD Stack;

View file

@ -21,7 +21,7 @@
typedef VOID (WINAPI *EMULATOR_BOP_PROC)(LPWORD Stack); typedef VOID (WINAPI *EMULATOR_BOP_PROC)(LPWORD Stack);
VOID RegisterBop(BYTE BopCode, EMULATOR_BOP_PROC BopHandler); 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_ #endif // _BOP_H_

View file

@ -704,7 +704,10 @@ WORD DosReadFile(WORD FileHandle,
if (ReadFile(Descriptor->Win32Handle, LocalBuffer, Count, &BytesRead32, NULL)) if (ReadFile(Descriptor->Win32Handle, LocalBuffer, Count, &BytesRead32, NULL))
{ {
/* Write to the memory */ /* 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 */ /* Update the position */
Descriptor->Position += BytesRead32; Descriptor->Position += BytesRead32;
@ -756,7 +759,11 @@ WORD DosWriteFile(WORD FileHandle,
ASSERT(LocalBuffer != NULL); ASSERT(LocalBuffer != NULL);
/* Read from the memory */ /* 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 */ /* Write the file */
if (WriteFile(Descriptor->Win32Handle, LocalBuffer, Count, &BytesWritten32, NULL)) if (WriteFile(Descriptor->Win32Handle, LocalBuffer, Count, &BytesWritten32, NULL))

View file

@ -13,6 +13,7 @@
#include "ntvdm.h" #include "ntvdm.h"
#include "emulator.h" #include "emulator.h"
#include "cpu/bop.h" #include "cpu/bop.h"
#include "../../memory.h"
#include "io.h" #include "io.h"
#include "hardware/ps2.h" #include "hardware/ps2.h"

View file

@ -6,8 +6,8 @@
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org> * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
*/ */
#ifndef _MEMORY_H_ #ifndef _DOS_MEMORY_H_
#define _MEMORY_H_ #define _DOS_MEMORY_H_
/* TYPEDEFS *******************************************************************/ /* TYPEDEFS *******************************************************************/
@ -45,6 +45,6 @@ BOOLEAN DosLinkUmb(VOID);
BOOLEAN DosUnlinkUmb(VOID); BOOLEAN DosUnlinkUmb(VOID);
VOID DosChangeMemoryOwner(WORD Segment, WORD NewOwner); VOID DosChangeMemoryOwner(WORD Segment, WORD NewOwner);
#endif // _MEMORY_H_ #endif // _DOS_MEMORY_H_
/* EOF */ /* EOF */

View file

@ -24,6 +24,7 @@
#include "bios/bios.h" #include "bios/bios.h"
#include "bios/bios32/bios32p.h" #include "bios/bios32/bios32p.h"
#include "memory.h"
#include "io.h" #include "io.h"
#include "dos32krnl/dos.h" #include "dos32krnl/dos.h"

View file

@ -42,8 +42,6 @@
LPVOID BaseAddress = NULL; LPVOID BaseAddress = NULL;
BOOLEAN VdmRunning = TRUE; BOOLEAN VdmRunning = TRUE;
static BOOLEAN A20Line = FALSE;
static HANDLE InputThread = NULL; static HANDLE InputThread = NULL;
LPCWSTR ExceptionName[] = LPCWSTR ExceptionName[] =
@ -63,46 +61,7 @@ LPCWSTR ExceptionName[] =
/* PRIVATE FUNCTIONS **********************************************************/ /* PRIVATE FUNCTIONS **********************************************************/
VOID WINAPI EmulatorReadMemory(PFAST486_STATE State, ULONG Address, PVOID Buffer, ULONG Size) UCHAR FASTCALL EmulatorIntAcknowledge(PFAST486_STATE State)
{
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)
{ {
UNREFERENCED_PARAMETER(State); UNREFERENCED_PARAMETER(State);
@ -110,7 +69,7 @@ UCHAR WINAPI EmulatorIntAcknowledge(PFAST486_STATE State)
return PicGetInterrupt(); return PicGetInterrupt();
} }
VOID WINAPI EmulatorFpu(PFAST486_STATE State) VOID FASTCALL EmulatorFpu(PFAST486_STATE State)
{ {
/* The FPU is wired to IRQ 13 */ /* The FPU is wired to IRQ 13 */
PicInterruptRequest(13); PicInterruptRequest(13);
@ -164,16 +123,6 @@ VOID EmulatorInterruptSignal(VOID)
Fast486InterruptSignal(&EmulatorContext); Fast486InterruptSignal(&EmulatorContext);
} }
VOID EmulatorSetA20(BOOLEAN Enabled)
{
A20Line = Enabled;
}
BOOLEAN EmulatorGetA20(VOID)
{
return A20Line;
}
static VOID WINAPI EmulatorDebugBreakBop(LPWORD Stack) static VOID WINAPI EmulatorDebugBreakBop(LPWORD Stack)
{ {
DPRINT1("NTVDM: BOP_DEBUGGER\n"); DPRINT1("NTVDM: BOP_DEBUGGER\n");

View file

@ -90,7 +90,7 @@ enum
EMULATOR_EXCEPTION_PAGE_FAULT EMULATOR_EXCEPTION_PAGE_FAULT
}; };
// extern FAST486_STATE EmulatorContext; extern FAST486_STATE EmulatorContext;
extern LPVOID BaseAddress; extern LPVOID BaseAddress;
extern BOOLEAN VdmRunning; extern BOOLEAN VdmRunning;
@ -98,28 +98,12 @@ extern BOOLEAN VdmRunning;
VOID DumpMemory(BOOLEAN TextFormat); VOID DumpMemory(BOOLEAN TextFormat);
VOID WINAPI EmulatorReadMemory UCHAR FASTCALL EmulatorIntAcknowledge
(
PFAST486_STATE State,
ULONG Address,
PVOID Buffer,
ULONG Size
);
VOID WINAPI EmulatorWriteMemory
(
PFAST486_STATE State,
ULONG Address,
PVOID Buffer,
ULONG Size
);
UCHAR WINAPI EmulatorIntAcknowledge
( (
PFAST486_STATE State PFAST486_STATE State
); );
VOID WINAPI EmulatorFpu VOID FASTCALL EmulatorFpu
( (
PFAST486_STATE State PFAST486_STATE State
); );
@ -129,8 +113,6 @@ VOID EmulatorException(BYTE ExceptionNumber, LPWORD Stack);
VOID EmulatorTerminate(VOID); VOID EmulatorTerminate(VOID);
VOID EmulatorInterruptSignal(VOID); VOID EmulatorInterruptSignal(VOID);
VOID EmulatorSetA20(BOOLEAN Enabled);
BOOLEAN EmulatorGetA20(VOID);
BOOLEAN EmulatorInitialize(HANDLE ConsoleInput, HANDLE ConsoleOutput); BOOLEAN EmulatorInitialize(HANDLE ConsoleInput, HANDLE ConsoleOutput);
VOID EmulatorCleanup(VOID); VOID EmulatorCleanup(VOID);

View file

@ -477,13 +477,13 @@ DWORD DmaRequest(IN WORD iChannel,
if (Increment) if (Increment)
{ {
MemWrite(CurrAddress, dmabuf, length); EmulatorWriteMemory(&EmulatorContext, CurrAddress, dmabuf, length);
} }
else else
{ {
for (i = 0; i < length; i++) for (i = 0; i < length; i++)
{ {
MemWrite(CurrAddress - i, dmabuf + i, sizeof(BYTE)); EmulatorWriteMemory(&EmulatorContext, CurrAddress - i, dmabuf + i, sizeof(BYTE));
} }
} }
@ -498,13 +498,13 @@ DWORD DmaRequest(IN WORD iChannel,
if (Increment) if (Increment)
{ {
MemRead(CurrAddress, dmabuf, length); EmulatorReadMemory(&EmulatorContext, CurrAddress, dmabuf, length);
} }
else else
{ {
for (i = 0; i < length; i++) for (i = 0; i < length; i++)
{ {
MemRead(CurrAddress - i, dmabuf + i, sizeof(BYTE)); EmulatorReadMemory(&EmulatorContext, CurrAddress - i, dmabuf + i, sizeof(BYTE));
} }
} }

View file

@ -15,6 +15,7 @@
#include "emulator.h" #include "emulator.h"
#include "ps2.h" #include "ps2.h"
#include "memory.h"
#include "io.h" #include "io.h"
#include "pic.h" #include "pic.h"
#include "clock.h" #include "clock.h"

View file

@ -343,7 +343,7 @@ VOID UnregisterIoPort(USHORT Port)
RtlZeroMemory(&IoPortProc[Port], sizeof(IoPortProc[Port])); RtlZeroMemory(&IoPortProc[Port], sizeof(IoPortProc[Port]));
} }
VOID WINAPI VOID FASTCALL
EmulatorReadIo(PFAST486_STATE State, EmulatorReadIo(PFAST486_STATE State,
USHORT Port, USHORT Port,
PVOID Buffer, PVOID Buffer,
@ -418,7 +418,7 @@ EmulatorReadIo(PFAST486_STATE State,
} }
} }
VOID WINAPI VOID FASTCALL
EmulatorWriteIo(PFAST486_STATE State, EmulatorWriteIo(PFAST486_STATE State,
USHORT Port, USHORT Port,
PVOID Buffer, PVOID Buffer,

View file

@ -85,7 +85,7 @@ VOID RegisterIoPort(USHORT Port,
VOID UnregisterIoPort(USHORT Port); VOID UnregisterIoPort(USHORT Port);
VOID WINAPI EmulatorReadIo VOID FASTCALL EmulatorReadIo
( (
PFAST486_STATE State, PFAST486_STATE State,
USHORT Port, USHORT Port,
@ -94,7 +94,7 @@ VOID WINAPI EmulatorReadIo
UCHAR DataSize UCHAR DataSize
); );
VOID WINAPI EmulatorWriteIo VOID FASTCALL EmulatorWriteIo
( (
PFAST486_STATE State, PFAST486_STATE State,
USHORT Port, USHORT Port,

View file

@ -36,6 +36,7 @@ typedef struct _MEM_HOOK
static LIST_ENTRY HookList; static LIST_ENTRY HookList;
static PMEM_HOOK PageTable[TOTAL_PAGES] = { NULL }; static PMEM_HOOK PageTable[TOTAL_PAGES] = { NULL };
static BOOLEAN A20Line = FALSE;
/* PRIVATE FUNCTIONS **********************************************************/ /* PRIVATE FUNCTIONS **********************************************************/
@ -137,12 +138,32 @@ WritePage(PMEM_HOOK Hook, ULONG Address, PVOID Buffer, ULONG Size)
/* PUBLIC FUNCTIONS ***********************************************************/ /* PUBLIC FUNCTIONS ***********************************************************/
VOID VOID FASTCALL EmulatorReadMemory(PFAST486_STATE State, ULONG Address, PVOID Buffer, ULONG Size)
MemRead(ULONG Address, PVOID Buffer, ULONG Size)
{ {
ULONG i, Offset, Length; ULONG i, Offset, Length;
ULONG FirstPage = Address >> 12; ULONG FirstPage, LastPage;
ULONG LastPage = (Address + Size - 1) >> 12;
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) if (FirstPage == LastPage)
{ {
@ -161,12 +182,21 @@ MemRead(ULONG Address, PVOID Buffer, ULONG Size)
} }
} }
VOID VOID FASTCALL EmulatorWriteMemory(PFAST486_STATE State, ULONG Address, PVOID Buffer, ULONG Size)
MemWrite(ULONG Address, PVOID Buffer, ULONG Size)
{ {
ULONG i, Offset, Length; ULONG i, Offset, Length;
ULONG FirstPage = Address >> 12; ULONG FirstPage, LastPage;
ULONG LastPage = (Address + Size - 1) >> 12;
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) if (FirstPage == LastPage)
{ {
@ -185,6 +215,16 @@ MemWrite(ULONG Address, PVOID Buffer, ULONG Size)
} }
} }
VOID EmulatorSetA20(BOOLEAN Enabled)
{
A20Line = Enabled;
}
BOOLEAN EmulatorGetA20(VOID)
{
return A20Line;
}
VOID VOID
MemExceptionHandler(ULONG FaultAddress, BOOLEAN Writing) MemExceptionHandler(ULONG FaultAddress, BOOLEAN Writing)
{ {

View file

@ -36,21 +36,28 @@ VOID MemCleanup(VOID);
VOID MemExceptionHandler(ULONG FaultAddress, BOOLEAN Writing); VOID MemExceptionHandler(ULONG FaultAddress, BOOLEAN Writing);
VOID VOID
MemRead FASTCALL
EmulatorReadMemory
( (
PFAST486_STATE State,
ULONG Address, ULONG Address,
PVOID Buffer, PVOID Buffer,
ULONG Size ULONG Size
); );
VOID VOID
MemWrite FASTCALL
EmulatorWriteMemory
( (
PFAST486_STATE State,
ULONG Address, ULONG Address,
PVOID Buffer, PVOID Buffer,
ULONG Size ULONG Size
); );
VOID EmulatorSetA20(BOOLEAN Enabled);
BOOLEAN EmulatorGetA20(VOID);
BOOL BOOL
MemInstallFastMemoryHook MemInstallFastMemoryHook
( (