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/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] 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++)