Fix and update for VESA BIOS support in syscons.

- Handle pixel (raster text) mode properly.
   - Clear screen and paint border right.
   - Paint text attribute (colors).
   - Fix off-by-one errors.
   - Add some sanity checks.
- Fix some function prototypes.
- Add some comment lines.
- Define generic text mode numbers so that the user can just give
  "80x25", "80x60", "132x25"..., rather than "VGA_xxx", to `vidcontrol'
  to change the current video mode.  `vidoio.c' and `vesa.c' will map
  these numbers to real video mode numbers appropriate and available
  with the given video hardware.  I believe this will be useful to make
  syscons more portable across archtectures.
This commit is contained in:
Kazutaka YOKOTA 1998-09-23 09:59:00 +00:00
parent e413bb5ca1
commit 95bafc8f5a
11 changed files with 650 additions and 147 deletions

View file

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
* $Id: scvesactl.c,v 1.1 1998/09/15 18:16:37 sos Exp $
*/
#include "sc.h"
@ -50,7 +50,11 @@
static int (*prev_user_ioctl)(dev_t dev, int cmd, caddr_t data, int flag,
struct proc *p);
extern struct tty *scdevtotty(dev_t dev);
/* external functions */
struct tty *scdevtotty(dev_t dev);
/* functions in this module */
int vesa_ioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p);
int
vesa_ioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
@ -79,6 +83,15 @@ vesa_ioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
else
goto vesa_text;
/* generic text modes */
case SW_TEXT_132x25: case SW_TEXT_132x30:
case SW_TEXT_132x43: case SW_TEXT_132x50:
case SW_TEXT_132x60:
adp = get_adapter(scp);
if (!(adp->va_flags & V_ADP_MODECHANGE))
return ENODEV;
return sc_set_text_mode(scp, tp, cmd & 0xff, 0, 0, 0);
/* text modes */
case SW_VESA_C80x60:
case SW_VESA_C132x25:

View file

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
* $Id: scvidctl.c,v 1.1 1998/09/15 18:16:37 sos Exp $
*/
#include "sc.h"
@ -49,7 +49,6 @@
/* video ioctl */
extern scr_stat *cur_console;
extern u_short *Crtat;
extern int fonts_loaded;
extern int sc_history_size;
extern u_char palette[];
@ -233,13 +232,28 @@ sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize,
if (scp->scr_buf != NULL) {
printf("set_pixel_mode(): mode:%x, col:%d, row:%d, font:%d\n",
scp->mode, xsize, ysize, fontsize);
printf("set_pixel_mode(): Crtat:%x, %dx%d, xoff:%d, yoff:%d\n",
Crtat, info.vi_width, info.vi_height,
printf("set_pixel_mode(): window:%x, %dx%d, xoff:%d, yoff:%d\n",
adp->va_window, info.vi_width, info.vi_height,
(info.vi_width/8 - xsize)/2,
(info.vi_height/fontsize - ysize)/2);
}
#endif
if ((info.vi_width < xsize*8) || (info.vi_height < ysize*fontsize))
return EINVAL;
/* only 16 color, 4 plane modes are supported XXX */
if ((info.vi_depth != 4) || (info.vi_planes != 4))
return ENODEV;
/*
* set_pixel_mode() currently does not support video modes whose
* memory size is larger than 64K. Because such modes require
* bank switching to access the entire screen. XXX
*/
if (info.vi_width*info.vi_height/8 > info.vi_window_size*1024)
return ENODEV;
/* stop screen saver, etc */
s = spltty();
if ((error = sc_clean_up(scp))) {
@ -268,9 +282,8 @@ sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize,
sc_alloc_history_buffer(scp, sc_history_size, i, FALSE);
splx(s);
/* FIXME */
if (scp == cur_console)
bzero(Crtat, scp->xpixel*scp->ypixel/8);
set_border(scp, scp->border);
scp->status &= ~UNKNOWN_MODE;
@ -335,6 +348,12 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p)
return ((*biosvidsw.set_win_org)(scp->adp, *(u_int *)data)
? ENODEV : 0);
/* generic text modes */
case SW_TEXT_80x25: case SW_TEXT_80x30:
case SW_TEXT_80x43: case SW_TEXT_80x50:
case SW_TEXT_80x60:
/* FALL THROUGH */
/* VGA TEXT MODES */
case SW_VGA_C40x25:
case SW_VGA_C80x25: case SW_VGA_M80x25:
@ -411,12 +430,8 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p)
scp->status |= UNKNOWN_MODE;
splx(s);
/* no restore fonts & palette */
if (scp == cur_console) {
if (scp == cur_console)
set_mode(scp);
/* FIXME */
if (scp->status & PIXEL_MODE)
bzero(Crtat, scp->xpixel*scp->ypixel/8);
}
sc_clear_screen(scp);
scp->status &= ~UNKNOWN_MODE;
return 0;
@ -424,7 +439,7 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p)
case KD_PIXEL: /* pixel (raster) display */
if (!(scp->status & (GRAPHICS_MODE | PIXEL_MODE)))
return EINVAL;
if (!(scp->status & PIXEL_MODE))
if (scp->status & GRAPHICS_MODE)
return sc_set_pixel_mode(scp, tp, scp->xsize, scp->ysize,
scp->font_size);
s = spltty();
@ -437,8 +452,6 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p)
if (scp == cur_console) {
set_mode(scp);
load_palette(scp, palette);
/* FIXME */
bzero(Crtat, scp->xpixel*scp->ypixel/8);
}
sc_clear_screen(scp);
scp->status &= ~UNKNOWN_MODE;

View file

