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