reactos/subsystems/ntvdm/bop.c
Hermès Bélusca-Maïto 39a527a21e [FAST486][NTVDM]
BOP numbers are 1 byte and map to a function (over 255). But one can pass additional "parameters" to those functions by adding extra bytes, however such functions must advance "by hand" the instruction pointer.

[NTVDM]
- Take into account our previous remark for the BIOS interrupt stubs, and comment them.
- Rework EmulatorBiosOperation (move almost all of its existing code into subfunctions in bop.c) so that one can call many other BOP functions in the future (WIP). The BOP number (still called) EMULATOR_INT_BOP (of value 0xFF) is used for internal 16 --> 32 bit switching for our 32bit bios.
- It appears that the IoRead/WriteCallback and IdleCallback must not be NULL for using fast486. I'm committing a temporary fix that I will definitely fix in a subsequent commit.

svn path=/branches/ntvdm/; revision=60812
2013-11-01 00:01:07 +00:00

166 lines
3.9 KiB
C

/*
* COPYRIGHT: GPL - See COPYING in the top level directory
* PROJECT: ReactOS Virtual DOS Machine
* FILE: bop.c
* PURPOSE: BIOS Operation 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 "bios.h"
#include "dos.h"
#include "vga.h"
#include "pic.h"
#include "ps2.h"
#include "timer.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"
};
VOID WINAPI Exception(BYTE ExceptionNumber, LPWORD Stack)
{
WORD CodeSegment, InstructionPointer;
ASSERT(ExceptionNumber < 8);
/* Get the CS:IP */
InstructionPointer = Stack[STACK_IP];
CodeSegment = Stack[STACK_CS];
/* Display a message to the user */
DisplayMessage(L"Exception: %s occured at %04X:%04X",
ExceptionName[ExceptionNumber],
CodeSegment,
InstructionPointer);
/* 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 BiosInt(BYTE IntNumber, LPWORD Stack)
// {
// }
VOID WINAPI IntDispatch(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;
}
switch (IntNum)
{
case BIOS_VIDEO_INTERRUPT:
{
/* This is the video BIOS interrupt, call the BIOS */
BiosVideoService(Stack);
break;
}
case BIOS_EQUIPMENT_INTERRUPT:
{
/* This is the BIOS "get equipment" command, call the BIOS */
BiosEquipmentService(Stack);
break;
}
case BIOS_KBD_INTERRUPT:
{
/* This is the keyboard BIOS interrupt, call the BIOS */
BiosKeyboardService(Stack);
break;
}
case BIOS_TIME_INTERRUPT:
{
/* This is the time BIOS interrupt, call the BIOS */
BiosTimeService(Stack);
break;
}
case BIOS_SYS_TIMER_INTERRUPT:
{
/* BIOS timer update */
BiosSystemTimerInterrupt(Stack);
break;
}
case 0x20:
{
DosInt20h(Stack);
break;
}
case 0x21:
{
DosInt21h(Stack);
break;
}
case 0x23:
{
DosBreakInterrupt(Stack);
break;
}
default:
{
DPRINT1("Unhandled interrupt: 0x%02X\n", IntNum);
break;
}
}
}
VOID WINAPI ControlBop(LPWORD Stack)
{
IntDispatch(Stack);
}
/* EOF */