Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 02 Sep 2004 01:24:34 +0800
From:      Deng XueFeng <dsnofe@msn.com>
To:        "Cyrille Lefevre" <clefevre-lists@9online.fr>
Cc:        current@freebsd.org
Subject:   Re: [BETA PATCH] VESA mode support for syscons
Message-ID:  <20040902012216.E864.DSNOFE@msn.com>
In-Reply-To: <002f01c49020$5e9df560$7890a8c0@gits.invalid>
References:  <BAY11-DAV3OkevWWGxe00021773@hotmail.com> <002f01c49020$5e9df560$7890a8c0@gits.invalid>

index | next in thread | previous in thread | raw e-mail

[-- Attachment #1 --]
This is the new patch.
but i haven't  test du to the limit of opt_sche.h
you can try this patch after current is not broken.
I wanna go to sleep.
so sleepy.
Zzzzzzzz...

Sincerely,
Deng XueFeng
MSN: dsnofe@msn.com
http://www.dengh.com

[-- Attachment #2 --]
? freebsd-syscons-patch-0902.diff
? new.diff
? syscons.diff
Index: scvesactl.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/syscons/scvesactl.c,v
retrieving revision 1.20
diff -u -r1.20 scvesactl.c
--- scvesactl.c	16 Jun 2004 09:46:58 -0000	1.20
+++ scvesactl.c	1 Sep 2004 17:04:15 -0000
@@ -2,6 +2,9 @@
  * Copyright (c) 1998 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
  * All rights reserved.
  *
+ * This code is derived from software contributed to The DragonFly Project
+ * by Sascha Wildner <saw@online.de>
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -105,6 +108,17 @@
 			return ENODEV;
 		mode = (cmd & 0xff) + M_VESA_BASE;
 		return sc_set_graphics_mode(scp, tp, mode);
+	default:
+		if (IOCGROUP(cmd) == 'V') {
+			if (!(scp->sc->adp->va_flags & V_ADP_MODECHANGE))
+				return ENODEV;
+
+			mode = (cmd & 0xff) + M_VESA_BASE;
+
+			if ((mode > M_VESA_FULL_1280) &&
+			    (mode < M_VESA_MODE_MAX))
+				return sc_set_graphics_mode(scp, tp, mode);
+		}
 	}
 
 	if (prev_user_ioctl)
Index: scvgarndr.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/syscons/scvgarndr.c,v
retrieving revision 1.15
diff -u -r1.15 scvgarndr.c
--- scvgarndr.c	30 May 2004 20:08:42 -0000	1.15
+++ scvgarndr.c	1 Sep 2004 17:04:16 -0000
@@ -2,6 +2,9 @@
  * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
  * All rights reserved.
  *
+ * This code is derived from software contributed to The DragonFly Project
+ * by Sascha Wildner <saw@online.de>
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -63,15 +66,22 @@
 #endif
 
 #ifdef SC_PIXEL_MODE
-static vr_clear_t		vga_pxlclear;
-static vr_draw_border_t		vga_pxlborder;
+static vr_init_t		vga_rndrinit;
+static vr_clear_t		vga_pxlclear_direct;
+static vr_clear_t		vga_pxlclear_planar;
+static vr_draw_border_t		vga_pxlborder_direct;
+static vr_draw_border_t		vga_pxlborder_planar;
 static vr_draw_t		vga_egadraw;
-static vr_draw_t		vga_vgadraw;
+static vr_draw_t		vga_vgadraw_direct;
+static vr_draw_t		vga_vgadraw_planar;
 static vr_set_cursor_t		vga_pxlcursor_shape;
-static vr_draw_cursor_t		vga_pxlcursor;
-static vr_blink_cursor_t	vga_pxlblink;
+static vr_draw_cursor_t		vga_pxlcursor_direct;
+static vr_draw_cursor_t		vga_pxlcursor_planar;
+static vr_blink_cursor_t	vga_pxlblink_direct;
+static vr_blink_cursor_t	vga_pxlblink_planar;
 #ifndef SC_NO_CUTPASTE
-static vr_draw_mouse_t		vga_pxlmouse;
+static vr_draw_mouse_t		vga_pxlmouse_direct;
+static vr_draw_mouse_t		vga_pxlmouse_planar;
 #else
 #define vga_pxlmouse		(vr_draw_mouse_t *)vga_nop
 #endif
@@ -84,6 +94,7 @@
 static void			vga_nop(scr_stat *scp, ...);
 
 static sc_rndr_sw_t txtrndrsw = {
+	(vr_init_t *)vga_nop,
 	vga_txtclear,
 	vga_txtborder,
 	vga_txtdraw,	
@@ -100,32 +111,35 @@
 
 #ifdef SC_PIXEL_MODE
 static sc_rndr_sw_t egarndrsw = {
-	vga_pxlclear,
-	vga_pxlborder,
+	(vr_init_t *)vga_nop,
+	vga_pxlclear_planar,
+	vga_pxlborder_planar,
 	vga_egadraw,
 	vga_pxlcursor_shape,
-	vga_pxlcursor,
-	vga_pxlblink,
+	vga_pxlcursor_planar,
+	vga_pxlblink_planar,
 	(vr_set_mouse_t *)vga_nop,
-	vga_pxlmouse,
+	vga_pxlmouse_planar,
 };
 RENDERER(ega, PIXEL_MODE, egarndrsw, vga_set);
 
 static sc_rndr_sw_t vgarndrsw = {
-	vga_pxlclear,
-	vga_pxlborder,
-	vga_vgadraw,
+	vga_rndrinit,
+	(vr_clear_t *)vga_nop,
+	(vr_draw_border_t *)vga_nop,
+	(vr_draw_t *)vga_nop,
 	vga_pxlcursor_shape,
-	vga_pxlcursor,
-	vga_pxlblink,
+	(vr_draw_cursor_t *)vga_nop,
+	(vr_blink_cursor_t *)vga_nop,
 	(vr_set_mouse_t *)vga_nop,
-	vga_pxlmouse,
+	(vr_draw_mouse_t *)vga_nop,
 };
 RENDERER(vga, PIXEL_MODE, vgarndrsw, vga_set);
 #endif /* SC_PIXEL_MODE */
 
 #ifndef SC_NO_MODE_CHANGE
 static sc_rndr_sw_t grrndrsw = {
+	(vr_init_t *)vga_nop,
 	(vr_clear_t *)vga_nop,
 	vga_grborder,
 	(vr_draw_t *)vga_nop,
@@ -155,6 +169,54 @@
 #endif
 #endif
 
+#ifdef SC_PIXEL_MODE
+#define	VIDEO_MEMORY_POS(scp, pos, x) 					\
+	scp->sc->adp->va_window +					\
+	x * scp->xoff +							\
+	scp->yoff * scp->font_size * scp->sc->adp->va_line_width +	\
+	x * (pos % scp->xsize) +					\
+	scp->font_size * scp->sc->adp->va_line_width * (pos / scp->xsize)
+
+#define	vga_drawpxl(pos, color)						\
+	switch (scp->sc->adp->va_info.vi_depth) {			\
+		case 32:						\
+		case 24:						\
+			writel(pos, vga_palette32[color]);		\
+			break;						\
+		case 16:						\
+			if (scp->sc->adp->va_info.vi_pixel_fsizes[1] == 5)\
+				writew(pos, vga_palette15[color]);	\
+			else						\
+				writew(pos, vga_palette16[color]);	\
+			break;						\
+		case 15:						\
+			writew(pos, vga_palette15[color]);		\
+			break;						\
+		}
+	
+static uint32_t vga_palette32[16] = {
+	0x000000, 0x0000ad, 0x00ad00, 0x00adad,
+	0xad0000, 0xad00ad, 0xad5200, 0xadadad,
+	0x525252, 0x5252ff, 0x52ff52, 0x52ffff,
+	0xff5252, 0xff52ff, 0xffff52, 0xffffff
+};
+
+static uint16_t vga_palette16[16] = {
+	0x0000, 0x0016, 0x0560, 0x0576, 0xb000, 0xb016, 0xb2a0, 0xb576,
+	0x52aa, 0x52bf, 0x57ea, 0x57ff, 0xfaaa, 0xfabf, 0xffea, 0xffff
+};
+
+static uint16_t vga_palette15[16] = {
+	0x0000, 0x0016, 0x02c0, 0x02d6, 0x5800, 0x5816, 0x5940, 0x5ad6,
+	0x294a, 0x295f, 0x2bea, 0x2bff, 0x7d4a, 0x7d5f, 0x7fea, 0x7fff
+};
+
+#ifndef SC_NO_CUTPASTE
+static uint32_t mouse_buf32[256];
+static uint16_t mouse_buf16[256];
+#endif
+#endif
+
 static void
 vga_nop(scr_stat *scp, ...)
 {
@@ -431,7 +493,49 @@
 /* pixel (raster text) mode renderer */
 
 static void
-vga_pxlclear(scr_stat *scp, int c, int attr)
+vga_rndrinit(scr_stat *scp)
+{
+	if (scp->sc->adp->va_info.vi_mem_model == V_INFO_MM_PLANAR) {
+		scp->rndr->clear = vga_pxlclear_planar;
+		scp->rndr->draw_border = vga_pxlborder_planar;
+		scp->rndr->draw = vga_vgadraw_planar;
+		scp->rndr->draw_cursor = vga_pxlcursor_planar;
+		scp->rndr->blink_cursor = vga_pxlblink_planar;
+		scp->rndr->draw_mouse = vga_pxlmouse_planar;
+	} else if (scp->sc->adp->va_info.vi_mem_model == V_INFO_MM_DIRECT) {
+		scp->rndr->clear = vga_pxlclear_direct;
+		scp->rndr->draw_border = vga_pxlborder_direct;
+		scp->rndr->draw = vga_vgadraw_direct;
+		scp->rndr->draw_cursor = vga_pxlcursor_direct;
+		scp->rndr->blink_cursor = vga_pxlblink_direct;
+		scp->rndr->draw_mouse = vga_pxlmouse_direct;
+	}
+}
+
+static void
+vga_pxlclear_direct(scr_stat *scp, int c, int attr)
+{
+	vm_offset_t p;
+	int line_width;
+	int pixel_size;
+	int lines;
+	int i;
+
+	line_width = scp->sc->adp->va_line_width;
+	pixel_size = scp->sc->adp->va_info.vi_pixel_size;
+	lines = scp->ysize * scp->font_size; 
+	p = scp->sc->adp->va_window +
+	    line_width * scp->yoff * scp->font_size +
+	    scp->xoff * 8 * pixel_size;
+
+	for (i = 0; i < lines; ++i) {
+		bzero_io((void *)p, scp->xsize * 8 * pixel_size);
+		p += line_width;
+	}
+}
+
+static void
+vga_pxlclear_planar(scr_stat *scp, int c, int attr)
 {
 	vm_offset_t p;
 	int line_width;
@@ -457,7 +561,64 @@
 }
 
 static void
-vga_pxlborder(scr_stat *scp, int color)
+vga_pxlborder_direct(scr_stat *scp, int color)
+{
+	vm_offset_t s;
+	vm_offset_t e;
+	vm_offset_t f;
+	int line_width;
+	int pixel_size;
+	int x;
+	int y;
+	int i;
+
+	line_width = scp->sc->adp->va_line_width;
+	pixel_size = scp->sc->adp->va_info.vi_pixel_size;
+
+	if (scp->yoff > 0) {
+		s = scp->sc->adp->va_window;
+		e = s + line_width * scp->yoff * scp->font_size;
+
+		for (f = s; f < e; f += pixel_size)
+			vga_drawpxl(f, color);
+	}
+
+	y = (scp->yoff + scp->ysize) * scp->font_size;
+
+	if (scp->ypixel > y) {
+		s = scp->sc->adp->va_window + line_width * y;
+		e = s + line_width * (scp->ypixel - y);
+
+		for (f = s; f < e; f += pixel_size)
+			vga_drawpxl(f, color);
+	}
+
+	y = scp->yoff * scp->font_size;
+	x = scp->xpixel / 8 - scp->xoff - scp->xsize;
+
+	for (i = 0; i < scp->ysize * scp->font_size; ++i) {
+		if (scp->xoff > 0) {
+			s = scp->sc->adp->va_window + line_width * (y + i);
+			e = s + scp->xoff * 8 * pixel_size;
+
+			for (f = s; f < e; f += pixel_size)
+				vga_drawpxl(f, color);
+		}
+
+		if (x > 0) {
+			s = scp->sc->adp->va_window + line_width * (y + i) +
+			    scp->xoff * 8 * pixel_size +
+			    scp->xsize * 8 * pixel_size;
+			e = s + x * 8 * pixel_size;
+
+			for (f = s; f < e; f += pixel_size)
+				vga_drawpxl(f, color);
+		}
+	}
+}
+
+static void
+vga_pxlborder_planar(scr_stat *scp, int color)
 {
 	vm_offset_t p;
 	int line_width;
@@ -506,11 +667,8 @@
 	u_char c;
 
 	line_width = scp->sc->adp->va_line_width;
-	d = scp->sc->adp->va_window
-		+ scp->xoff 
-		+ scp->yoff*scp->font_size*line_width 
-		+ (from%scp->xsize) 
-		+ scp->font_size*line_width*(from/scp->xsize);
+
+	d = VIDEO_MEMORY_POS(scp, from, 1);
 
 	outw(GDCIDX, 0x0005);		/* read mode 0, write mode 0 */
 	outw(GDCIDX, 0x0003);		/* data rotate/function select */
@@ -554,8 +712,58 @@
 	outw(GDCIDX, 0xff08);		/* bit mask */
 }
 
-static void 
-vga_vgadraw(scr_stat *scp, int from, int count, int flip)
+static void
+vga_vgadraw_direct(scr_stat *scp, int from, int count, int flip)
+{
+	vm_offset_t d = 0;
+	vm_offset_t e;
+	u_char *f;
+	u_short col1, col2, color;
+	int line_width, pixel_size;
+	int i, j, k;
+	int a;
+
+	line_width = scp->sc->adp->va_line_width;
+	pixel_size = scp->sc->adp->va_info.vi_pixel_size;
+
+	d = VIDEO_MEMORY_POS(scp, from, 8 * pixel_size);
+
+	if (from + count > scp->xsize * scp->ysize)
+		count = scp->xsize * scp->ysize - from;
+
+	for (i = from; count-- > 0; ++i) {
+		a = sc_vtb_geta(&scp->vtb, i);
+
+		if (flip) {
+			col1 = (((a & 0x7000) >> 4) | (a & 0x0800)) >> 8;
+			col2 = (((a & 0x8000) >> 4) | (a & 0x0700)) >> 8;
+		} else {
+			col1 = (a & 0x0f00) >> 8;
+			col2 = (a & 0xf000) >> 12;
+		}
+
+		e = d;
+		f = &(scp->font[sc_vtb_getc(&scp->vtb, i) * scp->font_size]);
+
+		for (j = 0; j < scp->font_size; ++j, ++f) {
+			for (k = 0; k < 8; ++k) {
+				color = *f & (1 << (7 - k)) ? col1 : col2;
+				vga_drawpxl(e + pixel_size * k, color);
+			}
+
+			e += line_width;
+		}
+
+		d += 8 * pixel_size;
+
+		if ((i % scp->xsize) == scp->xsize - 1)
+			d += scp->xoff * 16 * pixel_size +
+			     (scp->font_size - 1) * line_width;
+	}
+}
+
+static void
+vga_vgadraw_planar(scr_stat *scp, int from, int count, int flip)
 {
 	vm_offset_t d;
 	vm_offset_t e;
@@ -567,12 +775,9 @@
 	int a;
 	u_char c;
 
+	d = VIDEO_MEMORY_POS(scp, from, 1);
+
 	line_width = scp->sc->adp->va_line_width;
-	d = scp->sc->adp->va_window
-		+ scp->xoff 
-		+ scp->yoff*scp->font_size*line_width 
-		+ (from%scp->xsize) 
-		+ scp->font_size*line_width*(from/scp->xsize);
 
 	outw(GDCIDX, 0x0305);		/* read mode 0, write mode 3 */
 	outw(GDCIDX, 0x0003);		/* data rotate/function select */
@@ -630,7 +835,49 @@
 }
 
 static void 
-draw_pxlcursor(scr_stat *scp, int at, int on, int flip)
+draw_pxlcursor_direct(scr_stat *scp, int at, int on, int flip)
+{
+	vm_offset_t d = 0;
+	u_char *f;
+	int line_width, pixel_size;
+	int height;
+	int col1, col2, color;
+	int a;
+	int i, j;
+
+	line_width = scp->sc->adp->va_line_width;
+	pixel_size = scp->sc->adp->va_info.vi_pixel_size;
+
+	d = VIDEO_MEMORY_POS(scp, at, 8 * pixel_size) +
+	    (scp->font_size - scp->curs_attr.base - 1) * line_width;
+
+	a = sc_vtb_geta(&scp->vtb, at);
+
+	if (flip) {
+		col1 = ((on) ? (a & 0x0f00) : ((a & 0xf000) >> 4)) >> 8;
+		col2 = ((on) ? ((a & 0xf000) >> 4) : (a & 0x0f00)) >> 8;
+	} else {
+		col1 = ((on) ? ((a & 0xf000) >> 4) : (a & 0x0f00)) >> 8;
+		col2 = ((on) ? (a & 0x0f00) : ((a & 0xf000) >> 4)) >> 8;
+	}
+
+	f = &(scp->font[sc_vtb_getc(&scp->vtb, at) * scp->font_size +
+	      scp->font_size - scp->curs_attr.base - 1]);
+
+	height = imin(scp->curs_attr.height, scp->font_size);
+
+	for (i = 0; i < height; ++i, --f) {
+		for (j = 0; j < 8; ++j) {
+			color = *f & (1 << (7 - j)) ? col1 : col2;
+			vga_drawpxl(d + pixel_size * j, color);
+		}
+
+		d -= line_width;
+	}
+}
+
+static void 
+draw_pxlcursor_planar(scr_stat *scp, int at, int on, int flip)
 {
 	vm_offset_t d;
 	u_char *f;
@@ -642,12 +889,9 @@
 	u_char c;
 
 	line_width = scp->sc->adp->va_line_width;
-	d = scp->sc->adp->va_window
-		+ scp->xoff 
-		+ scp->yoff*scp->font_size*line_width 
-		+ (at%scp->xsize) 
-		+ scp->font_size*line_width*(at/scp->xsize)
-		+ (scp->font_size - scp->curs_attr.base - 1)*line_width;
+
+	d = VIDEO_MEMORY_POS(scp, at, 1) +
+	    (scp->font_size - scp->curs_attr.base - 1) * line_width;
 
 	outw(GDCIDX, 0x0005);		/* read mode 0, write mode 0 */
 	outw(GDCIDX, 0x0003);		/* data rotate/function select */
@@ -684,7 +928,35 @@
 static int pxlblinkrate = 0;
 
 static void 
-vga_pxlcursor(scr_stat *scp, int at, int blink, int on, int flip)
+vga_pxlcursor_direct(scr_stat *scp, int at, int blink, int on, int flip)
+{
+	if (scp->curs_attr.height <= 0)	/* the text cursor is disabled */
+		return;
+
+	if (on) {
+		if (!blink) {
+			scp->status |= VR_CURSOR_ON;
+			draw_pxlcursor_direct(scp, at, on, flip);
+		} else if (++pxlblinkrate & 4) {
+			pxlblinkrate = 0;
+			scp->status ^= VR_CURSOR_ON;
+			draw_pxlcursor_direct(scp, at,
+					      scp->status & VR_CURSOR_ON,
+					      flip);
+		}
+	} else {
+		if (scp->status & VR_CURSOR_ON)
+			draw_pxlcursor_direct(scp, at, on, flip);
+		scp->status &= ~VR_CURSOR_ON;
+	}
+	if (blink)
+		scp->status |= VR_CURSOR_BLINK;
+	else
+		scp->status &= ~VR_CURSOR_BLINK;
+}
+
+static void 
+vga_pxlcursor_planar(scr_stat *scp, int at, int blink, int on, int flip)
 {
 	if (scp->curs_attr.height <= 0)	/* the text cursor is disabled */
 		return;
@@ -692,17 +964,17 @@
 	if (on) {
 		if (!blink) {
 			scp->status |= VR_CURSOR_ON;
-			draw_pxlcursor(scp, at, on, flip);
+			draw_pxlcursor_planar(scp, at, on, flip);
 		} else if (++pxlblinkrate & 4) {
 			pxlblinkrate = 0;
 			scp->status ^= VR_CURSOR_ON;
-			draw_pxlcursor(scp, at,
-				       scp->status & VR_CURSOR_ON,
-				       flip);
+			draw_pxlcursor_planar(scp, at,
+					      scp->status & VR_CURSOR_ON,
+					      flip);
 		}
 	} else {
 		if (scp->status & VR_CURSOR_ON)
-			draw_pxlcursor(scp, at, on, flip);
+			draw_pxlcursor_planar(scp, at, on, flip);
 		scp->status &= ~VR_CURSOR_ON;
 	}
 	if (blink)
@@ -712,7 +984,7 @@
 }
 
 static void
-vga_pxlblink(scr_stat *scp, int at, int flip)
+vga_pxlblink_direct(scr_stat *scp, int at, int flip)
 {
 	if (!(scp->status & VR_CURSOR_BLINK))
 		return;
@@ -720,13 +992,25 @@
 		return;
 	pxlblinkrate = 0;
 	scp->status ^= VR_CURSOR_ON;
-	draw_pxlcursor(scp, at, scp->status & VR_CURSOR_ON, flip);
+	draw_pxlcursor_direct(scp, at, scp->status & VR_CURSOR_ON, flip);
+}
+
+static void
+vga_pxlblink_planar(scr_stat *scp, int at, int flip)
+{
+	if (!(scp->status & VR_CURSOR_BLINK))
+		return;
+	if (!(++pxlblinkrate & 4))
+		return;
+	pxlblinkrate = 0;
+	scp->status ^= VR_CURSOR_ON;
+	draw_pxlcursor_planar(scp, at, scp->status & VR_CURSOR_ON, flip);
 }
 
 #ifndef SC_NO_CUTPASTE
 
 static void
-draw_pxlmouse(scr_stat *scp, int x, int y)
+draw_pxlmouse_planar(scr_stat *scp, int x, int y)
 {
 	vm_offset_t p;
 	int line_width;
@@ -801,7 +1085,7 @@
 }
 
 static void
-remove_pxlmouse(scr_stat *scp, int x, int y)
+remove_pxlmouse_planar(scr_stat *scp, int x, int y)
 {
 	vm_offset_t p;
 	int col, row;
@@ -858,12 +1142,101 @@
 }
 
 static void 
-vga_pxlmouse(scr_stat *scp, int x, int y, int on)
+vga_pxlmouse_direct(scr_stat *scp, int x, int y, int on)
+{
+	vm_offset_t p;
+	int line_width, pixel_size;
+	int xend, yend;
+	static int x_old = 0, xend_old = 0;
+	static int y_old = 0, yend_old = 0;
+	int i, j;
+	uint32_t *u32;
+	uint16_t *u16;
+	int bpp;
+
+	if (!on)
+		return;
+
+	bpp = scp->sc->adp->va_info.vi_depth;
+
+	if ((bpp == 16) && (scp->sc->adp->va_info.vi_pixel_fsizes[1] == 5))
+		bpp = 15;
+
+	line_width = scp->sc->adp->va_line_width;
+	pixel_size = scp->sc->adp->va_info.vi_pixel_size;
+
+	xend = imin(x + 16, scp->xpixel);
+	yend = imin(y + 16, scp->ypixel);
+
+	p = scp->sc->adp->va_window + y_old * line_width + x_old * pixel_size;
+
+	for (i = 0; i < (yend_old - y_old); i++) {
+		for (j = (xend_old - x_old - 1); j >= 0; j--) {
+			switch (bpp) {
+			case 32:
+				u32 = (uint32_t*)(p + j * pixel_size);
+				writel(u32, mouse_buf32[i * 16 + j]);
+				break;
+			case 16:
+				/* FALLTHROUGH */
+			case 15:
+				u16 = (uint16_t*)(p + j * pixel_size);
+				writew(u16, mouse_buf16[i * 16 + j]);
+				break;
+			}
+		}
+
+		p += line_width;
+	}
+
+	p = scp->sc->adp->va_window + y * line_width + x * pixel_size;
+
+	for (i = 0; i < (yend - y); i++) {
+		for (j = (xend - x - 1); j >= 0; j--) {
+			switch (bpp) {
+			case 32:
+				u32 = (uint32_t*)(p + j * pixel_size);
+				mouse_buf32[i * 16 + j] = *u32;
+				if (mouse_or_mask[i] & (1 << (15 - j)))
+					writel(u32, vga_palette32[15]);
+				else if (mouse_and_mask[i] & (1 << (15 - j)))
+					writel(u32, 0);
+				break;
+			case 16:
+				u16 = (uint16_t*)(p + j * pixel_size);
+				mouse_buf16[i * 16 + j] = *u16;
+				if (mouse_or_mask[i] & (1 << (15 - j)))
+					writew(u16, vga_palette16[15]);
+				else if (mouse_and_mask[i] & (1 << (15 - j)))
+					writew(u16, 0);
+				break;
+			case 15:
+				u16 = (uint16_t*)(p  + j * pixel_size);
+				mouse_buf16[i * 16 + j] = *u16;
+				if (mouse_or_mask[i] & (1 << (15 - j)))
+					writew(u16, vga_palette15[15]);
+				else if (mouse_and_mask[i] & (1 << (15 - j)))
+					writew(u16, 0);
+				break;
+			}
+		}
+
+		p += line_width;
+	}
+
+	x_old = x;
+	y_old = y;
+	xend_old = xend;
+	yend_old = yend;
+}
+
+static void 
+vga_pxlmouse_planar(scr_stat *scp, int x, int y, int on)
 {
 	if (on)
-		draw_pxlmouse(scp, x, y);
+		draw_pxlmouse_planar(scp, x, y);
 	else
-		remove_pxlmouse(scp, x, y);
+		remove_pxlmouse_planar(scp, x, y);
 }
 
 #endif /* SC_NO_CUTPASTE */
Index: scvidctl.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/syscons/scvidctl.c,v
retrieving revision 1.32
diff -u -r1.32 scvidctl.c
--- scvidctl.c	13 Jul 2004 16:06:19 -0000	1.32
+++ scvidctl.c	1 Sep 2004 17:04:16 -0000
@@ -2,6 +2,9 @@
  * Copyright (c) 1998 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
  * All rights reserved.
  *
+ * This code is derived from software contributed to The DragonFly Project
+ * by Sascha Wildner <saw@online.de>
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -367,16 +370,29 @@
     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
+     * 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_width*info.vi_height/8 > info.vi_window_size)
+
+    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_depth != 15) && (info.vi_depth != 16) &&
+	    (info.vi_depth != 24) && (info.vi_depth != 32))
+	    return ENODEV;
+    } else
 	return ENODEV;
 
     /* stop screen saver, etc */
Index: syscons.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/syscons/syscons.c,v
retrieving revision 1.427
diff -u -r1.427 syscons.c
--- syscons.c	5 Aug 2004 23:54:04 -0000	1.427
+++ syscons.c	1 Sep 2004 17:04:18 -0000
@@ -2,6 +2,9 @@
  * Copyright (c) 1992-1998 Søren Schmidt
  * All rights reserved.
  *
+ * This code is derived from software contributed to The DragonFly Project
+ * by Sascha Wildner <saw@online.de>
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -3036,6 +3039,7 @@
     if (sw == scp->tsw) {
 	error = (*sw->te_init)(scp, &scp->ts, SC_TE_WARM_INIT);
 	scp->rndr = rndr;
+	scp->rndr->init(scp);
 	sc_clear_screen(scp);
 	/* assert(error == 0); */
 	return error;
@@ -3056,6 +3060,7 @@
     scp->tsw = sw;
     scp->ts = p;
     scp->rndr = rndr;
+    scp->rndr->init(scp);
 
     /* XXX */
     (*sw->te_default_attr)(scp, user_default.std_color, user_default.rev_color);
@@ -3414,6 +3419,7 @@
 
     /* setup video hardware for the given mode */
     (*vidsw[scp->sc->adapter]->set_mode)(scp->sc->adp, scp->mode);
+    scp->rndr->init(scp);
 #ifndef __sparc64__
     sc_vtb_init(&scp->scr, VTB_FRAMEBUFFER, scp->xsize, scp->ysize,
 		(void *)scp->sc->adp->va_window, FALSE);
Index: syscons.h
===================================================================
RCS file: /home/ncvs/src/sys/dev/syscons/syscons.h,v
retrieving revision 1.80
diff -u -r1.80 syscons.h
--- syscons.h	28 Jul 2004 06:29:02 -0000	1.80
+++ syscons.h	1 Sep 2004 17:04:18 -0000
@@ -1,6 +1,8 @@
 /*-
  * Copyright (c) 1995-1998 Søren Schmidt
  * All rights reserved.
+ * This code is derived from software contributed to The DragonFly Project
+ * by Sascha Wildner <saw@online.de>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -405,6 +407,7 @@
 		       SI_SUB_DRIVERS, SI_ORDER_MIDDLE)
 
 /* renderer function table */
+typedef void	vr_init_t(scr_stat *scp);
 typedef void	vr_clear_t(scr_stat *scp, int c, int attr);
 typedef void	vr_draw_border_t(scr_stat *scp, int color);
 typedef void	vr_draw_t(scr_stat *scp, int from, int count, int flip);
@@ -416,6 +419,7 @@
 typedef void	vr_draw_mouse_t(scr_stat *scp, int x, int y, int on);
 
 typedef struct sc_rndr_sw {
+	vr_init_t		*init;
 	vr_clear_t		*clear;
 	vr_draw_border_t	*draw_border;
 	vr_draw_t		*draw;
help

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20040902012216.E864.DSNOFE>