Reset the DAC to 6-bit mode before calling the BIOS to set the screen
mode. This works around bugs in at least 2 Intel BIOSes for our subsequent setting of the DAC back to 8-bit mode. The bug caused dark (mostly 1/4-intensity) colors for all except the first setting to a VESA graphics mode (including for settings to the current mode). Remove restoration (with less bits) of the palette in vesa_unload() after resetting the DAC to 6-bit mode. Depend on the BIOS to keep the palette consistent with the DAC for the simpler reset case like we do everywhere else in places that are actually important. Setting the video mode should reset everything to defaults, although we usually don't want that. Even the buggy BIOSes set the DAC to the default 6-bit mode, and set the palette to a default that matches the DAC. We don't undo the reset for most things, but we do undo it for the DAC (more precisely, we change to an 8-bit DAC if possible, and this is the only way that we set to an 8-bit DAC; it is accidental that if the DAC was in 8-bit mode from a previous mode switch then setting it to 8-bit mode is an undo). The buggy BIOSes are confused by our setting of the DAC to 8-bit mode in the "undo" case. They should multiply palette entries by 4 to match, but they actually leave all palette entries except #2 (green) and #248-255 (unused) untouched. Green is mysteriously scaled from 0x2a to 0x6a, and #248-255 are scaled correctly. Our support for the 8-bit DAC had almost no effect except to enable bugs. Syscons barely supports 16 colors, so it doesn't benefit much from having a palette with 16 million colors instead of only 256K. Applications can manage the palette using FBIO_{GET,SET}PALETTE, but the palette managed by this is only used in the less interesting modes (text and non-truecolor graphics modes up to 8 bits wide), and the kernel loses the changes on any mode switch (including to another vt in a different mode).
This commit is contained in:
parent
512e16501e
commit
8a64386a4e
@ -1322,6 +1322,16 @@ vesa_set_mode(video_adapter_t *adp, int mode)
|
||||
#if VESA_DEBUG > 0
|
||||
printf("VESA: about to set a VESA mode...\n");
|
||||
#endif
|
||||
/*
|
||||
* The mode change should reset the palette format to 6 bits, so
|
||||
* we must reset V_ADP_DAC8. Some BIOSes do an incomplete reset
|
||||
* if we call them with an 8-bit palette, so reset directly.
|
||||
*/
|
||||
if (adp->va_flags & V_ADP_DAC8) {
|
||||
vesa_bios_set_dac(6);
|
||||
adp->va_flags &= ~V_ADP_DAC8;
|
||||
}
|
||||
|
||||
/* don't use the linear frame buffer for text modes. XXX */
|
||||
if (!(info.vi_flags & V_INFO_GRAPHICS))
|
||||
info.vi_flags &= ~V_INFO_LINEAR;
|
||||
@ -1331,9 +1341,6 @@ vesa_set_mode(video_adapter_t *adp, int mode)
|
||||
if (vesa_bios_set_mode(mode | 0x8000))
|
||||
return (1);
|
||||
|
||||
/* Palette format is reset by the above VBE function call. */
|
||||
adp->va_flags &= ~V_ADP_DAC8;
|
||||
|
||||
if ((vesa_adp_info->v_flags & V_DAC8) != 0 &&
|
||||
(info.vi_flags & V_INFO_GRAPHICS) != 0 &&
|
||||
vesa_bios_set_dac(8) > 6)
|
||||
@ -1928,7 +1935,6 @@ vesa_load(void)
|
||||
static int
|
||||
vesa_unload(void)
|
||||
{
|
||||
u_char palette[256*3];
|
||||
int error;
|
||||
|
||||
/* if the adapter is currently in a VESA mode, don't unload */
|
||||
@ -1942,10 +1948,8 @@ vesa_unload(void)
|
||||
if ((error = vesa_unload_ioctl()) == 0) {
|
||||
if (vesa_adp != NULL) {
|
||||
if ((vesa_adp->va_flags & V_ADP_DAC8) != 0) {
|
||||
vesa_bios_save_palette(0, 256, palette, 8);
|
||||
vesa_bios_set_dac(6);
|
||||
vesa_adp->va_flags &= ~V_ADP_DAC8;
|
||||
vesa_bios_load_palette(0, 256, palette, 6);
|
||||
}
|
||||
vesa_adp->va_flags &= ~V_ADP_VESA;
|
||||
vidsw[vesa_adp->va_index] = prevvidsw;
|
||||
|
Loading…
Reference in New Issue
Block a user