1 /* 2 * Copyright (c) 1992 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc. 7 * 8 * %sccs.include.redist.c% 9 * 10 * from: $Hdr: vt100.c,v 4.300 91/06/09 06:14:56 root Rel41 $ SONY 11 * 12 * @(#)vt100.c 7.4 (Berkeley) 01/20/93 13 */ 14 15 #include <machine/fix_machine_type.h> 16 17 #include <sys/types.h> 18 #include <sys/param.h> 19 #include <sys/systm.h> 20 #include <news3400/iop/framebuf.h> 21 #include <news3400/iop/kbreg.h> 22 #include <news3400/iop/keyboard.h> 23 #include <news3400/fb/fbdefs.h> 24 #include <news3400/bm/vt100.h> 25 #include <news3400/bm/bitmapif.h> 26 27 #ifdef IPC_MRX 28 #include "config.h" 29 #define kbd_ioctl(chan, cmd, argp) { \ 30 if (kb_ioctl) \ 31 (*kb_ioctl)(chan, cmd, argp); \ 32 } 33 #endif 34 35 #ifdef IPC_MRX 36 #include "mrx.h" 37 #include "process.h" 38 #include "object.h" 39 #include "console.h" 40 #endif 41 42 #ifdef CPU_SINGLE 43 #include <news3400/sio/scc.h> 44 #endif 45 46 extern Key_string key_str; 47 extern int tmode; 48 static unsigned int first_code; 49 50 #ifdef IPC_MRX 51 #define SCC_KEYBOARD 0 52 #endif 53 54 SCREEN screen; 55 struct cursor inner_buf_csr; 56 int inner_buf_tstat; 57 char c_pos_mess[C_MESS_SIZ]; 58 extern struct csr_buf local_csr_buf; 59 60 #ifdef IPC_MRX 61 int bitmap_use; 62 #ifdef IPC_3CPU 63 #include "../../ubdev/msgio.h" 64 extern int ipc_ready; 65 #endif /* IPC_3CPU */ 66 extern struct cons_devsw vt100_cons; 67 #endif /* IPC_MRX */ 68 69 #ifdef CPU_DOUBLE 70 int auto_dimmer(); 71 #endif 72 73 #if CPU_SINGLE 74 extern int hz; 75 extern kbd_profun_init(); 76 #endif 77 78 lRectangle char_r1; 79 lRectangle font_r1; 80 lRectangle char_r2; 81 lRectangle font_r2; 82 83 int font_len1; 84 int font_len2; 85 86 int fcolor; 87 int bcolor; 88 89 int font_w; 90 int font_h; 91 int char_w; 92 int char_h; 93 int scr_w; 94 int scr_h; 95 int ch_pos; 96 int ul_pos; 97 int x_ofst; 98 int y_ofst; 99 int rit_m; 100 int btm_m; 101 int bell_len; 102 int dim_cnt; 103 int a_dim_on; 104 105 unsigned short fbuf[256]; 106 int fp; 107 int fpn; 108 lPoint fpp; 109 int fpa; 110 111 vt100init() 112 { 113 register int i; 114 register SCREEN *sp = &screen; 115 116 sp->s_term_mode = 0; 117 sp->s_term_mode |= (SRM|DECSCLM|DECAWM|DECARM|DECCSR_ACTV); 118 sp->s_current_stat = 0; 119 sp->s_csr.csr_x = 1; 120 sp->s_csr.csr_y = 1; 121 sp->s_csr.csr_p.x = x_ofst; 122 sp->s_csr.csr_p.y = y_ofst; 123 sp->s_csr.csr_attributes = NORMALM; 124 sp->s_region.top_margin = TOP_M; 125 sp->s_region.btm_margin = btm_m; 126 sp->s_plane = consfb->planemask; 127 sp->s_bgcol = 0; 128 fcolor = sp->s_plane; 129 bcolor = sp->s_bgcol; 130 for (i = 0; i < RIT_M_MAX; i++) 131 sp->s_tab_pos[i] = 0; 132 for (i = 9; i < RIT_M_MAX; i +=8) 133 sp->s_tab_pos[i] = 1; 134 135 esc_store_csr(sp); 136 inner_buf_tstat = sp->s_term_mode & (DECOM|DECAWM); 137 local_csr_buf.csr_number = 1; 138 139 cursor_on(&sp->s_csr.csr_p); 140 } 141 142 ncp_str(p, q, n) 143 register char *p, *q; 144 register int n; 145 { 146 while (n-- > 0) 147 *q++ = *p++; 148 } 149 150 /* 151 * default parameter set 152 */ 153 set_default_param() 154 { 155 register struct fbdev *cfb = consfb; 156 157 font_w = cfb->font_w; 158 font_h = cfb->font_h; 159 char_w = cfb->char_w; 160 char_h = cfb->char_h; 161 scr_w = cfb->scr_w; 162 scr_h = cfb->scr_h; 163 ch_pos = cfb->ch_pos; 164 ul_pos = cfb->ul_pos; 165 x_ofst = cfb->x_offset; 166 y_ofst = cfb->y_offset; 167 rit_m = cfb->rit_m; 168 btm_m = cfb->btm_m; 169 a_dim_on = 1; 170 171 font_r1.extent.x = font_w; 172 font_r1.extent.y = font_h; 173 font_r2.extent.x = font_w * 2; 174 font_r2.extent.y = font_h; 175 font_len1 = (font_w + 0x0f) >> 4; 176 font_len2 = (font_w*2 + 0x0f) >> 4; 177 char_r1.extent.x = char_w; 178 char_r1.extent.y = char_h; 179 char_r2.extent.x = char_w * 2; 180 char_r2.extent.y = char_h; 181 182 dim_cnt = DIM_CNT_DFLT; 183 bell_len = BELL_LEN_DFLT; 184 } 185 186 vt100_open() 187 { 188 static int only_one = 0; 189 extern char **ext_fnt_addr; 190 191 set_default_param(); 192 vt100init(); 193 bitmapinit(); 194 if (only_one == 0) { 195 #ifdef IPC_MRX 196 #ifdef IPC_3CPU 197 while (ipc_ready == 0) 198 proc_sleep_self(100); 199 #endif 200 while ((bitmap_use = object_query(BITMAP)) <= 0) 201 proc_sleep_self(100); 202 203 proc_create("auto_dimmer", auto_dimmer, 401, 512, 0); 204 #endif /* IPC_MRX */ 205 only_one = 1; 206 } 207 #define INIT_STRING "\033[42;1H" 208 vt100_write(0, INIT_STRING, sizeof(INIT_STRING) - 1); 209 #ifdef CPU_SINGLE 210 kbd_open(SCC_KEYBOARD); 211 #endif 212 } 213 214 #ifdef IPC_MRX 215 vt100_cons_setup() 216 { 217 int vt100_open(), vt100_read(), vt100_write(), vt100_ioctl(); 218 219 vt100_cons.open = vt100_open; 220 vt100_cons.read = vt100_read; 221 vt100_cons.write = vt100_write; 222 vt100_cons.ioctl = vt100_ioctl; 223 } 224 225 #define DIMMER_RESET 0 226 #define DIMMER_ON 1 227 #define DIMMER_OFF 2 228 #define DIMMER_INTERVAL 60 /* sec */ 229 230 static int dimmer_stdport; 231 232 auto_dimmer() 233 { 234 register int select, i; 235 register int dimm_counter = DIM_CNT_DFLT; 236 register int dimm_level = 0; 237 int ports[2], *mode; 238 239 spl0(); 240 ports[0] = dimmer_stdport = STDPORT; 241 ports[1] = port_create("auto_dimmer_sub"); 242 register_interval(ports[1], DIMMER_INTERVAL); 243 for(;;) { 244 select = msg_select(2, ports); 245 if (select == 0) { 246 msg_recv(ports[0], NULL, &mode, NULL, 0); 247 switch (*mode) { 248 case DIMMER_RESET: 249 if (!a_dim_on) 250 break; 251 dimm_counter = dim_cnt; 252 if (dimm_level > 0) { 253 dimm_level =0; 254 for (i = 0; i < nfbdev; i++) 255 fbbm_set_dimmer(&fbdev[i], 0); 256 } 257 break; 258 case DIMMER_ON: 259 dimm_counter = dim_cnt; 260 dimm_level =0; 261 for (i = 0; i < nfbdev; i++) 262 fbbm_set_dimmer(&fbdev[i], dimm_level); 263 a_dim_on = 1; 264 break; 265 case DIMMER_OFF: 266 dimm_counter = dim_cnt; 267 dimm_level =0; 268 for (i = 0; i < nfbdev; i++) 269 fbbm_set_dimmer(&fbdev[i], dimm_level); 270 a_dim_on = 0; 271 break; 272 } 273 } else { 274 msg_recv(ports[1], NULL, NULL, NULL, 0); 275 if (a_dim_on && (dimm_counter-- <= 0)) { 276 if (dimm_level < 3) { 277 dimm_level++; 278 } 279 for (i = 0; i < nfbdev; i++) 280 fbbm_set_dimmer(&fbdev[i], dimm_level); 281 dimm_counter = dim_cnt; 282 } 283 } 284 } 285 } 286 287 rst_dimmer_cnt() 288 { 289 register int diff; 290 static unsigned last_time; 291 extern unsigned sys_time; 292 int mode = DIMMER_RESET; 293 294 diff = sys_time - last_time; 295 if (diff > DIMMER_INTERVAL*HZ || diff < 0) { 296 dimmer(DIMMER_RESET); 297 last_time = sys_time; 298 } 299 } 300 301 auto_dimmer_on() 302 { 303 dimmer(DIMMER_ON); 304 } 305 306 auto_dimmer_off() 307 { 308 dimmer(DIMMER_OFF); 309 } 310 311 dimmer(mode) 312 int mode; 313 { 314 if (dimmer_stdport) 315 msg_send(dimmer_stdport, 0, &mode, sizeof(mode), 0); 316 } 317 #else /* IPC_MRX */ 318 319 static int dimmer_counter = DIM_CNT_DFLT; 320 static int dim_level = 0; 321 322 #ifdef CPU_SINGLE 323 auto_dimmer() 324 { 325 register int s, i; 326 327 s = spl4(); 328 if (a_dim_on && (dimmer_counter-- <= 0)) { 329 if (dim_level < 3) 330 dim_level++; 331 for (i = 0; i < nfbdev; i++) 332 fbbm_set_dimmer(&fbdev[i], dim_level); 333 dimmer_counter = dim_cnt; 334 } 335 splx(s); 336 timeout(auto_dimmer, (caddr_t) 0, 60 * hz); 337 } 338 #endif 339 340 rst_dimmer_cnt() 341 { 342 register int s, i; 343 344 if (!a_dim_on) 345 return; 346 #ifdef CPU_SINGLE 347 s = spl4(); 348 #endif 349 dimmer_counter = dim_cnt; 350 351 if (dim_level > 0) { 352 dim_level =0; 353 for (i = 0; i < nfbdev; i++) 354 fbbm_set_dimmer(&fbdev[i], 0); 355 } 356 splx(s); 357 } 358 359 auto_dimmer_on() 360 { 361 register int s, i; 362 363 #ifdef CPU_SINGLE 364 s = spl4(); 365 #endif 366 dimmer_counter = dim_cnt; 367 dim_level =0; 368 for (i = 0; i < nfbdev; i++) 369 fbbm_set_dimmer(&fbdev[i], dim_level); 370 a_dim_on = 1; 371 splx(s); 372 } 373 374 auto_dimmer_off() 375 { 376 register int s, i; 377 378 #ifdef CPU_SINGLE 379 s = spl4(); 380 #endif 381 dimmer_counter = dim_cnt; 382 dim_level =0; 383 for (i = 0; i < nfbdev; i++) 384 fbbm_set_dimmer(&fbdev[i], dim_level); 385 a_dim_on = 0; 386 splx(s); 387 } 388 #endif /* IPC_MRX */ 389 /* 390 * The routine `_putc(sp, c)' only prints a character c with the cursor 391 * attributes by using `copy_char(x, y, c, attributes)'. 392 * And when IRM (terminal insertion-replacement mode) is set, the characters 393 * righthand side of the cursor are shifted right and lost when they passed 394 * beyond the right margin. 395 * The position is specified by the sp pointer of the structure SCREEN. 396 * 397 */ 398 static 399 _putc(sp, c, kanji) 400 register SCREEN *sp; 401 unsigned int c; 402 { 403 if (sp->s_term_mode & IRM) { 404 vt_flush(&(sp->s_csr)); 405 move_chars(sp->s_csr.csr_x, sp->s_csr.csr_y, 406 rit_m - sp->s_csr.csr_x - ((kanji)? 1: 0), 407 sp->s_csr.csr_x + ((kanji) ? 2: 1)); 408 copy_char(sp, c, kanji); 409 } 410 if (fp) { 411 fbuf[fp++] = c; 412 fpn += kanji + 1; 413 } else { 414 fbuf[fp++] = c; 415 fpp = sp->s_csr.csr_p; 416 fpa = sp->s_csr.csr_attributes; 417 fpn = kanji + 1; 418 } 419 } 420 421 /* 422 * Scroll up and down in the scroll region. 423 * New oriented line must be cleared with terminal mode, that is whether 424 * the screen is reverse mode or not. 425 */ 426 scroll_up(top, bottom, revsw, fcol, bcol) 427 int top; 428 int bottom; 429 int revsw; 430 int fcol; 431 int bcol; 432 { 433 move_lines(top + 1, bottom - top, top); 434 clear_lines(bottom, 1, revsw, fcol, bcol); 435 } 436 437 scroll_down(top, bottom, revsw, fcol, bcol) 438 int top; 439 int bottom; 440 int revsw; 441 int fcol; 442 int bcol; 443 { 444 move_lines(top, bottom - top, top + 1); 445 clear_lines(top, 1, revsw, fcol, bcol); 446 } 447 448 /* 449 * Back space 450 * back_space(sp) moves cursor next to left at current cursor position. 451 * The cursor can not move beyond left or right margin. 452 */ 453 back_space(sp) 454 register SCREEN *sp; 455 { 456 register struct cursor *spc = &sp->s_csr; 457 458 cursor_off(); 459 if (spc->csr_x > LFT_M) { 460 spc->csr_x -= 1; 461 spc->csr_p.x -= char_w; 462 } 463 cursor_on(&spc->csr_p); 464 } 465 466 /* 467 * Tab stop 468 * next_tab_stop(sp) moves cursor to next tab stop. 469 */ 470 next_tab_stop(sp) 471 register SCREEN *sp; 472 { 473 register int i; 474 475 cursor_off(); 476 for (i = sp->s_csr.csr_x + 1; i < rit_m; i++) 477 if (sp->s_tab_pos[i] == 1) 478 break; 479 sp->s_csr.csr_x = min(i, rit_m); 480 sp->s_csr.csr_p.x = (sp->s_csr.csr_x - 1) * char_w + x_ofst; 481 cursor_on(&sp->s_csr.csr_p); 482 } 483 484 /* 485 * Carriage return 486 * carriage_ret(sp) moves cursor at beginning of the current line. 487 */ 488 carriage_ret(sp) 489 register SCREEN *sp; 490 { 491 cursor_off(); 492 sp->s_csr.csr_x = LFT_M; 493 sp->s_csr.csr_p.x = x_ofst; 494 cursor_on(&sp->s_csr.csr_p); 495 } 496 497 /* 498 * Bell 499 */ 500 static 501 bell() 502 { 503 #ifdef news1800 504 static int port; 505 506 if (port == 0) 507 port = port_create("port_cons_bell"); 508 kbd_ioctl(port, KIOCBELL, &bell_len); 509 #else 510 kbd_ioctl(SCC_KEYBOARD, KIOCBELL, &bell_len); 511 #endif 512 return (0); 513 } 514 515 int 516 Putchar(c, eob) 517 unsigned int c; 518 { 519 register SCREEN *sp = &screen; 520 unsigned int sftjis_to_jis(); 521 522 c &= 0xff; 523 524 if (eob) { 525 vt_flush(&(sp->s_csr)); 526 return(0); 527 } 528 529 if (c == 0x1b) { /* c == esc */ 530 vt_flush(&(sp->s_csr)); 531 recover(sp); 532 sp->s_current_stat |= ESCAPE; 533 return; 534 } else if (sp->s_current_stat & ESCAPE) { 535 (*sp->s_esc_handler)(sp, c); 536 return; 537 } else if (sp->s_current_stat & SKANJI) { 538 c = sftjis_to_jis(first_code, c); 539 if (sp->s_current_stat & JKANJI) { 540 addch(sp, c); 541 } else { 542 sp->s_current_stat |= JKANJI; 543 addch(sp, c); 544 sp->s_current_stat &= ~JKANJI; 545 } 546 sp->s_current_stat &= ~SKANJI; 547 goto set_csr; 548 } else if (sp->s_current_stat & EKANJI) { 549 c = (c & 0x7f) | (first_code << 8); 550 if (sp->s_current_stat & JKANJI) { 551 addch(sp, c); 552 } else { 553 sp->s_current_stat |= JKANJI; 554 addch(sp, c); 555 sp->s_current_stat &= ~JKANJI; 556 } 557 sp->s_current_stat &= ~EKANJI; 558 goto set_csr; 559 } else if (sp->s_current_stat & JKANJI) { 560 jiskanji(sp, c); 561 goto set_csr; 562 } else if (sp->s_current_stat & EKANA) { 563 sp->s_current_stat &= ~EKANA; 564 addch(sp, c); 565 goto set_csr; 566 } 567 if (c < 0x20) { /* control code */ 568 vt_flush(&(sp->s_csr)); 569 switch (c) { 570 case 0x00: /* ignore */ 571 break; 572 case 0x07: /* bell */ 573 bell(); 574 break; 575 case 0x08: /* back space */ 576 back_space(sp); 577 break; 578 case 0x09: /* tabulation */ 579 next_tab_stop(sp); 580 break; 581 case 0x0a: /* line feed */ 582 case 0x0b: /* vertical feed */ 583 case 0x0c: /* form feed */ 584 esc_index(sp); 585 break; 586 case 0x0d: /* carriage return */ 587 carriage_ret(sp); 588 break; 589 case 0x0e: /* shift out */ 590 break; 591 case 0x0f: /* shift in */ 592 break; 593 case 0x11: /* xon */ 594 break; 595 case 0x13: /* xoff */ 596 break; 597 case 0x18: /* cancel */ 598 sp->s_current_stat &= ~ESCAPE; 599 break; 600 case 0x1b: /* escape */ 601 /* NOT REACHED */ 602 recover(sp); 603 sp->s_current_stat |= ESCAPE; 604 break; 605 case 0x7f: /* delete */ 606 break; 607 608 default: 609 break; 610 } 611 } else { 612 switch (tmode) { 613 #ifdef KM_SJIS 614 case KM_SJIS: 615 if ((c >= JVR1S && c <= JVR1E) || 616 (c >= JVR2S && c <= JVR2E)) { 617 sp->s_current_stat |= SKANJI; 618 first_code = c; 619 } 620 else 621 addch(sp, c); 622 break; 623 #endif 624 #ifdef KM_EUC 625 case KM_EUC: 626 if (c >= CS1S && c <= CS1E) { 627 sp->s_current_stat |= EKANJI; 628 first_code = c & 0x7f; 629 } 630 else if (c == SS2) 631 sp->s_current_stat |= EKANA; 632 else 633 addch(sp, c); 634 break; 635 #endif 636 #ifdef KM_JIS 637 case KM_JIS: 638 #endif 639 #ifdef KM_ASCII 640 case KM_ASCII: 641 #endif 642 default: 643 addch(sp, c); 644 } 645 } 646 647 set_csr: 648 cursor_on(&sp->s_csr.csr_p); 649 /* altered */ 650 return ; 651 } 652 653 /* 654 * A printable character is printed in this routine by using 655 * the routine `_putc()'. 656 * Anyway, a character is printed in replacement mode or insertion 657 * mode and if the terminal is autowrap then it takes place wrapping 658 * and if cursor is bottom margin of the scroll region then it takes 659 * place scroll up. 660 * The escape sequence handling is another routine. 661 * 662 */ 663 addch(sp, c) 664 register SCREEN *sp; 665 unsigned int c; 666 { 667 register struct cursor *spc = &(sp->s_csr); 668 register struct region *spr = &(sp->s_region); 669 670 if (spc->csr_x >= rit_m || 671 ((sp->s_current_stat & JKANJI) && (spc->csr_x >= rit_m - 1))) { 672 vt_flush(spc); 673 if (sp->s_term_mode & DECAWM) { 674 if ((sp->s_current_stat & WRAP) || (spc->csr_x == rit_m 675 && sp->s_current_stat & JKANJI)) { 676 if (spc->csr_y == spr->btm_margin) { 677 cursor_off(); 678 scroll_up(spr->top_margin, 679 spr->btm_margin, 680 sp->s_term_mode & DECSCNM, 681 sp->s_plane, sp->s_bgcol); 682 cursor_on(&(spc->csr_p)); 683 } else if (spc->csr_y < btm_m) { 684 spc->csr_y += 1; 685 spc->csr_p.y += char_h; 686 } 687 spc->csr_x = LFT_M; 688 spc->csr_p.x = x_ofst; 689 addch(sp, c); 690 return; 691 } 692 sp->s_current_stat |= WRAP; 693 } 694 if (sp->s_current_stat & JKANJI) { 695 if (spc->csr_x != rit_m) { 696 _putc(sp, c, 1); 697 } 698 } else { 699 _putc(sp, c, 0); 700 } 701 if (spc->csr_x < rit_m) { 702 spc->csr_x += 1; 703 spc->csr_p.x += char_w; 704 } 705 706 return ; 707 } 708 if (sp->s_current_stat & JKANJI) { 709 _putc(sp, c, 1); 710 spc->csr_x++; 711 spc->csr_p.x += char_w; 712 } else { 713 _putc(sp, c, 0); 714 } 715 716 spc->csr_x++; /* altered */ 717 spc->csr_p.x += char_w; 718 719 sp->s_current_stat &= ~WRAP; 720 return ; 721 } 722