@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id$
* $Id: syscons.c,v 1.278 1998/09/15 18:16:37 sos Exp $
*/
#include "sc.h"
@ -121,6 +121,7 @@ typedef struct old_mouse_info {
/* XXX use sc_bcopy where video memory is concerned */
extern void generic_bcopy(const void *, void *, size_t);
extern void generic_bzero(void *, size_t);
static default_attr user_default = {
(FG_LIGHTGREY | BG_BLACK) << 8,
@ -293,6 +294,7 @@ static void do_bell(scr_stat *scp, int pitch, int duration);
static timeout_t blink_screen;
#ifdef SC_SPLASH_SCREEN
static void scsplash_init(scr_stat *scp);
static void scsplash_term(scr_stat *scp);
static void scsplash_saver(int show);
#define scsplash_stick(stick) (sticky_splash = (stick))
#else
@ -326,7 +328,8 @@ static struct cdevsw sc_cdevsw = {
static void
draw_cursor_image(scr_stat *scp)
{
u_short cursor_image, *ptr = Crtat + (scp->cursor_pos - scp->scr_buf);
u_short cursor_image;
u_short *ptr;
u_short prev_image;
if (ISPIXELSC(scp)) {
@ -335,6 +338,9 @@ draw_cursor_image(scr_stat *scp)
return;
}
ptr = (u_short *)(get_adapter(scp)->va_window)
+ (scp->cursor_pos - scp->scr_buf);
/* do we have a destructive cursor ? */
if (flags & CHAR_CURSOR) {
prev_image = scp->cursor_saveunder;
@ -383,9 +389,11 @@ remove_cursor_image(scr_stat *scp)
{
if (ISPIXELSC(scp))
sc_bcopy(scp, scp->scr_buf, scp->cursor_oldpos - scp->scr_buf,
scp->cursor_oldpos - scp->scr_buf, 0);
scp->cursor_oldpos - scp->scr_buf, 0);
else
*(Crtat + (scp->cursor_oldpos - scp->scr_buf)) = scp->cursor_saveunder;
*((u_short *)(get_adapter(scp)->va_window)
+ (scp->cursor_oldpos - scp->scr_buf))
= scp->cursor_saveunder;
}
static void
@ -412,13 +420,14 @@ scprobe(struct isa_device *dev)
printf("sc%d: no video adapter is found.\n", dev->id_unit);
return (0);
}
(*biosvidsw.diag)(bootverbose);
#if defined(VESA) && defined(VM86)
if (vesa_load())
return FALSE;
(*biosvidsw.diag)(bootverbose);
#endif
(*biosvidsw.diag)(bootverbose);
sc_port = dev->id_iobase;
if (sckbdprobe(dev->id_unit, dev->id_flags))
return (IO_KBDSIZE);
@ -663,9 +672,15 @@ scattach(struct isa_device *dev)
#if defined(VESA) && defined(VM86)
if ((flags & VESA800X600)
&& ((*biosvidsw.get_info)(scp->adp, M_VESA_800x600, &info) == 0)) {
#ifdef SC_SPLASH_SCREEN
scsplash_term(scp);
#endif
sc_set_graphics_mode(scp, NULL, M_VESA_800x600);
sc_set_pixel_mode(scp, NULL, COL, ROW, 16);
initial_video_mode = M_VESA_800x600;
#ifdef SC_SPLASH_SCREEN
scsplash_init(scp);
#endif
}
#endif /* VESA && VM86 */
@ -2310,10 +2325,8 @@ exchange_scr(void)
{
move_crsr(old_scp, old_scp->xpos, old_scp->ypos);
cur_console = new_scp;
if (old_scp->mode != new_scp->mode || ISUNKNOWNSC(old_scp)) {
if (adp_flags & V_ADP_MODECHANGE)
set_mode(new_scp);
}
if (old_scp->mode != new_scp->mode || ISUNKNOWNSC(old_scp))
set_mode(new_scp);
move_crsr(new_scp, new_scp->xpos, new_scp->ypos);
if (ISTEXTSC(new_scp) && (flags & CHAR_CURSOR))
set_destructive_cursor(new_scp);
@ -2326,10 +2339,6 @@ exchange_scr(void)
update_leds(new_scp->status);
delayed_next_scr = FALSE;
mark_all(new_scp);
/* FIXME: the screen size may be larger than a 64K segment. */
if (ISPIXELSC(new_scp))
bzero(Crtat, new_scp->xpixel*new_scp->ypixel/8);
}
static void
@ -2496,7 +2505,7 @@ scan_esc(scr_stat *scp, u_char c)
scp->xsize - scp->xpos);
mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
mark_for_update(scp, scp->cursor_pos - scp->scr_buf +
scp->xsize - scp->xpos);
scp->xsize - 1 - scp->xpos);
break;
case 1: /* clear from beginning of line to cursor */
fillw(scp->term.cur_color | scr_map[0x20],
@ -2510,7 +2519,7 @@ scan_esc(scr_stat *scp, u_char c)
scp->cursor_pos - scp->xpos,
scp->xsize);
mark_for_update(scp, scp->ypos * scp->xsize);
mark_for_update(scp, (scp->ypos + 1) * scp->xsize);
mark_for_update(scp, (scp->ypos + 1) * scp->xsize - 1);
break;
}
break;
@ -2555,7 +2564,7 @@ scan_esc(scr_stat *scp, u_char c)
src = dst + count;
fillw(scp->term.cur_color | scr_map[0x20], src, n);
mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
mark_for_update(scp, scp->cursor_pos - scp->scr_buf + n + count);
mark_for_update(scp, scp->cursor_pos - scp->scr_buf + n + count - 1);
break;
case '@': /* Insert n chars */
@ -2568,7 +2577,7 @@ scan_esc(scr_stat *scp, u_char c)
bcopy(src, dst, count * sizeof(u_short));
fillw(scp->term.cur_color | scr_map[0x20], src, n);
mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
mark_for_update(scp, scp->cursor_pos - scp->scr_buf + n + count);
mark_for_update(scp, scp->cursor_pos - scp->scr_buf + n + count - 1);
break;
case 'S': /* scroll up n lines */
@ -2604,7 +2613,7 @@ scan_esc(scr_stat *scp, u_char c)
fillw(scp->term.cur_color | scr_map[0x20],
scp->cursor_pos, n);
mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
mark_for_update(scp, scp->cursor_pos - scp->scr_buf + n);
mark_for_update(scp, scp->cursor_pos - scp->scr_buf + n - 1);
break;
case 'Z': /* move n tabs backwards */
@ -3023,8 +3032,8 @@ scinit(void)
/* copy screen to temporary buffer */
if (ISTEXTSC(console[0]))
generic_bcopy(Crtat, sc_buffer,
console[0]->xsize * console[0]->ysize * sizeof(u_short));
generic_bcopy((ushort *)(get_adapter(console[0])->va_window), sc_buffer,
console[0]->xsize * console[0]->ysize * sizeof(u_short));
console[0]->scr_buf = console[0]->mouse_pos = console[0]->mouse_oldpos
= sc_buffer;
@ -3993,6 +4002,9 @@ set_mode(scr_stat *scp)
}
mark_all(scp);
}
if (scp->status & PIXEL_MODE)
generic_bzero((u_char *)(adp->va_window), scp->xpixel*scp->ypixel/8);
set_border(scp, scp->border);
/* move hardware cursor out of the way */
@ -4001,6 +4013,46 @@ set_mode(scr_stat *scp)
return 0;
}
void
set_border(scr_stat *scp, int color)
{
u_char *p;
int xoff;
int yoff;
int xlen;
int ylen;
int i;
(*biosvidsw.set_border)(scp->adp, color);
if (scp->status & PIXEL_MODE) {
outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */
outw(GDCIDX, 0x0003); /* data rotate/function select */
outw(GDCIDX, 0x0f01); /* set/reset enable */
outw(GDCIDX, 0xff08); /* bit mask */
outw(GDCIDX, (color << 8) | 0x00); /* set/reset */
p = (u_char *)(get_adapter(scp)->va_window);
xoff = scp->xoff;
yoff = scp->yoff*scp->font_size;
xlen = scp->xpixel/8;
ylen = scp->ysize*scp->font_size;
if (yoff > 0) {
generic_bzero(p, xlen*yoff);
generic_bzero(p + xlen*(yoff + ylen),
xlen*scp->ypixel - xlen*(yoff + ylen));
}
if (xoff > 0) {
for (i = 0; i < ylen; ++i) {
generic_bzero(p + xlen*(yoff + i), xoff);
generic_bzero(p + xlen*(yoff + i) + xoff + scp->xsize,
xlen - xoff - scp->xsize);
}
}
outw(GDCIDX, 0x0000); /* set/reset */
outw(GDCIDX, 0x0001); /* set/reset enable */
}
}
void
copy_font(scr_stat *scp, int operation, int font_size, u_char *buf)
{
@ -4322,7 +4374,8 @@ draw_mouse_image(scr_stat *scp)
{
u_short buffer[32];
u_short xoffset, yoffset;
u_short *crt_pos = Crtat + (scp->mouse_pos - scp->scr_buf);
u_short *crt_pos = (u_short *)(get_adapter(scp)->va_window)
+ (scp->mouse_pos - scp->scr_buf);
u_char *font_buffer;
int font_size;
int i;
@ -4394,10 +4447,13 @@ draw_mouse_image(scr_stat *scp)
static void
remove_mouse_image(scr_stat *scp)
{
u_short *crt_pos = Crtat + (scp->mouse_oldpos - scp->scr_buf);
u_short *crt_pos;
if (!ISTEXTSC(scp))
return;
crt_pos = (u_short *)(get_adapter(scp)->va_window)
+ (scp->mouse_oldpos - scp->scr_buf);
*(crt_pos) = *(scp->mouse_oldpos);
*(crt_pos+1) = *(scp->mouse_oldpos+1);
*(crt_pos+scp->xsize) = *(scp->mouse_oldpos+scp->xsize);
@ -4409,11 +4465,13 @@ remove_mouse_image(scr_stat *scp)
static void
draw_cutmarking(scr_stat *scp)
{
u_short *crt_pos;
u_short *ptr;
u_short och, nch;
crt_pos = (u_short *)(get_adapter(scp)->va_window);
for (ptr=scp->scr_buf; ptr<=(scp->scr_buf+(scp->xsize*scp->ysize)); ptr++) {
nch = och = *(Crtat + (ptr - scp->scr_buf));
nch = och = *(crt_pos + (ptr - scp->scr_buf));
/* are we outside the selected area ? */
if ( ptr < (scp->mouse_cut_start > scp->mouse_cut_end ?
scp->mouse_cut_end : scp->mouse_cut_start) ||
@ -4435,7 +4493,7 @@ draw_cutmarking(scr_stat *scp)
}
}
if (nch != och)
*(Crtat + (ptr - scp->scr_buf)) = nch;
*(crt_pos + (ptr - scp->scr_buf)) = nch;
}
}
@ -4484,10 +4542,12 @@ blink_screen(void *arg)
else {
if (blink_in_progress & 1)
fillw(kernel_default.std_color | scr_map[0x20],
Crtat, scp->xsize * scp->ysize);
(u_short *)(get_adapter(scp)->va_window),
scp->xsize * scp->ysize);
else
fillw(kernel_default.rev_color | scr_map[0x20],
Crtat, scp->xsize * scp->ysize);
(u_short *)(get_adapter(scp)->va_window),
scp->xsize * scp->ysize);
blink_in_progress--;
timeout(blink_screen, scp, hz / 10);
}
@ -4497,15 +4557,19 @@ void
sc_bcopy(scr_stat *scp, u_short *p, int from, int to, int mark)
{
u_char *font;
u_char *d, *e;
u_char volatile *d;
u_char *e;
u_char *f;
int font_size;
int line_length;
int xsize;
u_short bg;
int i, j;
u_char c;
if (ISTEXTSC(scp)) {
generic_bcopy(p+from, Crtat+from, (to-from+1)*sizeof (u_short));
generic_bcopy(p + from, (u_short *)(get_adapter(scp)->va_window) + from,
(to - from + 1)*sizeof(u_short));
} else /* if ISPIXELSC(scp) */ {
if (mark)
mark = 255;
@ -4518,20 +4582,72 @@ sc_bcopy(scr_stat *scp, u_short *p, int from, int to, int mark)
font = font_14;
line_length = scp->xpixel/8;
xsize = scp->xsize;
d = (u_char *)Crtat
d = (u_char *)(get_adapter(scp)->va_window)
+ scp->xoff + scp->yoff*font_size*line_length
+ (from%xsize) + font_size*line_length*(from/xsize);
outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */
outw(GDCIDX, 0x0003); /* data rotate/function select */
outw(GDCIDX, 0x0f01); /* set/reset enable */
bg = -1;
for (i = from ; i <= to ; i++) {
e = d;
/* set background color in EGA/VGA latch */
if (bg != (p[i] & 0xf000)) {
bg = (p[i] & 0xf000);
outw(GDCIDX, (bg >> 4) | 0x00); /* set/reset */
outw(GDCIDX, 0xff08); /* bit mask */
*d = 0;
c = *d; /* set the background color in the latch */
}
/* foreground color */
outw(GDCIDX, (p[i] & 0x0f00) | 0x00); /* set/reset */
e = (u_char *)d;
f = &font[(p[i] & 0x00ff)*font_size];
for (j = 0 ; j < font_size; j++, f++) {
*e = mark^*f;
outw(GDCIDX, ((*f^mark) << 8) | 0x08); /* bit mask */
*e = 0;
e += line_length;
}
d++;
if ((i % xsize) == xsize - 1)
d += scp->xoff*2 + (font_size - 1)*line_length;
}
outw(GDCIDX, 0x0000); /* set/reset */
outw(GDCIDX, 0x0001); /* set/reset enable */
outw(GDCIDX, 0xff08); /* bit mask */
#if 0 /* VGA only */
outw(GDCIDX, 0x0305); /* read mode 0, write mode 3 */
outw(GDCIDX, 0x0003); /* data rotate/function select */
outw(GDCIDX, 0x0f01); /* set/reset enable */
outw(GDCIDX, 0xff08); /* bit mask */
bg = -1;
for (i = from ; i <= to ; i++) {
/* set background color in EGA/VGA latch */
if (bg != (p[i] & 0xf000)) {
bg = (p[i] & 0xf000);
outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */
outw(GDCIDX, (bg >> 4) | 0x00); /* set/reset */
*d = 0;
c = *d; /* set the background color in the latch */
outw(GDCIDX, 0x0305); /* read mode 0, write mode 3 */
}
/* foreground color */
outw(GDCIDX, (p[i] & 0x0f00) | 0x00); /* set/reset */
e = (u_char *)d;
f = &font[(p[i] & 0x00ff)*font_size];
for (j = 0 ; j < font_size; j++, f++) {
*e = *f^mark;
e += line_length;
}
d++;
if ((i % xsize) == xsize - 1)
d += scp->xoff*2 + (font_size - 1)*line_length;
}
outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */
outw(GDCIDX, 0x0000); /* set/reset */
outw(GDCIDX, 0x0001); /* set/reset enable */
#endif /* 0 */
}
}
@ -4542,14 +4658,6 @@ scsplash_init(scr_stat *scp)
{
video_info_t info;
/*
* We currently assume the splash screen always use
* VGA_CG320 mode and abort installation if this mode is not
* supported with this video card. XXX
*/
if ((*biosvidsw.get_info)(scp->adp, M_VGA_CG320, &info))
return;
if (scsplash_load(scp) == 0 && add_scrn_saver(scsplash_saver) == 0) {
default_saver = scsplash_saver;
scrn_blank_time = DEFAULT_BLANKTIME;
@ -4561,6 +4669,15 @@ scsplash_init(scr_stat *scp)
}
}
static void
scsplash_term(scr_stat *scp)
{
default_saver = none_saver;
scsplash_stick(FALSE);
remove_scrn_saver(scsplash_saver);
scsplash_unload(scp);
}
static void
scsplash_saver(int show)
{

View file

@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id$
* $Id: syscons.h,v 1.40 1998/09/15 18:16:38 sos Exp $
*/
#ifndef _I386_ISA_SYSCONS_H_
@ -210,9 +210,9 @@ int set_mode(scr_stat *scp);
scr_stat *sc_get_scr_stat(dev_t dev);
void copy_font(scr_stat *scp, int operation, int font_size, u_char *font_image);
void set_border(scr_stat *scp, int color);
#define save_palette(scp, pal) (*biosvidsw.save_palette)((scp)->adp, pal)
#define load_palette(scp, pal) (*biosvidsw.load_palette)((scp)->adp, pal)
#define set_border(scp, col) (*biosvidsw.set_border)((scp)->adp, col)
#define get_adapter(scp) (*biosvidsw.adapter)((scp)->adp)
int add_scrn_saver(void (*this)(int));

View file

@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: console.h,v 1.38 1998/08/03 11:30:28 yokota Exp $
* $Id: console.h,v 1.39 1998/09/15 18:16:37 sos Exp $
*/
#ifndef _MACHINE_CONSOLE_H_
@ -437,6 +437,17 @@ typedef struct {int scr_size[3];} scr_size_t;
#define M_HGC_P1 0xe1 /* hercules graphics - page 1 @ B8000 */
#define M_MCA_MODE 0xff /* monochrome adapter mode */
#define M_TEXT_80x25 200 /* generic text modes */
#define M_TEXT_80x30 201
#define M_TEXT_80x43 202
#define M_TEXT_80x50 203
#define M_TEXT_80x60 204
#define M_TEXT_132x25 205
#define M_TEXT_132x30 206
#define M_TEXT_132x43 207
#define M_TEXT_132x50 208
#define M_TEXT_132x60 209
#define SW_PC98_80x25 _IO('S', M_PC98_80x25)
#define SW_PC98_80x30 _IO('S', M_PC98_80x30)
#define SW_B40x25 _IO('S', M_B40x25)
@ -478,6 +489,17 @@ typedef struct {int scr_size[3];} scr_size_t;
#define SW_VGA_CG640 _IO('S', M_VGA_CG640)
#define SW_VGA_MODEX _IO('S', M_VGA_MODEX)
#define SW_TEXT_80x25 _IO('S', M_TEXT_80x25)
#define SW_TEXT_80x30 _IO('S', M_TEXT_80x30)
#define SW_TEXT_80x43 _IO('S', M_TEXT_80x43)
#define SW_TEXT_80x50 _IO('S', M_TEXT_80x50)
#define SW_TEXT_80x60 _IO('S', M_TEXT_80x60)
#define SW_TEXT_132x25 _IO('S', M_TEXT_132x25)
#define SW_TEXT_132x30 _IO('S', M_TEXT_132x30)
#define SW_TEXT_132x43 _IO('S', M_TEXT_132x43)
#define SW_TEXT_132x50 _IO('S', M_TEXT_132x50)
#define SW_TEXT_132x60 _IO('S', M_TEXT_132x60)
#define M_VESA_BASE 0x100 /* VESA mode number base */
#define M_VESA_CG640x400 0x100 /* 640x400, 256 color */

View file

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
* $Id: scvesactl.c,v 1.1 1998/09/15 18:16:37 sos Exp $
*/
#include "sc.h"
@ -50,7 +50,11 @@
static int (*prev_user_ioctl)(dev_t dev, int cmd, caddr_t data, int flag,
struct proc *p);
extern struct tty *scdevtotty(dev_t dev);
/* external functions */
struct tty *scdevtotty(dev_t dev);
/* functions in this module */
int vesa_ioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p);
int
vesa_ioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
@ -79,6 +83,15 @@ vesa_ioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
else
goto vesa_text;
/* generic text modes */
case SW_TEXT_132x25: case SW_TEXT_132x30:
case SW_TEXT_132x43: case SW_TEXT_132x50:
case SW_TEXT_132x60:
adp = get_adapter(scp);
if (!(adp->va_flags & V_ADP_MODECHANGE))
return ENODEV;
return sc_set_text_mode(scp, tp, cmd & 0xff, 0, 0, 0);
/* text modes */
case SW_VESA_C80x60:
case SW_VESA_C132x25:

