VOID VgaZeroVideoMemory( PHW_DEVICE_EXTENSION HwDeviceExtension ) /*++ Routine Description: This routine zeros the first 256K on the VGA. Arguments: HwDeviceExtension - Pointer to the miniport driver's device extension. Return Value: None. --*/ { UCHAR temp; // // Map font buffer at A0000 // VgaInterpretCmdStream(HwDeviceExtension, EnableA000Data); // // Enable all planes. // VideoPortWritePortUchar(HwDeviceExtension->IOAddress + SEQ_ADDRESS_PORT, IND_MAP_MASK); temp = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + SEQ_DATA_PORT) | (UCHAR)0x0F; VideoPortWritePortUchar(HwDeviceExtension->IOAddress + SEQ_DATA_PORT, temp); // // Zero the memory. // VideoPortZeroDeviceMemory(HwDeviceExtension->VideoMemoryAddress, 0xFFFF); VgaInterpretCmdStream(HwDeviceExtension, DisableA000Color); } // VgaZeroVideoMemory(...)
/* * @implemented */ VOID NTAPI VidResetDisplay(IN BOOLEAN HalReset) { /* Clear the current position */ curr_x = 0; curr_y = 0; /* Clear the screen with HAL if we were asked to */ if (HalReset) HalResetDisplay(); /* Re-initialize the VGA Display */ VgaInterpretCmdStream(AT_Initialization); /* Re-initialize the palette and fill the screen black */ InitializePalette(); VidSolidColorFill(0, 0, 639, 479, 0); }
VP_STATUS VgaSetMode( PHW_DEVICE_EXTENSION HwDeviceExtension, PVIDEO_MODE Mode, ULONG ModeSize ) /*++ Routine Description: This routine sets the vga into the requested mode. Arguments: HwDeviceExtension - Pointer to the miniport driver's device extension. Mode - Pointer to the structure containing the information about the font to be set. ModeSize - Length of the input buffer supplied by the user. Return Value: ERROR_INSUFFICIENT_BUFFER if the input buffer was not large enough for the input data. ERROR_INVALID_PARAMETER if the mode number is invalid. NO_ERROR if the operation completed successfully. --*/ { PVIDEOMODE pRequestedMode; VP_STATUS status; #ifdef INT10_MODE_SET VIDEO_X86_BIOS_ARGUMENTS biosArguments; #endif // // Check if the size of the data in the input buffer is large enough. // if (ModeSize < sizeof(VIDEO_MODE)) { return ERROR_INSUFFICIENT_BUFFER; } // // Extract the clear memory bit. // if (Mode->RequestedMode & VIDEO_MODE_NO_ZERO_MEMORY) { Mode->RequestedMode &= ~VIDEO_MODE_NO_ZERO_MEMORY; } else { VgaZeroVideoMemory(HwDeviceExtension); } // // Check to see if we are requesting a valid mode // if ( (Mode->RequestedMode >= NumVideoModes) || (!ModesVGA[Mode->RequestedMode].ValidMode) ) { return ERROR_INVALID_PARAMETER; } pRequestedMode = &ModesVGA[Mode->RequestedMode]; #ifdef INT10_MODE_SET VideoPortZeroMemory(&biosArguments, sizeof(VIDEO_X86_BIOS_ARGUMENTS)); biosArguments.Ebx = pRequestedMode->Int10ModeNumber; if (biosArguments.Ebx != 0) { biosArguments.Eax = 0x6f05; status = VideoPortInt10(HwDeviceExtension, &biosArguments); if (status != NO_ERROR) { return status; } } #endif // // Call the interpreter // VgaInterpretCmdStream(HwDeviceExtension, pRequestedMode->CmdStrings[HwDeviceExtension->AdapterType]); #ifdef INT10_MODE_SET { UCHAR temp; UCHAR dummy; UCHAR bIsColor; if (!(pRequestedMode->fbType & VIDEO_MODE_GRAPHICS)) { // // Fix to make sure we always set the colors in text mode to be // intensity, and not flashing // For this zero out the Mode Control Regsiter bit 3 (index 0x10 // of the Attribute controller). // if (VideoPortReadPortUchar(HwDeviceExtension->IOAddress + MISC_OUTPUT_REG_READ_PORT) & 0x01) { bIsColor = TRUE; } else { bIsColor = FALSE; } if (bIsColor) { dummy = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + INPUT_STATUS_1_COLOR); } else { dummy = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + INPUT_STATUS_1_MONO); } VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ATT_ADDRESS_PORT, (0x10 | VIDEO_ENABLE)); temp = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ATT_DATA_READ_PORT); temp &= 0xF7; if (bIsColor) { dummy = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + INPUT_STATUS_1_COLOR); } else { dummy = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + INPUT_STATUS_1_MONO); } VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ATT_ADDRESS_PORT, (0x10 | VIDEO_ENABLE)); VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ATT_DATA_WRITE_PORT, temp); } } #endif // // Update the location of the physical frame buffer within video memory. // HwDeviceExtension->PhysicalFrameLength = MemoryMaps[pRequestedMode->MemMap].MaxSize; HwDeviceExtension->PhysicalFrameBase.LowPart = MemoryMaps[pRequestedMode->MemMap].Start; // // Store the new mode value. // HwDeviceExtension->ModeIndex = Mode->RequestedMode; HwDeviceExtension->CurrentMode = pRequestedMode; return NO_ERROR; } //end VgaSetMode()
VP_STATUS VgaSetMode( PHW_DEVICE_EXTENSION HwDeviceExtension, PVIDEO_MODE Mode, ULONG ModeSize, // eVb: 2.2 [SET MODE] - Add new output parameter for framebuffer update functionality PULONG PhysPtrChange // eVb: 2.2 [END] ) /*++ Routine Description: This routine sets the vga into the requested mode. Arguments: HwDeviceExtension - Pointer to the miniport driver's device extension. Mode - Pointer to the structure containing the information about the font to be set. ModeSize - Length of the input buffer supplied by the user. Return Value: ERROR_INSUFFICIENT_BUFFER if the input buffer was not large enough for the input data. ERROR_INVALID_PARAMETER if the mode number is invalid. NO_ERROR if the operation completed successfully. --*/ { PVIDEOMODE pRequestedMode; VP_STATUS status; ULONG RequestedModeNum; // eVb: 2.3 [SET MODE] - Add new output parameter for framebuffer update functionality *PhysPtrChange = FALSE; // eVb: 2.3 [END] // // Check if the size of the data in the input buffer is large enough. // if (ModeSize < sizeof(VIDEO_MODE)) { return ERROR_INSUFFICIENT_BUFFER; } // // Extract the clear memory, and map linear bits. // RequestedModeNum = Mode->RequestedMode & ~(VIDEO_MODE_NO_ZERO_MEMORY | VIDEO_MODE_MAP_MEM_LINEAR); if (!(Mode->RequestedMode & VIDEO_MODE_NO_ZERO_MEMORY)) { #if defined(_X86_) VgaZeroVideoMemory(HwDeviceExtension); #endif } // // Check to see if we are requesting a valid mode // // eVb: 2.4 [CIRRUS] - Remove Cirrus-specific check for valid mode if ( (RequestedModeNum >= NumVideoModes) ) // eVb: 2.4 [END] { VideoDebugPrint((0, "Invalide Mode Number = %d!\n", RequestedModeNum)); return ERROR_INVALID_PARAMETER; } VideoDebugPrint((2, "Attempting to set mode %d\n", RequestedModeNum)); // eVb: 2.5 [VBE] - Use dynamic VBE mode list instead of hard-coded VGA list pRequestedMode = &VgaModeList[RequestedModeNum]; // eVb: 2.5 [END] VideoDebugPrint((2, "Info on Requested Mode:\n" "\tResolution: %dx%d\n", pRequestedMode->hres, pRequestedMode->vres )); // // VESA BIOS mode switch // // eVb: 2.6 [VBE] - VBE Mode Switch Support status = VbeSetMode(HwDeviceExtension, pRequestedMode, PhysPtrChange); if (status == ERROR_INVALID_FUNCTION) { // // VGA mode switch // if (!pRequestedMode->CmdStream) return ERROR_INVALID_FUNCTION; if (!VgaInterpretCmdStream(HwDeviceExtension, pRequestedMode->CmdStream)) return ERROR_INVALID_FUNCTION; goto Cleanup; } else if (status != NO_ERROR) return status; // eVb: 2.6 [END] // eVb: 2.7 [MODE-X] - Windows VGA Miniport Supports Mode-X, we should too // // ModeX check // if (pRequestedMode->hres == 320) { VideoPortDebugPrint(0, "ModeX not support!!!\n"); return ERROR_INVALID_PARAMETER; } // eVb: 2.7 [END] // // Text mode check // if (!(pRequestedMode->fbType & VIDEO_MODE_GRAPHICS)) { // eVb: 2.8 [TODO] - This code path is not implemented yet VideoPortDebugPrint(0, "Text-mode not support!!!\n"); return ERROR_INVALID_PARAMETER; // eVb: 2.8 [END] } Cleanup: // // Update the location of the physical frame buffer within video memory. // // eVb: 2.9 [VBE] - Linear and banked support is unified in VGA, unlike Cirrus HwDeviceExtension->PhysicalVideoMemoryBase.LowPart = pRequestedMode->PhysBase; HwDeviceExtension->PhysicalVideoMemoryLength = pRequestedMode->PhysSize; HwDeviceExtension->PhysicalFrameLength = pRequestedMode->FrameBufferSize; HwDeviceExtension->PhysicalFrameOffset.LowPart = pRequestedMode->FrameBufferBase; // eVb: 2.9 [END] // // Store the new mode value. // HwDeviceExtension->CurrentMode = pRequestedMode; HwDeviceExtension->ModeIndex = Mode->RequestedMode; return NO_ERROR; } //end VgaSetMode()
VP_STATUS VgaSetMode( PHW_DEVICE_EXTENSION HwDeviceExtension, PVIDEO_MODE Mode, ULONG ModeSize ) /*++ Routine Description: This routine sets the VGA into the requested mode. Arguments: HwDeviceExtension - Pointer to the miniport driver's device extension. Mode - Pointer to the structure containing the information about the font to be set. ModeSize - Length of the input buffer supplied by the user. Return Value: ERROR_INSUFFICIENT_BUFFER if the input buffer was not large enough for the input data. ERROR_INVALID_PARAMETER if the mode number is invalid. NO_ERROR if the operation completed successfully. --*/ { PVIDEOMODE pRequestedMode; VP_STATUS status; // // Check if the size of the data in the input buffer is large enough. // if (ModeSize < sizeof(VIDEO_MODE)) { return ERROR_INSUFFICIENT_BUFFER; } // // Extract the clear memory bit. // if (Mode->RequestedMode & VIDEO_MODE_NO_ZERO_MEMORY) { Mode->RequestedMode &= ~VIDEO_MODE_NO_ZERO_MEMORY; } else { VgaZeroVideoMemory(HwDeviceExtension); } // // Check to see if we are requesting a valid mode // if ((Mode->RequestedMode >= NUM_VIDEO_MODES) || (!ModesVGA[Mode->RequestedMode].ValidMode)) { VideoDebugPrint((0,"AVGA.sys: VGASetMode - ERROR_INVALID_PARAMETER.\n")); return ERROR_INVALID_PARAMETER; } pRequestedMode = &ModesVGA[Mode->RequestedMode]; HwDeviceExtension->ModeIndex = Mode->RequestedMode; // // Store the new mode value. // HwDeviceExtension->CurrentMode = pRequestedMode; #ifdef INT10_MODE_SET { VIDEO_X86_BIOS_ARGUMENTS biosArguments; UCHAR temp; UCHAR dummy; UCHAR bIsColor; /*********************************************************************** *** There appears to be a problem with some application *** *** which reset the first 16 palette registers. *** *** Since the palette is not reset when going to and *** *** from text modes by doing a set mode (instead of *** *** the hardware save restore), some colors might not *** *** appear as expected in the text modes. The bios *** *** calls seem to reload the palette so Andre Vachon *** *** suggested that we implement an Int10 mode set for the *** *** text modes. *** *** To accomplish this, we need to hard code the first *** *** three modes in modeset.h in the following switch. *** *** If more text modes are added to modeset.h, their *** *** index must be added to this switch statement. *** ***********************************************************************/ VideoPortZeroMemory(&biosArguments, sizeof(VIDEO_X86_BIOS_ARGUMENTS)); switch (Mode->RequestedMode) { case 0: // 720x400 /*********************************************************************** *** Prepare the card for the VGA mode 3+ instead of the CGA mode 3 *** ***********************************************************************/ biosArguments.Eax = 0x1202; // Select Scan line number biosArguments.Ebx = 0x0030; // to be 400 scan lines status = VideoPortInt10(HwDeviceExtension, &biosArguments); /*********************************************************************** *** Set the video mode to BIOS mode 3. *** ***********************************************************************/ VideoPortZeroMemory(&biosArguments, sizeof(VIDEO_X86_BIOS_ARGUMENTS)); biosArguments.Eax = 0x03; // bios mode 0x03 status = VideoPortInt10(HwDeviceExtension, &biosArguments); break; case 1: // 640x350 /*********************************************************************** *** Prepare the card for the EGA mode 3* instead of the CGA mode 3 *** ***********************************************************************/ biosArguments.Eax = 0x1201; // Select Scan line number biosArguments.Ebx = 0x0030; // to be 350 scan lines status = VideoPortInt10(HwDeviceExtension, &biosArguments); /*********************************************************************** *** Set the video mode to BIOS mode 3. *** ***********************************************************************/ VideoPortZeroMemory(&biosArguments, sizeof(VIDEO_X86_BIOS_ARGUMENTS)); biosArguments.Eax = 0x03; // bios mode 0x03 status = VideoPortInt10(HwDeviceExtension, &biosArguments); break; default: // all graphics modes are // handled by the default case biosArguments.Eax = pRequestedMode->Int10ModeNumber; status = VideoPortInt10(HwDeviceExtension, &biosArguments); break; } if (status != NO_ERROR) { return status; } // // Fix to get 640x350 text mode // if (!(pRequestedMode->fbType & VIDEO_MODE_GRAPHICS)) { // if ((pRequestedMode->hres == 640) && // (pRequestedMode->vres == 350)) { // // VgaInterpretCmdStream(HwDeviceExtension, VGA_TEXT_1); // // } else { // // Fix to make sure we always set the colors in text mode to be // intensity, and not flashing // For this zero out the Mode Control Regsiter bit 3 (index 0x10 // of the Attribute controller). // if (VideoPortReadPortUchar(HwDeviceExtension->IOAddress + MISC_OUTPUT_REG_READ_PORT) & 0x01) { bIsColor = TRUE; } else { bIsColor = FALSE; } if (bIsColor) { dummy = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + INPUT_STATUS_1_COLOR); } else { dummy = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + INPUT_STATUS_1_MONO); } VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ATT_ADDRESS_PORT, (0x10 | VIDEO_ENABLE)); temp = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ATT_DATA_READ_PORT); temp &= 0xF7; if (bIsColor) { dummy = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + INPUT_STATUS_1_COLOR); } else { dummy = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + INPUT_STATUS_1_MONO); } VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ATT_ADDRESS_PORT, (0x10 | VIDEO_ENABLE)); VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ATT_DATA_WRITE_PORT, temp); // } } } #else VgaInterpretCmdStream(HwDeviceExtension, pRequestedMode->CmdStrings); #endif // // Update the location of the physical frame buffer within video memory. // HwDeviceExtension->PhysicalFrameLength = MemoryMaps[pRequestedMode->MemMap].MaxSize; HwDeviceExtension->PhysicalFrameBase.LowPart = MemoryMaps[pRequestedMode->MemMap].Start; return NO_ERROR; } // end VgaSetMode()
VP_STATUS VgaSetMode( PHW_DEVICE_EXTENSION HwDeviceExtension, PVIDEO_MODE Mode, ULONG ModeSize ) /*++ Routine Description: This routine sets the VGA into the requested mode. Arguments: HwDeviceExtension - Pointer to the miniport driver's device extension. Mode - Pointer to the structure containing the information about the font to be set. ModeSize - Length of the input buffer supplied by the user. Return Value: ERROR_INSUFFICIENT_BUFFER if the input buffer was not large enough for the input data. ERROR_INVALID_PARAMETER if the mode number is invalid. NO_ERROR if the operation completed successfully. --*/ { PVIDEOMODE pRequestedMode; PUSHORT pusCmdStream; // // Check if the size of the data in the input buffer is large enough. // if (ModeSize < sizeof(VIDEO_MODE)) { return ERROR_INSUFFICIENT_BUFFER; } // // Extract the clear memory bit. // if (Mode->RequestedMode & VIDEO_MODE_NO_ZERO_MEMORY) { Mode->RequestedMode &= ~VIDEO_MODE_NO_ZERO_MEMORY; } else { VgaZeroVideoMemory(HwDeviceExtension); } // // Check to see if we are requesting a vlid mode // if ( (Mode->RequestedMode >= NumVideoModes) || (!ModesVGA[Mode->RequestedMode].ValidMode) ) { return ERROR_INVALID_PARAMETER; } pRequestedMode = &ModesVGA[Mode->RequestedMode]; // // Set the mode using the table // if (HwDeviceExtension->AdapterMemorySize == 0x100000) { VgaInterpretCmdStream(HwDeviceExtension, pRequestedMode->CmdStrings1M); // // Support 256 color modes by stretching the scan lines. // if (pRequestedMode->pStretchScan1M) { VgaInterpretCmdStream(HwDeviceExtension, pRequestedMode->pStretchScan1M); } } else { // // if (HwDeviceExtension->AdapterMemorySize == 0x80000) { // VgaInterpretCmdStream(HwDeviceExtension, pRequestedMode->CmdStrings512K); // // Support 256 color modes by stretching the scan lines. // if (pRequestedMode->pStretchScan512K) { VgaInterpretCmdStream(HwDeviceExtension, pRequestedMode->pStretchScan512K); } } // // Update the location of the physical frame buffer within video memory. // HwDeviceExtension->PhysicalFrameLength = MemoryMaps[pRequestedMode->MemMap].MaxSize; HwDeviceExtension->PhysicalFrameBase.LowPart = MemoryMaps[pRequestedMode->MemMap].Start; // // Store the new mode value. // HwDeviceExtension->CurrentMode = pRequestedMode; HwDeviceExtension->ModeIndex = Mode->RequestedMode; return NO_ERROR; } //end VgaSetMode()
/* * @implemented */ BOOLEAN NTAPI VidInitialize(IN BOOLEAN SetMode) { ULONG_PTR Context = 0; PHYSICAL_ADDRESS TranslatedAddress; PHYSICAL_ADDRESS NullAddress = {{0, 0}}, VgaAddress; ULONG AddressSpace = 1; BOOLEAN Result; ULONG_PTR Base; /* Make sure that we have a bus translation function */ if (!HalFindBusAddressTranslation) return FALSE; /* Get the VGA Register address */ Result = HalFindBusAddressTranslation(NullAddress, &AddressSpace, &TranslatedAddress, &Context, TRUE); if (!Result) return FALSE; /* Loop trying to find posssible VGA base addresses */ while (TRUE) { /* See if this is I/O Space, which we need to map */ if (!AddressSpace) { /* Map it */ Base = (ULONG_PTR)MmMapIoSpace(TranslatedAddress, 0x400, MmNonCached); } else { /* The base is the translated address, no need to map I/O space */ Base = TranslatedAddress.LowPart; } /* Try to see if this is VGA */ VgaRegisterBase = Base; if (VgaIsPresent()) { /* Translate the VGA Memory Address */ VgaAddress.LowPart = 0xA0000; VgaAddress.HighPart = 0; AddressSpace = 0; Result = HalFindBusAddressTranslation(VgaAddress, &AddressSpace, &TranslatedAddress, &Context, FALSE); if (Result) break; /* Try to see if there's any other address */ Result = HalFindBusAddressTranslation(NullAddress, &AddressSpace, &TranslatedAddress, &Context, TRUE); if (!Result) return FALSE; } else { /* It's not, so unmap the I/O space if we mapped it */ if (!AddressSpace) MmUnmapIoSpace((PVOID)VgaRegisterBase, 0x400); } } /* Success! See if this is I/O Space, which we need to map */ if (!AddressSpace) { /* Map it */ Base = (ULONG_PTR)MmMapIoSpace(TranslatedAddress, 0x20000, MmNonCached); } else { /* The base is the translated address, no need to map I/O space */ Base = TranslatedAddress.LowPart; } /* Set the VGA Memory Base */ VgaBase = Base; /* Now check if we have to set the mode */ if (SetMode) { /* Reset the display */ HalResetDisplay(); curr_x = 0; curr_y = 0; /* Initialize it */ VgaInterpretCmdStream(AT_Initialization); } /* VGA is ready */ return TRUE; }