2013-06-17 00:00:36 +00:00
|
|
|
/*
|
|
|
|
* 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 *******************************************************************/
|
|
|
|
|
2013-07-22 13:51:26 +00:00
|
|
|
#define NDEBUG
|
|
|
|
|
2013-06-26 22:58:41 +00:00
|
|
|
#include "emulator.h"
|
|
|
|
#include "bios.h"
|
2013-11-01 02:28:47 +00:00
|
|
|
#include "bop.h"
|
2013-06-26 22:58:41 +00:00
|
|
|
#include "dos.h"
|
2013-11-03 20:31:19 +00:00
|
|
|
#include "speaker.h"
|
2013-08-05 23:20:25 +00:00
|
|
|
#include "vga.h"
|
2013-06-26 22:58:41 +00:00
|
|
|
#include "pic.h"
|
|
|
|
#include "ps2.h"
|
|
|
|
#include "timer.h"
|
2013-11-03 21:33:22 +00:00
|
|
|
#include "cmos.h"
|
2013-06-17 00:00:36 +00:00
|
|
|
|
2013-06-26 22:58:41 +00:00
|
|
|
/* PRIVATE VARIABLES **********************************************************/
|
|
|
|
|
2013-10-19 16:55:51 +00:00
|
|
|
FAST486_STATE EmulatorContext;
|
2013-07-07 20:53:23 +00:00
|
|
|
|
2013-06-26 17:15:45 +00:00
|
|
|
static BOOLEAN A20Line = FALSE;
|
2013-06-17 00:00:36 +00:00
|
|
|
|
2013-06-26 22:58:41 +00:00
|
|
|
/* PRIVATE FUNCTIONS **********************************************************/
|
|
|
|
|
2013-10-27 12:17:06 +00:00
|
|
|
static VOID WINAPI EmulatorReadMemory(PFAST486_STATE State, ULONG Address, PVOID Buffer, ULONG Size)
|
2013-06-17 00:00:36 +00:00
|
|
|
{
|
2013-10-27 12:17:06 +00:00
|
|
|
UNREFERENCED_PARAMETER(State);
|
2013-08-07 19:56:28 +00:00
|
|
|
|
2013-06-26 17:15:45 +00:00
|
|
|
/* If the A20 line is disabled, mask bit 20 */
|
|
|
|
if (!A20Line) Address &= ~(1 << 20);
|
|
|
|
|
2013-06-17 00:00:36 +00:00
|
|
|
/* Make sure the requested address is valid */
|
|
|
|
if ((Address + Size) >= MAX_ADDRESS) return;
|
|
|
|
|
|
|
|
/* Read the data from the virtual address space and store it in the buffer */
|
|
|
|
RtlCopyMemory(Buffer, (LPVOID)((ULONG_PTR)BaseAddress + Address), Size);
|
2013-08-05 23:20:25 +00:00
|
|
|
|
|
|
|
/* Check if we modified the console video memory */
|
|
|
|
if (((Address + Size) >= VgaGetVideoBaseAddress())
|
|
|
|
&& (Address < VgaGetVideoLimitAddress()))
|
|
|
|
{
|
|
|
|
DWORD VgaAddress = max(Address, VgaGetVideoBaseAddress());
|
2013-10-27 12:17:06 +00:00
|
|
|
LPBYTE VgaBuffer = (LPBYTE)((ULONG_PTR)Buffer + VgaAddress - Address);
|
2013-08-05 23:20:25 +00:00
|
|
|
|
|
|
|
/* Read from the VGA memory */
|
|
|
|
VgaReadMemory(VgaAddress, VgaBuffer, Size);
|
|
|
|
}
|
2013-06-17 00:00:36 +00:00
|
|
|
}
|
|
|
|
|
2013-10-27 12:17:06 +00:00
|
|
|
static VOID WINAPI EmulatorWriteMemory(PFAST486_STATE State, ULONG Address, PVOID Buffer, ULONG Size)
|
2013-06-17 00:00:36 +00:00
|
|
|
{
|
2013-10-27 12:17:06 +00:00
|
|
|
UNREFERENCED_PARAMETER(State);
|
2013-08-07 19:56:28 +00:00
|
|
|
|
2013-06-26 17:15:45 +00:00
|
|
|
/* If the A20 line is disabled, mask bit 20 */
|
|
|
|
if (!A20Line) Address &= ~(1 << 20);
|
|
|
|
|
2013-06-17 00:00:36 +00:00
|
|
|
/* Make sure the requested address is valid */
|
|
|
|
if ((Address + Size) >= MAX_ADDRESS) return;
|
|
|
|
|
|
|
|
/* Make sure we don't write to the ROM area */
|
|
|
|
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);
|
|
|
|
|
|
|
|
/* Check if we modified the console video memory */
|
2013-08-05 23:20:25 +00:00
|
|
|
if (((Address + Size) >= VgaGetVideoBaseAddress())
|
|
|
|
&& (Address < VgaGetVideoLimitAddress()))
|
2013-06-17 00:00:36 +00:00
|
|
|
{
|
2013-08-05 23:20:25 +00:00
|
|
|
DWORD VgaAddress = max(Address, VgaGetVideoBaseAddress());
|
2013-10-27 12:17:06 +00:00
|
|
|
LPBYTE VgaBuffer = (LPBYTE)((ULONG_PTR)Buffer + VgaAddress - Address);
|
2013-08-05 23:20:25 +00:00
|
|
|
|
|
|
|
/* Write to the VGA memory */
|
|
|
|
VgaWriteMemory(VgaAddress, VgaBuffer, Size);
|
2013-06-17 00:00:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-09 15:00:19 +00:00
|
|
|
static VOID WINAPI EmulatorReadIo(PFAST486_STATE State, ULONG Port, PVOID Buffer, ULONG DataCount, UCHAR DataSize)
|
2013-06-17 00:00:36 +00:00
|
|
|
{
|
2013-11-09 03:30:27 +00:00
|
|
|
INT i, j;
|
2013-10-27 12:17:06 +00:00
|
|
|
LPBYTE Address = (LPBYTE)Buffer;
|
|
|
|
|
|
|
|
UNREFERENCED_PARAMETER(State);
|
2013-08-07 19:56:28 +00:00
|
|
|
|
2013-11-09 15:00:19 +00:00
|
|
|
for (i = 0; i < DataCount; i++) for (j = 0; j < DataSize; j++)
|
2013-06-21 00:47:07 +00:00
|
|
|
{
|
2013-11-09 03:30:27 +00:00
|
|
|
ULONG CurrentPort = Port + j;
|
|
|
|
|
|
|
|
switch (CurrentPort)
|
2013-06-21 00:47:07 +00:00
|
|
|
{
|
2013-11-03 14:37:30 +00:00
|
|
|
case PIC_MASTER_CMD:
|
|
|
|
case PIC_SLAVE_CMD:
|
|
|
|
{
|
2013-11-09 03:30:27 +00:00
|
|
|
*(Address++) = PicReadCommand(CurrentPort);
|
2013-11-03 14:37:30 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case PIC_MASTER_DATA:
|
|
|
|
case PIC_SLAVE_DATA:
|
|
|
|
{
|
2013-11-09 03:30:27 +00:00
|
|
|
*(Address++) = PicReadData(CurrentPort);
|
2013-11-03 14:37:30 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case PIT_DATA_PORT(0):
|
|
|
|
case PIT_DATA_PORT(1):
|
|
|
|
case PIT_DATA_PORT(2):
|
|
|
|
{
|
2013-11-09 03:30:27 +00:00
|
|
|
*(Address++) = PitReadData(CurrentPort - PIT_DATA_PORT(0));
|
2013-11-03 14:37:30 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case PS2_CONTROL_PORT:
|
|
|
|
{
|
|
|
|
*(Address++) = KeyboardReadStatus();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case PS2_DATA_PORT:
|
|
|
|
{
|
|
|
|
*(Address++) = KeyboardReadData();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2013-11-03 21:33:22 +00:00
|
|
|
case CMOS_DATA_PORT:
|
|
|
|
{
|
|
|
|
*(Address++) = CmosReadData();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2013-11-03 20:31:19 +00:00
|
|
|
case SPEAKER_CONTROL_PORT:
|
|
|
|
{
|
|
|
|
*(Address++) = SpeakerReadStatus();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2013-11-03 14:37:30 +00:00
|
|
|
case VGA_AC_WRITE:
|
|
|
|
case VGA_AC_READ:
|
|
|
|
case VGA_SEQ_INDEX:
|
|
|
|
case VGA_SEQ_DATA:
|
|
|
|
case VGA_DAC_READ_INDEX:
|
|
|
|
case VGA_DAC_WRITE_INDEX:
|
|
|
|
case VGA_DAC_DATA:
|
|
|
|
case VGA_MISC_READ:
|
|
|
|
case VGA_MISC_WRITE:
|
|
|
|
case VGA_CRTC_INDEX:
|
|
|
|
case VGA_CRTC_DATA:
|
|
|
|
case VGA_GC_INDEX:
|
|
|
|
case VGA_GC_DATA:
|
|
|
|
case VGA_STAT_MONO:
|
|
|
|
case VGA_STAT_COLOR:
|
|
|
|
{
|
2013-11-09 03:30:27 +00:00
|
|
|
*(Address++) = VgaReadPort(CurrentPort);
|
2013-11-03 14:37:30 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
|
|
|
{
|
2013-11-09 03:30:27 +00:00
|
|
|
DPRINT1("Read from unknown port: 0x%X\n", CurrentPort);
|
2013-11-03 14:37:30 +00:00
|
|
|
}
|
2013-07-23 21:43:57 +00:00
|
|
|
}
|
2013-06-21 00:47:07 +00:00
|
|
|
}
|
2013-06-17 00:00:36 +00:00
|
|
|
}
|
|
|
|
|
2013-11-09 15:00:19 +00:00
|
|
|
static VOID WINAPI EmulatorWriteIo(PFAST486_STATE State, ULONG Port, PVOID Buffer, ULONG DataCount, UCHAR DataSize)
|
2013-06-17 00:00:36 +00:00
|
|
|
{
|
2013-11-09 03:30:27 +00:00
|
|
|
INT i, j;
|
2013-11-03 14:37:30 +00:00
|
|
|
LPBYTE Address = (LPBYTE)Buffer;
|
2013-06-23 00:11:45 +00:00
|
|
|
|
2013-10-27 12:17:06 +00:00
|
|
|
UNREFERENCED_PARAMETER(State);
|
2013-08-07 19:56:28 +00:00
|
|
|
|
2013-11-09 15:00:19 +00:00
|
|
|
for (i = 0; i < DataCount; i++) for (j = 0; j < DataSize; j++)
|
2013-06-21 00:47:07 +00:00
|
|
|
{
|
2013-11-09 03:30:27 +00:00
|
|
|
ULONG CurrentPort = Port + j;
|
|
|
|
|
|
|
|
switch (CurrentPort)
|
2013-07-23 21:43:57 +00:00
|
|
|
{
|
2013-11-03 14:37:30 +00:00
|
|
|
case PIT_COMMAND_PORT:
|
|
|
|
{
|
|
|
|
PitWriteCommand(*(Address++));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case PIT_DATA_PORT(0):
|
|
|
|
case PIT_DATA_PORT(1):
|
|
|
|
case PIT_DATA_PORT(2):
|
|
|
|
{
|
2013-11-09 03:30:27 +00:00
|
|
|
PitWriteData(CurrentPort - PIT_DATA_PORT(0), *(Address++));
|
2013-11-03 14:37:30 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case PIC_MASTER_CMD:
|
|
|
|
case PIC_SLAVE_CMD:
|
|
|
|
{
|
2013-11-09 03:30:27 +00:00
|
|
|
PicWriteCommand(CurrentPort, *(Address++));
|
2013-11-03 14:37:30 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case PIC_MASTER_DATA:
|
|
|
|
case PIC_SLAVE_DATA:
|
|
|
|
{
|
2013-11-09 03:30:27 +00:00
|
|
|
PicWriteData(CurrentPort, *(Address++));
|
2013-11-03 14:37:30 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case PS2_CONTROL_PORT:
|
|
|
|
{
|
|
|
|
KeyboardWriteCommand(*(Address++));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case PS2_DATA_PORT:
|
|
|
|
{
|
|
|
|
KeyboardWriteData(*(Address++));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2013-11-03 21:33:22 +00:00
|
|
|
case CMOS_ADDRESS_PORT:
|
|
|
|
{
|
|
|
|
CmosWriteAddress(*(Address++));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case CMOS_DATA_PORT:
|
|
|
|
{
|
|
|
|
CmosWriteData(*(Address++));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2013-11-03 20:31:19 +00:00
|
|
|
case SPEAKER_CONTROL_PORT:
|
|
|
|
{
|
|
|
|
SpeakerWriteCommand(*(Address++));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2013-11-03 14:37:30 +00:00
|
|
|
case VGA_AC_WRITE:
|
|
|
|
case VGA_AC_READ:
|
|
|
|
case VGA_SEQ_INDEX:
|
|
|
|
case VGA_SEQ_DATA:
|
|
|
|
case VGA_DAC_READ_INDEX:
|
|
|
|
case VGA_DAC_WRITE_INDEX:
|
|
|
|
case VGA_DAC_DATA:
|
|
|
|
case VGA_MISC_READ:
|
|
|
|
case VGA_MISC_WRITE:
|
|
|
|
case VGA_CRTC_INDEX:
|
|
|
|
case VGA_CRTC_DATA:
|
|
|
|
case VGA_GC_INDEX:
|
|
|
|
case VGA_GC_DATA:
|
|
|
|
case VGA_STAT_MONO:
|
|
|
|
case VGA_STAT_COLOR:
|
|
|
|
{
|
2013-11-09 03:30:27 +00:00
|
|
|
VgaWritePort(CurrentPort, *(Address++));
|
2013-11-03 14:37:30 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
|
|
|
{
|
2013-11-09 03:30:27 +00:00
|
|
|
DPRINT1("Write to unknown port: 0x%X\n", CurrentPort);
|
2013-11-03 14:37:30 +00:00
|
|
|
}
|
2013-07-23 21:43:57 +00:00
|
|
|
}
|
2013-06-21 00:47:07 +00:00
|
|
|
}
|
2013-06-17 00:00:36 +00:00
|
|
|
}
|
|
|
|
|
2013-11-01 00:01:07 +00:00
|
|
|
static VOID WINAPI EmulatorBiosOperation(PFAST486_STATE State, UCHAR BopCode)
|
2013-06-17 00:00:36 +00:00
|
|
|
{
|
2013-11-01 00:01:07 +00:00
|
|
|
WORD StackSegment, StackPointer;
|
2013-07-23 19:31:00 +00:00
|
|
|
LPWORD Stack;
|
2013-06-17 00:00:36 +00:00
|
|
|
|
2013-07-23 19:31:00 +00:00
|
|
|
/* Get the SS:SP */
|
2013-10-26 20:48:31 +00:00
|
|
|
StackSegment = State->SegmentRegs[FAST486_REG_SS].Selector;
|
|
|
|
StackPointer = State->GeneralRegs[FAST486_REG_ESP].LowWord;
|
2013-06-17 00:00:36 +00:00
|
|
|
|
2013-07-23 19:31:00 +00:00
|
|
|
/* Get the stack */
|
2013-10-27 22:13:18 +00:00
|
|
|
Stack = (LPWORD)SEG_OFF_TO_PTR(StackSegment, StackPointer);
|
2013-06-17 00:00:36 +00:00
|
|
|
|
2013-11-01 02:28:47 +00:00
|
|
|
if (BopProc[BopCode] != NULL)
|
|
|
|
BopProc[BopCode](Stack);
|
|
|
|
else
|
|
|
|
DPRINT1("Invalid BOP code %u\n", BopCode);
|
2013-06-17 00:00:36 +00:00
|
|
|
}
|
|
|
|
|
2013-10-27 12:17:06 +00:00
|
|
|
static UCHAR WINAPI EmulatorIntAcknowledge(PFAST486_STATE State)
|
2013-10-27 00:37:01 +00:00
|
|
|
{
|
|
|
|
UNREFERENCED_PARAMETER(State);
|
|
|
|
|
|
|
|
/* Get the interrupt number from the PIC */
|
|
|
|
return PicGetInterrupt();
|
|
|
|
}
|
|
|
|
|
2013-06-17 00:00:36 +00:00
|
|
|
/* PUBLIC FUNCTIONS ***********************************************************/
|
|
|
|
|
2013-11-01 01:46:58 +00:00
|
|
|
BOOLEAN EmulatorInitialize(VOID)
|
2013-06-17 00:00:36 +00:00
|
|
|
{
|
|
|
|
/* Allocate memory for the 16-bit address space */
|
2013-07-02 02:08:30 +00:00
|
|
|
BaseAddress = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MAX_ADDRESS);
|
2013-06-17 00:00:36 +00:00
|
|
|
if (BaseAddress == NULL) return FALSE;
|
|
|
|
|
2013-11-01 01:46:58 +00:00
|
|
|
/* Initialize the CPU */
|
|
|
|
Fast486Initialize(&EmulatorContext,
|
|
|
|
EmulatorReadMemory,
|
|
|
|
EmulatorWriteMemory,
|
|
|
|
EmulatorReadIo,
|
|
|
|
EmulatorWriteIo,
|
|
|
|
NULL,
|
|
|
|
EmulatorBiosOperation,
|
|
|
|
EmulatorIntAcknowledge);
|
2013-06-17 00:00:36 +00:00
|
|
|
|
2013-06-26 17:15:45 +00:00
|
|
|
/* Enable interrupts */
|
|
|
|
EmulatorSetFlag(EMULATOR_FLAG_IF);
|
|
|
|
|
2013-06-17 00:00:36 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2013-11-01 01:46:58 +00:00
|
|
|
VOID EmulatorCleanup(VOID)
|
|
|
|
{
|
|
|
|
/* Free the memory allocated for the 16-bit address space */
|
|
|
|
if (BaseAddress != NULL) HeapFree(GetProcessHeap(), 0, BaseAddress);
|
|
|
|
}
|
|
|
|
|
2013-08-09 23:52:08 +00:00
|
|
|
VOID EmulatorSetStack(WORD Segment, DWORD Offset)
|
2013-06-17 00:00:36 +00:00
|
|
|
{
|
2013-10-19 16:55:51 +00:00
|
|
|
Fast486SetStack(&EmulatorContext, Segment, Offset);
|
2013-06-17 00:00:36 +00:00
|
|
|
}
|
|
|
|
|
2013-08-31 19:18:12 +00:00
|
|
|
// FIXME: This function assumes 16-bit mode!!!
|
2013-06-17 00:00:36 +00:00
|
|
|
VOID EmulatorExecute(WORD Segment, WORD Offset)
|
|
|
|
{
|
2013-10-19 16:55:51 +00:00
|
|
|
/* Tell Fast486 to move the instruction pointer */
|
|
|
|
Fast486ExecuteAt(&EmulatorContext, Segment, Offset);
|
2013-06-17 00:00:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VOID EmulatorInterrupt(BYTE Number)
|
|
|
|
{
|
2013-10-19 16:55:51 +00:00
|
|
|
/* Call the Fast486 API */
|
|
|
|
Fast486Interrupt(&EmulatorContext, Number);
|
2013-06-17 00:00:36 +00:00
|
|
|
}
|
|
|
|
|
2013-10-27 00:37:01 +00:00
|
|
|
VOID EmulatorInterruptSignal(VOID)
|
2013-06-26 17:15:45 +00:00
|
|
|
{
|
2013-10-19 16:55:51 +00:00
|
|
|
/* Call the Fast486 API */
|
2013-10-27 00:37:01 +00:00
|
|
|
Fast486InterruptSignal(&EmulatorContext);
|
2013-06-26 17:15:45 +00:00
|
|
|
}
|
|
|
|
|
2013-06-17 00:00:36 +00:00
|
|
|
ULONG EmulatorGetRegister(ULONG Register)
|
|
|
|
{
|
2013-08-16 19:33:04 +00:00
|
|
|
if (Register < EMULATOR_REG_ES)
|
|
|
|
{
|
|
|
|
return EmulatorContext.GeneralRegs[Register].Long;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return EmulatorContext.SegmentRegs[Register - EMULATOR_REG_ES].Selector;
|
|
|
|
}
|
2013-06-17 00:00:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VOID EmulatorSetRegister(ULONG Register, ULONG Value)
|
|
|
|
{
|
2013-10-09 21:48:52 +00:00
|
|
|
if (Register < EMULATOR_REG_ES)
|
|
|
|
{
|
|
|
|
EmulatorContext.GeneralRegs[Register].Long = Value;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-10-19 16:55:51 +00:00
|
|
|
Fast486SetSegment(&EmulatorContext, Register - EMULATOR_REG_ES, (USHORT)Value);
|
2013-10-09 21:48:52 +00:00
|
|
|
}
|
2013-06-17 00:00:36 +00:00
|
|
|
}
|
|
|
|
|
2013-10-27 22:13:18 +00:00
|
|
|
ULONG EmulatorGetProgramCounter(VOID)
|
|
|
|
{
|
|
|
|
return EmulatorContext.InstPtr.Long;
|
|
|
|
}
|
|
|
|
|
2013-06-17 00:00:36 +00:00
|
|
|
BOOLEAN EmulatorGetFlag(ULONG Flag)
|
|
|
|
{
|
2013-07-07 20:53:23 +00:00
|
|
|
return (EmulatorContext.Flags.Long & Flag) ? TRUE : FALSE;
|
2013-06-17 00:00:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VOID EmulatorSetFlag(ULONG Flag)
|
|
|
|
{
|
2013-07-07 20:53:23 +00:00
|
|
|
EmulatorContext.Flags.Long |= Flag;
|
2013-06-17 00:00:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VOID EmulatorClearFlag(ULONG Flag)
|
|
|
|
{
|
2013-07-07 20:53:23 +00:00
|
|
|
EmulatorContext.Flags.Long &= ~Flag;
|
2013-06-17 00:00:36 +00:00
|
|
|
}
|
|
|
|
|
2013-07-23 19:31:00 +00:00
|
|
|
VOID EmulatorStep(VOID)
|
2013-06-17 00:00:36 +00:00
|
|
|
{
|
2013-08-31 19:18:12 +00:00
|
|
|
/* Dump the state for debugging purposes */
|
2013-10-19 16:55:51 +00:00
|
|
|
// Fast486DumpState(&EmulatorContext);
|
2013-08-31 19:18:12 +00:00
|
|
|
|
|
|
|
/* Execute the next instruction */
|
2013-10-19 16:55:51 +00:00
|
|
|
Fast486StepInto(&EmulatorContext);
|
2013-06-17 00:00:36 +00:00
|
|
|
}
|
|
|
|
|
2013-06-26 17:15:45 +00:00
|
|
|
VOID EmulatorSetA20(BOOLEAN Enabled)
|
|
|
|
{
|
|
|
|
A20Line = Enabled;
|
|
|
|
}
|
|
|
|
|
2013-06-17 00:00:36 +00:00
|
|
|
/* EOF */
|