Author: hbelusca Date: Sat Nov 9 22:15:40 2013 New Revision: 60907
URL: http://svn.reactos.org/svn/reactos?rev=60907&view=rev Log: [NTVDM] Start my work on modularizing registration of "32-bit" interrupts, i.e. interrupts that are implemented in 32-bit mode, but are stubbed with 16-bit code (so that 16-bit apps can call them). The 16-bit stub code uses a BOP call to our Control BOP function (BOP 0xFF) which can handle in theory many sub-functions (as the BOP 0x58 documented here: http://www.ragestorm.net/tutorial?id=27) specified as an additional BYTE in the call: 0xC4 0xC4 bop_code <optional_bop_subfunction> Here, for calling 32-bit interrupts we use our BOP 0xFF, subfunction 0xFF. The final aim would be to generate the 16-bit stub code when one calls the RegisterInt32 helper function (contrary to what's happening now, that is, the 16-bit stub code is generated for all of the interrupts at BIOS initialization time, and we use it for BIOS and DOS interrupts).
Modified: branches/ntvdm/subsystems/ntvdm/bios.c branches/ntvdm/subsystems/ntvdm/bios.h branches/ntvdm/subsystems/ntvdm/bop.c branches/ntvdm/subsystems/ntvdm/bop.h branches/ntvdm/subsystems/ntvdm/dos.c branches/ntvdm/subsystems/ntvdm/dos.h branches/ntvdm/subsystems/ntvdm/emulator.c branches/ntvdm/subsystems/ntvdm/emulator.h
Modified: branches/ntvdm/subsystems/ntvdm/bios.c URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/bios.c?re... ============================================================================== --- branches/ntvdm/subsystems/ntvdm/bios.c [iso-8859-1] (original) +++ branches/ntvdm/subsystems/ntvdm/bios.c [iso-8859-1] Sat Nov 9 22:15:40 2013 @@ -10,8 +10,10 @@
#define NDEBUG
+#include "emulator.h" +#include "bop.h" + #include "bios.h" -#include "emulator.h" #include "vga.h" #include "pic.h" #include "ps2.h" @@ -461,7 +463,7 @@ { USHORT i; WORD Offset = 0; - LPWORD IntVecTable = (LPWORD)BaseAddress; + LPDWORD IntVecTable = (LPDWORD)BaseAddress; LPBYTE BiosCode = (LPBYTE)SEG_OFF_TO_PTR(BIOS_SEGMENT, 0);
/* Initialize the BDA */ @@ -480,8 +482,7 @@ /* Generate ISR stubs and fill the IVT */ for (i = 0x00; i <= 0xFF; i++) { - IntVecTable[i * 2] = Offset; - IntVecTable[i * 2 + 1] = BIOS_SEGMENT; + IntVecTable[i] = MAKELONG(Offset, BIOS_SEGMENT);
BiosCode[Offset++] = 0xFB; // sti
@@ -494,9 +495,10 @@ // BOP_SEQ: BiosCode[Offset++] = 0xF8; // clc
- BiosCode[Offset++] = LOBYTE(EMULATOR_BOP); // BOP sequence + BiosCode[Offset++] = LOBYTE(EMULATOR_BOP); // BOP sequence BiosCode[Offset++] = HIBYTE(EMULATOR_BOP); - BiosCode[Offset++] = EMULATOR_INT_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; @@ -504,8 +506,8 @@ // HACK: The following instruction should be HLT! BiosCode[Offset++] = 0x90; // nop
- BiosCode[Offset++] = 0xEB; // jmp BOP_SEQ (offset -9) - BiosCode[Offset++] = 0xF7; + BiosCode[Offset++] = 0xEB; // jmp BOP_SEQ (offset -10) + BiosCode[Offset++] = 0xF6;
// EXIT: BiosCode[Offset++] = 0x83; // add sp, 4 @@ -514,6 +516,12 @@
BiosCode[Offset++] = 0xCF; // iret } + RegisterInt32(BIOS_VIDEO_INTERRUPT , BiosVideoService ); + RegisterInt32(BIOS_EQUIPMENT_INTERRUPT, BiosEquipmentService ); + RegisterInt32(BIOS_MEMORY_SIZE , BiosGetMemorySize ); + RegisterInt32(BIOS_KBD_INTERRUPT , BiosKeyboardService ); + RegisterInt32(BIOS_TIME_INTERRUPT , BiosTimeService ); + RegisterInt32(BIOS_SYS_TIMER_INTERRUPT, BiosSystemTimerInterrupt);
/* Get the input handle to the real console, and check for success */ BiosConsoleInput = CreateFileW(L"CONIN$", @@ -818,7 +826,7 @@ BiosSetCursorPosition(Row, Column, Page); }
-VOID BiosVideoService(LPWORD Stack) +VOID WINAPI BiosVideoService(LPWORD Stack) { switch (getAH()) { @@ -1194,19 +1202,19 @@ } }
-VOID BiosEquipmentService(LPWORD Stack) +VOID WINAPI BiosEquipmentService(LPWORD Stack) { /* Return the equipment list */ setAX(Bda->EquipmentList); }
-VOID BiosGetMemorySize(LPWORD Stack) +VOID WINAPI BiosGetMemorySize(LPWORD Stack) { /* Return the conventional memory size in kB, typically 640 kB */ setAX(Bda->MemorySize); }
-VOID BiosKeyboardService(LPWORD Stack) +VOID WINAPI BiosKeyboardService(LPWORD Stack) { switch (getAH()) { @@ -1288,7 +1296,7 @@ } }
-VOID BiosTimeService(LPWORD Stack) +VOID WINAPI BiosTimeService(LPWORD Stack) { switch (getAH()) { @@ -1326,7 +1334,7 @@ } }
-VOID BiosSystemTimerInterrupt(LPWORD Stack) +VOID WINAPI BiosSystemTimerInterrupt(LPWORD Stack) { /* Increase the system tick count */ Bda->TickCounter++;
Modified: branches/ntvdm/subsystems/ntvdm/bios.h URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/bios.h?re... ============================================================================== --- branches/ntvdm/subsystems/ntvdm/bios.h [iso-8859-1] (original) +++ branches/ntvdm/subsystems/ntvdm/bios.h [iso-8859-1] Sat Nov 9 22:15:40 2013 @@ -159,13 +159,6 @@ WORD BiosGetCharacter(VOID); VOID BiosGetCursorPosition(PBYTE Row, PBYTE Column, BYTE Page); VOID BiosSetCursorPosition(BYTE Row, BYTE Column, BYTE Page); -VOID BiosVideoService(LPWORD Stack); -VOID BiosEquipmentService(LPWORD Stack); -VOID BiosGetMemorySize(LPWORD Stack); -VOID BiosKeyboardService(LPWORD Stack); -VOID BiosTimeService(LPWORD Stack); -VOID BiosHandleIrq(BYTE IrqNumber, LPWORD Stack); -VOID BiosSystemTimerInterrupt(LPWORD Stack); VOID BiosPrintCharacter(CHAR Character, BYTE Attribute, BYTE Page); BOOLEAN BiosScrollWindow( INT Direction, @@ -175,6 +168,15 @@ BYTE FillAttribute );
+VOID WINAPI BiosVideoService(LPWORD Stack); +VOID WINAPI BiosEquipmentService(LPWORD Stack); +VOID WINAPI BiosGetMemorySize(LPWORD Stack); +VOID WINAPI BiosKeyboardService(LPWORD Stack); +VOID WINAPI BiosTimeService(LPWORD Stack); +VOID WINAPI BiosSystemTimerInterrupt(LPWORD Stack); + +VOID BiosHandleIrq(BYTE IrqNumber, LPWORD Stack); + #endif // _BIOS_H_
/* EOF */
Modified: branches/ntvdm/subsystems/ntvdm/bop.c URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/bop.c?rev... ============================================================================== --- branches/ntvdm/subsystems/ntvdm/bop.c [iso-8859-1] (original) +++ branches/ntvdm/subsystems/ntvdm/bop.c [iso-8859-1] Sat Nov 9 22:15:40 2013 @@ -12,13 +12,10 @@ #define NDEBUG
#include "emulator.h" +#include "bop.h" + #include "bios.h" -#include "bop.h" #include "dos.h" -//#include "vga.h" -//#include "pic.h" -//#include "ps2.h" -//#include "timer.h" #include "registers.h"
LPCWSTR ExceptionName[] = @@ -33,6 +30,9 @@ L"FPU Not Available" };
+/* + * This is the list of registered BOP handlers. + */ EMULATOR_BOP_PROC BopProc[EMULATOR_MAX_BOP_NUM] = { NULL, @@ -292,6 +292,271 @@ NULL, 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) { @@ -344,11 +609,7 @@ // return; // }
-// VOID WINAPI BiosInt(BYTE IntNumber, LPWORD Stack) -// { -// } - -VOID WINAPI IntDispatch(LPWORD Stack) +VOID WINAPI Int32Dispatch(LPWORD Stack) { BYTE IntNum;
@@ -376,77 +637,48 @@ 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_MEMORY_SIZE: - { - /* This is the BIOS "get memory size" command, call the BIOS */ - BiosGetMemorySize(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; - } - case 0x2F: - { - DPRINT1("DOS System Function INT 0x2F, AH = %xh, AL = %xh NOT IMPLEMENTED!\n", - getAH(), getAL()); - Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF; - break; - } - default: - { - DPRINT1("Unhandled interrupt: 0x%02X\n", IntNum); - break; - } - } + /* 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) { - IntDispatch(Stack); + /* Get the Function Number and skip it */ + BYTE FuncNum = *(PBYTE)SEG_OFF_TO_PTR(getCS(), getIP()); + setIP(getIP() + 1); + + if (FuncNum == CTRL_BOP_INT32) + Int32Dispatch(Stack); + else + 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; + LPWORD Stack; + + /* Get the SS:SP */ + StackSegment = State->SegmentRegs[FAST486_REG_SS].Selector; + StackPointer = State->GeneralRegs[FAST486_REG_ESP].LowWord; + + /* Get the stack */ + Stack = (LPWORD)SEG_OFF_TO_PTR(StackSegment, StackPointer); + + /* Call the BOP handler */ + if (BopProc[BopCode] != NULL) + BopProc[BopCode](Stack); + else + DPRINT1("Invalid BOP code: 0x%02X\n", BopCode); +} + /* EOF */
Modified: branches/ntvdm/subsystems/ntvdm/bop.h URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/bop.h?rev... ============================================================================== --- branches/ntvdm/subsystems/ntvdm/bop.h [iso-8859-1] (original) +++ branches/ntvdm/subsystems/ntvdm/bop.h [iso-8859-1] Sat Nov 9 22:15:40 2013 @@ -7,10 +7,33 @@ * Hermes Belusca-Maito (hermes.belusca@sfr.fr) */
+#ifndef _BOP_H_ +#define _BOP_H_ + +/* DEFINES ********************************************************************/ + +/* BOP Identifiers */ +#define EMULATOR_BOP 0xC4C4 + +#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); - -extern EMULATOR_BOP_PROC BopProc[EMULATOR_MAX_BOP_NUM]; +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_ + /* EOF */
Modified: branches/ntvdm/subsystems/ntvdm/dos.c URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/dos.c?rev... ============================================================================== --- branches/ntvdm/subsystems/ntvdm/dos.c [iso-8859-1] (original) +++ branches/ntvdm/subsystems/ntvdm/dos.c [iso-8859-1] Sat Nov 9 22:15:40 2013 @@ -10,9 +10,11 @@
#define NDEBUG
+#include "emulator.h" +#include "bop.h" + #include "dos.h" #include "bios.h" -#include "emulator.h"
#include "registers.h"
@@ -1393,13 +1395,13 @@ } }
-VOID DosInt20h(LPWORD Stack) +VOID WINAPI DosInt20h(LPWORD Stack) { /* This is the exit interrupt */ DosTerminateProcess(Stack[STACK_CS], 0); }
-VOID DosInt21h(LPWORD Stack) +VOID WINAPI DosInt21h(LPWORD Stack) { BYTE Character; SYSTEMTIME SystemTime; @@ -2415,11 +2417,18 @@ } }
-VOID DosBreakInterrupt(LPWORD Stack) +VOID WINAPI DosBreakInterrupt(LPWORD Stack) { UNREFERENCED_PARAMETER(Stack);
VdmRunning = FALSE; +} + +VOID WINAPI DosInt2Fh(LPWORD Stack) +{ + DPRINT1("DOS System Function INT 0x2F, AH = %xh, AL = %xh NOT IMPLEMENTED!\n", + getAH(), getAL()); + Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF; }
BOOLEAN DosInitialize(VOID) @@ -2561,6 +2570,12 @@ DosSystemFileTable[1] = GetStdHandle(STD_OUTPUT_HANDLE); DosSystemFileTable[2] = GetStdHandle(STD_ERROR_HANDLE);
+ /* Register the DOS-32 Interrupts */ + RegisterInt32(0x20, DosInt20h ); + RegisterInt32(0x21, DosInt21h ); + RegisterInt32(0x23, DosBreakInterrupt); + RegisterInt32(0x2F, DosInt2Fh ); + return TRUE; }
Modified: branches/ntvdm/subsystems/ntvdm/dos.h URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/dos.h?rev... ============================================================================== --- branches/ntvdm/subsystems/ntvdm/dos.h [iso-8859-1] (original) +++ branches/ntvdm/subsystems/ntvdm/dos.h [iso-8859-1] Sat Nov 9 22:15:40 2013 @@ -136,9 +136,12 @@ CHAR DosReadCharacter(VOID); VOID DosPrintCharacter(CHAR Character); BOOLEAN DosHandleIoctl(BYTE ControlCode, WORD FileHandle); -VOID DosInt20h(LPWORD Stack); -VOID DosInt21h(LPWORD Stack); -VOID DosBreakInterrupt(LPWORD Stack); + +VOID WINAPI DosInt20h(LPWORD Stack); +VOID WINAPI DosInt21h(LPWORD Stack); +VOID WINAPI DosBreakInterrupt(LPWORD Stack); +VOID WINAPI DosInt2Fh(LPWORD Stack); + BOOLEAN DosInitialize(VOID);
#endif // _DOS_H_
Modified: branches/ntvdm/subsystems/ntvdm/emulator.c URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/emulator.... ============================================================================== --- branches/ntvdm/subsystems/ntvdm/emulator.c [iso-8859-1] (original) +++ branches/ntvdm/subsystems/ntvdm/emulator.c [iso-8859-1] Sat Nov 9 22:15:40 2013 @@ -272,24 +272,6 @@ } }
-VOID WINAPI EmulatorBiosOperation(PFAST486_STATE State, UCHAR BopCode) -{ - WORD StackSegment, StackPointer; - LPWORD Stack; - - /* Get the SS:SP */ - StackSegment = State->SegmentRegs[FAST486_REG_SS].Selector; - StackPointer = State->GeneralRegs[FAST486_REG_ESP].LowWord; - - /* Get the stack */ - Stack = (LPWORD)SEG_OFF_TO_PTR(StackSegment, StackPointer); - - if (BopProc[BopCode] != NULL) - BopProc[BopCode](Stack); - else - DPRINT1("Invalid BOP code %u\n", BopCode); -} - UCHAR WINAPI EmulatorIntAcknowledge(PFAST486_STATE State) { UNREFERENCED_PARAMETER(State);
Modified: branches/ntvdm/subsystems/ntvdm/emulator.h URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/emulator.... ============================================================================== --- branches/ntvdm/subsystems/ntvdm/emulator.h [iso-8859-1] (original) +++ branches/ntvdm/subsystems/ntvdm/emulator.h [iso-8859-1] Sat Nov 9 22:15:40 2013 @@ -120,12 +120,6 @@ UCHAR DataSize );
-VOID WINAPI EmulatorBiosOperation -( - PFAST486_STATE State, - UCHAR BopCode -); - UCHAR WINAPI EmulatorIntAcknowledge ( PFAST486_STATE State