scterm-sck.c revision 57136
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 * $FreeBSD: head/sys/pc98/cbus/scterm-sck.c 57136 2000-02-11 08:54:16Z kato $ 2756337Skato */ 2856337Skato 2956337Skato#include "sc.h" 3056337Skato#include "opt_syscons.h" 3156337Skato 3256337Skato#if NSC > 0 3356337Skato 3456337Skato#include <sys/param.h> 3556337Skato#include <sys/systm.h> 3656337Skato#include <sys/kernel.h> 3756337Skato#include <sys/consio.h> 3856337Skato 3956337Skato#include <machine/pc/display.h> 4056337Skato 4156337Skato#include <dev/syscons/syscons.h> 4256337Skato#include <dev/syscons/sctermvar.h> 4356337Skato 4456337Skato#ifndef SC_DUMB_TERMINAL 4556337Skato 4656337Skato#define MAX_ESC_PAR 5 4756337Skato 4856337Skato#ifdef KANJI 4956337Skato#define IS_KTYPE_ASCII_or_HANKAKU(A) (!((A) & 0xee)) 5056337Skato#define IS_KTYPE_KANA(A) ((A) & 0x11) 5156337Skato#define KTYPE_MASK_CTRL(A) ((A) &= 0xF0) 5256337Skato#endif /* KANJI */ 5356337Skato 5456337Skato/* attribute flags */ 5556337Skatotypedef struct { 5656337Skato u_short fg; /* foreground color */ 5756337Skato u_short bg; /* background color */ 5856337Skato} color_t; 5956337Skato 6056337Skatotypedef struct { 6156337Skato int flags; 6256337Skato#define SCTERM_BUSY (1 << 0) 6356337Skato int esc; 6456337Skato int num_param; 6556337Skato int last_param; 6656337Skato int param[MAX_ESC_PAR]; 6756337Skato int saved_xpos; 6856337Skato int saved_ypos; 6956337Skato 7056337Skato#ifdef KANJI 7156337Skato u_char kanji_1st_char; 7256337Skato u_char kanji_type; 7356337Skato#define KTYPE_ASCII 0 /* ASCII */ 7456337Skato#define KTYPE_KANA 1 /* HANKAKU */ 7556337Skato#define KTYPE_JKANA 0x10 /* JIS HANKAKU */ 7656337Skato#define KTYPE_7JIS 0x20 /* JIS */ 7756337Skato#define KTYPE_SJIS 2 /* Shift JIS */ 7856337Skato#define KTYPE_UJIS 4 /* UJIS */ 7956337Skato#define KTYPE_SUKANA 3 /* Shift JIS or UJIS HANKAKU */ 8056337Skato#define KTYPE_SUJIS 6 /* SHift JIS or UJIS */ 8156337Skato#define KTYPE_KANIN 0x80 /* Kanji Invoke sequence */ 8256337Skato#define KTYPE_ASCIN 0x40 /* ASCII Invoke sequence */ 8356337Skato#endif /* KANJI */ 8456337Skato 8556337Skato int attr_mask; /* current logical attr mask */ 8656337Skato#define NORMAL_ATTR 0x00 8756337Skato#define BLINK_ATTR 0x01 8856337Skato#define BOLD_ATTR 0x02 8956337Skato#define UNDERLINE_ATTR 0x04 9056337Skato#define REVERSE_ATTR 0x08 9156337Skato#define FG_CHANGED 0x10 9256337Skato#define BG_CHANGED 0x20 9356337Skato int cur_attr; /* current hardware attr word */ 9456337Skato color_t cur_color; /* current hardware color */ 9556337Skato color_t std_color; /* normal hardware color */ 9656337Skato color_t rev_color; /* reverse hardware color */ 9756337Skato color_t dflt_std_color; /* default normal color */ 9856337Skato color_t dflt_rev_color; /* default reverse color */ 9956337Skato} term_stat; 10056337Skato 10156337Skatostatic sc_term_init_t scterm_init; 10256337Skatostatic sc_term_term_t scterm_term; 10356337Skatostatic sc_term_puts_t scterm_puts; 10456337Skatostatic sc_term_ioctl_t scterm_ioctl; 10556337Skatostatic sc_term_reset_t scterm_reset; 10656337Skatostatic sc_term_default_attr_t scterm_default_attr; 10756337Skatostatic sc_term_clear_t scterm_clear; 10856337Skatostatic sc_term_notify_t scterm_notify; 10956337Skatostatic sc_term_input_t scterm_input; 11056337Skato 11156337Skatostatic sc_term_sw_t sc_term_sc = { 11256337Skato { NULL, NULL }, 11356337Skato "sck", /* emulator name */ 11456337Skato "syscons kanji terminal", /* description */ 11556337Skato "*", /* matching renderer, any :-) */ 11656337Skato sizeof(term_stat), /* softc size */ 11756337Skato 0, 11856337Skato scterm_init, 11956337Skato scterm_term, 12056337Skato scterm_puts, 12156337Skato scterm_ioctl, 12256337Skato scterm_reset, 12356337Skato scterm_default_attr, 12456337Skato scterm_clear, 12556337Skato scterm_notify, 12656337Skato scterm_input, 12756337Skato}; 12856337Skato 12956337SkatoSCTERM_MODULE(sc, sc_term_sc); 13056337Skato 13156337Skatostatic term_stat reserved_term_stat; 13256337Skatostatic int default_kanji = UJIS; 13356337Skatostatic void scterm_scan_esc(scr_stat *scp, term_stat *tcp, 13456337Skato u_char c); 13556337Skatostatic int mask2attr(term_stat *tcp); 13656337Skatostatic u_char iskanji1(u_char mode, u_char c); 13756337Skatostatic u_char iskanji2(u_char mode, u_char c); 13856337Skatostatic u_short kanji_convert(u_char mode, u_char h, u_char l); 13956337Skato 14056337Skatostatic int 14156337Skatoscterm_init(scr_stat *scp, void **softc, int code) 14256337Skato{ 14356337Skato term_stat *tcp; 14456337Skato 14556337Skato if (*softc == NULL) { 14656337Skato if (reserved_term_stat.flags & SCTERM_BUSY) 14756337Skato return EINVAL; 14856337Skato *softc = &reserved_term_stat; 14956337Skato } 15056337Skato tcp = *softc; 15156337Skato 15256337Skato switch (code) { 15356337Skato case SC_TE_COLD_INIT: 15456337Skato bzero(tcp, sizeof(*tcp)); 15556337Skato tcp->flags = SCTERM_BUSY; 15656337Skato tcp->esc = 0; 15756337Skato tcp->saved_xpos = -1; 15856337Skato tcp->saved_ypos = -1; 15956337Skato 16056337Skato#ifdef KANJI 16156337Skato tcp->kanji_1st_char = 0; 16256337Skato tcp->kanji_type = KTYPE_ASCII; 16356337Skato#endif 16456337Skato 16556337Skato tcp->attr_mask = NORMAL_ATTR; 16656337Skato /* XXX */ 16756337Skato tcp->dflt_std_color.fg = SC_NORM_ATTR & 0x0f; 16856337Skato tcp->dflt_std_color.bg = (SC_NORM_ATTR >> 4) & 0x0f; 16956337Skato tcp->dflt_rev_color.fg = SC_NORM_REV_ATTR & 0x0f; 17056337Skato tcp->dflt_rev_color.bg = (SC_NORM_REV_ATTR >> 4) & 0x0f; 17156337Skato tcp->std_color = tcp->dflt_std_color; 17256337Skato tcp->rev_color = tcp->dflt_rev_color; 17356337Skato tcp->cur_color = tcp->std_color; 17456337Skato tcp->cur_attr = mask2attr(tcp); 17556337Skato ++sc_term_sc.te_refcount; 17656337Skato break; 17756337Skato 17856337Skato case SC_TE_WARM_INIT: 17956337Skato tcp->esc = 0; 18056337Skato tcp->saved_xpos = -1; 18156337Skato tcp->saved_ypos = -1; 18257136Skato#if 0 18356337Skato tcp->std_color = tcp->dflt_std_color; 18456337Skato tcp->rev_color = tcp->dflt_rev_color; 18557136Skato#endif 18656337Skato tcp->cur_color = tcp->std_color; 18756337Skato tcp->cur_attr = mask2attr(tcp); 18856337Skato break; 18956337Skato } 19056337Skato 19156337Skato return 0; 19256337Skato} 19356337Skato 19456337Skatostatic int 19556337Skatoscterm_term(scr_stat *scp, void **softc) 19656337Skato{ 19756337Skato if (*softc == &reserved_term_stat) { 19856337Skato *softc = NULL; 19956337Skato bzero(&reserved_term_stat, sizeof(reserved_term_stat)); 20056337Skato } 20156337Skato --sc_term_sc.te_refcount; 20256337Skato return 0; 20356337Skato} 20456337Skato 20556337Skatostatic void 20656337Skatoscterm_scan_esc(scr_stat *scp, term_stat *tcp, u_char c) 20756337Skato{ 20856337Skato static u_char ansi_col[16] = { 20956337Skato FG_BLACK, FG_RED, FG_GREEN, FG_BROWN, 21056337Skato FG_BLUE, FG_MAGENTA, FG_CYAN, FG_LIGHTGREY, 21156337Skato FG_DARKGREY, FG_LIGHTRED, FG_LIGHTGREEN, FG_YELLOW, 21256337Skato FG_LIGHTBLUE, FG_LIGHTMAGENTA, FG_LIGHTCYAN, FG_WHITE 21356337Skato }; 21456337Skato sc_softc_t *sc; 21556337Skato int i, n; 21656337Skato 21756337Skato i = n = 0; 21856337Skato sc = scp->sc; 21956337Skato if (tcp->esc == 1) { /* seen ESC */ 22056337Skato switch (c) { 22156337Skato 22256337Skato case '7': /* Save cursor position */ 22356337Skato tcp->saved_xpos = scp->xpos; 22456337Skato tcp->saved_ypos = scp->ypos; 22556337Skato break; 22656337Skato 22756337Skato case '8': /* Restore saved cursor position */ 22856337Skato if (tcp->saved_xpos >= 0 && tcp->saved_ypos >= 0) 22956337Skato sc_move_cursor(scp, tcp->saved_xpos, tcp->saved_ypos); 23056337Skato break; 23156337Skato 23256337Skato case '[': /* Start ESC [ sequence */ 23356337Skato tcp->esc = 2; 23456337Skato tcp->last_param = -1; 23556337Skato for (i = tcp->num_param; i < MAX_ESC_PAR; i++) 23656337Skato tcp->param[i] = 1; 23756337Skato tcp->num_param = 0; 23856337Skato return; 23956337Skato 24056337Skato#ifdef KANJI 24156337Skato case '$': /* Kanji Invoke sequence */ 24256337Skato tcp->kanji_type = KTYPE_KANIN; 24356337Skato return; 24456337Skato#endif 24556337Skato 24656337Skato case 'M': /* Move cursor up 1 line, scroll if at top */ 24756337Skato sc_term_up_scroll(scp, 1, sc->scr_map[0x20], tcp->cur_attr, 0, 0); 24856337Skato break; 24956337Skato#if notyet 25056337Skato case 'Q': 25156337Skato tcp->esc = 4; 25256337Skato return; 25356337Skato#endif 25456337Skato case 'c': /* Clear screen & home */ 25556337Skato sc_clear_screen(scp); 25656337Skato break; 25756337Skato 25856337Skato case '(': /* iso-2022: designate 94 character set to G0 */ 25956337Skato#ifdef KANJI 26056337Skato tcp->kanji_type = KTYPE_ASCIN; 26156337Skato#else 26256337Skato tcp->esc = 5; 26356337Skato#endif 26456337Skato return; 26556337Skato } 26656337Skato } 26756337Skato else if (tcp->esc == 2) { /* seen ESC [ */ 26856337Skato if (c >= '0' && c <= '9') { 26956337Skato if (tcp->num_param < MAX_ESC_PAR) { 27056337Skato if (tcp->last_param != tcp->num_param) { 27156337Skato tcp->last_param = tcp->num_param; 27256337Skato tcp->param[tcp->num_param] = 0; 27356337Skato } else { 27456337Skato tcp->param[tcp->num_param] *= 10; 27556337Skato } 27656337Skato tcp->param[tcp->num_param] += c - '0'; 27756337Skato return; 27856337Skato } 27956337Skato } 28056337Skato tcp->num_param = tcp->last_param + 1; 28156337Skato switch (c) { 28256337Skato 28356337Skato case ';': 28456337Skato if (tcp->num_param < MAX_ESC_PAR) 28556337Skato return; 28656337Skato break; 28756337Skato 28856337Skato case '=': 28956337Skato tcp->esc = 3; 29056337Skato tcp->last_param = -1; 29156337Skato for (i = tcp->num_param; i < MAX_ESC_PAR; i++) 29256337Skato tcp->param[i] = 1; 29356337Skato tcp->num_param = 0; 29456337Skato return; 29556337Skato 29656337Skato case 'A': /* up n rows */ 29756337Skato sc_term_up(scp, tcp->param[0], 0); 29856337Skato break; 29956337Skato 30056337Skato case 'B': /* down n rows */ 30156337Skato sc_term_down(scp, tcp->param[0], 0); 30256337Skato break; 30356337Skato 30456337Skato case 'C': /* right n columns */ 30556337Skato sc_term_right(scp, tcp->param[0]); 30656337Skato break; 30756337Skato 30856337Skato case 'D': /* left n columns */ 30956337Skato sc_term_left(scp, tcp->param[0]); 31056337Skato break; 31156337Skato 31256337Skato case 'E': /* cursor to start of line n lines down */ 31356337Skato n = tcp->param[0]; if (n < 1) n = 1; 31456337Skato sc_move_cursor(scp, 0, scp->ypos + n); 31556337Skato break; 31656337Skato 31756337Skato case 'F': /* cursor to start of line n lines up */ 31856337Skato n = tcp->param[0]; if (n < 1) n = 1; 31956337Skato sc_move_cursor(scp, 0, scp->ypos - n); 32056337Skato break; 32156337Skato 32256337Skato case 'f': /* Cursor move */ 32356337Skato case 'H': 32456337Skato if (tcp->num_param == 0) 32556337Skato sc_move_cursor(scp, 0, 0); 32656337Skato else if (tcp->num_param == 2) 32756337Skato sc_move_cursor(scp, tcp->param[1] - 1, tcp->param[0] - 1); 32856337Skato break; 32956337Skato 33056337Skato case 'J': /* Clear all or part of display */ 33156337Skato if (tcp->num_param == 0) 33256337Skato n = 0; 33356337Skato else 33456337Skato n = tcp->param[0]; 33556337Skato sc_term_clr_eos(scp, n, sc->scr_map[0x20], tcp->cur_attr); 33656337Skato break; 33756337Skato 33856337Skato case 'K': /* Clear all or part of line */ 33956337Skato if (tcp->num_param == 0) 34056337Skato n = 0; 34156337Skato else 34256337Skato n = tcp->param[0]; 34356337Skato sc_term_clr_eol(scp, n, sc->scr_map[0x20], tcp->cur_attr); 34456337Skato break; 34556337Skato 34656337Skato case 'L': /* Insert n lines */ 34756337Skato sc_term_ins_line(scp, scp->ypos, tcp->param[0], 34856337Skato sc->scr_map[0x20], tcp->cur_attr, 0); 34956337Skato break; 35056337Skato 35156337Skato case 'M': /* Delete n lines */ 35256337Skato sc_term_del_line(scp, scp->ypos, tcp->param[0], 35356337Skato sc->scr_map[0x20], tcp->cur_attr, 0); 35456337Skato break; 35556337Skato 35656337Skato case 'P': /* Delete n chars */ 35756337Skato sc_term_del_char(scp, tcp->param[0], 35856337Skato sc->scr_map[0x20], tcp->cur_attr); 35956337Skato break; 36056337Skato 36156337Skato case '@': /* Insert n chars */ 36256337Skato sc_term_ins_char(scp, tcp->param[0], 36356337Skato sc->scr_map[0x20], tcp->cur_attr); 36456337Skato break; 36556337Skato 36656337Skato case 'S': /* scroll up n lines */ 36756337Skato sc_term_del_line(scp, 0, tcp->param[0], 36856337Skato sc->scr_map[0x20], tcp->cur_attr, 0); 36956337Skato break; 37056337Skato 37156337Skato case 'T': /* scroll down n lines */ 37256337Skato sc_term_ins_line(scp, 0, tcp->param[0], 37356337Skato sc->scr_map[0x20], tcp->cur_attr, 0); 37456337Skato break; 37556337Skato 37656337Skato case 'X': /* erase n characters in line */ 37756337Skato n = tcp->param[0]; if (n < 1) n = 1; 37856337Skato if (n > scp->xsize - scp->xpos) 37956337Skato n = scp->xsize - scp->xpos; 38056337Skato sc_vtb_erase(&scp->vtb, scp->cursor_pos, n, 38156337Skato sc->scr_map[0x20], tcp->cur_attr); 38256337Skato mark_for_update(scp, scp->cursor_pos); 38356337Skato mark_for_update(scp, scp->cursor_pos + n - 1); 38456337Skato break; 38556337Skato 38656337Skato case 'Z': /* move n tabs backwards */ 38756337Skato sc_term_backtab(scp, tcp->param[0]); 38856337Skato break; 38956337Skato 39056337Skato case '`': /* move cursor to column n */ 39156337Skato sc_term_col(scp, tcp->param[0]); 39256337Skato break; 39356337Skato 39456337Skato case 'a': /* move cursor n columns to the right */ 39556337Skato sc_term_right(scp, tcp->param[0]); 39656337Skato break; 39756337Skato 39856337Skato case 'd': /* move cursor to row n */ 39956337Skato sc_term_row(scp, tcp->param[0]); 40056337Skato break; 40156337Skato 40256337Skato case 'e': /* move cursor n rows down */ 40356337Skato sc_term_down(scp, tcp->param[0], 0); 40456337Skato break; 40556337Skato 40656337Skato case 'm': /* change attribute */ 40756337Skato if (tcp->num_param == 0) { 40856337Skato tcp->attr_mask = NORMAL_ATTR; 40956337Skato tcp->cur_color = tcp->std_color; 41056337Skato tcp->cur_attr = mask2attr(tcp); 41156337Skato break; 41256337Skato } 41356337Skato for (i = 0; i < tcp->num_param; i++) { 41456337Skato switch (n = tcp->param[i]) { 41556337Skato case 0: /* back to normal */ 41656337Skato tcp->attr_mask = NORMAL_ATTR; 41756337Skato tcp->cur_color = tcp->std_color; 41856337Skato tcp->cur_attr = mask2attr(tcp); 41956337Skato break; 42056337Skato case 1: /* bold */ 42156337Skato tcp->attr_mask |= BOLD_ATTR; 42256337Skato tcp->cur_attr = mask2attr(tcp); 42356337Skato break; 42456337Skato case 4: /* underline */ 42556337Skato tcp->attr_mask |= UNDERLINE_ATTR; 42656337Skato tcp->cur_attr = mask2attr(tcp); 42756337Skato break; 42856337Skato case 5: /* blink */ 42956337Skato tcp->attr_mask |= BLINK_ATTR; 43056337Skato tcp->cur_attr = mask2attr(tcp); 43156337Skato break; 43256337Skato case 7: /* reverse video */ 43356337Skato tcp->attr_mask |= REVERSE_ATTR; 43456337Skato tcp->cur_attr = mask2attr(tcp); 43556337Skato break; 43656337Skato case 30: case 31: /* set fg color */ 43756337Skato case 32: case 33: case 34: 43856337Skato case 35: case 36: case 37: 43956337Skato tcp->attr_mask |= FG_CHANGED; 44056337Skato tcp->cur_color.fg = ansi_col[n - 30]; 44156337Skato tcp->cur_attr = mask2attr(tcp); 44256337Skato break; 44356337Skato case 40: case 41: /* set bg color */ 44456337Skato case 42: case 43: case 44: 44556337Skato case 45: case 46: case 47: 44656337Skato tcp->attr_mask |= BG_CHANGED; 44756337Skato tcp->cur_color.bg = ansi_col[n - 40]; 44856337Skato tcp->cur_attr = mask2attr(tcp); 44956337Skato break; 45056337Skato } 45156337Skato } 45256337Skato break; 45356337Skato 45456337Skato case 's': /* Save cursor position */ 45556337Skato tcp->saved_xpos = scp->xpos; 45656337Skato tcp->saved_ypos = scp->ypos; 45756337Skato break; 45856337Skato 45956337Skato case 'u': /* Restore saved cursor position */ 46056337Skato if (tcp->saved_xpos >= 0 && tcp->saved_ypos >= 0) 46156337Skato sc_move_cursor(scp, tcp->saved_xpos, tcp->saved_ypos); 46256337Skato break; 46356337Skato 46456337Skato case 'x': 46556337Skato if (tcp->num_param == 0) 46656337Skato n = 0; 46756337Skato else 46856337Skato n = tcp->param[0]; 46956337Skato switch (n) { 47056337Skato case 0: /* reset attributes */ 47156337Skato tcp->attr_mask = NORMAL_ATTR; 47256337Skato tcp->cur_color = tcp->std_color = tcp->dflt_std_color; 47356337Skato tcp->rev_color = tcp->dflt_rev_color; 47456337Skato tcp->cur_attr = mask2attr(tcp); 47556337Skato break; 47656337Skato case 1: /* set ansi background */ 47756337Skato tcp->attr_mask &= ~BG_CHANGED; 47856337Skato tcp->cur_color.bg = tcp->std_color.bg = 47956337Skato ansi_col[tcp->param[1] & 0x0f]; 48056337Skato tcp->cur_attr = mask2attr(tcp); 48156337Skato break; 48256337Skato case 2: /* set ansi foreground */ 48356337Skato tcp->attr_mask &= ~FG_CHANGED; 48456337Skato tcp->cur_color.fg = tcp->std_color.fg = 48556337Skato ansi_col[tcp->param[1] & 0x0f]; 48656337Skato tcp->cur_attr = mask2attr(tcp); 48756337Skato break; 48856337Skato case 3: /* set ansi attribute directly */ 48956337Skato tcp->attr_mask &= ~(FG_CHANGED | BG_CHANGED); 49056337Skato tcp->cur_color.fg = tcp->std_color.fg = 49156337Skato tcp->param[1] & 0x0f; 49256337Skato tcp->cur_color.bg = tcp->std_color.bg = 49356337Skato (tcp->param[1] >> 4) & 0x0f; 49456337Skato tcp->cur_attr = mask2attr(tcp); 49556337Skato break; 49656337Skato case 5: /* set ansi reverse video background */ 49756337Skato tcp->rev_color.bg = ansi_col[tcp->param[1] & 0x0f]; 49856337Skato tcp->cur_attr = mask2attr(tcp); 49956337Skato break; 50056337Skato case 6: /* set ansi reverse video foreground */ 50156337Skato tcp->rev_color.fg = ansi_col[tcp->param[1] & 0x0f]; 50256337Skato tcp->cur_attr = mask2attr(tcp); 50356337Skato break; 50456337Skato case 7: /* set ansi reverse video directly */ 50556337Skato tcp->rev_color.fg = tcp->param[1] & 0x0f; 50656337Skato tcp->rev_color.bg = (tcp->param[1] >> 4) & 0x0f; 50756337Skato tcp->cur_attr = mask2attr(tcp); 50856337Skato break; 50956337Skato } 51056337Skato break; 51156337Skato 51256337Skato case 'z': /* switch to (virtual) console n */ 51356337Skato if (tcp->num_param == 1) 51456337Skato sc_switch_scr(sc, tcp->param[0]); 51556337Skato break; 51656337Skato } 51756337Skato } 51856337Skato else if (tcp->esc == 3) { /* seen ESC [0-9]+ = */ 51956337Skato if (c >= '0' && c <= '9') { 52056337Skato if (tcp->num_param < MAX_ESC_PAR) { 52156337Skato if (tcp->last_param != tcp->num_param) { 52256337Skato tcp->last_param = tcp->num_param; 52356337Skato tcp->param[tcp->num_param] = 0; 52456337Skato } else { 52556337Skato tcp->param[tcp->num_param] *= 10; 52656337Skato } 52756337Skato tcp->param[tcp->num_param] += c - '0'; 52856337Skato return; 52956337Skato } 53056337Skato } 53156337Skato tcp->num_param = tcp->last_param + 1; 53256337Skato switch (c) { 53356337Skato 53456337Skato case ';': 53556337Skato if (tcp->num_param < MAX_ESC_PAR) 53656337Skato return; 53756337Skato break; 53856337Skato 53956337Skato case 'A': /* set display border color */ 54056337Skato if (tcp->num_param == 1) { 54156337Skato scp->border=tcp->param[0] & 0xff; 54256337Skato if (scp == sc->cur_scp) 54356337Skato sc_set_border(scp, scp->border); 54456337Skato } 54556337Skato break; 54656337Skato 54756337Skato case 'B': /* set bell pitch and duration */ 54856337Skato if (tcp->num_param == 2) { 54956337Skato scp->bell_pitch = tcp->param[0]; 55056337Skato scp->bell_duration = tcp->param[1]; 55156337Skato } 55256337Skato break; 55356337Skato 55456337Skato case 'C': /* set cursor type & shape */ 55557136Skato i = spltty(); 55656337Skato if (!ISGRAPHSC(sc->cur_scp)) 55756337Skato sc_remove_cursor_image(sc->cur_scp); 55856337Skato if (tcp->num_param == 1) { 55956337Skato if (tcp->param[0] & 0x01) 56056337Skato sc->flags |= SC_BLINK_CURSOR; 56156337Skato else 56256337Skato sc->flags &= ~SC_BLINK_CURSOR; 56356337Skato if (tcp->param[0] & 0x02) 56456337Skato sc->flags |= SC_CHAR_CURSOR; 56556337Skato else 56656337Skato sc->flags &= ~SC_CHAR_CURSOR; 56756337Skato } else if (tcp->num_param == 2) { 56856337Skato sc->cursor_base = scp->font_size 56956337Skato - (tcp->param[1] & 0x1F) - 1; 57056337Skato sc->cursor_height = (tcp->param[1] & 0x1F) 57156337Skato - (tcp->param[0] & 0x1F) + 1; 57256337Skato } 57356337Skato /* 57456337Skato * The cursor shape is global property; all virtual consoles 57556337Skato * are affected. Update the cursor in the current console... 57656337Skato */ 57756337Skato if (!ISGRAPHSC(sc->cur_scp)) { 57856337Skato sc_set_cursor_image(sc->cur_scp); 57956337Skato sc_draw_cursor_image(sc->cur_scp); 58056337Skato } 58157136Skato splx(i); 58256337Skato break; 58356337Skato 58456337Skato case 'F': /* set ansi foreground */ 58556337Skato if (tcp->num_param == 1) { 58656337Skato tcp->attr_mask &= ~FG_CHANGED; 58756337Skato tcp->cur_color.fg = tcp->std_color.fg = tcp->param[0] & 0x0f; 58856337Skato tcp->cur_attr = mask2attr(tcp); 58956337Skato } 59056337Skato break; 59156337Skato 59256337Skato case 'G': /* set ansi background */ 59356337Skato if (tcp->num_param == 1) { 59456337Skato tcp->attr_mask &= ~BG_CHANGED; 59556337Skato tcp->cur_color.bg = tcp->std_color.bg = tcp->param[0] & 0x0f; 59656337Skato tcp->cur_attr = mask2attr(tcp); 59756337Skato } 59856337Skato break; 59956337Skato 60056337Skato case 'H': /* set ansi reverse video foreground */ 60156337Skato if (tcp->num_param == 1) { 60256337Skato tcp->rev_color.fg = tcp->param[0] & 0x0f; 60356337Skato tcp->cur_attr = mask2attr(tcp); 60456337Skato } 60556337Skato break; 60656337Skato 60756337Skato case 'I': /* set ansi reverse video background */ 60856337Skato if (tcp->num_param == 1) { 60956337Skato tcp->rev_color.bg = tcp->param[0] & 0x0f; 61056337Skato tcp->cur_attr = mask2attr(tcp); 61156337Skato } 61256337Skato break; 61356337Skato } 61456337Skato } 61556337Skato#if notyet 61656337Skato else if (tcp->esc == 4) { /* seen ESC Q */ 61756337Skato /* to be filled */ 61856337Skato } 61956337Skato#endif 62056337Skato else if (tcp->esc == 5) { /* seen ESC ( */ 62156337Skato switch (c) { 62256337Skato case 'B': /* iso-2022: desginate ASCII into G0 */ 62356337Skato break; 62456337Skato /* other items to be filled */ 62556337Skato default: 62656337Skato break; 62756337Skato } 62856337Skato } 62956337Skato tcp->esc = 0; 63056337Skato} 63156337Skato 63256337Skatostatic void 63356337Skatoscterm_puts(scr_stat *scp, u_char *buf, int len) 63456337Skato{ 63556337Skato term_stat *tcp = scp->ts; 63656337Skato u_char *ptr = buf; 63756337Skato#ifdef KANJI 63856337Skato u_short kanji_code; 63956337Skato#endif 64056337Skato 64156337Skatooutloop: 64256337Skato scp->sc->write_in_progress++; 64356337Skato 64456337Skato if (tcp->esc) { 64556337Skato scterm_scan_esc(scp, tcp, *ptr++); 64656337Skato len--; 64756337Skato } 64856337Skato else if (PRINTABLE(*ptr)) { /* Print only printables */ 64956337Skato vm_offset_t p; 65056337Skato u_char *map; 65156337Skato int attr; 65256337Skato int i; 65356337Skato#ifdef KANJI 65456337Skato u_char c; 65556337Skato#else 65656337Skato int cnt; 65756337Skato#endif 65856337Skato 65956337Skato p = sc_vtb_pointer(&scp->vtb, scp->cursor_pos); 66056337Skato map = scp->sc->scr_map; 66156337Skato attr = tcp->cur_attr; 66256337Skato 66356337Skato#ifdef KANJI 66456337Skato c = *ptr; 66556337Skato if (tcp->kanji_1st_char == 0) { 66656337Skato tcp->kanji_type = iskanji1(tcp->kanji_type, c); 66756337Skato if (!IS_KTYPE_ASCII_or_HANKAKU(tcp->kanji_type)) { 66856337Skato /* not Ascii & not HANKAKU */ 66956337Skato tcp->kanji_1st_char = c; 67056337Skato goto kanji_end; 67156337Skato } else { 67256337Skato tcp->kanji_1st_char = 0; 67356337Skato } 67456337Skato } else { 67556337Skato if ((tcp->kanji_type = iskanji2(tcp->kanji_type, c)) & 0xee) { 67656337Skato /* print kanji on TEXT VRAM */ 67756337Skato kanji_code = kanji_convert(tcp->kanji_type, c, tcp->kanji_1st_char); 67856337Skato mark_for_update(scp, scp->cursor_pos); 67956337Skato for (i=0; i<2; i++){ 68056337Skato /* *cursor_pos = (kanji_code | (i*0x80)); */ 68156337Skato p = sc_vtb_putchar(&scp->vtb, p, 68256337Skato kanji_code | ((i == 0) ? 0x00 : 0x80), 68356337Skato attr); 68456337Skato ++scp->cursor_pos; 68556337Skato if (++scp->xpos >= scp->xsize) { 68656337Skato scp->xpos = 0; 68756337Skato scp->ypos++; 68856337Skato } 68956337Skato } 69056337Skato mark_for_update(scp, scp->cursor_pos - 1); 69156337Skato KTYPE_MASK_CTRL(tcp->kanji_type); 69256337Skato tcp->kanji_1st_char = 0; 69356337Skato goto kanji_end; 69456337Skato } else { 69556337Skato tcp->kanji_1st_char = 0; 69656337Skato } 69756337Skato } 69856337Skato if (IS_KTYPE_KANA(tcp->kanji_type)) 69956337Skato c |= 0x80; 70056337Skato KTYPE_MASK_CTRL(tcp->kanji_type); 70156337Skato sc_vtb_putchar(&scp->vtb, p, map[c], attr); 70256337Skato mark_for_update(scp, scp->cursor_pos); 70356337Skato mark_for_update(scp, scp->cursor_pos); 70456337Skato ++scp->cursor_pos; 70556337Skato ++scp->xpos; 70656337Skatokanji_end: 70756337Skato ++ptr; 70856337Skato --len; 70956337Skato#else /* !KANJI */ 71056337Skato cnt = imin(len, scp->xsize - scp->xpos); 71156337Skato i = cnt; 71256337Skato do { 71356337Skato /* 71456337Skato * gcc-2.6.3 generates poor (un)sign extension code. Casting the 71556337Skato * pointers in the following to volatile should have no effect, 71656337Skato * but in fact speeds up this inner loop from 26 to 18 cycles 71756337Skato * (+ cache misses) on i486's. 71856337Skato */ 71956337Skato#define UCVP(ucp) ((u_char volatile *)(ucp)) 72056337Skato p = sc_vtb_putchar(&scp->vtb, p, UCVP(map)[*UCVP(ptr)], attr); 72156337Skato ++ptr; 72256337Skato --i; 72356337Skato } while (i > 0 && PRINTABLE(*ptr)); 72456337Skato 72556337Skato len -= cnt - i; 72656337Skato mark_for_update(scp, scp->cursor_pos); 72756337Skato scp->cursor_pos += cnt - i; 72856337Skato mark_for_update(scp, scp->cursor_pos - 1); 72956337Skato scp->xpos += cnt - i; 73056337Skato#endif /* !KANJI */ 73156337Skato 73256337Skato if (scp->xpos >= scp->xsize) { 73356337Skato scp->xpos = 0; 73456337Skato scp->ypos++; 73556337Skato } 73656337Skato } 73756337Skato else { 73856337Skato switch (*ptr) { 73956337Skato case 0x07: 74056337Skato sc_bell(scp, scp->bell_pitch, scp->bell_duration); 74156337Skato break; 74256337Skato 74356337Skato case 0x08: /* non-destructive backspace */ 74456337Skato if (scp->cursor_pos > 0) { 74556337Skato mark_for_update(scp, scp->cursor_pos); 74656337Skato scp->cursor_pos--; 74756337Skato mark_for_update(scp, scp->cursor_pos); 74856337Skato if (scp->xpos > 0) 74956337Skato scp->xpos--; 75056337Skato else { 75156337Skato scp->xpos += scp->xsize - 1; 75256337Skato scp->ypos--; 75356337Skato } 75456337Skato } 75556337Skato break; 75656337Skato 75756337Skato case 0x09: /* non-destructive tab */ 75856337Skato mark_for_update(scp, scp->cursor_pos); 75956337Skato scp->cursor_pos += (8 - scp->xpos % 8u); 76056337Skato scp->xpos += (8 - scp->xpos % 8u); 76156337Skato if (scp->xpos >= scp->xsize) { 76256337Skato scp->xpos = 0; 76356337Skato scp->ypos++; 76456337Skato scp->cursor_pos = scp->xsize * scp->ypos; 76556337Skato } 76656337Skato mark_for_update(scp, scp->cursor_pos); 76756337Skato break; 76856337Skato 76956337Skato case 0x0a: /* newline, same pos */ 77056337Skato mark_for_update(scp, scp->cursor_pos); 77156337Skato scp->cursor_pos += scp->xsize; 77256337Skato mark_for_update(scp, scp->cursor_pos); 77356337Skato scp->ypos++; 77456337Skato break; 77556337Skato 77656337Skato case 0x0c: /* form feed, clears screen */ 77756337Skato sc_clear_screen(scp); 77856337Skato break; 77956337Skato 78056337Skato case 0x0d: /* return, return to pos 0 */ 78156337Skato mark_for_update(scp, scp->cursor_pos); 78256337Skato scp->cursor_pos -= scp->xpos; 78356337Skato mark_for_update(scp, scp->cursor_pos); 78456337Skato scp->xpos = 0; 78556337Skato break; 78656337Skato 78756337Skato#ifdef PC98 78856337Skato case 0x0e: /* ^N */ 78956337Skato tcp->kanji_type = KTYPE_JKANA; 79056337Skato tcp->esc = 0; 79156337Skato tcp->kanji_1st_char = 0; 79256337Skato break; 79356337Skato 79456337Skato case 0x0f: /* ^O */ 79556337Skato tcp->kanji_type = KTYPE_ASCII; 79656337Skato tcp->esc = 0; 79756337Skato tcp->kanji_1st_char = 0; 79856337Skato break; 79956337Skato#endif /* PC98 */ 80056337Skato 80156337Skato case 0x1b: /* start escape sequence */ 80256337Skato tcp->esc = 1; 80356337Skato tcp->num_param = 0; 80456337Skato break; 80556337Skato } 80656337Skato ptr++; len--; 80756337Skato } 80856337Skato 80956337Skato sc_term_gen_scroll(scp, scp->sc->scr_map[0x20], tcp->cur_attr); 81056337Skato 81156337Skato scp->sc->write_in_progress--; 81256337Skato if (len) 81356337Skato goto outloop; 81456337Skato} 81556337Skato 81656337Skatostatic int 81756337Skatoscterm_ioctl(scr_stat *scp, struct tty *tp, u_long cmd, caddr_t data, 81856337Skato int flag, struct proc *p) 81956337Skato{ 82056337Skato term_stat *tcp = scp->ts; 82156337Skato vid_info_t *vi; 82256337Skato 82356337Skato switch (cmd) { 82456337Skato case GIO_ATTR: /* get current attributes */ 82556337Skato /* FIXME: */ 82656337Skato *(int*)data = (tcp->cur_attr >> 8) & 0xff; 82756337Skato return 0; 82856337Skato case CONS_GETINFO: /* get current (virtual) console info */ 82956337Skato vi = (vid_info_t *)data; 83056337Skato if (vi->size != sizeof(struct vid_info)) 83156337Skato return EINVAL; 83256337Skato vi->mv_norm.fore = tcp->std_color.fg; 83356337Skato vi->mv_norm.back = tcp->std_color.bg; 83456337Skato vi->mv_rev.fore = tcp->rev_color.fg; 83556337Skato vi->mv_rev.back = tcp->rev_color.bg; 83656337Skato /* 83756337Skato * The other fields are filled by the upper routine. XXX 83856337Skato */ 83956337Skato return ENOIOCTL; 84056337Skato } 84156337Skato return ENOIOCTL; 84256337Skato} 84356337Skato 84456337Skatostatic int 84556337Skatoscterm_reset(scr_stat *scp, int code) 84656337Skato{ 84756337Skato /* FIXME */ 84856337Skato return 0; 84956337Skato} 85056337Skato 85156337Skatostatic void 85256337Skatoscterm_default_attr(scr_stat *scp, int color, int rev_color) 85356337Skato{ 85456337Skato term_stat *tcp = scp->ts; 85556337Skato 85656337Skato tcp->dflt_std_color.fg = color & 0x0f; 85756337Skato tcp->dflt_std_color.bg = (color >> 4) & 0x0f; 85856337Skato tcp->dflt_rev_color.fg = rev_color & 0x0f; 85956337Skato tcp->dflt_rev_color.bg = (rev_color >> 4) & 0x0f; 86056337Skato tcp->std_color = tcp->dflt_std_color; 86156337Skato tcp->rev_color = tcp->dflt_rev_color; 86256337Skato tcp->cur_color = tcp->std_color; 86356337Skato tcp->cur_attr = mask2attr(tcp); 86456337Skato} 86556337Skato 86656337Skatostatic void 86756337Skatoscterm_clear(scr_stat *scp) 86856337Skato{ 86956337Skato term_stat *tcp = scp->ts; 87056337Skato 87156337Skato sc_move_cursor(scp, 0, 0); 87256337Skato sc_vtb_clear(&scp->vtb, scp->sc->scr_map[0x20], tcp->cur_attr); 87356337Skato mark_all(scp); 87456337Skato} 87556337Skato 87656337Skatostatic void 87756337Skatoscterm_notify(scr_stat *scp, int event) 87856337Skato{ 87956337Skato switch (event) { 88056337Skato case SC_TE_NOTIFY_VTSWITCH_IN: 88156337Skato break; 88256337Skato case SC_TE_NOTIFY_VTSWITCH_OUT: 88356337Skato break; 88456337Skato } 88556337Skato} 88656337Skato 88756337Skatostatic int 88856337Skatoscterm_input(scr_stat *scp, int c, struct tty *tp) 88956337Skato{ 89056337Skato return FALSE; 89156337Skato} 89256337Skato 89356337Skato/* 89456337Skato * Calculate hardware attributes word using logical attributes mask and 89556337Skato * hardware colors 89656337Skato */ 89756337Skato 89856337Skato/* FIXME */ 89956337Skatostatic int 90056337Skatomask2attr(term_stat *tcp) 90156337Skato{ 90256337Skato int attr, mask = tcp->attr_mask; 90356337Skato 90456337Skato if (mask & REVERSE_ATTR) { 90556337Skato attr = ((mask & FG_CHANGED) ? 90656337Skato tcp->cur_color.bg : tcp->rev_color.fg) | 90756337Skato (((mask & BG_CHANGED) ? 90856337Skato tcp->cur_color.fg : tcp->rev_color.bg) << 4); 90956337Skato } else 91056337Skato attr = tcp->cur_color.fg | (tcp->cur_color.bg << 4); 91156337Skato 91256337Skato /* XXX: underline mapping for Hercules adapter can be better */ 91356337Skato if (mask & (BOLD_ATTR | UNDERLINE_ATTR)) 91456337Skato attr ^= 0x08; 91556337Skato if (mask & BLINK_ATTR) 91656337Skato attr ^= 0x80; 91756337Skato 91856337Skato return (attr << 8); 91956337Skato} 92056337Skato 92156337Skato#ifdef KANJI 92256337Skatostatic u_char 92356337Skatoiskanji1(u_char mode, u_char c) 92456337Skato{ 92556337Skato if ((mode == KTYPE_7JIS) && (c >= 0x21) && (c <= 0x7e)) { 92656337Skato /* JIS */ 92756337Skato default_kanji = UJIS; 92856337Skato return KTYPE_7JIS; 92956337Skato } 93056337Skato 93156337Skato if ((mode == KTYPE_JKANA) && (c >= 0x21) && (c <= 0x5f)) { 93256337Skato /* JIS HANKAKU */ 93356337Skato default_kanji = UJIS; 93456337Skato return KTYPE_JKANA; 93556337Skato } 93656337Skato 93756337Skato#if 1 93856337Skato if ((c >= 0xa1) && (c <= 0xdf) && (default_kanji == UJIS)) { 93956337Skato /* UJIS */ 94056337Skato return KTYPE_UJIS; 94156337Skato } 94256337Skato#endif 94356337Skato 94456337Skato if ((c >= 0x81) && (c <= 0x9f) && (c != 0x8e)) { 94556337Skato /* SJIS */ 94656337Skato default_kanji = SJIS; 94756337Skato return KTYPE_SJIS; 94856337Skato } 94956337Skato 95056337Skato if ((c >= 0xa1) && (c <= 0xdf) && (default_kanji == SJIS)) { 95156337Skato /* SJIS HANKAKU */ 95256337Skato return KTYPE_KANA; 95356337Skato } 95456337Skato 95556337Skato#if 0 95656337Skato if ((c >= 0xa1) && (c <= 0xdf) && (default_kanji == UJIS)) { 95756337Skato /* UJIS */ 95856337Skato return KTYPE_UJIS; 95956337Skato } 96056337Skato#endif 96156337Skato 96256337Skato if ((c >= 0xf0) && (c <= 0xfe)) { 96356337Skato /* UJIS */ 96456337Skato default_kanji = UJIS; 96556337Skato return KTYPE_UJIS; 96656337Skato } 96756337Skato 96856337Skato if ((c >= 0xe0) && (c <= 0xef)) { 96956337Skato /* SJIS or UJIS */ 97056337Skato return KTYPE_SUJIS; 97156337Skato } 97256337Skato 97356337Skato if (c == 0x8e) { 97456337Skato /* SJIS or UJIS HANKAKU */ 97556337Skato return KTYPE_SUKANA; 97656337Skato } 97756337Skato 97856337Skato return KTYPE_ASCII; 97956337Skato} 98056337Skato 98156337Skatostatic u_char 98256337Skatoiskanji2(u_char mode, u_char c) 98356337Skato{ 98456337Skato switch (mode) { 98556337Skato case KTYPE_7JIS: 98656337Skato if ((c >= 0x21) && (c <= 0x7e)) { 98756337Skato /* JIS */ 98856337Skato return KTYPE_7JIS; 98956337Skato } 99056337Skato break; 99156337Skato case KTYPE_SJIS: 99256337Skato if ((c >= 0x40) && (c <= 0xfc) && (c != 0x7f)) { 99356337Skato /* SJIS */ 99456337Skato return KTYPE_SJIS; 99556337Skato } 99656337Skato break; 99756337Skato case KTYPE_UJIS: 99856337Skato if ((c >= 0xa1) && (c <= 0xfe)) { 99956337Skato /* UJIS */ 100056337Skato return KTYPE_UJIS; 100156337Skato } 100256337Skato break; 100356337Skato case KTYPE_SUKANA: 100456337Skato if ((c >= 0xa1) && (c <= 0xdf) && (default_kanji == UJIS)) { 100556337Skato /* UJIS HANKAKU */ 100656337Skato return KTYPE_KANA; 100756337Skato } 100856337Skato if ((c >= 0x40) && (c <= 0xfc) && (c != 0x7f)) { 100956337Skato /* SJIS */ 101056337Skato default_kanji = SJIS; 101156337Skato return KTYPE_SJIS; 101256337Skato } 101356337Skato break; 101456337Skato case KTYPE_SUJIS: 101556337Skato if ((c >= 0x40) && (c <= 0xa0) && (c != 0x7f)) { 101656337Skato /* SJIS */ 101756337Skato default_kanji = SJIS; 101856337Skato return KTYPE_SJIS; 101956337Skato } 102056337Skato if ((c == 0xfd) || (c == 0xfe)) { 102156337Skato /* UJIS */ 102256337Skato default_kanji = UJIS; 102356337Skato return KTYPE_UJIS; 102456337Skato } 102556337Skato if ((c >= 0xa1) && (c <= 0xfc)) { 102656337Skato if (default_kanji == SJIS) 102756337Skato return KTYPE_SJIS; 102856337Skato if (default_kanji == UJIS) 102956337Skato return KTYPE_UJIS; 103056337Skato } 103156337Skato break; 103256337Skato } 103356337Skato return KTYPE_ASCII; 103456337Skato} 103556337Skato 103656337Skato/* 103756337Skato * JIS X0208-83 keisen conversion table 103856337Skato */ 103956337Skatostatic u_short keiConv[32] = { 104056337Skato 0x240c, 0x260c, 0x300c, 0x340c, 0x3c0c, 0x380c, 0x400c, 0x500c, 104156337Skato 0x480c, 0x580c, 0x600c, 0x250c, 0x270c, 0x330c, 0x370c, 0x3f0c, 104256337Skato 0x3b0c, 0x470c, 0x570c, 0x4f0c, 0x5f0c, 0x6f0c, 0x440c, 0x530c, 104356337Skato 0x4c0c, 0x5b0c, 0x630c, 0x410c, 0x540c, 0x490c, 0x5c0c, 0x660c 104456337Skato}; 104556337Skato 104656337Skatostatic u_short 104756337Skatokanji_convert(u_char mode, u_char h, u_char l) 104856337Skato{ 104956337Skato u_short tmp, high, low, c; 105056337Skato high = (u_short) h; 105156337Skato low = (u_short) l; 105256337Skato 105356337Skato switch (mode) { 105456337Skato case KTYPE_SJIS: /* SHIFT JIS */ 105556337Skato if (low >= 0xe0) { 105656337Skato low -= 0x40; 105756337Skato } 105856337Skato low = (low - 0x81) * 2 + 0x21; 105956337Skato if (high > 0x7f) { 106056337Skato high--; 106156337Skato } 106256337Skato if (high > 0x9d) { 106356337Skato low++; 106456337Skato high -= 0x9e - 0x21; 106556337Skato } else { 106656337Skato high -= 0x40 - 0x21; 106756337Skato } 106856337Skato high &= 0x7F; 106956337Skato low &= 0x7F; 107056337Skato tmp = ((high << 8) | low) - 0x20; 107156337Skato break; 107256337Skato case KTYPE_7JIS: /* JIS */ 107356337Skato case KTYPE_UJIS: /* UJIS */ 107456337Skato high &= 0x7F; 107556337Skato low &= 0x7F; 107656337Skato tmp = ((high << 8) | low) - 0x20; 107756337Skato break; 107856337Skato default: 107956337Skato tmp = 0; 108056337Skato break; 108156337Skato } 108256337Skato 108356337Skato /* keisen */ 108456337Skato c = ((tmp & 0xff) << 8) | (tmp >> 8); 108556337Skato /* 0x2821 .. 0x2840 */ 108656337Skato if (0x0821 <= c && c <= 0x0840) 108756337Skato tmp = keiConv[c - 0x0821]; 108856337Skato 108956337Skato return (tmp); 109056337Skato} 109156337Skato#endif /* KANJI */ 109256337Skato 109356337Skato#endif /* SC_DUMB_TERMINAL */ 109456337Skato 109556337Skato#endif /* NSC > 0 */ 1096