From: Aleksandar Andrejevic Date: Fri, 1 Nov 2013 01:57:40 +0000 (+0000) Subject: [NTVDM] X-Git-Tag: backups/0.3.17@66124~1365^2~317 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=90d7fbd4a87a1cc75a11eadce7fa7fc6f12fbd3a;hp=f62b9a81d485a7c45afd438e9520ee5aa94f5278 [NTVDM] Revert a previous incorrect fix for the PIT. Modify the PitDecrementCount function to take a parameter instead of it being called multiple times (which is slower). svn path=/branches/ntvdm/; revision=60816 --- diff --git a/subsystems/ntvdm/ntvdm.c b/subsystems/ntvdm/ntvdm.c index c1efd21231b..f33001797e5 100644 --- a/subsystems/ntvdm/ntvdm.c +++ b/subsystems/ntvdm/ntvdm.c @@ -140,35 +140,20 @@ INT wmain(INT argc, WCHAR *argv[]) /* Main loop */ while (VdmRunning) { - /* Get the resolution of the system timer */ - DWORD TimerResolution = PitGetResolution(); - /* Get the current number of ticks */ CurrentTickCount = GetTickCount(); - if (TimerResolution > 1000) - { - /* Get the current performance counter value */ - QueryPerformanceCounter(&Counter); + /* Get the current performance counter value */ + QueryPerformanceCounter(&Counter); - /* Get the number of PIT ticks that have passed */ - TimerTicks = ((Counter.QuadPart - LastTimerTick.QuadPart) - * PIT_BASE_FREQUENCY) / Frequency.QuadPart; - } - else - { - /* Use the standard tick count */ - Counter.QuadPart = CurrentTickCount; + /* Get the number of PIT ticks that have passed */ + TimerTicks = ((Counter.QuadPart - LastTimerTick.QuadPart) + * PIT_BASE_FREQUENCY) / Frequency.QuadPart; - /* Get the number of PIT ticks that have passed */ - TimerTicks = ((Counter.QuadPart - LastTimerTick.QuadPart) - * PIT_BASE_FREQUENCY) / 1000; - } - /* Update the PIT */ if (TimerTicks > 0) { - for (i = 0; i < TimerTicks; i++) PitDecrementCount(); + PitDecrementCount(TimerTicks); LastTimerTick = Counter; } diff --git a/subsystems/ntvdm/timer.c b/subsystems/ntvdm/timer.c index 239a5abc29e..0d7327cd98c 100644 --- a/subsystems/ntvdm/timer.c +++ b/subsystems/ntvdm/timer.c @@ -146,7 +146,7 @@ VOID PitWriteData(BYTE Channel, BYTE Value) } } -VOID PitDecrementCount() +VOID PitDecrementCount(DWORD Count) { INT i; @@ -157,7 +157,12 @@ VOID PitDecrementCount() case PIT_MODE_INT_ON_TERMINAL_COUNT: { /* Decrement the value */ - PitChannels[i].CurrentValue--; + if (Count > PitChannels[i].CurrentValue) + { + /* The value does not reload in this case */ + PitChannels[i].CurrentValue = 0; + } + else PitChannels[i].CurrentValue -= Count; /* Did it fall to the terminal count? */ if (PitChannels[i].CurrentValue == 0 && !PitChannels[i].Pulsed) @@ -171,47 +176,100 @@ VOID PitDecrementCount() case PIT_MODE_RATE_GENERATOR: { - /* Decrement the value */ - PitChannels[i].CurrentValue--; + BOOLEAN Reloaded = FALSE; - /* Did it fall to zero? */ - if (PitChannels[i].CurrentValue != 0) break; + while (Count) + { + if ((Count > PitChannels[i].CurrentValue) + && (PitChannels[i].CurrentValue != 0)) + { + /* Decrease the count */ + Count -= PitChannels[i].CurrentValue; + + /* Reload the value */ + PitChannels[i].CurrentValue = PitChannels[i].ReloadValue; + + /* Set the flag */ + Reloaded = TRUE; + } + else + { + /* Decrease the value */ + PitChannels[i].CurrentValue -= Count; + + /* Clear the count */ + Count = 0; + + /* Did it fall to zero? */ + if (PitChannels[i].CurrentValue == 0) + { + PitChannels[i].CurrentValue = PitChannels[i].ReloadValue; + Reloaded = TRUE; + } + } + } - /* Yes, raise the output line and reload */ - if (i == 0) PicInterruptRequest(0); - PitChannels[i].CurrentValue = PitChannels[i].ReloadValue; + /* If there was a reload on channel 0, raise IRQ 0 */ + if ((i == 0) && Reloaded) PicInterruptRequest(0); break; } case PIT_MODE_SQUARE_WAVE: { - /* Decrement the value by 2 */ - PitChannels[i].CurrentValue -= 2; + INT ReloadCount = 0; + WORD ReloadValue = PitChannels[i].ReloadValue; - /* Did it fall to zero? */ - if (PitChannels[i].CurrentValue != 0) break; + /* The reload value must be even */ + ReloadValue &= ~1; - /* Yes, toggle the flip-flop */ - PitChannels[i].OutputFlipFlop = !PitChannels[i].OutputFlipFlop; - - /* Did this create a rising edge in the signal? */ - if (PitChannels[i].OutputFlipFlop) + while (Count) { - /* Yes, IRQ 0 if this is channel 0 */ - if (i == 0) PicInterruptRequest(0); + if (((Count * 2) > PitChannels[i].CurrentValue) + && (PitChannels[i].CurrentValue != 0)) + { + /* Decrease the count */ + Count -= PitChannels[i].CurrentValue / 2; + + /* Reload the value */ + PitChannels[i].CurrentValue = ReloadValue; + + /* Increment the reload count */ + ReloadCount++; + } + else + { + /* Clear the count */ + Count = 0; + + /* Decrease the value */ + PitChannels[i].CurrentValue -= Count * 2; + + /* Did it fall to zero? */ + if (PitChannels[i].CurrentValue == 0) + { + /* Reload the value */ + PitChannels[i].CurrentValue = ReloadValue; + + /* Increment the reload count */ + ReloadCount++; + } + } } - /* Reload the value, but make sure it's even */ - if (PitChannels[i].ReloadValue % 2) + if (ReloadCount == 0) break; + + /* Toggle the flip-flop if the number of reloads was odd */ + if (ReloadCount & 1) { - /* It's odd, reduce it by 1 */ - PitChannels[i].CurrentValue = PitChannels[i].ReloadValue - 1; + PitChannels[i].OutputFlipFlop = !PitChannels[i].OutputFlipFlop; } - else + + /* Was there any rising edge on channel 0 ? */ + if ((PitChannels[i].OutputFlipFlop || ReloadCount) && (i == 0)) { - /* It was even */ - PitChannels[i].CurrentValue = PitChannels[i].ReloadValue; + /* Yes, IRQ 0 */ + PicInterruptRequest(0); } break; diff --git a/subsystems/ntvdm/timer.h b/subsystems/ntvdm/timer.h index 01ec154e87b..637f4441fae 100644 --- a/subsystems/ntvdm/timer.h +++ b/subsystems/ntvdm/timer.h @@ -48,7 +48,7 @@ typedef struct _PIT_CHANNEL VOID PitWriteCommand(BYTE Value); BYTE PitReadData(BYTE Channel); VOID PitWriteData(BYTE Channel, BYTE Value); -VOID PitDecrementCount(); +VOID PitDecrementCount(DWORD Count); DWORD PitGetResolution(VOID); #endif // _TIMER_H_