mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +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
|
||||
bios.c
|
||||
bop.c
|
||||
cmos.c
|
||||
dos.c
|
||||
emulator.c
|
||||
int32.c
|
||||
pic.c
|
||||
registers.c
|
||||
timer.c
|
||||
ps2.c
|
||||
registers.c
|
||||
speaker.c
|
||||
timer.c
|
||||
vga.c
|
||||
cmos.c
|
||||
ntvdm.c
|
||||
ntvdm.rc
|
||||
${CMAKE_CURRENT_BINARY_DIR}/ntvdm.def)
|
||||
|
|
|
@ -11,14 +11,14 @@
|
|||
#define NDEBUG
|
||||
|
||||
#include "emulator.h"
|
||||
#include "bop.h"
|
||||
|
||||
#include "bios.h"
|
||||
|
||||
#include "vga.h"
|
||||
#include "pic.h"
|
||||
#include "ps2.h"
|
||||
#include "timer.h"
|
||||
|
||||
#include "int32.h"
|
||||
#include "registers.h"
|
||||
|
||||
/* PRIVATE VARIABLES **********************************************************/
|
||||
|
@ -461,11 +461,6 @@ BOOLEAN BiosSetVideoPage(BYTE PageNumber)
|
|||
|
||||
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 */
|
||||
Bda = (PBIOS_DATA_AREA)SEG_OFF_TO_PTR(BDA_SEGMENT, 0);
|
||||
Bda->EquipmentList = BIOS_EQUIPMENT_LIST;
|
||||
|
@ -479,43 +474,10 @@ BOOLEAN BiosInitialize(VOID)
|
|||
Bda->KeybdBufferStart = FIELD_OFFSET(BIOS_DATA_AREA, KeybdBuffer);
|
||||
Bda->KeybdBufferEnd = Bda->KeybdBufferStart + BIOS_KBD_BUFFER_SIZE * sizeof(WORD);
|
||||
|
||||
/* Generate ISR stubs and fill the IVT */
|
||||
for (i = 0x00; i <= 0xFF; i++)
|
||||
{
|
||||
IntVecTable[i] = MAKELONG(Offset, BIOS_SEGMENT);
|
||||
/* Initialize the 32-bit Interrupt system */
|
||||
InitializeInt32(BIOS_SEGMENT);
|
||||
|
||||
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
|
||||
}
|
||||
/* Register the BIOS 32-bit Interrupts */
|
||||
RegisterInt32(BIOS_VIDEO_INTERRUPT , BiosVideoService );
|
||||
RegisterInt32(BIOS_EQUIPMENT_INTERRUPT, BiosEquipmentService );
|
||||
RegisterInt32(BIOS_MEMORY_SIZE , BiosGetMemorySize );
|
||||
|
|
|
@ -14,21 +14,10 @@
|
|||
#include "emulator.h"
|
||||
#include "bop.h"
|
||||
|
||||
#include "bios.h"
|
||||
#include "dos.h"
|
||||
#include "int32.h"
|
||||
#include "registers.h"
|
||||
|
||||
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"
|
||||
};
|
||||
/* PRIVATE VARIABLES **********************************************************/
|
||||
|
||||
/*
|
||||
* This is the list of registered BOP handlers.
|
||||
|
@ -293,356 +282,7 @@ EMULATOR_BOP_PROC BopProc[EMULATOR_MAX_BOP_NUM] =
|
|||
ControlBop
|
||||
};
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
|
||||
VOID WINAPI ControlBop(LPWORD Stack)
|
||||
{
|
||||
|
@ -656,12 +296,6 @@ VOID WINAPI ControlBop(LPWORD Stack)
|
|||
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)
|
||||
{
|
||||
WORD StackSegment, StackPointer;
|
||||
|
|
|
@ -17,21 +17,14 @@
|
|||
|
||||
#define EMULATOR_CTRL_BOP 0xFF // Control BOP Handler
|
||||
#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
|
||||
|
||||
/* 32-bit Interrupt Identifiers */
|
||||
#define EMULATOR_MAX_INT_NUM 0xFF + 1
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
typedef VOID (WINAPI *EMULATOR_BOP_PROC)(LPWORD Stack);
|
||||
typedef VOID (WINAPI *EMULATOR_INT32_PROC)(LPWORD Stack);
|
||||
|
||||
VOID WINAPI ControlBop(LPWORD Stack);
|
||||
|
||||
VOID WINAPI RegisterInt32(BYTE IntNumber, EMULATOR_INT32_PROC IntHandler);
|
||||
VOID WINAPI EmulatorBiosOperation(PFAST486_STATE State, UCHAR BopCode);
|
||||
|
||||
#endif // _BOP_H_
|
||||
|
|
|
@ -11,11 +11,10 @@
|
|||
#define NDEBUG
|
||||
|
||||
#include "emulator.h"
|
||||
#include "bop.h"
|
||||
|
||||
#include "dos.h"
|
||||
#include "bios.h"
|
||||
|
||||
#include "bios.h"
|
||||
#include "int32.h"
|
||||
#include "registers.h"
|
||||
|
||||
/* PRIVATE VARIABLES **********************************************************/
|
||||
|
@ -2570,7 +2569,7 @@ BOOLEAN DosInitialize(VOID)
|
|||
DosSystemFileTable[1] = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
DosSystemFileTable[2] = GetStdHandle(STD_ERROR_HANDLE);
|
||||
|
||||
/* Register the DOS-32 Interrupts */
|
||||
/* Register the DOS 32-bit Interrupts */
|
||||
RegisterInt32(0x20, DosInt20h );
|
||||
RegisterInt32(0x21, DosInt21h );
|
||||
RegisterInt32(0x23, DosBreakInterrupt);
|
||||
|
|
|
@ -34,11 +34,6 @@
|
|||
#define EMULATOR_FLAG_VIP (1 << 20)
|
||||
#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_INT_NUM 1
|
||||
#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 BOOLEAN VdmRunning;
|
||||
extern LPCWSTR ExceptionName[];
|
||||
|
||||
VOID DisplayMessage(LPCWSTR Format, ...);
|
||||
|
||||
|
|
Loading…
Reference in a new issue