Module Name:    src
Committed By:   christos
Date:           Thu Dec  9 23:33:30 UTC 2010

Modified Files:
        src/sys/dev/ic: vga.c vgavar.h

Log Message:
PR/41415: IdOp: Implement save and restore palette for vga.


To generate a diff of this commit:
cvs rdiff -u -r1.105 -r1.106 src/sys/dev/ic/vga.c
cvs rdiff -u -r1.28 -r1.29 src/sys/dev/ic/vgavar.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/ic/vga.c
diff -u src/sys/dev/ic/vga.c:1.105 src/sys/dev/ic/vga.c:1.106
--- src/sys/dev/ic/vga.c:1.105	Tue Oct 19 18:27:54 2010
+++ src/sys/dev/ic/vga.c	Thu Dec  9 18:33:30 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: vga.c,v 1.105 2010/10/19 22:27:54 jmcneill Exp $ */
+/* $NetBSD: vga.c,v 1.106 2010/12/09 23:33:30 christos Exp $ */
 
 /*
  * Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vga.c,v 1.105 2010/10/19 22:27:54 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vga.c,v 1.106 2010/12/09 23:33:30 christos Exp $");
 
 /* for WSCONS_SUPPORT_PCVTFONTS */
 #include "opt_wsdisplay_compat.h"
@@ -101,7 +101,6 @@
 	/* videostate */
 	struct egavga_font *fontset1, *fontset2;
 	/* font data */
-	/* palette */
 
 	int mindispoffset, maxdispoffset;
 	int vga_rollover;
