Improve VESA mode switching via loader tunable `hint.sc.0.vesa_mode'.
The most notable change is history buffer is fully saved/restored now.
This commit is contained in:
parent
83c4cf226c
commit
f819ca27dd
@ -369,34 +369,7 @@ sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize,
|
|||||||
if ((info.vi_width < xsize*8) || (info.vi_height < ysize*fontsize))
|
if ((info.vi_width < xsize*8) || (info.vi_height < ysize*fontsize))
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
/*
|
if (!sc_support_pixel_mode(&info))
|
||||||
* We currently support the following graphic modes:
|
|
||||||
*
|
|
||||||
* - 4 bpp planar modes whose memory size does not exceed 64K
|
|
||||||
* - 15, 16, 24 and 32 bpp linear modes
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (info.vi_mem_model == V_INFO_MM_PLANAR) {
|
|
||||||
if (info.vi_planes != 4)
|
|
||||||
return ENODEV;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* A memory size >64K requires bank switching to access the entire
|
|
||||||
* screen. XXX
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (info.vi_width * info.vi_height / 8 > info.vi_window_size)
|
|
||||||
return ENODEV;
|
|
||||||
} else if (info.vi_mem_model == V_INFO_MM_DIRECT) {
|
|
||||||
if (!(info.vi_flags & V_INFO_LINEAR) &&
|
|
||||||
(info.vi_depth != 15) && (info.vi_depth != 16) &&
|
|
||||||
(info.vi_depth != 24) && (info.vi_depth != 32))
|
|
||||||
return ENODEV;
|
|
||||||
} else if (info.vi_mem_model == V_INFO_MM_PACKED) {
|
|
||||||
if (!(info.vi_flags & V_INFO_LINEAR) &&
|
|
||||||
(info.vi_depth != 8))
|
|
||||||
return ENODEV;
|
|
||||||
} else
|
|
||||||
return ENODEV;
|
return ENODEV;
|
||||||
|
|
||||||
/* stop screen saver, etc */
|
/* stop screen saver, etc */
|
||||||
@ -472,6 +445,48 @@ sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize,
|
|||||||
#endif /* SC_PIXEL_MODE */
|
#endif /* SC_PIXEL_MODE */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
sc_support_pixel_mode(void *arg)
|
||||||
|
{
|
||||||
|
#ifdef SC_PIXEL_MODE
|
||||||
|
video_info_t *info = arg;
|
||||||
|
|
||||||
|
if ((info->vi_flags & V_INFO_GRAPHICS) == 0)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We currently support the following graphic modes:
|
||||||
|
*
|
||||||
|
* - 4 bpp planar modes whose memory size does not exceed 64K
|
||||||
|
* - 15, 16, 24 and 32 bpp linear modes
|
||||||
|
*/
|
||||||
|
switch (info->vi_mem_model) {
|
||||||
|
case V_INFO_MM_PLANAR:
|
||||||
|
if (info->vi_planes != 4)
|
||||||
|
break;
|
||||||
|
/*
|
||||||
|
* A memory size >64K requires bank switching to access
|
||||||
|
* the entire screen. XXX
|
||||||
|
*/
|
||||||
|
if (info->vi_width * info->vi_height / 8 > info->vi_window_size)
|
||||||
|
break;
|
||||||
|
return (1);
|
||||||
|
case V_INFO_MM_DIRECT:
|
||||||
|
if ((info->vi_flags & V_INFO_LINEAR) == 0 &&
|
||||||
|
info->vi_depth != 15 && info->vi_depth != 16 &&
|
||||||
|
info->vi_depth != 24 && info->vi_depth != 32)
|
||||||
|
break;
|
||||||
|
return (1);
|
||||||
|
case V_INFO_MM_PACKED:
|
||||||
|
if ((info->vi_flags & V_INFO_LINEAR) == 0 &&
|
||||||
|
info->vi_depth != 8)
|
||||||
|
break;
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
#define fb_ioctl(a, c, d) \
|
#define fb_ioctl(a, c, d) \
|
||||||
(((a) == NULL) ? ENODEV : \
|
(((a) == NULL) ? ENODEV : \
|
||||||
vidd_ioctl((a), (c), (caddr_t)(d)))
|
vidd_ioctl((a), (c), (caddr_t)(d)))
|
||||||
|
@ -344,35 +344,94 @@ sc_alloc_tty(int index, int devnum)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SC_PIXEL_MODE
|
#ifdef SC_PIXEL_MODE
|
||||||
static int
|
static void
|
||||||
sc_initial_mode(video_adapter_t *adp, int unit)
|
sc_set_vesa_mode(scr_stat *scp, sc_softc_t *sc, int unit)
|
||||||
{
|
{
|
||||||
video_info_t info;
|
video_info_t info;
|
||||||
int depth, vmode;
|
int depth;
|
||||||
int i;
|
int i;
|
||||||
|
int vmode;
|
||||||
|
|
||||||
vmode = 0;
|
vmode = 0;
|
||||||
(void)resource_int_value("sc", unit, "vesa_mode", &vmode);
|
(void)resource_int_value("sc", unit, "vesa_mode", &vmode);
|
||||||
if (vmode < M_VESA_BASE || vmode > M_VESA_MODE_MAX)
|
if (vmode < M_VESA_BASE || vmode > M_VESA_MODE_MAX ||
|
||||||
vmode = 0;
|
vidd_get_info(sc->adp, vmode, &info) != 0 ||
|
||||||
|
!sc_support_pixel_mode(&info))
|
||||||
|
vmode = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the default mode is not supported, search for an available
|
* If the mode is unset or unsupported, search for an available
|
||||||
* 800x600 graphics mode with the highest color depth.
|
* 800x600 graphics mode with the highest color depth.
|
||||||
*/
|
*/
|
||||||
if (vmode == 0 || vidd_get_info(adp, vmode, &info) != 0) {
|
if (vmode == 0) {
|
||||||
depth = vmode = 0;
|
for (depth = 0, i = M_VESA_BASE; i <= M_VESA_MODE_MAX; i++)
|
||||||
for (i = M_VESA_BASE; i <= M_VESA_MODE_MAX; i++)
|
if (vidd_get_info(sc->adp, i, &info) == 0 &&
|
||||||
if (vidd_get_info(adp, i, &info) == 0 &&
|
info.vi_width == 800 && info.vi_height == 600 &&
|
||||||
(info.vi_flags & V_INFO_GRAPHICS) != 0 &&
|
sc_support_pixel_mode(&info) &&
|
||||||
info.vi_width == 800 && info.vi_height == 600 &&
|
info.vi_depth > depth) {
|
||||||
info.vi_depth > depth) {
|
vmode = i;
|
||||||
vmode = i;
|
depth = info.vi_depth;
|
||||||
depth = info.vi_depth;
|
}
|
||||||
}
|
if (vmode == 0)
|
||||||
|
return;
|
||||||
|
vidd_get_info(sc->adp, vmode, &info);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (vmode);
|
#ifndef SC_NO_FONT_LOADING
|
||||||
|
if ((sc->fonts_loaded & FONT_16) == 0)
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
#ifdef DEV_SPLASH
|
||||||
|
if ((sc->flags & SC_SPLASH_SCRN) != 0)
|
||||||
|
splash_term(sc->adp);
|
||||||
|
#endif
|
||||||
|
#ifndef SC_NO_HISTORY
|
||||||
|
if (scp->history != NULL) {
|
||||||
|
sc_vtb_append(&scp->vtb, 0, scp->history,
|
||||||
|
scp->ypos * scp->xsize + scp->xpos);
|
||||||
|
scp->history_pos = sc_vtb_tail(scp->history);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
vidd_set_mode(sc->adp, vmode);
|
||||||
|
scp->status |= (UNKNOWN_MODE | PIXEL_MODE | MOUSE_HIDDEN);
|
||||||
|
scp->status &= ~(GRAPHICS_MODE | MOUSE_VISIBLE);
|
||||||
|
scp->xpixel = info.vi_width;
|
||||||
|
scp->ypixel = info.vi_height;
|
||||||
|
scp->xsize = scp->xpixel / 8;
|
||||||
|
scp->ysize = scp->ypixel / 16;
|
||||||
|
scp->xpos = 0;
|
||||||
|
scp->ypos = scp->ysize - 1;
|
||||||
|
scp->xoff = scp->yoff = 0;
|
||||||
|
#ifndef SC_NO_FONT_LOADING
|
||||||
|
scp->font = sc->font_16;
|
||||||
|
#else
|
||||||
|
scp->font = NULL;
|
||||||
|
#endif
|
||||||
|
scp->font_size = 16;
|
||||||
|
scp->font_width = 8;
|
||||||
|
scp->start = scp->xsize * scp->ysize - 1;
|
||||||
|
scp->end = 0;
|
||||||
|
scp->cursor_pos = scp->cursor_oldpos = scp->xsize * scp->xsize;
|
||||||
|
scp->mode = sc->initial_mode = vmode;
|
||||||
|
#ifndef __sparc64__
|
||||||
|
sc_vtb_init(&scp->scr, VTB_FRAMEBUFFER, scp->xsize, scp->ysize,
|
||||||
|
(void *)sc->adp->va_window, FALSE);
|
||||||
|
#endif
|
||||||
|
sc_alloc_scr_buffer(scp, FALSE, FALSE);
|
||||||
|
sc_init_emulator(scp, NULL);
|
||||||
|
#ifndef SC_NO_CUTPASTE
|
||||||
|
sc_alloc_cut_buffer(scp, FALSE);
|
||||||
|
#endif
|
||||||
|
#ifndef SC_NO_HISTORY
|
||||||
|
sc_alloc_history_buffer(scp, 0, 0, FALSE);
|
||||||
|
#endif
|
||||||
|
sc_set_border(scp, scp->border);
|
||||||
|
sc_set_cursor_image(scp);
|
||||||
|
scp->status &= ~UNKNOWN_MODE;
|
||||||
|
#ifdef DEV_SPLASH
|
||||||
|
if ((sc->flags & SC_SPLASH_SCRN) != 0)
|
||||||
|
splash_init(sc->adp, scsplash_callback, sc);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -381,8 +440,8 @@ sc_attach_unit(int unit, int flags)
|
|||||||
{
|
{
|
||||||
sc_softc_t *sc;
|
sc_softc_t *sc;
|
||||||
scr_stat *scp;
|
scr_stat *scp;
|
||||||
int vc;
|
|
||||||
struct cdev *dev;
|
struct cdev *dev;
|
||||||
|
int vc;
|
||||||
|
|
||||||
flags &= ~SC_KERNEL_CONSOLE;
|
flags &= ~SC_KERNEL_CONSOLE;
|
||||||
|
|
||||||
@ -404,24 +463,8 @@ sc_attach_unit(int unit, int flags)
|
|||||||
sc_console = scp;
|
sc_console = scp;
|
||||||
|
|
||||||
#ifdef SC_PIXEL_MODE
|
#ifdef SC_PIXEL_MODE
|
||||||
if ((sc->config & SC_VESAMODE) != 0) {
|
if ((sc->config & SC_VESAMODE) != 0)
|
||||||
int vmode;
|
sc_set_vesa_mode(scp, sc, unit);
|
||||||
vmode = sc_initial_mode(sc->adp, unit);
|
|
||||||
if (vmode >= M_VESA_BASE) {
|
|
||||||
#ifdef DEV_SPLASH
|
|
||||||
if (sc->flags & SC_SPLASH_SCRN)
|
|
||||||
splash_term(sc->adp);
|
|
||||||
#endif
|
|
||||||
sc_set_graphics_mode(scp, NULL, vmode);
|
|
||||||
sc_set_pixel_mode(scp, NULL, 0, 0, 16, 8);
|
|
||||||
sc->initial_mode = vmode;
|
|
||||||
#ifdef DEV_SPLASH
|
|
||||||
/* put up the splash again! */
|
|
||||||
if (sc->flags & SC_SPLASH_SCRN)
|
|
||||||
splash_init(sc->adp, scsplash_callback, sc);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* SC_PIXEL_MODE */
|
#endif /* SC_PIXEL_MODE */
|
||||||
|
|
||||||
/* initialize cursor */
|
/* initialize cursor */
|
||||||
|
@ -623,6 +623,7 @@ int sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode,
|
|||||||
int sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode);
|
int sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode);
|
||||||
int sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize,
|
int sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize,
|
||||||
int ysize, int fontsize, int font_width);
|
int ysize, int fontsize, int font_width);
|
||||||
|
int sc_support_pixel_mode(void *arg);
|
||||||
int sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data,
|
int sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data,
|
||||||
struct thread *td);
|
struct thread *td);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user