2 * Copyright (c) 1999 FreeBSD(98) Porting Team.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer as
10 * the first lines of this file unmodified.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #include "opt_syscons.h"
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/kernel.h>
34 #include <sys/module.h>
35 #include <sys/consio.h>
37 #include <machine/pc/display.h>
39 #include <dev/syscons/syscons.h>
40 #include <pc98/cbus/sctermvar.h>
45 #define IS_KTYPE_ASCII_or_HANKAKU(A) (!((A) & 0xee))
46 #define IS_KTYPE_KANA(A) ((A) & 0x11)
47 #define KTYPE_MASK_CTRL(A) ((A) &= 0xF0)
52 u_short fg; /* foreground color */
53 u_short bg; /* background color */
58 #define SCTERM_BUSY (1 << 0)
62 int param[MAX_ESC_PAR];
67 u_char kanji_1st_char;
69 #define KTYPE_ASCII 0 /* ASCII */
70 #define KTYPE_KANA 1 /* HANKAKU */
71 #define KTYPE_JKANA 0x10 /* JIS HANKAKU */
72 #define KTYPE_7JIS 0x20 /* JIS */
73 #define KTYPE_SJIS 2 /* Shift JIS */
74 #define KTYPE_UJIS 4 /* UJIS */
75 #define KTYPE_SUKANA 3 /* Shift JIS or UJIS HANKAKU */
76 #define KTYPE_SUJIS 6 /* SHift JIS or UJIS */
77 #define KTYPE_KANIN 0x80 /* Kanji Invoke sequence */
78 #define KTYPE_ASCIN 0x40 /* ASCII Invoke sequence */
81 int attr_mask; /* current logical attr mask */
82 #define NORMAL_ATTR 0x00
83 #define BLINK_ATTR 0x01
84 #define BOLD_ATTR 0x02
85 #define UNDERLINE_ATTR 0x04
86 #define REVERSE_ATTR 0x08
87 #define FG_CHANGED 0x10
88 #define BG_CHANGED 0x20
89 int cur_attr; /* current hardware attr word */
90 color_t cur_color; /* current hardware color */
91 color_t std_color; /* normal hardware color */
92 color_t rev_color; /* reverse hardware color */
93 color_t dflt_std_color; /* default normal color */
94 color_t dflt_rev_color; /* default reverse color */
97 static sc_term_init_t scterm_init;
98 static sc_term_term_t scterm_term;
99 static sc_term_puts_t scterm_puts;
100 static sc_term_ioctl_t scterm_ioctl;
101 static sc_term_reset_t scterm_reset;
102 static sc_term_default_attr_t scterm_default_attr;
103 static sc_term_clear_t scterm_clear;
104 static sc_term_notify_t scterm_notify;
105 static sc_term_input_t scterm_input;
107 static sc_term_sw_t sc_term_sc = {
109 "sck", /* emulator name */
110 "syscons kanji terminal", /* description */
111 "*", /* matching renderer, any :-) */
112 sizeof(term_stat), /* softc size */
125 SCTERM_MODULE(sc, sc_term_sc);
127 static term_stat reserved_term_stat;
128 static int default_kanji = UJIS;
129 static void scterm_scan_esc(scr_stat *scp, term_stat *tcp,
131 static int mask2attr(term_stat *tcp);
134 __inline static u_char
135 iskanji1(u_char mode, u_char c)
138 if ((c >= 0xa1) && (c <= 0xdf)) {
139 if (default_kanji == UJIS) {
143 if (default_kanji == SJIS) {
151 /* SJIS or UJIS HANKAKU */
156 default_kanji = SJIS;
160 if ((c >= 0xe0) && (c <= 0xef)) {
165 if ((c >= 0xf0) && (c <= 0xfe)) {
167 default_kanji = UJIS;
171 if ((mode == KTYPE_7JIS) && (c >= 0x21) && (c <= 0x7e)) {
173 default_kanji = UJIS;
177 if ((mode == KTYPE_JKANA) && (c >= 0x21) && (c <= 0x5f)) {
179 default_kanji = UJIS;
187 __inline static u_char
188 iskanji2(u_char mode, u_char c)
192 if ((c >= 0x21) && (c <= 0x7e)) {
198 if ((c >= 0x40) && (c <= 0xfc) && (c != 0x7f)) {
204 if ((c >= 0xa1) && (c <= 0xfe)) {
210 if ((c >= 0xa1) && (c <= 0xdf) && (default_kanji == UJIS)) {
214 if ((c >= 0x40) && (c <= 0xfc) && (c != 0x7f)) {
216 default_kanji = SJIS;
221 if ((c >= 0x40) && (c <= 0xa0) && (c != 0x7f)) {
223 default_kanji = SJIS;
226 if ((c == 0xfd) || (c == 0xfe)) {
228 default_kanji = UJIS;
231 if ((c >= 0xa1) && (c <= 0xfc)) {
232 if (default_kanji == SJIS)
234 if (default_kanji == UJIS)
244 * JIS X0208-83 keisen conversion table
246 static u_short keiConv[32] = {
247 0x240c, 0x260c, 0x300c, 0x340c, 0x3c0c, 0x380c, 0x400c, 0x500c,
248 0x480c, 0x580c, 0x600c, 0x250c, 0x270c, 0x330c, 0x370c, 0x3f0c,
249 0x3b0c, 0x470c, 0x570c, 0x4f0c, 0x5f0c, 0x6f0c, 0x440c, 0x530c,
250 0x4c0c, 0x5b0c, 0x630c, 0x410c, 0x540c, 0x490c, 0x5c0c, 0x660c
254 kanji_convert(u_char mode, u_char h, u_char l)
256 u_short tmp, high, low, c;
262 case KTYPE_SJIS: /* SHIFT JIS */
266 low = (low - 0x81) * 2 + 0x21;
278 tmp = ((high << 8) | low) - 0x20;
280 case KTYPE_7JIS: /* JIS */
281 case KTYPE_UJIS: /* UJIS */
284 tmp = ((high << 8) | low) - 0x20;
292 c = ((tmp & 0xff) << 8) | (tmp >> 8);
293 /* 0x2821 .. 0x2840 */
294 if (0x0821 <= c && c <= 0x0840)
295 tmp = keiConv[c - 0x0821];
302 scterm_init(scr_stat *scp, void **softc, int code)
306 if (*softc == NULL) {
307 if (reserved_term_stat.flags & SCTERM_BUSY)
309 *softc = &reserved_term_stat;
314 case SC_TE_COLD_INIT:
315 bzero(tcp, sizeof(*tcp));
316 tcp->flags = SCTERM_BUSY;
318 tcp->saved_xpos = -1;
319 tcp->saved_ypos = -1;
321 tcp->kanji_1st_char = 0;
322 tcp->kanji_type = KTYPE_ASCII;
324 tcp->attr_mask = NORMAL_ATTR;
326 tcp->dflt_std_color.fg = SC_NORM_ATTR & 0x0f;
327 tcp->dflt_std_color.bg = (SC_NORM_ATTR >> 4) & 0x0f;
328 tcp->dflt_rev_color.fg = SC_NORM_REV_ATTR & 0x0f;
329 tcp->dflt_rev_color.bg = (SC_NORM_REV_ATTR >> 4) & 0x0f;
330 tcp->std_color = tcp->dflt_std_color;
331 tcp->rev_color = tcp->dflt_rev_color;
332 tcp->cur_color = tcp->std_color;
333 tcp->cur_attr = mask2attr(tcp);
334 ++sc_term_sc.te_refcount;
337 case SC_TE_WARM_INIT:
339 tcp->saved_xpos = -1;
340 tcp->saved_ypos = -1;
342 tcp->std_color = tcp->dflt_std_color;
343 tcp->rev_color = tcp->dflt_rev_color;
345 tcp->cur_color = tcp->std_color;
346 tcp->cur_attr = mask2attr(tcp);
354 scterm_term(scr_stat *scp, void **softc)
356 if (*softc == &reserved_term_stat) {
358 bzero(&reserved_term_stat, sizeof(reserved_term_stat));
360 --sc_term_sc.te_refcount;
365 scterm_scan_esc(scr_stat *scp, term_stat *tcp, u_char c)
367 static u_char ansi_col[16] = {
368 FG_BLACK, FG_RED, FG_GREEN, FG_BROWN,
369 FG_BLUE, FG_MAGENTA, FG_CYAN, FG_LIGHTGREY,
370 FG_DARKGREY, FG_LIGHTRED, FG_LIGHTGREEN, FG_YELLOW,
371 FG_LIGHTBLUE, FG_LIGHTMAGENTA, FG_LIGHTCYAN, FG_WHITE
373 static int cattrs[] = {
375 CONS_BLINK_CURSOR, /* blinking block */
376 CONS_CHAR_CURSOR, /* underline */
377 CONS_CHAR_CURSOR | CONS_BLINK_CURSOR, /* blinking underline */
378 CONS_RESET_CURSOR, /* reset to default */
379 CONS_HIDDEN_CURSOR, /* hide cursor */
381 static int tcattrs[] = {
382 CONS_RESET_CURSOR | CONS_LOCAL_CURSOR, /* normal */
383 CONS_HIDDEN_CURSOR | CONS_LOCAL_CURSOR, /* invisible */
384 CONS_BLINK_CURSOR | CONS_LOCAL_CURSOR, /* very visible */
392 if (tcp->esc == 1) { /* seen ESC */
394 switch (tcp->kanji_type) {
395 case KTYPE_KANIN: /* Kanji Invoke sequence */
399 tcp->kanji_type = KTYPE_7JIS;
401 tcp->kanji_1st_char = 0;
404 tcp->kanji_type = KTYPE_ASCII;
409 case KTYPE_ASCIN: /* Ascii Invoke sequence */
414 tcp->kanji_type = KTYPE_ASCII;
416 tcp->kanji_1st_char = 0;
419 tcp->kanji_type = KTYPE_JKANA;
421 tcp->kanji_1st_char = 0;
424 tcp->kanji_type = KTYPE_ASCII;
435 case '7': /* Save cursor position */
436 tcp->saved_xpos = scp->xpos;
437 tcp->saved_ypos = scp->ypos;
440 case '8': /* Restore saved cursor position */
441 if (tcp->saved_xpos >= 0 && tcp->saved_ypos >= 0)
442 sc_move_cursor(scp, tcp->saved_xpos,
446 case '[': /* Start ESC [ sequence */
448 tcp->last_param = -1;
449 for (i = tcp->num_param; i < MAX_ESC_PAR; i++)
455 case '$': /* Kanji Invoke sequence */
456 tcp->kanji_type = KTYPE_KANIN;
460 case 'M': /* Move cursor up 1 line, scroll if at top */
461 sc_term_up_scroll(scp, 1, sc->scr_map[0x20],
462 tcp->cur_attr, 0, 0);
469 case 'c': /* reset */
470 tcp->attr_mask = NORMAL_ATTR;
471 tcp->cur_color = tcp->std_color
472 = tcp->dflt_std_color;
473 tcp->rev_color = tcp->dflt_rev_color;
474 tcp->cur_attr = mask2attr(tcp);
475 sc_change_cursor_shape(scp,
476 CONS_RESET_CURSOR | CONS_LOCAL_CURSOR, -1, -1);
477 sc_clear_screen(scp);
480 case '(': /* iso-2022: designate 94 character set to G0 */
482 tcp->kanji_type = KTYPE_ASCIN;
488 } else if (tcp->esc == 2) { /* seen ESC [ */
489 if (c >= '0' && c <= '9') {
490 if (tcp->num_param < MAX_ESC_PAR) {
491 if (tcp->last_param != tcp->num_param) {
492 tcp->last_param = tcp->num_param;
493 tcp->param[tcp->num_param] = 0;
495 tcp->param[tcp->num_param] *= 10;
497 tcp->param[tcp->num_param] += c - '0';
501 tcp->num_param = tcp->last_param + 1;
505 if (tcp->num_param < MAX_ESC_PAR)
511 tcp->last_param = -1;
512 for (i = tcp->num_param; i < MAX_ESC_PAR; i++)
517 case 'A': /* up n rows */
518 sc_term_up(scp, tcp->param[0], 0);
521 case 'B': /* down n rows */
522 sc_term_down(scp, tcp->param[0], 0);
525 case 'C': /* right n columns */
526 sc_term_right(scp, tcp->param[0]);
529 case 'D': /* left n columns */
530 sc_term_left(scp, tcp->param[0]);
533 case 'E': /* cursor to start of line n lines down */
537 sc_move_cursor(scp, 0, scp->ypos + n);
540 case 'F': /* cursor to start of line n lines up */
544 sc_move_cursor(scp, 0, scp->ypos - n);
547 case 'f': /* Cursor move */
549 if (tcp->num_param == 0)
550 sc_move_cursor(scp, 0, 0);
551 else if (tcp->num_param == 2)
552 sc_move_cursor(scp, tcp->param[1] - 1,
556 case 'J': /* Clear all or part of display */
557 if (tcp->num_param == 0)
561 sc_term_clr_eos(scp, n, sc->scr_map[0x20],
565 case 'K': /* Clear all or part of line */
566 if (tcp->num_param == 0)
570 sc_term_clr_eol(scp, n, sc->scr_map[0x20],
574 case 'L': /* Insert n lines */
575 sc_term_ins_line(scp, scp->ypos, tcp->param[0],
576 sc->scr_map[0x20], tcp->cur_attr, 0);
579 case 'M': /* Delete n lines */
580 sc_term_del_line(scp, scp->ypos, tcp->param[0],
581 sc->scr_map[0x20], tcp->cur_attr, 0);
584 case 'P': /* Delete n chars */
585 sc_term_del_char(scp, tcp->param[0],
586 sc->scr_map[0x20], tcp->cur_attr);
589 case '@': /* Insert n chars */
590 sc_term_ins_char(scp, tcp->param[0],
591 sc->scr_map[0x20], tcp->cur_attr);
594 case 'S': /* scroll up n lines */
595 sc_term_del_line(scp, 0, tcp->param[0],
596 sc->scr_map[0x20], tcp->cur_attr, 0);
599 case 'T': /* scroll down n lines */
600 sc_term_ins_line(scp, 0, tcp->param[0],
601 sc->scr_map[0x20], tcp->cur_attr, 0);
604 case 'X': /* erase n characters in line */
608 if (n > scp->xsize - scp->xpos)
609 n = scp->xsize - scp->xpos;
610 sc_vtb_erase(&scp->vtb, scp->cursor_pos, n,
611 sc->scr_map[0x20], tcp->cur_attr);
612 mark_for_update(scp, scp->cursor_pos);
613 mark_for_update(scp, scp->cursor_pos + n - 1);
616 case 'Z': /* move n tabs backwards */
617 sc_term_backtab(scp, tcp->param[0]);
620 case '`': /* move cursor to column n */
621 sc_term_col(scp, tcp->param[0]);
624 case 'a': /* move cursor n columns to the right */
625 sc_term_right(scp, tcp->param[0]);
628 case 'd': /* move cursor to row n */
629 sc_term_row(scp, tcp->param[0]);
632 case 'e': /* move cursor n rows down */
633 sc_term_down(scp, tcp->param[0], 0);
636 case 'm': /* change attribute */
637 if (tcp->num_param == 0) {
638 tcp->attr_mask = NORMAL_ATTR;
639 tcp->cur_color = tcp->std_color;
640 tcp->cur_attr = mask2attr(tcp);
643 for (i = 0; i < tcp->num_param; i++) {
644 switch (n = tcp->param[i]) {
645 case 0: /* back to normal */
646 tcp->attr_mask = NORMAL_ATTR;
647 tcp->cur_color = tcp->std_color;
648 tcp->cur_attr = mask2attr(tcp);
651 tcp->attr_mask |= BOLD_ATTR;
652 tcp->cur_attr = mask2attr(tcp);
654 case 4: /* underline */
655 tcp->attr_mask |= UNDERLINE_ATTR;
656 tcp->cur_attr = mask2attr(tcp);
659 tcp->attr_mask |= BLINK_ATTR;
660 tcp->cur_attr = mask2attr(tcp);
662 case 7: /* reverse */
663 tcp->attr_mask |= REVERSE_ATTR;
664 tcp->cur_attr = mask2attr(tcp);
666 case 22: /* remove bold (or dim) */
667 tcp->attr_mask &= ~BOLD_ATTR;
668 tcp->cur_attr = mask2attr(tcp);
670 case 24: /* remove underline */
671 tcp->attr_mask &= ~UNDERLINE_ATTR;
672 tcp->cur_attr = mask2attr(tcp);
674 case 25: /* remove blink */
675 tcp->attr_mask &= ~BLINK_ATTR;
676 tcp->cur_attr = mask2attr(tcp);
678 case 27: /* remove reverse */
679 tcp->attr_mask &= ~REVERSE_ATTR;
680 tcp->cur_attr = mask2attr(tcp);
682 case 30: case 31: /* set ansi fg color */
683 case 32: case 33: case 34:
684 case 35: case 36: case 37:
685 tcp->attr_mask |= FG_CHANGED;
686 tcp->cur_color.fg = ansi_col[n - 30];
687 tcp->cur_attr = mask2attr(tcp);
689 case 39: /* restore fg color back to normal */
690 tcp->attr_mask &= ~(FG_CHANGED|BOLD_ATTR);
691 tcp->cur_color.fg = tcp->std_color.fg;
692 tcp->cur_attr = mask2attr(tcp);
694 case 40: case 41: /* set ansi bg color */
695 case 42: case 43: case 44:
696 case 45: case 46: case 47:
697 tcp->attr_mask |= BG_CHANGED;
698 tcp->cur_color.bg = ansi_col[n - 40];
699 tcp->cur_attr = mask2attr(tcp);
701 case 49: /* restore bg color back to normal */
702 tcp->attr_mask &= ~BG_CHANGED;
703 tcp->cur_color.bg = tcp->std_color.bg;
704 tcp->cur_attr = mask2attr(tcp);
710 case 's': /* Save cursor position */
711 tcp->saved_xpos = scp->xpos;
712 tcp->saved_ypos = scp->ypos;
715 case 'u': /* Restore saved cursor position */
716 if (tcp->saved_xpos >= 0 && tcp->saved_ypos >= 0)
717 sc_move_cursor(scp, tcp->saved_xpos,
722 if (tcp->num_param == 0)
727 case 0: /* reset colors and attributes back to normal */
728 tcp->attr_mask = NORMAL_ATTR;
729 tcp->cur_color = tcp->std_color
730 = tcp->dflt_std_color;
731 tcp->rev_color = tcp->dflt_rev_color;
732 tcp->cur_attr = mask2attr(tcp);
734 case 1: /* set ansi background */
735 tcp->attr_mask &= ~BG_CHANGED;
736 tcp->cur_color.bg = tcp->std_color.bg
737 = ansi_col[tcp->param[1] & 0x0f];
738 tcp->cur_attr = mask2attr(tcp);
740 case 2: /* set ansi foreground */
741 tcp->attr_mask &= ~FG_CHANGED;
742 tcp->cur_color.fg = tcp->std_color.fg
743 = ansi_col[tcp->param[1] & 0x0f];
744 tcp->cur_attr = mask2attr(tcp);
746 case 3: /* set adapter attribute directly */
747 tcp->attr_mask &= ~(FG_CHANGED | BG_CHANGED);
748 tcp->cur_color.fg = tcp->std_color.fg
749 = tcp->param[1] & 0x0f;
750 tcp->cur_color.bg = tcp->std_color.bg
751 = (tcp->param[1] >> 4) & 0x0f;
752 tcp->cur_attr = mask2attr(tcp);
754 case 5: /* set ansi reverse background */
755 tcp->rev_color.bg = ansi_col[tcp->param[1] & 0x0f];
756 tcp->cur_attr = mask2attr(tcp);
758 case 6: /* set ansi reverse foreground */
759 tcp->rev_color.fg = ansi_col[tcp->param[1] & 0x0f];
760 tcp->cur_attr = mask2attr(tcp);
762 case 7: /* set adapter reverse attribute directly */
763 tcp->rev_color.fg = tcp->param[1] & 0x0f;
764 tcp->rev_color.bg = (tcp->param[1] >> 4) & 0x0f;
765 tcp->cur_attr = mask2attr(tcp);
770 case 'z': /* switch to (virtual) console n */
771 if (tcp->num_param == 1)
772 sc_switch_scr(sc, tcp->param[0]);
775 } else if (tcp->esc == 3) { /* seen ESC [0-9]+ = */
776 if (c >= '0' && c <= '9') {
777 if (tcp->num_param < MAX_ESC_PAR) {
778 if (tcp->last_param != tcp->num_param) {
779 tcp->last_param = tcp->num_param;
780 tcp->param[tcp->num_param] = 0;
782 tcp->param[tcp->num_param] *= 10;
784 tcp->param[tcp->num_param] += c - '0';
788 tcp->num_param = tcp->last_param + 1;
792 if (tcp->num_param < MAX_ESC_PAR)
796 case 'A': /* set display border color */
797 if (tcp->num_param == 1) {
798 scp->border=tcp->param[0] & 0xff;
799 if (scp == sc->cur_scp)
800 sc_set_border(scp, scp->border);
804 case 'B': /* set bell pitch and duration */
805 if (tcp->num_param == 2) {
806 scp->bell_pitch = tcp->param[0];
808 (tcp->param[1] * hz + 99) / 100;
812 case 'C': /* set global/parmanent cursor type & shape */
819 case 1: /* flags only */
820 if (v0 < sizeof(cattrs)/sizeof(cattrs[0]))
822 else /* backward compatibility */
823 v0 = cattrs[v0 & 0x3];
824 sc_change_cursor_shape(scp, v0, -1, -1);
828 v0 &= 0x1f; /* backward compatibility */
831 case 3: /* base and height */
832 if (v2 == 0) /* count from top */
833 sc_change_cursor_shape(scp, -1,
834 scp->font_size - v1 - 1,
836 else if (v2 == 1) /* count from bottom */
837 sc_change_cursor_shape(scp, -1,
844 case 'F': /* set adapter foreground */
845 if (tcp->num_param == 1) {
846 tcp->attr_mask &= ~FG_CHANGED;
847 tcp->cur_color.fg = tcp->std_color.fg
848 = tcp->param[0] & 0x0f;
849 tcp->cur_attr = mask2attr(tcp);
853 case 'G': /* set adapter background */
854 if (tcp->num_param == 1) {
855 tcp->attr_mask &= ~BG_CHANGED;
856 tcp->cur_color.bg = tcp->std_color.bg
857 = tcp->param[0] & 0x0f;
858 tcp->cur_attr = mask2attr(tcp);
862 case 'H': /* set adapter reverse foreground */
863 if (tcp->num_param == 1) {
864 tcp->rev_color.fg = tcp->param[0] & 0x0f;
865 tcp->cur_attr = mask2attr(tcp);
869 case 'I': /* set adapter reverse background */
870 if (tcp->num_param == 1) {
871 tcp->rev_color.bg = tcp->param[0] & 0x0f;
872 tcp->cur_attr = mask2attr(tcp);
876 case 'S': /* set local/temporary cursor type & shape */
885 if (v0 < sizeof(tcattrs)/sizeof(tcattrs[0]))
886 sc_change_cursor_shape(scp,
887 tcattrs[v0], -1, -1);
894 } else if (tcp->esc == 4) { /* seen ESC Q */
897 } else if (tcp->esc == 5) { /* seen ESC ( */
899 case 'B': /* iso-2022: desginate ASCII into G0 */
901 /* other items to be filled */
910 scterm_puts(scr_stat *scp, u_char *buf, int len, int kernel)
922 scp->sc->write_in_progress++;
923 backup = tcp->cur_color;
925 tcp->cur_color.fg = SC_KERNEL_CONS_ATTR & 0x0f;
926 tcp->cur_color.bg = (SC_KERNEL_CONS_ATTR >> 4) & 0x0f;
930 scterm_scan_esc(scp, tcp, *ptr++);
932 } else if (PRINTABLE(*ptr)) { /* Print only printables */
942 p = sc_vtb_pointer(&scp->vtb, scp->cursor_pos);
943 map = scp->sc->scr_map;
944 attr = tcp->cur_attr;
948 if (tcp->kanji_1st_char == 0) {
949 tcp->kanji_type = iskanji1(tcp->kanji_type, c);
950 if (!IS_KTYPE_ASCII_or_HANKAKU(tcp->kanji_type)) {
951 /* not Ascii & not HANKAKU */
952 tcp->kanji_1st_char = c;
954 } else if (tcp->kanji_type == KTYPE_ASCII) {
955 cnt = imin(len, scp->xsize - scp->xpos);
958 p = sc_vtb_putchar(&scp->vtb, p, map[c], attr);
961 } while (i > 0 && PRINTABLE(c) &&
962 iskanji1(tcp->kanji_type, c) == KTYPE_ASCII);
965 mark_for_update(scp, scp->cursor_pos);
966 scp->cursor_pos += cnt - i;
967 mark_for_update(scp, scp->cursor_pos - 1);
968 scp->xpos += cnt - i;
969 KTYPE_MASK_CTRL(tcp->kanji_type);
973 if ((tcp->kanji_type =
974 iskanji2(tcp->kanji_type, c)) & 0xee) {
975 /* print kanji on TEXT VRAM */
976 kanji_code = kanji_convert(tcp->kanji_type, c,
977 tcp->kanji_1st_char);
978 mark_for_update(scp, scp->cursor_pos);
979 for (i = 0; i < 2; i++) {
980 /* *cursor_pos = (kanji_code | (i*0x80)); */
981 p = sc_vtb_putchar(&scp->vtb, p,
982 kanji_code | ((i == 0) ? 0x00 : 0x80), attr);
984 if (++scp->xpos >= scp->xsize) {
989 mark_for_update(scp, scp->cursor_pos - 1);
990 KTYPE_MASK_CTRL(tcp->kanji_type);
991 tcp->kanji_1st_char = 0;
994 tcp->kanji_1st_char = 0;
997 if (IS_KTYPE_KANA(tcp->kanji_type))
999 KTYPE_MASK_CTRL(tcp->kanji_type);
1000 sc_vtb_putchar(&scp->vtb, p, map[c], attr);
1001 mark_for_update(scp, scp->cursor_pos);
1002 mark_for_update(scp, scp->cursor_pos);
1010 cnt = imin(len, scp->xsize - scp->xpos);
1014 * gcc-2.6.3 generates poor (un)sign extension code.
1015 * Casting the pointers in the following to volatile should
1016 * have no effect, but in fact speeds up this inner loop
1017 * from 26 to 18 cycles (+ cache misses) on i486's.
1019 #define UCVP(ucp) ((u_char volatile *)(ucp))
1020 p = sc_vtb_putchar(&scp->vtb, p, UCVP(map)[*UCVP(ptr)],
1024 } while (i > 0 && PRINTABLE(*ptr));
1027 mark_for_update(scp, scp->cursor_pos);
1028 scp->cursor_pos += cnt - i;
1029 mark_for_update(scp, scp->cursor_pos - 1);
1030 scp->xpos += cnt - i;
1033 if (scp->xpos >= scp->xsize) {
1040 sc_bell(scp, scp->bell_pitch, scp->bell_duration);
1043 case 0x08: /* non-destructive backspace */
1044 if (scp->cursor_pos > 0) {
1045 mark_for_update(scp, scp->cursor_pos);
1047 mark_for_update(scp, scp->cursor_pos);
1051 scp->xpos += scp->xsize - 1;
1057 case 0x09: /* non-destructive tab */
1058 mark_for_update(scp, scp->cursor_pos);
1059 scp->cursor_pos += (8 - scp->xpos % 8u);
1060 scp->xpos += (8 - scp->xpos % 8u);
1061 if (scp->xpos >= scp->xsize) {
1064 scp->cursor_pos = scp->xsize * scp->ypos;
1066 mark_for_update(scp, scp->cursor_pos);
1069 case 0x0a: /* newline, same pos */
1070 mark_for_update(scp, scp->cursor_pos);
1071 scp->cursor_pos += scp->xsize;
1072 mark_for_update(scp, scp->cursor_pos);
1076 case 0x0c: /* form feed, clears screen */
1077 sc_clear_screen(scp);
1080 case 0x0d: /* return, return to pos 0 */
1081 mark_for_update(scp, scp->cursor_pos);
1082 scp->cursor_pos -= scp->xpos;
1083 mark_for_update(scp, scp->cursor_pos);
1088 tcp->kanji_type = KTYPE_JKANA;
1090 tcp->kanji_1st_char = 0;
1094 tcp->kanji_type = KTYPE_ASCII;
1096 tcp->kanji_1st_char = 0;
1099 case 0x1b: /* start escape sequence */
1108 sc_term_gen_scroll(scp, scp->sc->scr_map[0x20], tcp->cur_attr);
1111 tcp->cur_color = backup;
1112 scp->sc->write_in_progress--;
1118 scterm_ioctl(scr_stat *scp, struct tty *tp, u_long cmd, caddr_t data,
1121 term_stat *tcp = scp->ts;
1125 case GIO_ATTR: /* get current attributes */
1127 *(int*)data = (tcp->cur_attr >> 8) & 0xff;
1129 case CONS_GETINFO: /* get current (virtual) console info */
1130 vi = (vid_info_t *)data;
1131 if (vi->size != sizeof(struct vid_info))
1133 vi->mv_norm.fore = tcp->std_color.fg;
1134 vi->mv_norm.back = tcp->std_color.bg;
1135 vi->mv_rev.fore = tcp->rev_color.fg;
1136 vi->mv_rev.back = tcp->rev_color.bg;
1138 * The other fields are filled by the upper routine. XXX
1146 scterm_reset(scr_stat *scp, int code)
1153 scterm_default_attr(scr_stat *scp, int color, int rev_color)
1155 term_stat *tcp = scp->ts;
1157 tcp->dflt_std_color.fg = color & 0x0f;
1158 tcp->dflt_std_color.bg = (color >> 4) & 0x0f;
1159 tcp->dflt_rev_color.fg = rev_color & 0x0f;
1160 tcp->dflt_rev_color.bg = (rev_color >> 4) & 0x0f;
1161 tcp->std_color = tcp->dflt_std_color;
1162 tcp->rev_color = tcp->dflt_rev_color;
1163 tcp->cur_color = tcp->std_color;
1164 tcp->cur_attr = mask2attr(tcp);
1168 scterm_clear(scr_stat *scp)
1170 term_stat *tcp = scp->ts;
1172 sc_move_cursor(scp, 0, 0);
1173 sc_vtb_clear(&scp->vtb, scp->sc->scr_map[0x20], tcp->cur_attr);
1178 scterm_notify(scr_stat *scp, int event)
1181 case SC_TE_NOTIFY_VTSWITCH_IN:
1183 case SC_TE_NOTIFY_VTSWITCH_OUT:
1189 scterm_input(scr_stat *scp, int c, struct tty *tp)
1195 * Calculate hardware attributes word using logical attributes mask and
1201 mask2attr(term_stat *tcp)
1203 int attr, mask = tcp->attr_mask;
1205 if (mask & REVERSE_ATTR) {
1206 attr = ((mask & FG_CHANGED) ?
1207 tcp->cur_color.bg : tcp->rev_color.fg) |
1208 (((mask & BG_CHANGED) ?
1209 tcp->cur_color.fg : tcp->rev_color.bg) << 4);
1211 attr = tcp->cur_color.fg | (tcp->cur_color.bg << 4);
1213 /* XXX: underline mapping for Hercules adapter can be better */
1214 if (mask & (BOLD_ATTR | UNDERLINE_ATTR))
1216 if (mask & BLINK_ATTR)