Author: hbelusca
Date: Sun Nov 16 16:01:09 2014
New Revision: 65421
URL: 
http://svn.reactos.org/svn/reactos?rev=65421&view=rev
Log:
[NTVDM]
- Remove some old comments (and commented DPRINTs);
- More support for Bda->VGAOptions;
- Improve implementation of VidBiosSetCursorShape (start some cursor emulation, and add a
note about it);
- Implement few "Alternate Function Select" subfunctions.
Modified:
    trunk/reactos/subsystems/ntvdm/bios/vidbios.c
Modified: trunk/reactos/subsystems/ntvdm/bios/vidbios.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/ntvdm/bios/vidb…
==============================================================================
--- trunk/reactos/subsystems/ntvdm/bios/vidbios.c       [iso-8859-1] (original)
+++ trunk/reactos/subsystems/ntvdm/bios/vidbios.c       [iso-8859-1] Sun Nov 16 16:01:09
2014
@@ -50,7 +50,7 @@
     /* Sequencer Registers */
     {0x00, 0x08, 0x03, 0x00, 0x02},
-    /* CRTC Registers */
+    /* CRTC Registers */                /* CGA-compatible: 0xC7, 0x06, 0x07 */
     {0x2D, 0x27, 0x28, 0x90, 0x2B, 0xA0, 0xBF, 0x1F, 0x00, 0x4F, 0x0D, 0x0E,
      0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x14, 0x1F, 0x96, 0xB9, 0xA3,
      0xFF},
@@ -71,7 +71,7 @@
     /* Sequencer Registers */
     {0x00, 0x00, 0x03, 0x00, 0x02},
-    /* CRTC Registers */
+    /* CRTC Registers */                /* CGA-compatible: 0xC7, 0x06, 0x07 */
     {0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81, 0xBF, 0x1F, 0x00, 0x4F, 0x0D, 0x0E,
      0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x28, 0x1F, 0x96, 0xB9, 0xA3,
      0xFF},
@@ -2100,19 +2100,25 @@
      */
     Bda->CrtBasePort = (Registers->Misc & 0x01) ? VGA_CRTC_INDEX_COLOR
                                                 : VGA_CRTC_INDEX_MONO;
+    /* Bit 1 indicates whether display is color (0) or monochrome (1) */
+    Bda->VGAOptions  = (Bda->VGAOptions & 0xFD) | (!(Registers->Misc &
0x01) << 1);
+
+    /* Turn the video off */
+    IOWriteB(VGA_SEQ_INDEX, VGA_SEQ_CLOCK_REG);
+    IOWriteB(VGA_SEQ_DATA , IOReadB(VGA_SEQ_DATA) | VGA_SEQ_CLOCK_SD);
     /* Write the misc register */
     IOWriteB(VGA_MISC_WRITE, Registers->Misc);
     /* Synchronous reset on */
     IOWriteB(VGA_SEQ_INDEX, VGA_SEQ_RESET_REG);
-    IOWriteB(VGA_SEQ_DATA , VGA_SEQ_RESET_AR);
+    IOWriteB(VGA_SEQ_DATA , VGA_SEQ_RESET_AR );
     /* Write the sequencer registers */
     for (i = 1; i < VGA_SEQ_MAX_REG; i++)
     {
         IOWriteB(VGA_SEQ_INDEX, i);
-        IOWriteB(VGA_SEQ_DATA, Registers->Sequencer[i]);
+        IOWriteB(VGA_SEQ_DATA , Registers->Sequencer[i]);
     }
     /* Synchronous reset off */
@@ -2121,9 +2127,9 @@
     /* Unlock CRTC registers 0-7 */
     IOWriteB(VGA_CRTC_INDEX, VGA_CRTC_END_HORZ_BLANKING_REG);
-    IOWriteB(VGA_CRTC_DATA, IOReadB(VGA_CRTC_DATA) | 0x80);
+    IOWriteB(VGA_CRTC_DATA , IOReadB(VGA_CRTC_DATA) | 0x80);
     IOWriteB(VGA_CRTC_INDEX, VGA_CRTC_VERT_RETRACE_END_REG);
