mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +00:00
[NTVDM]
Implement cycle-based timing for VGA. svn path=/trunk/; revision=68095
This commit is contained in:
parent
d4365a1beb
commit
f3c5b91037
4 changed files with 58 additions and 30 deletions
|
@ -36,26 +36,28 @@
|
|||
/* VARIABLES ******************************************************************/
|
||||
|
||||
static LIST_ENTRY Timers;
|
||||
static ULONGLONG Cycles = 0ULL;
|
||||
static ULONGLONG CurrentIps = 20000000ULL; // 20 MIPS is a good estimate
|
||||
static LARGE_INTEGER StartPerfCount, Frequency;
|
||||
// static ULONG StartTickCount;
|
||||
static LARGE_INTEGER Counter;
|
||||
static ULONG CurrentTickCount;
|
||||
|
||||
#ifdef IPS_DISPLAY
|
||||
static ULONGLONG LastCycles = 0ULL;
|
||||
static PHARDWARE_TIMER IpsTimer;
|
||||
static ULONGLONG Cycles = 0ULL;
|
||||
#endif
|
||||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
||||
#ifdef IPS_DISPLAY
|
||||
static VOID FASTCALL IpsDisplayCallback(ULONGLONG ElapsedTime)
|
||||
static VOID FASTCALL IpsCallback(ULONGLONG ElapsedTime)
|
||||
{
|
||||
DPRINT1("NTVDM: %I64u Instructions Per Second\n", Cycles / ElapsedTime);
|
||||
Cycles = 0ULL;
|
||||
}
|
||||
CurrentIps = (Cycles - LastCycles) / ElapsedTime;
|
||||
|
||||
#ifdef IPS_DISPLAY
|
||||
DPRINT1("NTVDM: %I64u Instructions Per Second\n", CurrentIps);
|
||||
#endif
|
||||
|
||||
LastCycles = Cycles;
|
||||
}
|
||||
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
|
||||
VOID ClockUpdate(VOID)
|
||||
|
@ -76,10 +78,7 @@ VOID ClockUpdate(VOID)
|
|||
for (i = 0; VdmRunning && CpuRunning && (i < STEPS_PER_CYCLE); i++)
|
||||
{
|
||||
CpuStep();
|
||||
|
||||
#ifdef IPS_DISPLAY
|
||||
++Cycles;
|
||||
#endif
|
||||
}
|
||||
|
||||
for (Entry = Timers.Flink; Entry != &Timers; Entry = Entry->Flink)
|
||||
|
@ -199,6 +198,16 @@ VOID DestroyHardwareTimer(PHARDWARE_TIMER Timer)
|
|||
}
|
||||
}
|
||||
|
||||
ULONGLONG GetCycleCount(VOID)
|
||||
{
|
||||
return Cycles;
|
||||
}
|
||||
|
||||
ULONGLONG GetCycleSpeed(VOID)
|
||||
{
|
||||
return CurrentIps;
|
||||
}
|
||||
|
||||
BOOLEAN ClockInitialize(VOID)
|
||||
{
|
||||
InitializeListHead(&Timers);
|
||||
|
@ -215,16 +224,12 @@ BOOLEAN ClockInitialize(VOID)
|
|||
/* Find the starting tick count */
|
||||
// StartTickCount = GetTickCount();
|
||||
|
||||
#ifdef IPS_DISPLAY
|
||||
|
||||
IpsTimer = CreateHardwareTimer(HARDWARE_TIMER_ENABLED, HZ_TO_NS(1), IpsDisplayCallback);
|
||||
IpsTimer = CreateHardwareTimer(HARDWARE_TIMER_ENABLED, HZ_TO_NS(1), IpsCallback);
|
||||
if (IpsTimer == NULL)
|
||||
{
|
||||
wprintf(L"FATAL: Cannot create IPS display timer.\n");
|
||||
wprintf(L"FATAL: Cannot create IPS timer.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -44,6 +44,9 @@ VOID DisableHardwareTimer(PHARDWARE_TIMER Timer);
|
|||
VOID SetHardwareTimerDelay(PHARDWARE_TIMER Timer, ULONGLONG NewDelay);
|
||||
VOID DestroyHardwareTimer(PHARDWARE_TIMER Timer);
|
||||
|
||||
ULONGLONG GetCycleCount(VOID);
|
||||
ULONGLONG GetCycleSpeed(VOID);
|
||||
|
||||
VOID ClockUpdate(VOID);
|
||||
BOOLEAN ClockInitialize(VOID);
|
||||
|
||||
|
|
|
@ -282,8 +282,8 @@ static BYTE VgaDacRegisters[VGA_PALETTE_SIZE];
|
|||
|
||||
// static VGA_REGISTERS VgaRegisters;
|
||||
|
||||
static BOOLEAN InVerticalRetrace = FALSE;
|
||||
static BOOLEAN InHorizontalRetrace = FALSE;
|
||||
static ULONGLONG VerticalRetraceCycle = 0ULL;
|
||||
static ULONGLONG HorizontalRetraceCycle = 0ULL;
|
||||
|
||||
static BOOLEAN NeedsUpdate = FALSE;
|
||||
static BOOLEAN ModeChanged = FALSE;
|
||||
|
@ -1413,8 +1413,31 @@ static BYTE WINAPI VgaReadPort(USHORT Port)
|
|||
case VGA_INSTAT1_READ_COLOR:
|
||||
{
|
||||
BYTE Result = 0;
|
||||
BOOLEAN Vsync = InVerticalRetrace;
|
||||
BOOLEAN Hsync = InHorizontalRetrace;
|
||||
BOOLEAN Vsync, Hsync;
|
||||
ULONGLONG Cycles = GetCycleCount();
|
||||
ULONG CyclesPerMicrosecond = (ULONG)((GetCycleSpeed() + 500000ULL) / 1000000ULL);
|
||||
ULONG Dots = (VgaSeqRegisters[VGA_SEQ_CLOCK_REG] & 1) ? 9 : 8;
|
||||
ULONG Clock = ((VgaMiscRegister >> 2) & 1) ? 28 : 25;
|
||||
ULONG HorizTotalDots = ((ULONG)VgaCrtcRegisters[VGA_CRTC_HORZ_TOTAL_REG] + 5) * Dots;
|
||||
ULONG VblankStart, VblankEnd, HblankStart, HblankEnd;
|
||||
ULONG HblankDuration, VblankDuration;
|
||||
|
||||
/* Calculate the vertical blanking duration in cycles */
|
||||
VblankStart = VgaCrtcRegisters[VGA_CRTC_START_VERT_BLANKING_REG] & 0x7F;
|
||||
VblankEnd = VgaCrtcRegisters[VGA_CRTC_END_VERT_BLANKING_REG] & 0x7F;
|
||||
if (VblankEnd < VblankStart) VblankEnd |= 0x80;
|
||||
VblankDuration = ((VblankEnd - VblankStart) * HorizTotalDots
|
||||
* CyclesPerMicrosecond + (Clock >> 1)) / Clock;
|
||||
|
||||
/* Calculate the horizontal blanking duration in cycles */
|
||||
HblankStart = VgaCrtcRegisters[VGA_CRTC_START_HORZ_BLANKING_REG] & 0x1F;
|
||||
HblankEnd = VgaCrtcRegisters[VGA_CRTC_END_HORZ_BLANKING_REG] & 0x1F;
|
||||
if (HblankEnd < HblankStart) HblankEnd |= 0x20;
|
||||
HblankDuration = ((HblankEnd - HblankStart) * Dots
|
||||
* CyclesPerMicrosecond + (Clock >> 1)) / Clock;
|
||||
|
||||
Vsync = (Cycles - VerticalRetraceCycle) < (ULONGLONG)VblankDuration;
|
||||
Hsync = (Cycles - HorizontalRetraceCycle) < (ULONGLONG)HblankDuration;
|
||||
|
||||
/* Reset the AC latch */
|
||||
VgaAcLatch = FALSE;
|
||||
|
@ -1429,9 +1452,6 @@ static BYTE WINAPI VgaReadPort(USHORT Port)
|
|||
/* Set an additional flag if there was a vertical retrace */
|
||||
if (Vsync) Result |= VGA_STAT_VRETRACE;
|
||||
|
||||
/* Clear the flags */
|
||||
InHorizontalRetrace = InVerticalRetrace = FALSE;
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
|
@ -1787,8 +1807,8 @@ static VOID FASTCALL VgaVerticalRetrace(ULONGLONG ElapsedTime)
|
|||
|
||||
UNREFERENCED_PARAMETER(ElapsedTime);
|
||||
|
||||
/* Set the vertical retrace flag */
|
||||
InVerticalRetrace = TRUE;
|
||||
/* Set the vertical retrace cycle */
|
||||
VerticalRetraceCycle = GetCycleCount();
|
||||
|
||||
/* If nothing has changed, just return */
|
||||
// if (!ModeChanged && !CursorChanged && !PaletteChanged && !NeedsUpdate)
|
||||
|
@ -1859,8 +1879,8 @@ static VOID FASTCALL VgaHorizontalRetrace(ULONGLONG ElapsedTime)
|
|||
{
|
||||
UNREFERENCED_PARAMETER(ElapsedTime);
|
||||
|
||||
/* Set the flag */
|
||||
InHorizontalRetrace = TRUE;
|
||||
/* Set the cycle */
|
||||
HorizontalRetraceCycle = GetCycleCount();
|
||||
}
|
||||
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
|
|
|
@ -161,7 +161,7 @@ enum
|
|||
VGA_CRTC_OFFSET_REG,
|
||||
VGA_CRTC_UNDERLINE_REG,
|
||||
VGA_CRTC_START_VERT_BLANKING_REG,
|
||||
VGA_CRTC_END_VERT_BLANKING,
|
||||
VGA_CRTC_END_VERT_BLANKING_REG,
|
||||
VGA_CRTC_MODE_CONTROL_REG,
|
||||
VGA_CRTC_LINE_COMPARE_REG,
|
||||
VGA_CRTC_MAX_REG
|
||||
|
|
Loading…
Reference in a new issue