View file

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
* $Id: scvidctl.c,v 1.1 1998/09/15 18:16:37 sos Exp $
*/
#include "sc.h"
@ -49,7 +49,6 @@
/* video ioctl */
extern scr_stat *cur_console;
extern u_short *Crtat;
extern int fonts_loaded;
extern int sc_history_size;
extern u_char palette[];
@ -233,13 +232,28 @@ sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize,
if (scp->scr_buf != NULL) {
printf("set_pixel_mode(): mode:%x, col:%d, row:%d, font:%d\n",
scp->mode, xsize, ysize, fontsize);
printf("set_pixel_mode(): Crtat:%x, %dx%d, xoff:%d, yoff:%d\n",
Crtat, info.vi_width, info.vi_height,
printf("set_pixel_mode(): window:%x, %dx%d, xoff:%d, yoff:%d\n",
adp->va_window, info.vi_width, info.vi_height,
(info.vi_width/8 - xsize)/2,
(info.vi_height/fontsize - ysize)/2);
}
#endif
if ((info.vi_width < xsize*8) || (info.vi_height < ysize*fontsize))
return EINVAL;
/* only 16 color, 4 plane modes are supported XXX */
if ((info.vi_depth != 4) || (info.vi_planes != 4))
return ENODEV;
/*
* set_pixel_mode() currently does not support video modes whose
* memory size is larger than 64K. Because such modes require
* bank switching to access the entire screen. XXX
*/
if (info.vi_width*info.vi_height/8 > info.vi_window_size*1024)
return ENODEV;
/* stop screen saver, etc */
s = spltty();
if ((error = sc_clean_up(scp))) {
@ -268,9 +282,8 @@ sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize,
sc_alloc_history_buffer(scp, sc_history_size, i, FALSE);
splx(s);
/* FIXME */
if (scp == cur_console)
bzero(Crtat, scp->xpixel*scp->ypixel/8);
set_border(scp, scp->border);
scp->status &= ~UNKNOWN_MODE;
@ -335,6 +348,12 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p)
return ((*biosvidsw.set_win_org)(scp->adp, *(u_int *)data)
? ENODEV : 0);
/* generic text modes */
case SW_TEXT_80x25: case SW_TEXT_80x30:
case SW_TEXT_80x43: case SW_TEXT_80x50:
case SW_TEXT_80x60:
/* FALL THROUGH */
/* VGA TEXT MODES */
case SW_VGA_C40x25:
case SW_VGA_C80x25: case SW_VGA_M80x25:
@ -411,12 +430,8 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p)
scp->status |= UNKNOWN_MODE;
splx(s);
/* no restore fonts & palette */
if (scp == cur_console) {
if (scp == cur_console)
set_mode(scp);
/* FIXME */
if (scp->status & PIXEL_MODE)
bzero(Crtat, scp->xpixel*scp->ypixel/8);
}
sc_clear_screen(scp);
scp->status &= ~UNKNOWN_MODE;
return 0;
@ -424,7 +439,7 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p)
case KD_PIXEL: /* pixel (raster) display */
if (!(scp->status & (GRAPHICS_MODE | PIXEL_MODE)))
return EINVAL;
if (!(scp->status & PIXEL_MODE))
if (scp->status & GRAPHICS_MODE)
return sc_set_pixel_mode(scp, tp, scp->xsize, scp->ysize,
scp->font_size);
s = spltty();
@ -437,8 +452,6 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p)
if (scp == cur_console) {
set_mode(scp);
load_palette(scp, palette);
/* FIXME */
bzero(Crtat, scp->xpixel*scp->ypixel/8);
}
sc_clear_screen(scp);
scp->status &= ~UNKNOWN_MODE;

