Module Name:    src
Committed By:   martin
Date:           Thu May 16 12:27:50 UTC 2024

Modified Files:
        src/distrib/notes/hp300 [netbsd-10]: hardware
        src/share/man/man4/man4.hp300 [netbsd-10]: topcat.4
        src/sys/arch/hp300/dev [netbsd-10]: diofb.c diofbvar.h topcat.c
            topcatreg.h

Log Message:
Pull up following revision(s) (requested by tsutsui in ticket #690):

        sys/arch/hp300/dev/topcat.c: revision 1.7
        sys/arch/hp300/dev/topcat.c: revision 1.8
        sys/arch/hp300/dev/topcat.c: revision 1.9
        sys/arch/hp300/dev/diofb.c: revision 1.8
        sys/arch/hp300/dev/diofb.c: revision 1.9
        sys/arch/hp300/dev/diofb.c: revision 1.10
        sys/arch/hp300/dev/topcat.c: revision 1.10
        sys/arch/hp300/dev/topcat.c: revision 1.11
        sys/arch/hp300/dev/topcat.c: revision 1.12
        sys/arch/hp300/dev/topcatreg.h: revision 1.5
        distrib/notes/hp300/hardware: revision 1.28
        sys/arch/hp300/dev/diofbvar.h: revision 1.5
        share/man/man4/man4.hp300/topcat.4: revision 1.8

Increase DELAY() for waitbusy macroes as pre-wscons and 4.4BSD did.

It looks necessary for sane palette ops at least on HP98543 topcat
on 68030 HP 9000/360.

Move a check of topcat(4) specific fb width quirks to topcat.c.

We need to check fb->planes but it's propbed in topcat.c after
common diofb_fbinquire() is called.

Also add a comment that it looks these 1 bpp and 4 bpp boards have
VRAM with sparse address layout and we have to handle
512 pixels per line with 1024 bytes per line.

Fix MD allocattr to return proper attributes what MI rasops(9) expects.
Use proper planemask per a vaild number of planes.

Check tc_waitbusy() before writing palette registers in topcat_setcolor().
This seems to make palette operations more stable on my HP360 with HP98543.

Add DELAY(9) to make palette register settings stable on 98543 in HP360.
Note 98547 (6 bpp variant) on HP370 (68030 33MHz) doesn't need these
DELAYs so maybe only some old variants (98543 and 98545?) on 020/030
have such restriction (actually only one nop seems enough.)

Fix topcat(4) problems on some models that cause garbages on screen.
- Make sure that windowmove (hardware BITBLT) ops complete by checking
  tc_busywait() before calling putchar functions by MI rasops(9).
  It looks CPU accesses against VRAM during windowmove (copy, erase,
  and cursor) ops causes unexpected garbages at least on 98543 on HP360,
  98547 on HP370, and also on 98543 on 040 HP380 (but not on 98549).
- Handle 'sparse VRAM' on 98543 (and probably 98542) properly:
 - Prepare and use own topcat_putchar1_4() function for sparse VRAM.
 - Pass proper 'VRAM width' rather than actuall font width to all
   windowmove (copycols, erasecols, copyrows, eraserows, and do_cursor)
   operation functions.
Now all topcat(4) consoles on 98543 on HP360/HP380 and 98547 on HP370
work fine, and no visible regression on 98549 on HP380 and 98544 on HP360.

Note that 98542 and 98543 variants are also supported by topcat(4).

Add 98542 and 98543 framebuffers to supported "Graphics Devices" section.
I hope someone will sync a list of supported devices in port wiki pages
with one in this installation notes.

Add comments about quirks of 98542/98543 framebuffers with 1024x400 pixels.


To generate a diff of this commit:
cvs rdiff -u -r1.26.2.1 -r1.26.2.2 src/distrib/notes/hp300/hardware
cvs rdiff -u -r1.7 -r1.7.54.1 src/share/man/man4/man4.hp300/topcat.4
cvs rdiff -u -r1.7 -r1.7.6.1 src/sys/arch/hp300/dev/diofb.c
cvs rdiff -u -r1.3 -r1.3.90.1 src/sys/arch/hp300/dev/diofbvar.h
cvs rdiff -u -r1.6 -r1.6.2.1 src/sys/arch/hp300/dev/topcat.c
cvs rdiff -u -r1.2 -r1.2.90.1 src/sys/arch/hp300/dev/topcatreg.h

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

Modified files:

Index: src/distrib/notes/hp300/hardware
diff -u src/distrib/notes/hp300/hardware:1.26.2.1 src/distrib/notes/hp300/hardware:1.26.2.2
--- src/distrib/notes/hp300/hardware:1.26.2.1	Sun Jan 14 16:00:09 2024
+++ src/distrib/notes/hp300/hardware	Thu May 16 12:27:50 2024
@@ -1,4 +1,4 @@
-.\"	$NetBSD: hardware,v 1.26.2.1 2024/01/14 16:00:09 martin Exp $
+.\"	$NetBSD: hardware,v 1.26.2.2 2024/05/16 12:27:50 martin Exp $
 .
 .Nx*M
 \*V will run on most HP 9000/300- and 400-series machines.
@@ -155,6 +155,10 @@ Network interfaces
 .It
 Graphics Devices
 .(bullet -compact
+98542 monochrome Topcat (512x400, 1 bit, DIO-II)
+.It
+98543 color Topcat (512x400, 4 bits, DIO-II)
+.It
 98544 monochrome Topcat (1024x768, 1 bit, DIO-II)
 .It
 98545A color Topcat (1024x768, 4 bits, DIO-II)

Index: src/share/man/man4/man4.hp300/topcat.4
diff -u src/share/man/man4/man4.hp300/topcat.4:1.7 src/share/man/man4/man4.hp300/topcat.4:1.7.54.1
--- src/share/man/man4/man4.hp300/topcat.4:1.7	Wed Feb  9 14:37:56 2011
+++ src/share/man/man4/man4.hp300/topcat.4	Thu May 16 12:27:50 2024
@@ -1,4 +1,4 @@
-.\"	$NetBSD: topcat.4,v 1.7 2011/02/09 14:37:56 wiz Exp $
+.\"	$NetBSD: topcat.4,v 1.7.54.1 2024/05/16 12:27:50 martin Exp $
 .\"
 .\" Copyright (c) 1990, 1991, 1993
 .\"	The Regents of the University of California.  All rights reserved.
@@ -33,7 +33,7 @@
 .\"
 .\"     from: @(#)tc.4	8.1 (Berkeley) 6/9/93
 .\"
-.Dd February 9, 2011
+.Dd May 1, 2024
 .Dt TOPCAT 4 hp300
 .Os
 .Sh NAME
@@ -52,7 +52,7 @@ device interface
 .Sh DESCRIPTION
 This driver is for the
 .Tn HP98544 ,
-98545 and 98547
+98545, 98542, 98543, and 98547
 .Dq Topcat
 and
 .Tn HP98548 ,

Index: src/sys/arch/hp300/dev/diofb.c
diff -u src/sys/arch/hp300/dev/diofb.c:1.7 src/sys/arch/hp300/dev/diofb.c:1.7.6.1
--- src/sys/arch/hp300/dev/diofb.c:1.7	Sat Aug  7 16:18:53 2021
+++ src/sys/arch/hp300/dev/diofb.c	Thu May 16 12:27:50 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: diofb.c,v 1.7 2021/08/07 16:18:53 thorpej Exp $	*/
+/*	$NetBSD: diofb.c,v 1.7.6.1 2024/05/16 12:27:50 martin Exp $	*/
 /*	$OpenBSD: diofb.c,v 1.18 2010/12/26 15:40:59 miod Exp $	*/
 
 /*
@@ -146,15 +146,6 @@ diofb_fbinquire(struct diofb *fb, int sc
 	if (fb->dheight > fb->fbheight)
 		fb->dheight = fb->fbheight;
 
-	/*
-	 * Some displays, such as the HP332 and HP340 internal video
-	 * appear to return a display width of 1024 instead of 512.
-	 */
-	if (fbr->num_planes == 1 || fbr->num_planes == 4) {
-		if (fb->dwidth == 1024 && fb->dheight == 400)
-			fb->dwidth = 512;
-	}
-
 	fb->planes = fbr->num_planes;
 	if (fb->planes > 8)
 		fb->planes = 8;
@@ -360,9 +351,7 @@ diofb_allocattr(void *cookie, int fg, in
 		bg = swap;
 	}
 
-	flg = ((flg & WSATTR_UNDERLINE) ? 1 : 0);
-
-	*attr = (bg << 16) | (fg << 24) | flg;
+	*attr = (bg << 16) | (fg << 24) | (flg & WSATTR_UNDERLINE);
 
 	return 0;
 }
@@ -372,10 +361,11 @@ diofb_copycols(void *cookie, int row, in
 {
 	struct rasops_info *ri = cookie;
 	struct diofb *fb = ri->ri_hw;
+	int fontwidth = fb->wsd.fontwidth;
 
-	n *= ri->ri_font->fontwidth;
-	src *= ri->ri_font->fontwidth;
-	dst *= ri->ri_font->fontwidth;
+	n *= fontwidth;
+	src *= fontwidth;
+	dst *= fontwidth;
 	row *= ri->ri_font->fontheight;
 
 	(*fb->bmv)(fb, ri->ri_xorigin + src, ri->ri_yorigin + row,
@@ -405,11 +395,12 @@ diofb_erasecols(void *cookie, int row, i
 	struct diofb *fb = ri->ri_hw;
 	int fg, bg;
 	int snum, scol, srow;
+	int fontwidth = fb->wsd.fontwidth;
 
 	rasops_unpack_attr(attr, &fg, &bg, NULL);
 
-	snum = num * ri->ri_font->fontwidth;
-	scol = col * ri->ri_font->fontwidth + ri->ri_xorigin;
+	snum = num * fontwidth;
+	scol = col * fontwidth + ri->ri_xorigin;
 	srow = row * ri->ri_font->fontheight + ri->ri_yorigin;
 
 	/*
@@ -434,7 +425,7 @@ diofb_eraserows(void *cookie, int row, i
 	bg ^= 0xff;
 
 	if (num == ri->ri_rows && (ri->ri_flg & RI_FULLCLEAR)) {
-		rc = (*fb->bmv)(fb, 0, 0, 0, 0, ri->ri_width, ri->ri_height,
+		rc = (*fb->bmv)(fb, 0, 0, 0, 0, fb->fbwidth, ri->ri_height,
 		    RR_CLEAR, bg);
 	} else {
 		srow = row * ri->ri_font->fontheight + ri->ri_yorigin;
@@ -451,10 +442,11 @@ diofb_do_cursor(struct rasops_info *ri)
 {
 	struct diofb *fb = ri->ri_hw;
 	int x, y;
+	int fontwidth = fb->wsd.fontwidth;
 
-	x = ri->ri_ccol * ri->ri_font->fontwidth + ri->ri_xorigin;
+	x = ri->ri_ccol * fontwidth + ri->ri_xorigin;
 	y = ri->ri_crow * ri->ri_font->fontheight + ri->ri_yorigin;
-	(*fb->bmv)(fb, x, y, x, y, ri->ri_font->fontwidth,
+	(*fb->bmv)(fb, x, y, x, y, fontwidth,
 	    ri->ri_font->fontheight, RR_INVERT, 0xff);
 }
 

Index: src/sys/arch/hp300/dev/diofbvar.h
diff -u src/sys/arch/hp300/dev/diofbvar.h:1.3 src/sys/arch/hp300/dev/diofbvar.h:1.3.90.1
--- src/sys/arch/hp300/dev/diofbvar.h:1.3	Sat Feb 12 16:40:29 2011
+++ src/sys/arch/hp300/dev/diofbvar.h	Thu May 16 12:27:50 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: diofbvar.h,v 1.3 2011/02/12 16:40:29 tsutsui Exp $	*/
+/*	$NetBSD: diofbvar.h,v 1.3.90.1 2024/05/16 12:27:50 martin Exp $	*/
 /*	$OpenBSD: diofbvar.h,v 1.10 2006/08/11 18:33:13 miod Exp $	*/
 
 /*
@@ -105,6 +105,9 @@ struct diofb {
 	/* blockmove routine */
 	int	(*bmv)(struct diofb *, uint16_t, uint16_t, uint16_t,
 		    uint16_t, uint16_t, uint16_t, int16_t, int16_t);
+
+	/* putchar routine to handle rasops; MD busywait might be required */
+	void	(*wsputchar)(void *, int, int, u_int, long);
 };
 
 /* Replacement Rules (rops) */

Index: src/sys/arch/hp300/dev/topcat.c
diff -u src/sys/arch/hp300/dev/topcat.c:1.6 src/sys/arch/hp300/dev/topcat.c:1.6.2.1
--- src/sys/arch/hp300/dev/topcat.c:1.6	Wed Nov 30 11:36:50 2022
+++ src/sys/arch/hp300/dev/topcat.c	Thu May 16 12:27:50 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: topcat.c,v 1.6 2022/11/30 11:36:50 tsutsui Exp $	*/
+/*	$NetBSD: topcat.c,v 1.6.2.1 2024/05/16 12:27:50 martin Exp $	*/
 /*	$OpenBSD: topcat.c,v 1.15 2006/08/11 18:33:13 miod Exp $	*/
 
 /*
@@ -149,6 +149,8 @@ static int	topcat_windowmove(struct diof
 		    uint16_t, uint16_t, uint16_t, int16_t, int16_t);
 
 static int	topcat_ioctl(void *, void *, u_long, void *, int, struct lwp *);
+static void	topcat_putchar8(void *, int, int, u_int, long);
+static void	topcat_putchar1_4(void *, int, int, u_int, long);
 
 static struct wsdisplay_accessops topcat_accessops = {
 	topcat_ioctl,
@@ -312,8 +314,10 @@ int
 topcat_reset(struct diofb *fb, int scode, struct diofbreg *fbr)
 {
 	volatile struct tcboxfb *tc = (struct tcboxfb *)fbr;
+	struct rasops_info *ri = &fb->ri;
 	int rc;
 	u_int i;
+	bool sparse = false;
 
 	if ((rc = diofb_fbinquire(fb, scode, fbr)) != 0)
 		return rc;
@@ -344,9 +348,47 @@ topcat_reset(struct diofb *fb, int scode
 		fb->planemask = (1 << fb->planes) - 1;
 	}
 
+	/*
+	 * Some displays, such as the HP332 and HP340 internal video
+	 * and HP98542/98543 appear to return a display width of 1024
+	 * instead of 512. It looks these boards have actually have
+	 * enough 64KB (1bpp) or 256KB (4bpp) VRAM and RAMDAC capabilities
+	 * to display 1024x400 pixels.
+	 * 
+	 * However HP's officlal "Service Information Manual" for
+	 * "HP 900 Series 300 Computers Models 330/350" says:
+	 *  "The medium-resolution board uses eight memory chips per plane.
+	 *   This is enough to display 512 doubled pixels by 400 scan lines."
+	 *
+	 * This "512 doubled pixels" implies that the native HP-UX treated
+	 * these 1024x400 framebuffers as pseudo 512x400 ones because
+	 * ancient 1980s CRTs (such as 35741) didn't display such higher
+	 * resolution. Furthermore, even modern LCDs can only handle
+	 * upto 720 pixels in the "400 line" as VGA compatible mode.
+	 *
+	 * As mentioned above, we treat these 1024x400 1 bit or 4 bit
+	 * framebuffers as "2 bytes per pixel" ones, so we have to handle
+	 * 512 pixels per line with 1024 bytes per line.
+	 */
+	if (fb->planes <= 4 && fb->dwidth == 1024 && fb->dheight == 400) {
+		fb->dwidth = 512;
+		sparse = true;
+	}
+
 	fb->bmv = topcat_windowmove;
 	topcat_restore(fb);
 	diofb_fbsetup(fb);
+	if (!sparse) {
+		/* save original rasops putchar op */
+		fb->wsputchar = ri->ri_ops.putchar;
+		ri->ri_ops.putchar = topcat_putchar8;
+	} else {
+		ri->ri_ops.putchar = topcat_putchar1_4;
+		/* copycols and erasecols ops require byte size of fontwidth */
+		fb->wsd.fontwidth *= 2;
+		/* copyrows and eraserows ops require byte size per line */
+		ri->ri_emuwidth *= 2;
+	}
 	for (i = 0; i <= fb->planemask; i++)
 		topcat_setcolor(fb, i);
 
@@ -382,7 +424,7 @@ topcat_restore(struct diofb *fb)
 	tc->prr  = RR_COPY;
 
 	/* Enable display */
-	tc->nblank = 0xff;
+	tc->nblank = fb->planemask;
 }
 
 int
@@ -440,9 +482,11 @@ topcat_setcolor(struct diofb *fb, u_int 
 	if (fb->planemask == 1)
 		return;
 
+	tc_waitbusy(tc, fb->planemask);
+
 	if (tc->regs.fbid != GID_TOPCAT) {
 		tccm_waitbusy(tc);
-		tc->plane_mask = 0xff;
+		tc->plane_mask = fb->planemask;
 		tc->cindex = ~index;
 		tc->rdata  = fb->cmap.r[index];
 		tc->gdata  = fb->cmap.g[index];
@@ -455,11 +499,13 @@ topcat_setcolor(struct diofb *fb, u_int 
 		tc->cindex = 0;
 	} else {
 		tccm_waitbusy(tc);
-		tc->plane_mask = 0xff;
+		tc->plane_mask = fb->planemask;
 		tc->rdata  = fb->cmap.r[index];
 		tc->gdata  = fb->cmap.g[index];
 		tc->bdata  = fb->cmap.b[index];
+		DELAY(1);	/* necessary for at least old HP98543 */
 		tc->cindex = ~index;
+		DELAY(1);	/* necessary for at least old HP98543 */
 		tc->strobe = 0xff;
 		/* XXX delay required on 68020/30 to avoid bus error */
 		DELAY(100);
@@ -513,12 +559,13 @@ topcat_windowmove(struct diofb *fb, uint
 
 	tc_waitbusy(tc, fb->planemask);
 
-	tc->wen = planemask;
-	tc->wmrr = rop;
 	if (planemask != 0xff) {
 		tc->wen = planemask ^ 0xff;
 		tc->wmrr = rop ^ 0x0f;
 		tc->wen = fb->planemask;
+	} else {
+		tc->wen = planemask;
+		tc->wmrr = rop;
 	}
 	tc->source_y = sy;
 	tc->source_x = sx;
@@ -528,11 +575,108 @@ topcat_windowmove(struct diofb *fb, uint
 	tc->wwidth = cx;
 	tc->wmove = fb->planemask;
 
-	tc_waitbusy(tc, fb->planemask);
-
 	return 0;
 }
 
+static void
+topcat_putchar8(void *cookie, int row, int col, u_int uc, long attr)
+{
+	struct rasops_info *ri = (struct rasops_info *)cookie;
+	struct diofb *diofb = ri->ri_hw;
+	volatile struct tcboxfb *tc = (struct tcboxfb *)diofb->regkva;
+
+	/* Wait windowmove ops complete before drawing a glyph */
+	tc_waitbusy(tc, diofb->planemask);
+
+	/* Call the original rasops putchar */
+	(*diofb->wsputchar)(cookie, row, col, uc, attr);
+}
+
+/*
+ * Put a single character on 1 bpp (98542) or 4 bpp (98543) variants
+ * with 1024x400 VRAM to treat them as a pseudo 512x400 bitmap.
+ */
+static void
+topcat_putchar1_4(void *cookie, int row, int col, u_int uc, long attr)
+{
+	int width, height, cnt, fs;
+	uint32_t fb;
+	uint8_t *fr, clr[2];
+	uint8_t *dp, *rp;
+	struct rasops_info *ri;
+	struct diofb *diofb;
+	volatile struct tcboxfb *tc;
+
+	ri = (struct rasops_info *)cookie;
+
+	if (!CHAR_IN_FONT(uc, ri->ri_font))
+		return;
+
+	rp = ri->ri_bits + (row * ri->ri_yscale) +
+	    (col * ri->ri_xscale * 2);
+
+	height = ri->ri_font->fontheight;
+	width = ri->ri_font->fontwidth;
+	clr[0] = (uint8_t)ri->ri_devcmap[(attr >> 16) & 0xf];
+	clr[1] = (uint8_t)ri->ri_devcmap[(attr >> 24) & 0xf];
+
+	/* Wait windowmove ops complete before drawing a glyph */
+	diofb = ri->ri_hw;
+	tc = (struct tcboxfb *)diofb->regkva;
+	tc_waitbusy(tc, diofb->planemask);
+
+	/*
+	 * We have to put pixel data to both odd and even addresses
+	 * to handle "doubled pixels" as noted above.
+	 */
+	if (uc == ' ') {
+		uint16_t c = clr[0];
+
+		c = c << 8 | c;
+		while (height--) {
+			dp = rp;
+			rp += ri->ri_stride;
+
+			for (cnt = width; cnt; cnt--) {
+				*(uint16_t *)dp = c;
+				dp += 2;
+			}
+		}
+	} else {
+		uc -= ri->ri_font->firstchar;
+		fr = (uint8_t *)ri->ri_font->data + uc * ri->ri_fontscale;
+		fs = ri->ri_font->stride;
+
+		while (height--) {
+			dp = rp;
+			fb = be32dec(fr);
+			fr += fs;
+			rp += ri->ri_stride;
+
+			for (cnt = width; cnt; cnt--) {
+				uint16_t c = clr[(fb >> 31) & 1];
+
+				c = c << 8 | c;
+				*(uint16_t *)dp = c;
+				dp += 2;
+				fb <<= 1;
+			}
+		}
+	}
+
+	/* Do underline */
+	if ((attr & WSATTR_UNDERLINE) != 0) {
+		uint16_t c = clr[1];
+
+		c = c << 8 | c;
+		rp -= ri->ri_stride * ri->ri_ul.off;
+
+		while (width--) {
+			*(uint16_t *)rp = c;
+			rp += 2;
+		}
+	}
+}
 
 /*
  *   Topcat/catseye console attachment

Index: src/sys/arch/hp300/dev/topcatreg.h
diff -u src/sys/arch/hp300/dev/topcatreg.h:1.2 src/sys/arch/hp300/dev/topcatreg.h:1.2.90.1
--- src/sys/arch/hp300/dev/topcatreg.h:1.2	Sat Feb 12 16:40:29 2011
+++ src/sys/arch/hp300/dev/topcatreg.h	Thu May 16 12:27:50 2024
@@ -1,5 +1,5 @@
 /*	$OpenBSD: topcatreg.h,v 1.2 2005/01/24 21:36:39 miod Exp $	*/
-/*	$NetBSD: topcatreg.h,v 1.2 2011/02/12 16:40:29 tsutsui Exp $	*/
+/*	$NetBSD: topcatreg.h,v 1.2.90.1 2024/05/16 12:27:50 martin Exp $	*/
 
 /*
  * Copyright (c) 1988 University of Utah.
@@ -42,13 +42,13 @@
 #define tccm_waitbusy(regaddr) \
 do { \
 	while (((volatile struct tcboxfb *)(regaddr))->cmap_busy & 0x04) \
-		DELAY(10); \
+		DELAY(100); \
 } while (/* CONSTCOND */0)
 
 #define tc_waitbusy(regaddr,planes) \
 do { \
 	while (((volatile struct tcboxfb *)(regaddr))->busy & planes) \
-		DELAY(10); \
+		DELAY(100); \
 } while (/* CONSTCOND */0)
 
 struct tcboxfb {

Reply via email to