[NTVDM]
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sun, 24 May 2015 12:35:29 +0000 (12:35 +0000)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sun, 24 May 2015 12:35:29 +0000 (12:35 +0000)
- Update the CrtModeControl byte in the BDA when we change video modes.
- Implement INT 10h, AX=1003h "Toggle Intensity/Blinking Bit".
- Partially implement INT 10h, AH=1Bh "Functionality/State Information (VGA)".

svn path=/trunk/; revision=67879

reactos/subsystems/mvdm/ntvdm/bios/bios.h
reactos/subsystems/mvdm/ntvdm/bios/vidbios.c
reactos/subsystems/mvdm/ntvdm/bios/vidbios.h

index f194643..be9ef20 100644 (file)
@@ -97,7 +97,8 @@ typedef struct
     WORD CharacterHeight;                       // 0x85
     BYTE VGAOptions;                            // 0x87
     BYTE VGASwitches;                           // 0x88
-    BYTE VGAFlags[2];                           // 0x89
+    BYTE VGAFlags;                              // 0x89
+    BYTE VGADccIDActive;                        // 0x8a
     DWORD Reserved3;                            // 0x8b
     BYTE Reserved4;                             // 0x8f
     BYTE Reserved5[2];                          // 0x90
index 5e4720e..342c6d6 100644 (file)
@@ -1942,6 +1942,8 @@ static CONST UCHAR Font8x16[VGA_FONT_CHARACTERS * 16] =
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 };
 
+PVGA_STATIC_FUNC_TABLE VgaStaticFuncTable;
+
 /* PRIVATE FUNCTIONS **********************************************************/
 
 static BOOLEAN VidBiosScrollWindow(SCROLL_DIRECTION Direction,
@@ -2127,7 +2129,14 @@ static BOOLEAN VgaSetRegisters(PVGA_REGISTERS Registers)
     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);
+    Bda->VGAOptions     = (Bda->VGAOptions     & 0xFD) | (!(Registers->Misc & 0x01) << 1);
+    Bda->CrtModeControl = (Bda->CrtModeControl & 0xFB) | (!(Registers->Misc & 0x01) << 1);
+
+    /* Update blink bit in BDA */
+    if (Registers->Attribute[VGA_AC_CONTROL_REG] & VGA_AC_CONTROL_BLINK)
+        Bda->CrtModeControl |= (1 << 5);
+    else
+        Bda->CrtModeControl &= ~(1 << 5);
 
     /* Turn the video off */
     IOWriteB(VGA_SEQ_INDEX, VGA_SEQ_CLOCK_REG);
@@ -2408,11 +2417,6 @@ static BOOLEAN VidBiosSetVideoMode(BYTE ModeNumber)
     /* Clear the VGA memory if needed */
     if (!DoNotClear) VgaClearMemory();
 
-    // Bda->CrtModeControl;
-    // Bda->CrtColorPaletteMask;
-    // Bda->EGAFlags;
-    // Bda->VGAFlags;
-
     /* Update the values in the BDA */
     Bda->VideoMode       = ModeNumber;
     Bda->VideoPageSize   = VideoModePageSize[ModeNumber];
@@ -2423,6 +2427,10 @@ static BOOLEAN VidBiosSetVideoMode(BYTE ModeNumber)
     Bda->VGAOptions      = 0x60 | (Bda->VGAOptions & 0x7F) | (DoNotClear ? 0x80 : 0x00);
     Bda->VGASwitches     = 0xF9;    /* High-resolution  */
 
+    // Bda->VGAFlags;
+    // Bda->CrtModeControl;
+    // Bda->CrtColorPaletteMask;
+
     /* Set the start address in the CRTC */
     IOWriteB(VGA_CRTC_INDEX, VGA_CRTC_START_ADDR_LOW_REG);
     IOWriteB(VGA_CRTC_DATA , LOBYTE(Bda->VideoPageOffset));
@@ -2885,6 +2893,35 @@ VOID WINAPI VidBiosVideoService(LPWORD Stack)
                     break;
                 }
 
