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:
Ray Chason
2020-01-25 13:38:02 -05:00
committed by Pasi Kallinen
parent c911446188
commit c0d1c4efb7

View File

@@ -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(&regs, 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(&regs, 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, &regs);
/* 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(&regs, 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, &regs);
}
__dpmi_free_dos_memory(palette_sel);
return TRUE;