diff --git a/reactos/subsystems/mvdm/ntvdm/bios/bios.h b/reactos/subsystems/mvdm/ntvdm/bios/bios.h index f194643b038..be9ef20d176 100644 --- a/reactos/subsystems/mvdm/ntvdm/bios/bios.h +++ b/reactos/subsystems/mvdm/ntvdm/bios/bios.h @@ -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 diff --git a/reactos/subsystems/mvdm/ntvdm/bios/vidbios.c b/reactos/subsystems/mvdm/ntvdm/bios/vidbios.c index 5e4720e8cdd..342c6d6728a 100644 --- a/reactos/subsystems/mvdm/ntvdm/bios/vidbios.c +++ b/reactos/subsystems/mvdm/ntvdm/bios/vidbios.c @@ -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); diff --git a/reactos/subsystems/mvdm/ntvdm/bios/vidbios.h b/reactos/subsystems/mvdm/ntvdm/bios/vidbios.h index 6c802278213..105874290aa 100644 --- a/reactos/subsystems/mvdm/ntvdm/bios/vidbios.h +++ b/reactos/subsystems/mvdm/ntvdm/bios/vidbios.h @@ -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);