@@ -526,7 +525,7 @@
 vga_init(struct vga_config *vc, bus_space_tag_t iot, bus_space_tag_t memt)
 {
 	struct vga_handle *vh = &vc->hdl;
-	u_int8_t mor;
+	uint8_t mor;
 	int i;
 
 	vh->vh_iot = iot;
@@ -536,7 +535,7 @@
 		panic("vga_init: couldn't map vga io");
 
 	/* read "misc output register" */
-	mor = bus_space_read_1(vh->vh_iot, vh->vh_ioh_vga, VGA_MISC_DATAR);
+	mor = vga_raw_read(vh, VGA_MISC_DATAR);
 	vh->vh_mono = !(mor & 1);
 
 	if (bus_space_map(vh->vh_iot, (vh->vh_mono ? 0x3b0 : 0x3d0), 0x10, 0,
@@ -589,6 +588,7 @@
 	if (!vh->vh_mono && (u_int)WSDISPLAY_BORDER_COLOR < sizeof(fgansitopc))
 		_vga_attr_write(vh, VGA_ATC_OVERSCAN,
 		                fgansitopc[WSDISPLAY_BORDER_COLOR]);
+	vga_save_palette(vc);
 }
 
 void
@@ -781,6 +781,11 @@
 	const struct vga_funcs *vf = vc->vc_funcs;
 
 	switch (cmd) {
+	case WSDISPLAYIO_SMODE:
+		if (*(u_int *)data == WSDISPLAYIO_MODE_EMUL)
+			vga_restore_palette(vc);
+		return 0;
+
 	case WSDISPLAYIO_GTYPE:
 		*(int *)data = vc->vc_type;
 		return 0;
@@ -1037,7 +1042,7 @@
 	}
 
 	vga_setfont(vc, scr);
-	/* XXX swich colours! */
+	vga_restore_palette(vc);
 
 	scr->pcs.visibleoffset = scr->pcs.dispoffset = scr->mindispoffset;
 	if (!oldscr || (scr->pcs.dispoffset != oldscr->pcs.dispoffset)) {
@@ -1173,7 +1178,7 @@
 #ifdef WSCONS_SUPPORT_PCVTFONTS
 
 #define NOTYET 0xffff
-static const u_int16_t pcvt_unichars[0xa0] = {
+static const uint16_t pcvt_unichars[0xa0] = {
 /* 0 */	_e006U, /* N/L control */
 	NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET,
 	NOTYET,
@@ -1444,7 +1449,7 @@
 {
 	struct vga_handle *vh = &vc->hdl;
 	u_int idx;
-	u_int8_t value;
+	uint8_t value;
 
 	if (vh->vh_mono)
 		return ENODEV;
@@ -1486,3 +1491,40 @@
 	vga_6845_write(&sc->sc_vc->hdl, curend, 0x00);
 #endif
 }
+
+void
+vga_save_palette(struct vga_config *vc)
+{
+	struct vga_handle *vh = &vc->hdl;
+	size_t i;
+	uint8_t *palette = vc->palette;
+
+	if (vh->vh_mono)
+		return;
+
+	vga_raw_write(vh, VGA_DAC_PELMASK, 0xff);
+	vga_raw_write(vh, VGA_DAC_ADDRR, 0x00);
+	for (i = 0; i < sizeof(vc->palette); i++)
+		*palette++ = vga_raw_read(vh, VGA_DAC_PALETTE);
+
+	vga_raw_read(vh, 0x0a);			/* reset flip/flop */
+}
+
+void
+vga_restore_palette(struct vga_config *vc)
+{
+	struct vga_handle *vh = &vc->hdl;
+	size_t i;
+	uint8_t *palette = vc->palette;
+
+	if (vh->vh_mono)
+		return;
+
+	vga_raw_write(vh, VGA_DAC_PELMASK, 0xff);
+	vga_raw_write(vh, VGA_DAC_ADDRW, 0x00);
+	for (i = 0; i < sizeof(vc->palette); i++)
+		vga_raw_write(vh, VGA_DAC_PALETTE, *palette++);
+
+	vga_raw_read(vh, 0x0a);			/* reset flip/flop */
+	vga_enable(vh);
+}

Index: src/sys/dev/ic/vgavar.h
diff -u src/sys/dev/ic/vgavar.h:1.28 src/sys/dev/ic/vgavar.h:1.29
--- src/sys/dev/ic/vgavar.h:1.28	Fri Mar 14 18:12:08 2008
+++ src/sys/dev/ic/vgavar.h	Thu Dec  9 18:33:30 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: vgavar.h,v 1.28 2008/03/14 22:12:08 cube Exp $ */
+/* $NetBSD: vgavar.h,v 1.29 2010/12/09 23:33:30 christos Exp $ */
 
 /*
  * Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -68,6 +68,7 @@
 	int vc_type;
 	const struct vga_funcs *vc_funcs;
 
+	u_int8_t palette[256 * 3];
 #ifndef VGA_RASTERCONSOLE
 	int currentfontset1, currentfontset2;
 	int vc_nfontslots;
@@ -91,73 +92,81 @@
 static __inline u_int8_t 	_vga_gdc_read(struct vga_handle *, int);
 static __inline void 	_vga_gdc_write(struct vga_handle *, int, u_int8_t);
 
+#define	vga_raw_read(vh, reg) \
+    bus_space_read_1(vh->vh_iot, vh->vh_ioh_vga, reg)
+#define	vga_raw_write(vh, reg, value) \
+    bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga, reg, value)
+
+#define	vga_enable(vh) \
+    vga_raw_write(vh, 0, 0x20)
+
+#define vga_reset_state(vh) \
+    (void) bus_space_read_1(vh->vh_iot, vh->vh_ioh_6845, 10)
+
 static __inline u_int8_t
 _vga_attr_read(struct vga_handle *vh, int reg)
 {
 	u_int8_t res;
 
 	/* reset state */
-	(void) bus_space_read_1(vh->vh_iot, vh->vh_ioh_6845, 10);
+	vga_reset_state(vh);
 
-	bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga, VGA_ATC_INDEX, reg);
-	res = bus_space_read_1(vh->vh_iot, vh->vh_ioh_vga, VGA_ATC_DATAR);
+	vga_raw_write(vh, VGA_ATC_INDEX, reg);
+	res = vga_raw_read(vh, VGA_ATC_DATAR);
 
-	/* reset state XXX unneeded? */
-	(void) bus_space_read_1(vh->vh_iot, vh->vh_ioh_6845, 10);
+	/* XXX unneeded? */
+	vga_reset_state(vh);
 
-	/* enable */
-	bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga, 0, 0x20);
+	vga_enable(vh);
 
-	return (res);
+	return res;
 }
 
 static __inline void
 _vga_attr_write(struct vga_handle *vh, int reg, u_int8_t val)
 {
 
-	/* reset state */
-	(void) bus_space_read_1(vh->vh_iot, vh->vh_ioh_6845, 10);
+	vga_reset_state(vh);
 
-	bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga, VGA_ATC_INDEX, reg);
-	bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga, VGA_ATC_DATAW, val);
+	vga_raw_write(vh, VGA_ATC_INDEX, reg);
+	vga_raw_write(vh, VGA_ATC_DATAW, val);
 
-	/* reset state XXX unneeded? */
-	(void) bus_space_read_1(vh->vh_iot, vh->vh_ioh_6845, 10);
+	/* XXX unneeded? */
+	vga_reset_state(vh);
 
-	/* enable */
-	bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga, 0, 0x20);
+	vga_enable(vh);
 }
 
 static __inline u_int8_t
 _vga_ts_read(struct vga_handle *vh, int reg)
 {
 
-	bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga, VGA_TS_INDEX, reg);
-	return (bus_space_read_1(vh->vh_iot, vh->vh_ioh_vga, VGA_TS_DATA));
+	vga_raw_write(vh, VGA_TS_INDEX, reg);
+	return vga_raw_read(vh, VGA_TS_DATA);
 }
 
 static __inline void
 _vga_ts_write(struct vga_handle *vh, int reg, u_int8_t val)
 {
 
-	bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga, VGA_TS_INDEX, reg);
-	bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga, VGA_TS_DATA, val);
+	vga_raw_write(vh, VGA_TS_INDEX, reg);
+	vga_raw_write(vh, VGA_TS_DATA, val);
 }
 
 static __inline u_int8_t
 _vga_gdc_read(struct vga_handle *vh, int reg)
 {
 
-	bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga, VGA_GDC_INDEX, reg);
-	return (bus_space_read_1(vh->vh_iot, vh->vh_ioh_vga, VGA_GDC_DATA));
+	vga_raw_write(vh, VGA_GDC_INDEX, reg);
+	return vga_raw_read(vh, VGA_GDC_DATA);
 }
 
 static __inline void
 _vga_gdc_write(struct vga_handle *vh, int reg, u_int8_t val)
 {
 
-	bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga, VGA_GDC_INDEX, reg);
-	bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga, VGA_GDC_DATA, val);
+	vga_raw_write(vh, VGA_GDC_INDEX, reg);
+	vga_raw_write(vh, VGA_GDC_DATA, val);
 }
 
 #define vga_attr_read(vh, reg) \
@@ -208,5 +217,7 @@
 #endif /* !VGA_RASTERCONSOLE */
 void	vga_reset(struct vga_handle *, void (*)(struct vga_handle *));
 void	vga_initregs(struct vga_handle *);
+void	vga_save_palette(struct vga_config *);
+void	vga_restore_palette(struct vga_config *);
 
 extern int vga_no_builtinfont;

Reply via email to