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... ============================================================================== --- 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... ============================================================================== --- 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/hardw... ============================================================================== --- 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/hardw... ============================================================================== --- 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