Use 8 bit mode if available
This was not previously done because the palette was not correctly set up, and QEMU gave incorrect colors. The palette setup function now falls back to the standard BIOS function if the VESA BIOS function fails, which resolves the issue with QEMU. The mode selection logic now favors 8 bit color if the tile set is compatible. Using 8 bit mode means fewer writes to memory and fewer uses of the BIOS window function.
This commit is contained in:
committed by
Pasi Kallinen
parent
c911446188
commit
c0d1c4efb7
@@ -788,8 +788,19 @@ vesa_Init(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
vesa_mode = 0xFFFF; /* might want an 8 bit mode after loading tiles */
|
||||
vesa_detect();
|
||||
if (vesa_mode == 0xFFFF) {
|
||||
vesa_detect();
|
||||
raw_printf("Reverting to TTY mode, no VESA mode available.",
|
||||
tilefailure);
|
||||
wait_synch();
|
||||
iflags.usevga = 0;
|
||||
iflags.tile_view = FALSE;
|
||||
iflags.over_view = FALSE;
|
||||
CO = 80;
|
||||
LI = 25;
|
||||
/* clear_screen() */ /* not vesa_clear_screen() */
|
||||
return;
|
||||
}
|
||||
vesa_SwitchMode(vesa_mode);
|
||||
windowprocs.win_cliparound = vesa_cliparound;
|
||||
@@ -813,7 +824,7 @@ vesa_Init(void)
|
||||
*
|
||||
* If mode == MODETEXT (0x03), then the card is placed into text
|
||||
* mode. Otherwise, the card is placed in the mode selected by
|
||||
* vesa_detect. Supported modes are those with packed 8 bit pixels.
|
||||
* vesa_detect.
|
||||
*
|
||||
*/
|
||||
static void
|
||||
@@ -910,6 +921,7 @@ vesa_detect()
|
||||
dosmemput(&vbe_info, sizeof(vbe_info), vbe_info_seg * 16L);
|
||||
|
||||
/* Request VESA BIOS information */
|
||||
memset(®s, 0, sizeof(regs));
|
||||
regs.x.ax = 0x4F00;
|
||||
regs.x.di = 0;
|
||||
regs.x.es = vbe_info_seg;
|
||||
@@ -928,7 +940,10 @@ vesa_detect()
|
||||
+ (vbe_info.VideoModePtr & 0xFFFF);
|
||||
|
||||
/* Scan the mode list for an acceptable mode */
|
||||
vesa_mode = vesa_FindMode(mode_addr, 32);
|
||||
if (get_palette() != NULL)
|
||||
vesa_mode = vesa_FindMode(mode_addr, 8);
|
||||
if (vesa_mode == 0xFFFF)
|
||||
vesa_mode = vesa_FindMode(mode_addr, 32);
|
||||
if (vesa_mode == 0xFFFF)
|
||||
vesa_mode = vesa_FindMode(mode_addr, 24);
|
||||
if (vesa_mode == 0xFFFF)
|
||||
@@ -1271,13 +1286,10 @@ static boolean
|
||||
vesa_SetHardPalette(palette)
|
||||
const struct Pixel *palette;
|
||||
{
|
||||
const struct Pixel *p = palette;
|
||||
int palette_sel = -1; /* custodial */
|
||||
int palette_seg;
|
||||
unsigned long palette_ptr;
|
||||
unsigned char p2[1024];
|
||||
unsigned i, shift;
|
||||
unsigned char r, g, b;
|
||||
unsigned long color;
|
||||
__dpmi_regs regs;
|
||||
|
||||
palette_seg = __dpmi_allocate_dos_memory( 1024 / 16, &palette_sel);
|
||||
@@ -1297,36 +1309,23 @@ const struct Pixel *palette;
|
||||
shift = 8 - regs.h.bh;
|
||||
}
|
||||
|
||||
/* First, try the VESA palette function */
|
||||
/* Set the tile set and text colors */
|
||||
palette_ptr = palette_seg * 16L;
|
||||
#ifdef USE_TILES
|
||||
for (i = 0; i < FIRST_TEXT_COLOR; ++i) {
|
||||
r = p->r >> shift;
|
||||
g = p->g >> shift;
|
||||
b = p->b >> shift;
|
||||
color = ((unsigned long) r << 16)
|
||||
| ((unsigned long) g << 8)
|
||||
| ((unsigned long) b << 0);
|
||||
_farpokel(_dos_ds, palette_ptr, color);
|
||||
palette_ptr += 4;
|
||||
++p;
|
||||
p2[i*4 + 0] = palette[i].b >> shift;
|
||||
p2[i*4 + 1] = palette[i].g >> shift;
|
||||
p2[i*4 + 2] = palette[i].r >> shift;
|
||||
}
|
||||
#else
|
||||
palette_ptr += FIRST_TEXT_COLOR * 4;
|
||||
#endif
|
||||
p = defpalette;
|
||||
for (i = FIRST_TEXT_COLOR; i < 256; ++i) {
|
||||
r = p->r >> shift;
|
||||
g = p->g >> shift;
|
||||
b = p->b >> shift;
|
||||
color = ((unsigned long) r << 16)
|
||||
| ((unsigned long) g << 8)
|
||||
| ((unsigned long) b << 0);
|
||||
_farpokel(_dos_ds, palette_ptr, color);
|
||||
palette_ptr += 4;
|
||||
++p;
|
||||
p2[i*4 + 0] = defpalette[i-FIRST_TEXT_COLOR].b >> shift;
|
||||
p2[i*4 + 1] = defpalette[i-FIRST_TEXT_COLOR].g >> shift;
|
||||
p2[i*4 + 2] = defpalette[i-FIRST_TEXT_COLOR].r >> shift;
|
||||
}
|
||||
|
||||
/* Call the BIOS */
|
||||
dosmemput(p2, 256*4, palette_seg*16L);
|
||||
memset(®s, 0, sizeof(regs));
|
||||
regs.x.ax = 0x4F09;
|
||||
regs.h.bl = 0;
|
||||
@@ -1336,6 +1335,33 @@ const struct Pixel *palette;
|
||||
regs.x.es = palette_seg;
|
||||
(void) __dpmi_int(VIDEO_BIOS, ®s);
|
||||
|
||||
/* If that didn't work, use the original BIOS function */
|
||||
if (regs.x.ax != 0x004F) {
|
||||
/* Set the tile set and text colors */
|
||||
#ifdef USE_TILES
|
||||
for (i = 0; i < FIRST_TEXT_COLOR; ++i) {
|
||||
p2[i*3 + 0] = palette[i].r >> shift;
|
||||
p2[i*3 + 1] = palette[i].g >> shift;
|
||||
p2[i*3 + 2] = palette[i].b >> shift;
|
||||
}
|
||||
#endif
|
||||
for (i = FIRST_TEXT_COLOR; i < 256; ++i) {
|
||||
p2[i*3 + 0] = defpalette[i-FIRST_TEXT_COLOR].r >> shift;
|
||||
p2[i*3 + 1] = defpalette[i-FIRST_TEXT_COLOR].g >> shift;
|
||||
p2[i*3 + 2] = defpalette[i-FIRST_TEXT_COLOR].b >> shift;
|
||||
}
|
||||
|
||||
/* Call the BIOS */
|
||||
dosmemput(p2, 256*3, palette_seg*16L);
|
||||
memset(®s, 0, sizeof(regs));
|
||||
regs.x.ax = 0x1012;
|
||||
regs.x.cx = 256;
|
||||
regs.x.bx = 0;
|
||||
regs.x.dx = 0;
|
||||
regs.x.es = palette_seg;
|
||||
(void) __dpmi_int(VIDEO_BIOS, ®s);
|
||||
}
|
||||
|
||||
__dpmi_free_dos_memory(palette_sel);
|
||||
return TRUE;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user