Author: aandrejevic
Date: Tue Jun 9 19:22:52 2015
New Revision: 68095
URL:
http://svn.reactos.org/svn/reactos?rev=68095&view=rev
Log:
[NTVDM]
Implement cycle-based timing for VGA.
Modified:
trunk/reactos/subsystems/mvdm/ntvdm/clock.c
trunk/reactos/subsystems/mvdm/ntvdm/clock.h
trunk/reactos/subsystems/mvdm/ntvdm/hardware/video/vga.c
trunk/reactos/subsystems/mvdm/ntvdm/hardware/video/vga.h
Modified: trunk/reactos/subsystems/mvdm/ntvdm/clock.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/cloc…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/clock.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/clock.c [iso-8859-1] Tue Jun 9 19:22:52 2015
@@ -36,25 +36,27 @@
/* 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;
+static ULONGLONG LastCycles = 0ULL;
+static PHARDWARE_TIMER IpsTimer;
+
+/* PRIVATE FUNCTIONS **********************************************************/
+
+static VOID FASTCALL IpsCallback(ULONGLONG ElapsedTime)
+{
+ CurrentIps = (Cycles - LastCycles) / ElapsedTime;
#ifdef IPS_DISPLAY
-static PHARDWARE_TIMER IpsTimer;
-static ULONGLONG Cycles = 0ULL;
+ DPRINT1("NTVDM: %I64u Instructions Per Second\n", CurrentIps);
#endif
-/* PRIVATE FUNCTIONS **********************************************************/
-
-#ifdef IPS_DISPLAY
-static VOID FASTCALL IpsDisplayCallback(ULONGLONG ElapsedTime)
-{
- DPRINT1("NTVDM: %I64u Instructions Per Second\n", Cycles / ElapsedTime);
- Cycles = 0ULL;
-}
-#endif
+ LastCycles = Cycles;
+}
/* PUBLIC FUNCTIONS ***********************************************************/
@@ -76,10 +78,7 @@
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 @@
}
}
+ULONGLONG GetCycleCount(VOID)
+{
+ return Cycles;
+}
+
+ULONGLONG GetCycleSpeed(VOID)
+{
+ return CurrentIps;
+}
+
BOOLEAN ClockInitialize(VOID)
{
InitializeListHead(&Timers);
@@ -215,16 +224,12 @@
/* 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;
}
Modified: trunk/reactos/subsystems/mvdm/ntvdm/clock.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/cloc…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/clock.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/clock.h [iso-8859-1] Tue Jun 9 19:22:52 2015
@@ -44,6 +44,9 @@
VOID SetHardwareTimerDelay(PHARDWARE_TIMER Timer, ULONGLONG NewDelay);
VOID DestroyHardwareTimer(PHARDWARE_TIMER Timer);
+ULONGLONG GetCycleCount(VOID);
+ULONGLONG GetCycleSpeed(VOID);
+
VOID ClockUpdate(VOID);
BOOLEAN ClockInitialize(VOID);
Modified: trunk/reactos/subsystems/mvdm/ntvdm/hardware/video/vga.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/hard…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/hardware/video/vga.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/hardware/video/vga.c [iso-8859-1] Tue Jun 9
19:22:52 2015
@@ -282,8 +282,8 @@
// 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 @@
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;
@@ -1428,9 +1451,6 @@
/* 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 @@
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 @@
{
UNREFERENCED_PARAMETER(ElapsedTime);
- /* Set the flag */
- InHorizontalRetrace = TRUE;
+ /* Set the cycle */
+ HorizontalRetraceCycle = GetCycleCount();
}
/* PUBLIC FUNCTIONS ***********************************************************/
Modified: trunk/reactos/subsystems/mvdm/ntvdm/hardware/video/vga.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/hard…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/hardware/video/vga.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/hardware/video/vga.h [iso-8859-1] Tue Jun 9
19:22:52 2015
@@ -161,7 +161,7 @@
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