-    IOWriteB(VGA_CRTC_DATA, IOReadB(VGA_CRTC_DATA) & ~0x80);
+    IOWriteB(VGA_CRTC_DATA , IOReadB(VGA_CRTC_DATA) & ~0x80);
     // Make sure they remain unlocked
     Registers->CRT[VGA_CRTC_END_HORZ_BLANKING_REG] |= 0x80;
     Registers->CRT[VGA_CRTC_VERT_RETRACE_END_REG] &= ~0x80;
@@ -2132,24 +2138,21 @@
     for (i = 0; i < VGA_CRTC_MAX_REG; i++)
     {
         IOWriteB(VGA_CRTC_INDEX, i);
-        IOWriteB(VGA_CRTC_DATA, Registers->CRT[i]);
+        IOWriteB(VGA_CRTC_DATA , Registers->CRT[i]);
     }
     /* Write the GC registers */
     for (i = 0; i < VGA_GC_MAX_REG; i++)
     {
         IOWriteB(VGA_GC_INDEX, i);
-        IOWriteB(VGA_GC_DATA, Registers->Graphics[i]);
+        IOWriteB(VGA_GC_DATA , Registers->Graphics[i]);
     }
     /* Write the AC registers */
-    // DbgPrint("\n");
     for (i = 0; i < VGA_AC_MAX_REG; i++)
     {
         VgaSetSinglePaletteRegister(i, Registers->Attribute[i]);
-        // DbgPrint("Registers->Attribute[%d] = %d\n", i,
Registers->Attribute[i]);
     }
-    // DbgPrint("\n");
     /* Set the PEL mask */
     IOWriteB(VGA_DAC_MASK, 0xFF);
@@ -2157,6 +2160,10 @@
     /* Enable screen and disable palette access */
     IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
     IOWriteB(VGA_AC_INDEX, 0x20);
+
+    /* Turn the video on */
+    IOWriteB(VGA_SEQ_INDEX, VGA_SEQ_CLOCK_REG);
+    IOWriteB(VGA_SEQ_DATA , IOReadB(VGA_SEQ_DATA) & ~VGA_SEQ_CLOCK_SD);
     /* Enable interrupts */
     setIF(1);
@@ -2263,6 +2270,53 @@
     }
 }
