Author: hbelusca Date: Wed Jan 29 00:25:43 2014 New Revision: 61875
URL: http://svn.reactos.org/svn/reactos?rev=61875&view=rev Log: [NTVDM] - Enable experimental sound support (only PC speaker for the moment, aka. uses beep.sys). - Introduce a #define WORKING_TIMER which aim is to disable the currently problematic approximate performance counter value calculation done in order not to call QueryPerformanceCounter each time. The problem is that we then compute a number of clock ticks for the PIT, which becomes negative, and therefore everything starts to hang. Disabling this code and calling each time QueryPerformanceCounter, fixes everything; we gain in precision but we loose in performance... A definitive fix must be found, [TheFlash] !!
This fixes sound (and hangs) in Advanced NetWars, Dangerous Dave, ElitePlus and Rescue Rover (the games that I've tested so far).
Modified: branches/ntvdm/subsystems/ntvdm/emulator.c branches/ntvdm/subsystems/ntvdm/hardware/speaker.c branches/ntvdm/subsystems/ntvdm/hardware/speaker.h branches/ntvdm/subsystems/ntvdm/ntvdm.c
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] Wed Jan 29 00:25:43 2014 @@ -134,6 +134,7 @@
static VOID WINAPI Port61hWrite(ULONG Port, BYTE Data) { + // BOOLEAN SpeakerChange = FALSE; BYTE OldPort61hState = Port61hState;
/* Only the four lowest bytes can be written */ @@ -141,7 +142,8 @@
if ((OldPort61hState ^ Port61hState) & 0x01) { - DPRINT1("PIT 2 Gate %s\n", Port61hState & 0x01 ? "on" : "off"); + DPRINT("PIT 2 Gate %s\n", Port61hState & 0x01 ? "on" : "off"); + // SpeakerChange = TRUE; }
PitSetGate(2, !!(Port61hState & 0x01)); @@ -149,8 +151,11 @@ if ((OldPort61hState ^ Port61hState) & 0x02) { /* There were some change for the speaker... */ - DPRINT1("Speaker %s\n", Port61hState & 0x02 ? "on" : "off"); - } + DPRINT("Speaker %s\n", Port61hState & 0x02 ? "on" : "off"); + // SpeakerChange = TRUE; + } + // if (SpeakerChange) SpeakerChange(); + SpeakerChange(); }
static VOID WINAPI PitChan0Out(LPVOID Param, BOOLEAN State) @@ -183,6 +188,8 @@
static VOID WINAPI PitChan2Out(LPVOID Param, BOOLEAN State) { + // BYTE OldPort61hState = Port61hState; + #if 0 if (State) { @@ -197,6 +204,9 @@ #else Port61hState = (Port61hState & 0xDF) | (State << 5); #endif + DPRINT("Speaker PIT out\n"); + // if ((OldPort61hState ^ Port61hState) & 0x20) + // SpeakerChange(); }
/* PUBLIC FUNCTIONS ***********************************************************/
Modified: branches/ntvdm/subsystems/ntvdm/hardware/speaker.c URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/hardware/... ============================================================================== --- branches/ntvdm/subsystems/ntvdm/hardware/speaker.c [iso-8859-1] (original) +++ branches/ntvdm/subsystems/ntvdm/hardware/speaker.c [iso-8859-1] Wed Jan 29 00:25:43 2014 @@ -31,7 +31,7 @@
/* PUBLIC FUNCTIONS ***********************************************************/
-VOID SpeakerPool(VOID) +VOID SpeakerChange(VOID) { BYTE Port61hState = IOReadB(CONTROL_SYSTEM_PORT61H); BOOLEAN IsConnectedToPITChannel2 = !!(Port61hState & 0x01);
Modified: branches/ntvdm/subsystems/ntvdm/hardware/speaker.h URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/hardware/... ============================================================================== --- branches/ntvdm/subsystems/ntvdm/hardware/speaker.h [iso-8859-1] (original) +++ branches/ntvdm/subsystems/ntvdm/hardware/speaker.h [iso-8859-1] Wed Jan 29 00:25:43 2014 @@ -17,7 +17,7 @@
/* FUNCTIONS ******************************************************************/
-VOID SpeakerPool(VOID); +VOID SpeakerChange(VOID);
VOID SpeakerInitialize(VOID); VOID SpeakerCleanup(VOID);
Modified: branches/ntvdm/subsystems/ntvdm/ntvdm.c URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/ntvdm.c?r... ============================================================================== --- branches/ntvdm/subsystems/ntvdm/ntvdm.c [iso-8859-1] (original) +++ branches/ntvdm/subsystems/ntvdm/ntvdm.c [iso-8859-1] Wed Jan 29 00:25:43 2014 @@ -26,7 +26,17 @@ */ #define TESTING
-#define IPS_DISPLAY +/* + * Activate IPS_DISPLAY if you want to display the + * number of instructions per second, as well as + * the computed number of ticks for the PIT. + */ +// #define IPS_DISPLAY + +/* + * Activate WORKING_TIMER when the PIT timing problem is fixed. + */ +// #define WORKING_TIMER
/* PUBLIC VARIABLES ***********************************************************/
@@ -257,12 +267,15 @@ /* Main loop */ while (VdmRunning) { +#ifdef WORKING_TIMER DWORD PitResolution = PitGetResolution(); +#endif DWORD RtcFrequency = RtcGetTicksPerSecond();
/* Get the current number of ticks */ CurrentTickCount = GetTickCount();
+#ifdef WORKING_TIMER if ((PitResolution <= 1000) && (RtcFrequency <= 1000)) { /* Calculate the approximate performance counter value instead */ @@ -271,6 +284,7 @@ * (Frequency.QuadPart / 1000); } else +#endif { /* Get the current performance counter value */ QueryPerformanceCounter(&Counter); @@ -331,7 +345,7 @@ #ifdef IPS_DISPLAY if ((CurrentTickCount - LastCyclePrintout) >= 1000) { - DPRINT1("NTVDM: %lu Instructions Per Second; TimerTicks = %lu\n", Cycles, TimerTicks); + DPRINT1("NTVDM: %lu Instructions Per Second; TimerTicks = %I64d\n", Cycles, TimerTicks); LastCyclePrintout = CurrentTickCount; Cycles = 0; }