Created
March 31, 2024 03:10
-
-
Save tsutsui/c8d55043a668786763e6196a72c9fc5e to your computer and use it in GitHub Desktop.
NetBSD/x68k ite(4) console sixel support patch for netbsd-10, based on https://github.com/isaki68k/misc/blob/master/NetBSD/patch/x68k-ite-sixel.diff
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Index: sys/arch/x68k/conf/GENERIC | |
=================================================================== | |
RCS file: /cvsroot/src/sys/arch/x68k/conf/GENERIC,v | |
retrieving revision 1.207 | |
diff -u -p -d -r1.207 GENERIC | |
--- sys/arch/x68k/conf/GENERIC 29 Sep 2022 10:10:10 -0000 1.207 | |
+++ sys/arch/x68k/conf/GENERIC 31 Mar 2024 02:24:54 -0000 | |
@@ -229,6 +229,9 @@ kbd0 at mfp0 # standard keyboard | |
ite0 at grf0 grfaddr 0 # internal terminal emulator | |
options ITE_KERNEL_ATTR=4 # bold for kernel messages | |
# see /sys/arch/x68k/dev/itevar.h | |
+options ITE_SIXEL | |
+options ITE_16COLOR | |
+options ITE_SYSCTL | |
## floppy disks | |
fdc0 at intio0 addr 0xe94000 intr 96 dma 0 dmaintr 100 # floppy controller | |
Index: sys/arch/x68k/conf/files.x68k | |
=================================================================== | |
RCS file: /cvsroot/src/sys/arch/x68k/conf/files.x68k,v | |
retrieving revision 1.83 | |
diff -u -p -d -r1.83 files.x68k | |
--- sys/arch/x68k/conf/files.x68k 8 May 2019 13:40:17 -0000 1.83 | |
+++ sys/arch/x68k/conf/files.x68k 31 Mar 2024 02:24:54 -0000 | |
@@ -67,6 +67,9 @@ file arch/x68k/dev/grf_tv.c grf | ite | |
file arch/x68k/dev/grf_gv.c grf | ite | |
defparam opt_ite.h ITE_KERNEL_ATTR | |
+defflag opt_ite.h ITE_SIXEL | |
+defflag opt_ite.h ITE_16COLOR | |
+defflag opt_ite.h ITE_SYSCTL | |
device ite : tty | |
attach ite at grf | |
file arch/x68k/dev/ite.c ite needs-flag | |
Index: sys/arch/x68k/dev/ite.c | |
=================================================================== | |
RCS file: /cvsroot/src/sys/arch/x68k/dev/ite.c,v | |
retrieving revision 1.70 | |
diff -u -p -d -r1.70 ite.c | |
--- sys/arch/x68k/dev/ite.c 25 Jun 2022 05:01:31 -0000 1.70 | |
+++ sys/arch/x68k/dev/ite.c 31 Mar 2024 02:24:55 -0000 | |
@@ -91,6 +91,9 @@ void opm_bell(void); | |
#define SUBR_CLEAR(ip,sy,sx,h,w) ip->isw->ite_clear(ip,sy,sx,h,w) | |
#define SUBR_SCROLL(ip,sy,sx,count,dir) \ | |
ip->isw->ite_scroll(ip,sy,sx,count,dir) | |
+#if defined(ITE_SIXEL) | |
+#define SUBR_SIXEL(ip,sy,sx) ip->isw->ite_sixel(ip,sy,sx) | |
+#endif | |
struct consdev; | |
@@ -1207,10 +1210,18 @@ ite_putstr(const u_char *s, int len, dev | |
if ((ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE) | |
return; | |
+#if defined(ITE_SIXEL) | |
+ /* avoid flicking cursor */ | |
+ if (ip->escape == 0) | |
+#endif | |
SUBR_CURSOR(ip, START_CURSOROPT); | |
for (i = 0; i < len; i++) | |
if (s[i] != 0) | |
iteputchar(s[i], ip); | |
+#if defined(ITE_SIXEL) | |
+ /* avoid flicking cursor */ | |
+ if (ip->escape == 0) | |
+#endif | |
SUBR_CURSOR(ip, END_CURSOROPT); | |
} | |
@@ -1219,8 +1230,24 @@ iteputchar(int c, struct ite_softc *ip) | |
{ | |
int n, x, y; | |
char *cp; | |
+#if defined(ITE_SIXEL) | |
+ const uint32_t table[64] = { | |
+ 0x000000,0x000001,0x000010,0x000011,0x000100,0x000101,0x000110,0x000111, | |
+ 0x001000,0x001001,0x001010,0x001011,0x001100,0x001101,0x001110,0x001111, | |
+ 0x010000,0x010001,0x010010,0x010011,0x010100,0x010101,0x010110,0x010111, | |
+ 0x011000,0x011001,0x011010,0x011011,0x011100,0x011101,0x011110,0x011111, | |
+ 0x100000,0x100001,0x100010,0x100011,0x100100,0x100101,0x100110,0x100111, | |
+ 0x101000,0x101001,0x101010,0x101011,0x101100,0x101101,0x101110,0x101111, | |
+ 0x110000,0x110001,0x110010,0x110011,0x110100,0x110101,0x110110,0x110111, | |
+ 0x111000,0x111001,0x111010,0x111011,0x111100,0x111101,0x111110,0x111111, | |
+ }; | |
+#endif | |
+#if defined(ITE_SIXEL) | |
+ if ((c >= 0x20 && ip->escape != 0) || ip->escape == DCS) { | |
+#else | |
if (c >= 0x20 && ip->escape != 0) { | |
+#endif | |
switch (ip->escape) { | |
case ESC: | |
@@ -1284,6 +1311,11 @@ iteputchar(int c, struct ite_softc *ip) | |
/* String Terminator */ | |
c = ST; | |
ip->escape = 0; | |
+#if defined(ITE_SIXEL) | |
+ if (ip->decsixel_y != 0) { | |
+ ite_lf(ip); | |
+ } | |
+#endif | |
break; | |
case ']': | |
@@ -1950,9 +1982,29 @@ iteputchar(int c, struct ite_softc *ip) | |
break; | |
case '1': | |
+#if defined(ITE_16COLOR) | |
+ if (c_p[1] == '0') { | |
+ switch (c_p[2]) { | |
+ case '0': case '1': case '2': case '3': | |
+ case '4': case '5': case '6': case '7': | |
+ /* background colors */ | |
+ ip->bgcolor = c_p[2] - '0' + 8; | |
+ c_p += 3; | |
+ break; | |
+ default: | |
+ c_p += 3; | |
+ break; | |
+ } | |
+ } else { | |
+ set_attr(ip, ATTR_BOLD); | |
+ c_p++; | |
+ } | |
+ break; | |
+#else | |
set_attr(ip, ATTR_BOLD); | |
c_p++; | |
break; | |
+#endif | |
case '2': | |
switch (c_p[1]) { | |
@@ -2036,6 +2088,22 @@ iteputchar(int c, struct ite_softc *ip) | |
c_p++; | |
break; | |
+#if defined(ITE_16COLOR) | |
+ case '9': | |
+ switch (c_p[1]) { | |
+ case '0': case '1': case '2': case '3': | |
+ case '4': case '5': case '6': case '7': | |
+ /* foreground colors */ | |
+ ip->fgcolor = c_p[1] - '0' + 8; | |
+ c_p += 2; | |
+ break; | |
+ default: | |
+ c_p++; | |
+ break; | |
+ } | |
+ break; | |
+#endif | |
+ | |
default: | |
c_p++; | |
break; | |
@@ -2162,6 +2230,225 @@ iteputchar(int c, struct ite_softc *ip) | |
} | |
break; | |
+#if defined(ITE_SIXEL) | |
+ case DCS: | |
+ switch (ip->dcs_cmd) { | |
+ case DCS_DISCARD: | |
+ /* discard sixel cause kernel message interrupted */ | |
+ switch (c) { | |
+ case '-': | |
+ /* restart from next SIXEL line */ | |
+ ite_lf(ip); | |
+ goto sixel_restart; | |
+ | |
+ case CAN: | |
+ case SUB: | |
+ /* SUB should also display a reverse question mark... */ | |
+ ip->escape = 0; | |
+ return; | |
+ | |
+ case ESC: | |
+ ip->escape = ESC; | |
+ return; | |
+ default: | |
+ return; | |
+ } | |
+ break; | |
+ | |
+ case DCS_START: | |
+ /* the biggie... */ | |
+ switch (c) { | |
+ case '0': case '1': case '2': case '3': case '4': | |
+ case '5': case '6': case '7': case '8': case '9': | |
+ case ';': case '$': | |
+ if (ip->ap < ip->argbuf + MAX_ARGSIZE) | |
+ *ip->ap++ = c; | |
+ return; | |
+ | |
+ case 'q': | |
+ /* init sixel */ | |
+ /* | |
+ * DCS <P1> ; <P2> ; <P3> q | |
+ * P1 is aspect ratio, XXX not supported. | |
+ * P2 is bgcolor mode. | |
+ * 0..2: bgcolor mode, XXX not supported here. | |
+ * bit2 means 'OR'ed color mode. it's original extension. | |
+ */ | |
+ ip->ap = ip->argbuf; | |
+ cp = strchr(ip->ap, ';'); | |
+ if (cp != NULL) { | |
+ int mode; | |
+ mode = atoi(cp + 1) - '0'; | |
+ ip->decsixel_ormode = (mode & 4); | |
+ } else { | |
+ ip->decsixel_ormode = 0; | |
+ } | |
+ sixel_restart: | |
+ ip->dcs_cmd = DCS_SIXEL; | |
+ ip->decsixel_state = DECSIXEL_INIT; | |
+ ip->decsixel_ph = MAX_SIXEL_WIDTH; | |
+ ip->decsixel_x = 0; | |
+ ip->decsixel_y = 0; | |
+ ip->decsixel_repcount = 0; | |
+ ip->decsixel_color = ip->fgcolor; | |
+ memset(ip->decsixel_buf, 0, sizeof(ip->decsixel_buf)); | |
+ return; | |
+ | |
+ case CAN: | |
+ case SUB: | |
+ /* SUB should also display a reverse question mark... */ | |
+ ip->escape = 0; | |
+ return; | |
+ | |
+ case ESC: | |
+ ip->escape = ESC; | |
+ return; | |
+ | |
+ default: | |
+ return; | |
+ } | |
+ break; | |
+ | |
+ case DCS_SIXEL: | |
+ sixel_loop: | |
+ switch (ip->decsixel_state) { | |
+ case DECSIXEL_INIT: | |
+ switch (c) { | |
+ case CAN: | |
+ case SUB: | |
+ /* SUB should also display a reverse question mark... */ | |
+ ip->escape = 0; | |
+ return; | |
+ case ESC: | |
+ ip->escape = ESC; | |
+ return; | |
+ case DECSIXEL_REPEAT: | |
+ ip->decsixel_state = c; | |
+ ip->decsixel_repcount = 0; | |
+ return; | |
+ case DECSIXEL_RASTER: | |
+ case DECSIXEL_COLOR: | |
+ ip->decsixel_state = c; | |
+ ip->ap = ip->argbuf; | |
+ return; | |
+ case '$': // CR | |
+ ip->decsixel_x = 0; | |
+ return; | |
+ case '-': // LF | |
+ /* XXX FONTHEIGHT is defined in ite_tv.c, not here... */ | |
+ if (ip->decsixel_y + 6 > 15) { | |
+ ite_lf(ip); | |
+ ip->decsixel_y -= 16; | |
+ } | |
+ SUBR_SIXEL(ip, ip->cury, ip->curx); | |
+ memset(ip->decsixel_buf, 0, sizeof(ip->decsixel_buf)); | |
+ ip->decsixel_x = 0; | |
+ ip->decsixel_y += 6; | |
+ return; | |
+ default: | |
+ if ('?' <= c && c <= '~' | |
+ && ip->decsixel_x < MAX_SIXEL_WIDTH) { | |
+ uint32_t d; | |
+ d = table[c - '?'] * ip->decsixel_color; | |
+ ip->decsixel_buf[ip->decsixel_x] |= d; | |
+ ip->decsixel_x++; | |
+ } else { | |
+ /* ignore */ | |
+ } | |
+ return; | |
+ } | |
+ break; | |
+ case DECSIXEL_REPEAT: | |
+ if ('0' <= c && c <= '9') { | |
+ ip->decsixel_repcount = ip->decsixel_repcount * 10 | |
+ + (c - '0'); | |
+ } else if ('?' <= c && c <= '~') { | |
+ int cnt = MIN(ip->decsixel_repcount, | |
+ MAX_SIXEL_WIDTH - ip->decsixel_x); | |
+ uint32_t d; | |
+ int i; | |
+ d = table[c - '?'] * ip->decsixel_color; | |
+ for (i = 0; i < cnt; i++) { | |
+ ip->decsixel_buf[ip->decsixel_x + i] |= d; | |
+ } | |
+ ip->decsixel_x += cnt; | |
+ ip->decsixel_state = DECSIXEL_INIT; | |
+ } else { | |
+ /* invalid ? */ | |
+ ip->decsixel_state = DECSIXEL_INIT; | |
+ } | |
+ return; | |
+ case DECSIXEL_RASTER: | |
+ case DECSIXEL_RASTER_PAD: | |
+ case DECSIXEL_RASTER_PH: | |
+ case DECSIXEL_RASTER_PV: | |
+ switch (c) { | |
+ case '0': case '1': case '2': case '3': case '4': | |
+ case '5': case '6': case '7': case '8': case '9': | |
+ if (ip->ap < ip->argbuf + MAX_ARGSIZE) | |
+ *ip->ap++ = c; | |
+ return; | |
+ case ';': | |
+ default: | |
+ switch (ip->decsixel_state) { | |
+ case DECSIXEL_RASTER: | |
+ /* ignore PAN */ | |
+ ip->ap = ip->argbuf; | |
+ ip->decsixel_state = DECSIXEL_RASTER_PAD; | |
+ return; | |
+ case DECSIXEL_RASTER_PAD: | |
+ /* ignore PAD */ | |
+ ip->ap = ip->argbuf; | |
+ ip->decsixel_state = DECSIXEL_RASTER_PH; | |
+ return; | |
+ case DECSIXEL_RASTER_PH: | |
+ ip->decsixel_ph = ite_zargnum(ip); | |
+ ip->ap = ip->argbuf; | |
+ ip->decsixel_state = DECSIXEL_RASTER_PV; | |
+ return; | |
+ case DECSIXEL_RASTER_PV: | |
+ /* ignore PV */ | |
+ ip->decsixel_state = DECSIXEL_INIT; | |
+ /* c is a next sequence char */ | |
+ goto sixel_loop; | |
+ default: | |
+ /* NOTREACHED */ | |
+ return; | |
+ } | |
+ } | |
+ return; | |
+ case DECSIXEL_COLOR: | |
+ switch (c) { | |
+ case '0': case '1': case '2': case '3': case '4': | |
+ case '5': case '6': case '7': case '8': case '9': | |
+ case ';': | |
+ if (ip->ap < ip->argbuf + MAX_ARGSIZE) | |
+ *ip->ap++ = c; | |
+ return; | |
+ default: | |
+ *ip->ap = '\0'; | |
+ if (strchr(ip->argbuf, ';')) { | |
+ /* ignore the palette definition */ | |
+ } else { | |
+ /* otherwise, it specifies color */ | |
+#if defined(ITE_16COLOR) | |
+ ip->decsixel_color = ite_zargnum(ip) & 15; | |
+#else | |
+ ip->decsixel_color = ite_zargnum(ip) & 7; | |
+#endif | |
+ } | |
+ ip->decsixel_state = DECSIXEL_INIT; | |
+ ip->ap = ip->argbuf; | |
+ /* c is a next sequence char */ | |
+ goto sixel_loop; | |
+ } | |
+ return; | |
+ } | |
+ break; | |
+ } | |
+ break; | |
+#endif /* ITE_SIXEL */ | |
+ | |
default: | |
ip->escape = 0; | |
return; | |
@@ -2289,6 +2576,9 @@ iteputchar(int c, struct ite_softc *ip) | |
case DCS: /* device control string introducer */ | |
ip->escape = DCS; | |
+#if defined(ITE_SIXEL) | |
+ ip->dcs_cmd = DCS_START; | |
+#endif | |
ip->ap = ip->argbuf; | |
break; | |
@@ -2547,12 +2837,23 @@ itecnputc(dev_t dev, int c) | |
#ifdef ITE_KERNEL_ATTR | |
short save_attribute; | |
#endif | |
+#if defined(ITE_SIXEL) | |
+ int save_escape; | |
+#endif | |
if (panicstr && !paniced && | |
(ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE) { | |
(void) iteon(dev, 3); | |
paniced = 1; | |
} | |
+ | |
+#if defined(ITE_SIXEL) | |
+ save_escape = ip->escape; | |
+ if (ip->escape == DCS) { | |
+ ip->escape = 0; | |
+ ip->dcs_cmd = DCS_DISCARD; | |
+ } | |
+#endif | |
#ifdef ITE_KERNEL_ATTR | |
save_attribute = ip->attribute; | |
ip->attribute = ITE_KERNEL_ATTR; | |
@@ -2561,5 +2862,10 @@ itecnputc(dev_t dev, int c) | |
#ifdef ITE_KERNEL_ATTR | |
ip->attribute = save_attribute; | |
#endif | |
+#if defined(ITE_SIXEL) | |
+ if (ip->escape == 0) { | |
+ ip->escape = save_escape; | |
+ } | |
+#endif | |
} | |
#endif | |
Index: sys/arch/x68k/dev/ite_tv.c | |
=================================================================== | |
RCS file: /cvsroot/src/sys/arch/x68k/dev/ite_tv.c,v | |
retrieving revision 1.19 | |
diff -u -p -d -r1.19 ite_tv.c | |
--- sys/arch/x68k/dev/ite_tv.c 25 Jun 2022 03:57:17 -0000 1.19 | |
+++ sys/arch/x68k/dev/ite_tv.c 31 Mar 2024 02:24:55 -0000 | |
@@ -33,10 +33,15 @@ | |
#include <sys/cdefs.h> | |
__KERNEL_RCSID(0, "$NetBSD: ite_tv.c,v 1.19 2022/06/25 03:57:17 tsutsui Exp $"); | |
+#include "opt_ite.h" | |
+ | |
#include <sys/param.h> | |
#include <sys/device.h> | |
#include <sys/proc.h> | |
#include <sys/systm.h> | |
+#if defined(ITE_SYSCTL) | |
+#include <sys/sysctl.h> | |
+#endif | |
#include <machine/bus.h> | |
#include <machine/grfioctl.h> | |
@@ -71,6 +76,9 @@ __KERNEL_RCSID(0, "$NetBSD: ite_tv.c,v 1 | |
static u_int tv_top; | |
static uint8_t *tv_row[PLANELINES]; | |
+#if defined(ITE_SIXEL) | |
+uint8_t *tv_end; | |
+#endif | |
static uint8_t *tv_font[256]; | |
static volatile uint8_t *tv_kfont[0x7f]; | |
@@ -89,6 +97,9 @@ static void tv_putc(struct ite_softc *, | |
static void tv_cursor(struct ite_softc *, int); | |
static void tv_clear(struct ite_softc *, int, int, int, int); | |
static void tv_scroll(struct ite_softc *, int, int, int, int); | |
+#if defined(ITE_SIXEL) | |
+static void tv_sixel(struct ite_softc *, int, int); | |
+#endif | |
static inline uint32_t expbits(uint32_t); | |
static inline void txrascpy(uint8_t, uint8_t, int16_t, uint16_t); | |
@@ -166,6 +177,9 @@ tv_init(struct ite_softc *ip) | |
for (i = 0; i < PLANELINES; i++) | |
tv_row[i] = | |
(void *)__UNVOLATILE(&IODEVbase->tvram[ROWOFFSET(i)]); | |
+#if defined(ITE_SIXEL) | |
+ tv_end = (void *)__UNVOLATILE(&IODEVbase->tvram[ROWOFFSET(i)]); | |
+#endif | |
/* shadow ANK font */ | |
memcpy(kern_font, (void *)&IODEVbase->cgrom0_8x16, 256 * FONTHEIGHT); | |
ite_set_glyph(); | |
@@ -189,6 +203,9 @@ tv_init(struct ite_softc *ip) | |
ip->isw->ite_cursor = tv_cursor; | |
ip->isw->ite_clear = tv_clear; | |
ip->isw->ite_scroll = tv_scroll; | |
+#if defined(ITE_SIXEL) | |
+ ip->isw->ite_sixel = tv_sixel; | |
+#endif | |
/* | |
* Initialize colormap | |
@@ -196,7 +213,7 @@ tv_init(struct ite_softc *ip) | |
#define RED (0x1f << 6) | |
#define BLUE (0x1f << 1) | |
#define GREEN (0x1f << 11) | |
- IODEVbase->tpalet[0] = 0; /* black */ | |
+ IODEVbase->tpalet[0] = 0; /* transparent */ | |
IODEVbase->tpalet[1] = 1 | RED; /* red */ | |
IODEVbase->tpalet[2] = 1 | GREEN; /* green */ | |
IODEVbase->tpalet[3] = 1 | RED | GREEN; /* yellow */ | |
@@ -204,6 +221,20 @@ tv_init(struct ite_softc *ip) | |
IODEVbase->tpalet[5] = 1 | BLUE | RED; /* magenta */ | |
IODEVbase->tpalet[6] = 1 | BLUE | GREEN; /* cyan */ | |
IODEVbase->tpalet[7] = 1 | BLUE | RED | GREEN; /* white */ | |
+ | |
+#if defined(ITE_16COLOR) | |
+#define hRED (0x0f << 6) | |
+#define hBLUE (0x0f << 1) | |
+#define hGREEN (0x0f << 11) | |
+ IODEVbase->tpalet[8] = 1; /* black */ | |
+ IODEVbase->tpalet[9] = 1 | hRED; | |
+ IODEVbase->tpalet[10] = 1 | hGREEN; | |
+ IODEVbase->tpalet[11] = 1 | hRED | hGREEN; | |
+ IODEVbase->tpalet[12] = 1 | hBLUE; | |
+ IODEVbase->tpalet[13] = 1 | hBLUE | hRED; | |
+ IODEVbase->tpalet[14] = 1 | hBLUE | hGREEN; | |
+ IODEVbase->tpalet[15] = 1 | hBLUE | hRED | hGREEN; | |
+#endif /* ITE_16COLOR */ | |
} | |
/* | |
@@ -741,3 +772,169 @@ tv_scroll(struct ite_softc *ip, int srcy | |
break; | |
} | |
} | |
+ | |
+#if defined(ITE_SIXEL) | |
+/* | |
+ * put SIXEL graphics | |
+ */ | |
+static void | |
+tv_sixel(struct ite_softc *ip, int sy, int sx) | |
+{ | |
+ uint8_t *p; | |
+ int width; | |
+ int y; | |
+ int cx; | |
+ int px; | |
+#if defined(ITE_16COLOR) | |
+ uint16_t data[4]; | |
+#else | |
+ uint16_t data[3]; | |
+#endif | |
+ uint8_t color; | |
+ | |
+ width = MIN(ip->decsixel_ph, MAX_SIXEL_WIDTH); | |
+ width = MIN(width, PLANEWIDTH - sx * FONTWIDTH); | |
+ | |
+ p = CHADDR(sy, sx); | |
+ p += ROWBYTES * ip->decsixel_y; | |
+ /* boundary check */ | |
+ if (p < tv_row[0]) { | |
+ p = tv_end + (p - tv_row[0]); | |
+ } | |
+ | |
+ for (y = 0; y < 6; y++) { | |
+ /* for each 16dot word */ | |
+ for (cx = 0; cx < howmany(width, 16); cx++) { | |
+ data[0] = 0; | |
+ data[1] = 0; | |
+ data[2] = 0; | |
+#if defined(ITE_16COLOR) | |
+ data[3] = 0; | |
+#endif | |
+ for (px = 0; px < 16; px++) { | |
+ color = ip->decsixel_buf[cx * 16 + px] >> (y * 4); | |
+ /* x68k console is 8 colors */ | |
+ data[0] = (data[0] << 1) | ((color >> 0) & 1); | |
+ data[1] = (data[1] << 1) | ((color >> 1) & 1); | |
+ data[2] = (data[2] << 1) | ((color >> 2) & 1); | |
+#if defined(ITE_16COLOR) | |
+ data[3] = (data[3] << 1) | ((color >> 3) & 1); | |
+#endif | |
+ } | |
+ *(uint16_t *)(p + cx * 2 ) = data[0]; | |
+ *(uint16_t *)(p + cx * 2 + 0x20000) = data[1]; | |
+ *(uint16_t *)(p + cx * 2 + 0x40000) = data[2]; | |
+#if defined(ITE_16COLOR) | |
+ *(uint16_t *)(p + cx * 2 + 0x60000) = data[3]; | |
+#endif | |
+ } | |
+ | |
+ p += ROWBYTES; | |
+ if (p >= tv_end) { | |
+ p = tv_row[0] + (p - tv_end); | |
+ } | |
+ } | |
+} | |
+#endif /* ITE_SIXEL */ | |
+ | |
+#if defined(ITE_SYSCTL) | |
+static int | |
+sysctl_hw_ite_textpalette(SYSCTLFN_ARGS) | |
+{ | |
+ struct sysctlnode node; | |
+ int idx; | |
+ int error; | |
+ int t; | |
+ | |
+ node = *rnode; | |
+ idx = node.sysctl_name[strlen("tpalette")] - '0'; | |
+ if (idx > 9) | |
+ idx -= 7; | |
+ t = (int)(IODEVbase->tpalet[idx]); | |
+ | |
+ node.sysctl_data = &t; | |
+ | |
+ error = sysctl_lookup(SYSCTLFN_CALL(&node)); | |
+ if (error || newp == NULL) | |
+ return error; | |
+ | |
+ if (t < 0 || t > 65535) | |
+ return EINVAL; | |
+ | |
+ IODEVbase->tpalet[idx] = t; | |
+ | |
+ return 0; | |
+} | |
+ | |
+SYSCTL_SETUP(sysctl_ite_setup, "sysctl hw.ite setup") | |
+{ | |
+ char name[16]; | |
+ const struct sysctlnode *node; | |
+ int i; | |
+ | |
+ sysctl_createv(NULL, 0, NULL, &node, | |
+ CTLFLAG_PERMANENT, CTLTYPE_NODE, | |
+ "ite", SYSCTL_DESCR("ite"), | |
+ NULL, 0, NULL, 0, | |
+ CTL_HW, CTL_CREATE, CTL_EOL); | |
+ if (node == NULL) | |
+ return; | |
+ | |
+ for (i = 0; i < 16; i++) { | |
+ snprintf(name, sizeof(name), "tpalette%X", i); | |
+ sysctl_createv(NULL, 0, NULL, NULL, | |
+ CTLFLAG_PERMANENT | CTLFLAG_READWRITE, | |
+ CTLTYPE_INT, | |
+ name, SYSCTL_DESCR("text palette"), | |
+ sysctl_hw_ite_textpalette, 0, NULL, 0, | |
+ CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL); | |
+ } | |
+} | |
+#endif /* ITE_SYSCTL */ | |
+ | |
+#if defined(ITE_SYSCTL) | |
+static int sysctl_hw_sysport_contrast(SYSCTLFN_PROTO); | |
+static int | |
+sysctl_hw_sysport_contrast(SYSCTLFN_ARGS) | |
+{ | |
+ struct sysctlnode node; | |
+ int error; | |
+ int t; | |
+ | |
+ node = *rnode; | |
+ t = (int)(IODEVbase->io_sysport.contrast); | |
+ | |
+ node.sysctl_data = &t; | |
+ | |
+ error = sysctl_lookup(SYSCTLFN_CALL(&node)); | |
+ if (error || newp == NULL) | |
+ return error; | |
+ | |
+ if (t < 0 || t > 15) | |
+ return EINVAL; | |
+ | |
+ IODEVbase->io_sysport.contrast = t; | |
+ | |
+ return 0; | |
+} | |
+ | |
+SYSCTL_SETUP(sysctl_sysport, "sysctl sysport.contrast") | |
+{ | |
+ const struct sysctlnode *node; | |
+ | |
+ sysctl_createv(NULL, 0, NULL, &node, | |
+ CTLFLAG_PERMANENT, CTLTYPE_NODE, | |
+ "sysport", SYSCTL_DESCR("sysport"), | |
+ NULL, 0, NULL, 0, | |
+ CTL_HW, CTL_CREATE, CTL_EOL); | |
+ if (node == NULL) | |
+ return; | |
+ | |
+ sysctl_createv(NULL, 0, NULL, NULL, | |
+ CTLFLAG_PERMANENT | CTLFLAG_READWRITE, | |
+ CTLTYPE_INT, | |
+ "contrast", SYSCTL_DESCR("contrast"), | |
+ sysctl_hw_sysport_contrast, 0, NULL, 0, | |
+ CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL); | |
+} | |
+#endif | |
Index: sys/arch/x68k/dev/itevar.h | |
=================================================================== | |
RCS file: /cvsroot/src/sys/arch/x68k/dev/itevar.h,v | |
retrieving revision 1.16 | |
diff -u -p -d -r1.16 itevar.h | |
--- sys/arch/x68k/dev/itevar.h 25 Jun 2022 03:18:38 -0000 1.16 | |
+++ sys/arch/x68k/dev/itevar.h 31 Mar 2024 02:24:55 -0000 | |
@@ -50,6 +50,7 @@ struct itesw { | |
void (*ite_putc)(struct ite_softc *, int, int, int, int); | |
void (*ite_cursor)(struct ite_softc *, int); | |
void (*ite_scroll)(struct ite_softc *, int, int, int, int); | |
+ void (*ite_sixel)(struct ite_softc *, int, int); | |
}; | |
enum ite_arraymaxs { | |
@@ -94,6 +95,28 @@ struct ite_softc { | |
short save_curx, save_cury, save_attribute, save_char; | |
char sc_G0, sc_G1, sc_G2, sc_G3; | |
char *sc_GL, *sc_GR; | |
+ enum { | |
+ DCS_START = 0, | |
+ DCS_SIXEL = 'q', // DECRQSS also use 'q'... | |
+ DCS_DISCARD = -1, | |
+ } dcs_cmd; | |
+ enum { | |
+ DECSIXEL_INIT = 0, | |
+ DECSIXEL_RASTER_PAD, | |
+ DECSIXEL_RASTER_PH, | |
+ DECSIXEL_RASTER_PV, | |
+ DECSIXEL_REPEAT = '!', | |
+ DECSIXEL_RASTER = '\"', | |
+ DECSIXEL_COLOR = '#', | |
+ } decsixel_state; | |
+ int decsixel_ph; | |
+ int decsixel_x; | |
+ int decsixel_y; | |
+ int decsixel_repcount; | |
+ int decsixel_color; | |
+ int decsixel_ormode; | |
+#define MAX_SIXEL_WIDTH (768) | |
+ uint32_t decsixel_buf[MAX_SIXEL_WIDTH]; | |
}; | |
enum emul_level { |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment