Subject: port-sparc/29860: Add wscons support to the SPARCbook's pnozz driver
To: None <port-sparc-maintainer@netbsd.org, gnats-admin@netbsd.org,>
From: None <macallan18@earthlink.net>
List: netbsd-bugs
Date: 04/02/2005 01:50:00
>Number: 29860
>Category: port-sparc
>Synopsis: Add wscons support to the SPARCbook's pnozz driver
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: port-sparc-maintainer
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Sat Apr 02 01:50:00 +0000 2005
>Originator: Michael Lorenz
>Release: -current
>Organization:
>Environment:
NetBSD morgoth 2.99.16 NetBSD 2.99.16 (MORGOTH) #112: Wed Mar 9 16:03:55 EST 2005 root@morgoth:/data/src/sys/arch/sparc/compile/MORGOTH sparc
>Description:
The patch below adds the following things to pnozz:
- wscons support
- virtual consoles
- colour
- full acceleration
Since the SPARCbook keyboard doesn't have a STOP key I also added an #ifdef to use the Alt key for console switching.
kernel config changes:
options WSEMUL_VT100
options WS_DEFAULT_FG=WSCOL_BLACK
options WS_DEFAULT_BG=0x0f
options WS_KERNEL_FG=WSCOL_GREEN
options WS_KERNEL_BG=0x0f
options WSDISPLAY_COMPAT_USL # VT handling
options WSDISPLAY_DEFAULTSCREENS=1
options SPARCBOOK_CMD # enable screen switching with lAlt-Fn
options FONT_BOLD8x16 # a somewhat smaller font
# Tadpole 3GX/3GS (P9100 -- P Nine One Zero Zero -> pnozz)
pnozz0 at sbus? slot ? offset ?
wsdisplay* at pnozz? console ?
... this requires wskbd attaching to kbd which currently only works with a rather grisly hack ( I'll supply it on demand, but it's really gruesome and there are people working on a real solution )
So far it works only in 8bit colour, supporting higher depths shouldn't be problematic though.
>How-To-Repeat:
Install NetBSD on a SPARCbook 3GX
Here's the dmesg output:
Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
The NetBSD Foundation, Inc. All rights reserved.
Copyright (c) 1982, 1986, 1989, 1991, 1993
The Regents of the University of California. All rights reserved.
NetBSD 2.99.16 (MORGOTH) #112: Wed Mar 9 16:03:55 EST 2005
root@morgoth:/data/src/sys/arch/sparc/compile/MORGOTH
total memory = 65200 KB
avail memory = 61312 KB
bootpath: /iommu@0,10000000/sbus@0,10001000/espdma@4,8400000/esp@4,8800000/sd@3,
0
mainbus0 (root): Tadpole_S3GX: hostid 80ae2531
cpu0 at mainbus0: MB86904 @ 110 MHz, on-chip FPU
cpu0: 16K instruction (32 b/l), 8K data (16 b/l): cache enabled
obio0 at mainbus0
clock0 at obio0 slot 0 offset 0x202000: mk48t08
timer0 at obio0 slot 0 offset 0xd00000: delay constant 52
zs0 at obio0 slot 0 offset 0x100000 level 12 powered via auxio2 softpri 6
zstty0 at zs0 channel 0
zstty1 at zs0 channel 1
zs1 at obio0 slot 0 offset 0x0 level 12 softpri 6
kbd0 at zs1 channel 0: baud rate 1200 (console input)
wskbd0 at kbd0: console keyboard
ms0 at zs1 channel 1: baud rate 1200
wssunkbd_enable
open...
kbd_sun_open
init...
slavioconfig at obio0 slot 0 offset 0x800000 not configured
auxreg0 at obio0 slot 0 offset 0x900000
auxiotwo0 at obio0 slot 0 offset 0x910000
tctrl0 at obio0 slot 0 offset 0xd1000020 level 11
tctrl0: main power available
clk-ctrl at obio0 slot 0 offset 0x3c0000 not configured
com0 at obio0 slot 0 offset 0x3a0000 level 13: ns16550a, working fifo
iommu0 at mainbus0 addr 0x10000000: version 0x4/0x0, page-size 4096, range 64MB
sbus0 at iommu0: clock = 22 MHz
pnozz0 at sbus0 slot 0 offset 0x8000000 level 2: rev 4, 800x600, depth 8 (consol
e)
wsdisplay0 at pnozz0 kbdmux 1: console (default, vt100 emulation), using wskbd0
wsmux1: connecting to wsdisplay0
pnozz0: attached to /dev/fb
dma0 at sbus0 slot 4 offset 0x8400000: DMA rev 2
esp0 at dma0 slot 4 offset 0x8800000 level 4: ESP200, 40MHz, SCSI ID 7
scsibus0 at esp0: 8 targets, 8 luns per target
SUNW,bpp at sbus0 slot 4 offset 0xc800000 level 3 not configured
ledma0 at sbus0 slot 4 offset 0x8400010: DMA rev 2
le0 at ledma0 slot 4 offset 0x8c00000 level 6: address 00:00:83:ae:25:31
le0: 8 receive buffers, 2 transmit buffers
ts102 at sbus0 slot 1 offset 0x2000000 level 11 not configured
dbri0 at sbus0 slot 2 offset 0x40 level 9
dbri0: need to power up first....done
scsibus0: waiting 2 seconds for devices to settle...
sd0 at scsibus0 target 3 lun 0: <ADTX, AXSITS2532U 011D, K2.1> disk fixed
sd0: fabricating a geometry
sd0: 6194 MB, 6194 cyl, 64 head, 32 sec, 512 bytes/sect x 12685680 sectors
sd0: sync (200.00ns offset 7), 8-bit (5.000MB/s) transfers
root on sd0a dumps on sd0b
sd0: fabricating a geometry
sd0: fabricating a geometry
root file system type: ffs
WARNING: clock gained 17 days -- CHECK AND RESET THE DATE!
wsdisplay0: screen 1 added (default, vt100 emulation)
wsdisplay0: screen 2 added (default, vt100 emulation)
wsdisplay0: screen 3 added (default, vt100 emulation)
wsdisplay0: screen 4 added (default, vt100 emulation)
>Fix:
Index: wskbdmap_sun.c
===================================================================
RCS file: /cvsroot/src/sys/dev/sun/wskbdmap_sun.c,v
retrieving revision 1.5
diff -u -w -r1.5 wskbdmap_sun.c
--- wskbdmap_sun.c 27 Feb 2005 00:27:49 -0000 1.5
+++ wskbdmap_sun.c 2 Apr 2005 01:37:23 -0000
@@ -65,7 +65,11 @@
KC(0x10), KS_Cmd_Screen6, KS_f7,
KC(0x11), KS_Cmd_Screen7, KS_f8,
KC(0x12), KS_Cmd_Screen8, KS_f9,
+#ifdef SPARCBOOK_CMD
+ KC(0x13), KS_Cmd, KS_Alt_L,
+#else
KC(0x13), KS_Alt_L,
+#endif
KC(0x14), KS_Up,
KC(0x15), KS_Pause,
KC(0x16), KS_Print_Screen,
Index: files.sbus
===================================================================
RCS file: /cvsroot/src/sys/dev/sbus/files.sbus,v
retrieving revision 1.20
diff -u -w -r1.20 files.sbus
--- files.sbus 27 Feb 2005 00:27:48 -0000 1.20
+++ files.sbus 2 Apr 2005 01:33:19 -0000
@@ -121,6 +126,6 @@
file dev/sbus/zx.c zx
# Tadpole 3GX/3GS (P9100 -- P Nine One Zero Zero -> pnozz)
-device pnozz: fb, bt_dac, rasops8, rasops16, rasops32
+device pnozz: fb, bt_dac, rasops8, rasops16, rasops32, wsemuldisplaydev
attach pnozz at sbus
file dev/sbus/p9100.c pnozz needs-flag
Index: p9100.c
===================================================================
RCS file: /cvsroot/src/sys/dev/sbus/p9100.c,v
retrieving revision 1.20
diff -u -w -r1.20 p9100.c
--- p9100.c 27 Feb 2005 00:27:48 -0000 1.20
+++ p9100.c 2 Apr 2005 01:33:20 -0000
@@ -64,12 +64,18 @@
#include <dev/sun/fbvar.h>
#include <dev/sun/btreg.h>
#include <dev/sun/btvar.h>
-#if 0
+
#include <dev/sbus/p9100reg.h>
-#endif
#include <dev/sbus/sbusvar.h>
+/*#include <dev/wscons/wsdisplayvar.h>*/
+#include <dev/wscons/wsconsio.h>
+#include <dev/wsfont/wsfont.h>
+#include <dev/rasops/rasops.h>
+
+#include "opt_wsemul.h"
+
#include "tctrl.h"
#if NTCTRL > 0
#include <machine/tctrl.h>
@@ -96,24 +102,64 @@
bus_space_handle_t sc_fb_memh; /* bus space handle */
uint32_t sc_junk;
+ uint32_t sc_mono_width; /* for setup_mono */
+ uint32_t sc_width, sc_height; /* panel width / height */
+ uint32_t sc_stride, sc_depth;
union bt_cmap sc_cmap; /* Brooktree color map */
+
+#ifdef PNOZZ_SOFT_PUTCHAR
+ void (*putchar)(void *c, int row, int col, u_int uc, long attr);
+#endif
+ int sc_mode;
+ uint32_t sc_bg;
+ void (*switchcb)(void *, int, int);
+ void *switchcbarg;
+ struct callout switch_callout;
+ LIST_HEAD(, p9100_screen) screens;
+ struct p9100_screen *active, *wanted;
+ const struct wsscreen_descr *currenttype;
+
};
-/* The Tadpole 3GX Technical Reference Manual lies. The ramdac registers
- * are map in 4 byte increments, not 8.
- */
-#define SCRN_RPNT_CTL_1 0x0138 /* Screen Respaint Timing Control 1 */
-#define VIDEO_ENABLED 0x00000020
-#define PWRUP_CNFG 0x0194 /* Power Up Configuration */
-#define DAC_CMAP_WRIDX 0x0200 /* IBM RGB528 Palette Address (Write) */
-#define DAC_CMAP_DATA 0x0204 /* IBM RGB528 Palette Data */
-#define DAC_PXL_MASK 0x0208 /* IBM RGB528 Pixel Mask */
-#define DAC_CMAP_RDIDX 0x020c /* IBM RGB528 Palette Address (Read) */
-#define DAC_INDX_LO 0x0210 /* IBM RGB528 Index Low */
-#define DAC_INDX_HI 0x0214 /* IBM RGB528 Index High */
-#define DAC_INDX_DATA 0x0218 /* IBM RGB528 Index Data (Indexed Registers) */
-#define DAC_INDX_CTL 0x021c /* IBM RGB528 Index Control */
+struct p9100_screen {
+ struct rasops_info ri;
+ LIST_ENTRY(p9100_screen) next;
+ struct p9100_softc *sc;
+ const struct wsscreen_descr *type;
+ int active;
+ u_int16_t *chars;
+ long *attrs;
+ int dispoffset;
+ int mindispoffset;
+ int maxdispoffset;
+
+ int cursoron;
+ int cursorcol;
+ int cursorrow;
+ int cursordrawn;
+};
+
+static struct p9100_screen p9100_console_screen;
+
+extern const u_char rasops_cmap[768];
+
+struct wsscreen_descr p9100_defscreendesc = {
+ "default",
+ 0, 0,
+ NULL,
+ 8, 16,
+ WSSCREEN_WSCOLORS,
+};
+
+const struct wsscreen_descr *_p9100_scrlist[] = {
+ &p9100_defscreendesc,
+ /* XXX other formats, graphics screen? */
+};
+
+struct wsscreen_list p9100_screenlist = {
+ sizeof(_p9100_scrlist) / sizeof(struct wsscreen_descr *), _p9100_scrlist
+};
/* autoconfiguration driver */
static int p9100_sbus_match(struct device *, struct cfdata *, void *);
@@ -147,10 +193,59 @@
static int p9100_get_video(struct p9100_softc *);
static uint32_t p9100_ctl_read_4(struct p9100_softc *, bus_size_t);
static void p9100_ctl_write_4(struct p9100_softc *, bus_size_t, uint32_t);
-#if 0
-static uint8_t p9100_ramdac_read(struct p9100_softc *, bus_size_t);
-#endif
-static void p9100_ramdac_write(struct p9100_softc *, bus_size_t, uint8_t);
+uint8_t p9100_ramdac_read(struct p9100_softc *, bus_size_t);
+void p9100_ramdac_write(struct p9100_softc *, bus_size_t, uint8_t);
+
+static void p9100_sync(struct p9100_softc *);
+void p9100_bitblt(struct p9100_softc *, int, int, int, int, int, int, uint32_t); /* coordinates, rasop */
+void p9100_rectfill(struct p9100_softc *, int, int, int, int, uint32_t); /* coordinates, colour */
+static void p9100_init_engine(struct p9100_softc *);
+void p9100_setup_mono(struct p9100_softc *, int, int, int, int, uint32_t, uint32_t);
+void p9100_feed_line(struct p9100_softc *, int, uint8_t *);
+static void p9100_set_color_reg(struct p9100_softc *, int, int32_t);
+
+void p9100_cursor(void *, int, int, int);
+int p9100_mapchar(void *, int, u_int *);
+void p9100_putchar(void *, int, int, u_int, long);
+void p9100_copycols(void *, int, int, int, int);
+void p9100_erasecols(void *, int, int, int, long);
+void p9100_copyrows(void *, int, int, int);
+void p9100_eraserows(void *, int, int, long);
+int p9100_allocattr(void *, int, int, int, long *);
+
+void p9100_scroll(void *, void *, int);
+
+int p9100_putcmap(struct p9100_softc *, struct wsdisplay_cmap *);
+int p9100_getcmap(struct p9100_softc *, struct wsdisplay_cmap *);
+int p9100_ioctl(void *, u_long, caddr_t, int, struct proc *);
+paddr_t p9100_mmap(void *, off_t, int);
+int p9100_alloc_screen(void *, const struct wsscreen_descr *, void **, int *, int *, long *);
+void p9100_free_screen(void *, void *);
+int p9100_show_screen(void *, void *, int, void (*)(void *, int, int), void *);
+void p9100_switch_screen(struct p9100_softc *);
+void p9100_restore_screen(struct p9100_screen *, const struct wsscreen_descr *, u_int16_t *);
+void p9100_clearscreen(struct p9100_softc *);
+
+int p9100_load_font(void *, void *, struct wsdisplay_font *);
+
+void p9100_init_screen(struct p9100_softc *, struct p9100_screen *, int, long *);
+
+int p9100_intr(void *);
+
+struct wsdisplay_accessops p9100_accessops = {
+ p9100_ioctl,
+ p9100_mmap,
+ p9100_alloc_screen,
+ p9100_free_screen,
+ p9100_show_screen,
+ NULL, /* load_font */
+ NULL, /* polls */
+ NULL, /* getwschar */
+ NULL, /* putwschar */
+ NULL, /* scroll */
+ NULL, /* getborder */
+ NULL /* setborder */
+};
/*
* Match a p9100.
@@ -175,7 +270,10 @@
struct fbdevice *fb = &sc->sc_fb;
int isconsole;
int node;
- int i;
+ int i,j;
+ struct wsemuldisplaydev_attach_args aa;
+ struct rasops_info *ri;
+ unsigned long defattr;
/* Remember cookies for p9100_mmap() */
sc->sc_bustag = sa->sa_bustag;
@@ -197,6 +295,16 @@
fb->fb_type.fb_type = FBTYPE_SUN3COLOR;
fb->fb_pixels = NULL;
+ sc->sc_mode=WSDISPLAYIO_MODE_EMUL;
+#ifdef PNOZZ_SOFT_PUTCHAR
+ sc->putchar=NULL;
+#endif
+
+ LIST_INIT(&sc->screens);
+ sc->active = NULL;
+ sc->currenttype = &p9100_defscreendesc;
+ callout_init(&sc->switch_callout);
+
node = sa->sa_node;
isconsole = fb_is_console(node);
if (!isconsole) {
@@ -213,21 +321,13 @@
if (sbus_bus_map(sc->sc_bustag,
sa->sa_reg[0].oa_space,
sa->sa_reg[0].oa_base,
- sc->sc_ctl_psize,
+ /* XXX for some reason the SBus resources don't cover all registers, so we just map what we need */
+ /*sc->sc_ctl_psize*/ 0x8000,
BUS_SPACE_MAP_LINEAR, &sc->sc_ctl_memh) != 0) {
printf("%s: cannot map control registers\n", self->dv_xname);
return;
}
- if (sbus_bus_map(sc->sc_bustag,
- sa->sa_reg[1].oa_space,
- sa->sa_reg[1].oa_base,
- sc->sc_cmd_psize,
- BUS_SPACE_MAP_LINEAR, &sc->sc_cmd_memh) != 0) {
- printf("%s: cannot map command registers\n", self->dv_xname);
- return;
- }
-
if (sa->sa_npromvaddrs != 0)
fb->fb_pixels = (caddr_t)sa->sa_promvaddrs[0];
@@ -255,7 +355,16 @@
panic("pnozz: can't determine screen depth (0x%02x)", i);
}
}
- fb_setsize_obp(fb, fb->fb_type.fb_depth, 800, 600, node);
+ sc->sc_depth=(fb->fb_type.fb_depth>>3);
+
+ /* XXX for some reason I get a kernel trap with this */
+ sc->sc_width=prom_getpropint(node,"width",800);
+ sc->sc_height=prom_getpropint(node,"height",600);
+ sc->sc_stride=prom_getpropint(node,"linebytes",sc->sc_width*(fb->fb_type.fb_depth>>3));
+
+ p9100_init_engine(sc);
+
+ fb_setsize_obp(fb, fb->fb_type.fb_depth, sc->sc_width, sc->sc_height, node);
sbus_establish(&sc->sc_sd, &sc->sc_dev);
@@ -269,7 +378,16 @@
printf(", %d entry colormap", fb->fb_type.fb_cmsize);
/* Initialize the default color map. */
- bt_initcmap(&sc->sc_cmap, 256);
+ /*bt_initcmap(&sc->sc_cmap, 256);*/
+ j=0;
+ for(i=0;i<256;i++) {
+ sc->sc_cmap.cm_map[i][0]=rasops_cmap[j];
+ j++;
+ sc->sc_cmap.cm_map[i][1]=rasops_cmap[j];
+ j++;
+ sc->sc_cmap.cm_map[i][2]=rasops_cmap[j];
+ j++;
+ }
p9100loadcmap(sc, 0, 256);
/* make sure we are not blanked */
@@ -284,20 +402,58 @@
if (isconsole) {
printf(" (console)\n");
#ifdef RASTERCONSOLE
- for (i = 0; i < fb->fb_type.fb_size; i++) {
- if (fb->fb_pixels[i] == 0) {
- fb->fb_pixels[i] = 1;
- } else if (fb->fb_pixels[i] == (char) 255) {
- fb->fb_pixels[i] = 0;
- }
- }
- p9100loadcmap(sc, 255, 1);
+ /*p9100loadcmap(sc, 255, 1);*/
fbrcons_init(fb);
#endif
} else
printf("\n");
+ wsfont_init();
+
+ p9100_init_screen(sc,&p9100_console_screen,1,&defattr);
+ p9100_console_screen.active=1;
+ sc->active=&p9100_console_screen;
+ ri=&p9100_console_screen.ri;
+
+ p9100_defscreendesc.nrows = ri->ri_rows;
+ p9100_defscreendesc.ncols = ri->ri_cols;
+ p9100_defscreendesc.textops = &ri->ri_ops;
+ p9100_defscreendesc.capabilities = ri->ri_caps;
+
+ if(isconsole) {
+ wsdisplay_cnattach(&p9100_defscreendesc, ri, 0, 0, defattr);
+ }
+
+ sc->sc_bg=(defattr>>16)&0xff;
+
+ p9100_clearscreen(sc);
+
+ aa.console = isconsole;
+ aa.scrdata = &p9100_screenlist;
+ aa.accessops = &p9100_accessops;
+ aa.accesscookie = sc;
+
+ config_found(self, &aa, wsemuldisplaydevprint);
+
+ /* attach the fb */
fb_attach(fb, isconsole);
+
+#if 0
+ p9100_rectfill(sc,10,10,200,200,0x01);
+ p9100_rectfill(sc,210,10,200,200,0xff);
+ p9100_bitblt(sc,10,10,110,110,400,200,ROP_SRC);
+#endif
+#if 0
+ p9100_setup_mono(sc,750,500,32,1,1,6);
+ {
+ uint32_t ev=0xc3000000, odd=0x3c000000;
+ for(i=0;i<16;i++) {
+ p9100_feed_line(sc, 1, (uint8_t*)&ev);
+ p9100_feed_line(sc, 1, (uint8_t*)&odd);
+ }
+ }
+ delay(4000000);
+#endif
}
static void
@@ -306,22 +462,12 @@
{
struct p9100_softc *sc = arg;
#ifdef RASTERCONSOLE
- struct fbdevice *fb = &sc->sc_fb;
- int i;
-
- for (i = 0; i < fb->fb_type.fb_size; i++) {
- if (fb->fb_pixels[i] == 1) {
- fb->fb_pixels[i] = 0;
- } else if (fb->fb_pixels[i] == 0) {
- fb->fb_pixels[i] = 255;
- }
- }
sc->sc_cmap.cm_map[0][0] = 0xff;
sc->sc_cmap.cm_map[0][1] = 0xff;
sc->sc_cmap.cm_map[0][2] = 0xff;
sc->sc_cmap.cm_map[1][0] = 0;
sc->sc_cmap.cm_map[1][1] = 0;
- sc->sc_cmap.cm_map[1][2] = 0x80;
+ sc->sc_cmap.cm_map[1][2] = 0x00;
p9100loadcmap(sc, 0, 2);
sc->sc_cmap.cm_map[255][0] = 0;
sc->sc_cmap.cm_map[255][1] = 0;
@@ -409,20 +555,157 @@
bus_space_write_4(sc->sc_bustag, sc->sc_ctl_memh, off, v);
}
-#if 0
-static uint8_t
+/* wait until the engine is idle */
+static void
+p9100_sync(struct p9100_softc *sc)
+{
+ while((p9100_ctl_read_4(sc,ENGINE_STATUS)&(ENGINE_BUSY|BLITTER_BUSY))!=0);
+}
+
+static void
+p9100_set_color_reg(struct p9100_softc *sc, int reg, int32_t col)
+{
+ uint32_t out;
+ switch(sc->sc_depth)
+ {
+ case 1: /* 8 bit */
+ out=(col<<8)|col;
+ out|=out<<16;
+ break;
+ case 2: /* 16 bit */
+ out=col|(col<<16);
+ break;
+ default:
+ out=col;
+ }
+ p9100_ctl_write_4(sc,reg,out);
+}
+/* initialize the drawing engine */
+static void
+p9100_init_engine(struct p9100_softc *sc)
+{
+ /* reset clipping rectangles */
+ uint32_t max=((sc->sc_width&0x3fff)<< 16)|(sc->sc_height&0x3fff);
+ p9100_ctl_write_4(sc,WINDOW_OFFSET,0);
+ p9100_ctl_write_4(sc,WINDOW_MIN,0);
+ p9100_ctl_write_4(sc,WINDOW_MAX,max);
+ p9100_ctl_write_4(sc,BYTE_CLIP_MIN,0);
+ p9100_ctl_write_4(sc,BYTE_CLIP_MAX,max);
+ p9100_ctl_write_4(sc,DRAW_MODE,0);
+ p9100_ctl_write_4(sc,PLANE_MASK,0xffffffff);
+ p9100_ctl_write_4(sc,PATTERN0,0xffffffff);
+ p9100_ctl_write_4(sc,PATTERN1,0xffffffff);
+ p9100_ctl_write_4(sc,PATTERN2,0xffffffff);
+ p9100_ctl_write_4(sc,PATTERN3,0xffffffff);
+}
+
+/* screen-to-screen blit */
+void
+p9100_bitblt(struct p9100_softc *sc, int xs, int ys, int xd, int yd, int wi, int he, uint32_t rop)
+{
+ uint32_t src, dst, srcw,dstw, junk;
+ src=((xs&0x3fff)<<16)|(ys&0x3fff);
+ dst=((xd&0x3fff)<<16)|(yd&0x3fff);
+ srcw=(((xs+wi-1)&0x3fff)<<16)|((ys+he-1)&0x3fff);
+ dstw=(((xd+wi-1)&0x3fff)<<16)|((yd+he-1)&0x3fff);
+ p9100_sync(sc);
+ p9100_ctl_write_4(sc,RASTER_OP,rop);
+
+ p9100_ctl_write_4(sc,ABS_XY0,src);
+
+ p9100_ctl_write_4(sc,ABS_XY1,srcw);
+ p9100_ctl_write_4(sc,ABS_XY2,dst);
+ p9100_ctl_write_4(sc,ABS_XY3,dstw);
+ junk=p9100_ctl_read_4(sc,COMMAND_BLIT);
+ /*p9100_sync(sc);*/
+}
+
+/* solid rectangle fill */
+void
+p9100_rectfill(struct p9100_softc *sc, int xs, int ys, int wi, int he, uint32_t col)
+{
+ uint32_t src, srcw, junk;
+ src=((xs&0x3fff)<<16)|(ys&0x3fff);
+ srcw=(((xs+wi)&0x3fff)<<16)|((ys+he)&0x3fff);
+ p9100_sync(sc);
+ p9100_set_color_reg(sc,FOREGROUND_COLOR,col);
+ p9100_set_color_reg(sc,BACKGROUND_COLOR,col);
+ p9100_ctl_write_4(sc,RASTER_OP,ROP_PAT);
+ p9100_ctl_write_4(sc,COORD_INDEX,0);
+ p9100_ctl_write_4(sc,RECT_RTW_XY,src);
+ p9100_ctl_write_4(sc,RECT_RTW_XY,srcw);
+ junk=p9100_ctl_read_4(sc,COMMAND_QUAD);
+ /*p9100_sync(sc);*/
+}
+
+void
+p9100_setup_mono(struct p9100_softc *sc, int x, int y, int wi, int he, uint32_t fg,
+ uint32_t bg)
+{
+ p9100_sync(sc);
+ /* this doesn't make any sense to me either, but for some reason the chip
+ applies the foreground colour to 0 pixels */
+ p9100_set_color_reg(sc,FOREGROUND_COLOR,bg);
+ p9100_set_color_reg(sc,BACKGROUND_COLOR,fg);
+
+ p9100_ctl_write_4(sc,RASTER_OP,ROP_SRC);
+ p9100_ctl_write_4(sc,ABS_X0,x);
+ p9100_ctl_write_4(sc,ABS_XY1,(x<<16)|(y&0xFFFFL));
+ p9100_ctl_write_4(sc,ABS_X2,(x+wi));
+ p9100_ctl_write_4(sc,ABS_Y3,he);
+ /* now feed the data into the chip */
+ sc->sc_mono_width=wi;
+}
+
+void
+p9100_feed_line(struct p9100_softc *sc, int count, uint8_t *data)
+{
+ int i;
+ uint32_t latch=0, bork;
+ int shift=24;
+ int to_go=sc->sc_mono_width;
+ for(i=0;i<count;i++) {
+ bork=data[i];
+ latch|=(bork<<shift);
+ if(shift==0) {
+ /* check how many bits are significant */
+ if(to_go>31) {
+ p9100_ctl_write_4(sc,(PIXEL_1+(31<<2)),latch);
+ to_go-=32;
+ } else
+ {
+ p9100_ctl_write_4(sc,(PIXEL_1+((to_go-1)<<2)),latch);
+ to_go=0;
+ }
+ latch=0;
+ shift=24;
+ } else
+ shift-=8;
+ }
+ if(shift!=24)
+ p9100_ctl_write_4(sc,(PIXEL_1+((to_go-1)<<2)),latch);
+}
+
+void
+p9100_clearscreen(struct p9100_softc *sc)
+{
+ p9100_rectfill(sc,0,0,sc->sc_width,sc->sc_height,sc->sc_bg);
+}
+
+uint8_t
p9100_ramdac_read(struct p9100_softc *sc, bus_size_t off)
{
sc->sc_junk = p9100_ctl_read_4(sc, PWRUP_CNFG);
- return p9100_ctl_read_4(sc, off) >> 16;
+ sc->sc_junk = bus_space_read_4(sc->sc_bustag, sc->sc_fb_memh, off);
+ return ((bus_space_read_4(sc->sc_bustag, sc->sc_ctl_memh,off)>>16)&0xff);
}
-#endif
-static void
+void
p9100_ramdac_write(struct p9100_softc *sc, bus_size_t off, uint8_t v)
{
sc->sc_junk = p9100_ctl_read_4(sc, PWRUP_CNFG);
- p9100_ctl_write_4(sc, off, v << 16);
+ sc->sc_junk = bus_space_read_4(sc->sc_bustag, sc->sc_fb_memh, off);
+ bus_space_write_4(sc->sc_bustag, sc->sc_ctl_memh, off, ((uint32_t)v)<<16);
}
/*
@@ -463,12 +746,13 @@
static void
p9100loadcmap(struct p9100_softc *sc, int start, int ncolors)
{
- u_char *p;
-
+ int i;
p9100_ramdac_write(sc, DAC_CMAP_WRIDX, start);
- for (p = sc->sc_cmap.cm_map[start], ncolors *= 3; ncolors-- > 0; p++) {
- p9100_ramdac_write(sc, DAC_CMAP_DATA, *p);
+ for (i=0;i<ncolors;i++) {
+ p9100_ramdac_write(sc, DAC_CMAP_DATA, sc->sc_cmap.cm_map[i+start][0]);
+ p9100_ramdac_write(sc, DAC_CMAP_DATA, sc->sc_cmap.cm_map[i+start][1]);
+ p9100_ramdac_write(sc, DAC_CMAP_DATA, sc->sc_cmap.cm_map[i+start][2]);
}
}
@@ -524,3 +808,566 @@
prot,
BUS_SPACE_MAP_LINEAR));
}
+
+
+/* wscons stuff */
+
+void
+p9100_switch_screen(struct p9100_softc *sc)
+{
+ struct p9100_screen *scr, *oldscr;
+
+ scr = sc->wanted;
+ if (!scr) {
+ printf("p9100_switch_screen: disappeared\n");
+ (*sc->switchcb)(sc->switchcbarg, EIO, 0);
+ return;
+ }
+ oldscr = sc->active; /* can be NULL! */
+#ifdef DIAGNOSTIC
+ if (oldscr) {
+ if (!oldscr->active)
+ panic("p9100_switch_screen: not active");
+ }
+#endif
+ if (scr == oldscr)
+ return;
+
+#ifdef DIAGNOSTIC
+/* XXX: this one bites us at reboot */
+/* if (scr->active)
+ panic("p9100_switch_screen: active");*/
+#endif
+
+ if (oldscr)
+ oldscr->active = 0;
+#ifdef notyet
+ if (sc->currenttype != type) {
+ p9100_set_screentype(sc, type);
+ sc->currenttype = type;
+ }
+#endif
+
+ /* Clear the entire screen. */
+
+ scr->active = 1;
+ p9100_restore_screen(scr, &p9100_defscreendesc, scr->chars);
+
+ sc->active = scr;
+
+ scr->ri.ri_ops.cursor(scr, scr->cursoron, scr->cursorrow, scr->cursorcol);
+
+ sc->wanted = 0;
+ if (sc->switchcb)
+ (*sc->switchcb)(sc->switchcbarg, 0, 0);
+}
+
+void
+p9100_restore_screen(struct p9100_screen *scr,
+ const struct wsscreen_descr *type, u_int16_t *mem)
+{
+ int i, j, offset=0;
+ uint16_t *charptr=scr->chars;
+ long *attrptr=scr->attrs;
+ p9100_clearscreen(scr->sc);
+ for (i = 0; i < scr->ri.ri_rows; i++) {
+ for (j = 0; j < scr->ri.ri_cols; j++) {
+ p9100_putchar(scr, i, j, charptr[offset], attrptr[offset]);
+ offset++;
+ }
+ }
+ scr->cursordrawn=0;
+}
+
+void
+p9100_cursor(void *cookie, int on, int row, int col)
+{
+ struct rasops_info *ri=cookie;
+ struct p9100_screen *scr=ri->ri_hw;
+ struct p9100_softc *sc=scr->sc;
+ int x,y,wi=ri->ri_font->fontwidth,he=ri->ri_font->fontheight;
+ if((scr->active) && (sc->sc_mode==WSDISPLAYIO_MODE_EMUL)) {
+ x=scr->cursorcol*wi+ri->ri_xorigin;
+ y=scr->cursorrow*he+ri->ri_yorigin;
+ if(scr->cursordrawn) {
+ p9100_bitblt(sc,x,y,x,y,wi,he,(ROP_SRC^0xff));
+ scr->cursordrawn=0;
+ }
+ scr->cursorrow=row;
+ scr->cursorcol=col;
+ if((scr->cursoron=on)!=0)
+ {
+ x=scr->cursorcol*wi+ri->ri_xorigin;
+ y=scr->cursorrow*he+ri->ri_yorigin;
+ p9100_bitblt(sc,x,y,x,y,wi,he,(ROP_SRC^0xff));
+ scr->cursordrawn=1;
+ }
+ } else {
+ scr->cursoron=on;
+ scr->cursorrow=row;
+ scr->cursorcol=col;
+ scr->cursordrawn=0;
+ }
+
+}
+
+#if 0
+int
+p9100_mapchar(void *cookie, int uni, u_int *index)
+{
+ return 0;
+}
+#endif
+
+void
+p9100_putchar(void *cookie, int row, int col, u_int c, long attr)
+{
+ struct rasops_info *ri=cookie;
+ struct p9100_screen *scr=ri->ri_hw;
+ struct p9100_softc *sc=scr->sc;
+ int pos;
+ if((row>=0) && (row<ri->ri_rows) && (col>=0) && (col<ri->ri_cols)) {
+ pos=col+row*ri->ri_cols;
+ scr->attrs[pos]=attr;
+ scr->chars[pos]=c;
+
+#ifdef PNOZZ_SOFT_PUTCHAR
+ if((sc->putchar!=NULL) && ( scr->active)&& (sc->sc_mode==WSDISPLAYIO_MODE_EMUL)) {
+ p9100_sync(sc);
+ sc->putchar(cookie,row,col,c,attr);
+ }
+#else
+ if((scr->active) && (sc->sc_mode==WSDISPLAYIO_MODE_EMUL)) {
+ int fg,bg,uc,i;
+ uint8_t *data;
+ int x,y,wi=ri->ri_font->fontwidth,he=ri->ri_font->fontheight;
+
+ if (!CHAR_IN_FONT(c, ri->ri_font))
+ return;
+ bg = (u_char)ri->ri_devcmap[(attr >> 16) & 0xff];
+ fg = (u_char)ri->ri_devcmap[(attr >> 24) & 0xff];
+ x=ri->ri_xorigin+col*wi;
+ y=ri->ri_yorigin+row*he;
+ if(c==0x20) {
+ p9100_rectfill(sc,x,y,wi,he,bg);
+ } else {
+ uc = c-ri->ri_font->firstchar;
+ data = (uint8_t *)ri->ri_font->data + uc * ri->ri_fontscale;
+
+ p9100_setup_mono(sc,x,y,wi,1,fg,bg);
+ for(i=0;i<he;i++) {
+ p9100_feed_line(sc,ri->ri_font->stride,data);
+ data+=ri->ri_font->stride;
+ }
+ /*p9100_sync(sc);*/
+ }
+ }
+#endif
+ }
+}
+
+void
+p9100_copycols(void *cookie, int row, int srccol, int dstcol, int ncols)
+{
+ struct rasops_info *ri=cookie;
+ struct p9100_screen *scr=ri->ri_hw;
+ struct p9100_softc *sc=scr->sc;
+ int32_t xs,xd,y,width,height;
+
+ int from=srccol+row*ri->ri_cols;
+ int to=dstcol+row*ri->ri_cols;
+ memmove(&scr->attrs[to],&scr->attrs[from],ncols*sizeof(long));
+ memmove(&scr->chars[to],&scr->chars[from],ncols*sizeof(uint16_t));
+
+ if((scr->active) && (sc->sc_mode==WSDISPLAYIO_MODE_EMUL)) {
+ xs=ri->ri_xorigin+ri->ri_font->fontwidth*srccol;
+ xd=ri->ri_xorigin+ri->ri_font->fontwidth*dstcol;
+ y=ri->ri_yorigin+ri->ri_font->fontheight*row;
+ width=ri->ri_font->fontwidth*ncols;
+ height=ri->ri_font->fontheight;
+ p9100_bitblt(sc,xs,y,xd,y,width,height,ROP_SRC);
+ }
+}
+
+void
+p9100_erasecols(void *cookie, int row, int startcol, int ncols, long fillattr)
+{
+ struct rasops_info *ri=cookie;
+ struct p9100_screen *scr=ri->ri_hw;
+ struct p9100_softc *sc=scr->sc;
+ int32_t x,y,width,height,bg;
+
+ int start=startcol+row*ri->ri_cols;
+ int end=start+ncols, i;
+ for(i=start;i<end;i++) {
+ scr->attrs[i]=fillattr;
+ scr->chars[i]=0x20;
+ }
+ if((scr->active) && (sc->sc_mode==WSDISPLAYIO_MODE_EMUL)) {
+ x=ri->ri_xorigin+ri->ri_font->fontwidth*startcol;
+ y=ri->ri_yorigin+ri->ri_font->fontheight*row;
+ width=ri->ri_font->fontwidth*ncols;
+ height=ri->ri_font->fontheight;
+ bg=(fillattr>>16)&0xff;
+ p9100_rectfill(sc,x,y,width,height,bg);
+ }
+}
+
+void
+p9100_copyrows(void *cookie, int srcrow, int dstrow, int nrows)
+{
+ struct rasops_info *ri=cookie;
+ struct p9100_screen *scr=ri->ri_hw;
+ struct p9100_softc *sc=scr->sc;
+ int32_t x,ys,yd,width,height;
+
+ int from=ri->ri_cols*srcrow, to=ri->ri_cols*dstrow, len=ri->ri_cols*nrows;
+ memmove(&scr->attrs[to],&scr->attrs[from],len*sizeof(long));
+ memmove(&scr->chars[to],&scr->chars[from],len*sizeof(uint16_t));
+
+ if((scr->active) && (sc->sc_mode==WSDISPLAYIO_MODE_EMUL)) {
+ x=ri->ri_xorigin;
+ ys=ri->ri_yorigin+ri->ri_font->fontheight*srcrow;
+ yd=ri->ri_yorigin+ri->ri_font->fontheight*dstrow;
+ width=ri->ri_emuwidth;
+ height=ri->ri_font->fontheight*nrows;
+ p9100_bitblt(sc,x,ys,x,yd,width,height,ROP_SRC);
+ }
+}
+
+void
+p9100_eraserows(void *cookie, int row, int nrows, long fillattr)
+{
+ struct rasops_info *ri=cookie;
+ struct p9100_screen *scr=ri->ri_hw;
+ struct p9100_softc *sc=scr->sc;
+ int32_t x,y,width,height,bg;
+
+ int start=ri->ri_cols*row, end=ri->ri_cols*(row+nrows),i;
+ for(i=start;i<end;i++) {
+ scr->attrs[i]=fillattr;
+ scr->chars[i]=0x20;
+ }
+
+ if((scr->active) && (sc->sc_mode==WSDISPLAYIO_MODE_EMUL)) {
+ x=ri->ri_xorigin;
+ y=ri->ri_yorigin+ri->ri_font->fontheight*row;
+ width=ri->ri_emuwidth;
+ height=ri->ri_font->fontheight*nrows;
+ bg=(fillattr>>16)&0xff;
+ p9100_rectfill(sc,x,y,width,height,bg);
+ }
+}
+
+int
+p9100_allocattr(void *cookie, int fg, int bg, int flags, long *attrp)
+{
+ /*printf("allocattr(%d %d %d)\n",fg,bg,flags);*/
+ if((fg==0)&&(bg==0))
+ {
+ fg=WS_DEFAULT_FG;
+ bg=WS_DEFAULT_BG;
+ }
+ if(flags&WSATTR_REVERSE) {
+ *attrp=(bg&0xff)<<24|(fg&0xff)<<16|(flags&0xff)<<8;
+ } else
+ *attrp=(fg&0xff)<<24|(bg&0xff)<<16|(flags&0xff)<<8;
+ return 0;
+}
+
+/*
+ * wsdisplay_accessops
+ */
+
+int
+p9100_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
+{
+ /* we'll probably need to add more stuff here */
+ struct p9100_softc *sc = v;
+ struct wsdisplay_fbinfo *wdf;
+ struct p9100_screen *ms=sc->active;
+ switch (cmd) {
+ case WSDISPLAYIO_GTYPE:
+ *(u_int *)data = WSDISPLAY_TYPE_SB_P9100;
+ return 0;
+
+ case FBIOGVIDEO:
+ case WSDISPLAYIO_SVIDEO:
+ *(int *)data = p9100_get_video(sc);
+ return 0;
+ case WSDISPLAYIO_GVIDEO:
+ case FBIOSVIDEO:
+ p9100_set_video(sc, *(int *)data);
+ return 0;
+
+ case WSDISPLAYIO_GINFO:
+ wdf = (void *)data;
+ wdf->height = ms->ri.ri_height;
+ wdf->width = ms->ri.ri_width;
+ wdf->depth = ms->ri.ri_depth;
+ wdf->cmsize = 256;
+ return 0;
+
+ case WSDISPLAYIO_GETCMAP:
+ return p9100_getcmap(sc, (struct wsdisplay_cmap *)data);
+
+ case WSDISPLAYIO_PUTCMAP:
+ return p9100_putcmap(sc, (struct wsdisplay_cmap *)data);
+
+ /* PCI config read/write passthrough. */
+ case WSDISPLAYIO_SMODE:
+ {
+ int new_mode=*(int*)data;
+ if(new_mode!=sc->sc_mode)
+ {
+ sc->sc_mode=new_mode;
+ if(new_mode==WSDISPLAYIO_MODE_EMUL)
+ {
+ /* we'll probably want to reset the console into a known state here
+ just in case the Xserver crashed or didn't properly clean up after
+ itself for whetever reason */
+ p9100_init_engine(sc); /* who knows what they did to the engine when we weren't looking */
+ p9100_restore_screen(ms, ms->type, ms->chars);
+ p9100_cursor(ms, ms->cursoron, ms->cursorrow, ms->cursorcol);
+ }
+ }
+ }
+ }
+ return EPASSTHROUGH;
+}
+
+paddr_t
+p9100_mmap(void *v, off_t offset, int prot)
+{
+ struct p9100_softc *sc = v;
+ paddr_t pa;
+ /* 'regular' framebuffer mmap()ing */
+ if(offset<sc->sc_fb_psize) {
+ pa = bus_space_mmap(sc->sc_bustag,sc->sc_fb_paddr+offset,0,prot,BUS_SPACE_MAP_LINEAR);
+ return pa;
+ }
+
+ if((offset>=sc->sc_fb_paddr) && (offset<(sc->sc_fb_paddr+sc->sc_fb_psize))) {
+ pa = bus_space_mmap(sc->sc_bustag,offset,0,prot,BUS_SPACE_MAP_LINEAR);
+ return pa;
+ }
+
+ if((offset>=sc->sc_ctl_paddr) && (offset<(sc->sc_ctl_paddr+sc->sc_ctl_psize))) {
+ pa = bus_space_mmap(sc->sc_bustag,offset,0,prot,BUS_SPACE_MAP_LINEAR);
+ return pa;
+ }
+
+ return -1;
+}
+
+void
+p9100_init_screen(struct p9100_softc *sc, struct p9100_screen *scr,
+ int existing, long *defattr)
+{
+ struct rasops_info *ri=&scr->ri;
+ int cnt;
+ scr->sc = sc;
+ /*scr->type = type;*/
+ scr->dispoffset = 0;
+ scr->cursorcol = 0;
+ scr->cursorrow = 0;
+ scr->cursordrawn=0;
+
+ ri->ri_depth = sc->sc_depth<<3;
+ ri->ri_width = sc->sc_width;
+ ri->ri_height = sc->sc_height;
+ ri->ri_stride = sc->sc_stride;
+ ri->ri_flg = RI_CENTER;
+
+ ri->ri_bits = bus_space_vaddr(sc->sc_bustag,sc->sc_fb_memh);
+
+#ifdef DEBUG_P9100
+ printf("addr: %08lx\n",(ulong)ri->ri_bits);
+#endif
+ rasops_init(ri, sc->sc_height/8, sc->sc_width/8);
+ ri->ri_caps=WSSCREEN_WSCOLORS;
+ rasops_reconfig(ri, sc->sc_height / ri->ri_font->fontheight,
+ sc->sc_width / ri->ri_font->fontwidth);
+
+ p9100_allocattr(ri, WS_DEFAULT_FG, WS_DEFAULT_BG, 0, defattr);
+
+ cnt=ri->ri_rows * ri->ri_cols;
+ scr->attrs=(long *)malloc(cnt*(sizeof(long)+sizeof(uint16_t)),
+ M_DEVBUF, M_WAITOK);
+ scr->chars=(uint16_t *)&scr->attrs[cnt];
+ /* we allocate both chars and attributes in one chunk, attributes first because
+ they have the (potentially) bigger alignment */
+
+ /* enable acceleration */
+ ri->ri_hw=scr;
+ ri->ri_ops.copyrows=p9100_copyrows;
+ ri->ri_ops.copycols=p9100_copycols;
+ ri->ri_ops.eraserows=p9100_eraserows;
+ ri->ri_ops.erasecols=p9100_erasecols;
+ ri->ri_ops.cursor=p9100_cursor;
+ ri->ri_ops.allocattr=p9100_allocattr;
+#ifdef PNOZZ_SOFT_PUTCHAR
+ if(sc->putchar==NULL)
+ sc->putchar=ri->ri_ops.putchar;
+#endif
+ ri->ri_ops.putchar=p9100_putchar;
+
+ if (existing) {
+ scr->active = 1;
+ } else {
+ scr->active = 0;
+ }
+
+ p9100_eraserows(&scr->ri, 0, ri->ri_rows, *defattr);
+
+ LIST_INSERT_HEAD(&sc->screens, scr, next);
+}
+
+int
+p9100_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
+ int *curxp, int *curyp, long *defattrp)
+{
+ struct p9100_softc *sc = v;
+ struct p9100_screen *scr;
+
+ scr = malloc(sizeof(struct p9100_screen), M_DEVBUF, M_WAITOK|M_ZERO);
+ p9100_init_screen(sc, scr, 0, defattrp);
+
+ if (sc->active == NULL) {
+ scr->active = 1;
+ sc->active = scr;
+ sc->currenttype = type;
+ }
+
+ *cookiep = scr;
+ *curxp = scr->cursorcol;
+ *curyp = scr->cursorrow;
+ return 0;
+}
+
+void
+p9100_free_screen(void *v, void *cookie)
+{
+ struct p9100_softc *sc = v;
+ struct p9100_screen *scr = cookie;
+
+ LIST_REMOVE(scr, next);
+ if (scr != &p9100_console_screen) {
+ free(scr->attrs, M_DEVBUF);
+ free(scr, M_DEVBUF);
+ } else
+ panic("p9100_free_screen: console");
+
+ if (sc->active == scr)
+ sc->active = 0;
+}
+
+int
+p9100_show_screen(void *v, void *cookie, int waitok,
+ void (*cb)(void *, int, int), void *cbarg)
+{
+ struct p9100_softc *sc = v;
+ struct p9100_screen *scr, *oldscr;
+
+ scr = cookie;
+ oldscr = sc->active;
+ if (scr == oldscr)
+ return 0;
+
+ sc->wanted = scr;
+ sc->switchcb = cb;
+ sc->switchcbarg = cbarg;
+ if (cb) {
+ callout_reset(&sc->switch_callout, 0,
+ (void(*)(void *))p9100_switch_screen, sc);
+ return EAGAIN;
+ }
+
+ p9100_switch_screen(sc);
+ return 0;
+}
+
+int
+p9100_putcmap(struct p9100_softc *sc, struct wsdisplay_cmap *cm)
+{
+ u_int index = cm->index;
+ u_int count = cm->count;
+ int i, error;
+ u_char rbuf[256], gbuf[256], bbuf[256];
+ u_char *r, *g, *b;
+
+ printf("putcmap: %d %d\n",index, count);
+ if (cm->index >= 256 || cm->count > 256 ||
+ (cm->index + cm->count) > 256)
+ return EINVAL;
+ error = copyin(cm->red, &rbuf[index], count);
+ if (error)
+ return error;
+ error = copyin(cm->green, &gbuf[index], count);
+ if (error)
+ return error;
+ error = copyin(cm->blue, &bbuf[index], count);
+ if (error)
+ return error;
+
+ r = &rbuf[index];
+ g = &gbuf[index];
+ b = &bbuf[index];
+
+ for (i = 0; i < count; i++) {
+ sc->sc_cmap.cm_map[index][0]=*r;
+ sc->sc_cmap.cm_map[index][1]=*g;
+ sc->sc_cmap.cm_map[index][2]=*b;
+ index++;
+ r++, g++, b++;
+ }
+ p9100loadcmap(sc,0,256);
+ return 0;
+}
+
+int
+p9100_getcmap(struct p9100_softc *sc, struct wsdisplay_cmap *cm)
+{
+ u_int index = cm->index;
+ u_int count = cm->count;
+ int error,i;
+ uint8_t red[256],green[256],blue[256];
+
+ if (index >= 255 || count > 256 || index + count > 256)
+ return EINVAL;
+
+ i=index;
+ while(i<(index+count)) {
+ red[i]=sc->sc_cmap.cm_map[i][0];
+ green[i]=sc->sc_cmap.cm_map[i][1];
+ blue[i]=sc->sc_cmap.cm_map[i][2];
+ i++;
+ }
+ error = copyout(&red[index], cm->red, count);
+ if (error)
+ return error;
+ error = copyout(&green[index], cm->green, count);
+ if (error)
+ return error;
+ error = copyout(&blue[index], cm->blue, count);
+ if (error)
+ return error;
+
+ return 0;
+}
+
+#if 0
+int
+p9100_load_font(void *v, void *cookie, struct wsdisplay_font *data)
+{
+
+ return 0;
+}
+#endif
+int
+p9100_intr(void *arg)
+{
+ //p9100_softc *sc=arg;
+ //printf(".");
+ return 1;
+}
... and put this into p9100reg.h:
/* $NetBSD: p9100.c,v 1.20 2005/02/27 00:27:48 perry Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Matt Thomas.
*
* 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.
*/
#ifndef P9100_REG_H
#define P9100_REG_H
/* The Tadpole 3GX Technical Reference Manual lies. The ramdac registers
* are map in 4 byte increments, not 8.
*/
#define SCRN_RPNT_CTL_1 0x0138 /* Screen Respaint Timing Control 1 */
#define VIDEO_ENABLED 0x00000020
#define PWRUP_CNFG 0x0194 /* Power Up Configuration */
#define DAC_CMAP_WRIDX 0x0200 /* IBM RGB528 Palette Address (Write) */
#define DAC_CMAP_DATA 0x0204 /* IBM RGB528 Palette Data */
#define DAC_PXL_MASK 0x0208 /* IBM RGB528 Pixel Mask */
#define DAC_CMAP_RDIDX 0x020c /* IBM RGB528 Palette Address (Read) */
#define DAC_INDX_LO 0x0210 /* IBM RGB528 Index Low */
#define DAC_INDX_HI 0x0214 /* IBM RGB528 Index High */
#define DAC_INDX_DATA 0x0218 /* IBM RGB528 Index Data (Indexed Registers) */
#define DAC_INDX_CTL 0x021c /* IBM RGB528 Index Control */
#define ENGINE_STATUS 0x2000 /* drawing engine status register */
#define BLITTER_BUSY 0x80000000
#define ENGINE_BUSY 0x40000000
#define COMMAND_BLIT 0x2004
#define COMMAND_QUAD 0x2008
#define PIXEL_1 0x2080 /* pixel data for monochrome colour expansion */
/* apparently bits 2-6 control how many pixels we write - n+1 */
/* drawing engine registers */
#define COORD_INDEX 0x218c
#define WINDOW_OFFSET 0x2190
#define FOREGROUND_COLOR 0x2200
#define BACKGROUND_COLOR 0x2204
#define PLANE_MASK 0x2208
#define DRAW_MODE 0x220c
#define PATTERN_ORIGIN_X 0x2210
#define PATTERN_ORIGIN_Y 0x2214
#define RASTER_OP 0x2218
#define ROP_NO_SOLID 0x02000 /* if set use pattern instead of color for quad operations */
#define ROP_2BIT_PATTERN 0x04000 /* 4-colour pattern instead of mono */
#define ROP_PIX1_TRANS 0x08000 /* transparent background in mono */
#define ROP_OVERSIZE 0x10000
#define ROP_PATTERN 0x20000 /* the manual says pattern enable */
#define ROP_TRANS 0x20000 /* but XFree86 says trans */
#define ROP_SRC 0xCC
#define ROP_PAT 0xF0
#define ROP_DST 0xAA
#define ROP_SET 0xff
#define PIXEL_8 0x221c
#define WINDOW_MIN 0x2220
#define WINDOW_MAX 0x2224
#define PATTERN0 0x2280
#define PATTERN1 0x2284
#define PATTERN2 0x2288
#define PATTERN3 0x228c
#define USER0 0x2290
#define USER1 0x2294
#define USER2 0x2298
#define USER3 0x229c
#define BYTE_CLIP_MIN 0x22a0
#define BYTE_CLIP_MAX 0x22a4
/* coordinate registers */
#define ABS_X0 0x3008
#define ABS_Y0 0x3010
#define ABS_XY0 0x3018
#define REL_X0 0x3028
#define REL_Y0 0x3030
#define REL_XY0 0x3038
#define ABS_X1 0x3048
#define ABS_Y1 0x3050
#define ABS_XY1 0x3058
#define REL_X1 0x3068
#define REL_Y1 0x3070
#define REL_XY1 0x3078
#define ABS_X2 0x3088
#define ABS_Y2 0x3090
#define ABS_XY2 0x3098
#define REL_X2 0x30a8
#define REL_Y2 0x30b0
#define REL_XY2 0x30b8
#define ABS_X3 0x30c8
#define ABS_Y3 0x30d0
#define ABS_XY3 0x30d8
#define REL_X3 0x30e8
#define REL_Y3 0x30f0
#define REL_XY3 0x30f8
/* meta-coordinates */
#define POINT_RTW_X 0x3208
#define POINT_RTW_Y 0x3210
#define POINT_RTW_XY 0x3218
#define POINT_RTP_X 0x3228
#define POINT_RTP_Y 0x3220
#define POINT_RTP_XY 0x3238
#define LINE_RTW_X 0x3248
#define LINE_RTW_Y 0x3250
#define LINE_RTW_XY 0x3258
#define LINE_RTP_X 0x3268
#define LINE_RTP_Y 0x3260
#define LINE_RTP_XY 0x3278
#define TRIANGLE_RTW_X 0x3288
#define TRIANGLE_RTW_Y 0x3290
#define TRIANGLE_RTW_XY 0x3298
#define TRIANGLE_RTP_X 0x32a8
#define TRIANGLE_RTP_Y 0x32a0
#define TRIANGLE_RTP_XY 0x32b8
#define QUAD_RTW_X 0x32c8
#define QUAD_RTW_Y 0x32d0
#define QUAD_RTW_XY 0x32d8
#define QUAD_RTP_X 0x32e8
#define QUAD_RTP_Y 0x32e0
#define QUAD_RTP_XY 0x32f8
#define RECT_RTW_X 0x3308
#define RECT_RTW_Y 0x3310
#define RECT_RTW_XY 0x3318
#define RECT_RTP_X 0x3328
#define RECT_RTP_Y 0x3320
#define RECT_RTP_XY 0x3338
#endif