+                /* Toggle Intensity/Blinking Bit */
+                case 0x03:
+                {
+                    /* Read the old AC mode control register value */
+                    BYTE VgaAcControlReg;
+                    IOWriteB(VGA_AC_INDEX, VGA_AC_CONTROL_REG);
+                    VgaAcControlReg = IOReadB(VGA_AC_READ);
+
+                    /* Toggle the blinking bit and write the new value */
+                    if (getBL())
+                    {
+                        VgaAcControlReg |= VGA_AC_CONTROL_BLINK;
+                        Bda->CrtModeControl |= (1 << 5);
+                    }
+                    else
+                    {
+                        VgaAcControlReg &= ~VGA_AC_CONTROL_BLINK;
+                        Bda->CrtModeControl &= ~(1 << 5);
+                    }
+
+                    IOWriteB(VGA_AC_INDEX, VGA_AC_CONTROL_REG);
+                    IOWriteB(VGA_AC_WRITE, VgaAcControlReg);
+
+                    /* Enable screen and disable palette access */
+                    IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
+                    IOWriteB(VGA_AC_INDEX, 0x20);
+                    break;
+                }
+
                 /* Get Single Palette Register */
                 case 0x07:
                 {
@@ -3223,18 +3260,73 @@ VOID WINAPI VidBiosVideoService(LPWORD Stack)
             switch (getAL())
             {
                 case 0x00: /* Get Display combination code */
-                   setAX(MAKEWORD(0x1A, 0x1A));
-                   setBX(MAKEWORD(0x08, 0x00)); /* VGA w/ color analog display */
-                   break;
+                {
+                    setBL(Bda->VGADccIDActive);
+                    setBH(0x00); // No alternate display
+
+                    /* Return success */
+                    setAL(0x1A);
+                    break;
+                }
                 case 0x01: /* Set Display combination code */
-                   DPRINT1("Set Display combination code - Unsupported\n");
-                   break;
+                {
+                    DPRINT1("Set Display combination code - Unsupported\n");
+                    break;
+                }
                 default:
-                   break;
+                    break;
             }
             break;
         }
 
