Author: aandrejevic
Date: Wed May 27 23:31:49 2015
New Revision: 67938

URL: http://svn.reactos.org/svn/reactos?rev=67938&view=rev
Log:
[NTVDM]
Implement VGA panning.


Modified:
    trunk/reactos/subsystems/mvdm/ntvdm/hardware/video/vga.c

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=67938&r1=67937&r2=67938&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] 
Wed May 27 23:31:49 2015
@@ -1059,9 +1059,11 @@
 {
     SHORT i, j, k;
     DWORD AddressSize = VgaGetAddressSize();
+    DWORD ScanlineSize = (DWORD)VgaCrtcRegisters[VGA_CRTC_OFFSET_REG] * 2;
+    BYTE PresetRowScan = VgaCrtcRegisters[VGA_CRTC_PRESET_ROW_SCAN_REG] & 0x1F;
     DWORD Address = MAKEWORD(VgaCrtcRegisters[VGA_CRTC_START_ADDR_LOW_REG],
-                             VgaCrtcRegisters[VGA_CRTC_START_ADDR_HIGH_REG]);
-    DWORD ScanlineSize = (DWORD)VgaCrtcRegisters[VGA_CRTC_OFFSET_REG] * 2;
+                             VgaCrtcRegisters[VGA_CRTC_START_ADDR_HIGH_REG])
+                    + ((VgaCrtcRegisters[VGA_CRTC_PRESET_ROW_SCAN_REG] >> 5) & 
3);
 
     /*
      * If console framebuffer is NULL, that means something went wrong
@@ -1075,6 +1077,7 @@
         /* Graphics mode */
         PBYTE GraphicsBuffer = (PBYTE)ConsoleFramebuffer;
         DWORD InterlaceHighBit = VGA_INTERLACE_HIGH_BIT;
+        SHORT X, Y;
 
         /*
          * Synchronize access to the graphics framebuffer
@@ -1096,6 +1099,10 @@
                 /* Odd-numbered line in interlaced mode - set the high bit */
                 Address |= InterlaceHighBit;
             }
+
+            /* Apply the preset row scan */
+            Y = i - PresetRowScan;
+            if (Y < 0) Y += CurrResolution.Y;
 
             /* Loop through the pixels */
             for (j = 0; j < CurrResolution.X; j++)
@@ -1216,58 +1223,71 @@
                                                  : 0);
                 }
 
