156337Skato/*- 256337Skato * Copyright (c) 1999 FreeBSD(98) Porting Team. 356337Skato * All rights reserved. 456337Skato * 556337Skato * Redistribution and use in source and binary forms, with or without 656337Skato * modification, are permitted provided that the following conditions 756337Skato * are met: 856337Skato * 1. Redistributions of source code must retain the above copyright 956337Skato * notice, this list of conditions and the following disclaimer as 1056337Skato * the first lines of this file unmodified. 1156337Skato * 2. Redistributions in binary form must reproduce the above copyright 1256337Skato * notice, this list of conditions and the following disclaimer in the 1356337Skato * documentation and/or other materials provided with the distribution. 1456337Skato * 1556337Skato * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 1656337Skato * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1756337Skato * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1856337Skato * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 1956337Skato * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2056337Skato * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2156337Skato * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2256337Skato * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2356337Skato * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2456337Skato * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2556337Skato */ 2656337Skato 27332815Snyan#include <sys/cdefs.h> 28332815Snyan__FBSDID("$FreeBSD: stable/11/sys/pc98/cbus/scterm-sck.c 332815 2018-04-20 12:40:05Z nyan $"); 29332815Snyan 3056337Skato#include "opt_syscons.h" 3156337Skato 3256337Skato#include <sys/param.h> 3356337Skato#include <sys/systm.h> 3456337Skato#include <sys/kernel.h> 35130070Sphk#include <sys/module.h> 3656337Skato#include <sys/consio.h> 3756337Skato 3856337Skato#include <machine/pc/display.h> 3956337Skato 4056337Skato#include <dev/syscons/syscons.h> 41186681Sed#include <pc98/cbus/sctermvar.h> 4256337Skato 4356337Skato#define MAX_ESC_PAR 5 4456337Skato 4556337Skato#ifdef KANJI 4656337Skato#define IS_KTYPE_ASCII_or_HANKAKU(A) (!((A) & 0xee)) 4756337Skato#define IS_KTYPE_KANA(A) ((A) & 0x11) 4856337Skato#define KTYPE_MASK_CTRL(A) ((A) &= 0xF0) 4956337Skato#endif /* KANJI */ 5056337Skato 5156337Skato/* attribute flags */ 5256337Skatotypedef struct { 5356337Skato u_short fg; /* foreground color */ 5456337Skato u_short bg; /* background color */ 5556337Skato} color_t; 5656337Skato 5756337Skatotypedef struct { 5856337Skato int flags; 5956337Skato#define SCTERM_BUSY (1 << 0) 6056337Skato int esc; 6156337Skato int num_param; 6256337Skato int last_param; 6356337Skato int param[MAX_ESC_PAR]; 6456337Skato int saved_xpos; 6556337Skato int saved_ypos; 6656337Skato 6756337Skato#ifdef KANJI 6856337Skato u_char kanji_1st_char; 6956337Skato u_char kanji_type; 7056337Skato#define KTYPE_ASCII 0 /* ASCII */ 7156337Skato#define KTYPE_KANA 1 /* HANKAKU */ 7256337Skato#define KTYPE_JKANA 0x10 /* JIS HANKAKU */ 7356337Skato#define KTYPE_7JIS 0x20 /* JIS */ 7456337Skato#define KTYPE_SJIS 2 /* Shift JIS */ 7556337Skato#define KTYPE_UJIS 4 /* UJIS */ 7656337Skato#define KTYPE_SUKANA 3 /* Shift JIS or UJIS HANKAKU */ 7756337Skato#define KTYPE_SUJIS 6 /* SHift JIS or UJIS */ 7856337Skato#define KTYPE_KANIN 0x80 /* Kanji Invoke sequence */ 7956337Skato#define KTYPE_ASCIN 0x40 /* ASCII Invoke sequence */ 8056337Skato#endif /* KANJI */ 8156337Skato 8256337Skato int attr_mask; /* current logical attr mask */ 8356337Skato#define NORMAL_ATTR 0x00 8456337Skato#define BLINK_ATTR 0x01 8556337Skato#define BOLD_ATTR 0x02 8656337Skato#define UNDERLINE_ATTR 0x04 8756337Skato#define REVERSE_ATTR 0x08 8856337Skato#define FG_CHANGED 0x10 8956337Skato#define BG_CHANGED 0x20 9056337Skato int cur_attr; /* current hardware attr word */ 9156337Skato color_t cur_color; /* current hardware color */ 9256337Skato color_t std_color; /* normal hardware color */ 9356337Skato color_t rev_color; /* reverse hardware color */ 9456337Skato color_t dflt_std_color; /* default normal color */ 9556337Skato color_t dflt_rev_color; /* default reverse color */ 9656337Skato} term_stat; 9756337Skato 98199171Sedstatic sc_term_init_t scterm_init; 99199171Sedstatic sc_term_term_t scterm_term; 100199171Sedstatic sc_term_puts_t scterm_puts; 101199171Sedstatic sc_term_ioctl_t scterm_ioctl; 102199171Sedstatic sc_term_reset_t scterm_reset; 10356337Skatostatic sc_term_default_attr_t scterm_default_attr; 104199171Sedstatic sc_term_clear_t scterm_clear; 105199171Sedstatic sc_term_notify_t scterm_notify; 106199171Sedstatic sc_term_input_t scterm_input; 107199171Sedstatic sc_term_fkeystr_t scterm_fkeystr; 10856337Skato 10956337Skatostatic sc_term_sw_t sc_term_sc = { 11056337Skato { NULL, NULL }, 11158381Snyan "sck", /* emulator name */ 11258381Snyan "syscons kanji terminal", /* description */ 11358381Snyan "*", /* matching renderer, any :-) */ 11458381Snyan sizeof(term_stat), /* softc size */ 11556337Skato 0, 11656337Skato scterm_init, 11756337Skato scterm_term, 11856337Skato scterm_puts, 11956337Skato scterm_ioctl, 12056337Skato scterm_reset, 12156337Skato scterm_default_attr, 12256337Skato scterm_clear, 12356337Skato scterm_notify, 12456337Skato scterm_input, 125199171Sed scterm_fkeystr, 12656337Skato}; 12756337Skato 12856337SkatoSCTERM_MODULE(sc, sc_term_sc); 12956337Skato 13056337Skatostatic term_stat reserved_term_stat; 13156337Skatostatic int default_kanji = UJIS; 13256337Skatostatic void scterm_scan_esc(scr_stat *scp, term_stat *tcp, 13356337Skato u_char c); 13456337Skatostatic int mask2attr(term_stat *tcp); 13556337Skato 13690012Snyan#ifdef KANJI 137228471Sedstatic inline u_char 13890012Snyaniskanji1(u_char mode, u_char c) 13990012Snyan{ 14090465Snyan if (c > 0x80) { 14190465Snyan if ((c >= 0xa1) && (c <= 0xdf)) { 14290465Snyan if (default_kanji == UJIS) { 14390465Snyan /* UJIS */ 14490465Snyan return KTYPE_UJIS; 14590465Snyan } 14690465Snyan if (default_kanji == SJIS) { 14790465Snyan /* SJIS HANKAKU */ 14890465Snyan return KTYPE_KANA; 14990465Snyan } 15090465Snyan } 15190012Snyan 15290465Snyan if (c <= 0x9f) { 15390465Snyan if (c == 0x8e) { 15490465Snyan /* SJIS or UJIS HANKAKU */ 15590465Snyan return KTYPE_SUKANA; 15690465Snyan } 15790012Snyan 15890465Snyan /* SJIS */ 15990465Snyan default_kanji = SJIS; 16090465Snyan return KTYPE_SJIS; 16190465Snyan } 16290012Snyan 16390465Snyan if ((c >= 0xe0) && (c <= 0xef)) { 16490465Snyan /* SJIS or UJIS */ 16590465Snyan return KTYPE_SUJIS; 16690465Snyan } 16790012Snyan 16890465Snyan if ((c >= 0xf0) && (c <= 0xfe)) { 16990465Snyan /* UJIS */ 17090465Snyan default_kanji = UJIS; 17190465Snyan return KTYPE_UJIS; 17290465Snyan } 17390465Snyan } else { 17490465Snyan if ((mode == KTYPE_7JIS) && (c >= 0x21) && (c <= 0x7e)) { 17590465Snyan /* JIS */ 17690465Snyan default_kanji = UJIS; 17790465Snyan return KTYPE_7JIS; 17890465Snyan } 17990012Snyan 18090465Snyan if ((mode == KTYPE_JKANA) && (c >= 0x21) && (c <= 0x5f)) { 18190465Snyan /* JIS HANKAKU */ 18290465Snyan default_kanji = UJIS; 18390465Snyan return KTYPE_JKANA; 18490465Snyan } 18590465Snyan } 18690012Snyan 18790465Snyan return KTYPE_ASCII; 18890012Snyan} 18990012Snyan 190228471Sedstatic inline u_char 19190012Snyaniskanji2(u_char mode, u_char c) 19290012Snyan{ 19390467Snyan switch (mode) { 19490467Snyan case KTYPE_7JIS: 19590467Snyan if ((c >= 0x21) && (c <= 0x7e)) { 19690467Snyan /* JIS */ 19790467Snyan return KTYPE_7JIS; 19890467Snyan } 19990467Snyan break; 20090467Snyan case KTYPE_SJIS: 20190467Snyan if ((c >= 0x40) && (c <= 0xfc) && (c != 0x7f)) { 20290467Snyan /* SJIS */ 20390467Snyan return KTYPE_SJIS; 20490467Snyan } 20590467Snyan break; 20690467Snyan case KTYPE_UJIS: 20790467Snyan if ((c >= 0xa1) && (c <= 0xfe)) { 20890467Snyan /* UJIS */ 20990467Snyan return KTYPE_UJIS; 21090467Snyan } 21190467Snyan break; 21290467Snyan case KTYPE_SUKANA: 21390467Snyan if ((c >= 0xa1) && (c <= 0xdf) && (default_kanji == UJIS)) { 21490467Snyan /* UJIS HANKAKU */ 21590467Snyan return KTYPE_KANA; 21690467Snyan } 21790467Snyan if ((c >= 0x40) && (c <= 0xfc) && (c != 0x7f)) { 21890467Snyan /* SJIS */ 21990467Snyan default_kanji = SJIS; 22090467Snyan return KTYPE_SJIS; 22190467Snyan } 22290467Snyan break; 22390467Snyan case KTYPE_SUJIS: 22490467Snyan if ((c >= 0x40) && (c <= 0xa0) && (c != 0x7f)) { 22590467Snyan /* SJIS */ 22690467Snyan default_kanji = SJIS; 22790467Snyan return KTYPE_SJIS; 22890467Snyan } 22990467Snyan if ((c == 0xfd) || (c == 0xfe)) { 23090467Snyan /* UJIS */ 23190467Snyan default_kanji = UJIS; 23290467Snyan return KTYPE_UJIS; 23390467Snyan } 23490467Snyan if ((c >= 0xa1) && (c <= 0xfc)) { 23590467Snyan if (default_kanji == SJIS) 23690467Snyan return KTYPE_SJIS; 23790467Snyan if (default_kanji == UJIS) 23890467Snyan return KTYPE_UJIS; 23990467Snyan } 24090467Snyan break; 24190012Snyan } 24290467Snyan 24390467Snyan return KTYPE_ASCII; 24490012Snyan} 24590012Snyan 24690012Snyan/* 24790012Snyan * JIS X0208-83 keisen conversion table 24890012Snyan */ 24990012Snyanstatic u_short keiConv[32] = { 25090012Snyan 0x240c, 0x260c, 0x300c, 0x340c, 0x3c0c, 0x380c, 0x400c, 0x500c, 25190012Snyan 0x480c, 0x580c, 0x600c, 0x250c, 0x270c, 0x330c, 0x370c, 0x3f0c, 25290012Snyan 0x3b0c, 0x470c, 0x570c, 0x4f0c, 0x5f0c, 0x6f0c, 0x440c, 0x530c, 25390012Snyan 0x4c0c, 0x5b0c, 0x630c, 0x410c, 0x540c, 0x490c, 0x5c0c, 0x660c 25490012Snyan}; 25590012Snyan 25690012Snyanstatic u_short 25790012Snyankanji_convert(u_char mode, u_char h, u_char l) 25890012Snyan{ 25990467Snyan u_short tmp, high, low, c; 26090012Snyan 26190467Snyan high = (u_short) h; 26290467Snyan low = (u_short) l; 26390467Snyan 26490467Snyan switch (mode) { 26590467Snyan case KTYPE_SJIS: /* SHIFT JIS */ 26690467Snyan if (low >= 0xe0) { 26790467Snyan low -= 0x40; 26890467Snyan } 26990467Snyan low = (low - 0x81) * 2 + 0x21; 27090467Snyan if (high > 0x7f) { 27190467Snyan high--; 27290467Snyan } 27390467Snyan if (high > 0x9d) { 27490467Snyan low++; 27590467Snyan high -= 0x9e - 0x21; 27690467Snyan } else { 27790467Snyan high -= 0x40 - 0x21; 27890467Snyan } 27990467Snyan high &= 0x7F; 28090467Snyan low &= 0x7F; 28190467Snyan tmp = ((high << 8) | low) - 0x20; 28290467Snyan break; 28390467Snyan case KTYPE_7JIS: /* JIS */ 28490467Snyan case KTYPE_UJIS: /* UJIS */ 28590467Snyan high &= 0x7F; 28690467Snyan low &= 0x7F; 28790467Snyan tmp = ((high << 8) | low) - 0x20; 28890467Snyan break; 28990467Snyan default: 29090467Snyan tmp = 0; 29190467Snyan break; 29290012Snyan } 29390012Snyan 29490467Snyan /* keisen */ 29590467Snyan c = ((tmp & 0xff) << 8) | (tmp >> 8); 29690467Snyan /* 0x2821 .. 0x2840 */ 29790467Snyan if (0x0821 <= c && c <= 0x0840) 29890467Snyan tmp = keiConv[c - 0x0821]; 29990012Snyan 30090467Snyan return (tmp); 30190012Snyan} 30290012Snyan#endif /* KANJI */ 30390012Snyan 30456337Skatostatic int 30556337Skatoscterm_init(scr_stat *scp, void **softc, int code) 30656337Skato{ 30756337Skato term_stat *tcp; 30856337Skato 30956337Skato if (*softc == NULL) { 31056337Skato if (reserved_term_stat.flags & SCTERM_BUSY) 31156337Skato return EINVAL; 31256337Skato *softc = &reserved_term_stat; 31356337Skato } 31456337Skato tcp = *softc; 31556337Skato 31656337Skato switch (code) { 31756337Skato case SC_TE_COLD_INIT: 31856337Skato bzero(tcp, sizeof(*tcp)); 31956337Skato tcp->flags = SCTERM_BUSY; 32056337Skato tcp->esc = 0; 32156337Skato tcp->saved_xpos = -1; 32256337Skato tcp->saved_ypos = -1; 32356337Skato#ifdef KANJI 32456337Skato tcp->kanji_1st_char = 0; 32556337Skato tcp->kanji_type = KTYPE_ASCII; 32656337Skato#endif 32756337Skato tcp->attr_mask = NORMAL_ATTR; 32856337Skato /* XXX */ 32956337Skato tcp->dflt_std_color.fg = SC_NORM_ATTR & 0x0f; 33056337Skato tcp->dflt_std_color.bg = (SC_NORM_ATTR >> 4) & 0x0f; 33156337Skato tcp->dflt_rev_color.fg = SC_NORM_REV_ATTR & 0x0f; 33256337Skato tcp->dflt_rev_color.bg = (SC_NORM_REV_ATTR >> 4) & 0x0f; 33356337Skato tcp->std_color = tcp->dflt_std_color; 33456337Skato tcp->rev_color = tcp->dflt_rev_color; 33556337Skato tcp->cur_color = tcp->std_color; 33656337Skato tcp->cur_attr = mask2attr(tcp); 33756337Skato ++sc_term_sc.te_refcount; 33856337Skato break; 33956337Skato 34056337Skato case SC_TE_WARM_INIT: 34156337Skato tcp->esc = 0; 34256337Skato tcp->saved_xpos = -1; 34356337Skato tcp->saved_ypos = -1; 34457136Skato#if 0 34556337Skato tcp->std_color = tcp->dflt_std_color; 34656337Skato tcp->rev_color = tcp->dflt_rev_color; 34757136Skato#endif 34856337Skato tcp->cur_color = tcp->std_color; 34956337Skato tcp->cur_attr = mask2attr(tcp); 35056337Skato break; 35156337Skato } 35256337Skato 35356337Skato return 0; 35456337Skato} 35556337Skato 35656337Skatostatic int 35756337Skatoscterm_term(scr_stat *scp, void **softc) 35856337Skato{ 35956337Skato if (*softc == &reserved_term_stat) { 36056337Skato *softc = NULL; 36156337Skato bzero(&reserved_term_stat, sizeof(reserved_term_stat)); 36256337Skato } 36356337Skato --sc_term_sc.te_refcount; 36456337Skato return 0; 36556337Skato} 36656337Skato 36756337Skatostatic void 36856337Skatoscterm_scan_esc(scr_stat *scp, term_stat *tcp, u_char c) 36956337Skato{ 37056337Skato static u_char ansi_col[16] = { 37156337Skato FG_BLACK, FG_RED, FG_GREEN, FG_BROWN, 37256337Skato FG_BLUE, FG_MAGENTA, FG_CYAN, FG_LIGHTGREY, 37356337Skato FG_DARKGREY, FG_LIGHTRED, FG_LIGHTGREEN, FG_YELLOW, 37456337Skato FG_LIGHTBLUE, FG_LIGHTMAGENTA, FG_LIGHTCYAN, FG_WHITE 37558381Snyan }; 37681231Snyan static int cattrs[] = { 37781231Snyan 0, /* block */ 37881231Snyan CONS_BLINK_CURSOR, /* blinking block */ 37981231Snyan CONS_CHAR_CURSOR, /* underline */ 38081231Snyan CONS_CHAR_CURSOR | CONS_BLINK_CURSOR, /* blinking underline */ 38181231Snyan CONS_RESET_CURSOR, /* reset to default */ 38281231Snyan CONS_HIDDEN_CURSOR, /* hide cursor */ 38381231Snyan }; 38481231Snyan static int tcattrs[] = { 38581231Snyan CONS_RESET_CURSOR | CONS_LOCAL_CURSOR, /* normal */ 38681231Snyan CONS_HIDDEN_CURSOR | CONS_LOCAL_CURSOR, /* invisible */ 38781231Snyan CONS_BLINK_CURSOR | CONS_LOCAL_CURSOR, /* very visible */ 38881231Snyan }; 38956337Skato sc_softc_t *sc; 39081231Snyan int v0, v1, v2; 39156337Skato int i, n; 39256337Skato 39358381Snyan i = n = 0; 39458381Snyan sc = scp->sc; 39558381Snyan if (tcp->esc == 1) { /* seen ESC */ 39659778Snyan#ifdef KANJI 39759778Snyan switch (tcp->kanji_type) { 39859778Snyan case KTYPE_KANIN: /* Kanji Invoke sequence */ 39959778Snyan switch (c) { 40059778Snyan case 'B': 40159778Snyan case '@': 40259778Snyan tcp->kanji_type = KTYPE_7JIS; 40359778Snyan tcp->esc = 0; 40459778Snyan tcp->kanji_1st_char = 0; 40559778Snyan return; 40659778Snyan default: 40759778Snyan tcp->kanji_type = KTYPE_ASCII; 40859778Snyan tcp->esc = 0; 40959778Snyan break; 41059778Snyan } 41159778Snyan break; 41259778Snyan case KTYPE_ASCIN: /* Ascii Invoke sequence */ 41359778Snyan switch (c) { 41459778Snyan case 'J': 41559778Snyan case 'B': 41659778Snyan case 'H': 41759778Snyan tcp->kanji_type = KTYPE_ASCII; 41859778Snyan tcp->esc = 0; 41959778Snyan tcp->kanji_1st_char = 0; 42059778Snyan return; 42159778Snyan case 'I': 42259778Snyan tcp->kanji_type = KTYPE_JKANA; 42359778Snyan tcp->esc = 0; 42459778Snyan tcp->kanji_1st_char = 0; 42559778Snyan return; 42659778Snyan default: 42759778Snyan tcp->kanji_type = KTYPE_ASCII; 42859778Snyan tcp->esc = 0; 42959778Snyan break; 43059778Snyan } 43159778Snyan break; 43259778Snyan default: 43359778Snyan break; 43459778Snyan } 43559778Snyan#endif 43658381Snyan switch (c) { 43756337Skato 43858381Snyan case '7': /* Save cursor position */ 43958381Snyan tcp->saved_xpos = scp->xpos; 44058381Snyan tcp->saved_ypos = scp->ypos; 44158381Snyan break; 44256337Skato 44358381Snyan case '8': /* Restore saved cursor position */ 44458381Snyan if (tcp->saved_xpos >= 0 && tcp->saved_ypos >= 0) 44558381Snyan sc_move_cursor(scp, tcp->saved_xpos, 44658381Snyan tcp->saved_ypos); 44758381Snyan break; 44856337Skato 44958381Snyan case '[': /* Start ESC [ sequence */ 45058381Snyan tcp->esc = 2; 45158381Snyan tcp->last_param = -1; 45258381Snyan for (i = tcp->num_param; i < MAX_ESC_PAR; i++) 45358381Snyan tcp->param[i] = 1; 45458381Snyan tcp->num_param = 0; 45558381Snyan return; 45656337Skato 45756337Skato#ifdef KANJI 45858381Snyan case '$': /* Kanji Invoke sequence */ 45958381Snyan tcp->kanji_type = KTYPE_KANIN; 46058381Snyan return; 46156337Skato#endif 46256337Skato 46358381Snyan case 'M': /* Move cursor up 1 line, scroll if at top */ 46458381Snyan sc_term_up_scroll(scp, 1, sc->scr_map[0x20], 46558381Snyan tcp->cur_attr, 0, 0); 46658381Snyan break; 467153110Sru#ifdef notyet 46858381Snyan case 'Q': 46958381Snyan tcp->esc = 4; 47058381Snyan return; 47156337Skato#endif 47264021Snyan case 'c': /* reset */ 47364021Snyan tcp->attr_mask = NORMAL_ATTR; 47464021Snyan tcp->cur_color = tcp->std_color 47564021Snyan = tcp->dflt_std_color; 47664021Snyan tcp->rev_color = tcp->dflt_rev_color; 47764021Snyan tcp->cur_attr = mask2attr(tcp); 47881231Snyan sc_change_cursor_shape(scp, 47981231Snyan CONS_RESET_CURSOR | CONS_LOCAL_CURSOR, -1, -1); 48058381Snyan sc_clear_screen(scp); 48158381Snyan break; 48256337Skato 48358381Snyan case '(': /* iso-2022: designate 94 character set to G0 */ 48456337Skato#ifdef KANJI 48558381Snyan tcp->kanji_type = KTYPE_ASCIN; 48656337Skato#else 48758381Snyan tcp->esc = 5; 48856337Skato#endif 48958381Snyan return; 49056337Skato } 49158381Snyan } else if (tcp->esc == 2) { /* seen ESC [ */ 49258381Snyan if (c >= '0' && c <= '9') { 49358381Snyan if (tcp->num_param < MAX_ESC_PAR) { 49458381Snyan if (tcp->last_param != tcp->num_param) { 49558381Snyan tcp->last_param = tcp->num_param; 49658381Snyan tcp->param[tcp->num_param] = 0; 49758381Snyan } else { 49858381Snyan tcp->param[tcp->num_param] *= 10; 49958381Snyan } 50058381Snyan tcp->param[tcp->num_param] += c - '0'; 50158381Snyan return; 50258381Snyan } 50358381Snyan } 50458381Snyan tcp->num_param = tcp->last_param + 1; 50558381Snyan switch (c) { 50656337Skato 50758381Snyan case ';': 50858381Snyan if (tcp->num_param < MAX_ESC_PAR) 50958381Snyan return; 51058381Snyan break; 51156337Skato 51258381Snyan case '=': 51358381Snyan tcp->esc = 3; 51458381Snyan tcp->last_param = -1; 51558381Snyan for (i = tcp->num_param; i < MAX_ESC_PAR; i++) 51658381Snyan tcp->param[i] = 1; 51758381Snyan tcp->num_param = 0; 51858381Snyan return; 51956337Skato 52058381Snyan case 'A': /* up n rows */ 52158381Snyan sc_term_up(scp, tcp->param[0], 0); 52258381Snyan break; 52356337Skato 52458381Snyan case 'B': /* down n rows */ 52558381Snyan sc_term_down(scp, tcp->param[0], 0); 52658381Snyan break; 52756337Skato 52858381Snyan case 'C': /* right n columns */ 52958381Snyan sc_term_right(scp, tcp->param[0]); 53058381Snyan break; 53156337Skato 53258381Snyan case 'D': /* left n columns */ 53358381Snyan sc_term_left(scp, tcp->param[0]); 53458381Snyan break; 53556337Skato 53658381Snyan case 'E': /* cursor to start of line n lines down */ 53758381Snyan n = tcp->param[0]; 53858381Snyan if (n < 1) 53958381Snyan n = 1; 54058381Snyan sc_move_cursor(scp, 0, scp->ypos + n); 54158381Snyan break; 54256337Skato 54358381Snyan case 'F': /* cursor to start of line n lines up */ 54458381Snyan n = tcp->param[0]; 54558381Snyan if (n < 1) 54658381Snyan n = 1; 54758381Snyan sc_move_cursor(scp, 0, scp->ypos - n); 54858381Snyan break; 54956337Skato 55058381Snyan case 'f': /* Cursor move */ 55158381Snyan case 'H': 55258381Snyan if (tcp->num_param == 0) 55358381Snyan sc_move_cursor(scp, 0, 0); 55458381Snyan else if (tcp->num_param == 2) 55558381Snyan sc_move_cursor(scp, tcp->param[1] - 1, 55658381Snyan tcp->param[0] - 1); 55758381Snyan break; 55856337Skato 55958381Snyan case 'J': /* Clear all or part of display */ 56058381Snyan if (tcp->num_param == 0) 56158381Snyan n = 0; 56258381Snyan else 56358381Snyan n = tcp->param[0]; 56458381Snyan sc_term_clr_eos(scp, n, sc->scr_map[0x20], 56558381Snyan tcp->cur_attr); 56658381Snyan break; 56756337Skato 56858381Snyan case 'K': /* Clear all or part of line */ 56958381Snyan if (tcp->num_param == 0) 57058381Snyan n = 0; 57158381Snyan else 57258381Snyan n = tcp->param[0]; 57358381Snyan sc_term_clr_eol(scp, n, sc->scr_map[0x20], 57458381Snyan tcp->cur_attr); 57558381Snyan break; 57656337Skato 57758381Snyan case 'L': /* Insert n lines */ 57858381Snyan sc_term_ins_line(scp, scp->ypos, tcp->param[0], 57958381Snyan sc->scr_map[0x20], tcp->cur_attr, 0); 58058381Snyan break; 58156337Skato 58258381Snyan case 'M': /* Delete n lines */ 58358381Snyan sc_term_del_line(scp, scp->ypos, tcp->param[0], 58458381Snyan sc->scr_map[0x20], tcp->cur_attr, 0); 58558381Snyan break; 58656337Skato 58758381Snyan case 'P': /* Delete n chars */ 58858381Snyan sc_term_del_char(scp, tcp->param[0], 58958381Snyan sc->scr_map[0x20], tcp->cur_attr); 59058381Snyan break; 59156337Skato 59258381Snyan case '@': /* Insert n chars */ 59358381Snyan sc_term_ins_char(scp, tcp->param[0], 59458381Snyan sc->scr_map[0x20], tcp->cur_attr); 59558381Snyan break; 59656337Skato 59758381Snyan case 'S': /* scroll up n lines */ 59858381Snyan sc_term_del_line(scp, 0, tcp->param[0], 59958381Snyan sc->scr_map[0x20], tcp->cur_attr, 0); 60058381Snyan break; 60156337Skato 60258381Snyan case 'T': /* scroll down n lines */ 60358381Snyan sc_term_ins_line(scp, 0, tcp->param[0], 60458381Snyan sc->scr_map[0x20], tcp->cur_attr, 0); 60558381Snyan break; 60656337Skato 60758381Snyan case 'X': /* erase n characters in line */ 60858381Snyan n = tcp->param[0]; 60958381Snyan if (n < 1) 61058381Snyan n = 1; 61158381Snyan if (n > scp->xsize - scp->xpos) 61258381Snyan n = scp->xsize - scp->xpos; 61358381Snyan sc_vtb_erase(&scp->vtb, scp->cursor_pos, n, 61458381Snyan sc->scr_map[0x20], tcp->cur_attr); 61558381Snyan mark_for_update(scp, scp->cursor_pos); 61658381Snyan mark_for_update(scp, scp->cursor_pos + n - 1); 61758381Snyan break; 61856337Skato 61958381Snyan case 'Z': /* move n tabs backwards */ 62058381Snyan sc_term_backtab(scp, tcp->param[0]); 62158381Snyan break; 62256337Skato 62358381Snyan case '`': /* move cursor to column n */ 62458381Snyan sc_term_col(scp, tcp->param[0]); 62558381Snyan break; 62656337Skato 62758381Snyan case 'a': /* move cursor n columns to the right */ 62858381Snyan sc_term_right(scp, tcp->param[0]); 62958381Snyan break; 63056337Skato 63158381Snyan case 'd': /* move cursor to row n */ 63258381Snyan sc_term_row(scp, tcp->param[0]); 63358381Snyan break; 63456337Skato 63558381Snyan case 'e': /* move cursor n rows down */ 63658381Snyan sc_term_down(scp, tcp->param[0], 0); 63758381Snyan break; 63856337Skato 63958381Snyan case 'm': /* change attribute */ 64058381Snyan if (tcp->num_param == 0) { 64158381Snyan tcp->attr_mask = NORMAL_ATTR; 64258381Snyan tcp->cur_color = tcp->std_color; 64358381Snyan tcp->cur_attr = mask2attr(tcp); 64458381Snyan break; 64558381Snyan } 64658381Snyan for (i = 0; i < tcp->num_param; i++) { 64758381Snyan switch (n = tcp->param[i]) { 64858381Snyan case 0: /* back to normal */ 64958381Snyan tcp->attr_mask = NORMAL_ATTR; 65058381Snyan tcp->cur_color = tcp->std_color; 65158381Snyan tcp->cur_attr = mask2attr(tcp); 65258381Snyan break; 65358381Snyan case 1: /* bold */ 65458381Snyan tcp->attr_mask |= BOLD_ATTR; 65558381Snyan tcp->cur_attr = mask2attr(tcp); 65658381Snyan break; 65758381Snyan case 4: /* underline */ 65858381Snyan tcp->attr_mask |= UNDERLINE_ATTR; 65958381Snyan tcp->cur_attr = mask2attr(tcp); 66058381Snyan break; 66158381Snyan case 5: /* blink */ 66258381Snyan tcp->attr_mask |= BLINK_ATTR; 66358381Snyan tcp->cur_attr = mask2attr(tcp); 66458381Snyan break; 66564021Snyan case 7: /* reverse */ 66658381Snyan tcp->attr_mask |= REVERSE_ATTR; 66758381Snyan tcp->cur_attr = mask2attr(tcp); 66858381Snyan break; 66964021Snyan case 22: /* remove bold (or dim) */ 67064021Snyan tcp->attr_mask &= ~BOLD_ATTR; 67164021Snyan tcp->cur_attr = mask2attr(tcp); 67264021Snyan break; 67364021Snyan case 24: /* remove underline */ 67464021Snyan tcp->attr_mask &= ~UNDERLINE_ATTR; 67564021Snyan tcp->cur_attr = mask2attr(tcp); 67664021Snyan break; 67764021Snyan case 25: /* remove blink */ 67864021Snyan tcp->attr_mask &= ~BLINK_ATTR; 67964021Snyan tcp->cur_attr = mask2attr(tcp); 68064021Snyan break; 68164021Snyan case 27: /* remove reverse */ 68264021Snyan tcp->attr_mask &= ~REVERSE_ATTR; 68364021Snyan tcp->cur_attr = mask2attr(tcp); 68464021Snyan break; 68564021Snyan case 30: case 31: /* set ansi fg color */ 68658381Snyan case 32: case 33: case 34: 68758381Snyan case 35: case 36: case 37: 68858381Snyan tcp->attr_mask |= FG_CHANGED; 68958381Snyan tcp->cur_color.fg = ansi_col[n - 30]; 69058381Snyan tcp->cur_attr = mask2attr(tcp); 69158381Snyan break; 69264021Snyan case 39: /* restore fg color back to normal */ 69364021Snyan tcp->attr_mask &= ~(FG_CHANGED|BOLD_ATTR); 69461950Snyan tcp->cur_color.fg = tcp->std_color.fg; 69561950Snyan tcp->cur_attr = mask2attr(tcp); 69661950Snyan break; 69764021Snyan case 40: case 41: /* set ansi bg color */ 69858381Snyan case 42: case 43: case 44: 69958381Snyan case 45: case 46: case 47: 70058381Snyan tcp->attr_mask |= BG_CHANGED; 70158381Snyan tcp->cur_color.bg = ansi_col[n - 40]; 70258381Snyan tcp->cur_attr = mask2attr(tcp); 70358381Snyan break; 70464021Snyan case 49: /* restore bg color back to normal */ 70561950Snyan tcp->attr_mask &= ~BG_CHANGED; 70661950Snyan tcp->cur_color.bg = tcp->std_color.bg; 70761950Snyan tcp->cur_attr = mask2attr(tcp); 70861950Snyan break; 70958381Snyan } 71058381Snyan } 71158381Snyan break; 71256337Skato 71358381Snyan case 's': /* Save cursor position */ 71458381Snyan tcp->saved_xpos = scp->xpos; 71558381Snyan tcp->saved_ypos = scp->ypos; 71658381Snyan break; 71756337Skato 71858381Snyan case 'u': /* Restore saved cursor position */ 71958381Snyan if (tcp->saved_xpos >= 0 && tcp->saved_ypos >= 0) 72058381Snyan sc_move_cursor(scp, tcp->saved_xpos, 72158381Snyan tcp->saved_ypos); 72258381Snyan break; 72356337Skato 72458381Snyan case 'x': 72558381Snyan if (tcp->num_param == 0) 72658381Snyan n = 0; 72758381Snyan else 72858381Snyan n = tcp->param[0]; 72958381Snyan switch (n) { 73064021Snyan case 0: /* reset colors and attributes back to normal */ 73158381Snyan tcp->attr_mask = NORMAL_ATTR; 73288392Snyan tcp->cur_color = tcp->std_color 73388392Snyan = tcp->dflt_std_color; 73458381Snyan tcp->rev_color = tcp->dflt_rev_color; 73558381Snyan tcp->cur_attr = mask2attr(tcp); 73658381Snyan break; 73758381Snyan case 1: /* set ansi background */ 73858381Snyan tcp->attr_mask &= ~BG_CHANGED; 73988392Snyan tcp->cur_color.bg = tcp->std_color.bg 74088392Snyan = ansi_col[tcp->param[1] & 0x0f]; 74158381Snyan tcp->cur_attr = mask2attr(tcp); 74258381Snyan break; 74358381Snyan case 2: /* set ansi foreground */ 74458381Snyan tcp->attr_mask &= ~FG_CHANGED; 74588392Snyan tcp->cur_color.fg = tcp->std_color.fg 74688392Snyan = ansi_col[tcp->param[1] & 0x0f]; 74758381Snyan tcp->cur_attr = mask2attr(tcp); 74858381Snyan break; 74964021Snyan case 3: /* set adapter attribute directly */ 75058381Snyan tcp->attr_mask &= ~(FG_CHANGED | BG_CHANGED); 75188392Snyan tcp->cur_color.fg = tcp->std_color.fg 75288392Snyan = tcp->param[1] & 0x0f; 75388392Snyan tcp->cur_color.bg = tcp->std_color.bg 75488392Snyan = (tcp->param[1] >> 4) & 0x0f; 75558381Snyan tcp->cur_attr = mask2attr(tcp); 75658381Snyan break; 75764021Snyan case 5: /* set ansi reverse background */ 75888392Snyan tcp->rev_color.bg = ansi_col[tcp->param[1] & 0x0f]; 75958381Snyan tcp->cur_attr = mask2attr(tcp); 76058381Snyan break; 76164021Snyan case 6: /* set ansi reverse foreground */ 76288392Snyan tcp->rev_color.fg = ansi_col[tcp->param[1] & 0x0f]; 76358381Snyan tcp->cur_attr = mask2attr(tcp); 76458381Snyan break; 76564021Snyan case 7: /* set adapter reverse attribute directly */ 76658381Snyan tcp->rev_color.fg = tcp->param[1] & 0x0f; 76758381Snyan tcp->rev_color.bg = (tcp->param[1] >> 4) & 0x0f; 76858381Snyan tcp->cur_attr = mask2attr(tcp); 76958381Snyan break; 77058381Snyan } 77158381Snyan break; 77256337Skato 77358381Snyan case 'z': /* switch to (virtual) console n */ 77458381Snyan if (tcp->num_param == 1) 77558381Snyan sc_switch_scr(sc, tcp->param[0]); 77658381Snyan break; 77756337Skato } 77858381Snyan } else if (tcp->esc == 3) { /* seen ESC [0-9]+ = */ 77958381Snyan if (c >= '0' && c <= '9') { 78058381Snyan if (tcp->num_param < MAX_ESC_PAR) { 78158381Snyan if (tcp->last_param != tcp->num_param) { 78258381Snyan tcp->last_param = tcp->num_param; 78358381Snyan tcp->param[tcp->num_param] = 0; 78458381Snyan } else { 78558381Snyan tcp->param[tcp->num_param] *= 10; 78658381Snyan } 78758381Snyan tcp->param[tcp->num_param] += c - '0'; 78858381Snyan return; 78958381Snyan } 79058381Snyan } 79158381Snyan tcp->num_param = tcp->last_param + 1; 79258381Snyan switch (c) { 79356337Skato 79458381Snyan case ';': 79558381Snyan if (tcp->num_param < MAX_ESC_PAR) 79658381Snyan return; 79758381Snyan break; 79856337Skato 79958381Snyan case 'A': /* set display border color */ 80058381Snyan if (tcp->num_param == 1) { 80158381Snyan scp->border=tcp->param[0] & 0xff; 80258381Snyan if (scp == sc->cur_scp) 80358381Snyan sc_set_border(scp, scp->border); 80458381Snyan } 80558381Snyan break; 80656337Skato 80758381Snyan case 'B': /* set bell pitch and duration */ 80858381Snyan if (tcp->num_param == 2) { 80958381Snyan scp->bell_pitch = tcp->param[0]; 81078811Snyan scp->bell_duration = 81178811Snyan (tcp->param[1] * hz + 99) / 100; 81258381Snyan } 81358381Snyan break; 81456337Skato 81581231Snyan case 'C': /* set global/parmanent cursor type & shape */ 81658381Snyan i = spltty(); 81781231Snyan n = tcp->num_param; 81881231Snyan v0 = tcp->param[0]; 81981231Snyan v1 = tcp->param[1]; 82081231Snyan v2 = tcp->param[2]; 82181231Snyan switch (n) { 82281231Snyan case 1: /* flags only */ 823298352Spfg if (v0 < nitems(cattrs)) 82481231Snyan v0 = cattrs[v0]; 82581231Snyan else /* backward compatibility */ 82681231Snyan v0 = cattrs[v0 & 0x3]; 82781231Snyan sc_change_cursor_shape(scp, v0, -1, -1); 82881231Snyan break; 82981231Snyan case 2: 83081231Snyan v2 = 0; 83181231Snyan v0 &= 0x1f; /* backward compatibility */ 83281231Snyan v1 &= 0x1f; 83381231Snyan /* FALL THROUGH */ 83481231Snyan case 3: /* base and height */ 83581231Snyan if (v2 == 0) /* count from top */ 83681231Snyan sc_change_cursor_shape(scp, -1, 83781231Snyan scp->font_size - v1 - 1, 83881231Snyan v1 - v0 + 1); 83981231Snyan else if (v2 == 1) /* count from bottom */ 84081231Snyan sc_change_cursor_shape(scp, -1, 84181231Snyan v0, v1 - v0 + 1); 84281231Snyan break; 84358381Snyan } 84458381Snyan splx(i); 84558381Snyan break; 84656337Skato 84764021Snyan case 'F': /* set adapter foreground */ 84858381Snyan if (tcp->num_param == 1) { 84958381Snyan tcp->attr_mask &= ~FG_CHANGED; 85088392Snyan tcp->cur_color.fg = tcp->std_color.fg 85188392Snyan = tcp->param[0] & 0x0f; 85258381Snyan tcp->cur_attr = mask2attr(tcp); 85358381Snyan } 85458381Snyan break; 85556337Skato 85664021Snyan case 'G': /* set adapter background */ 85758381Snyan if (tcp->num_param == 1) { 85858381Snyan tcp->attr_mask &= ~BG_CHANGED; 85988392Snyan tcp->cur_color.bg = tcp->std_color.bg 86088392Snyan = tcp->param[0] & 0x0f; 86158381Snyan tcp->cur_attr = mask2attr(tcp); 86258381Snyan } 86358381Snyan break; 86456337Skato 86564021Snyan case 'H': /* set adapter reverse foreground */ 86658381Snyan if (tcp->num_param == 1) { 86758381Snyan tcp->rev_color.fg = tcp->param[0] & 0x0f; 86858381Snyan tcp->cur_attr = mask2attr(tcp); 86958381Snyan } 87058381Snyan break; 87156337Skato 87264021Snyan case 'I': /* set adapter reverse background */ 87358381Snyan if (tcp->num_param == 1) { 87458381Snyan tcp->rev_color.bg = tcp->param[0] & 0x0f; 87558381Snyan tcp->cur_attr = mask2attr(tcp); 87658381Snyan } 87758381Snyan break; 87881231Snyan 87981231Snyan case 'S': /* set local/temporary cursor type & shape */ 88081231Snyan i = spltty(); 88181231Snyan n = tcp->num_param; 88281231Snyan v0 = tcp->param[0]; 88381231Snyan switch (n) { 88481231Snyan case 0: 88581231Snyan v0 = 0; 88681231Snyan /* FALL THROUGH */ 88781231Snyan case 1: 888298352Spfg if (v0 < nitems(tcattrs)) 88981231Snyan sc_change_cursor_shape(scp, 89081231Snyan tcattrs[v0], -1, -1); 89181231Snyan break; 89281231Snyan } 89381231Snyan splx(i); 89481231Snyan break; 89558381Snyan } 896153110Sru#ifdef notyet 89758381Snyan } else if (tcp->esc == 4) { /* seen ESC Q */ 89858381Snyan /* to be filled */ 89956337Skato#endif 90058381Snyan } else if (tcp->esc == 5) { /* seen ESC ( */ 90158381Snyan switch (c) { 90258381Snyan case 'B': /* iso-2022: desginate ASCII into G0 */ 90358381Snyan break; 90458381Snyan /* other items to be filled */ 90558381Snyan default: 90658381Snyan break; 90758381Snyan } 90856337Skato } 90958381Snyan tcp->esc = 0; 91056337Skato} 91156337Skato 91256337Skatostatic void 913332815Snyanscterm_puts(scr_stat *scp, u_char *buf, int len) 91456337Skato{ 91588392Snyan term_stat *tcp; 91688392Snyan u_char *ptr; 91756337Skato#ifdef KANJI 91856337Skato u_short kanji_code; 91956337Skato#endif 92056337Skato 92188392Snyan tcp = scp->ts; 92288392Snyan ptr = buf; 92356337Skatooutloop: 92458381Snyan scp->sc->write_in_progress++; 92556337Skato 92658381Snyan if (tcp->esc) { 92758381Snyan scterm_scan_esc(scp, tcp, *ptr++); 92858381Snyan len--; 92958381Snyan } else if (PRINTABLE(*ptr)) { /* Print only printables */ 93058381Snyan vm_offset_t p; 93158381Snyan u_char *map; 93258381Snyan int attr; 93358381Snyan int i; 93490465Snyan int cnt; 93556337Skato#ifdef KANJI 93658381Snyan u_char c; 93756337Skato#endif 93856337Skato 93958381Snyan p = sc_vtb_pointer(&scp->vtb, scp->cursor_pos); 94058381Snyan map = scp->sc->scr_map; 94158381Snyan attr = tcp->cur_attr; 94256337Skato 94356337Skato#ifdef KANJI 94458381Snyan c = *ptr; 94558381Snyan if (tcp->kanji_1st_char == 0) { 94658381Snyan tcp->kanji_type = iskanji1(tcp->kanji_type, c); 94758381Snyan if (!IS_KTYPE_ASCII_or_HANKAKU(tcp->kanji_type)) { 94858381Snyan /* not Ascii & not HANKAKU */ 94958381Snyan tcp->kanji_1st_char = c; 95058381Snyan goto kanji_end; 95190465Snyan } else if (tcp->kanji_type == KTYPE_ASCII) { 95290465Snyan cnt = imin(len, scp->xsize - scp->xpos); 95390465Snyan i = cnt; 95490465Snyan do { 95590465Snyan p = sc_vtb_putchar(&scp->vtb, p, map[c], attr); 95690465Snyan c = *++ptr; 95790465Snyan --i; 95890465Snyan } while (i > 0 && PRINTABLE(c) && 95990465Snyan iskanji1(tcp->kanji_type, c) == KTYPE_ASCII); 96090465Snyan 96190465Snyan len -= cnt - i; 96290465Snyan mark_for_update(scp, scp->cursor_pos); 96390465Snyan scp->cursor_pos += cnt - i; 96490465Snyan mark_for_update(scp, scp->cursor_pos - 1); 96590465Snyan scp->xpos += cnt - i; 96690465Snyan KTYPE_MASK_CTRL(tcp->kanji_type); 96790465Snyan goto ascii_end; 96856337Skato } 96958381Snyan } else { 97058381Snyan if ((tcp->kanji_type = 97158381Snyan iskanji2(tcp->kanji_type, c)) & 0xee) { 97258381Snyan /* print kanji on TEXT VRAM */ 97358381Snyan kanji_code = kanji_convert(tcp->kanji_type, c, 97458381Snyan tcp->kanji_1st_char); 97558381Snyan mark_for_update(scp, scp->cursor_pos); 97658381Snyan for (i = 0; i < 2; i++) { 97758381Snyan /* *cursor_pos = (kanji_code | (i*0x80)); */ 97858381Snyan p = sc_vtb_putchar(&scp->vtb, p, 97958381Snyan kanji_code | ((i == 0) ? 0x00 : 0x80), attr); 98058381Snyan ++scp->cursor_pos; 98158381Snyan if (++scp->xpos >= scp->xsize) { 98258381Snyan scp->xpos = 0; 98358381Snyan scp->ypos++; 98458381Snyan } 98558381Snyan } 98658381Snyan mark_for_update(scp, scp->cursor_pos - 1); 98758381Snyan KTYPE_MASK_CTRL(tcp->kanji_type); 98858381Snyan tcp->kanji_1st_char = 0; 98958381Snyan goto kanji_end; 99058381Snyan } else { 99158381Snyan tcp->kanji_1st_char = 0; 99258381Snyan } 99358381Snyan } 99458381Snyan if (IS_KTYPE_KANA(tcp->kanji_type)) 99558381Snyan c |= 0x80; 99656337Skato KTYPE_MASK_CTRL(tcp->kanji_type); 99758381Snyan sc_vtb_putchar(&scp->vtb, p, map[c], attr); 99858381Snyan mark_for_update(scp, scp->cursor_pos); 99958381Snyan mark_for_update(scp, scp->cursor_pos); 100058381Snyan ++scp->cursor_pos; 100158381Snyan ++scp->xpos; 100256337Skatokanji_end: 100358381Snyan ++ptr; 100458381Snyan --len; 100590465Snyanascii_end: 100656337Skato#else /* !KANJI */ 100758381Snyan cnt = imin(len, scp->xsize - scp->xpos); 100858381Snyan i = cnt; 100958381Snyan do { 101058381Snyan /* 101158381Snyan * gcc-2.6.3 generates poor (un)sign extension code. 101258381Snyan * Casting the pointers in the following to volatile should 101358381Snyan * have no effect, but in fact speeds up this inner loop 101458381Snyan * from 26 to 18 cycles (+ cache misses) on i486's. 101558381Snyan */ 101656337Skato#define UCVP(ucp) ((u_char volatile *)(ucp)) 101758381Snyan p = sc_vtb_putchar(&scp->vtb, p, UCVP(map)[*UCVP(ptr)], 101858381Snyan attr); 101958381Snyan ++ptr; 102058381Snyan --i; 102158381Snyan } while (i > 0 && PRINTABLE(*ptr)); 102256337Skato 102358381Snyan len -= cnt - i; 102458381Snyan mark_for_update(scp, scp->cursor_pos); 102558381Snyan scp->cursor_pos += cnt - i; 102658381Snyan mark_for_update(scp, scp->cursor_pos - 1); 102758381Snyan scp->xpos += cnt - i; 102856337Skato#endif /* !KANJI */ 102956337Skato 103058381Snyan if (scp->xpos >= scp->xsize) { 103158381Snyan scp->xpos = 0; 103258381Snyan scp->ypos++; 103356337Skato } 103458381Snyan } else { 103558381Snyan switch (*ptr) { 103658381Snyan case 0x07: 103758381Snyan sc_bell(scp, scp->bell_pitch, scp->bell_duration); 103858381Snyan break; 103956337Skato 104058381Snyan case 0x08: /* non-destructive backspace */ 104158381Snyan if (scp->cursor_pos > 0) { 104258381Snyan mark_for_update(scp, scp->cursor_pos); 104358381Snyan scp->cursor_pos--; 104458381Snyan mark_for_update(scp, scp->cursor_pos); 104558381Snyan if (scp->xpos > 0) 104658381Snyan scp->xpos--; 104758381Snyan else { 104858381Snyan scp->xpos += scp->xsize - 1; 104958381Snyan scp->ypos--; 105058381Snyan } 105158381Snyan } 105258381Snyan break; 105356337Skato 105458381Snyan case 0x09: /* non-destructive tab */ 105558381Snyan mark_for_update(scp, scp->cursor_pos); 105658381Snyan scp->cursor_pos += (8 - scp->xpos % 8u); 105758381Snyan scp->xpos += (8 - scp->xpos % 8u); 105858381Snyan if (scp->xpos >= scp->xsize) { 105958381Snyan scp->xpos = 0; 106058381Snyan scp->ypos++; 106158381Snyan scp->cursor_pos = scp->xsize * scp->ypos; 106258381Snyan } 106358381Snyan mark_for_update(scp, scp->cursor_pos); 106458381Snyan break; 106556337Skato 106658381Snyan case 0x0a: /* newline, same pos */ 106758381Snyan mark_for_update(scp, scp->cursor_pos); 106858381Snyan scp->cursor_pos += scp->xsize; 106958381Snyan mark_for_update(scp, scp->cursor_pos); 107058381Snyan scp->ypos++; 107158381Snyan break; 107256337Skato 107358381Snyan case 0x0c: /* form feed, clears screen */ 107458381Snyan sc_clear_screen(scp); 107558381Snyan break; 107656337Skato 107758381Snyan case 0x0d: /* return, return to pos 0 */ 107858381Snyan mark_for_update(scp, scp->cursor_pos); 107958381Snyan scp->cursor_pos -= scp->xpos; 108058381Snyan mark_for_update(scp, scp->cursor_pos); 108158381Snyan scp->xpos = 0; 108258381Snyan break; 108358381Snyan 108458381Snyan case 0x0e: /* ^N */ 108590467Snyan tcp->kanji_type = KTYPE_JKANA; 108690467Snyan tcp->esc = 0; 108790467Snyan tcp->kanji_1st_char = 0; 108890467Snyan break; 108956337Skato 109058381Snyan case 0x0f: /* ^O */ 109158381Snyan tcp->kanji_type = KTYPE_ASCII; 109258381Snyan tcp->esc = 0; 109358381Snyan tcp->kanji_1st_char = 0; 109458381Snyan break; 109556337Skato 109658381Snyan case 0x1b: /* start escape sequence */ 109758381Snyan tcp->esc = 1; 109858381Snyan tcp->num_param = 0; 109958381Snyan break; 110058381Snyan } 110158381Snyan ptr++; 110258381Snyan len--; 110356337Skato } 110456337Skato 110558381Snyan sc_term_gen_scroll(scp, scp->sc->scr_map[0x20], tcp->cur_attr); 110656337Skato 110758381Snyan scp->sc->write_in_progress--; 110858381Snyan if (len) 110958381Snyan goto outloop; 111056337Skato} 111156337Skato 111256337Skatostatic int 111356337Skatoscterm_ioctl(scr_stat *scp, struct tty *tp, u_long cmd, caddr_t data, 1114181905Sed struct thread *td) 111556337Skato{ 111656337Skato term_stat *tcp = scp->ts; 111756337Skato vid_info_t *vi; 111856337Skato 111956337Skato switch (cmd) { 112056337Skato case GIO_ATTR: /* get current attributes */ 112156337Skato /* FIXME: */ 112256337Skato *(int*)data = (tcp->cur_attr >> 8) & 0xff; 112356337Skato return 0; 112456337Skato case CONS_GETINFO: /* get current (virtual) console info */ 112556337Skato vi = (vid_info_t *)data; 112656337Skato if (vi->size != sizeof(struct vid_info)) 112756337Skato return EINVAL; 112856337Skato vi->mv_norm.fore = tcp->std_color.fg; 112956337Skato vi->mv_norm.back = tcp->std_color.bg; 113056337Skato vi->mv_rev.fore = tcp->rev_color.fg; 113156337Skato vi->mv_rev.back = tcp->rev_color.bg; 113256337Skato /* 113356337Skato * The other fields are filled by the upper routine. XXX 113456337Skato */ 113556337Skato return ENOIOCTL; 113656337Skato } 113756337Skato return ENOIOCTL; 113856337Skato} 113956337Skato 114056337Skatostatic int 114156337Skatoscterm_reset(scr_stat *scp, int code) 114256337Skato{ 114356337Skato /* FIXME */ 114456337Skato return 0; 114556337Skato} 114656337Skato 114756337Skatostatic void 114856337Skatoscterm_default_attr(scr_stat *scp, int color, int rev_color) 114956337Skato{ 115056337Skato term_stat *tcp = scp->ts; 115156337Skato 115256337Skato tcp->dflt_std_color.fg = color & 0x0f; 115356337Skato tcp->dflt_std_color.bg = (color >> 4) & 0x0f; 115456337Skato tcp->dflt_rev_color.fg = rev_color & 0x0f; 115556337Skato tcp->dflt_rev_color.bg = (rev_color >> 4) & 0x0f; 115656337Skato tcp->std_color = tcp->dflt_std_color; 115756337Skato tcp->rev_color = tcp->dflt_rev_color; 115856337Skato tcp->cur_color = tcp->std_color; 115956337Skato tcp->cur_attr = mask2attr(tcp); 116056337Skato} 116156337Skato 116256337Skatostatic void 116356337Skatoscterm_clear(scr_stat *scp) 116456337Skato{ 116556337Skato term_stat *tcp = scp->ts; 116656337Skato 116756337Skato sc_move_cursor(scp, 0, 0); 116856337Skato sc_vtb_clear(&scp->vtb, scp->sc->scr_map[0x20], tcp->cur_attr); 116956337Skato mark_all(scp); 117056337Skato} 117156337Skato 117256337Skatostatic void 117356337Skatoscterm_notify(scr_stat *scp, int event) 117456337Skato{ 117556337Skato switch (event) { 117656337Skato case SC_TE_NOTIFY_VTSWITCH_IN: 117756337Skato break; 117856337Skato case SC_TE_NOTIFY_VTSWITCH_OUT: 117956337Skato break; 118056337Skato } 118156337Skato} 118256337Skato 118356337Skatostatic int 118456337Skatoscterm_input(scr_stat *scp, int c, struct tty *tp) 118556337Skato{ 118656337Skato return FALSE; 118756337Skato} 118856337Skato 1189199171Sedstatic const char * 1190199171Sedscterm_fkeystr(scr_stat *scp, int c) 1191199171Sed{ 1192199171Sed 1193199171Sed return (NULL); 1194199171Sed} 1195199171Sed 119656337Skato/* 119756337Skato * Calculate hardware attributes word using logical attributes mask and 119856337Skato * hardware colors 119956337Skato */ 120056337Skato 120156337Skato/* FIXME */ 120256337Skatostatic int 120356337Skatomask2attr(term_stat *tcp) 120456337Skato{ 120556337Skato int attr, mask = tcp->attr_mask; 120656337Skato 120756337Skato if (mask & REVERSE_ATTR) { 120856337Skato attr = ((mask & FG_CHANGED) ? 120956337Skato tcp->cur_color.bg : tcp->rev_color.fg) | 121056337Skato (((mask & BG_CHANGED) ? 121156337Skato tcp->cur_color.fg : tcp->rev_color.bg) << 4); 121256337Skato } else 121356337Skato attr = tcp->cur_color.fg | (tcp->cur_color.bg << 4); 121456337Skato 121556337Skato /* XXX: underline mapping for Hercules adapter can be better */ 121656337Skato if (mask & (BOLD_ATTR | UNDERLINE_ATTR)) 121756337Skato attr ^= 0x08; 121856337Skato if (mask & BLINK_ATTR) 121956337Skato attr ^= 0x80; 122056337Skato 122156337Skato return (attr << 8); 122256337Skato} 1223