+        /* Functionality/State Information (VGA) */
+        case 0x1B:
+        {
+            PVGA_DYNAMIC_FUNC_TABLE Table = SEG_OFF_TO_PTR(getES(), getDI());
+
+            /* Check for only supported subfunction */
+            if (getBX() != 0x0000)
+            {
+                DPRINT1("INT 10h, AH=1Bh, unsupported subfunction 0x%04x\n", getBX());
+                break;
+            }
+
+            /* Fill the VGA dynamic functionality table with our information */
+
+            Table->StaticFuncTablePtr = MAKELONG(VIDEO_STATE_INFO_OFFSET, VIDEO_BIOS_DATA_SEG);
+
+            Table->VideoMode       = Bda->VideoMode;
+            Table->ScreenColumns   = Bda->ScreenColumns;
+            Table->VideoPageSize   = Bda->VideoPageSize;
+            Table->VideoPageOffset = Bda->VideoPageOffset;
+            RtlCopyMemory(Table->CursorPosition, Bda->CursorPosition, sizeof(Bda->CursorPosition));
+            Table->CursorEndLine   = Bda->CursorEndLine;
+            Table->CursorStartLine = Bda->CursorStartLine;
+            Table->VideoPage       = Bda->VideoPage;
+            Table->CrtBasePort     = Bda->CrtBasePort;
+            Table->CrtModeControl  = Bda->CrtModeControl;
+            Table->CrtColorPaletteMask = Bda->CrtColorPaletteMask;
+            Table->ScreenRows      = Bda->ScreenRows;
+            Table->CharacterHeight = Bda->CharacterHeight;
+
+            Table->VGADccIDActive    = Bda->VGADccIDActive;
+            Table->VGADccIDAlternate = 0x00; // No alternate display
+            // Table->CurrModeSupportedColorsNum;
+            // Table->CurrModeSupportedPagesNum;
+            // Table->Scanlines;
+            // Table->PrimaryCharTable;
+            // Table->SecondaryCharTable;
+            // Table->VGAFlags;
+            Table->VGAAvailMemory = (Bda->VGAOptions & 0x60) >> 5;
+            // Table->VGASavePtrStateFlags;
+            // Table->VGADispInfo;
+            UNIMPLEMENTED;
+
+            /* Return success */
+            setAL(0x1B);
+            break;
+        }
+
         default:
         {
             DPRINT1("BIOS Function INT 10h, AH = 0x%02X, AL = 0x%02X, BH = 0x%02X NOT IMPLEMENTED\n",
@@ -3287,7 +3379,19 @@ BOOLEAN VidBiosInitialize(VOID)
     ((PULONG)BaseAddress)[0x42] = (ULONG)NULL; // Relocated Default INT 10h Video Services
     ((PULONG)BaseAddress)[0x6D] = (ULONG)NULL; // Video BIOS Entry Point
 
-    /* Fill the tables */
+    /* Initialize the VGA static function table */
+    VgaStaticFuncTable = SEG_OFF_TO_PTR(VIDEO_BIOS_DATA_SEG, VIDEO_STATE_INFO_OFFSET);
+    RtlZeroMemory(VgaStaticFuncTable, sizeof(*VgaStaticFuncTable));
+    VgaStaticFuncTable->SupportedModes[0] = 0xFF; // Modes 0x00 to 0x07 supported
+    VgaStaticFuncTable->SupportedModes[1] = 0xFF; // Modes 0x08 to 0x0F supported
+    VgaStaticFuncTable->SupportedModes[2] = 0x0F; // Modes 0x10 to 0x13 supported
+    VgaStaticFuncTable->SupportedScanlines   = 0x07; // Scanlines 200, 350 and 400 supported
+    VgaStaticFuncTable->TextCharBlocksNumber = 0;
+    VgaStaticFuncTable->MaxActiveTextCharBlocksNumber = 0;
+    VgaStaticFuncTable->VGAFuncSupportFlags = 0x0CFD; // See: http://www.ctyme.com/intr/rb-0221.htm#Table46
+    VgaStaticFuncTable->VGASavePtrFuncFlags = 0x18;   // See: http://www.ctyme.com/intr/rb-0221.htm#Table47
+
+    /* Fill the font tables */
     RtlMoveMemory(SEG_OFF_TO_PTR(VIDEO_BIOS_DATA_SEG, FONT_8x8_OFFSET),
                   Font8x8, sizeof(Font8x8));
     RtlMoveMemory(SEG_OFF_TO_PTR(VIDEO_BIOS_DATA_SEG, FONT_8x16_OFFSET),
@@ -3307,6 +3411,10 @@ BOOLEAN VidBiosInitialize(VOID)
     //   (that should be done here, or maybe in VGA ??)
     //
 
+    Bda->CrtModeControl      = 0x00;
+    Bda->CrtColorPaletteMask = 0x00;
+    Bda->VGADccIDActive = 0x08; // VGA w/ color analog active display
+
     /* Set the default video mode */
     VidBiosSetVideoMode(BIOS_DEFAULT_VIDEO_MODE);
 
index 6c80227..1058742 100644 (file)
@@ -29,6 +29,8 @@
 #define FONT_8x16_OFFSET        0x0800
 #define FONT_8x14_OFFSET        0x1800
 
+#define VIDEO_STATE_INFO_OFFSET 0x3000 // == 0x1800 + (sizeof(Font8x14) == 0x0E00) + 0x0A00 for padding
+
 typedef enum
 {
     SCROLL_UP,
@@ -37,6 +39,65 @@ typedef enum
     SCROLL_RIGHT
 } SCROLL_DIRECTION;
 
+#pragma pack(push, 1)
+
+typedef struct _VGA_STATIC_FUNC_TABLE
+{
+    BYTE SupportedModes[3];                     // 0x00
+    DWORD Reserved0;                            // 0x03
+    BYTE SupportedScanlines;                    // 0x07
+    BYTE TextCharBlocksNumber;                  // 0x08
+    BYTE MaxActiveTextCharBlocksNumber;         // 0x09
+    WORD VGAFuncSupportFlags;                   // 0x0a
+    WORD Reserved1;                             // 0x0c
+    BYTE VGASavePtrFuncFlags;                   // 0x0e
+    BYTE Reserved2;                             // 0x0f
+} VGA_STATIC_FUNC_TABLE, *PVGA_STATIC_FUNC_TABLE;
+
+typedef struct _VGA_DYNAMIC_FUNC_TABLE
+{
+    DWORD StaticFuncTablePtr;                   // 0x00
+
+    /*
+     * The following fields follow the same order as in the BDA,
+     * from offset 0x49 up to offset 0x66...
+     */
+    BYTE VideoMode;                             // 0x04
+    WORD ScreenColumns;                         // 0x05
+    WORD VideoPageSize;                         // 0x07
+    WORD VideoPageOffset;                       // 0x09
+    WORD CursorPosition[BIOS_MAX_PAGES];        // 0x0b
+    BYTE CursorEndLine;                         // 0x1b
+    BYTE CursorStartLine;                       // 0x1c
+    BYTE VideoPage;                             // 0x1d
+    WORD CrtBasePort;                           // 0x1e
+    BYTE CrtModeControl;                        // 0x20
+    BYTE CrtColorPaletteMask;                   // 0x21
+    /* ... and offsets 0x84 and 0x85. */
+    BYTE ScreenRows;                            // 0x22
+    WORD CharacterHeight;                       // 0x23
+
+    BYTE VGADccIDActive;                        // 0x25
+    BYTE VGADccIDAlternate;                     // 0x26
+    WORD CurrModeSupportedColorsNum;            // 0x27
+    BYTE CurrModeSupportedPagesNum;             // 0x29
+    BYTE Scanlines;                             // 0x2a
+    BYTE PrimaryCharTable;                      // 0x2b
+    BYTE SecondaryCharTable;                    // 0x2c
+
+    /* Contains part of information from BDA::VGAFlags (offset 0x89) */
+    BYTE VGAFlags;                              // 0x2d
+
+    BYTE Reserved0[3];                          // 0x2e
+    BYTE VGAAvailMemory;                        // 0x31
+    BYTE VGASavePtrStateFlags;                  // 0x32
+    BYTE VGADispInfo;                           // 0x33
+
+    BYTE Reserved1[12];                         // 0x34 - 0x40
+} VGA_DYNAMIC_FUNC_TABLE, *PVGA_DYNAMIC_FUNC_TABLE;
+
+#pragma pack(pop)
+
 /* FUNCTIONS ******************************************************************/
 
 VOID VidBiosSyncCursorPosition(VOID);