#define NDEBUG
#include "emulator.h"
+#include "callback.h"
#include "clock.h"
-#include "bios/bios.h"
+#include "bios/rom.h"
#include "hardware/cmos.h"
#include "hardware/pic.h"
#include "hardware/ps2.h"
/* PRIVATE VARIABLES **********************************************************/
FAST486_STATE EmulatorContext;
+BOOLEAN CpuSimulate = FALSE;
+
+/* No more than 'MaxCpuCallLevel' recursive CPU calls are allowed */
+const static INT MaxCpuCallLevel = 32;
+static INT CpuCallLevel = 0;
+
LPVOID BaseAddress = NULL;
BOOLEAN VdmRunning = TRUE;
{
UNREFERENCED_PARAMETER(State);
+ // BIG HACK!!!! To make BIOS images working correctly,
+ // until Aleksander rewrites memory management!!
+ if (Address >= 0xFFFFFFF0) Address -= 0xFFF00000;
+
/* If the A20 line is disabled, mask bit 20 */
if (!A20Line) Address &= ~(1 << 20);
DWORD VgaAddress = max(Address, VgaGetVideoBaseAddress());
DWORD ActualSize = min(Address + Size - 1, VgaGetVideoLimitAddress())
- VgaAddress + 1;
- LPBYTE DestBuffer = (LPBYTE)((ULONG_PTR)BaseAddress + VgaAddress);
+ LPBYTE DestBuffer = (LPBYTE)REAL_TO_PHYS(VgaAddress);
/* Read from the VGA memory */
VgaReadMemory(VgaAddress, DestBuffer, ActualSize);
}
/* Read the data from the virtual address space and store it in the buffer */
- RtlCopyMemory(Buffer, (LPVOID)((ULONG_PTR)BaseAddress + Address), Size);
+ RtlCopyMemory(Buffer, REAL_TO_PHYS(Address), Size);
}
VOID WINAPI EmulatorWriteMemory(PFAST486_STATE State, ULONG Address, PVOID Buffer, ULONG Size)
{
UNREFERENCED_PARAMETER(State);
+ // BIG HACK!!!! To make BIOS images working correctly,
+ // until Aleksander rewrites memory management!!
+ if (Address >= 0xFFFFFFF0) Address -= 0xFFF00000;
+
/* If the A20 line is disabled, mask bit 20 */
if (!A20Line) Address &= ~(1 << 20);
if ((Address + Size) >= ROM_AREA_START && (Address < ROM_AREA_END)) return;
/* Read the data from the buffer and store it in the virtual address space */
- RtlCopyMemory((LPVOID)((ULONG_PTR)BaseAddress + Address), Buffer, Size);
+ RtlCopyMemory(REAL_TO_PHYS(Address), Buffer, Size);
/*
* Check if we modified the VGA memory.
DWORD VgaAddress = max(Address, VgaGetVideoBaseAddress());
DWORD ActualSize = min(Address + Size - 1, VgaGetVideoLimitAddress())
- VgaAddress + 1;
- LPBYTE SrcBuffer = (LPBYTE)((ULONG_PTR)BaseAddress + VgaAddress);
+ LPBYTE SrcBuffer = (LPBYTE)REAL_TO_PHYS(VgaAddress);
/* Write to the VGA memory */
VgaWriteMemory(VgaAddress, SrcBuffer, ActualSize);
VOID EmulatorSimulate(VOID)
{
- UNIMPLEMENTED;
+ if (CpuCallLevel > MaxCpuCallLevel)
+ {
+ DisplayMessage(L"Too many CPU levels of recursion (%d, expected maximum %d)",
+ CpuCallLevel, MaxCpuCallLevel);
+
+ /* Stop the VDM */
+ VdmRunning = FALSE;
+ 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)
{
- UNIMPLEMENTED;
+ /* Stop simulation */
+ CpuSimulate = FALSE;
}
VOID EmulatorInterrupt(BYTE Number)
EmulatorIntAcknowledge,
NULL /* TODO: Use a TLB */);
- /* Enable interrupts */
- setIF(1);
-
/* Initialize DMA */
/* Initialize the PIC, the PIT, the CMOS and the PC Speaker */
PS2Initialize(ConsoleInput);
/* Set the console input mode */
- // SetConsoleMode(ConsoleInput, ENABLE_MOUSE_INPUT | ENABLE_PROCESSED_INPUT);
+ // FIXME: Activate ENABLE_WINDOW_INPUT when we will want to perform actions
+ // upon console window events (screen buffer resize, ...).
+ SetConsoleMode(ConsoleInput, ENABLE_PROCESSED_INPUT /* | ENABLE_WINDOW_INPUT */);
/* Start the input thread */
InputThread = CreateThread(NULL, 0, &PumpConsoleInput, ConsoleInput, 0, NULL);
// if (!VgaInitialize(ConsoleOutput)) return FALSE;
VgaInitialize(ConsoleOutput);
- /* Register the emulator BOPs */
+ /* Initialize the software callback system and register the emulator BOPs */
+ InitializeCallbacks();
RegisterBop(BOP_DEBUGGER , EmulatorDebugBreakBop);
RegisterBop(BOP_UNSIMULATE, EmulatorUnsimulateBop);
VOID EmulatorCleanup(VOID)
{
- // VgaCleanup();
+ VgaCleanup();
/* Close the input thread handle */
if (InputThread != NULL) CloseHandle(InputThread);