diff --git a/include/ddk/vddsvc.h b/include/ddk/vddsvc.h index 72d502987dc..8a77ae44f2f 100644 --- a/include/ddk/vddsvc.h +++ b/include/ddk/vddsvc.h @@ -26,6 +26,22 @@ #include #endif +/* + * Interrupts services + */ +#define ICA_MASTER 0 +#define ICA_SLAVE 1 + +VOID +WINAPI +call_ica_hw_interrupt(INT ms, + BYTE line, + INT count); + +#define VDDSimulateInterrupt(ms, line, count) \ + call_ica_hw_interrupt((ms), (line), (count)) // Windows specifies a count of 1 ... + + /* * Registers manipulation */ diff --git a/subsystems/ntvdm/ntvdm.h b/subsystems/ntvdm/ntvdm.h index b0e80f03fe7..b4fb49417c4 100644 --- a/subsystems/ntvdm/ntvdm.h +++ b/subsystems/ntvdm/ntvdm.h @@ -24,7 +24,7 @@ #include #include -#include +#include #include diff --git a/subsystems/ntvdm/ntvdm.spec b/subsystems/ntvdm/ntvdm.spec index 6df8ee2951c..263e5a37e92 100644 --- a/subsystems/ntvdm/ntvdm.spec +++ b/subsystems/ntvdm/ntvdm.spec @@ -175,8 +175,6 @@ - - @ stdcall MGetVdmPointer(long long long) @ stdcall Sim32pGetVDMPointer(long long) @@ -184,5 +182,6 @@ @ stdcall VdmMapFlat(long long long) ;@ stdcall VdmUnmapFlat(long long ptr long) ; Not exported on x86 +@ stdcall call_ica_hw_interrupt(long long long) @ stdcall VDDInstallIOHook(long long ptr ptr) @ stdcall VDDDeInstallIOHook(long long ptr) diff --git a/subsystems/ntvdm/pic.c b/subsystems/ntvdm/pic.c index c479dfdc1a2..d9552201a68 100644 --- a/subsystems/ntvdm/pic.c +++ b/subsystems/ntvdm/pic.c @@ -3,6 +3,7 @@ * PROJECT: ReactOS Virtual DOS Machine * FILE: pic.c * PURPOSE: Programmable Interrupt Controller emulation + * (Interrupt Controller Adapter (ICA) in Windows terminology) * PROGRAMMERS: Aleksandar Andrejevic */ @@ -200,7 +201,7 @@ VOID PicInterruptRequest(BYTE Number) if (Number >= 0 && Number < 8) { /* Check if any of the higher-priority interrupts are busy */ - for (i = 0; i <= Number ; i++) + for (i = 0; i <= Number; i++) { if (MasterPic.InServiceRegister & (1 << Number)) return; } @@ -301,4 +302,41 @@ BOOLEAN PicInitialize(VOID) return TRUE; } + + +VOID +WINAPI +call_ica_hw_interrupt(INT ms, + BYTE line, + INT count) +{ + BYTE InterruptNumber = line; + + /* Check for PIC validity */ + if (ms != ICA_MASTER || ms != ICA_SLAVE) return; + + /* + * Adjust the interrupt request number according to the parameters, + * by adding an offset == 8 to the interrupt number. + * + * Indeed VDDs calling this function usually subtracts 8 so that they give: + * + * ms | line | corresponding interrupt number + * ------------+--------+-------------------------------- + * ICA_MASTER | 0 -- 7 | 0 -- 7 + * ICA_SLAVE | 0 -- 7 | 8 -- 15 + * + * and PicInterruptRequest subtracts again 8 to the interrupt number + * if it is greater or equal than 8 (so that it determines which PIC + * to use via the interrupt number). + */ + if (ms == ICA_SLAVE) InterruptNumber += 8; + + /* Send the specified number of interrupt requests */ + while (count-- > 0) + { + PicInterruptRequest(InterruptNumber); + } +} + /* EOF */ diff --git a/subsystems/ntvdm/pic.h b/subsystems/ntvdm/pic.h index 2ff7ed7ef13..f24f31c94d3 100644 --- a/subsystems/ntvdm/pic.h +++ b/subsystems/ntvdm/pic.h @@ -2,7 +2,8 @@ * COPYRIGHT: GPL - See COPYING in the top level directory * PROJECT: ReactOS Virtual DOS Machine * FILE: pic.h - * PURPOSE: Programmable Interrupt Controller emulation (header file) + * PURPOSE: Programmable Interrupt Controller emulation + * (Interrupt Controller Adapter (ICA) in Windows terminology) * PROGRAMMERS: Aleksandar Andrejevic */