[NTVDM]
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Tue, 24 Dec 2013 22:40:15 +0000 (22:40 +0000)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Tue, 24 Dec 2013 22:40:15 +0000 (22:40 +0000)
- BIOS: Fix setting video page parameters when setting mode, and effectively fix setting of video page (fix the involved CRTC registers !!).
  Now Advanced NetWars works without flickering.
- VGA: Fix code presentation.

svn path=/branches/ntvdm/; revision=61390

subsystems/ntvdm/bios.c
subsystems/ntvdm/bios.h
subsystems/ntvdm/vga.c
subsystems/ntvdm/vga.h

index 89f0498..cc6cf0f 100644 (file)
@@ -254,7 +254,7 @@ static VGA_REGISTERS VideoMode_320x200_256color =
 };
 
 /* See http://wiki.osdev.org/Drawing_In_Protected_Mode#Locating_Video_Memory */
-static PVGA_REGISTERS VideoModes[] =
+static PVGA_REGISTERS VideoModes[BIOS_MAX_VIDEO_MODE + 1] =
 {
     &VideoMode_40x25_text,          /* Mode 00h */      // 16 color (mono)
     &VideoMode_40x25_text,          /* Mode 01h */      // 16 color
@@ -272,12 +272,23 @@ static PVGA_REGISTERS VideoModes[] =
     &VideoMode_320x200_16color,     /* Mode 0Dh */      // EGA 320*200 16 color
     &VideoMode_640x200_16color,     /* Mode 0Eh */      // EGA 640*200 16 color
     NULL,                           /* Mode 0Fh */      // EGA 640*350 mono
-    &VideoMode_640x350_16color,     /* Mode 10h */      // EGA 640*350 16 color
+    &VideoMode_640x350_16color,     /* Mode 10h */      // EGA 640*350 HiRes 16 color
     &VideoMode_640x480_2color,      /* Mode 11h */      // VGA 640*480 mono
     &VideoMode_640x480_16color,     /* Mode 12h */      // VGA
     &VideoMode_320x200_256color,    /* Mode 13h */      // VGA
 };
 
+// FIXME: Are they computable with the previous data ??
+// Values taken from DosBox
+static WORD VideoModePageSize[BIOS_MAX_VIDEO_MODE + 1] =
+{
+    0x0800, 0x0800, 0x1000, 0x1000,
+    0x4000, 0x4000, 0x4000, 0x1000,
+    0x0000, 0x0000, 0x0000, 0x0000,
+    0x0000, 0x2000, 0x4000, 0x8000,
+    0x8000, 0xA000, 0xA000, 0x2000
+};
+
 /* PRIVATE FUNCTIONS **********************************************************/
 
 static BOOLEAN BiosKbdBufferPush(WORD Data)