+                /* Apply horizontal pixel panning */
+                if (VgaAcRegisters[VGA_AC_CONTROL_REG] & VGA_AC_CONTROL_8BIT)
+                {
+                    X = j - ((VgaAcRegisters[VGA_AC_HORZ_PANNING_REG] & 0x0F) 
>> 1);
+                }
+                else
+                {
+                    X = j - (VgaAcRegisters[VGA_AC_HORZ_PANNING_REG] & 0x0F);
+                }
+
+                /* Wrap around */
+                if (X < 0) X += CurrResolution.X;
+
                 /* Take into account DoubleVision mode when checking for pixel 
updates */
                 if (DoubleWidth && DoubleHeight)
                 {
                     /* Now check if the resulting pixel data has changed */
-                    if (GraphicsBuffer[(i * 2 * CurrResolution.X * 2) + (j * 
2)] != PixelData)
+                    if (GraphicsBuffer[(Y * 2 * CurrResolution.X * 2) + (X * 
2)] != PixelData)
                     {
                         /* Yes, write the new value */
-                        GraphicsBuffer[(i * 2 * CurrResolution.X * 2) + (j * 
2)] = PixelData;
-                        GraphicsBuffer[(i * 2 * CurrResolution.X * 2) + (j * 2 
+ 1)] = PixelData;
-                        GraphicsBuffer[((i * 2 + 1) * CurrResolution.X * 2) + 
(j * 2)] = PixelData;
-                        GraphicsBuffer[((i * 2 + 1) * CurrResolution.X * 2) + 
(j * 2 + 1)] = PixelData;
+                        GraphicsBuffer[(Y * 2 * CurrResolution.X * 2) + (X * 
2)] = PixelData;
+                        GraphicsBuffer[(Y * 2 * CurrResolution.X * 2) + (X * 2 
+ 1)] = PixelData;
+                        GraphicsBuffer[((Y * 2 + 1) * CurrResolution.X * 2) + 
(X * 2)] = PixelData;
+                        GraphicsBuffer[((Y * 2 + 1) * CurrResolution.X * 2) + 
(X * 2 + 1)] = PixelData;
 
                         /* Mark the specified pixel as changed */
-                        VgaMarkForUpdate(i, j);
+                        VgaMarkForUpdate(Y, X);
                     }
                 }
                 else if (DoubleWidth && !DoubleHeight)
                 {
                     /* Now check if the resulting pixel data has changed */
-                    if (GraphicsBuffer[(i * CurrResolution.X * 2) + (j * 2)] 
!= PixelData)
+                    if (GraphicsBuffer[(Y * CurrResolution.X * 2) + (X * 2)] 
!= PixelData)
                     {
                         /* Yes, write the new value */
-                        GraphicsBuffer[(i * CurrResolution.X * 2) + (j * 2)] = 
PixelData;
-                        GraphicsBuffer[(i * CurrResolution.X * 2) + (j * 2 + 
1)] = PixelData;
+                        GraphicsBuffer[(Y * CurrResolution.X * 2) + (X * 2)] = 
PixelData;
+                        GraphicsBuffer[(Y * CurrResolution.X * 2) + (X * 2 + 
1)] = PixelData;
 
                         /* Mark the specified pixel as changed */
-                        VgaMarkForUpdate(i, j);
+                        VgaMarkForUpdate(Y, X);
                     }
                 }
                 else if (!DoubleWidth && DoubleHeight)
                 {
                     /* Now check if the resulting pixel data has changed */
-                    if (GraphicsBuffer[(i * 2 * CurrResolution.X) + j] != 
PixelData)
+                    if (GraphicsBuffer[(Y * 2 * CurrResolution.X) + X] != 
PixelData)
                     {
                         /* Yes, write the new value */
-                        GraphicsBuffer[(i * 2 * CurrResolution.X) + j] = 
PixelData;
-                        GraphicsBuffer[((i * 2 + 1) * CurrResolution.X) + j] = 
PixelData;
+                        GraphicsBuffer[(Y * 2 * CurrResolution.X) + X] = 
PixelData;
+                        GraphicsBuffer[((Y * 2 + 1) * CurrResolution.X) + X] = 
PixelData;
 
                         /* Mark the specified pixel as changed */
-                        VgaMarkForUpdate(i, j);
+                        VgaMarkForUpdate(Y, X);
                     }
                 }
                 else // if (!DoubleWidth && !DoubleHeight)
                 {
                     /* Now check if the resulting pixel data has changed */
-                    if (GraphicsBuffer[i * CurrResolution.X + j] != PixelData)
+                    if (GraphicsBuffer[Y * CurrResolution.X + X] != PixelData)
                     {
                         /* Yes, write the new value */
-                        GraphicsBuffer[i * CurrResolution.X + j] = PixelData;
+                        GraphicsBuffer[Y * CurrResolution.X + X] = PixelData;
 
                         /* Mark the specified pixel as changed */
-                        VgaMarkForUpdate(i, j);
+                        VgaMarkForUpdate(Y, X);
                     }
                 }
             }
@@ -1297,6 +1317,12 @@
         DWORD CurrentAddr;
         PCHAR_CELL CharBuffer = (PCHAR_CELL)ConsoleFramebuffer;
         CHAR_CELL CharInfo;
+
+        /*
+         * Technically, the horizontal panning and preset row count should
+         * affect text mode too. However, it works on pixels and not 
characters,
+         * so we can't support it currently.
+         */
 
         /* Loop through the scanlines */
         for (i = 0; i < CurrResolution.Y; i++)


Reply via email to