From: Hermès Bélusca-Maïto Date: Wed, 29 Jan 2014 00:25:43 +0000 (+0000) Subject: [NTVDM] X-Git-Tag: backups/0.3.17@66124~1365^2~110 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=d25d9ea618f7054c1a79423e610159e6a7956ccb [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). svn path=/branches/ntvdm/; revision=61875 --- diff --git a/subsystems/ntvdm/emulator.c b/subsystems/ntvdm/emulator.c index bc3f1017665..4e8f9e81ff2 100644 --- a/subsystems/ntvdm/emulator.c +++ b/subsystems/ntvdm/emulator.c @@ -134,6 +134,7 @@ static BYTE WINAPI Port61hRead(ULONG Port) 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 @@ static VOID WINAPI Port61hWrite(ULONG Port, BYTE Data) 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 @@ static VOID WINAPI Port61hWrite(ULONG Port, BYTE Data) 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 PitChan1Out(LPVOID Param, BOOLEAN State) static VOID WINAPI PitChan2Out(LPVOID Param, BOOLEAN State) { + // BYTE OldPort61hState = Port61hState; + #if 0 if (State) { @@ -197,6 +204,9 @@ static VOID WINAPI PitChan2Out(LPVOID Param, BOOLEAN State) #else Port61hState = (Port61hState & 0xDF) | (State << 5); #endif + DPRINT("Speaker PIT out\n"); + // if ((OldPort61hState ^ Port61hState) & 0x20) + // SpeakerChange(); } /* PUBLIC FUNCTIONS ***********************************************************/ diff --git a/subsystems/ntvdm/hardware/speaker.c b/subsystems/ntvdm/hardware/speaker.c index 26af44da373..03bf25cc84a 100644 --- a/subsystems/ntvdm/hardware/speaker.c +++ b/subsystems/ntvdm/hardware/speaker.c @@ -31,7 +31,7 @@ static HANDLE hBeep = NULL; /* PUBLIC FUNCTIONS ***********************************************************/ -VOID SpeakerPool(VOID) +VOID SpeakerChange(VOID) { BYTE Port61hState = IOReadB(CONTROL_SYSTEM_PORT61H); BOOLEAN IsConnectedToPITChannel2 = !!(Port61hState & 0x01); diff --git a/subsystems/ntvdm/hardware/speaker.h b/subsystems/ntvdm/hardware/speaker.h index 207b501ee03..94c9fc07db5 100644 --- a/subsystems/ntvdm/hardware/speaker.h +++ b/subsystems/ntvdm/hardware/speaker.h @@ -17,7 +17,7 @@ /* FUNCTIONS ******************************************************************/ -VOID SpeakerPool(VOID); +VOID SpeakerChange(VOID); VOID SpeakerInitialize(VOID); VOID SpeakerCleanup(VOID); diff --git a/subsystems/ntvdm/ntvdm.c b/subsystems/ntvdm/ntvdm.c index 004c42e7d90..91bccf7b849 100644 --- a/subsystems/ntvdm/ntvdm.c +++ b/subsystems/ntvdm/ntvdm.c @@ -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 @@ INT wmain(INT argc, WCHAR *argv[]) /* 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 @@ INT wmain(INT argc, WCHAR *argv[]) * (Frequency.QuadPart / 1000); } else +#endif { /* Get the current performance counter value */ QueryPerformanceCounter(&Counter); @@ -331,7 +345,7 @@ INT wmain(INT argc, WCHAR *argv[]) #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; }