@@ -469,6 +480,8 @@ BYTE BiosGetVideoMode(VOID)
 BOOLEAN BiosSetVideoMode(BYTE ModeNumber)
 {
     INT i;
+    BYTE Page;
+
     COORD Resolution;
     PVGA_REGISTERS VgaMode = VideoModes[ModeNumber];
 
@@ -504,12 +517,20 @@ BOOLEAN BiosSetVideoMode(BYTE ModeNumber)
 
     // Bda->CrtModeControl;
     // Bda->CrtColorPaletteMask;
+    // Bda->EGAFlags;
+    // Bda->VGAFlags;
 
     /* Update the values in the BDA */
-    Bda->VideoMode = ModeNumber;
-    Bda->VideoPage = 0;
-    Bda->VideoPageSize = BIOS_PAGE_SIZE;
-    Bda->VideoPageOffset = 0;
+    Bda->VideoMode       = ModeNumber;
+    Bda->VideoPageSize   = VideoModePageSize[ModeNumber];
+    Bda->VideoPage       = 0;
+    Bda->VideoPageOffset = Bda->VideoPage * Bda->VideoPageSize;
+
+    /* Set the start address in the CRTC */
+    VgaWritePort(VGA_CRTC_INDEX, VGA_CRTC_START_ADDR_LOW_REG);
+    VgaWritePort(VGA_CRTC_DATA , LOBYTE(Bda->VideoPageOffset));
+    VgaWritePort(VGA_CRTC_INDEX, VGA_CRTC_START_ADDR_HIGH_REG);
+    VgaWritePort(VGA_CRTC_DATA , HIBYTE(Bda->VideoPageOffset));
 
     /* Get the character height */
     VgaWritePort(VGA_CRTC_INDEX, VGA_CRTC_MAX_SCAN_LINE_REG);
@@ -519,28 +540,40 @@ BOOLEAN BiosSetVideoMode(BYTE ModeNumber)
     Bda->ScreenColumns = Resolution.X;
     Bda->ScreenRows    = Resolution.Y - 1;
 
+    /* Set cursor position for each page */
+    for (Page = 0; Page < BIOS_MAX_PAGES; ++Page)
+        BiosSetCursorPosition(0, 0, Page);
+
     return TRUE;
 }
 
 BOOLEAN BiosSetVideoPage(BYTE PageNumber)
 {
+    BYTE Row, Column;
+
     /* Check if the page exists */
     if (PageNumber >= BIOS_MAX_PAGES) return FALSE;
 
     /* Check if this is the same page */
     if (PageNumber == Bda->VideoPage) return TRUE;
 
-    /* Set the values in the BDA */
-    Bda->VideoPage = PageNumber;
-    Bda->VideoPageSize = BIOS_PAGE_SIZE;
-    Bda->VideoPageOffset = PageNumber * BIOS_PAGE_SIZE;
+    /* Update the values in the BDA */
+    Bda->VideoPage       = PageNumber;
+    Bda->VideoPageOffset = Bda->VideoPage * Bda->VideoPageSize;
 
     /* Set the start address in the CRTC */
-    VgaWritePort(VGA_CRTC_INDEX, VGA_CRTC_CURSOR_LOC_LOW_REG);
+    VgaWritePort(VGA_CRTC_INDEX, VGA_CRTC_START_ADDR_LOW_REG);
     VgaWritePort(VGA_CRTC_DATA , LOBYTE(Bda->VideoPageOffset));
-    VgaWritePort(VGA_CRTC_INDEX, VGA_CRTC_CURSOR_LOC_HIGH_REG);
+    VgaWritePort(VGA_CRTC_INDEX, VGA_CRTC_START_ADDR_HIGH_REG);
     VgaWritePort(VGA_CRTC_DATA , HIBYTE(Bda->VideoPageOffset));
 
+    /*
+     * Get the cursor location (we don't update anything on the BIOS side
+     * but we update the cursor location on the VGA side).
+     */
+    BiosGetCursorPosition(&Row, &Column, PageNumber);
+    BiosSetCursorPosition(Row, Column, PageNumber);
+
     return TRUE;
 }
 
index d220c6e..836d015 100644 (file)
@@ -38,7 +38,6 @@
 
 #define BIOS_DEFAULT_VIDEO_MODE 0x03
 #define BIOS_MAX_PAGES 8
-#define BIOS_PAGE_SIZE 0x1000
 #define BIOS_MAX_VIDEO_MODE 0x13
 #define DEFAULT_ATTRIBUTE   0x07
 
index f6d91ab..f7ddd1b 100644 (file)
@@ -645,8 +645,8 @@ static VOID VgaUpdateFramebuffer(VOID)
     INT i, j, k;
     COORD Resolution = VgaGetDisplayResolution();
     INT AddressSize = VgaGetAddressSize();
-    DWORD Address = (VgaCrtcRegisters[VGA_CRTC_START_ADDR_HIGH_REG] << 8)
-                    + VgaCrtcRegisters[VGA_CRTC_START_ADDR_LOW_REG];
+    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;
 
     /*
index 57d77e7..363daa6 100644 (file)
@@ -2,7 +2,7 @@
  * COPYRIGHT:       GPL - See COPYING in the top level directory
  * PROJECT:         ReactOS Virtual DOS Machine
  * FILE:            vga.h
- * PURPOSE:         VGA hardware emulation (header file)
+ * PURPOSE:         VGA hardware emulation
  * PROGRAMMERS:     Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
  */