I've separated out the 256 colour code from the rest of my console enhancement patchset, because it seems that the bold and italic code was causing some problems that I haven't yet fully resolved.
Also, various bits from the previous mega-patch are now in cvs, so it no longer applies cleanly. Index: rasops/rasops.c =================================================================== RCS file: /cvs/src/sys/dev/rasops/rasops.c,v retrieving revision 1.69 diff -u -p -r1.69 rasops.c --- rasops/rasops.c 18 Jan 2023 11:08:49 -0000 1.69 +++ rasops/rasops.c 30 Jan 2023 09:08:22 -0000 @@ -446,6 +446,10 @@ rasops_reconfig(struct rasops_info *ri, WSSCREEN_WSCOLORS | WSSCREEN_REVERSE; } + if (ri->ri_depth == 32) { + ri->ri_caps |= WSSCREEN_256COL ; + } + switch (ri->ri_depth) { #if NRASOPS1 > 0 case 1: @@ -561,7 +565,7 @@ rasops_pack_cattr(void *cookie, int fg, if ((flg & WSATTR_HILIT) != 0 && fg < 8) fg += 8; - *attr = (bg << 16) | (fg << 24) | (flg & WSATTR_UNDERLINE); + *attr = (bg << 16) | (fg << 24) | flg; return (0); } @@ -867,6 +871,18 @@ rasops_init_devcmap(struct rasops_info * ri->ri_devcmap[i] = c; #endif } + + /* Define colours 16-255 iff we are running in 32bpp */ + + if (ri->ri_depth == 32) { + for (i = 16 ; i <= 231; i++) { + ri->ri_devcmap[i] = EBCOL(i); + } + for (i = 232 ; i < 256; i++) { + ri->ri_devcmap[i] = EBGREY(i) | EBGREY(i) << 8 | + EBGREY(i) << 16; + } + } #endif } @@ -876,8 +892,8 @@ rasops_init_devcmap(struct rasops_info * void rasops_unpack_attr(void *cookie, uint32_t attr, int *fg, int *bg, int *underline) { - *fg = ((u_int)attr >> 24) & 0xf; - *bg = ((u_int)attr >> 16) & 0xf; + *fg = ((u_int)attr >> 24) & 0xff; + *bg = ((u_int)attr >> 16) & 0xff; if (underline != NULL) *underline = (u_int)attr & WSATTR_UNDERLINE; } @@ -907,7 +923,7 @@ rasops_eraserows(void *cookie, int row, return 0; #endif - clr = ri->ri_devcmap[(attr >> 16) & 0xf]; + clr = ri->ri_devcmap[(attr >> 16) & 0xff]; /* * XXX The wsdisplay_emulops interface seems a little deficient in @@ -1061,7 +1077,7 @@ rasops_erasecols(void *cookie, int row, num = num * ri->ri_xscale; rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale); height = ri->ri_font->fontheight; - clr = ri->ri_devcmap[(attr >> 16) & 0xf]; + clr = ri->ri_devcmap[(attr >> 16) & 0xff]; /* Don't bother using the full loop for <= 32 pels */ if (num <= 32) { @@ -1263,7 +1279,7 @@ rasops_putchar_rotated(void *cookie, int /* XXX this assumes 16-bit color depth */ if ((attr & WSATTR_UNDERLINE) != 0) { - int16_t c = (int16_t)ri->ri_devcmap[((u_int)attr >> 24) & 0xf]; + int16_t c = (int16_t)ri->ri_devcmap[((u_int)attr >> 24) & 0xff]; while (height--) { *(int16_t *)rp = c; @@ -1791,8 +1807,8 @@ rasops_wronly_do_cursor(struct rasops_in attr = ri->ri_bs[off].attr; if ((ri->ri_flg & RI_CURSOR) == 0) { - fg = ((u_int)attr >> 24) & 0xf; - bg = ((u_int)attr >> 16) & 0xf; + fg = ((u_int)attr >> 24) & 0xff; + bg = ((u_int)attr >> 16) & 0xff; attr &= ~0x0ffff0000; attr |= (fg << 16) | (bg << 24); } Index: rasops/rasops.h =================================================================== RCS file: /cvs/src/sys/dev/rasops/rasops.h,v retrieving revision 1.25 diff -u -p -r1.25 rasops.h --- rasops/rasops.h 25 May 2020 09:55:49 -0000 1.25 +++ rasops/rasops.h 30 Jan 2023 09:08:22 -0000 @@ -106,7 +106,7 @@ struct rasops_info { u_char *ri_origbits; /* where screen bits actually start */ int ri_xorigin; /* where ri_bits begins (x) */ int ri_yorigin; /* where ri_bits begins (y) */ - int32_t ri_devcmap[16]; /* color -> framebuffer data */ + int32_t ri_devcmap[256]; /* color -> framebuffer data */ /* The emulops you need to use, and the screen caps for wscons */ struct wsdisplay_emulops ri_ops; @@ -184,5 +184,16 @@ int rasops_check_framebuffer(paddr_t); extern const u_char rasops_isgray[16]; extern const u_char rasops_cmap[256*3]; + +/* + * Macros to calculate the 6x6x6 colour cube and greyscale ramp used when + * supporting 256-colours + */ + +#define EBCOL_RED(x) (48*((x-16)%6)) +#define EBCOL_GREEN(x) ((48*(((x-16)/6)%6)) << 8) +#define EBCOL_BLUE(x) ((48*(((x-16)/36)%6)) << 16) +#define EBCOL(x) EBCOL_RED(x) | EBCOL_GREEN(x) | EBCOL_BLUE(x) +#define EBGREY(x) (int)(1+((i-232)*11)) #endif /* _RASOPS_H_ */ Index: rasops/rasops32.c =================================================================== RCS file: /cvs/src/sys/dev/rasops/rasops32.c,v retrieving revision 1.13 diff -u -p -r1.13 rasops32.c --- rasops/rasops32.c 18 Jan 2023 11:08:49 -0000 1.13 +++ rasops/rasops32.c 30 Jan 2023 09:08:22 -0000 @@ -91,8 +91,8 @@ rasops32_putchar(void *cookie, int row, width = ri->ri_font->fontwidth; step = ri->ri_stride >> 3; - b = ri->ri_devcmap[(attr >> 16) & 0xf]; - f = ri->ri_devcmap[(attr >> 24) & 0xf]; + b = ri->ri_devcmap[(attr >> 16) & 0xff]; + f = ri->ri_devcmap[(attr >> 24) & 0xff]; u.d[0][0] = b; u.d[0][1] = b; u.d[1][0] = b; u.d[1][1] = f; u.d[2][0] = f; u.d[2][1] = b; Index: wscons/wsdisplayvar.h =================================================================== RCS file: /cvs/src/sys/dev/wscons/wsdisplayvar.h,v retrieving revision 1.38 diff -u -p -r1.38 wsdisplayvar.h --- wscons/wsdisplayvar.h 13 Sep 2020 10:05:46 -0000 1.38 +++ wscons/wsdisplayvar.h 30 Jan 2023 09:08:22 -0000 @@ -114,6 +114,7 @@ struct wsscreen_descr { #define WSSCREEN_HILIT 4 /* can highlight (however) */ #define WSSCREEN_BLINK 8 /* can blink */ #define WSSCREEN_UNDERLINE 16 /* can underline */ +#define WSSCREEN_256COL 32 /* supports 256 colours */ }; /* Index: wscons/wsemul_vt100_subr.c =================================================================== RCS file: /cvs/src/sys/dev/wscons/wsemul_vt100_subr.c,v retrieving revision 1.29 diff -u -p -r1.29 wsemul_vt100_subr.c --- wscons/wsemul_vt100_subr.c 12 Jan 2023 20:39:37 -0000 1.29 +++ wscons/wsemul_vt100_subr.c 30 Jan 2023 09:08:22 -0000 @@ -615,6 +615,62 @@ wsemul_vt100_handle_csi(struct wsemul_vt flags |= WSATTR_WSCOLORS; fgcol = ARG(n) - 30; break; + /* + * Sequences starting CSI 38 escape to a larger + * colourspace, typically either 256 colours or 24-bit. + * + * We support CSI 38;5;X;m to set colour X from a + * palette of 256. + */ + case 38: + /* + * 38 followed by zero arguments is meaningless. + */ + if (edp->nargs == n+1) { + break ; + } + /* + * 5 should normally be followed by a single + * argument, but zero arguments is also valid to + * set colour zero. + */ + if (ARG(n + 1)== 5) { + flags |= WSATTR_WSCOLORS; + if (edp->scrcapabilities & + WSSCREEN_256COL) { + fgcol = ARG2_OR_DEF(n); + } else { + fgcol = (ARG2_OR_DEF(n) < 8 ? + ARG2_OR_DEF(n) : fgcol ); + } + n+=(EXIST_ARG2(n) ? 2 : 1); + break; + } + /* + * 2 should introduce a sequence of three + * arguments, specifying RGB. + * + * We don't, (yet!), support setting colours by + * 24-bit RGB arguments and don't want to + * interpret these as regular SGR codes. + * + * If there are more then three, skip just + * three, otherwise skip all of them. + */ + if (ARG(n + 1) == 2) { + n=(edp->nargs-n > 5 ? n + 4 : + edp->nargs); + break; + } + /* + * Invalid code, I.E. not 2 or 5. + * + * We do what xterm does and just skip the + * single unrecognised argument, then allow any + * following arguments to be interpreted as SGR. + */ + n++; + break; case 39: /* reset fg color */ fgcol = WSCOL_WHITE; @@ -626,6 +682,29 @@ wsemul_vt100_handle_csi(struct wsemul_vt /* bg color */ flags |= WSATTR_WSCOLORS; bgcol = ARG(n) - 40; + break; + case 48: /* set 8-bit background colour */ + if (edp->nargs == n+1) { + break ; + } + if (ARG(n+1)==5) { + flags |= WSATTR_WSCOLORS; + if (edp->scrcapabilities & + WSSCREEN_256COL) { + bgcol = ARG2_OR_DEF(n); + } else { + bgcol = (ARG2_OR_DEF(n) < 8 ? + ARG2_OR_DEF(n) : bgcol ); + } + n+=(EXIST_ARG2(n) ? 2 : 1); + break; + } + if (ARG(n+1)==2) { + n=(edp->nargs-n > 5 ? n+4 : + edp->nargs); + break; + } + n++; break; case 49: /* reset bg color */ Index: wscons/wsemul_vt100var.h =================================================================== RCS file: /cvs/src/sys/dev/wscons/wsemul_vt100var.h,v retrieving revision 1.12 diff -u -p -r1.12 wsemul_vt100var.h --- wscons/wsemul_vt100var.h 12 Jan 2023 20:39:37 -0000 1.12 +++ wscons/wsemul_vt100var.h 30 Jan 2023 09:08:22 -0000 @@ -130,6 +130,8 @@ struct wsemul_vt100_emuldata { #define ERASECOLS(f, n, a) (edp->emulcookie, edp->crow, (f), (n), (a)) #endif #define COLS_LEFT (NCOLS - edp->ccol - 1) +#define EXIST_ARG2(i) ((edp->nargs-n) >= 3) +#define ARG2_OR_DEF(i) (EXIST_ARG2(i) ? ARG(i + 2) : 0) /* * response to primary DA request