+static VOID VidBiosSetCursorShape(WORD CursorStartEnd)
+{
+    /* Only valid in text-mode */
+    if ((Bda->VideoMode > 0x03) && (Bda->VideoMode != 0x07)) return;
+
+    /* Update the BDA */
+    Bda->CursorStartLine = HIBYTE(CursorStartEnd) & 0x1F;
+    Bda->CursorEndLine   = LOBYTE(CursorStartEnd) & 0x1F;
+
+    /*
+     * In cursor emulation mode, we suppose the cursor scanlines
+     * to be in CGA mode, so that we need to adjust them
+     *
+     * WARNING!!
+     * =========
+     * Contrary to what is mentioned in lots of literature out there, e.g. in:
+     * 
http://webpages.charter.net/danrollins/techhelp/0072.HTM
+     * 
http://www.bioscentral.com/misc/bda.htm
+     * and in other various places, bit 0 of Bda->VGAOptions is 0 when
+     * cursor emulation is ENABLED, and is 1 when it is DISABLED.
+     *
+     * The following documentation is right about this fact:
+     *
http://www.cs.nyu.edu/~mwalfish/classes/ut/s12-cs372h/ref/hardware/vgadoc/V…
+     * 
https://sites.google.com/site/pcdosretro/biosdata
+     *
+     * A proof that it is OK is that in the following code samples it is
+     * explicitely mentioned that setting bit 0 disables cursor emulation:
+     * - Code snippets in PC Magazine vol.5 num.15 of 16/09/1986, p.291-292;
+     * - CardFile DOS utility (Jeff Prosise, PC Magazine vol.6 num.17 of 13/10/1987,
p.403-416):
+     *   
https://ia600700.us.archive.org/1/items/srccode-00000020/cardfile.asm.txt
+     *   (function 'show_cursor', "or ega_info,1    ;disable EGA cursor
emulation")
+     */
+    if (!(Bda->VGAOptions & 0x01))
+    {
+        // HACK: Quick "fix" for cursor scanline adjustment. This must be
reworked.
+        DPRINT1("HACK: Using HACK for cursor scanlines adjustment\n");
+        CursorStartEnd = MAKEWORD((LOBYTE(CursorStartEnd) & 0x1F) * 2,
+                                  (HIBYTE(CursorStartEnd) & 0x1F) * 2 |
(HIBYTE(CursorStartEnd) & 0xE0));
+    }
+
+    /* Modify the CRTC registers */
+    IOWriteB(VGA_CRTC_INDEX, VGA_CRTC_CURSOR_START_REG);
+    IOWriteB(VGA_CRTC_DATA , HIBYTE(CursorStartEnd));
+    IOWriteB(VGA_CRTC_INDEX, VGA_CRTC_CURSOR_END_REG);
+    IOWriteB(VGA_CRTC_DATA , LOBYTE(CursorStartEnd));
+}
+
 VOID VidBiosSyncCursorPosition(VOID)
 {
     BYTE Row, Column;
@@ -2340,7 +2394,7 @@
     Bda->VideoPageOffset = Bda->VideoPage * Bda->VideoPageSize;
     /* 256 KB Video RAM; set bit 7 if we do not clear the screen */
-    Bda->VGAOptions      = 0x60 | (DoNotClear ? 0x80 : 0x00);
+    Bda->VGAOptions      = 0x60 | (Bda->VGAOptions & 0x7F) | (DoNotClear ? 0x80
: 0x00);
     Bda->VGASwitches     = 0xF9;    /* High-resolution  */
     /* Set the start address in the CRTC */
@@ -2357,6 +2411,15 @@
     Resolution = VgaGetDisplayResolution();
     Bda->ScreenColumns = Resolution.X;
     Bda->ScreenRows    = Resolution.Y - 1;
+
+    /*
+     * Update the cursor shape (text-mode only).
+     * Use the default CGA cursor scanline values,
+     * see: 
http://vitaly_filatov.tripod.com/ng/asm/asm_023.2.html
+     */
+    if ((ModeNumber >= 0x00 && ModeNumber <= 0x03) || (ModeNumber == 0x07))
+        // FIXME: we might read the CRT registers and do the adjustment?
+        VidBiosSetCursorShape(MAKEWORD(0x07, 0x06));
     /* Set the cursor position for each page */
     for (Page = 0; Page < BIOS_MAX_PAGES; ++Page)
@@ -2519,18 +2582,7 @@
         /* Set Text-Mode Cursor Shape */
         case 0x01:
         {
-            WORD CursorStartEnd = getCX();
-
-            /* Update the BDA */
-            Bda->CursorStartLine = HIBYTE(CursorStartEnd) & 0x1F;
-            Bda->CursorEndLine   = LOBYTE(CursorStartEnd) & 0x1F;
-
-            /* Modify the CRTC registers */
-            IOWriteB(VGA_CRTC_INDEX, VGA_CRTC_CURSOR_START_REG);
-            IOWriteB(VGA_CRTC_DATA , HIBYTE(CursorStartEnd));
-            IOWriteB(VGA_CRTC_INDEX, VGA_CRTC_CURSOR_END_REG);
-            IOWriteB(VGA_CRTC_DATA , Bda->CursorEndLine);
-
+            VidBiosSetCursorShape(getCX());
             break;
         }
@@ -2548,7 +2600,6 @@
             if (getBH() >= BIOS_MAX_PAGES) break;
             /* Return the result */
-            setAX(0);
             setCX(MAKEWORD(Bda->CursorEndLine, Bda->CursorStartLine));
             setDX(Bda->CursorPosition[getBH()]);
             break;
@@ -2650,7 +2701,7 @@
         /* Set Video Colors */
         case 0x0B:
         {
-            if (Bda->VideoMode < 4 || Bda->VideoMode > 6)
+            if (Bda->VideoMode < 0x04 || Bda->VideoMode > 0x06)
             {
                 DPRINT1("BIOS Function INT 10h, AH = 0Bh, BH = 0x%02X is unsupported
for non-CGA modes\n",
                         getBH());
@@ -2673,7 +2724,7 @@
                     VgaSetSinglePaletteRegister(VGA_AC_OVERSCAN_REG, Index);
                     /* Don't set any extra colors when in text mode */
-                    if (Bda->VideoMode <= 3) break;
+                    if (Bda->VideoMode <= 0x03) break;
                     VgaSetSinglePaletteRegister(0x00, Index);
@@ -2704,7 +2755,7 @@
                     Bda->CrtColorPaletteMask = (Bda->CrtColorPaletteMask &
0xDF) | ((Index & 1) ? 0x20 : 0x00);
                     /* Don't set any extra colors when in text mode */
-                    if (Bda->VideoMode <= 3) break;
+                    if (Bda->VideoMode <= 0x03) break;
                     Index = (Bda->CrtColorPaletteMask & 0x10) | 0x02 | Index;
@@ -3051,8 +3102,71 @@
         /* Alternate Function Select */
         case 0x12:
         {
-            DPRINT1("BIOS Function INT 10h, AH = 12h (Alternate Function Select), BX
= 0x%04X NOT IMPLEMENTED\n",
-                    getBX());
+            switch (getBL())
+            {
+                /* Get EGA/VGA Information */
+                case 0x10:
+                {
+                    setBH((Bda->VGAOptions  & 0x02) >> 1);  /* Color (0) or
monochrome (1) display */
+                    setBL((Bda->VGAOptions  & 0x60) >> 5);  /* Video RAM
size */
+                    setCH((Bda->VGASwitches & 0xF0) >> 4);  /* Features
settings */
+                    setCL( Bda->VGASwitches & 0x0F);        /* Switches settings
*/
+                    break;
+                }
+
+                /* Enable/Disable Cursor Emulation */
+                case 0x34:
+                {
+                    BYTE State = getAL();
+
+                    /* Check for validity */
+                    if (State > 1) break;
+
+                    /*
+                     * Enable (State == 0) or disable (State == 1) cursor emulation.
+                     * Please read the WARNING in the 'VidBiosSetCursorShape'
+                     * function for more details.
+                     */
+                    Bda->VGAOptions = (Bda->VGAOptions & 0xFE) | (State &
0x01);
+
+                    /* Return success */
+                    setAL(0x12);
+                    break;
+                }
+
+                /* Enable/Disable screen refresh */
+                case 0x36:
+                {
+                    BYTE State = getAL();
+                    BYTE Clocking;
+
+                    /* Check for validity */
+                    if (State > 1) break;
+
+                    /* Turn the video on (State == 0) or off (State == 1) */
+                    IOWriteB(VGA_SEQ_INDEX, VGA_SEQ_CLOCK_REG);
+                    Clocking = IOReadB(VGA_SEQ_DATA);
+
+                    if (State == 0)
+                        Clocking &= ~VGA_SEQ_CLOCK_SD;
+                    else
+                        Clocking |= VGA_SEQ_CLOCK_SD;
+
+                    IOWriteB(VGA_SEQ_DATA, Clocking);
+
+                    /* Return success */
+                    setAL(0x12);
+                    break;
+                }
+
+                default:
+                {
+                    DPRINT1("BIOS Function INT 10h, AH = 12h (Alternate Function
Select), BX = 0x%04X NOT IMPLEMENTED\n",
+                            getBX());
+                    break;
+                }
+            }
+
             break;
         }