- 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
This commit is contained in:
Hermès Bélusca-Maïto 2015-05-24 12:35:29 +00:00
parent d4a0828949
commit 578d9849a0
3 changed files with 184 additions and 14 deletions

View 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

View 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);

View 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);