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/vidbi... ============================================================================== --- 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/VG... + * 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; }