[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: New wsdisplay for playstation2



<10311010230.AA12846@lachesis.sm.sony.co.jp>の記事において
shin@sm.sony.co.jpさんは書きました。

> mailにある内容だけではコンパイルできないと思います。

確かにそうですね。
#toolchain を用意してなかったので手抜きしてました。すいません。

適当に添付のとおりに直すと compile は通りますが、
wsdisplay_emulops で allocattr が alloc_attr になってるとか
CFATTACH_DECL() を使ってないとかいうところを見ると
だいぶ古いソースで作業してるっぽいです。

ただ当人は最初のメールでもあった cnputc() あたりを
もう少し直すと言ってるのでしばらく待ってみます。
---
Izumi Tsutsui
tsutsui@ceres.dti.ne.jp

Index: dev/wscons/wsconsio.h
===================================================================
RCS file: /cvsroot/src/sys/dev/wscons/wsconsio.h,v
retrieving revision 1.58
diff -u -r1.58 wsconsio.h
--- dev/wscons/wsconsio.h	3 Jun 2003 06:48:12 -0000	1.58
+++ dev/wscons/wsconsio.h	1 Nov 2003 03:47:05 -0000
@@ -260,6 +260,7 @@
 #define		WSDISPLAY_TYPE_HYPERION	31	/* HP Hyperion */
 #define		WSDISPLAY_TYPE_AMIGACC	32	/* Amiga custom chips */
 #define		WSDISPLAY_TYPE_SUN24	33	/* Sun 24 bit framebuffers */
+#define		WSDISPLAY_TYPE_PS2GS	34	/* GS on Playstation2 */
 
 /* Basic display information.  Not applicable to all display types. */
 struct wsdisplay_fbinfo {
Index: arch/playstation2/conf/files.playstation2
===================================================================
RCS file: /cvsroot/src/sys/arch/playstation2/conf/files.playstation2,v
retrieving revision 1.11
diff -u -r1.11 files.playstation2
--- arch/playstation2/conf/files.playstation2	27 Jul 2003 01:19:30 -0000	1.11
+++ arch/playstation2/conf/files.playstation2	1 Nov 2003 03:47:05 -0000
@@ -39,7 +39,7 @@
 #
 #	PlayStation 2 internal devices (optional)
 #
-device	gsfb: wsemuldisplaydev
+device	gsfb: wsemuldisplaydev, rasops16, rasops32
 attach	gsfb at mainbus
 file	arch/playstation2/ee/gsfb.c			gsfb
 
@@ -82,6 +82,7 @@
 # Workstation Console
 #
 include "dev/wscons/files.wscons"
+include "dev/rasops/files.rasops"
 include "dev/wsfont/files.wsfont"
 
 include "dev/usb/files.usb"
Index: arch/playstation2/ee/gsfb.c
===================================================================
RCS file: /cvsroot/src/sys/arch/playstation2/ee/gsfb.c,v
retrieving revision 1.8
diff -u -r1.8 gsfb.c
--- arch/playstation2/ee/gsfb.c	22 Oct 2003 20:26:32 -0000	1.8
+++ arch/playstation2/ee/gsfb.c	1 Nov 2003 03:47:05 -0000
@@ -1,47 +1,7 @@
-/*	$NetBSD: gsfb.c,v 1.8 2003/10/22 20:26:32 he Exp $	*/
-
-/*-
- * Copyright (c) 2001 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by UCHIYAMA Yasushi.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *        This product includes software developed by the NetBSD
- *        Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: gsfb.c,v 1.8 2003/10/22 20:26:32 he Exp $");
-
 #include "debug_playstation2.h"
 
 #include <sys/param.h>
+#include <sys/device.h>
 #include <sys/systm.h>
 
 #include <machine/autoconf.h>
@@ -52,545 +12,351 @@
 #include <dev/wscons/wsdisplayvar.h>
 #include <dev/wscons/wscons_callbacks.h>
 
-#include <dev/wsfont/wsfont.h>
+#include <dev/rasops/rasops.h>
 
+#include <playstation2/ee/dmacvar.h>
+#include <playstation2/ee/dmacreg.h>
 #include <playstation2/ee/eevar.h>
 #include <playstation2/ee/gsvar.h>
 #include <playstation2/ee/gsreg.h>
-#include <playstation2/ee/dmacvar.h>
-#include <playstation2/ee/dmacreg.h>
+#include <playstation2/ee/intcvar.h>
 
-#ifdef DEBUG
-#define STATIC
-#else
-#define STATIC	static
-#endif
 
-STATIC struct gsfb {
-	int initialized;
-	int attached;
-	int is_console;
-	const struct wsscreen_descr *screen;
-	struct wsdisplay_font *font;
-} gsfb;
-
-STATIC void gsfb_dma_kick(paddr_t, size_t);
-STATIC void gsfb_font_expand_psmct32(const struct wsdisplay_font *, u_int,
-    long, u_int32_t *);
-STATIC __inline__ void gsfb_set_cursor_pos(u_int32_t *, int, int, int, int);
-
-#define ATTR_FG_GET(a)	(((a )>> 24) & 0xf)
-#define ATTR_BG_GET(a)	(((a )>> 16) & 0xf)
-#define ATTR_FG_SET(x)	(((x) << 24) & 0x0f000000)
-#define ATTR_BG_SET(x)	(((x) << 16) & 0x000f0000)
-
-STATIC const u_int32_t gsfb_ansi_psmct32[] = {
-	0x80000000, /* black */
-	0x800000aa, /* red */
-	0x8000aa00, /* green */
-	0x8000aaaa, /* brown */
-	0x80aa0000, /* blue */
-	0x80aa00aa, /* magenta */
-	0x80aaaa00, /* cyan */
-	0x80aaaaaa, /* white */
-	0x80000000, /* black */
-	0x800000ff, /* red */
-	0x8000ff00, /* green */
-	0x8000ffff, /* brown */
-	0x80ff0000, /* blue */
-	0x80ff00ff, /* magenta */
-	0x80ffff00, /* cyan */
-	0x80ffffff, /* black */
-};
 
-#define TRXPOS_DXY(f, x, y)						\
-({									\
-	f[9] = ((x) & 0x000007ff) | (((y) << 16) & 0x07ff0000);		\
-})
-
-#define TRXPOS_SY_DY(f, sy, dy)						\
-({									\
-	f[8] = (((sy) << 16) & 0x07ff0000);				\
-	f[9] = (((dy) << 16) & 0x07ff0000);				\
-})
-
-#define TRXPOS_DXY_SXY(f, dx, dy, sx, sy)				\
-({									\
-	f[8] = ((((sy) << 16) & 0x07ff0000) | ((sx) & 0x000007ff));	\
-	f[9] = ((((dy) << 16) & 0x07ff0000) | ((dx) & 0x000007ff));	\
-})
-
-STATIC u_int32_t gsfb_scroll_cmd_640x16[] __attribute__((__aligned__(16))) = {
-        0x00008004, 0x10000000, 0x0000000e, 0x00000000,
-        0x000a0000, 0x000a0000, 0x00000050, 0x00000000,
-        0x07ff0000, 0x07ff0000, 0x00000051, 0x00000000,
-        0x00000280, 0x00000010, 0x00000052, 0x00000000,
-        0x00000002, 0x00000000, 0x00000053, 0x00000000,
-};
+/* internal */
+void gsfb_do_redraw(void); /* XXX should be static, called from ddb */
+static void gsfb_hwinit(void);
+static void gsfb_init(void);
+static void gsfb_dma_kick_phys(paddr_t, size_t);
+static void gsfb_dma_kick_kseg0(void *, size_t);
+static void gsfb_dma_kick_kseg1(void *, size_t);
+static int vblank_intr(void *);
+
+#define GSFB_BUFFER_DEPTH 32
+#define CLEAR 1
+
+
+#if GSFB_BUFFER_DEPTH == 32
+#  define GSFB_PIXEL_SIZE 4
+#  define GSFB_BUFFER_HEIGHT 200
+#elif GSFB_BUFFER_DEPTH == 15 || GSFB_BUFFER_DEPTH == 16
+#  define GSFB_PIXEL_SIZE 2
+#  define GSFB_BUFFER_HEIGHT 400
+#else 
+#  error
+#endif
+#define GSFB_BUFFER_WIDTH 640
+#define GSFB_BUFFER_SIZE \
+    (GSFB_BUFFER_WIDTH * GSFB_BUFFER_HEIGHT * GSFB_PIXEL_SIZE)
 
-STATIC u_int32_t gsfb_cursor_cmd[] __attribute__((__aligned__(16))) = {
-	0x00008007, 0x10000000, 0x0000000e, 0x00000000,
-	0x00000001, 0x00000000, 0x0000001a, 0x00000000,
-        0x000000a4, 0x00000080, 0x00000042, 0x00000000,
-	0x00000046, 0x00000000, 0x00000000, 0x00000000,
-	0x80ffffff, 0x00000000, 0x00000001, 0x00000000,
-	0x00000000, 0x00000000, 0x0000000d, 0x00000000,
-	0x80ffffff, 0x00000000, 0x00000001, 0x00000000,
-	0x00000000, 0x00000000, 0x00000005, 0x00000000,
-};
+/* 
+ *  Documentation can be found at:
+ * What:		Where:		Pages
+ * GIFtag		EEUSER_E.pdf	151
+ * BITBLTBUF		GSUSER_E.pdf	76, 101
+ * TRXPOS		GSUSER_E.pdf	76
+ * TRXREG		GSUSER_E.pdf	77
+ * TRXDIR		GSUSER_E.pdf	77
+ * FRAME_1              GSUSER_E.pdf    110
+ * SCISSOR_1            GSUSER_E.pdf    121
+ * ZBUF_1               GSUSER_E.pdf    176
+ */
+
+#define GSFB_PACKETS(name) \
+  static u_int32_t name __attribute__((__aligned__(16)))
 
-STATIC u_int32_t gsfb_copy_cmd_8x16[] __attribute__((__aligned__(16))) = {
-        0x00008004, 0x10000000, 0x0000000e, 0x00000000,
-        0x000a0000, 0x000a0000, 0x00000050, 0x00000000,
-        0x07ff07ff, 0x07ff07ff, 0x00000051, 0x00000000,
-        0x00000008, 0x00000010, 0x00000052, 0x00000000,
-        0x00000002, 0x00000000, 0x00000053, 0x00000000,
-};
 
-STATIC u_int32_t gsfb_init_cmd_640x480[] __attribute__((__aligned__(16))) = {
-	0x00008008, 0x10000000, 0x0000000e, 0x00000000,
-	0x000a0000, 0x00000000, 0x0000004c, 0x00000000,
-	0x00000096, 0x00000000, 0x0000004e, 0x00000000,
-	0x02800000, 0x01e00000, 0x00000040, 0x00000000,
-	0x00000006, 0x00000000, 0x00000000, 0x00000000,
+GSFB_PACKETS(gsfb_init_cmd_640x480x32[]) = {
+#if CLEAR
+        0x00008008, 0x10000000, 0x0000000e, 0x00000000, /* GIFtag */
+#else
+        0x00008003, 0x10000000, 0x0000000e, 0x00000000, /* GIFtag */
+#endif
+#if GSFB_PIXEL_SIZE == 4
+	0x000a0000, 0x00000000, 0x0000004c, 0x00000000, /* FRAME_1 */
+	0x00000096, 0x00000000, 0x0000004e, 0x00000000, /* ZBUF_1 */ 
+#elif GSFB_PIXEL_SIZE == 2
+	0x020a0000, 0x00000000, 0x0000004c, 0x00000000, /* FRAME_1 */
+	0x02000096, 0x00000000, 0x0000004e, 0x00000000, /* ZBUF_1 */ 
+#else
+#error
+#endif      
+	0x02800000, 0x01e00000, 0x00000040, 0x00000000, /* SCISSOR_1 */
+#if CLEAR
+	0x00000006, 0x00000000, 0x00000000, 0x00000000, /* PRIM */ 
 	0x80000000, 0x00000000, 0x00000001, 0x00000000,
 	0x00000000, 0x00000000, 0x0000000d, 0x00000000,
 	0x80000000, 0x00000000, 0x00000001, 0x00000000,
 	0x1e002800, 0x00000000, 0x00000005, 0x00000000,
+#endif
 };
 
-STATIC u_int32_t gsfb_load_cmd_8x16_psmct32[(6 + 32) * 4]
-	__attribute__((__aligned__(16))) = {
-	/* GIF tag + GS command */
-        0x00000004, 0x10000000, 0x0000000e, 0x00000000,
-        0x00000000, 0x000a0000, 0x00000050, 0x00000000,
-        0x00000000, 0x00000000, 0x00000051, 0x00000000,
-        0x00000008, 0x00000016, 0x00000052, 0x00000000,
-        0x00000000, 0x00000000, 0x00000053, 0x00000000,
-        0x00008020, 0x08000000, 0x00000000, 0x00000000,
-	/* Load area */
-#define FONT_SCRATCH_BASE	(6 * 4)
-};
-
-#ifdef GSFB_DEBUG_MONITOR
-#include <machine/stdarg.h>
-STATIC const struct _gsfb_debug_window {
-	int start, nrow, attr;
-} _gsfb_debug_window[3] = {
-	{ 24, 2 , ATTR_BG_SET(WSCOL_BROWN) | ATTR_FG_SET(WSCOL_BLUE) },
-	{ 26, 2 , ATTR_BG_SET(WSCOL_CYAN) | ATTR_FG_SET(WSCOL_BLUE) },
-	{ 28, 2 , ATTR_BG_SET(WSCOL_WHITE) | ATTR_FG_SET(WSCOL_BLUE) },
+GSFB_PACKETS(gsfb_load_screen[]) = {
+#if GSFB_PIXEL_SIZE == 4 && GSFB_BUFFER_HEIGHT == 200
+	0x00000004, 0x10000000, 0x0000000e, 0x00000000, /* GIFtag */
+	0x00000000, 0x000a0000, 0x00000050, 0x00000000, /* BITBLTBUF */
+	0x00000000, 0x00000000, 0x00000051, 0x00000000, /* TRXPOS */
+        0x00000280, 0x000000c8, 0x00000052, 0x00000000, /* TRXREG */
+        0x00000000, 0x00000000, 0x00000053, 0x00000000, /* TRXDIR */
+        0x0000fd00, 0x08000000, 0x00000000, 0x00000000, /* GIFtag */
+#elif GSFB_PIXEL_SIZE == 2 && GSFB_BUFFER_HEIGHT == 400
+	0x00000004, 0x10000000, 0x0000000e, 0x00000000, /* GIFtag */
+	0x00000000, 0x020a0000, 0x00000050, 0x00000000, /* BITBLTBUF */
+	0x00000000, 0x00000000, 0x00000051, 0x00000000, /* TRXPOS */
+        0x00000280, 0x00000190, 0x00000052, 0x00000000, /* TRXREG */
+        0x00000000, 0x00000000, 0x00000053, 0x00000000, /* TRXDIR */
+        0x0000fd00, 0x08000000, 0x00000000, 0x00000000, /* GIFtag */
+#else
+#error
+#endif 
 };
-STATIC char _gsfb_debug_buf[80 * 2];
-#endif /* GSFB_DEBUG_MONITOR */
 
-STATIC int gsfb_match(struct device *, struct cfdata *, void *);
-STATIC void gsfb_attach(struct device *, struct device *, void *);
+static int gsfb_nscreens = 0;
+static int gsfb_attached = 0;
+static int gsfb_console = 0;
+static char * gsfb_screen_base = 0;
+char gsfb_screen_mem[GSFB_BUFFER_SIZE + sizeof gsfb_load_screen + NBPG]; 
+static struct rasops_info gsfb_rinfo;
 
-CFATTACH_DECL(gsfb, sizeof(struct device),
-    gsfb_match, gsfb_attach, NULL, NULL);
+static int gsfb_match(struct device *, struct cfdata *, void *);
+static void gsfb_attach(struct device *, struct device *, void *);
 
-STATIC void gsfb_hwinit(void);
-STATIC int gsfb_swinit(void);
+CFATTACH_DECL(gsfb, sizeof(struct device), gsfb_match, gsfb_attach, NULL, NULL);
 
-/* console */
+/* console (exported) */
 void gsfbcnprobe(struct consdev *);
 void gsfbcninit(struct consdev *);
 
-/* emul ops */
-STATIC void _gsfb_cursor(void *, int, int, int);
-STATIC int _gsfb_mapchar(void *, int, unsigned int *);
-STATIC void _gsfb_putchar(void *, int, int, u_int, long);
-STATIC void _gsfb_copycols(void *, int, int, int, int);
-STATIC void _gsfb_erasecols(void *, int, int, int, long);
-STATIC void _gsfb_copyrows(void *, int, int, int);
-STATIC void _gsfb_eraserows(void *, int, int, long);
-STATIC int _gsfb_allocattr(void *, int, int, int, long *);
-
 /* access ops */
-STATIC int _gsfb_ioctl(void *, u_long, caddr_t, int, struct proc *);
-STATIC paddr_t _gsfb_mmap(void *, off_t, int);
-STATIC int _gsfb_alloc_screen(void *, const struct wsscreen_descr *, void **,
-    int *, int *, long *);
-STATIC void _gsfb_free_screen(void *, void *);
-STATIC int _gsfb_show_screen(void *, void *, int, void (*)(void *, int, int),
-    void *);
-STATIC void _gsfb_pollc(void *, int);
-
-/* 
- * wsdisplay attach args 
- *   std: screen size 640 x 480, font size 8 x 16
- */
-#define GSFB_STD_SCREEN_WIDTH		640
-#define GSFB_STD_SCREEN_HEIGHT		480
-#define GSFB_STD_FONT_WIDTH		8
-#define GSFB_STD_FONT_HEIGHT		16
-const struct wsdisplay_emulops _gsfb_emulops = {
-	.cursor		= _gsfb_cursor,
-	.mapchar	= _gsfb_mapchar,
-	.putchar	= _gsfb_putchar,
-	.copycols	= _gsfb_copycols,
-	.erasecols	= _gsfb_erasecols,
-	.copyrows	= _gsfb_copyrows,
-	.eraserows	= _gsfb_eraserows,
-	.allocattr	= _gsfb_allocattr
+static int gsfb_ioctl(void *, u_long, caddr_t, int, struct proc *);
+static paddr_t gsfb_mmap(void *, off_t, int);
+static int gsfb_alloc_screen(void *, const struct wsscreen_descr *, void **,
+			     int *, int *, long *);
+static void gsfb_free_screen(void *, void *);
+static int gsfb_show_screen(void *, void *, int, void (*)(void *, int, int),
+			     void *);
+
+static const struct wsdisplay_accessops gsfb_accessops = {
+	.ioctl		= gsfb_ioctl,
+	.mmap		= gsfb_mmap,
+	.alloc_screen	= gsfb_alloc_screen,
+	.free_screen	= gsfb_free_screen,
+	.show_screen	= gsfb_show_screen,
+	.load_font	= 0,
 };
 
-const struct wsscreen_descr _gsfb_std_screen = {
-	.name		= "std",
-	.ncols		= 80,
-#ifdef GSFB_DEBUG_MONITOR
-	.nrows		= 24,
-#else
-	.nrows		= 30,
-#endif
-	.textops	= &_gsfb_emulops,
-	.fontwidth	= 8,
-	.fontheight	= 16,
-	.capabilities	= WSSCREEN_UNDERLINE | WSSCREEN_HILIT |
-	WSSCREEN_WSCOLORS
-};
 
-const struct wsscreen_descr *_gsfb_screen_table[] = {
-	&_gsfb_std_screen,
+static struct wsscreen_descr gsfb_stdscreen = {
+	.name = "std", 
+	.ncols = 0, 
+	.nrows = 0, 
+	.textops = 0, 
+	.fontwidth = 0,
+	.fontheight = 0,
+	.capabilities = WSSCREEN_WSCOLORS
 };
 
-struct wsscreen_list _gsfb_screen_list = {
-	.nscreens	= sizeof(_gsfb_screen_table) /
-	sizeof(_gsfb_screen_table[0]),
-	.screens	= _gsfb_screen_table
+static const struct wsscreen_descr * gsfb_screen_table[] = {
+	&gsfb_stdscreen,
 };
 
-struct wsdisplay_accessops _gsfb_accessops = {
-	.ioctl		= _gsfb_ioctl,
-	.mmap		= _gsfb_mmap,
-	.alloc_screen	= _gsfb_alloc_screen,
-	.free_screen	= _gsfb_free_screen,
-	.show_screen	= _gsfb_show_screen,
-	.load_font	= 0,
-	.pollc		= _gsfb_pollc
+static const struct wsscreen_list gsfb_screen_list = {
+	.nscreens	= sizeof gsfb_screen_table /
+	                      sizeof gsfb_screen_table[0],
+	.screens	= gsfb_screen_table
 };
 
+
+static inline void * 
+gsfb_uncached(void * addr)
+{
+	return (void *) MIPS_PHYS_TO_KSEG1(MIPS_KSEG0_TO_PHYS(addr));
+}
+
 int
 gsfb_match(struct device *parent, struct cfdata *cf, void *aux)
 {
-	extern struct cfdriver gsfb_cd;
-	struct mainbus_attach_args *ma = aux;
-
-	if (strcmp(ma->ma_name, gsfb_cd.cd_name) != 0)
-		return (0);
-
-	return (!gsfb.attached);
+#if 0	
+	struct mainbus_attach_args *ma;
+        ma = aux;
+	return strcmp(ma->ma_name, cf->cf_driver->cd_name) ?
+		0 : !gsfb_attached;
+#endif
+	return !gsfb_attached;
 }
 
 void
 gsfb_attach(struct device *parent, struct device *self, void *aux)
 {
 	struct wsemuldisplaydev_attach_args wa;
-
-	gsfb.attached = 1;
-	if (!gsfb.is_console && gsfb_swinit() != 0)
-		return;
-
+	
+	gsfb_attached = 1;
+	gsfb_init();
 	printf("\n");
-
-	wa.console	= gsfb.is_console;
-	wa.scrdata	= &_gsfb_screen_list;
-	wa.accessops	= &_gsfb_accessops;
-	wa.accesscookie	= &gsfb;
-
+	wa.console	= gsfb_console;
+	wa.scrdata	= &gsfb_screen_list;
+	wa.accessops	= &gsfb_accessops;
+	wa.accesscookie	= NULL; 
+	
 	config_found(self, &wa, wsdisplaydevprint);
 }
 
 /*
  * console
  */
+
 void
 gsfbcnprobe(struct consdev *cndev)
 {
-	
+	cndev->cn_dev = NODEV;
 	cndev->cn_pri = CN_INTERNAL;
-}
-
-void
-gsfbcninit(struct consdev *cndev)
-{
-	paddr_t paddr = MIPS_KSEG0_TO_PHYS(gsfb_init_cmd_640x480);
-	long defattr =  ATTR_BG_SET(WSCOL_BLACK) | ATTR_FG_SET(WSCOL_WHITE);
-
-	gsfb.is_console = 1;
-
-	gsfb_hwinit();
-	gsfb_swinit();
-
-	gsfb_dma_kick(paddr, sizeof gsfb_init_cmd_640x480);
-#ifdef GSFB_DEBUG_MONITOR
+#if 0 && NWSDISPLAY > 0
 	{
-		const struct _gsfb_debug_window *win;
-		int i;
-
-		for (i = 0; i < 3; i++) {
-			win = &_gsfb_debug_window[i];
-			_gsfb_eraserows(0, win->start, win->nrow, win->attr);
-		}
+		int maj = nchrdev;
+		while (maj--)
+			if (cdevsw[maj].d_open == wsdisplayopen)
+				break;
+		if (maj >= 0)
+			cndev->cn_dev = makedev(maj,0);
 	}
-#endif /* GSFB_DEBUG_MONITOR */
-
-	wsdisplay_cnattach(&_gsfb_std_screen, &gsfb, 0, 0, defattr);
+#endif
 }
 
 void
-gsfb_hwinit()
-{
-	gs_init(VESA_1A);
-	dmac_init();
-
-	/* reset GIF channel DMA */
-	_reg_write_4(D2_QWC_REG, 0);
-	_reg_write_4(D2_MADR_REG, 0);
-	_reg_write_4(D2_TADR_REG, 0);
-	_reg_write_4(D2_CHCR_REG, 0);
-}
-
-int
-gsfb_swinit()
+gsfbcninit(struct consdev *cndev)
 {
-	int font;
-
-	wsfont_init();	
-	font = wsfont_find(NULL, 8, 16, 0,  WSDISPLAY_FONTORDER_L2R,
-	    WSDISPLAY_FONTORDER_L2R);
-	if (font < 0)
-		return (1);
-
-	if (wsfont_lock(font, &gsfb.font))
-		return (1);
-
-	gsfb.screen = &_gsfb_std_screen;
-	gsfb.initialized = 1;
-
-	return (0);
+	long defattr;
+	gsfb_init();
+	(*gsfb_rinfo.ri_ops.allocattr)(&gsfb_rinfo, 0, 0, 0, &defattr);
+	wsdisplay_cnattach(&gsfb_stdscreen, &gsfb_rinfo, 0, 0, defattr);
+	gsfb_console = 1;
+	cn_tab->cn_pri = CN_INTERNAL;
 }
 
 /*
  * wsdisplay
  */
-void
-_gsfb_cursor(void *cookie, int on, int row, int col)
-{
-	paddr_t paddr = MIPS_KSEG0_TO_PHYS(gsfb_cursor_cmd);
-	u_int32_t *buf = (void *)MIPS_PHYS_TO_KSEG1(paddr);
-	struct wsdisplay_font *font = gsfb.font;
-
-	gsfb_set_cursor_pos(buf, col, row, font->fontwidth, font->fontheight);
-
-	gsfb_dma_kick(paddr, sizeof gsfb_cursor_cmd);
-}
-
-__inline__ void
-gsfb_set_cursor_pos(u_int32_t *p, int x, int y, int w, int h)
-{
-
-	x *= w;
-	y *= h;
-	p[20] = ((x << 4) & 0xffff) | ((y << 20) & 0xffff0000);
-	p[28] = (((x + w - 1) << 4) & 0xffff) |
-	    (((y + h - 1) << 20) & 0xffff0000);
-}
 
 int
-_gsfb_mapchar(void *cookie, int c, unsigned int *cp)
-{
-	struct wsdisplay_font *font = gsfb.font;
-	
-	if (font->encoding != WSDISPLAY_FONTENC_ISO)
-		if ((c = wsfont_map_unichar(font, c)) < 0)
-			goto nomap;
-
-	if (c < font->firstchar || c >= font->firstchar + font->numchars)
-			goto nomap;
-
-	*cp = c;
-	return (5);
-
- nomap:
-	*cp = ' ';
-	return (0);
-}
-
-void
-_gsfb_putchar(void *cookie, int row, int col, u_int uc, long attr)
+gsfb_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
 {
-	paddr_t paddr = MIPS_KSEG0_TO_PHYS(gsfb_load_cmd_8x16_psmct32);
-	u_int32_t *buf = (void *)MIPS_PHYS_TO_KSEG1(paddr);
-	struct wsdisplay_font *font = gsfb.font;
-
-	/* copy font data to DMA region */
-	gsfb_font_expand_psmct32(font, uc, attr, &buf[FONT_SCRATCH_BASE]);
-
-	/* set destination position */
-	TRXPOS_DXY(buf, col * font->fontwidth, row * font->fontheight);
-
-	/* kick to GIF */
-	gsfb_dma_kick(paddr, sizeof gsfb_load_cmd_8x16_psmct32);
+        switch (cmd) {
+	case WSDISPLAYIO_GTYPE:
+                *(u_int *)data = WSDISPLAY_TYPE_PS2GS;
+		return 0;
+        case WSDISPLAYIO_GINFO:
+#define fbi ((struct wsdisplay_fbinfo *)data)
+                fbi->width = GSFB_BUFFER_WIDTH;
+                fbi->height = GSFB_BUFFER_HEIGHT;
+                fbi->depth = GSFB_BUFFER_DEPTH;
+                fbi->cmsize = 0;
+                return 0;
+#undef fbi
+        }
+	return EPASSTHROUGH;
 }
 
-void
-_gsfb_copycols(void *cookie, int row, int srccol, int dstcol, int ncols)
-{
-	paddr_t paddr = MIPS_KSEG0_TO_PHYS(gsfb_copy_cmd_8x16);
-	u_int32_t *cmd = (void *)MIPS_PHYS_TO_KSEG1(paddr);
-	int y = gsfb.font->fontheight * row;
-	int w = gsfb.font->fontwidth;
-	int i;
-
-	if (dstcol > srccol) {
-		for (i = ncols - 1; i >= 0; i--) {
-			TRXPOS_DXY_SXY(cmd, (dstcol + i) * w, y, (srccol + i) * w, y);
-			gsfb_dma_kick(paddr, sizeof gsfb_copy_cmd_8x16);
-		}
-	} else {
-		for (i = 0; i < ncols; i++) {
-			TRXPOS_DXY_SXY(cmd, (dstcol + i) * w, y, (srccol + i) * w, y);
-			gsfb_dma_kick(paddr, sizeof gsfb_copy_cmd_8x16);
-		}
-	}
-}
-
-void
-_gsfb_erasecols(void *cookie, int row, int startcol, int ncols, long attr)
+paddr_t
+gsfb_mmap(void *v, off_t offset, int prot)
 {
-	int i;
-	
-	for (i = 0; i < ncols; i++)
-		_gsfb_putchar(cookie, row, startcol + i, ' ', attr);
+	if (GSFB_BUFFER_SIZE < offset)
+	    return -1;
+	return mips_btop(offset + gsfb_screen_base);
 }
 
-void
-_gsfb_copyrows(void *cookie, int src, int dst, int num)
+int
+gsfb_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
+		  int *curxp, int *curyp, long *attrp)
 {
-	paddr_t paddr = MIPS_KSEG0_TO_PHYS(gsfb_scroll_cmd_640x16);
-	u_int32_t *cmd = (void *)MIPS_PHYS_TO_KSEG1(paddr);
-	int i;
-	int h = gsfb.font->fontheight;
-
-	if (dst > src) {
-		for (i = num - 1; i >= 0; i--) {
-			TRXPOS_SY_DY(cmd, (src + i) * h, (dst  + i) * h);
-			gsfb_dma_kick(paddr, sizeof gsfb_scroll_cmd_640x16);
-		}
-	} else {
-		for (i = 0; i < num; i++) {
-			TRXPOS_SY_DY(cmd, (src + i) * h, (dst  + i) * h);
-			gsfb_dma_kick(paddr, sizeof gsfb_scroll_cmd_640x16);
-		}
-	}
+	if (gsfb_nscreens > 0)
+	    return ENOMEM;
+	*cookiep = &gsfb_rinfo; 
+	*curxp = 0;
+	*curyp = 0;
+	(*gsfb_rinfo.ri_ops.allocattr)(&gsfb_rinfo, 0, 0, 0, attrp);
+	gsfb_nscreens++;
+	return (0);
 }
 
 void
-_gsfb_eraserows(void *cookie, int row, int nrow, long attr)
+gsfb_free_screen(void *v, void *cookie)
 {
-	int i, j;
-	
-	for (j = 0; j < nrow; j++)
-		for (i = 0; i < gsfb.screen->ncols; i++)
-			_gsfb_putchar(cookie, row + j, i, ' ', attr);
+ 	panic("gsfb_free_screen: console");
 }
 
 int
-_gsfb_allocattr(void *cookie, int fg, int bg, int flags, long *attr)
+gsfb_show_screen(void *v, void *cookie, int waitok,
+		 void (*cb)(void *, int, int), void *cbarg)
 {
-
-	if ((flags & WSATTR_BLINK) != 0)
-		return (EINVAL);
-
-	if ((flags & WSATTR_WSCOLORS) == 0) {
-		fg = WSCOL_WHITE;
-		bg = WSCOL_BLACK;
-	}
-
-	if ((flags & WSATTR_HILIT) != 0)
-		fg += 8;
-
-	flags = (flags & WSATTR_UNDERLINE) ? 1 : 0;
-
-
-	*attr = ATTR_BG_SET(bg) | ATTR_FG_SET(fg) | flags;
-
 	return (0);
 }
 
-int
-_gsfb_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
-{
-
-	return (EPASSTHROUGH); /* Inappropriate ioctl for device */
-}
-
-paddr_t
-_gsfb_mmap(void *v, off_t offset, int prot)
-{
-
-	return (0); /* can't mmap */
-}
+/* 
+ * Internal
+ */
 
-int
-_gsfb_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
-    int *curxp, int *curyp, long *attrp)
+void
+gsfb_hwinit()
 {
+	gs_init(VESA_1A);
+	dmac_init();
 
-	*attrp = ATTR_BG_SET(WSCOL_BLACK) | ATTR_FG_SET(WSCOL_WHITE);
+	/* reset GIF channel DMA */
+	_reg_write_4(D2_QWC_REG, 0);
+	_reg_write_4(D2_MADR_REG, 0);
+	_reg_write_4(D2_TADR_REG, 0);
+	_reg_write_4(D2_CHCR_REG, 0);
 
-	return (0);
+	gsfb_dma_kick_kseg0(gsfb_init_cmd_640x480x32, 
+			    sizeof gsfb_init_cmd_640x480x32);
 }
 
 void
-_gsfb_free_screen(void *v, void *cookie)
-{
-}
-
-int
-_gsfb_show_screen(void *v, void *cookie, int waitok,
-    void (*cb)(void *, int, int), void *cbarg)
+gsfb_init()
 {
+	static int gsfb_initialized = 0;
+	char * base;
+	if (gsfb_initialized)
+		return;
+	gsfb_initialized = 1;
 
-	return (0);
-}
+	base = (char *)
+		mips_round_page(gsfb_screen_mem + sizeof gsfb_load_screen);
+	base = gsfb_uncached(base);
+	memcpy(base - sizeof gsfb_load_screen,
+	       gsfb_load_screen, sizeof gsfb_load_screen);
+	
+	gsfb_hwinit();
+	
+	memset(&gsfb_rinfo, 0, sizeof gsfb_rinfo);
+	gsfb_rinfo.ri_depth = GSFB_BUFFER_DEPTH;
+	gsfb_rinfo.ri_bits = base;
+	gsfb_rinfo.ri_width = GSFB_BUFFER_WIDTH;
+	gsfb_rinfo.ri_height = GSFB_BUFFER_HEIGHT;
+	gsfb_rinfo.ri_stride = GSFB_BUFFER_WIDTH * GSFB_PIXEL_SIZE;
+
+	rasops_init(&gsfb_rinfo, 1000, 1000);
+
+	gsfb_stdscreen.nrows = gsfb_rinfo.ri_rows;
+	gsfb_stdscreen.ncols = gsfb_rinfo.ri_cols;
+	gsfb_stdscreen.textops = &gsfb_rinfo.ri_ops;
+	gsfb_stdscreen.capabilities = gsfb_rinfo.ri_caps;
 
-void
-_gsfb_pollc(void *v, int on)
-{
+	gsfb_screen_base = base;
 
+	/* install vblank handler */
+	intc_intr_establish(I_CH2_VB_ON, IPL_TTY, vblank_intr, 0);
 }
 
-/* 
- * font expansion 
- *   PSMCT32 only
- */
-void
-gsfb_font_expand_psmct32(const struct wsdisplay_font *font, u_int c, long attr,
-    u_int32_t *buf)
+void 
+gsfb_do_redraw()
 {
-	u_int32_t fg, bg;
-	u_int8_t *bitmap;
-	int i, j;
-	
-	KDASSERT(((u_int32_t)buf & 15) == 0);
-
-	fg = gsfb_ansi_psmct32[ATTR_FG_GET(attr)];
-	bg = gsfb_ansi_psmct32[ATTR_BG_GET(attr)];
-
-	bitmap = (u_int8_t *)font->data + (c - font->firstchar) * 
-	    font->fontheight * font->stride;
-	for (i = 0; i < font->fontheight; i++, bitmap++) {
-		u_int32_t b = *bitmap;
-		for (j = 0; j < font->fontwidth; j++, b <<= 1)
-			*buf++ = (b & 0x80) ? fg : bg;
-	}
+	gsfb_dma_kick_kseg1(gsfb_screen_base - sizeof gsfb_load_screen,
+			    GSFB_BUFFER_SIZE + sizeof gsfb_load_screen);
 }
 
 void 
-gsfb_dma_kick(paddr_t addr, size_t size)
+gsfb_dma_kick_phys(paddr_t addr, size_t size)
 {
 	/* Wait for previous DMA request complete */
 	while (_reg_read_4(D2_QWC_REG))
@@ -612,46 +378,26 @@
 	dmac_chcr_write(D_CH2_GIF, D_CHCR_STR);
 }
 
-#ifdef GSFB_DEBUG_MONITOR
 void
-__gsfb_print(int window, const char *fmt, ...)
+gsfb_dma_kick_kseg0(void * addr, size_t size)
 {
-	const struct _gsfb_debug_window *win;
-	int i, s, x, y, n, a;
-	u_int c;
-	va_list ap;
-	
-	if (!gsfb.initialized)
-		return;
-	
-	s = _intr_suspend();
-	win = &_gsfb_debug_window[window];
-	x = 0;
-	y = win->start;
-	n = win->nrow * 80;
-	a = win->attr;
-
-	va_start(ap, fmt);
-	vsnprintf(_gsfb_debug_buf, n, fmt, ap);
-	va_end(ap);
-
-	_gsfb_eraserows(0, y, win->nrow, a);
-
-	for (i = 0; i < n &&
-	    (c = (u_int)_gsfb_debug_buf[i] & 0x7f) != 0; i++) {
-		if (c == '\n')
-			x = 0, y++;
-		else
-			_gsfb_putchar(0, y, x++, c, a);
-	}
-
-	_intr_resume(s);
+	gsfb_dma_kick_phys(MIPS_KSEG0_TO_PHYS(addr), size);
 }
 
 void
-__gsfb_print_hex(int a0, int a1, int a2, int a3)
+gsfb_dma_kick_kseg1(void * addr, size_t size)
 {
-	__gsfb_print(2, "a0=%08x a1=%08x a2=%08x a3=%08x",
-	    a0, a1, a2, a3);
+	gsfb_dma_kick_phys(MIPS_KSEG1_TO_PHYS(addr), size);
 }
-#endif /* GSFB_DEBUG_MONITOR */
+
+int 
+vblank_intr(void * unused)
+{
+	static int skipcnt = 0;
+	if (!skipcnt--) {
+		skipcnt = 0;
+		gsfb_do_redraw();
+	}
+	return 1;
+}
+