mirror of
https://github.com/reactos/reactos.git
synced 2024-12-29 10:35:28 +00:00
[NTVDM]
Finish my Interruption revamp. - Move interrupt-related code from bop.c to int32.c - Introduce InitializeInt32 helper so that one can initialize all the needed 16-bit stubs for the 32-bit interrupts. - Remove unneeded defines in emulator.h and an exported variable in ntvdm.h. svn path=/branches/ntvdm/; revision=60908
This commit is contained in:
parent
6da6a5ce56
commit
dd9dafc7ff
9 changed files with 227 additions and 432 deletions
|
@ -6,15 +6,16 @@ spec2def(ntvdm.exe ntvdm.spec)
|
||||||
list(APPEND SOURCE
|
list(APPEND SOURCE
|
||||||
bios.c
|
bios.c
|
||||||
bop.c
|
bop.c
|
||||||
|
cmos.c
|
||||||
dos.c
|
dos.c
|
||||||
emulator.c
|
emulator.c
|
||||||
|
int32.c
|
||||||
pic.c
|
pic.c
|
||||||
registers.c
|
|
||||||
timer.c
|
|
||||||
ps2.c
|
ps2.c
|
||||||
|
registers.c
|
||||||
speaker.c
|
speaker.c
|
||||||
|
timer.c
|
||||||
vga.c
|
vga.c
|
||||||
cmos.c
|
|
||||||
ntvdm.c
|
ntvdm.c
|
||||||
ntvdm.rc
|
ntvdm.rc
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/ntvdm.def)
|
${CMAKE_CURRENT_BINARY_DIR}/ntvdm.def)
|
||||||
|
|
|
@ -11,14 +11,14 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
|
|
||||||
#include "emulator.h"
|
#include "emulator.h"
|
||||||
#include "bop.h"
|
|
||||||
|
|
||||||
#include "bios.h"
|
#include "bios.h"
|
||||||
|
|
||||||
#include "vga.h"
|
#include "vga.h"
|
||||||
#include "pic.h"
|
#include "pic.h"
|
||||||
#include "ps2.h"
|
#include "ps2.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
|
|
||||||
|
#include "int32.h"
|
||||||
#include "registers.h"
|
#include "registers.h"
|
||||||
|
|
||||||
/* PRIVATE VARIABLES **********************************************************/
|
/* PRIVATE VARIABLES **********************************************************/
|
||||||
|
@ -461,11 +461,6 @@ BOOLEAN BiosSetVideoPage(BYTE PageNumber)
|
||||||
|
|
||||||
BOOLEAN BiosInitialize(VOID)
|
BOOLEAN BiosInitialize(VOID)
|
||||||
{
|
{
|
||||||
USHORT i;
|
|
||||||
WORD Offset = 0;
|
|
||||||
LPDWORD IntVecTable = (LPDWORD)BaseAddress;
|
|
||||||
LPBYTE BiosCode = (LPBYTE)SEG_OFF_TO_PTR(BIOS_SEGMENT, 0);
|
|
||||||
|
|
||||||
/* Initialize the BDA */
|
/* Initialize the BDA */
|
||||||
Bda = (PBIOS_DATA_AREA)SEG_OFF_TO_PTR(BDA_SEGMENT, 0);
|
Bda = (PBIOS_DATA_AREA)SEG_OFF_TO_PTR(BDA_SEGMENT, 0);
|
||||||
Bda->EquipmentList = BIOS_EQUIPMENT_LIST;
|
Bda->EquipmentList = BIOS_EQUIPMENT_LIST;
|
||||||
|
@ -479,43 +474,10 @@ BOOLEAN BiosInitialize(VOID)
|
||||||
Bda->KeybdBufferStart = FIELD_OFFSET(BIOS_DATA_AREA, KeybdBuffer);
|
Bda->KeybdBufferStart = FIELD_OFFSET(BIOS_DATA_AREA, KeybdBuffer);
|
||||||
Bda->KeybdBufferEnd = Bda->KeybdBufferStart + BIOS_KBD_BUFFER_SIZE * sizeof(WORD);
|
Bda->KeybdBufferEnd = Bda->KeybdBufferStart + BIOS_KBD_BUFFER_SIZE * sizeof(WORD);
|
||||||
|
|
||||||
/* Generate ISR stubs and fill the IVT */
|
/* Initialize the 32-bit Interrupt system */
|
||||||
for (i = 0x00; i <= 0xFF; i++)
|
InitializeInt32(BIOS_SEGMENT);
|
||||||
{
|
|
||||||
IntVecTable[i] = MAKELONG(Offset, BIOS_SEGMENT);
|
|
||||||
|
|
||||||
BiosCode[Offset++] = 0xFB; // sti
|
/* Register the BIOS 32-bit Interrupts */
|
||||||
|
|
||||||
BiosCode[Offset++] = 0x6A; // push i
|
|
||||||
BiosCode[Offset++] = (UCHAR)i;
|
|
||||||
|
|
||||||
BiosCode[Offset++] = 0x6A; // push 0
|
|
||||||
BiosCode[Offset++] = 0x00;
|
|
||||||
|
|
||||||
// BOP_SEQ:
|
|
||||||
BiosCode[Offset++] = 0xF8; // clc
|
|
||||||
|
|
||||||
BiosCode[Offset++] = LOBYTE(EMULATOR_BOP); // BOP sequence
|
|
||||||
BiosCode[Offset++] = HIBYTE(EMULATOR_BOP);
|
|
||||||
BiosCode[Offset++] = EMULATOR_CTRL_BOP; // Control BOP
|
|
||||||
BiosCode[Offset++] = CTRL_BOP_INT32; // 32-bit Interrupt dispatcher
|
|
||||||
|
|
||||||
BiosCode[Offset++] = 0x73; // jnc EXIT (offset +3)
|
|
||||||
BiosCode[Offset++] = 0x03;
|
|
||||||
|
|
||||||
// HACK: The following instruction should be HLT!
|
|
||||||
BiosCode[Offset++] = 0x90; // nop
|
|
||||||
|
|
||||||
BiosCode[Offset++] = 0xEB; // jmp BOP_SEQ (offset -10)
|
|
||||||
BiosCode[Offset++] = 0xF6;
|
|
||||||
|
|
||||||
// EXIT:
|
|
||||||
BiosCode[Offset++] = 0x83; // add sp, 4
|
|
||||||
BiosCode[Offset++] = 0xC4;
|
|
||||||
BiosCode[Offset++] = 0x04;
|
|
||||||
|
|
||||||
BiosCode[Offset++] = 0xCF; // iret
|
|
||||||
}
|
|
||||||
RegisterInt32(BIOS_VIDEO_INTERRUPT , BiosVideoService );
|
RegisterInt32(BIOS_VIDEO_INTERRUPT , BiosVideoService );
|
||||||
RegisterInt32(BIOS_EQUIPMENT_INTERRUPT, BiosEquipmentService );
|
RegisterInt32(BIOS_EQUIPMENT_INTERRUPT, BiosEquipmentService );
|
||||||
RegisterInt32(BIOS_MEMORY_SIZE , BiosGetMemorySize );
|
RegisterInt32(BIOS_MEMORY_SIZE , BiosGetMemorySize );
|
||||||
|
|
|
@ -14,21 +14,10 @@
|
||||||
#include "emulator.h"
|
#include "emulator.h"
|
||||||
#include "bop.h"
|
#include "bop.h"
|
||||||
|
|
||||||
#include "bios.h"
|
#include "int32.h"
|
||||||
#include "dos.h"
|
|
||||||
#include "registers.h"
|
#include "registers.h"
|
||||||
|
|
||||||
LPCWSTR ExceptionName[] =
|
/* PRIVATE VARIABLES **********************************************************/
|
||||||
{
|
|
||||||
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"
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is the list of registered BOP handlers.
|
* This is the list of registered BOP handlers.
|
||||||
|
@ -293,356 +282,7 @@ EMULATOR_BOP_PROC BopProc[EMULATOR_MAX_BOP_NUM] =
|
||||||
ControlBop
|
ControlBop
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||||
* This is the list of registered 32-bit Interrupt handlers.
|
|
||||||
*/
|
|
||||||
EMULATOR_INT32_PROC Int32Proc[EMULATOR_MAX_INT_NUM] =
|
|
||||||
{
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
VOID WINAPI Exception(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 */
|
|
||||||
VdmRunning = FALSE;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// VOID WINAPI IrqDispatch(BYTE IrqNumber, LPWORD Stack)
|
|
||||||
// {
|
|
||||||
// /* Check if this was an PIC IRQ */
|
|
||||||
// if (IntNum >= BIOS_PIC_MASTER_INT && IntNum < BIOS_PIC_MASTER_INT + 8)
|
|
||||||
// {
|
|
||||||
// /* It was an IRQ from the master PIC */
|
|
||||||
// BiosHandleIrq(IntNum - BIOS_PIC_MASTER_INT, Stack);
|
|
||||||
// }
|
|
||||||
// else if (IntNum >= BIOS_PIC_SLAVE_INT && IntNum < BIOS_PIC_SLAVE_INT + 8)
|
|
||||||
// {
|
|
||||||
// /* It was an IRQ from the slave PIC */
|
|
||||||
// BiosHandleIrq(IntNum - BIOS_PIC_SLAVE_INT + 8, Stack);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
VOID WINAPI Int32Dispatch(LPWORD Stack)
|
|
||||||
{
|
|
||||||
BYTE IntNum;
|
|
||||||
|
|
||||||
/* Get the interrupt number */
|
|
||||||
IntNum = LOBYTE(Stack[STACK_INT_NUM]);
|
|
||||||
|
|
||||||
/* Check if this was an exception */
|
|
||||||
if (IntNum < 8)
|
|
||||||
{
|
|
||||||
Exception(IntNum, Stack);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if this was an PIC IRQ */
|
|
||||||
if (IntNum >= BIOS_PIC_MASTER_INT && IntNum < BIOS_PIC_MASTER_INT + 8)
|
|
||||||
{
|
|
||||||
/* It was an IRQ from the master PIC */
|
|
||||||
BiosHandleIrq(IntNum - BIOS_PIC_MASTER_INT, Stack);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (IntNum >= BIOS_PIC_SLAVE_INT && IntNum < BIOS_PIC_SLAVE_INT + 8)
|
|
||||||
{
|
|
||||||
/* It was an IRQ from the slave PIC */
|
|
||||||
BiosHandleIrq(IntNum - BIOS_PIC_SLAVE_INT + 8, Stack);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Call the 32-bit Interrupt handler */
|
|
||||||
if (Int32Proc[IntNum] != NULL)
|
|
||||||
Int32Proc[IntNum](Stack);
|
|
||||||
else
|
|
||||||
DPRINT1("Unhandled 32-bit interrupt: 0x%02X\n", IntNum);
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID WINAPI ControlBop(LPWORD Stack)
|
VOID WINAPI ControlBop(LPWORD Stack)
|
||||||
{
|
{
|
||||||
|
@ -656,12 +296,6 @@ VOID WINAPI ControlBop(LPWORD Stack)
|
||||||
DPRINT1("Unassigned Control BOP Function: 0x%02X\n", FuncNum);
|
DPRINT1("Unassigned Control BOP Function: 0x%02X\n", FuncNum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VOID WINAPI RegisterInt32(BYTE IntNumber, EMULATOR_INT32_PROC IntHandler)
|
|
||||||
{
|
|
||||||
Int32Proc[IntNumber] = IntHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID WINAPI EmulatorBiosOperation(PFAST486_STATE State, UCHAR BopCode)
|
VOID WINAPI EmulatorBiosOperation(PFAST486_STATE State, UCHAR BopCode)
|
||||||
{
|
{
|
||||||
WORD StackSegment, StackPointer;
|
WORD StackSegment, StackPointer;
|
||||||
|
|
|
@ -17,21 +17,14 @@
|
||||||
|
|
||||||
#define EMULATOR_CTRL_BOP 0xFF // Control BOP Handler
|
#define EMULATOR_CTRL_BOP 0xFF // Control BOP Handler
|
||||||
#define CTRL_BOP_DEFLT 0x00 // Default Control BOP Function
|
#define CTRL_BOP_DEFLT 0x00 // Default Control BOP Function
|
||||||
#define CTRL_BOP_INT32 0xFF // 32-bit Interrupt dispatcher
|
|
||||||
|
|
||||||
#define EMULATOR_MAX_BOP_NUM 0xFF + 1
|
#define EMULATOR_MAX_BOP_NUM 0xFF + 1
|
||||||
|
|
||||||
/* 32-bit Interrupt Identifiers */
|
|
||||||
#define EMULATOR_MAX_INT_NUM 0xFF + 1
|
|
||||||
|
|
||||||
/* FUNCTIONS ******************************************************************/
|
/* FUNCTIONS ******************************************************************/
|
||||||
|
|
||||||
typedef VOID (WINAPI *EMULATOR_BOP_PROC)(LPWORD Stack);
|
typedef VOID (WINAPI *EMULATOR_BOP_PROC)(LPWORD Stack);
|
||||||
typedef VOID (WINAPI *EMULATOR_INT32_PROC)(LPWORD Stack);
|
|
||||||
|
|
||||||
VOID WINAPI ControlBop(LPWORD Stack);
|
VOID WINAPI ControlBop(LPWORD Stack);
|
||||||
|
|
||||||
VOID WINAPI RegisterInt32(BYTE IntNumber, EMULATOR_INT32_PROC IntHandler);
|
|
||||||
VOID WINAPI EmulatorBiosOperation(PFAST486_STATE State, UCHAR BopCode);
|
VOID WINAPI EmulatorBiosOperation(PFAST486_STATE State, UCHAR BopCode);
|
||||||
|
|
||||||
#endif // _BOP_H_
|
#endif // _BOP_H_
|
||||||
|
|
|
@ -11,11 +11,10 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
|
|
||||||
#include "emulator.h"
|
#include "emulator.h"
|
||||||
#include "bop.h"
|
|
||||||
|
|
||||||
#include "dos.h"
|
#include "dos.h"
|
||||||
#include "bios.h"
|
|
||||||
|
|
||||||
|
#include "bios.h"
|
||||||
|
#include "int32.h"
|
||||||
#include "registers.h"
|
#include "registers.h"
|
||||||
|
|
||||||
/* PRIVATE VARIABLES **********************************************************/
|
/* PRIVATE VARIABLES **********************************************************/
|
||||||
|
@ -2570,7 +2569,7 @@ BOOLEAN DosInitialize(VOID)
|
||||||
DosSystemFileTable[1] = GetStdHandle(STD_OUTPUT_HANDLE);
|
DosSystemFileTable[1] = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
DosSystemFileTable[2] = GetStdHandle(STD_ERROR_HANDLE);
|
DosSystemFileTable[2] = GetStdHandle(STD_ERROR_HANDLE);
|
||||||
|
|
||||||
/* Register the DOS-32 Interrupts */
|
/* Register the DOS 32-bit Interrupts */
|
||||||
RegisterInt32(0x20, DosInt20h );
|
RegisterInt32(0x20, DosInt20h );
|
||||||
RegisterInt32(0x21, DosInt21h );
|
RegisterInt32(0x21, DosInt21h );
|
||||||
RegisterInt32(0x23, DosBreakInterrupt);
|
RegisterInt32(0x23, DosBreakInterrupt);
|
||||||
|
|
|
@ -34,11 +34,6 @@
|
||||||
#define EMULATOR_FLAG_VIP (1 << 20)
|
#define EMULATOR_FLAG_VIP (1 << 20)
|
||||||
#define EMULATOR_FLAG_ID (1 << 21)
|
#define EMULATOR_FLAG_ID (1 << 21)
|
||||||
|
|
||||||
/* Common definitions */
|
|
||||||
#define EMULATOR_BOP 0xC4C4
|
|
||||||
#define EMULATOR_INT_BOP 0xFF
|
|
||||||
#define EMULATOR_MAX_BOP_NUM 0xFF + 1
|
|
||||||
|
|
||||||
#define STACK_COUNTER 0
|
#define STACK_COUNTER 0
|
||||||
#define STACK_INT_NUM 1
|
#define STACK_INT_NUM 1
|
||||||
#define STACK_IP 2
|
#define STACK_IP 2
|
||||||
|
|
181
subsystems/ntvdm/int32.c
Normal file
181
subsystems/ntvdm/int32.c
Normal file
|
@ -0,0 +1,181 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: GPL - See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS Virtual DOS Machine
|
||||||
|
* FILE: int32.c
|
||||||
|
* PURPOSE: 32-bit Interrupt Handlers
|
||||||
|
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||||
|
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES *******************************************************************/
|
||||||
|
|
||||||
|
#define NDEBUG
|
||||||
|
|
||||||
|
#include "emulator.h"
|
||||||
|
#include "int32.h"
|
||||||
|
|
||||||
|
#include "bop.h"
|
||||||
|
#include "bios.h"
|
||||||
|
|
||||||
|
/* PRIVATE VARIABLES **********************************************************/
|
||||||
|
|
||||||
|
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"
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is the list of registered 32-bit Interrupt handlers.
|
||||||
|
*/
|
||||||
|
EMULATOR_INT32_PROC Int32Proc[EMULATOR_MAX_INT32_NUM] = { NULL };
|
||||||
|
|
||||||
|
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||||
|
|
||||||
|
VOID WINAPI Exception(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 */
|
||||||
|
VdmRunning = FALSE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
VOID WINAPI IrqDispatch(BYTE IrqNumber, LPWORD Stack)
|
||||||
|
{
|
||||||
|
/* Check if this was an PIC IRQ */
|
||||||
|
if (IntNum >= BIOS_PIC_MASTER_INT && IntNum < BIOS_PIC_MASTER_INT + 8)
|
||||||
|
{
|
||||||
|
/* It was an IRQ from the master PIC */
|
||||||
|
BiosHandleIrq(IntNum - BIOS_PIC_MASTER_INT, Stack);
|
||||||
|
}
|
||||||
|
else if (IntNum >= BIOS_PIC_SLAVE_INT && IntNum < BIOS_PIC_SLAVE_INT + 8)
|
||||||
|
{
|
||||||
|
/* It was an IRQ from the slave PIC */
|
||||||
|
BiosHandleIrq(IntNum - BIOS_PIC_SLAVE_INT + 8, Stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
VOID WINAPI Int32Dispatch(LPWORD Stack)
|
||||||
|
{
|
||||||
|
BYTE IntNum;
|
||||||
|
|
||||||
|
/* Get the interrupt number */
|
||||||
|
IntNum = LOBYTE(Stack[STACK_INT_NUM]);
|
||||||
|
|
||||||
|
/* Check if this was an exception */
|
||||||
|
if (IntNum < 8)
|
||||||
|
{
|
||||||
|
Exception(IntNum, Stack);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if this was an PIC IRQ */
|
||||||
|
if (IntNum >= BIOS_PIC_MASTER_INT && IntNum < BIOS_PIC_MASTER_INT + 8)
|
||||||
|
{
|
||||||
|
/* It was an IRQ from the master PIC */
|
||||||
|
BiosHandleIrq(IntNum - BIOS_PIC_MASTER_INT, Stack);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (IntNum >= BIOS_PIC_SLAVE_INT && IntNum < BIOS_PIC_SLAVE_INT + 8)
|
||||||
|
{
|
||||||
|
/* It was an IRQ from the slave PIC */
|
||||||
|
BiosHandleIrq(IntNum - BIOS_PIC_SLAVE_INT + 8, Stack);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Call the 32-bit Interrupt handler */
|
||||||
|
if (Int32Proc[IntNum] != NULL)
|
||||||
|
Int32Proc[IntNum](Stack);
|
||||||
|
else
|
||||||
|
DPRINT1("Unhandled 32-bit interrupt: 0x%02X\n", IntNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID WINAPI InitializeInt32(WORD BiosSegment)
|
||||||
|
{
|
||||||
|
USHORT i;
|
||||||
|
WORD Offset = 0;
|
||||||
|
|
||||||
|
LPDWORD IntVecTable = (LPDWORD)BaseAddress;
|
||||||
|
LPBYTE BiosCode = (LPBYTE)SEG_OFF_TO_PTR(BiosSegment, 0);
|
||||||
|
|
||||||
|
/* Generate ISR stubs and fill the IVT */
|
||||||
|
for (i = 0x00; i <= 0xFF; i++)
|
||||||
|
{
|
||||||
|
IntVecTable[i] = MAKELONG(Offset, BiosSegment);
|
||||||
|
|
||||||
|
BiosCode[Offset++] = 0xFB; // sti
|
||||||
|
|
||||||
|
BiosCode[Offset++] = 0x6A; // push i
|
||||||
|
BiosCode[Offset++] = (UCHAR)i;
|
||||||
|
|
||||||
|
BiosCode[Offset++] = 0x6A; // push 0
|
||||||
|
BiosCode[Offset++] = 0x00;
|
||||||
|
|
||||||
|
// BOP_SEQ:
|
||||||
|
BiosCode[Offset++] = 0xF8; // clc
|
||||||
|
|
||||||
|
BiosCode[Offset++] = LOBYTE(EMULATOR_BOP); // BOP sequence
|
||||||
|
BiosCode[Offset++] = HIBYTE(EMULATOR_BOP);
|
||||||
|
BiosCode[Offset++] = EMULATOR_CTRL_BOP; // Control BOP
|
||||||
|
BiosCode[Offset++] = CTRL_BOP_INT32; // 32-bit Interrupt dispatcher
|
||||||
|
|
||||||
|
BiosCode[Offset++] = 0x73; // jnc EXIT (offset +3)
|
||||||
|
BiosCode[Offset++] = 0x03;
|
||||||
|
|
||||||
|
// HACK: The following instruction should be HLT!
|
||||||
|
BiosCode[Offset++] = 0x90; // nop
|
||||||
|
|
||||||
|
BiosCode[Offset++] = 0xEB; // jmp BOP_SEQ (offset -10)
|
||||||
|
BiosCode[Offset++] = 0xF6;
|
||||||
|
|
||||||
|
// EXIT:
|
||||||
|
BiosCode[Offset++] = 0x83; // add sp, 4
|
||||||
|
BiosCode[Offset++] = 0xC4;
|
||||||
|
BiosCode[Offset++] = 0x04;
|
||||||
|
|
||||||
|
BiosCode[Offset++] = 0xCF; // iret
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID WINAPI RegisterInt32(BYTE IntNumber, EMULATOR_INT32_PROC IntHandler)
|
||||||
|
{
|
||||||
|
Int32Proc[IntNumber] = IntHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* EOF */
|
31
subsystems/ntvdm/int32.h
Normal file
31
subsystems/ntvdm/int32.h
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: GPL - See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS Virtual DOS Machine
|
||||||
|
* FILE: int32.h
|
||||||
|
* PURPOSE: 32-bit Interrupt Handlers
|
||||||
|
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||||
|
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _INT32_H_
|
||||||
|
#define _INT32_H_
|
||||||
|
|
||||||
|
/* DEFINES ********************************************************************/
|
||||||
|
|
||||||
|
/* 32-bit Interrupt dispatcher function code for the Control BOP Handler */
|
||||||
|
#define CTRL_BOP_INT32 0xFF
|
||||||
|
|
||||||
|
/* 32-bit Interrupt Identifiers */
|
||||||
|
#define EMULATOR_MAX_INT32_NUM 0xFF + 1
|
||||||
|
|
||||||
|
/* FUNCTIONS ******************************************************************/
|
||||||
|
|
||||||
|
typedef VOID (WINAPI *EMULATOR_INT32_PROC)(LPWORD Stack);
|
||||||
|
|
||||||
|
VOID WINAPI Int32Dispatch(LPWORD Stack);
|
||||||
|
VOID WINAPI InitializeInt32(WORD BiosSegment);
|
||||||
|
VOID WINAPI RegisterInt32(BYTE IntNumber, EMULATOR_INT32_PROC IntHandler);
|
||||||
|
|
||||||
|
#endif // _INT32_H_
|
||||||
|
|
||||||
|
/* EOF */
|
|
@ -39,7 +39,6 @@
|
||||||
|
|
||||||
extern LPVOID BaseAddress;
|
extern LPVOID BaseAddress;
|
||||||
extern BOOLEAN VdmRunning;
|
extern BOOLEAN VdmRunning;
|
||||||
extern LPCWSTR ExceptionName[];
|
|
||||||
|
|
||||||
VOID DisplayMessage(LPCWSTR Format, ...);
|
VOID DisplayMessage(LPCWSTR Format, ...);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue