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/clock.c?rev=68095&r1=68094&r2=68095&view=diff
==============================================================================
--- 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/clock.h?rev=68095&r1=68094&r2=68095&view=diff
==============================================================================
--- 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/hardware/video/vga.c?rev=68095&r1=68094&r2=68095&view=diff
==============================================================================
--- 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/hardware/video/vga.h?rev=68095&r1=68094&r2=68095&view=diff
==============================================================================
--- 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


Reply via email to