diff --git a/sys/msdos/vidvesa.c b/sys/msdos/vidvesa.c index 65ae2e845..f1e1848ef 100644 --- a/sys/msdos/vidvesa.c +++ b/sys/msdos/vidvesa.c @@ -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;