mirror of
https://github.com/reactos/reactos.git
synced 2025-01-07 14:51:00 +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 */
|
/* Main loop */
|
||||||
while (VdmRunning)
|
while (VdmRunning)
|
||||||
{
|
{
|
||||||
/* Get the resolution of the system timer */
|
|
||||||
DWORD TimerResolution = PitGetResolution();
|
|
||||||
|
|
||||||
/* Get the current number of ticks */
|
/* Get the current number of ticks */
|
||||||
CurrentTickCount = GetTickCount();
|
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 */
|
/* Get the number of PIT ticks that have passed */
|
||||||
TimerTicks = ((Counter.QuadPart - LastTimerTick.QuadPart)
|
TimerTicks = ((Counter.QuadPart - LastTimerTick.QuadPart)
|
||||||
* PIT_BASE_FREQUENCY) / Frequency.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) / 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Update the PIT */
|
/* Update the PIT */
|
||||||
if (TimerTicks > 0)
|
if (TimerTicks > 0)
|
||||||
{
|
{
|
||||||
for (i = 0; i < TimerTicks; i++) PitDecrementCount();
|
PitDecrementCount(TimerTicks);
|
||||||
LastTimerTick = Counter;
|
LastTimerTick = Counter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -146,7 +146,7 @@ VOID PitWriteData(BYTE Channel, BYTE Value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID PitDecrementCount()
|
VOID PitDecrementCount(DWORD Count)
|
||||||
{
|
{
|
||||||
INT i;
|
INT i;
|
||||||
|
|
||||||
|
@ -157,7 +157,12 @@ VOID PitDecrementCount()
|
||||||
case PIT_MODE_INT_ON_TERMINAL_COUNT:
|
case PIT_MODE_INT_ON_TERMINAL_COUNT:
|
||||||
{
|
{
|
||||||
/* Decrement the value */
|
/* 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? */
|
/* Did it fall to the terminal count? */
|
||||||
if (PitChannels[i].CurrentValue == 0 && !PitChannels[i].Pulsed)
|
if (PitChannels[i].CurrentValue == 0 && !PitChannels[i].Pulsed)
|
||||||
|
@ -171,47 +176,100 @@ VOID PitDecrementCount()
|
||||||
|
|
||||||
case PIT_MODE_RATE_GENERATOR:
|
case PIT_MODE_RATE_GENERATOR:
|
||||||
{
|
{
|
||||||
/* Decrement the value */
|
BOOLEAN Reloaded = FALSE;
|
||||||
PitChannels[i].CurrentValue--;
|
|
||||||
|
|
||||||
/* Did it fall to zero? */
|
while (Count)
|
||||||
if (PitChannels[i].CurrentValue != 0) break;
|
{
|
||||||
|
if ((Count > PitChannels[i].CurrentValue)
|
||||||
|
&& (PitChannels[i].CurrentValue != 0))
|
||||||
|
{
|
||||||
|
/* Decrease the count */
|
||||||
|
Count -= PitChannels[i].CurrentValue;
|
||||||
|
|
||||||
/* Yes, raise the output line and reload */
|
/* Reload the value */
|
||||||
if (i == 0) PicInterruptRequest(0);
|
PitChannels[i].CurrentValue = PitChannels[i].ReloadValue;
|
||||||
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case PIT_MODE_SQUARE_WAVE:
|
case PIT_MODE_SQUARE_WAVE:
|
||||||
{
|
{
|
||||||
/* Decrement the value by 2 */
|
INT ReloadCount = 0;
|
||||||
PitChannels[i].CurrentValue -= 2;
|
WORD ReloadValue = PitChannels[i].ReloadValue;
|
||||||
|
|
||||||
/* Did it fall to zero? */
|
/* The reload value must be even */
|
||||||
if (PitChannels[i].CurrentValue != 0) break;
|
ReloadValue &= ~1;
|
||||||
|
|
||||||
/* Yes, toggle the flip-flop */
|
while (Count)
|
||||||
PitChannels[i].OutputFlipFlop = !PitChannels[i].OutputFlipFlop;
|
|
||||||
|
|
||||||
/* Did this create a rising edge in the signal? */
|
|
||||||
if (PitChannels[i].OutputFlipFlop)
|
|
||||||
{
|
{
|
||||||
/* Yes, IRQ 0 if this is channel 0 */
|
if (((Count * 2) > PitChannels[i].CurrentValue)
|
||||||
if (i == 0) PicInterruptRequest(0);
|
&& (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 (ReloadCount == 0) break;
|
||||||
if (PitChannels[i].ReloadValue % 2)
|
|
||||||
|
/* Toggle the flip-flop if the number of reloads was odd */
|
||||||
|
if (ReloadCount & 1)
|
||||||
{
|
{
|
||||||
/* It's odd, reduce it by 1 */
|
PitChannels[i].OutputFlipFlop = !PitChannels[i].OutputFlipFlop;
|
||||||
PitChannels[i].CurrentValue = PitChannels[i].ReloadValue - 1;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
/* Was there any rising edge on channel 0 ? */
|
||||||
|
if ((PitChannels[i].OutputFlipFlop || ReloadCount) && (i == 0))
|
||||||
{
|
{
|
||||||
/* It was even */
|
/* Yes, IRQ 0 */
|
||||||
PitChannels[i].CurrentValue = PitChannels[i].ReloadValue;
|
PicInterruptRequest(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -48,7 +48,7 @@ typedef struct _PIT_CHANNEL
|
||||||
VOID PitWriteCommand(BYTE Value);
|
VOID PitWriteCommand(BYTE Value);
|
||||||
BYTE PitReadData(BYTE Channel);
|
BYTE PitReadData(BYTE Channel);
|
||||||
VOID PitWriteData(BYTE Channel, BYTE Value);
|
VOID PitWriteData(BYTE Channel, BYTE Value);
|
||||||
VOID PitDecrementCount();
|
VOID PitDecrementCount(DWORD Count);
|
||||||
DWORD PitGetResolution(VOID);
|
DWORD PitGetResolution(VOID);
|
||||||
|
|
||||||
#endif // _TIMER_H_
|
#endif // _TIMER_H_
|
||||||
|
|
Loading…
Reference in a new issue