mirror of
https://github.com/reactos/reactos.git
synced 2025-01-06 06:20:13 +00:00
[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
This commit is contained in:
parent
f62b9a81d4
commit
90d7fbd4a8
3 changed files with 92 additions and 49 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
/* Yes, raise the output line and reload */
|
||||
if (i == 0) PicInterruptRequest(0);
|
||||
PitChannels[i].CurrentValue = PitChannels[i].ReloadValue;
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
|
|
@ -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_
|
||||
|
|
Loading…
Reference in a new issue