1170754Sdelphij/*- 2170754Sdelphij * Copyright (c) 1999 FreeBSD(98) Porting Team. 3170754Sdelphij * All rights reserved. 4170754Sdelphij * 5170754Sdelphij * Redistribution and use in source and binary forms, with or without 6170754Sdelphij * modification, are permitted provided that the following conditions 7170754Sdelphij * are met: 8170754Sdelphij * 1. Redistributions of source code must retain the above copyright 9170754Sdelphij * notice, this list of conditions and the following disclaimer as 10170754Sdelphij * the first lines of this file unmodified. 11170754Sdelphij * 2. Redistributions in binary form must reproduce the above copyright 12170754Sdelphij * notice, this list of conditions and the following disclaimer in the 13170754Sdelphij * documentation and/or other materials provided with the distribution. 14170754Sdelphij * 15170754Sdelphij * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 16170754Sdelphij * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17170754Sdelphij * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18170754Sdelphij * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 19170754Sdelphij * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20170754Sdelphij * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21170754Sdelphij * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22170754Sdelphij * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23170754Sdelphij * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24170754Sdelphij * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25170754Sdelphij * 26170754Sdelphij * $FreeBSD: releng/11.0/sys/pc98/cbus/scterm-sck.c 298352 2016-04-20 15:45:55Z pfg $ 27170754Sdelphij */ 28170754Sdelphij 29170754Sdelphij#include "opt_syscons.h" 30170754Sdelphij 31170754Sdelphij#include <sys/param.h> 32170754Sdelphij#include <sys/systm.h> 33170754Sdelphij#include <sys/kernel.h> 34170754Sdelphij#include <sys/module.h> 35170754Sdelphij#include <sys/consio.h> 36170754Sdelphij 37170754Sdelphij#include <machine/pc/display.h> 38170754Sdelphij 39170754Sdelphij#include <dev/syscons/syscons.h> 40170754Sdelphij#include <pc98/cbus/sctermvar.h> 41170754Sdelphij 42170754Sdelphij#define MAX_ESC_PAR 5 43170754Sdelphij 44170754Sdelphij#ifdef KANJI 45170754Sdelphij#define IS_KTYPE_ASCII_or_HANKAKU(A) (!((A) & 0xee)) 46170754Sdelphij#define IS_KTYPE_KANA(A) ((A) & 0x11) 47170754Sdelphij#define KTYPE_MASK_CTRL(A) ((A) &= 0xF0) 48170754Sdelphij#endif /* KANJI */ 49170754Sdelphij 50170754Sdelphij/* attribute flags */ 51170754Sdelphijtypedef struct { 52170754Sdelphij u_short fg; /* foreground color */ 53170754Sdelphij u_short bg; /* background color */ 54170754Sdelphij} color_t; 55170754Sdelphij 56170754Sdelphijtypedef struct { 57170754Sdelphij int flags; 58170754Sdelphij#define SCTERM_BUSY (1 << 0) 59170754Sdelphij int esc; 60170754Sdelphij int num_param; 61170754Sdelphij int last_param; 62170754Sdelphij int param[MAX_ESC_PAR]; 63170754Sdelphij int saved_xpos; 64170754Sdelphij int saved_ypos; 65170754Sdelphij 66170754Sdelphij#ifdef KANJI 67170754Sdelphij u_char kanji_1st_char; 68170754Sdelphij u_char kanji_type; 69170754Sdelphij#define KTYPE_ASCII 0 /* ASCII */ 70170754Sdelphij#define KTYPE_KANA 1 /* HANKAKU */ 71170754Sdelphij#define KTYPE_JKANA 0x10 /* JIS HANKAKU */ 72170754Sdelphij#define KTYPE_7JIS 0x20 /* JIS */ 73170754Sdelphij#define KTYPE_SJIS 2 /* Shift JIS */ 74170754Sdelphij#define KTYPE_UJIS 4 /* UJIS */ 75170754Sdelphij#define KTYPE_SUKANA 3 /* Shift JIS or UJIS HANKAKU */ 76170754Sdelphij#define KTYPE_SUJIS 6 /* SHift JIS or UJIS */ 77170754Sdelphij#define KTYPE_KANIN 0x80 /* Kanji Invoke sequence */ 78170754Sdelphij#define KTYPE_ASCIN 0x40 /* ASCII Invoke sequence */ 79170754Sdelphij#endif /* KANJI */ 80170754Sdelphij 81170754Sdelphij int attr_mask; /* current logical attr mask */ 82170754Sdelphij#define NORMAL_ATTR 0x00 83170754Sdelphij#define BLINK_ATTR 0x01 84170754Sdelphij#define BOLD_ATTR 0x02 85170754Sdelphij#define UNDERLINE_ATTR 0x04 86170754Sdelphij#define REVERSE_ATTR 0x08 87170754Sdelphij#define FG_CHANGED 0x10 88170754Sdelphij#define BG_CHANGED 0x20 89170754Sdelphij int cur_attr; /* current hardware attr word */ 90170754Sdelphij color_t cur_color; /* current hardware color */ 91170754Sdelphij color_t std_color; /* normal hardware color */ 92170754Sdelphij color_t rev_color; /* reverse hardware color */ 93170754Sdelphij color_t dflt_std_color; /* default normal color */ 94170754Sdelphij color_t dflt_rev_color; /* default reverse color */ 95170754Sdelphij} term_stat; 96170754Sdelphij 97170754Sdelphijstatic sc_term_init_t scterm_init; 98170754Sdelphijstatic sc_term_term_t scterm_term; 99170754Sdelphijstatic sc_term_puts_t scterm_puts; 100170754Sdelphijstatic sc_term_ioctl_t scterm_ioctl; 101170754Sdelphijstatic sc_term_reset_t scterm_reset; 102170754Sdelphijstatic sc_term_default_attr_t scterm_default_attr; 103170754Sdelphijstatic sc_term_clear_t scterm_clear; 104170754Sdelphijstatic sc_term_notify_t scterm_notify; 105170754Sdelphijstatic sc_term_input_t scterm_input; 106170754Sdelphijstatic sc_term_fkeystr_t scterm_fkeystr; 107170754Sdelphij 108170754Sdelphijstatic sc_term_sw_t sc_term_sc = { 109170754Sdelphij { NULL, NULL }, 110170754Sdelphij "sck", /* emulator name */ 111170754Sdelphij "syscons kanji terminal", /* description */ 112170754Sdelphij "*", /* matching renderer, any :-) */ 113170754Sdelphij sizeof(term_stat), /* softc size */ 114170754Sdelphij 0, 115170754Sdelphij scterm_init, 116170754Sdelphij scterm_term, 117170754Sdelphij scterm_puts, 118170754Sdelphij scterm_ioctl, 119170754Sdelphij scterm_reset, 120170754Sdelphij scterm_default_attr, 121170754Sdelphij scterm_clear, 122170754Sdelphij scterm_notify, 123170754Sdelphij scterm_input, 124170754Sdelphij scterm_fkeystr, 125170754Sdelphij}; 126170754Sdelphij 127170754SdelphijSCTERM_MODULE(sc, sc_term_sc); 128170754Sdelphij 129170754Sdelphijstatic term_stat reserved_term_stat; 130170754Sdelphijstatic int default_kanji = UJIS; 131170754Sdelphijstatic void scterm_scan_esc(scr_stat *scp, term_stat *tcp, 132170754Sdelphij u_char c); 133170754Sdelphijstatic int mask2attr(term_stat *tcp); 134170754Sdelphij 135170754Sdelphij#ifdef KANJI 136170754Sdelphijstatic inline u_char 137170754Sdelphijiskanji1(u_char mode, u_char c) 138170754Sdelphij{ 139170754Sdelphij if (c > 0x80) { 140170754Sdelphij if ((c >= 0xa1) && (c <= 0xdf)) { 141170754Sdelphij if (default_kanji == UJIS) { 142170754Sdelphij /* UJIS */ 143170754Sdelphij return KTYPE_UJIS; 144170754Sdelphij } 145170754Sdelphij if (default_kanji == SJIS) { 146170754Sdelphij /* SJIS HANKAKU */ 147170754Sdelphij return KTYPE_KANA; 148170754Sdelphij } 149170754Sdelphij } 150170754Sdelphij 151170754Sdelphij if (c <= 0x9f) { 152170754Sdelphij if (c == 0x8e) { 153170754Sdelphij /* SJIS or UJIS HANKAKU */ 154170754Sdelphij return KTYPE_SUKANA; 155170754Sdelphij } 156170754Sdelphij 157170754Sdelphij /* SJIS */ 158170754Sdelphij default_kanji = SJIS; 159170754Sdelphij return KTYPE_SJIS; 160170754Sdelphij } 161170754Sdelphij 162170754Sdelphij if ((c >= 0xe0) && (c <= 0xef)) { 163170754Sdelphij /* SJIS or UJIS */ 164170754Sdelphij return KTYPE_SUJIS; 165170754Sdelphij } 166170754Sdelphij 167170754Sdelphij if ((c >= 0xf0) && (c <= 0xfe)) { 168170754Sdelphij /* UJIS */ 169170754Sdelphij default_kanji = UJIS; 170170754Sdelphij return KTYPE_UJIS; 171170754Sdelphij } 172170754Sdelphij } else { 173170754Sdelphij if ((mode == KTYPE_7JIS) && (c >= 0x21) && (c <= 0x7e)) { 174170754Sdelphij /* JIS */ 175170754Sdelphij default_kanji = UJIS; 176170754Sdelphij return KTYPE_7JIS; 177170754Sdelphij } 178170754Sdelphij 179170754Sdelphij if ((mode == KTYPE_JKANA) && (c >= 0x21) && (c <= 0x5f)) { 180170754Sdelphij /* JIS HANKAKU */ 181170754Sdelphij default_kanji = UJIS; 182170754Sdelphij return KTYPE_JKANA; 183170754Sdelphij } 184170754Sdelphij } 185170754Sdelphij 186170754Sdelphij return KTYPE_ASCII; 187170754Sdelphij} 188170754Sdelphij 189170754Sdelphijstatic inline u_char 190170754Sdelphijiskanji2(u_char mode, u_char c) 191170754Sdelphij{ 192170754Sdelphij switch (mode) { 193170754Sdelphij case KTYPE_7JIS: 194170754Sdelphij if ((c >= 0x21) && (c <= 0x7e)) { 195170754Sdelphij /* JIS */ 196170754Sdelphij return KTYPE_7JIS; 197170754Sdelphij } 198170754Sdelphij break; 199170754Sdelphij case KTYPE_SJIS: 200170754Sdelphij if ((c >= 0x40) && (c <= 0xfc) && (c != 0x7f)) { 201170754Sdelphij /* SJIS */ 202170754Sdelphij return KTYPE_SJIS; 203170754Sdelphij } 204170754Sdelphij break; 205170754Sdelphij case KTYPE_UJIS: 206170754Sdelphij if ((c >= 0xa1) && (c <= 0xfe)) { 207170754Sdelphij /* UJIS */ 208170754Sdelphij return KTYPE_UJIS; 209170754Sdelphij } 210170754Sdelphij break; 211170754Sdelphij case KTYPE_SUKANA: 212170754Sdelphij if ((c >= 0xa1) && (c <= 0xdf) && (default_kanji == UJIS)) { 213170754Sdelphij /* UJIS HANKAKU */ 214170754Sdelphij return KTYPE_KANA; 215170754Sdelphij } 216170754Sdelphij if ((c >= 0x40) && (c <= 0xfc) && (c != 0x7f)) { 217170754Sdelphij /* SJIS */ 218170754Sdelphij default_kanji = SJIS; 219170754Sdelphij return KTYPE_SJIS; 220170754Sdelphij } 221170754Sdelphij break; 222170754Sdelphij case KTYPE_SUJIS: 223170754Sdelphij if ((c >= 0x40) && (c <= 0xa0) && (c != 0x7f)) { 224170754Sdelphij /* SJIS */ 225170754Sdelphij default_kanji = SJIS; 226170754Sdelphij return KTYPE_SJIS; 227170754Sdelphij } 228170754Sdelphij if ((c == 0xfd) || (c == 0xfe)) { 229170754Sdelphij /* UJIS */ 230170754Sdelphij default_kanji = UJIS; 231170754Sdelphij return KTYPE_UJIS; 232170754Sdelphij } 233170754Sdelphij if ((c >= 0xa1) && (c <= 0xfc)) { 234170754Sdelphij if (default_kanji == SJIS) 235170754Sdelphij return KTYPE_SJIS; 236170754Sdelphij if (default_kanji == UJIS) 237170754Sdelphij return KTYPE_UJIS; 238170754Sdelphij } 239170754Sdelphij break; 240170754Sdelphij } 241170754Sdelphij 242170754Sdelphij return KTYPE_ASCII; 243170754Sdelphij} 244170754Sdelphij 245170754Sdelphij/* 246170754Sdelphij * JIS X0208-83 keisen conversion table 247170754Sdelphij */ 248170754Sdelphijstatic u_short keiConv[32] = { 249170754Sdelphij 0x240c, 0x260c, 0x300c, 0x340c, 0x3c0c, 0x380c, 0x400c, 0x500c, 250170754Sdelphij 0x480c, 0x580c, 0x600c, 0x250c, 0x270c, 0x330c, 0x370c, 0x3f0c, 251170754Sdelphij 0x3b0c, 0x470c, 0x570c, 0x4f0c, 0x5f0c, 0x6f0c, 0x440c, 0x530c, 252170754Sdelphij 0x4c0c, 0x5b0c, 0x630c, 0x410c, 0x540c, 0x490c, 0x5c0c, 0x660c 253170754Sdelphij}; 254170754Sdelphij 255170754Sdelphijstatic u_short 256170754Sdelphijkanji_convert(u_char mode, u_char h, u_char l) 257170754Sdelphij{ 258170754Sdelphij u_short tmp, high, low, c; 259170754Sdelphij 260170754Sdelphij high = (u_short) h; 261170754Sdelphij low = (u_short) l; 262170754Sdelphij 263170754Sdelphij switch (mode) { 264170754Sdelphij case KTYPE_SJIS: /* SHIFT JIS */ 265170754Sdelphij if (low >= 0xe0) { 266170754Sdelphij low -= 0x40; 267170754Sdelphij } 268170754Sdelphij low = (low - 0x81) * 2 + 0x21; 269170754Sdelphij if (high > 0x7f) { 270170754Sdelphij high--; 271170754Sdelphij } 272170754Sdelphij if (high > 0x9d) { 273170754Sdelphij low++; 274170754Sdelphij high -= 0x9e - 0x21; 275170754Sdelphij } else { 276170754Sdelphij high -= 0x40 - 0x21; 277170754Sdelphij } 278170754Sdelphij high &= 0x7F; 279170754Sdelphij low &= 0x7F; 280170754Sdelphij tmp = ((high << 8) | low) - 0x20; 281170754Sdelphij break; 282170754Sdelphij case KTYPE_7JIS: /* JIS */ 283170754Sdelphij case KTYPE_UJIS: /* UJIS */ 284170754Sdelphij high &= 0x7F; 285170754Sdelphij low &= 0x7F; 286170754Sdelphij tmp = ((high << 8) | low) - 0x20; 287170754Sdelphij break; 288170754Sdelphij default: 289170754Sdelphij tmp = 0; 290170754Sdelphij break; 291170754Sdelphij } 292170754Sdelphij 293170754Sdelphij /* keisen */ 294170754Sdelphij c = ((tmp & 0xff) << 8) | (tmp >> 8); 295170754Sdelphij /* 0x2821 .. 0x2840 */ 296170754Sdelphij if (0x0821 <= c && c <= 0x0840) 297170754Sdelphij tmp = keiConv[c - 0x0821]; 298170754Sdelphij 299170754Sdelphij return (tmp); 300170754Sdelphij} 301170754Sdelphij#endif /* KANJI */ 302170754Sdelphij 303170754Sdelphijstatic int 304170754Sdelphijscterm_init(scr_stat *scp, void **softc, int code) 305170754Sdelphij{ 306170754Sdelphij term_stat *tcp; 307170754Sdelphij 308170754Sdelphij if (*softc == NULL) { 309170754Sdelphij if (reserved_term_stat.flags & SCTERM_BUSY) 310170754Sdelphij return EINVAL; 311170754Sdelphij *softc = &reserved_term_stat; 312170754Sdelphij } 313170754Sdelphij tcp = *softc; 314170754Sdelphij 315170754Sdelphij switch (code) { 316170754Sdelphij case SC_TE_COLD_INIT: 317170754Sdelphij bzero(tcp, sizeof(*tcp)); 318170754Sdelphij tcp->flags = SCTERM_BUSY; 319170754Sdelphij tcp->esc = 0; 320170754Sdelphij tcp->saved_xpos = -1; 321170754Sdelphij tcp->saved_ypos = -1; 322170754Sdelphij#ifdef KANJI 323170754Sdelphij tcp->kanji_1st_char = 0; 324170754Sdelphij tcp->kanji_type = KTYPE_ASCII; 325170754Sdelphij#endif 326170754Sdelphij tcp->attr_mask = NORMAL_ATTR; 327170754Sdelphij /* XXX */ 328170754Sdelphij tcp->dflt_std_color.fg = SC_NORM_ATTR & 0x0f; 329170754Sdelphij tcp->dflt_std_color.bg = (SC_NORM_ATTR >> 4) & 0x0f; 330170754Sdelphij tcp->dflt_rev_color.fg = SC_NORM_REV_ATTR & 0x0f; 331170754Sdelphij tcp->dflt_rev_color.bg = (SC_NORM_REV_ATTR >> 4) & 0x0f; 332170754Sdelphij tcp->std_color = tcp->dflt_std_color; 333170754Sdelphij tcp->rev_color = tcp->dflt_rev_color; 334170754Sdelphij tcp->cur_color = tcp->std_color; 335170754Sdelphij tcp->cur_attr = mask2attr(tcp); 336170754Sdelphij ++sc_term_sc.te_refcount; 337170754Sdelphij break; 338170754Sdelphij 339170754Sdelphij case SC_TE_WARM_INIT: 340170754Sdelphij tcp->esc = 0; 341170754Sdelphij tcp->saved_xpos = -1; 342170754Sdelphij tcp->saved_ypos = -1; 343170754Sdelphij#if 0 344170754Sdelphij tcp->std_color = tcp->dflt_std_color; 345170754Sdelphij tcp->rev_color = tcp->dflt_rev_color; 346170754Sdelphij#endif 347170754Sdelphij tcp->cur_color = tcp->std_color; 348170754Sdelphij tcp->cur_attr = mask2attr(tcp); 349170754Sdelphij break; 350170754Sdelphij } 351170754Sdelphij 352170754Sdelphij return 0; 353170754Sdelphij} 354170754Sdelphij 355170754Sdelphijstatic int 356170754Sdelphijscterm_term(scr_stat *scp, void **softc) 357170754Sdelphij{ 358170754Sdelphij if (*softc == &reserved_term_stat) { 359170754Sdelphij *softc = NULL; 360170754Sdelphij bzero(&reserved_term_stat, sizeof(reserved_term_stat)); 361170754Sdelphij } 362170754Sdelphij --sc_term_sc.te_refcount; 363170754Sdelphij return 0; 364170754Sdelphij} 365170754Sdelphij 366170754Sdelphijstatic void 367170754Sdelphijscterm_scan_esc(scr_stat *scp, term_stat *tcp, u_char c) 368170754Sdelphij{ 369170754Sdelphij static u_char ansi_col[16] = { 370170754Sdelphij FG_BLACK, FG_RED, FG_GREEN, FG_BROWN, 371170754Sdelphij FG_BLUE, FG_MAGENTA, FG_CYAN, FG_LIGHTGREY, 372170754Sdelphij FG_DARKGREY, FG_LIGHTRED, FG_LIGHTGREEN, FG_YELLOW, 373170754Sdelphij FG_LIGHTBLUE, FG_LIGHTMAGENTA, FG_LIGHTCYAN, FG_WHITE 374170754Sdelphij }; 375170754Sdelphij static int cattrs[] = { 376170754Sdelphij 0, /* block */ 377170754Sdelphij CONS_BLINK_CURSOR, /* blinking block */ 378170754Sdelphij CONS_CHAR_CURSOR, /* underline */ 379170754Sdelphij CONS_CHAR_CURSOR | CONS_BLINK_CURSOR, /* blinking underline */ 380170754Sdelphij CONS_RESET_CURSOR, /* reset to default */ 381170754Sdelphij CONS_HIDDEN_CURSOR, /* hide cursor */ 382170754Sdelphij }; 383170754Sdelphij static int tcattrs[] = { 384170754Sdelphij CONS_RESET_CURSOR | CONS_LOCAL_CURSOR, /* normal */ 385170754Sdelphij CONS_HIDDEN_CURSOR | CONS_LOCAL_CURSOR, /* invisible */ 386170754Sdelphij CONS_BLINK_CURSOR | CONS_LOCAL_CURSOR, /* very visible */ 387170754Sdelphij }; 388170754Sdelphij sc_softc_t *sc; 389170754Sdelphij int v0, v1, v2; 390170754Sdelphij int i, n; 391170754Sdelphij 392170754Sdelphij i = n = 0; 393170754Sdelphij sc = scp->sc; 394170754Sdelphij if (tcp->esc == 1) { /* seen ESC */ 395170754Sdelphij#ifdef KANJI 396170754Sdelphij switch (tcp->kanji_type) { 397170754Sdelphij case KTYPE_KANIN: /* Kanji Invoke sequence */ 398170754Sdelphij switch (c) { 399170754Sdelphij case 'B': 400170754Sdelphij case '@': 401170754Sdelphij tcp->kanji_type = KTYPE_7JIS; 402170754Sdelphij tcp->esc = 0; 403170754Sdelphij tcp->kanji_1st_char = 0; 404170754Sdelphij return; 405170754Sdelphij default: 406170754Sdelphij tcp->kanji_type = KTYPE_ASCII; 407170754Sdelphij tcp->esc = 0; 408170754Sdelphij break; 409170754Sdelphij } 410170754Sdelphij break; 411170754Sdelphij case KTYPE_ASCIN: /* Ascii Invoke sequence */ 412170754Sdelphij switch (c) { 413170754Sdelphij case 'J': 414170754Sdelphij case 'B': 415170754Sdelphij case 'H': 416170754Sdelphij tcp->kanji_type = KTYPE_ASCII; 417170754Sdelphij tcp->esc = 0; 418170754Sdelphij tcp->kanji_1st_char = 0; 419170754Sdelphij return; 420170754Sdelphij case 'I': 421170754Sdelphij tcp->kanji_type = KTYPE_JKANA; 422170754Sdelphij tcp->esc = 0; 423170754Sdelphij tcp->kanji_1st_char = 0; 424170754Sdelphij return; 425170754Sdelphij default: 426170754Sdelphij tcp->kanji_type = KTYPE_ASCII; 427170754Sdelphij tcp->esc = 0; 428170754Sdelphij break; 429170754Sdelphij } 430170754Sdelphij break; 431170754Sdelphij default: 432170754Sdelphij break; 433170754Sdelphij } 434170754Sdelphij#endif 435170754Sdelphij switch (c) { 436170754Sdelphij 437170754Sdelphij case '7': /* Save cursor position */ 438170754Sdelphij tcp->saved_xpos = scp->xpos; 439170754Sdelphij tcp->saved_ypos = scp->ypos; 440170754Sdelphij break; 441170754Sdelphij 442170754Sdelphij case '8': /* Restore saved cursor position */ 443170754Sdelphij if (tcp->saved_xpos >= 0 && tcp->saved_ypos >= 0) 444170754Sdelphij sc_move_cursor(scp, tcp->saved_xpos, 445170754Sdelphij tcp->saved_ypos); 446170754Sdelphij break; 447170754Sdelphij 448170754Sdelphij case '[': /* Start ESC [ sequence */ 449170754Sdelphij tcp->esc = 2; 450170754Sdelphij tcp->last_param = -1; 451170754Sdelphij for (i = tcp->num_param; i < MAX_ESC_PAR; i++) 452170754Sdelphij tcp->param[i] = 1; 453170754Sdelphij tcp->num_param = 0; 454170754Sdelphij return; 455170754Sdelphij 456170754Sdelphij#ifdef KANJI 457170754Sdelphij case '$': /* Kanji Invoke sequence */ 458170754Sdelphij tcp->kanji_type = KTYPE_KANIN; 459170754Sdelphij return; 460170754Sdelphij#endif 461170754Sdelphij 462170754Sdelphij case 'M': /* Move cursor up 1 line, scroll if at top */ 463170754Sdelphij sc_term_up_scroll(scp, 1, sc->scr_map[0x20], 464170754Sdelphij tcp->cur_attr, 0, 0); 465170754Sdelphij break; 466170754Sdelphij#ifdef notyet 467170754Sdelphij case 'Q': 468170754Sdelphij tcp->esc = 4; 469170754Sdelphij return; 470170754Sdelphij#endif 471170754Sdelphij case 'c': /* reset */ 472170754Sdelphij tcp->attr_mask = NORMAL_ATTR; 473170754Sdelphij tcp->cur_color = tcp->std_color 474170754Sdelphij = tcp->dflt_std_color; 475170754Sdelphij tcp->rev_color = tcp->dflt_rev_color; 476170754Sdelphij tcp->cur_attr = mask2attr(tcp); 477170754Sdelphij sc_change_cursor_shape(scp, 478170754Sdelphij CONS_RESET_CURSOR | CONS_LOCAL_CURSOR, -1, -1); 479170754Sdelphij sc_clear_screen(scp); 480170754Sdelphij break; 481170754Sdelphij 482170754Sdelphij case '(': /* iso-2022: designate 94 character set to G0 */ 483170754Sdelphij#ifdef KANJI 484170754Sdelphij tcp->kanji_type = KTYPE_ASCIN; 485170754Sdelphij#else 486170754Sdelphij tcp->esc = 5; 487170754Sdelphij#endif 488170754Sdelphij return; 489170754Sdelphij } 490170754Sdelphij } else if (tcp->esc == 2) { /* seen ESC [ */ 491170754Sdelphij if (c >= '0' && c <= '9') { 492170754Sdelphij if (tcp->num_param < MAX_ESC_PAR) { 493170754Sdelphij if (tcp->last_param != tcp->num_param) { 494170754Sdelphij tcp->last_param = tcp->num_param; 495170754Sdelphij tcp->param[tcp->num_param] = 0; 496170754Sdelphij } else { 497170754Sdelphij tcp->param[tcp->num_param] *= 10; 498170754Sdelphij } 499170754Sdelphij tcp->param[tcp->num_param] += c - '0'; 500170754Sdelphij return; 501170754Sdelphij } 502170754Sdelphij } 503170754Sdelphij tcp->num_param = tcp->last_param + 1; 504170754Sdelphij switch (c) { 505170754Sdelphij 506170754Sdelphij case ';': 507170754Sdelphij if (tcp->num_param < MAX_ESC_PAR) 508170754Sdelphij return; 509170754Sdelphij break; 510170754Sdelphij 511170754Sdelphij case '=': 512170754Sdelphij tcp->esc = 3; 513170754Sdelphij tcp->last_param = -1; 514170754Sdelphij for (i = tcp->num_param; i < MAX_ESC_PAR; i++) 515170754Sdelphij tcp->param[i] = 1; 516170754Sdelphij tcp->num_param = 0; 517170754Sdelphij return; 518170754Sdelphij 519170754Sdelphij case 'A': /* up n rows */ 520170754Sdelphij sc_term_up(scp, tcp->param[0], 0); 521170754Sdelphij break; 522170754Sdelphij 523170754Sdelphij case 'B': /* down n rows */ 524170754Sdelphij sc_term_down(scp, tcp->param[0], 0); 525170754Sdelphij break; 526170754Sdelphij 527170754Sdelphij case 'C': /* right n columns */ 528170754Sdelphij sc_term_right(scp, tcp->param[0]); 529170754Sdelphij break; 530170754Sdelphij 531170754Sdelphij case 'D': /* left n columns */ 532170754Sdelphij sc_term_left(scp, tcp->param[0]); 533170754Sdelphij break; 534170754Sdelphij 535170754Sdelphij case 'E': /* cursor to start of line n lines down */ 536170754Sdelphij n = tcp->param[0]; 537170754Sdelphij if (n < 1) 538170754Sdelphij n = 1; 539170754Sdelphij sc_move_cursor(scp, 0, scp->ypos + n); 540170754Sdelphij break; 541170754Sdelphij 542170754Sdelphij case 'F': /* cursor to start of line n lines up */ 543170754Sdelphij n = tcp->param[0]; 544170754Sdelphij if (n < 1) 545170754Sdelphij n = 1; 546170754Sdelphij sc_move_cursor(scp, 0, scp->ypos - n); 547170754Sdelphij break; 548170754Sdelphij 549170754Sdelphij case 'f': /* Cursor move */ 550170754Sdelphij case 'H': 551170754Sdelphij if (tcp->num_param == 0) 552170754Sdelphij sc_move_cursor(scp, 0, 0); 553170754Sdelphij else if (tcp->num_param == 2) 554170754Sdelphij sc_move_cursor(scp, tcp->param[1] - 1, 555170754Sdelphij tcp->param[0] - 1); 556170754Sdelphij break; 557170754Sdelphij 558170754Sdelphij case 'J': /* Clear all or part of display */ 559170754Sdelphij if (tcp->num_param == 0) 560170754Sdelphij n = 0; 561170754Sdelphij else 562170754Sdelphij n = tcp->param[0]; 563170754Sdelphij sc_term_clr_eos(scp, n, sc->scr_map[0x20], 564170754Sdelphij tcp->cur_attr); 565170754Sdelphij break; 566170754Sdelphij 567170754Sdelphij case 'K': /* Clear all or part of line */ 568170754Sdelphij if (tcp->num_param == 0) 569170754Sdelphij n = 0; 570170754Sdelphij else 571170754Sdelphij n = tcp->param[0]; 572170754Sdelphij sc_term_clr_eol(scp, n, sc->scr_map[0x20], 573170754Sdelphij tcp->cur_attr); 574170754Sdelphij break; 575170754Sdelphij 576170754Sdelphij case 'L': /* Insert n lines */ 577170754Sdelphij sc_term_ins_line(scp, scp->ypos, tcp->param[0], 578170754Sdelphij sc->scr_map[0x20], tcp->cur_attr, 0); 579170754Sdelphij break; 580170754Sdelphij 581170754Sdelphij case 'M': /* Delete n lines */ 582170754Sdelphij sc_term_del_line(scp, scp->ypos, tcp->param[0], 583170754Sdelphij sc->scr_map[0x20], tcp->cur_attr, 0); 584170754Sdelphij break; 585170754Sdelphij 586170754Sdelphij case 'P': /* Delete n chars */ 587170754Sdelphij sc_term_del_char(scp, tcp->param[0], 588170754Sdelphij sc->scr_map[0x20], tcp->cur_attr); 589170754Sdelphij break; 590170754Sdelphij 591170754Sdelphij case '@': /* Insert n chars */ 592170754Sdelphij sc_term_ins_char(scp, tcp->param[0], 593170754Sdelphij sc->scr_map[0x20], tcp->cur_attr); 594170754Sdelphij break; 595170754Sdelphij 596170754Sdelphij case 'S': /* scroll up n lines */ 597170754Sdelphij sc_term_del_line(scp, 0, tcp->param[0], 598170754Sdelphij sc->scr_map[0x20], tcp->cur_attr, 0); 599170754Sdelphij break; 600170754Sdelphij 601170754Sdelphij case 'T': /* scroll down n lines */ 602170754Sdelphij sc_term_ins_line(scp, 0, tcp->param[0], 603170754Sdelphij sc->scr_map[0x20], tcp->cur_attr, 0); 604170754Sdelphij break; 605170754Sdelphij 606170754Sdelphij case 'X': /* erase n characters in line */ 607170754Sdelphij n = tcp->param[0]; 608170754Sdelphij if (n < 1) 609170754Sdelphij n = 1; 610170754Sdelphij if (n > scp->xsize - scp->xpos) 611170754Sdelphij n = scp->xsize - scp->xpos; 612170754Sdelphij sc_vtb_erase(&scp->vtb, scp->cursor_pos, n, 613170754Sdelphij sc->scr_map[0x20], tcp->cur_attr); 614170754Sdelphij mark_for_update(scp, scp->cursor_pos); 615170754Sdelphij mark_for_update(scp, scp->cursor_pos + n - 1); 616170754Sdelphij break; 617170754Sdelphij 618170754Sdelphij case 'Z': /* move n tabs backwards */ 619170754Sdelphij sc_term_backtab(scp, tcp->param[0]); 620170754Sdelphij break; 621170754Sdelphij 622170754Sdelphij case '`': /* move cursor to column n */ 623170754Sdelphij sc_term_col(scp, tcp->param[0]); 624170754Sdelphij break; 625170754Sdelphij 626170754Sdelphij case 'a': /* move cursor n columns to the right */ 627170754Sdelphij sc_term_right(scp, tcp->param[0]); 628170754Sdelphij break; 629170754Sdelphij 630170754Sdelphij case 'd': /* move cursor to row n */ 631170754Sdelphij sc_term_row(scp, tcp->param[0]); 632170754Sdelphij break; 633170754Sdelphij 634170754Sdelphij case 'e': /* move cursor n rows down */ 635170754Sdelphij sc_term_down(scp, tcp->param[0], 0); 636170754Sdelphij break; 637170754Sdelphij 638170754Sdelphij case 'm': /* change attribute */ 639170754Sdelphij if (tcp->num_param == 0) { 640170754Sdelphij tcp->attr_mask = NORMAL_ATTR; 641170754Sdelphij tcp->cur_color = tcp->std_color; 642170754Sdelphij tcp->cur_attr = mask2attr(tcp); 643170754Sdelphij break; 644170754Sdelphij } 645170754Sdelphij for (i = 0; i < tcp->num_param; i++) { 646170754Sdelphij switch (n = tcp->param[i]) { 647170754Sdelphij case 0: /* back to normal */ 648170754Sdelphij tcp->attr_mask = NORMAL_ATTR; 649170754Sdelphij tcp->cur_color = tcp->std_color; 650170754Sdelphij tcp->cur_attr = mask2attr(tcp); 651170754Sdelphij break; 652170754Sdelphij case 1: /* bold */ 653170754Sdelphij tcp->attr_mask |= BOLD_ATTR; 654170754Sdelphij tcp->cur_attr = mask2attr(tcp); 655170754Sdelphij break; 656170754Sdelphij case 4: /* underline */ 657170754Sdelphij tcp->attr_mask |= UNDERLINE_ATTR; 658170754Sdelphij tcp->cur_attr = mask2attr(tcp); 659170754Sdelphij break; 660170754Sdelphij case 5: /* blink */ 661170754Sdelphij tcp->attr_mask |= BLINK_ATTR; 662170754Sdelphij tcp->cur_attr = mask2attr(tcp); 663170754Sdelphij break; 664170754Sdelphij case 7: /* reverse */ 665170754Sdelphij tcp->attr_mask |= REVERSE_ATTR; 666170754Sdelphij tcp->cur_attr = mask2attr(tcp); 667170754Sdelphij break; 668170754Sdelphij case 22: /* remove bold (or dim) */ 669170754Sdelphij tcp->attr_mask &= ~BOLD_ATTR; 670170754Sdelphij tcp->cur_attr = mask2attr(tcp); 671170754Sdelphij break; 672170754Sdelphij case 24: /* remove underline */ 673170754Sdelphij tcp->attr_mask &= ~UNDERLINE_ATTR; 674170754Sdelphij tcp->cur_attr = mask2attr(tcp); 675170754Sdelphij break; 676170754Sdelphij case 25: /* remove blink */ 677170754Sdelphij tcp->attr_mask &= ~BLINK_ATTR; 678 tcp->cur_attr = mask2attr(tcp); 679 break; 680 case 27: /* remove reverse */ 681 tcp->attr_mask &= ~REVERSE_ATTR; 682 tcp->cur_attr = mask2attr(tcp); 683 break; 684 case 30: case 31: /* set ansi fg color */ 685 case 32: case 33: case 34: 686 case 35: case 36: case 37: 687 tcp->attr_mask |= FG_CHANGED; 688 tcp->cur_color.fg = ansi_col[n - 30]; 689 tcp->cur_attr = mask2attr(tcp); 690 break; 691 case 39: /* restore fg color back to normal */ 692 tcp->attr_mask &= ~(FG_CHANGED|BOLD_ATTR); 693 tcp->cur_color.fg = tcp->std_color.fg; 694 tcp->cur_attr = mask2attr(tcp); 695 break; 696 case 40: case 41: /* set ansi bg color */ 697 case 42: case 43: case 44: 698 case 45: case 46: case 47: 699 tcp->attr_mask |= BG_CHANGED; 700 tcp->cur_color.bg = ansi_col[n - 40]; 701 tcp->cur_attr = mask2attr(tcp); 702 break; 703 case 49: /* restore bg color back to normal */ 704 tcp->attr_mask &= ~BG_CHANGED; 705 tcp->cur_color.bg = tcp->std_color.bg; 706 tcp->cur_attr = mask2attr(tcp); 707 break; 708 } 709 } 710 break; 711 712 case 's': /* Save cursor position */ 713 tcp->saved_xpos = scp->xpos; 714 tcp->saved_ypos = scp->ypos; 715 break; 716 717 case 'u': /* Restore saved cursor position */ 718 if (tcp->saved_xpos >= 0 && tcp->saved_ypos >= 0) 719 sc_move_cursor(scp, tcp->saved_xpos, 720 tcp->saved_ypos); 721 break; 722 723 case 'x': 724 if (tcp->num_param == 0) 725 n = 0; 726 else 727 n = tcp->param[0]; 728 switch (n) { 729 case 0: /* reset colors and attributes back to normal */ 730 tcp->attr_mask = NORMAL_ATTR; 731 tcp->cur_color = tcp->std_color 732 = tcp->dflt_std_color; 733 tcp->rev_color = tcp->dflt_rev_color; 734 tcp->cur_attr = mask2attr(tcp); 735 break; 736 case 1: /* set ansi background */ 737 tcp->attr_mask &= ~BG_CHANGED; 738 tcp->cur_color.bg = tcp->std_color.bg 739 = ansi_col[tcp->param[1] & 0x0f]; 740 tcp->cur_attr = mask2attr(tcp); 741 break; 742 case 2: /* set ansi foreground */ 743 tcp->attr_mask &= ~FG_CHANGED; 744 tcp->cur_color.fg = tcp->std_color.fg 745 = ansi_col[tcp->param[1] & 0x0f]; 746 tcp->cur_attr = mask2attr(tcp); 747 break; 748 case 3: /* set adapter attribute directly */ 749 tcp->attr_mask &= ~(FG_CHANGED | BG_CHANGED); 750 tcp->cur_color.fg = tcp->std_color.fg 751 = tcp->param[1] & 0x0f; 752 tcp->cur_color.bg = tcp->std_color.bg 753 = (tcp->param[1] >> 4) & 0x0f; 754 tcp->cur_attr = mask2attr(tcp); 755 break; 756 case 5: /* set ansi reverse background */ 757 tcp->rev_color.bg = ansi_col[tcp->param[1] & 0x0f]; 758 tcp->cur_attr = mask2attr(tcp); 759 break; 760 case 6: /* set ansi reverse foreground */ 761 tcp->rev_color.fg = ansi_col[tcp->param[1] & 0x0f]; 762 tcp->cur_attr = mask2attr(tcp); 763 break; 764 case 7: /* set adapter reverse attribute directly */ 765 tcp->rev_color.fg = tcp->param[1] & 0x0f; 766 tcp->rev_color.bg = (tcp->param[1] >> 4) & 0x0f; 767 tcp->cur_attr = mask2attr(tcp); 768 break; 769 } 770 break; 771 772 case 'z': /* switch to (virtual) console n */ 773 if (tcp->num_param == 1) 774 sc_switch_scr(sc, tcp->param[0]); 775 break; 776 } 777 } else if (tcp->esc == 3) { /* seen ESC [0-9]+ = */ 778 if (c >= '0' && c <= '9') { 779 if (tcp->num_param < MAX_ESC_PAR) { 780 if (tcp->last_param != tcp->num_param) { 781 tcp->last_param = tcp->num_param; 782 tcp->param[tcp->num_param] = 0; 783 } else { 784 tcp->param[tcp->num_param] *= 10; 785 } 786 tcp->param[tcp->num_param] += c - '0'; 787 return; 788 } 789 } 790 tcp->num_param = tcp->last_param + 1; 791 switch (c) { 792 793 case ';': 794 if (tcp->num_param < MAX_ESC_PAR) 795 return; 796 break; 797 798 case 'A': /* set display border color */ 799 if (tcp->num_param == 1) { 800 scp->border=tcp->param[0] & 0xff; 801 if (scp == sc->cur_scp) 802 sc_set_border(scp, scp->border); 803 } 804 break; 805 806 case 'B': /* set bell pitch and duration */ 807 if (tcp->num_param == 2) { 808 scp->bell_pitch = tcp->param[0]; 809 scp->bell_duration = 810 (tcp->param[1] * hz + 99) / 100; 811 } 812 break; 813 814 case 'C': /* set global/parmanent cursor type & shape */ 815 i = spltty(); 816 n = tcp->num_param; 817 v0 = tcp->param[0]; 818 v1 = tcp->param[1]; 819 v2 = tcp->param[2]; 820 switch (n) { 821 case 1: /* flags only */ 822 if (v0 < nitems(cattrs)) 823 v0 = cattrs[v0]; 824 else /* backward compatibility */ 825 v0 = cattrs[v0 & 0x3]; 826 sc_change_cursor_shape(scp, v0, -1, -1); 827 break; 828 case 2: 829 v2 = 0; 830 v0 &= 0x1f; /* backward compatibility */ 831 v1 &= 0x1f; 832 /* FALL THROUGH */ 833 case 3: /* base and height */ 834 if (v2 == 0) /* count from top */ 835 sc_change_cursor_shape(scp, -1, 836 scp->font_size - v1 - 1, 837 v1 - v0 + 1); 838 else if (v2 == 1) /* count from bottom */ 839 sc_change_cursor_shape(scp, -1, 840 v0, v1 - v0 + 1); 841 break; 842 } 843 splx(i); 844 break; 845 846 case 'F': /* set adapter foreground */ 847 if (tcp->num_param == 1) { 848 tcp->attr_mask &= ~FG_CHANGED; 849 tcp->cur_color.fg = tcp->std_color.fg 850 = tcp->param[0] & 0x0f; 851 tcp->cur_attr = mask2attr(tcp); 852 } 853 break; 854 855 case 'G': /* set adapter background */ 856 if (tcp->num_param == 1) { 857 tcp->attr_mask &= ~BG_CHANGED; 858 tcp->cur_color.bg = tcp->std_color.bg 859 = tcp->param[0] & 0x0f; 860 tcp->cur_attr = mask2attr(tcp); 861 } 862 break; 863 864 case 'H': /* set adapter reverse foreground */ 865 if (tcp->num_param == 1) { 866 tcp->rev_color.fg = tcp->param[0] & 0x0f; 867 tcp->cur_attr = mask2attr(tcp); 868 } 869 break; 870 871 case 'I': /* set adapter reverse background */ 872 if (tcp->num_param == 1) { 873 tcp->rev_color.bg = tcp->param[0] & 0x0f; 874 tcp->cur_attr = mask2attr(tcp); 875 } 876 break; 877 878 case 'S': /* set local/temporary cursor type & shape */ 879 i = spltty(); 880 n = tcp->num_param; 881 v0 = tcp->param[0]; 882 switch (n) { 883 case 0: 884 v0 = 0; 885 /* FALL THROUGH */ 886 case 1: 887 if (v0 < nitems(tcattrs)) 888 sc_change_cursor_shape(scp, 889 tcattrs[v0], -1, -1); 890 break; 891 } 892 splx(i); 893 break; 894 } 895#ifdef notyet 896 } else if (tcp->esc == 4) { /* seen ESC Q */ 897 /* to be filled */ 898#endif 899 } else if (tcp->esc == 5) { /* seen ESC ( */ 900 switch (c) { 901 case 'B': /* iso-2022: desginate ASCII into G0 */ 902 break; 903 /* other items to be filled */ 904 default: 905 break; 906 } 907 } 908 tcp->esc = 0; 909} 910 911static void 912scterm_puts(scr_stat *scp, u_char *buf, int len, int kernel) 913{ 914 term_stat *tcp; 915 u_char *ptr; 916#ifdef KANJI 917 u_short kanji_code; 918#endif 919 color_t backup; 920 921 tcp = scp->ts; 922 ptr = buf; 923outloop: 924 scp->sc->write_in_progress++; 925 backup = tcp->cur_color; 926 if (kernel) { 927 tcp->cur_color.fg = SC_KERNEL_CONS_ATTR & 0x0f; 928 tcp->cur_color.bg = (SC_KERNEL_CONS_ATTR >> 4) & 0x0f; 929 } 930 931 if (tcp->esc) { 932 scterm_scan_esc(scp, tcp, *ptr++); 933 len--; 934 } else if (PRINTABLE(*ptr)) { /* Print only printables */ 935 vm_offset_t p; 936 u_char *map; 937 int attr; 938 int i; 939 int cnt; 940#ifdef KANJI 941 u_char c; 942#endif 943 944 p = sc_vtb_pointer(&scp->vtb, scp->cursor_pos); 945 map = scp->sc->scr_map; 946 attr = tcp->cur_attr; 947 948#ifdef KANJI 949 c = *ptr; 950 if (tcp->kanji_1st_char == 0) { 951 tcp->kanji_type = iskanji1(tcp->kanji_type, c); 952 if (!IS_KTYPE_ASCII_or_HANKAKU(tcp->kanji_type)) { 953 /* not Ascii & not HANKAKU */ 954 tcp->kanji_1st_char = c; 955 goto kanji_end; 956 } else if (tcp->kanji_type == KTYPE_ASCII) { 957 cnt = imin(len, scp->xsize - scp->xpos); 958 i = cnt; 959 do { 960 p = sc_vtb_putchar(&scp->vtb, p, map[c], attr); 961 c = *++ptr; 962 --i; 963 } while (i > 0 && PRINTABLE(c) && 964 iskanji1(tcp->kanji_type, c) == KTYPE_ASCII); 965 966 len -= cnt - i; 967 mark_for_update(scp, scp->cursor_pos); 968 scp->cursor_pos += cnt - i; 969 mark_for_update(scp, scp->cursor_pos - 1); 970 scp->xpos += cnt - i; 971 KTYPE_MASK_CTRL(tcp->kanji_type); 972 goto ascii_end; 973 } 974 } else { 975 if ((tcp->kanji_type = 976 iskanji2(tcp->kanji_type, c)) & 0xee) { 977 /* print kanji on TEXT VRAM */ 978 kanji_code = kanji_convert(tcp->kanji_type, c, 979 tcp->kanji_1st_char); 980 mark_for_update(scp, scp->cursor_pos); 981 for (i = 0; i < 2; i++) { 982 /* *cursor_pos = (kanji_code | (i*0x80)); */ 983 p = sc_vtb_putchar(&scp->vtb, p, 984 kanji_code | ((i == 0) ? 0x00 : 0x80), attr); 985 ++scp->cursor_pos; 986 if (++scp->xpos >= scp->xsize) { 987 scp->xpos = 0; 988 scp->ypos++; 989 } 990 } 991 mark_for_update(scp, scp->cursor_pos - 1); 992 KTYPE_MASK_CTRL(tcp->kanji_type); 993 tcp->kanji_1st_char = 0; 994 goto kanji_end; 995 } else { 996 tcp->kanji_1st_char = 0; 997 } 998 } 999 if (IS_KTYPE_KANA(tcp->kanji_type)) 1000 c |= 0x80; 1001 KTYPE_MASK_CTRL(tcp->kanji_type); 1002 sc_vtb_putchar(&scp->vtb, p, map[c], attr); 1003 mark_for_update(scp, scp->cursor_pos); 1004 mark_for_update(scp, scp->cursor_pos); 1005 ++scp->cursor_pos; 1006 ++scp->xpos; 1007kanji_end: 1008 ++ptr; 1009 --len; 1010ascii_end: 1011#else /* !KANJI */ 1012 cnt = imin(len, scp->xsize - scp->xpos); 1013 i = cnt; 1014 do { 1015 /* 1016 * gcc-2.6.3 generates poor (un)sign extension code. 1017 * Casting the pointers in the following to volatile should 1018 * have no effect, but in fact speeds up this inner loop 1019 * from 26 to 18 cycles (+ cache misses) on i486's. 1020 */ 1021#define UCVP(ucp) ((u_char volatile *)(ucp)) 1022 p = sc_vtb_putchar(&scp->vtb, p, UCVP(map)[*UCVP(ptr)], 1023 attr); 1024 ++ptr; 1025 --i; 1026 } while (i > 0 && PRINTABLE(*ptr)); 1027 1028 len -= cnt - i; 1029 mark_for_update(scp, scp->cursor_pos); 1030 scp->cursor_pos += cnt - i; 1031 mark_for_update(scp, scp->cursor_pos - 1); 1032 scp->xpos += cnt - i; 1033#endif /* !KANJI */ 1034 1035 if (scp->xpos >= scp->xsize) { 1036 scp->xpos = 0; 1037 scp->ypos++; 1038 } 1039 } else { 1040 switch (*ptr) { 1041 case 0x07: 1042 sc_bell(scp, scp->bell_pitch, scp->bell_duration); 1043 break; 1044 1045 case 0x08: /* non-destructive backspace */ 1046 if (scp->cursor_pos > 0) { 1047 mark_for_update(scp, scp->cursor_pos); 1048 scp->cursor_pos--; 1049 mark_for_update(scp, scp->cursor_pos); 1050 if (scp->xpos > 0) 1051 scp->xpos--; 1052 else { 1053 scp->xpos += scp->xsize - 1; 1054 scp->ypos--; 1055 } 1056 } 1057 break; 1058 1059 case 0x09: /* non-destructive tab */ 1060 mark_for_update(scp, scp->cursor_pos); 1061 scp->cursor_pos += (8 - scp->xpos % 8u); 1062 scp->xpos += (8 - scp->xpos % 8u); 1063 if (scp->xpos >= scp->xsize) { 1064 scp->xpos = 0; 1065 scp->ypos++; 1066 scp->cursor_pos = scp->xsize * scp->ypos; 1067 } 1068 mark_for_update(scp, scp->cursor_pos); 1069 break; 1070 1071 case 0x0a: /* newline, same pos */ 1072 mark_for_update(scp, scp->cursor_pos); 1073 scp->cursor_pos += scp->xsize; 1074 mark_for_update(scp, scp->cursor_pos); 1075 scp->ypos++; 1076 break; 1077 1078 case 0x0c: /* form feed, clears screen */ 1079 sc_clear_screen(scp); 1080 break; 1081 1082 case 0x0d: /* return, return to pos 0 */ 1083 mark_for_update(scp, scp->cursor_pos); 1084 scp->cursor_pos -= scp->xpos; 1085 mark_for_update(scp, scp->cursor_pos); 1086 scp->xpos = 0; 1087 break; 1088 1089 case 0x0e: /* ^N */ 1090 tcp->kanji_type = KTYPE_JKANA; 1091 tcp->esc = 0; 1092 tcp->kanji_1st_char = 0; 1093 break; 1094 1095 case 0x0f: /* ^O */ 1096 tcp->kanji_type = KTYPE_ASCII; 1097 tcp->esc = 0; 1098 tcp->kanji_1st_char = 0; 1099 break; 1100 1101 case 0x1b: /* start escape sequence */ 1102 tcp->esc = 1; 1103 tcp->num_param = 0; 1104 break; 1105 } 1106 ptr++; 1107 len--; 1108 } 1109 1110 sc_term_gen_scroll(scp, scp->sc->scr_map[0x20], tcp->cur_attr); 1111 1112 if (kernel) 1113 tcp->cur_color = backup; 1114 scp->sc->write_in_progress--; 1115 if (len) 1116 goto outloop; 1117} 1118 1119static int 1120scterm_ioctl(scr_stat *scp, struct tty *tp, u_long cmd, caddr_t data, 1121 struct thread *td) 1122{ 1123 term_stat *tcp = scp->ts; 1124 vid_info_t *vi; 1125 1126 switch (cmd) { 1127 case GIO_ATTR: /* get current attributes */ 1128 /* FIXME: */ 1129 *(int*)data = (tcp->cur_attr >> 8) & 0xff; 1130 return 0; 1131 case CONS_GETINFO: /* get current (virtual) console info */ 1132 vi = (vid_info_t *)data; 1133 if (vi->size != sizeof(struct vid_info)) 1134 return EINVAL; 1135 vi->mv_norm.fore = tcp->std_color.fg; 1136 vi->mv_norm.back = tcp->std_color.bg; 1137 vi->mv_rev.fore = tcp->rev_color.fg; 1138 vi->mv_rev.back = tcp->rev_color.bg; 1139 /* 1140 * The other fields are filled by the upper routine. XXX 1141 */ 1142 return ENOIOCTL; 1143 } 1144 return ENOIOCTL; 1145} 1146 1147static int 1148scterm_reset(scr_stat *scp, int code) 1149{ 1150 /* FIXME */ 1151 return 0; 1152} 1153 1154static void 1155scterm_default_attr(scr_stat *scp, int color, int rev_color) 1156{ 1157 term_stat *tcp = scp->ts; 1158 1159 tcp->dflt_std_color.fg = color & 0x0f; 1160 tcp->dflt_std_color.bg = (color >> 4) & 0x0f; 1161 tcp->dflt_rev_color.fg = rev_color & 0x0f; 1162 tcp->dflt_rev_color.bg = (rev_color >> 4) & 0x0f; 1163 tcp->std_color = tcp->dflt_std_color; 1164 tcp->rev_color = tcp->dflt_rev_color; 1165 tcp->cur_color = tcp->std_color; 1166 tcp->cur_attr = mask2attr(tcp); 1167} 1168 1169static void 1170scterm_clear(scr_stat *scp) 1171{ 1172 term_stat *tcp = scp->ts; 1173 1174 sc_move_cursor(scp, 0, 0); 1175 sc_vtb_clear(&scp->vtb, scp->sc->scr_map[0x20], tcp->cur_attr); 1176 mark_all(scp); 1177} 1178 1179static void 1180scterm_notify(scr_stat *scp, int event) 1181{ 1182 switch (event) { 1183 case SC_TE_NOTIFY_VTSWITCH_IN: 1184 break; 1185 case SC_TE_NOTIFY_VTSWITCH_OUT: 1186 break; 1187 } 1188} 1189 1190static int 1191scterm_input(scr_stat *scp, int c, struct tty *tp) 1192{ 1193 return FALSE; 1194} 1195 1196static const char * 1197scterm_fkeystr(scr_stat *scp, int c) 1198{ 1199 1200 return (NULL); 1201} 1202 1203/* 1204 * Calculate hardware attributes word using logical attributes mask and 1205 * hardware colors 1206 */ 1207 1208/* FIXME */ 1209static int 1210mask2attr(term_stat *tcp) 1211{ 1212 int attr, mask = tcp->attr_mask; 1213 1214 if (mask & REVERSE_ATTR) { 1215 attr = ((mask & FG_CHANGED) ? 1216 tcp->cur_color.bg : tcp->rev_color.fg) | 1217 (((mask & BG_CHANGED) ? 1218 tcp->cur_color.fg : tcp->rev_color.bg) << 4); 1219 } else 1220 attr = tcp->cur_color.fg | (tcp->cur_color.bg << 4); 1221 1222 /* XXX: underline mapping for Hercules adapter can be better */ 1223 if (mask & (BOLD_ATTR | UNDERLINE_ATTR)) 1224 attr ^= 0x08; 1225 if (mask & BLINK_ATTR) 1226 attr ^= 0x80; 1227 1228 return (attr << 8); 1229} 1230