View file

@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id$
* $Id: syscons.c,v 1.278 1998/09/15 18:16:37 sos Exp $
*/
#include "sc.h"
@ -121,6 +121,7 @@ typedef struct old_mouse_info {
/* XXX use sc_bcopy where video memory is concerned */
extern void generic_bcopy(const void *, void *, size_t);
extern void generic_bzero(void *, size_t);
static default_attr user_default = {
(FG_LIGHTGREY | BG_BLACK) << 8,
@ -293,6 +294,7 @@ static void do_bell(scr_stat *scp, int pitch, int duration);
static timeout_t blink_screen;
#ifdef SC_SPLASH_SCREEN
static void scsplash_init(scr_stat *scp);
static void scsplash_term(scr_stat *scp);
static void scsplash_saver(int show);
#define scsplash_stick(stick) (sticky_splash = (stick))
#else
@ -326,7 +328,8 @@ static struct cdevsw sc_cdevsw = {
static void
draw_cursor_image(scr_stat *scp)
{
u_short cursor_image, *ptr = Crtat + (scp->cursor_pos - scp->scr_buf);
u_short cursor_image;
u_short *ptr;
u_short prev_image;
if (ISPIXELSC(scp)) {
@ -335,6 +338,9 @@ draw_cursor_image(scr_stat *scp)
return;
}
ptr = (u_short *)(get_adapter(scp)->va_window)
+ (scp->cursor_pos - scp->scr_buf);
/* do we have a destructive cursor ? */
if (flags & CHAR_CURSOR) {
prev_image = scp->cursor_saveunder;
@ -383,9 +389,11 @@ remove_cursor_image(scr_stat *scp)
{
if (ISPIXELSC(scp))
sc_bcopy(scp, scp->scr_buf, scp->cursor_oldpos - scp->scr_buf,
scp->cursor_oldpos - scp->scr_buf, 0);
scp->cursor_oldpos - scp->scr_buf, 0);
else
*(Crtat + (scp->cursor_oldpos - scp->scr_buf)) = scp->cursor_saveunder;
*((u_short *)(get_adapter(scp)->va_window)
+ (scp->cursor_oldpos - scp->scr_buf))
= scp->cursor_saveunder;
}
static void
@ -412,13 +420,14 @@ scprobe(struct isa_device *dev)
printf("sc%d: no video adapter is found.\n", dev->id_unit);
return (0);
}
(*biosvidsw.diag)(bootverbose);
#if defined(VESA) && defined(VM86)
if (vesa_load())
return FALSE;
(*biosvidsw.diag)(bootverbose);
#endif
(*biosvidsw.diag)(bootverbose);
sc_port = dev->id_iobase;
if (sckbdprobe(dev->id_unit, dev->id_flags))
return (IO_KBDSIZE);
@ -663,9 +672,15 @@ scattach(struct isa_device *dev)
#if defined(VESA) && defined(VM86)
if ((flags & VESA800X600)
&& ((*biosvidsw.get_info)(scp->adp, M_VESA_800x600, &info) == 0)) {
#ifdef SC_SPLASH_SCREEN
scsplash_term(scp);
#endif
sc_set_graphics_mode(scp, NULL, M_VESA_800x600);
sc_set_pixel_mode(scp, NULL, COL, ROW, 16);
initial_video_mode = M_VESA_800x600;
#ifdef SC_SPLASH_SCREEN
scsplash_init(scp);
#endif
}
#endif /* VESA && VM86 */
@ -2310,10 +2325,8 @@ exchange_scr(void)
{
move_crsr(old_scp, old_scp->xpos, old_scp->ypos);
cur_console = new_scp;
if (old_scp->mode != new_scp->mode || ISUNKNOWNSC(old_scp)) {
if (adp_flags & V_ADP_MODECHANGE)
set_mode(new_scp);
}
if (old_scp->mode != new_scp->mode || ISUNKNOWNSC(old_scp))
set_mode(new_scp);
move_crsr(new_scp, new_scp->xpos, new_scp->ypos);
if (ISTEXTSC(new_scp) && (flags & CHAR_CURSOR))
set_destructive_cursor(new_scp);
@ -2326,10 +2339,6 @@ exchange_scr(void)
update_leds(new_scp->status);
delayed_next_scr = FALSE;
mark_all(new_scp);
/* FIXME: the screen size may be larger than a 64K segment. */
if (ISPIXELSC(new_scp))
bzero(Crtat, new_scp->xpixel*new_scp->ypixel/8);
}
static void
@ -2496,7 +2505,7 @@ scan_esc(scr_stat *scp, u_char c)
scp->xsize - scp->xpos);
mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
mark_for_update(scp, scp->cursor_pos - scp->scr_buf +
scp->xsize - scp->xpos);
scp->xsize - 1 - scp->xpos);
break;
case 1: /* clear from beginning of line to cursor */
fillw(scp->term.cur_color | scr_map[0x20],
@ -2510,7 +2519,7 @@ scan_esc(scr_stat *scp, u_char c)
scp->cursor_pos - scp->xpos,
scp->xsize);
mark_for_update(scp, scp->ypos * scp->xsize);
mark_for_update(scp, (scp->ypos + 1) * scp->xsize);
mark_for_update(scp, (scp->ypos + 1) * scp->xsize - 1);
break;
}
break;
@ -2555,7 +2564,7 @@ scan_esc(scr_stat *scp, u_char c)
src = dst + count;
fillw(scp->term.cur_color | scr_map[0x20], src, n);
mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
mark_for_update(scp, scp->cursor_pos - scp->scr_buf + n + count);
mark_for_update(scp, scp->cursor_pos - scp->scr_buf + n + count - 1);
break;
case '@': /* Insert n chars */
@ -2568,7 +2577,7 @@ scan_esc(scr_stat *scp, u_char c)
bcopy(src, dst, count * sizeof(u_short));
fillw(scp->term.cur_color | scr_map[0x20], src, n);
mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
mark_for_update(scp, scp->cursor_pos - scp->scr_buf + n + count);
mark_for_update(scp, scp->cursor_pos - scp->scr_buf + n + count - 1);
break;
case 'S': /* scroll up n lines */
@ -2604,7 +2613,7 @@ scan_esc(scr_stat *scp, u_char c)
fillw(scp->term.cur_color | scr_map[0x20],
scp->cursor_pos, n);
mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
mark_for_update(scp, scp->cursor_pos - scp->scr_buf + n);
mark_for_update(scp, scp->cursor_pos - scp->scr_buf + n - 1);
break;
case 'Z': /* move n tabs backwards */
@ -3023,8 +3032,8 @@ scinit(void)
/* copy screen to temporary buffer */
if (ISTEXTSC(console[0]))
generic_bcopy(Crtat, sc_buffer,
console[0]->xsize * console[0]->ysize * sizeof(u_short));
generic_bcopy((ushort *)(get_adapter(console[0])->va_window), sc_buffer,
console[0]->xsize * console[0]->ysize * sizeof(u_short));
console[0]->scr_buf = console[0]->mouse_pos = console[0]->mouse_oldpos
= sc_buffer;
@ -3993,6 +4002,9 @@ set_mode(scr_stat *scp)
}
mark_all(scp);
}
if (scp->status & PIXEL_MODE)
generic_bzero((u_char *)(adp->va_window), scp->xpixel*scp->ypixel/8);
set_border(scp, scp->border);
/* move hardware cursor out of the way */
@ -4001,6 +4013,46 @@ set_mode(scr_stat *scp)
return 0;
}
void
set_border(scr_stat *scp, int color)
{
u_char *p;
int xoff;
int yoff;
int xlen;
int ylen;
int i;
(*biosvidsw.set_border)(scp->adp, color);
if (scp->status & PIXEL_MODE) {
outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */
outw(GDCIDX, 0x0003); /* data rotate/function select */
outw(GDCIDX, 0x0f01); /* set/reset enable */
outw(GDCIDX, 0xff08); /* bit mask */
outw(GDCIDX, (color << 8) | 0x00); /* set/reset */
p = (u_char *)(get_adapter(scp)->va_window);
xoff = scp->xoff;
yoff = scp->yoff*scp->font_size;
xlen = scp->xpixel/8;
ylen = scp->ysize*scp->font_size;
if (yoff > 0) {
generic_bzero(p, xlen*yoff);
generic_bzero(p + xlen*(yoff + ylen),
xlen*scp->ypixel - xlen*(yoff + ylen));
}
if (xoff > 0) {
for (i = 0; i < ylen; ++i) {
generic_bzero(p + xlen*(yoff + i), xoff);
generic_bzero(p + xlen*(yoff + i) + xoff + scp->xsize,
xlen - xoff - scp->xsize);
}
}
outw(GDCIDX, 0x0000); /* set/reset */
outw(GDCIDX, 0x0001); /* set/reset enable */
}
}
void
copy_font(scr_stat *scp, int operation, int font_size, u_char *buf)
{
@ -4322,7 +4374,8 @@ draw_mouse_image(scr_stat *scp)
{
u_short buffer[32];
u_short xoffset, yoffset;
u_short *crt_pos = Crtat + (scp->mouse_pos - scp->scr_buf);
u_short *crt_pos = (u_short *)(get_adapter(scp)->va_window)
+ (scp->mouse_pos - scp->scr_buf);
u_char *font_buffer;
int font_size;
int i;
@ -4394,10 +4447,13 @@ draw_mouse_image(scr_stat *scp)
static void
remove_mouse_image(scr_stat *scp)
{
u_short *crt_pos = Crtat + (scp->mouse_oldpos - scp->scr_buf);
u_short *crt_pos;
if (!ISTEXTSC(scp))
return;
crt_pos = (u_short *)(get_adapter(scp)->va_window)
+ (scp->mouse_oldpos - scp->scr_buf);
*(crt_pos) = *(scp->mouse_oldpos);
*(crt_pos+1) = *(scp->mouse_oldpos+1);
*(crt_pos+scp->xsize) = *(scp->mouse_oldpos+scp->xsize);
@ -4409,11 +4465,13 @@ remove_mouse_image(scr_stat *scp)
static void
draw_cutmarking(scr_stat *scp)
{
u_short *crt_pos;
u_short *ptr;
u_short och, nch;
crt_pos = (u_short *)(get_adapter(scp)->va_window);
for (ptr=scp->scr_buf; ptr<=(scp->scr_buf+(scp->xsize*scp->ysize)); ptr++) {
nch = och = *(Crtat + (ptr - scp->scr_buf));
nch = och = *(crt_pos + (ptr - scp->scr_buf));
/* are we outside the selected area ? */
if ( ptr < (scp->mouse_cut_start > scp->mouse_cut_end ?
scp->mouse_cut_end : scp->mouse_cut_start) ||
@ -4435,7 +4493,7 @@ draw_cutmarking(scr_stat *scp)
}
}
if (nch != och)
*(Crtat + (ptr - scp->scr_buf)) = nch;
*(crt_pos + (ptr - scp->scr_buf)) = nch;
}
}
@ -4484,10 +4542,12 @@ blink_screen(void *arg)
else {
if (blink_in_progress & 1)
fillw(kernel_default.std_color | scr_map[0x20],
Crtat, scp->xsize * scp->ysize);
(u_short *)(get_adapter(scp)->va_window),
scp->xsize * scp->ysize);
else
fillw(kernel_default.rev_color | scr_map[0x20],
Crtat, scp->xsize * scp->ysize);
(u_short *)(get_adapter(scp)->va_window),
scp->xsize * scp->ysize);
blink_in_progress--;
timeout(blink_screen, scp, hz / 10);
}
@ -4497,15 +4557,19 @@ void
sc_bcopy(scr_stat *scp, u_short *p, int from, int to, int mark)
{
u_char *font;
u_char *d, *e;
u_char volatile *d;
u_char *e;
u_char *f;
int font_size;
int line_length;
int xsize;
u_short bg;
int i, j;
u_char c;
if (ISTEXTSC(scp)) {
generic_bcopy(p+from, Crtat+from, (to-from+1)*sizeof (u_short));
generic_bcopy(p + from, (u_short *)(get_adapter(scp)->va_window) + from,
(to - from + 1)*sizeof(u_short));
} else /* if ISPIXELSC(scp) */ {
if (mark)
mark = 255;
@ -4518,20 +4582,72 @@ sc_bcopy(scr_stat *scp, u_short *p, int from, int to, int mark)
font = font_14;
line_length = scp->xpixel/8;
xsize = scp->xsize;
d = (u_char *)Crtat
d = (u_char *)(get_adapter(scp)->va_window)
+ scp->xoff + scp->yoff*font_size*line_length
+ (from%xsize) + font_size*line_length*(from/xsize);
outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */
outw(GDCIDX, 0x0003); /* data rotate/function select */
outw(GDCIDX, 0x0f01); /* set/reset enable */
bg = -1;
for (i = from ; i <= to ; i++) {
e = d;
/* set background color in EGA/VGA latch */
if (bg != (p[i] & 0xf000)) {
bg = (p[i] & 0xf000);
outw(GDCIDX, (bg >> 4) | 0x00); /* set/reset */
outw(GDCIDX, 0xff08); /* bit mask */
*d = 0;
c = *d; /* set the background color in the latch */
}
/* foreground color */
outw(GDCIDX, (p[i] & 0x0f00) | 0x00); /* set/reset */
e = (u_char *)d;
f = &font[(p[i] & 0x00ff)*font_size];
for (j = 0 ; j < font_size; j++, f++) {
*e = mark^*f;
outw(GDCIDX, ((*f^mark) << 8) | 0x08); /* bit mask */
*e = 0;
e += line_length;
}
d++;
if ((i % xsize) == xsize - 1)
d += scp->xoff*2 + (font_size - 1)*line_length;
}
outw(GDCIDX, 0x0000); /* set/reset */
outw(GDCIDX, 0x0001); /* set/reset enable */
outw(GDCIDX, 0xff08); /* bit mask */
#if 0 /* VGA only */
outw(GDCIDX, 0x0305); /* read mode 0, write mode 3 */
outw(GDCIDX, 0x0003); /* data rotate/function select */
outw(GDCIDX, 0x0f01); /* set/reset enable */
outw(GDCIDX, 0xff08); /* bit mask */
bg = -1;
for (i = from ; i <= to ; i++) {
/* set background color in EGA/VGA latch */
if (bg != (p[i] & 0xf000)) {
bg = (p[i] & 0xf000);
outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */
outw(GDCIDX, (bg >> 4) | 0x00); /* set/reset */
*d = 0;
c = *d; /* set the background color in the latch */
outw(GDCIDX, 0x0305); /* read mode 0, write mode 3 */
}
/* foreground color */
outw(GDCIDX, (p[i] & 0x0f00) | 0x00); /* set/reset */
e = (u_char *)d;
f = &font[(p[i] & 0x00ff)*font_size];
for (j = 0 ; j < font_size; j++, f++) {
*e = *f^mark;
e += line_length;
}
d++;
if ((i % xsize) == xsize - 1)
d += scp->xoff*2 + (font_size - 1)*line_length;
}
outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */
outw(GDCIDX, 0x0000); /* set/reset */
outw(GDCIDX, 0x0001); /* set/reset enable */
#endif /* 0 */
}
}
@ -4542,14 +4658,6 @@ scsplash_init(scr_stat *scp)
{
video_info_t info;
/*
* We currently assume the splash screen always use
* VGA_CG320 mode and abort installation if this mode is not
* supported with this video card. XXX
*/
if ((*biosvidsw.get_info)(scp->adp, M_VGA_CG320, &info))
return;
if (scsplash_load(scp) == 0 && add_scrn_saver(scsplash_saver) == 0) {
default_saver = scsplash_saver;
scrn_blank_time = DEFAULT_BLANKTIME;
@ -4561,6 +4669,15 @@ scsplash_init(scr_stat *scp)
}
}
static void
scsplash_term(scr_stat *scp)
{
default_saver = none_saver;
scsplash_stick(FALSE);
remove_scrn_saver(scsplash_saver);
scsplash_unload(scp);
}
static void
scsplash_saver(int show)
{

View file

@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id$
* $Id: syscons.h,v 1.40 1998/09/15 18:16:38 sos Exp $
*/
#ifndef _I386_ISA_SYSCONS_H_
@ -210,9 +210,9 @@ int set_mode(scr_stat *scp);
scr_stat *sc_get_scr_stat(dev_t dev);
void copy_font(scr_stat *scp, int operation, int font_size, u_char *font_image);
void set_border(scr_stat *scp, int color);
#define save_palette(scp, pal) (*biosvidsw.save_palette)((scp)->adp, pal)
#define load_palette(scp, pal) (*biosvidsw.load_palette)((scp)->adp, pal)
#define set_border(scp, col) (*biosvidsw.set_border)((scp)->adp, col)
#define get_adapter(scp) (*biosvidsw.adapter)((scp)->adp)
int add_scrn_saver(void (*this)(int));

View file

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
* $Id: vesa.c,v 1.1 1998/09/15 18:16:38 sos Exp $
*/
#include "sc.h"
@ -133,9 +133,10 @@ static int vesa_bios_load_palette(int start, int colors, u_char *palette);
#define STATE_ALL (STATE_HW | STATE_DATA | STATE_DAC | STATE_REG)
static int vesa_bios_state_buf_size(void);
static int vesa_bios_save_restore(int code, void *p, size_t size);
static int translate_flags(u_int16_t vflags);
static int vesa_map_gen_mode_num(int type, int color, int mode);
static int vesa_translate_flags(u_int16_t vflags);
static int vesa_bios_init(void);
static void clear_modes(video_info_t *info, int color);
static void vesa_clear_modes(video_info_t *info, int color);
static void
dump_buffer(u_char *buf, size_t len)
@ -282,8 +283,30 @@ vesa_bios_save_restore(int code, void *p, size_t size)
return ((err != 0) || (vmf.vmf_eax != 0x4f));
}
/* map a generic video mode to a known mode */
static int
translate_flags(u_int16_t vflags)
vesa_map_gen_mode_num(int type, int color, int mode)
{
static struct {
int from;
int to;
} mode_map[] = {
{ M_TEXT_132x25, M_VESA_C132x25 },
{ M_TEXT_132x43, M_VESA_C132x43 },
{ M_TEXT_132x50, M_VESA_C132x50 },
{ M_TEXT_132x60, M_VESA_C132x60 },
};
int i;
for (i = 0; i < sizeof(mode_map)/sizeof(mode_map[0]); ++i) {
if (mode_map[i].from == mode)
return mode_map[i].to;
}
return mode;
}
static int
vesa_translate_flags(u_int16_t vflags)
{
static struct {
u_int16_t mask;
@ -373,8 +396,8 @@ vesa_bios_init(void)
vesa_vmode[modes].vi_buffer = vmode.v_lfb;
vesa_vmode[modes].vi_buffer_size = vmode.v_offscreen;
/* pixel format, memory model... */
vesa_vmode[modes].vi_flags = translate_flags(vmode.v_modeattr)
| V_INFO_VESA;
vesa_vmode[modes].vi_flags
= vesa_translate_flags(vmode.v_modeattr) | V_INFO_VESA;
++modes;
}
vesa_vmode[modes].vi_mode = EOT;
@ -386,7 +409,7 @@ vesa_bios_init(void)
}
static void
clear_modes(video_info_t *info, int color)
vesa_clear_modes(video_info_t *info, int color)
{
while (info->vi_mode != EOT) {
if ((info->vi_flags & V_INFO_COLOR) != color)
@ -432,6 +455,9 @@ vesa_get_info(int ad, int mode, video_info_t *info)
if (ad != vesa_adp->va_index)
return 1;
mode = vesa_map_gen_mode_num(vesa_adp->va_type,
vesa_adp->va_flags & V_ADP_COLOR, mode);
for (i = 0; vesa_vmode[i].vi_mode != EOT; ++i) {
if (vesa_vmode[i].vi_mode == NA)
continue;
@ -490,6 +516,8 @@ vesa_set_mode(int ad, int mode)
if (ad != vesa_adp->va_index)
return (*prevvidsw.set_mode)(ad, mode);
mode = vesa_map_gen_mode_num(vesa_adp->va_type,
vesa_adp->va_flags & V_ADP_COLOR, mode);
#ifdef SC_VIDEO_DEBUG
printf("VESA: set_mode(): %d(%x) -> %d(%x)\n",
vesa_adp->va_mode, vesa_adp->va_mode, mode, mode);
@ -697,6 +725,11 @@ vesa_diag(int level)
u_int32_t p;
int i;
#ifndef VESA_MODULE
/* call the previous handler first */
(*prevvidsw.diag)(level);
#endif
/* general adapter information */
printf("VESA: v%d.%d, %dk memory, flags:0x%x, mode table:%p (%x)\n",
((vesa_adp_info->v_version & 0xf000) >> 12) * 10
@ -806,9 +839,9 @@ vesa_load(void)
/* remove conflicting modes if we have more than one adapter */
if (adapters > 1) {
clear_modes(vesa_vmode,
(vesa_adp->va_flags & V_ADP_COLOR) ?
V_INFO_COLOR : 0);
vesa_clear_modes(vesa_vmode,
(vesa_adp->va_flags & V_ADP_COLOR) ?
V_INFO_COLOR : 0);
}
#ifdef VESA_MODULE

View file

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
* $Id: videoio.c,v 1.1 1998/09/15 18:16:38 sos Exp $
*/
#include "sc.h"
@ -189,6 +189,7 @@ static int rows_offset = 1;
static void map_mode_table(u_char *map[], u_char *table, int max);
static void clear_mode_map(int ad, u_char *map[], int max, int color);
static int map_mode_num(int mode);
static int map_gen_mode_num(int type, int color, int mode);
static int map_bios_mode_num(int type, int color, int bios_mode);
static u_char *get_mode_param(int mode);
static void fill_adapter_param(int code, video_adapter_t *adp);
@ -249,7 +250,7 @@ clear_mode_map(int ad, u_char *map[], int max, int color)
}
}
/* the non-standard video mode is based on a standard mode... */
/* map the non-standard video mode to a known mode number */
static int
map_mode_num(int mode)
{
@ -276,6 +277,58 @@ map_mode_num(int mode)
return mode;
}
/* map a generic video mode to a known mode number */
static int
map_gen_mode_num(int type, int color, int mode)
{
static struct {
int from;
int to_color;
int to_mono;
} mode_map[] = {
{ M_TEXT_80x30, M_VGA_C80x30, M_VGA_M80x30, },
{ M_TEXT_80x43, M_ENH_C80x43, M_ENH_B80x43, },
{ M_TEXT_80x50, M_VGA_C80x50, M_VGA_M80x50, },
{ M_TEXT_80x60, M_VGA_C80x60, M_VGA_M80x60, },
};
int i;
if (mode == M_TEXT_80x25) {
switch (type) {
case KD_VGA:
if (color)
return M_VGA_C80x25;
else
return M_VGA_M80x25;
break;
case KD_EGA:
if (color)
return M_ENH_C80x25;
else
return M_EGAMONO80x25;
break;
case KD_CGA:
return M_C80x25;
case KD_MONO:
case KD_HERCULES:
return M_EGAMONO80x25; /* XXX: this name is confusing */
default:
return -1;
}
}
for (i = 0; i < sizeof(mode_map)/sizeof(mode_map[0]); ++i) {
if (mode_map[i].from == mode)
return ((color) ? mode_map[i].to_color : mode_map[i].to_mono);
}
return mode;
}
/* turn the BIOS video number into our video mode number */
static int
map_bios_mode_num(int type, int color, int bios_mode)
@ -356,7 +409,7 @@ static u_char
{
if (mode >= V_MODE_MAP_SIZE)
mode = map_mode_num(mode);
if (mode < V_MODE_MAP_SIZE)
if ((mode >= 0) && (mode < V_MODE_MAP_SIZE))
return mode_map[mode];
else
return NULL;
@ -480,9 +533,14 @@ comp_adpregs(u_char *buf1, u_char *buf2)
return (identical) ? COMP_IDENTICAL : COMP_SIMILAR;
}
/* exported functions */
/* entry points */
/* all adapters */
/*
* init()
* Return the # of video adapters found; usually 1 or 0.
*
* all adapters
*/
static int
vid_init(void)
{
@ -739,7 +797,13 @@ vid_init(void)
return adapters;
}
/* all adapters */
/*
* adapter();
* Return a pointer to the video_adapter structure of the requested
* adapter.
*
* all adapters
*/
static video_adapter_t
*vid_adapter(int ad)
{
@ -750,7 +814,12 @@ static video_adapter_t
return &adapter[ad];
}
/* all adapters */
/*
* get_info():
* Return the video_info structure of the requested video mode.
*
* all adapters
*/
static int
vid_get_info(int ad, int mode, video_info_t *info)
{
@ -761,6 +830,8 @@ vid_get_info(int ad, int mode, video_info_t *info)
if ((ad < 0) || (ad >= adapters))
return 1;
mode = map_gen_mode_num(adapter[ad].va_type,
adapter[ad].va_flags & V_ADP_COLOR, mode);
if (adapter[ad].va_flags & V_ADP_MODECHANGE) {
/*
* If the parameter table entry for this mode is not found,
@ -789,7 +860,14 @@ vid_get_info(int ad, int mode, video_info_t *info)
return 1;
}
/* all adapters */
/*
* query_mode():
* Find a video mode matching the requested parameters.
* Fields filled with 0 are considered "don't care" fields and
* match any modes.
*
* all adapters
*/
static int
vid_query_mode(int ad, video_info_t *info)
{
@ -836,7 +914,12 @@ vid_query_mode(int ad, video_info_t *info)
return -1;
}
/* EGA/VGA */
/*
* set_mode():
* Change the video mode.
*
* EGA/VGA
*/
static int
vid_set_mode(int ad, int mode)
{
@ -845,6 +928,8 @@ vid_set_mode(int ad, int mode)
prologue(ad, V_ADP_MODECHANGE, 1);
mode = map_gen_mode_num(adapter[ad].va_type,
adapter[ad].va_flags & V_ADP_COLOR, mode);
if (vid_get_info(ad, mode, &info))
return 1;
params.sig = V_STATE_SIG;
@ -1061,7 +1146,12 @@ set_normal_mode(video_adapter_t *adp, u_char *buf)
splx(s);
}
/* EGA/VGA */
/*
* save_font():
* Read the font data in the requested font page from the video adapter.
*
* EGA/VGA
*/
static int
vid_save_font(int ad, int page, int fontsize, u_char *data, int ch, int count)
{
@ -1092,6 +1182,7 @@ vid_save_font(int ad, int page, int fontsize, u_char *data, int ch, int count)
if (page > 3)
segment -= 0xe000;
#ifndef SC_BAD_FLICKER
if (adapter[ad].va_type == KD_VGA) { /* what about EGA? XXX */
s = splhigh();
outb(TSIDX, 0x00); outb(TSREG, 0x01);
@ -1100,6 +1191,7 @@ vid_save_font(int ad, int page, int fontsize, u_char *data, int ch, int count)
outb(TSIDX, 0x00); outb(TSREG, 0x03);
splx(s);
}
#endif
set_font_mode(&adapter[ad], buf);
if (fontsize == 32) {
@ -1114,6 +1206,7 @@ vid_save_font(int ad, int page, int fontsize, u_char *data, int ch, int count)
}
set_normal_mode(&adapter[ad], buf);
#ifndef SC_BAD_FLICKER
if (adapter[ad].va_type == KD_VGA) {
s = splhigh();
outb(TSIDX, 0x00); outb(TSREG, 0x01);
@ -1121,11 +1214,19 @@ vid_save_font(int ad, int page, int fontsize, u_char *data, int ch, int count)
outb(TSIDX, 0x00); outb(TSREG, 0x03);
splx(s);
}
#endif
return 0;
}
/* EGA/VGA */
/*
* load_font():
* Set the font data in the requested font page.
* NOTE: it appears that some recent video adapters do not support
* the font page other than 0... XXX
*
* EGA/VGA
*/
static int
vid_load_font(int ad, int page, int fontsize, u_char *data, int ch, int count)
{
@ -1156,6 +1257,7 @@ vid_load_font(int ad, int page, int fontsize, u_char *data, int ch, int count)
if (page > 3)
segment -= 0xe000;
#ifndef SC_BAD_FLICKER
if (adapter[ad].va_type == KD_VGA) { /* what about EGA? XXX */
s = splhigh();
outb(TSIDX, 0x00); outb(TSREG, 0x01);
@ -1164,6 +1266,7 @@ vid_load_font(int ad, int page, int fontsize, u_char *data, int ch, int count)
outb(TSIDX, 0x00); outb(TSREG, 0x03);
splx(s);
}
#endif
set_font_mode(&adapter[ad], buf);
if (fontsize == 32) {
@ -1178,6 +1281,7 @@ vid_load_font(int ad, int page, int fontsize, u_char *data, int ch, int count)
}
set_normal_mode(&adapter[ad], buf);
#ifndef SC_BAD_FLICKER
if (adapter[ad].va_type == KD_VGA) {
s = splhigh();
outb(TSIDX, 0x00); outb(TSREG, 0x01);
@ -1185,11 +1289,19 @@ vid_load_font(int ad, int page, int fontsize, u_char *data, int ch, int count)
outb(TSIDX, 0x00); outb(TSREG, 0x03);
splx(s);
}
#endif
return 0;
}
/* EGA/VGA */
/*
* show_font():
* Activate the requested font page.
* NOTE: it appears that some recent video adapters do not support
* the font page other than 0... XXX
*
* EGA/VGA
*/
static int
vid_show_font(int ad, int page)
{
@ -1207,7 +1319,12 @@ vid_show_font(int ad, int page)
return 0;
}
/* VGA */
/*
* save_palette():
* Read DAC values. The values have expressed in 8 bits.
*
* VGA
*/
static int
vid_save_palette(int ad, u_char *palette)
{
@ -1226,7 +1343,12 @@ vid_save_palette(int ad, u_char *palette)
return 0;
}
/* VGA */
/*
* load_palette():
* Set DAC values.
*
* VGA
*/
static int
vid_load_palette(int ad, u_char *palette)
{
@ -1243,7 +1365,12 @@ vid_load_palette(int ad, u_char *palette)
return 0;
}
/* CGA/EGA/VGA */
/*
* set_border():
* Change the border color.
*
* CGA/EGA/VGA
*/
static int
vid_set_border(int ad, int color)
{
@ -1266,7 +1393,14 @@ vid_set_border(int ad, int color)
return 0;
}
/* VGA */
/*
* save_state():
* Read video register values.
* NOTE: this function only reads the standard EGA/VGA registers.
* any extra/extended registers of SVGA adapters are not saved.
*
* VGA
*/
static int
vid_save_state(int ad, void *p, size_t size)
{
@ -1345,7 +1479,14 @@ vid_save_state(int ad, void *p, size_t size)
return 0;
}
/* EGA/VGA */
/*
* load_state():
* Set video registers at once.
* NOTE: this function only updates the standard EGA/VGA registers.
* any extra/extended registers of SVGA adapters are not changed.
*
* EGA/VGA
*/
static int
vid_load_state(int ad, void *p)
{
@ -1402,7 +1543,10 @@ vid_load_state(int ad, void *p)
return 0;
}
/* all */
/*
* set_origin():
* Change the origin (window mapping) of the banked frame buffer.
*/
static int
vid_set_origin(int ad, off_t offset)
{
@ -1413,7 +1557,12 @@ vid_set_origin(int ad, off_t offset)
return 1;
}
/* all */
/*
* read_hw_cursor():
* Read the position of the hardware text cursor.
*
* all adapters
*/
static int
vid_read_hw_cursor(int ad, int *col, int *row)
{
@ -1440,7 +1589,13 @@ vid_read_hw_cursor(int ad, int *col, int *row)
return 0;
}
/* all */
/*
* set_hw_cursor():
* Move the hardware text cursor. If the requested position is (-1, -1),
* the text cursor won't be shown.
*
* all adapters
*/
static int
vid_set_hw_cursor(int ad, int col, int row)
{
@ -1540,6 +1695,13 @@ dump_buffer(u_char *buf, size_t len)
}
}
/*
* diag():
* Print some information about the video adapter and video modes,
* with requested level of details.
*
* all adapters
*/
static int
vid_diag(int level)
{