Initial import from FreeBSD RELENG_4:
[games.git] / sys / dev / video / pcvt / i386 / pcvt_vtf.c
1 /*
2  * Copyright (c) 1999 Hellmuth Michaelis
3  *
4  * Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch.
5  *
6  * Copyright (c) 1992, 1993 Brian Dunford-Shore.
7  *
8  * All rights reserved.
9  *
10  * This code is derived from software contributed to Berkeley by
11  * William Jolitz and Don Ahn.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  * 1. Redistributions of source code must retain the above copyright
17  *    notice, this list of conditions and the following disclaimer.
18  * 2. Redistributions in binary form must reproduce the above copyright
19  *    notice, this list of conditions and the following disclaimer in the
20  *    documentation and/or other materials provided with the distribution.
21  * 3. All advertising materials mentioning features or use of this software
22  *    must display the following acknowledgement:
23  *      This product includes software developed by Hellmuth Michaelis,
24  *      Brian Dunford-Shore and Joerg Wunsch.
25  * 4. The name authors may not be used to endorse or promote products
26  *    derived from this software without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
29  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
30  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
31  * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
32  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
33  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
37  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38  */
39
40 /*---------------------------------------------------------------------------*
41  *
42  *      pcvt_vtf.c      VT220 Terminal Emulator Functions
43  *      -------------------------------------------------
44  *
45  *      Last Edit-Date: [Mon Dec 27 14:13:33 1999]
46  *
47  * $FreeBSD: src/sys/i386/isa/pcvt/pcvt_vtf.c,v 1.11 1999/12/30 16:17:11 hm Exp $
48  *
49  *---------------------------------------------------------------------------*/
50
51 #include "vt.h"
52 #if NVT > 0
53
54 #define PCVT_INCLUDE_VT_SELATTR /* get inline function from pcvt_hdr.h */
55
56 #include <i386/isa/pcvt/pcvt_hdr.h>     /* global include */
57 #include <i386/isa/pcvt/pcvt_tbl.h>     /* character set conversion tables */
58
59 static void clear_dld ( struct video_state *svsp );
60 static void init_dld ( struct video_state *svsp );
61 static void init_udk ( struct video_state *svsp );
62 static void respond ( struct video_state *svsp );
63 static void roll_down ( struct video_state *svsp, int n );
64 static void selective_erase ( struct video_state *svsp, u_short *pcrtat,
65                               int length );
66 static void swcsp ( struct video_state *svsp, u_short *ctp );
67
68 /*---------------------------------------------------------------------------*
69  *      DECSTBM - set top and bottom margins
70  *---------------------------------------------------------------------------*/
71 void
72 vt_stbm(struct video_state *svsp)
73 {
74         /* both 0 => scrolling region = entire screen */
75
76         if((svsp->parms[0] == 0) && (svsp->parms[1] == 0))
77         {
78                 svsp->cur_offset = 0;
79                 svsp->scrr_beg = 0;
80                 svsp->scrr_len = svsp->screen_rows;
81                 svsp->scrr_end = svsp->scrr_len - 1;
82                 svsp->col = 0;
83                 return;
84         }
85
86         if(svsp->parms[1] <= svsp->parms[0])
87                 return;
88
89         /* range parm 1 */
90
91         if(svsp->parms[0] < 1)
92                 svsp->parms[0] = 1;
93         else if(svsp->parms[0] > svsp->screen_rows-1)
94                 svsp->parms[0] = svsp->screen_rows-1;
95
96         /* range parm 2 */
97
98         if(svsp->parms[1] < 2)
99                 svsp->parms[1] = 2;
100         else if(svsp->parms[1] > svsp->screen_rows)
101                 svsp->parms[1] = svsp->screen_rows;
102
103         svsp->scrr_beg = svsp->parms[0]-1;      /* begin of scrolling region */
104         svsp->scrr_len = svsp->parms[1] - svsp->parms[0] + 1; /* no of lines */
105         svsp->scrr_end = svsp->parms[1]-1;
106
107         /* cursor to first pos */
108         if(svsp->m_om)
109                 svsp->cur_offset = svsp->scrr_beg * svsp->maxcol;
110         else
111                 svsp->cur_offset = 0;
112
113         svsp->col = 0;
114 }
115
116 /*---------------------------------------------------------------------------*
117  *      SGR - set graphic rendition
118  *---------------------------------------------------------------------------*/
119 void
120 vt_sgr(struct video_state *svsp)
121 {
122         register int i = 0;
123         u_short setcolor = 0;
124         char colortouched = 0;
125
126         do
127         {
128                 switch(svsp->parms[i++])
129                 {
130                         case 0:         /* reset to normal attributes */
131                                 svsp->vtsgr = VT_NORMAL;
132                                 break;
133
134                         case 1:         /* bold */
135                                 svsp->vtsgr |= VT_BOLD;
136                                 break;
137
138                         case 4:         /* underline */
139                                 svsp->vtsgr |= VT_UNDER;
140                                 break;
141
142                         case 5:         /* blinking */
143                                 svsp->vtsgr |= VT_BLINK;
144                                 break;
145
146                         case 7:         /* reverse */
147                                 svsp->vtsgr |= VT_INVERSE;
148                                 break;
149
150                         case 22:        /* not bold */
151                                 svsp->vtsgr &= ~VT_BOLD;
152                                 break;
153
154                         case 24:        /* not underlined */
155                                 svsp->vtsgr &= ~VT_UNDER;
156                                 break;
157
158                         case 25:        /* not blinking */
159                                 svsp->vtsgr &= ~VT_BLINK;
160                                 break;
161
162                         case 27:        /* not reverse */
163                                 svsp->vtsgr &= ~VT_INVERSE;
164                                 break;
165
166                         case 30:        /* foreground colors */
167                         case 31:
168                         case 32:
169                         case 33:
170                         case 34:
171                         case 35:
172                         case 36:
173                         case 37:
174                                 if(color)
175                                 {
176                                  colortouched = 1;
177                                  setcolor |= ((fgansitopc[(svsp->parms[i-1]-30) & 7]) << 8);
178                                 }
179                                 break;
180
181                         case 40:        /* background colors */
182                         case 41:
183                         case 42:
184                         case 43:
185                         case 44:
186                         case 45:
187                         case 46:
188                         case 47:
189                                 if(color)
190                                 {
191                                  colortouched = 1;
192                                  setcolor |= ((bgansitopc[(svsp->parms[i-1]-40) & 7]) << 8);
193                                 }
194                                 break;
195                 }
196         }
197         while(i <= svsp->parmi);
198         if(color)
199         {
200                 if(colortouched)
201                         svsp->c_attr = setcolor;
202                 else
203                         svsp->c_attr = ((sgr_tab_color[svsp->vtsgr]) << 8);
204         }
205         else
206         {
207                 if(adaptor_type == MDA_ADAPTOR)
208                         svsp->c_attr = ((sgr_tab_imono[svsp->vtsgr]) << 8);
209                 else
210                         svsp->c_attr = ((sgr_tab_mono[svsp->vtsgr]) << 8);
211         }
212 }
213
214 /*---------------------------------------------------------------------------*
215  *      CUU - cursor up
216  *---------------------------------------------------------------------------*/
217 void
218 vt_cuu(struct video_state *svsp)
219 {
220         register int p = svsp->parms[0];
221
222         if (p <= 0)                             /* parameter min */
223                 p = 1;
224
225         p = min(p, svsp->row - svsp->scrr_beg);
226
227         if (p <= 0)
228                 return;
229
230         svsp->cur_offset -= (svsp->maxcol * p);
231 }
232
233 /*---------------------------------------------------------------------------*
234  *      CUD - cursor down
235  *---------------------------------------------------------------------------*/
236 void
237 vt_cud(struct video_state *svsp)
238 {
239         register int p = svsp->parms[0];
240
241         if (p <= 0)
242                 p = 1;
243
244         p = min(p, svsp->scrr_end - svsp->row);
245
246         if (p <= 0)
247                 return;
248
249         svsp->cur_offset += (svsp->maxcol * p);
250 }
251
252 /*---------------------------------------------------------------------------*
253  *      CUF - cursor forward
254  *---------------------------------------------------------------------------*/
255 void
256 vt_cuf(struct video_state *svsp)
257 {
258         register int p = svsp->parms[0];
259
260         if(svsp->col == ((svsp->maxcol)-1))     /* already at right margin */
261                 return;
262
263         if(p <= 0)                              /* parameter min = 1 */
264                 p = 1;
265         else if(p > ((svsp->maxcol)-1))         /* parameter max = 79 */
266                 p = ((svsp->maxcol)-1);
267
268         if((svsp->col + p) > ((svsp->maxcol)-1))/* not more than right margin */
269                 p = ((svsp->maxcol)-1) - svsp->col;
270
271         svsp->cur_offset += p;
272         svsp->col += p;
273 }
274
275 /*---------------------------------------------------------------------------*
276  *      CUB - cursor backward
277  *---------------------------------------------------------------------------*/
278 void
279 vt_cub(struct video_state *svsp)
280 {
281         register int p = svsp->parms[0];
282
283         if(svsp->col == 0)                      /* already at left margin ? */
284                 return;
285
286         if(p <= 0)                              /* parameter min = 1 */
287                 p = 1;
288         else if(p > ((svsp->maxcol)-1))         /* parameter max = 79 */
289                 p = ((svsp->maxcol)-1);
290
291         if((svsp->col - p) <= 0)                /* not more than left margin */
292                 p = svsp->col;
293
294         svsp->cur_offset -= p;
295         svsp->col -= p;
296 }
297
298 /*---------------------------------------------------------------------------*
299  *      ED - erase in display
300  *---------------------------------------------------------------------------*/
301 void
302 vt_clreos(struct video_state *svsp)
303 {
304         switch(svsp->parms[0])
305         {
306                 case 0:
307                         fillw(user_attr | ' ', svsp->Crtat + svsp->cur_offset,
308                                 svsp->Crtat +
309                                 (svsp->maxcol * svsp->screen_rows) -
310                                 (svsp->Crtat + svsp->cur_offset));
311                         break;
312
313                 case 1:
314                         fillw(user_attr | ' ', svsp->Crtat,
315                                 svsp->Crtat + svsp->cur_offset -
316                                 svsp->Crtat + 1 );
317                         break;
318
319                 case 2:
320                         fillw(user_attr | ' ', svsp->Crtat,
321                                 svsp->maxcol * svsp->screen_rows);
322                         break;
323         }
324 }
325
326 /*---------------------------------------------------------------------------*
327  *      EL - erase in line
328  *---------------------------------------------------------------------------*/
329 void
330 vt_clreol(struct video_state *svsp)
331 {
332         switch(svsp->parms[0])
333         {
334                 case 0:
335                         fillw(user_attr | ' ',
336                                 svsp->Crtat + svsp->cur_offset,
337                                 svsp->maxcol-svsp->col);
338                         break;
339
340                 case 1:
341                         fillw(user_attr | ' ',
342                                 svsp->Crtat + svsp->cur_offset - svsp->col,
343                                 svsp->col + 1);
344                         break;
345
346                 case 2:
347                         fillw(user_attr | ' ',
348                                 svsp->Crtat + svsp->cur_offset - svsp->col,
349                                 svsp->maxcol);
350                         break;
351         }
352 }
353
354 /*---------------------------------------------------------------------------*
355  *      CUP - cursor position / HVP - horizontal & vertical position
356  *---------------------------------------------------------------------------*/
357 void
358 vt_curadr(struct video_state *svsp)
359 {
360         if(svsp->m_om)  /* relative to scrolling region */
361         {
362                 if((svsp->parms[0] == 0) && (svsp->parms[1] == 0))
363                 {
364                         svsp->cur_offset = svsp->scrr_beg * svsp->maxcol;
365                         svsp->col = 0;
366                         svsp->abs_write = 0;
367                         return;
368                 }
369
370                 if(svsp->parms[0] <= 0)
371                         svsp->parms[0] = 1;
372                 else if(svsp->parms[0] > svsp->scrr_len)
373                         svsp->parms[0] = svsp->scrr_len;
374
375                 if(svsp->parms[1] <= 0 )
376                         svsp->parms[1] = 1;
377                 if(svsp->parms[1] > svsp->maxcol)
378                         svsp->parms[1] = svsp->maxcol;
379
380                 svsp->cur_offset = (svsp->scrr_beg * svsp->maxcol) +
381                                    ((svsp->parms[0] - 1) * svsp->maxcol) +
382                                    svsp->parms[1] - 1;
383                 svsp->col = svsp->parms[1] - 1;
384                 svsp->abs_write = 0;
385         }
386         else    /* relative to screen start */
387         {
388                 if((svsp->parms[0] == 0) && (svsp->parms[1] == 0))
389                 {
390                         svsp->cur_offset = 0;
391                         svsp->col = 0;
392                         svsp->abs_write = 0;
393                         return;
394                 }
395
396                 if(svsp->parms[0] <= 0)
397                         svsp->parms[0] = 1;
398                 else if(svsp->parms[0] > svsp->screen_rows)
399                         svsp->parms[0] = svsp->screen_rows;
400
401                 if(svsp->parms[1] <= 0 )
402                         svsp->parms[1] = 1;
403                 if(svsp->parms[1] > svsp->maxcol)       /* col */
404                         svsp->parms[1] = svsp->maxcol;
405
406                 svsp->cur_offset = (((svsp->parms[0]-1)*svsp->maxcol) +
407                                     (svsp->parms[1]-1));
408                 svsp->col = svsp->parms[1]-1;
409
410                 if (svsp->cur_offset >=
411                         ((svsp->scrr_beg + svsp->scrr_len + 1) * svsp->maxcol))
412
413                         svsp->abs_write = 1;
414                 else
415                         svsp->abs_write = 0;
416         }
417 }
418
419 /*---------------------------------------------------------------------------*
420  *      RIS - reset to initial state (hard emulator runtime reset)
421  *---------------------------------------------------------------------------*/
422 void
423 vt_ris(struct video_state *svsp)
424 {
425         fillw(user_attr | ' ', svsp->Crtat, svsp->maxcol * svsp->screen_rows);
426         svsp->cur_offset = 0;           /* cursor upper left corner */
427         svsp->col = 0;
428         svsp->row = 0;
429         svsp->lnm = 0;                  /* CR only */
430         clear_dld(svsp);                /* clear download charset */
431         vt_clearudk(svsp);              /* clear user defined keys */
432         svsp->selchar = 0;              /* selective attribute off */
433         vt_str(svsp);                   /* and soft terminal reset */
434 }
435
436 /*---------------------------------------------------------------------------*
437  *      DECSTR - soft terminal reset (SOFT emulator runtime reset)
438  *---------------------------------------------------------------------------*/
439 void
440 vt_str(struct video_state *svsp)
441 {
442         int i;
443
444         clr_parms(svsp);                        /* escape parameter init */
445         svsp->state = STATE_INIT;               /* initial state */
446
447         svsp->dis_fnc = 0;                      /* display functions reset */
448
449         svsp->sc_flag = 0;                      /* save cursor position */
450         svsp->transparent = 0;                  /* enable control code processing */
451
452         for(i = 0; i < MAXTAB; i++)             /* setup tabstops */
453         {
454                 if(!(i % 8))
455                         svsp->tab_stops[i] = 1;
456                 else
457                         svsp->tab_stops[i] = 0;
458         }
459
460         svsp->irm = 0;                          /* replace mode */
461         svsp->m_om = 0;                         /* origin mode */
462         svsp->m_awm = 1;                        /* auto wrap mode */
463
464 #if PCVT_INHIBIT_NUMLOCK
465         svsp->num_lock = 0;                     /* keypad application mode */
466 #else
467         svsp->num_lock = 1;                     /* keypad numeric mode */
468 #endif
469
470         svsp->scroll_lock = 0;                  /* reset keyboard modes */
471         svsp->caps_lock = 0;
472
473         svsp->ckm = 1;                          /* cursor key mode = "normal" ... */
474         svsp->scrr_beg = 0;                     /* start of scrolling region */
475         svsp->scrr_len = svsp->screen_rows;     /* no. of lines in scrolling region */
476         svsp->abs_write = 0;                    /* scrr is complete screen */
477         svsp->scrr_end = svsp->scrr_len - 1;
478
479         if(adaptor_type == EGA_ADAPTOR || adaptor_type == VGA_ADAPTOR)
480         {
481                 svsp->G0 = cse_ascii;           /* G0 = ascii   */
482                 svsp->G1 = cse_ascii;           /* G1 = ascii   */
483                 svsp->G2 = cse_supplemental;    /* G2 = supplemental */
484                 svsp->G3 = cse_supplemental;    /* G3 = supplemental */
485                 svsp->GL = &svsp->G0;           /* GL = G0 */
486                 svsp->GR = &svsp->G2;           /* GR = G2 */
487         }
488         else
489         {
490                 svsp->G0 = csd_ascii;           /* G0 = ascii   */
491                 svsp->G1 = csd_ascii;           /* G1 = ascii   */
492                 svsp->G2 = csd_supplemental;    /* G2 = supplemental */
493                 svsp->G3 = csd_supplemental;    /* G3 = supplemental */
494                 svsp->GL = &svsp->G0;           /* GL = G0 */
495                 svsp->GR = &svsp->G2;           /* GR = G2 */
496         }
497
498         svsp->vtsgr = VT_NORMAL;                /* no attributes */
499         svsp->c_attr = user_attr;               /* reset sgr to normal */
500
501         svsp->selchar = 0;                      /* selective attribute off */
502         vt_initsel(svsp);
503
504         init_ufkl(svsp);                        /* init user fkey labels */
505         init_sfkl(svsp);                        /* init system fkey labels */
506
507         update_led();                           /* update keyboard LED's */
508 }
509
510 /*---------------------------------------------------------------------------*
511  *      RI - reverse index, move cursor up
512  *---------------------------------------------------------------------------*/
513 void
514 vt_ri(struct video_state *svsp)
515 {
516         if(svsp->cur_offset >= ((svsp->scrr_beg * svsp->maxcol) + svsp->maxcol))
517                 svsp->cur_offset -= svsp->maxcol;
518         else
519                 roll_down(svsp, 1);
520 }
521
522 /*---------------------------------------------------------------------------*
523  *      IND - index, move cursor down
524  *---------------------------------------------------------------------------*/
525 void
526 vt_ind(struct video_state *svsp)
527 {
528         if(svsp->cur_offset < (svsp->scrr_end * svsp->maxcol))
529                 svsp->cur_offset += svsp->maxcol;
530         else
531                 roll_up(svsp, 1);
532 }
533
534 /*---------------------------------------------------------------------------*
535  *      NEL - next line, first pos of next line
536  *---------------------------------------------------------------------------*/
537 void
538 vt_nel(struct video_state *svsp)
539 {
540         if(svsp->cur_offset < (svsp->scrr_end * svsp->maxcol))
541         {
542                 svsp->cur_offset += (svsp->maxcol-svsp->col);
543                 svsp->col = 0;
544         }
545         else
546         {
547                 roll_up(svsp, 1);
548                 svsp->cur_offset -= svsp->col;
549                 svsp->col = 0;
550         }
551 }
552
553 /*---------------------------------------------------------------------------*
554  *      set dec private modes, esc [ ? x h
555  *---------------------------------------------------------------------------*/
556 void
557 vt_set_dec_priv_qm(struct video_state *svsp)
558 {
559         switch(svsp->parms[0])
560         {
561                 case 0:         /* error, ignored */
562                 case 1:         /* CKM - cursor key mode */
563                         svsp->ckm = 1;
564                         break;
565
566                 case 2:         /* ANM - ansi/vt52 mode */
567                         break;
568
569                 case 3:         /* COLM - column mode */
570                         vt_col(svsp, SCR_COL132);
571                         break;
572
573                 case 4:         /* SCLM - scrolling mode */
574                 case 5:         /* SCNM - screen mode */
575                         break;
576
577                 case 6:         /* OM - origin mode */
578                         svsp->m_om = 1;
579                         break;
580
581                 case 7:         /* AWM - auto wrap mode */
582                         svsp->m_awm = 1;
583                         swritefkl(7,(u_char *)"AUTOWRAPENABLE *",svsp);
584                         break;
585
586                 case 8:         /* ARM - auto repeat mode */
587                         kbrepflag = 1;
588                         break;
589
590                 case 9:         /* INLM - interlace mode */
591                 case 10:        /* EDM - edit mode */
592                 case 11:        /* LTM - line transmit mode */
593                 case 12:        /* */
594                 case 13:        /* SCFDM - space compression / field delimiting */
595                 case 14:        /* TEM - transmit execution mode */
596                 case 15:        /* */
597                 case 16:        /* EKEM - edit key execution mode */
598                         break;
599
600                 case 25:        /* TCEM - text cursor enable mode */
601                         if(vsp == svsp)
602                                 sw_cursor(1);   /* cursor on */
603                         svsp->cursor_on = 1;
604                         break;
605
606                 case 42:        /* NRCM - 7bit NRC characters */
607                         break;
608         }
609 }
610
611 /*---------------------------------------------------------------------------*
612  *      reset dec private modes, esc [ ? x l
613  *---------------------------------------------------------------------------*/
614 void
615 vt_reset_dec_priv_qm(struct video_state *svsp)
616 {
617         switch(svsp->parms[0])
618         {
619                 case 0:         /* error, ignored */
620                 case 1:         /* CKM - cursor key mode */
621                         svsp->ckm = 0;
622                         break;
623
624                 case 2:         /* ANM - ansi/vt52 mode */
625                         break;
626
627                 case 3:         /* COLM - column mode */
628                         vt_col(svsp, SCR_COL80);
629                         break;
630
631                 case 4:         /* SCLM - scrolling mode */
632                 case 5:         /* SCNM - screen mode */
633                         break;
634
635                 case 6:         /* OM - origin mode */
636                         svsp->m_om = 0;
637                         break;
638
639                 case 7:         /* AWM - auto wrap mode */
640                         svsp->m_awm = 0;
641                         swritefkl(7,(u_char *)"AUTOWRAPENABLE  ",svsp);
642                         break;
643
644                 case 8:         /* ARM - auto repeat mode */
645                         kbrepflag = 0;
646                         break;
647
648                 case 9:         /* INLM - interlace mode */
649                 case 10:        /* EDM - edit mode */
650                 case 11:        /* LTM - line transmit mode */
651                 case 12:        /* */
652                 case 13:        /* SCFDM - space compression / field delimiting */
653                 case 14:        /* TEM - transmit execution mode */
654                 case 15:        /* */
655                 case 16:        /* EKEM - edit key execution mode */
656                         break;
657
658                 case 25:        /* TCEM - text cursor enable mode */
659                         if(vsp == svsp)
660                                 sw_cursor(0);   /* cursor off */
661                         svsp->cursor_on = 0;
662                         break;
663
664                 case 42:        /* NRCM - 7bit NRC characters */
665                         break;
666         }
667 }
668
669 /*---------------------------------------------------------------------------*
670  *      set ansi modes, esc [ x
671  *---------------------------------------------------------------------------*/
672 void
673 vt_set_ansi(struct video_state *svsp)
674 {
675         switch(svsp->parms[0])
676         {
677                 case 0:         /* error, ignored */
678                 case 1:         /* GATM - guarded area transfer mode */
679                 case 2:         /* KAM - keyboard action mode */
680                 case 3:         /* CRM - Control Representation mode */
681                         break;
682
683                 case 4:         /* IRM - insert replacement mode */
684                         svsp->irm = 1; /* Insert mode */
685                         break;
686
687                 case 5:         /* SRTM - status report transfer mode */
688                 case 6:         /* ERM - erasue mode */
689                 case 7:         /* VEM - vertical editing mode */
690                 case 10:        /* HEM - horizontal editing mode */
691                 case 11:        /* PUM - position unit mode */
692                 case 12:        /* SRM - send-receive mode */
693                 case 13:        /* FEAM - format effector action mode */
694                 case 14:        /* FETM - format effector transfer mode */
695                 case 15:        /* MATM - multiple area transfer mode */
696                 case 16:        /* TTM - transfer termination */
697                 case 17:        /* SATM - selected area transfer mode */
698                 case 18:        /* TSM - tabulation stop mode */
699                 case 19:        /* EBM - editing boundary mode */
700                         break;
701
702                 case 20:        /* LNM - line feed / newline mode */
703                         svsp->lnm = 1;
704                         break;
705         }
706 }
707
708 /*---------------------------------------------------------------------------*
709  *      reset ansi modes, esc [ x
710  *---------------------------------------------------------------------------*/
711 void
712 vt_reset_ansi(struct video_state *svsp)
713 {
714         switch(svsp->parms[0])
715         {
716                 case 0:         /* error, ignored */
717                 case 1:         /* GATM - guarded area transfer mode */
718                 case 2:         /* KAM - keyboard action mode */
719                 case 3:         /* CRM - Control Representation mode */
720                         break;
721
722                 case 4:         /* IRM - insert replacement mode */
723                         svsp->irm = 0;  /* Replace mode */
724                         break;
725
726                 case 5:         /* SRTM - status report transfer mode */
727                 case 6:         /* ERM - erasue mode */
728                 case 7:         /* VEM - vertical editing mode */
729                 case 10:        /* HEM - horizontal editing mode */
730                 case 11:        /* PUM - position unit mode */
731                 case 12:        /* SRM - send-receive mode */
732                 case 13:        /* FEAM - format effector action mode */
733                 case 14:        /* FETM - format effector transfer mode */
734                 case 15:        /* MATM - multiple area transfer mode */
735                 case 16:        /* TTM - transfer termination */
736                 case 17:        /* SATM - selected area transfer mode */
737                 case 18:        /* TSM - tabulation stop mode */
738                 case 19:        /* EBM - editing boundary mode */
739                         break;
740
741                 case 20:        /* LNM - line feed / newline mode */
742                         svsp->lnm = 0;
743                         break;
744         }
745 }
746
747 /*---------------------------------------------------------------------------*
748  *      clear tab stop(s)
749  *---------------------------------------------------------------------------*/
750 void
751 vt_clrtab(struct video_state *svsp)
752 {
753         int i;
754
755         if(svsp->parms[0] == 0)
756                 svsp->tab_stops[svsp->col] = 0;
757         else if(svsp->parms[0] == 3)
758         {
759                 for(i=0; i<MAXTAB; i++)
760                         svsp->tab_stops[i] = 0;
761         }
762 }
763
764 /*---------------------------------------------------------------------------*
765  *      DECSC - save cursor & attributes
766  *---------------------------------------------------------------------------*/
767 void
768 vt_sc(struct video_state *svsp)
769 {
770         svsp->sc_flag = 1;
771         svsp->sc_row = svsp->row;
772         svsp->sc_col = svsp->col;
773         svsp->sc_cur_offset = svsp->cur_offset;
774         svsp->sc_attr = svsp->c_attr;
775         svsp->sc_awm = svsp->m_awm;
776         svsp->sc_om = svsp->m_om;
777         svsp->sc_G0 = svsp->G0;
778         svsp->sc_G1 = svsp->G1;
779         svsp->sc_G2 = svsp->G2;
780         svsp->sc_G3 = svsp->G3;
781         svsp->sc_GL = svsp->GL;
782         svsp->sc_GR = svsp->GR;
783         svsp->sc_sel = svsp->selchar;
784         svsp->sc_vtsgr = svsp->vtsgr;
785 }
786
787 /*---------------------------------------------------------------------------*
788  *      DECRC - restore cursor & attributes
789  *---------------------------------------------------------------------------*/
790 void
791 vt_rc(struct video_state *svsp)
792 {
793         if(svsp->sc_flag == 1)
794         {
795                 svsp->sc_flag = 0;
796                 svsp->row = svsp->sc_row;
797                 svsp->col = svsp->sc_col;
798                 svsp->cur_offset = svsp->sc_cur_offset;
799                 svsp->c_attr = svsp->sc_attr;
800                 svsp->m_awm = svsp->sc_awm;
801                 svsp->m_om = svsp->sc_om;
802                 svsp->G0 = svsp->sc_G0;
803                 svsp->G1 = svsp->sc_G1;
804                 svsp->G2 = svsp->sc_G2;
805                 svsp->G3 = svsp->sc_G3;
806                 svsp->GL = svsp->sc_GL;
807                 svsp->GR = svsp->sc_GR;
808                 svsp->selchar = svsp->sc_sel;
809                 svsp->vtsgr = svsp->sc_vtsgr;
810         }
811 }
812
813 /*---------------------------------------------------------------------------*
814  *      designate a character set as G0, G1, G2 or G3 for 94/96 char sets
815  *---------------------------------------------------------------------------*/
816 void
817 vt_designate(struct video_state *svsp)
818 {
819         u_short *ctp = NULL;
820         u_char ch;
821
822         if(svsp->whichi == 1)
823                 ch = svsp->which[0];
824         else
825         {
826                 int i;
827
828                 if(svsp->dld_id[0] == '\0')
829                         return;
830
831                 if(!(((adaptor_type == EGA_ADAPTOR) ||
832                      (adaptor_type == VGA_ADAPTOR)) &&
833                      (vgacs[svsp->vga_charset].secondloaded)))
834                 {
835                         return;
836                 }
837
838                 for(i = (svsp->whichi)-1; i >= 0; i--)
839                 {
840                          if(svsp->which[i] != svsp->dld_id[i])
841                                 return;
842                 }
843 #ifdef HAVECSE_DOWNLOADABLE
844                 ctp = cse_downloadable;
845                 swcsp(svsp, ctp);
846 #endif
847                 return;
848         }
849
850         if(((adaptor_type == EGA_ADAPTOR) || (adaptor_type == VGA_ADAPTOR)) &&
851            (vgacs[svsp->vga_charset].secondloaded))
852         {
853                 if((ch == svsp->dld_id[0]) && (svsp->dld_id[1] == '\0'))
854                 {
855 #ifdef HAVECSE_DOWNLOADABLE
856                         ctp = cse_downloadable;
857                         swcsp(svsp, ctp);
858 #endif
859                         return;
860                 }
861
862                 switch(ch)
863                 {
864                         case 'A': /* British or ISO-Latin-1 */
865                                 switch(svsp->state)
866                                 {
867                                         case STATE_BROPN: /* designate G0 */
868                                         case STATE_BRCLO: /* designate G1 */
869                                         case STATE_STAR:  /* designate G2 */
870                                         case STATE_PLUS:  /* designate G3 */
871 #ifdef HAVECSE_BRITISH
872                                                 ctp = cse_british;
873 #endif
874                                                 break;
875
876                                         case STATE_MINUS: /* designate G1 (96)*/
877                                         case STATE_DOT:   /* designate G2 (96)*/
878                                         case STATE_SLASH: /* designate G3 (96)*/
879 #ifdef HAVECSE_ISOLATIN
880                                                 ctp = cse_isolatin;
881 #endif
882                                                 break;
883                                 }
884                                 break;
885
886                         case 'B': /* USASCII */
887 #ifdef HAVECSE_ASCII
888                                 ctp = cse_ascii;
889 #endif
890                                 break;
891
892                         case 'C': /* Finnish */
893                         case '5': /* Finnish */
894 #ifdef HAVECSE_FINNISH
895                                 ctp = cse_finnish;
896 #endif
897                                 break;
898
899                         case 'E': /* Norwegian/Danish */
900                         case '6': /* Norwegian/Danish */
901 #ifdef HAVECSE_NORWEGIANDANISH
902                                 ctp = cse_norwegiandanish;
903 #endif
904                                 break;
905
906                         case 'H': /* Swedish */
907                         case '7': /* Swedish */
908 #ifdef HAVECSE_SWEDISH
909                                 ctp = cse_swedish;
910 #endif
911                                 break;
912
913                         case 'K': /* German */
914 #ifdef HAVECSE_GERMAN
915                                 ctp = cse_german;
916 #endif
917                                 break;
918
919                         case 'Q': /* French Canadien */
920 #ifdef HAVECSE_FRENCHCANADA
921                                 ctp = cse_frenchcanada;
922 #endif
923                                 break;
924
925                         case 'R': /* French */
926 #ifdef HAVECSE_FRENCH
927                                 ctp = cse_french;
928 #endif
929                                 break;
930
931                         case 'Y': /* Italian */
932 #ifdef HAVECSE_ITALIAN
933                                 ctp = cse_italian;
934 #endif
935                                 break;
936
937                         case 'Z': /* Spanish */
938 #ifdef HAVECSE_SPANISH
939                                 ctp = cse_spanish;
940 #endif
941                                 break;
942
943                         case '0': /* special graphics */
944 #ifdef HAVECSE_SPECIAL
945                                 ctp = cse_special;
946 #endif
947                                 break;
948
949                         case '1': /* alternate ROM */
950 #ifdef HAVECSE_ALTERNATEROM1
951                                 ctp = cse_alternaterom1;
952 #endif
953                                 break;
954
955                         case '2': /* alt ROM, spec graphics */
956 #ifdef HAVECSE_ALTERNATEROM2
957                                 ctp = cse_alternaterom2;
958 #endif
959                                 break;
960
961                         case '3': /* HP Roman 8, upper 128 chars*/
962 #ifdef HAVECSE_ROMAN8
963                                 ctp = cse_roman8;
964 #endif
965                                 break;
966
967                         case '4': /* Dutch */
968 #ifdef HAVECSE_DUTCH
969                                 ctp = cse_dutch;
970 #endif
971                                 break;
972
973                         case '<': /* DEC Supplemental */
974 #ifdef HAVECSE_SUPPLEMENTAL
975                                 ctp = cse_supplemental;
976 #endif
977                                 break;
978
979                         case '=': /* Swiss */
980 #ifdef HAVECSE_SWISS
981                                 ctp = cse_swiss;
982 #endif
983                                 break;
984
985                         case '>': /* DEC Technical */
986 #ifdef HAVECSE_TECHNICAL
987                                 ctp = cse_technical;
988 #endif
989                                 break;
990
991                         default:
992                                 break;
993                 }
994         }
995         else
996         {
997                 switch(ch)
998                 {
999                         case 'A': /* British or ISO-Latin-1 */
1000                                 switch(svsp->state)
1001                                 {
1002                                         case STATE_BROPN: /* designate G0 */
1003                                         case STATE_BRCLO: /* designate G1 */
1004                                         case STATE_STAR:  /* designate G2 */
1005                                         case STATE_PLUS:  /* designate G3 */
1006 #ifdef HAVECSD_BRITISH
1007                                                 ctp = csd_british;
1008 #endif
1009                                                 break;
1010
1011                                         case STATE_MINUS: /* designate G1 (96)*/
1012                                         case STATE_DOT:   /* designate G2 (96)*/
1013                                         case STATE_SLASH: /* designate G3 (96)*/
1014 #ifdef HAVECSD_ISOLATIN
1015                                                 ctp = csd_isolatin;
1016 #endif
1017                                                 break;
1018                                 }
1019                                 break;
1020
1021                         case 'B': /* USASCII */
1022 #ifdef HAVECSD_ASCII
1023                                 ctp = csd_ascii;
1024 #endif
1025                                 break;
1026
1027                         case 'C': /* Finnish */
1028                         case '5': /* Finnish */
1029 #ifdef HAVECSD_FINNISH
1030                                 ctp = csd_finnish;
1031 #endif
1032                                 break;
1033
1034                         case 'E': /* Norwegian/Danish */
1035                         case '6': /* Norwegian/Danish */
1036 #ifdef HAVECSD_NORWEGIANDANISH
1037                                 ctp = csd_norwegiandanish;
1038 #endif
1039                                 break;
1040
1041                         case 'H': /* Swedish */
1042                         case '7': /* Swedish */
1043 #ifdef HAVECSD_SWEDISH
1044                                 ctp = csd_swedish;
1045 #endif
1046                                 break;
1047
1048                         case 'K': /* German */
1049 #ifdef HAVECSD_GERMAN
1050                                 ctp = csd_german;
1051 #endif
1052                                 break;
1053
1054                         case 'Q': /* French Canadien */
1055 #ifdef HAVECSD_FRENCHCANADA
1056                                 ctp = csd_frenchcanada;
1057 #endif
1058                                 break;
1059
1060                         case 'R': /* French */
1061 #ifdef HAVECSD_FRENCH
1062                                 ctp = csd_french;
1063 #endif
1064                                 break;
1065
1066                         case 'Y': /* Italian */
1067 #ifdef HAVECSD_ITALIAN
1068                                 ctp = csd_italian;
1069 #endif
1070                                 break;
1071
1072                         case 'Z': /* Spanish */
1073 #ifdef HAVECSD_SPANISH
1074                                 ctp = csd_spanish;
1075 #endif
1076                                 break;
1077
1078                         case '0': /* special graphics */
1079 #ifdef HAVECSD_SPECIAL
1080                                 ctp = csd_special;
1081 #endif
1082                                 break;
1083
1084                         case '1': /* alternate ROM */
1085 #ifdef HAVECSD_ALTERNATEROM1
1086                                 ctp = csd_alternaterom1;
1087 #endif
1088                                 break;
1089
1090                         case '2': /* alt ROM, spec graphics */
1091 #ifdef HAVECSD_ALTERNATEROM2
1092                                 ctp = csd_alternaterom2;
1093 #endif
1094                                 break;
1095
1096                         case '3': /* HP Roman 8, upper 128 chars*/
1097 #ifdef HAVECSD_ROMAN8
1098                                 ctp = csd_roman8;
1099 #endif
1100                                 break;
1101
1102                         case '4': /* Dutch */
1103 #ifdef HAVECSD_DUTCH
1104                                 ctp = csd_dutch;
1105 #endif
1106                                 break;
1107
1108                         case '<': /* DEC Supplemental */
1109 #ifdef HAVECSD_SUPPLEMENTAL
1110                                 ctp = csd_supplemental;
1111 #endif
1112                                 break;
1113
1114                         case '=': /* Swiss */
1115 #ifdef HAVECSD_SWISS
1116                                 ctp = csd_swiss;
1117 #endif
1118                                 break;
1119
1120                         case '>': /* DEC Technical */
1121 #ifdef HAVECSD_TECHNICAL
1122                                 ctp = csd_technical;
1123 #endif
1124                                 break;
1125
1126                         default:
1127                                 break;
1128                 }
1129         }
1130         swcsp(svsp, ctp);
1131 }
1132
1133 /*---------------------------------------------------------------------------*
1134  *      device attributes
1135  *---------------------------------------------------------------------------*/
1136 void
1137 vt_da(struct video_state *svsp)
1138 {
1139         static u_char *response = (u_char *)DA_VT220;
1140
1141         svsp->report_chars = response;
1142         svsp->report_count = 18;
1143         respond(svsp);
1144 }
1145
1146 /*---------------------------------------------------------------------------*
1147  *      screen alignment display
1148  *---------------------------------------------------------------------------*/
1149 void
1150 vt_aln(struct video_state *svsp)
1151 {
1152         register int i;
1153
1154         svsp->cur_offset = 0;
1155         svsp->col = 0;
1156
1157         for(i=0; i < (svsp->screen_rows*svsp->maxcol); i++)
1158         {
1159                 *(svsp->Crtat + svsp->cur_offset) = user_attr | 'E';
1160                 vt_selattr(svsp);
1161                 svsp->cur_offset++;
1162                 svsp->col++;
1163         }
1164
1165         svsp->cur_offset = 0;   /* reset everything ! */
1166         svsp->col = 0;
1167         svsp->row = 0;
1168 }
1169
1170 /*---------------------------------------------------------------------------*
1171  *      request terminal parameters
1172  *---------------------------------------------------------------------------*/
1173 void
1174 vt_reqtparm(struct video_state *svsp)
1175 {
1176         static u_char *answr = (u_char *)"\033[3;1;1;120;120;1;0x";
1177
1178         svsp->report_chars = answr;
1179         svsp->report_count = 20;
1180         respond(svsp);
1181 }
1182
1183 /*---------------------------------------------------------------------------*
1184  *      invoke selftest
1185  *---------------------------------------------------------------------------*/
1186 void
1187 vt_tst(struct video_state *svsp)
1188 {
1189         clear_dld(svsp);
1190 }
1191
1192 /*---------------------------------------------------------------------------*
1193  *      device status reports
1194  *---------------------------------------------------------------------------*/
1195 void
1196 vt_dsr(struct video_state *svsp)
1197 {
1198         static u_char *answr = (u_char *)"\033[0n";
1199         static u_char *panswr = (u_char *)"\033[?13n"; /* Printer Unattached */
1200         static u_char *udkanswr = (u_char *)"\033[?21n"; /* UDK Locked */
1201         static u_char *langanswr = (u_char *)"\033[?27;1n"; /* North American*/
1202         static u_char buffer[16];
1203         int i = 0;
1204
1205         switch(svsp->parms[0])
1206         {
1207                 case 5:         /* return status */
1208                         svsp->report_chars = answr;
1209                         svsp->report_count = 4;
1210                         respond(svsp);
1211                         break;
1212
1213                 case 6:         /* return cursor position */
1214                         buffer[i++] = 0x1b;
1215                         buffer[i++] = '[';
1216                         if((svsp->row+1) > 10)
1217                                 buffer[i++] = ((svsp->row+1) / 10) + '0';
1218                         buffer[i++] = ((svsp->row+1) % 10) + '0';
1219                         buffer[i++] = ';';
1220                         if((svsp->col+1) > 10)
1221                                 buffer[i++] = ((svsp->col+1) / 10) + '0';
1222                         buffer[i++] = ((svsp->col+1) % 10) + '0';
1223                         buffer[i++] = 'R';
1224                         buffer[i++] = '\0';
1225
1226                         svsp->report_chars = buffer;
1227                         svsp->report_count = i;
1228                         respond(svsp);
1229                         break;
1230
1231                 case 15:        /* return printer status */
1232                         svsp->report_chars = panswr;
1233                         svsp->report_count = 6;
1234                         respond(svsp);
1235                         break;
1236
1237                 case 25:        /* return udk status */
1238                         svsp->report_chars = udkanswr;
1239                         svsp->report_count = 6;
1240                         respond(svsp);
1241                         break;
1242
1243                 case 26:        /* return language status */
1244                         svsp->report_chars = langanswr;
1245                         svsp->report_count = 8;
1246                         respond(svsp);
1247                         break;
1248
1249                 default:        /* nothing else valid */
1250                         break;
1251         }
1252 }
1253
1254 /*---------------------------------------------------------------------------*
1255  *      IL - insert line
1256  *---------------------------------------------------------------------------*/
1257 void
1258 vt_il(struct video_state *svsp)
1259 {
1260         register int p = svsp->parms[0];
1261
1262         if((svsp->row >= svsp->scrr_beg) && (svsp->row <= svsp->scrr_end))
1263         {
1264                 if(p <= 0)
1265                         p = 1;
1266                 else if(p > svsp->scrr_end - svsp->row)
1267                         p = svsp->scrr_end - svsp->row;
1268
1269                 svsp->cur_offset -= svsp->col;
1270                 svsp->col = 0;
1271                 if(svsp->row == svsp->scrr_beg)
1272                         roll_down(svsp, p);
1273                 else
1274                 {
1275                     bcopy(svsp->Crtat + svsp->cur_offset,
1276                           svsp->Crtat + svsp->cur_offset + (p * svsp->maxcol),
1277                           svsp->maxcol * (svsp->scrr_end-svsp->row+1-p) * CHR );
1278
1279                     fillw(user_attr | ' ',
1280                           svsp->Crtat + svsp->cur_offset,
1281                           p * svsp->maxcol);
1282                 }
1283         }
1284 }
1285
1286 /*---------------------------------------------------------------------------*
1287  *      ICH - insert character
1288  *---------------------------------------------------------------------------*/
1289 void
1290 vt_ic(struct video_state *svsp)
1291 {
1292         register int p = svsp->parms[0];
1293
1294         if(p <= 0)
1295                 p = 1;
1296         else if(p > svsp->maxcol-svsp->col)
1297                 p = svsp->maxcol-svsp->col;
1298
1299         while(p--)
1300         {
1301                 bcopy((svsp->Crtat + svsp->cur_offset),
1302                       (svsp->Crtat + svsp->cur_offset) + 1,
1303                       (((svsp->maxcol)-1)-svsp->col) * CHR);
1304
1305                 *(svsp->Crtat + svsp->cur_offset) = user_attr | ' ';
1306                 vt_selattr(svsp);
1307         }
1308 }
1309
1310 /*---------------------------------------------------------------------------*
1311  *      DL - delete line
1312  *---------------------------------------------------------------------------*/
1313 void
1314 vt_dl(struct video_state *svsp)
1315 {
1316         register int p = svsp->parms[0];
1317
1318         if((svsp->row >= svsp->scrr_beg) && (svsp->row <= svsp->scrr_end))
1319         {
1320                 if(p <= 0)
1321                         p = 1;
1322                 else if(p > svsp->scrr_end - svsp->row)
1323                         p = svsp->scrr_end - svsp->row;
1324
1325                 svsp->cur_offset -= svsp->col;
1326                 svsp->col = 0;
1327
1328                 if(svsp->row == svsp->scrr_beg)
1329                         roll_up(svsp, p);
1330                 else
1331                 {
1332                     bcopy(svsp->Crtat + svsp->cur_offset + (p * svsp->maxcol),
1333                           svsp->Crtat + svsp->cur_offset,
1334                           svsp->maxcol * (svsp->scrr_end-svsp->row+1-p) * CHR );
1335
1336                     fillw(user_attr | ' ',
1337                           svsp->Crtat + ((svsp->scrr_end-p+1) * svsp->maxcol),
1338                           p * svsp->maxcol);
1339                 }
1340         }
1341 }
1342
1343 /*---------------------------------------------------------------------------*
1344  *      DCH - delete character
1345  *---------------------------------------------------------------------------*/
1346 void
1347 vt_dch(struct video_state *svsp)
1348 {
1349         register int p = svsp->parms[0];
1350
1351         if(p <= 0)
1352                 p = 1;
1353         else if(p > svsp->maxcol-svsp->col)
1354                 p = svsp->maxcol-svsp->col;
1355
1356         while(p--)
1357         {
1358                 bcopy((svsp->Crtat + svsp->cur_offset)+1,
1359                       (svsp->Crtat + svsp->cur_offset),
1360                       (((svsp->maxcol)-1) - svsp->col)* CHR );
1361
1362                 *((svsp->Crtat + svsp->cur_offset) +
1363                         ((svsp->maxcol)-1)-svsp->col) = user_attr | ' ';
1364         }
1365 }
1366
1367 /*---------------------------------------------------------------------------*
1368  *      scroll up
1369  *---------------------------------------------------------------------------*/
1370 void
1371 vt_su(struct video_state *svsp)
1372 {
1373         register int p = svsp->parms[0];
1374
1375         if(p <= 0)
1376                 p = 1;
1377         else if(p > svsp->screen_rows-1)
1378                 p = svsp->screen_rows-1;
1379
1380         roll_up(svsp, p);
1381 }
1382
1383 /*---------------------------------------------------------------------------*
1384  *      scroll down
1385  *---------------------------------------------------------------------------*/
1386 void
1387 vt_sd(struct video_state *svsp)
1388 {
1389         register int p = svsp->parms[0];
1390
1391         if(p <= 0)
1392                 p = 1;
1393         else if(p > svsp->screen_rows-1)
1394                 p = svsp->screen_rows-1;
1395
1396         roll_down(svsp, p);
1397 }
1398
1399 /*---------------------------------------------------------------------------*
1400  *      ECH - erase character
1401  *---------------------------------------------------------------------------*/
1402 void
1403 vt_ech(struct video_state *svsp)
1404 {
1405         register int p = svsp->parms[0];
1406
1407         if(p <= 0)
1408                 p = 1;
1409         else if(p > svsp->maxcol-svsp->col)
1410                 p = svsp->maxcol-svsp->col;
1411
1412         fillw(user_attr | ' ', (svsp->Crtat + svsp->cur_offset), p);
1413 }
1414
1415 /*---------------------------------------------------------------------------*
1416  *      media copy      (NO PRINTER AVAILABLE IN KERNEL ...)
1417  *---------------------------------------------------------------------------*/
1418 void
1419 vt_mc(struct video_state *svsp)
1420 {
1421 }
1422
1423 /*---------------------------------------------------------------------------*
1424  *      Device Control String State Machine Entry for:
1425  *
1426  *      DECUDK - user-defined keys      and
1427  *      DECDLD - downloadable charset
1428  *
1429  *---------------------------------------------------------------------------*/
1430 void
1431 vt_dcsentry(U_char ch, struct video_state *svsp)
1432 {
1433         switch(svsp->dcs_state)
1434         {
1435                 case DCS_INIT:
1436                         switch(ch)
1437                         {
1438                                 case '0':
1439                                 case '1':
1440                                 case '2':
1441                                 case '3':
1442                                 case '4':
1443                                 case '5':
1444                                 case '6':
1445                                 case '7':
1446                                 case '8':
1447                                 case '9':       /* parameters */
1448                                         svsp->parms[svsp->parmi] *= 10;
1449                                         svsp->parms[svsp->parmi] += (ch -'0');
1450                                         break;
1451
1452                                 case ';':       /* next parameter */
1453                                         svsp->parmi =
1454                                                 (svsp->parmi+1 < MAXPARMS) ?
1455                                                 svsp->parmi+1 : svsp->parmi;
1456                                         break;
1457
1458                                 case '|':       /* DECUDK */
1459                                         svsp->transparent = 1;
1460                                         init_udk(svsp);
1461                                         svsp->dcs_state = DCS_AND_UDK;
1462                                         break;
1463
1464                                 case '{':       /* DECDLD */
1465                                         svsp->transparent = 1;
1466                                         init_dld(svsp);
1467                                         svsp->dcs_state = DCS_DLD_DSCS;
1468                                         break;
1469
1470                                 default:         /* failsafe */
1471                                         svsp->transparent = 0;
1472                                         svsp->state = STATE_INIT;
1473                                         svsp->dcs_state = DCS_INIT;
1474                                         break;
1475                         }
1476                         break;
1477
1478                 case DCS_AND_UDK:        /* DCS ... | */
1479                         switch(ch)
1480                         {
1481                                 case '0':
1482                                 case '1':
1483                                 case '2':
1484                                 case '3':
1485                                 case '4':
1486                                 case '5':
1487                                 case '6':
1488                                 case '7':
1489                                 case '8':
1490                                 case '9':       /* fkey number */
1491                                         svsp->udk_fnckey *= 10;
1492                                         svsp->udk_fnckey += (ch -'0');
1493                                         break;
1494
1495                                 case '/':       /* Key */
1496                                         svsp->dcs_state = DCS_UDK_DEF;
1497                                         break;
1498
1499                                 case 0x1b:       /* ESC */
1500                                         svsp->dcs_state = DCS_UDK_ESC;
1501                                         break;
1502
1503                                 default:
1504                                         svsp->transparent = 0;
1505                                         svsp->state = STATE_INIT;
1506                                         svsp->dcs_state = DCS_INIT;
1507                                         break;
1508                         }
1509                         break;
1510
1511                 case DCS_UDK_DEF:        /* DCS ... | fnckey / */
1512                         switch(ch)
1513                         {
1514                                 case '0':
1515                                 case '1':
1516                                 case '2':
1517                                 case '3':
1518                                 case '4':
1519                                 case '5':
1520                                 case '6':
1521                                 case '7':
1522                                 case '8':
1523                                 case '9':
1524                                         if(svsp->udk_deflow)    /* low nibble */
1525                                         {
1526                                                 svsp->udk_def[svsp->udk_defi] |= (ch -'0');
1527                                                 svsp->udk_deflow = 0;
1528                                                 svsp->udk_defi = (svsp->udk_defi+1 >= MAXUDKDEF) ?
1529                                                 svsp->udk_defi : svsp->udk_defi+1;
1530                                         }
1531                                         else                    /* high nibble */
1532                                         {
1533                                                 svsp->udk_def[svsp->udk_defi] = ((ch -'0') << 4);
1534                                                 svsp->udk_deflow = 1;
1535                                         }
1536                                         break;
1537
1538                                 case 'a':
1539                                 case 'b':
1540                                 case 'c':
1541                                 case 'd':
1542                                 case 'e':
1543                                 case 'f':
1544                                         if(svsp->udk_deflow)    /* low nibble */
1545                                         {
1546                                                 svsp->udk_def[svsp->udk_defi] |= (ch - 'a' + 10);
1547                                                 svsp->udk_deflow = 0;
1548                                                 svsp->udk_defi = (svsp->udk_defi+1 >= MAXUDKDEF) ?
1549                                                 svsp->udk_defi : svsp->udk_defi+1;
1550                                         }
1551                                         else                    /* high nibble */
1552                                         {
1553                                                 svsp->udk_def[svsp->udk_defi] = ((ch - 'a' + 10) << 4);
1554                                                 svsp->udk_deflow = 1;
1555                                         }
1556                                         break;
1557
1558
1559
1560                                 case 'A':
1561                                 case 'B':
1562                                 case 'C':
1563                                 case 'D':
1564                                 case 'E':
1565                                 case 'F':
1566                                         if(svsp->udk_deflow)    /* low nibble */
1567                                         {
1568                                                 svsp->udk_def[svsp->udk_defi] |= (ch - 'A' + 10);
1569                                                 svsp->udk_deflow = 0;
1570                                                 svsp->udk_defi = (svsp->udk_defi+1 >= MAXUDKDEF) ?
1571                                                 svsp->udk_defi : svsp->udk_defi+1;
1572                                         }
1573                                         else                    /* high nibble */
1574                                         {
1575                                                 svsp->udk_def[svsp->udk_defi] = ((ch - 'A' + 10) << 4);
1576                                                 svsp->udk_deflow = 1;
1577                                         }
1578                                         break;
1579
1580                                 case ';':       /* next function key */
1581                                         vt_udk(svsp);
1582                                         svsp->dcs_state = DCS_AND_UDK;
1583                                         break;
1584
1585                                 case 0x1b:       /* ESC */
1586                                         svsp->dcs_state = DCS_UDK_ESC;
1587                                         break;
1588
1589                                 default:
1590                                         svsp->transparent = 0;
1591                                         svsp->state = STATE_INIT;
1592                                         svsp->dcs_state = DCS_INIT;
1593                                         break;
1594                         }
1595                         break;
1596
1597                 case DCS_UDK_ESC:        /* DCS ... | fkey/def ... ESC */
1598                         switch(ch)
1599                         {
1600                                 case '\\':      /* ST */
1601                                         vt_udk(svsp);
1602                                         svsp->transparent = 0;
1603                                         svsp->state = STATE_INIT;
1604                                         svsp->dcs_state = DCS_INIT;
1605                                         break;
1606
1607                                 default:
1608                                         svsp->transparent = 0;
1609                                         svsp->state = STATE_INIT;
1610                                         svsp->dcs_state = DCS_INIT;
1611                                         break;
1612                         }
1613                         break;
1614
1615
1616                 case DCS_DLD_DSCS:       /* got DCS ... { */
1617                         if(ch >= ' ' && ch <= '/')      /* intermediates ... */
1618                         {
1619                                 svsp->dld_dscs[svsp->dld_dscsi] = ch;
1620                                 svsp->dld_id[svsp->dld_dscsi] = ch;
1621                                 if(svsp->dld_dscsi >= DSCS_LENGTH)
1622                                 {
1623                                         svsp->transparent = 0;
1624                                         svsp->state = STATE_INIT;
1625                                         svsp->dcs_state = DCS_INIT;
1626                                         svsp->dld_id[0] = '\0';
1627                                 }
1628                                 else
1629                                 {
1630                                         svsp->dld_dscsi++;
1631                                 }
1632                         }
1633                         else if(ch >= '0' && ch <= '~') /* final .... */
1634                         {
1635                                 svsp->dld_dscs[svsp->dld_dscsi] = ch;
1636                                 svsp->dld_id[svsp->dld_dscsi++] = ch;
1637                                 svsp->dld_id[svsp->dld_dscsi] = '\0';
1638                                 svsp->dcs_state = DCS_DLD_DEF;
1639                         }
1640                         else
1641                         {
1642                                 svsp->transparent = 0;
1643                                 svsp->state = STATE_INIT;
1644                                 svsp->dcs_state = DCS_INIT;
1645                                 svsp->dld_id[0] = '\0';
1646                         }
1647                         break;
1648
1649                 case DCS_DLD_DEF:        /* DCS ... { dscs */
1650                         switch(ch)
1651                         {
1652                                 case 0x1b:       /* ESC */
1653                                         svsp->dcs_state = DCS_DLD_ESC;
1654                                         break;
1655
1656                                 case '/':        /* sixel upper / lower divider */
1657                                         svsp->dld_sixel_lower = 1;
1658                                         break;
1659
1660                                 case ';':        /* character divider */
1661                                         vt_dld(svsp);
1662                                         svsp->parms[1]++;       /* next char */
1663                                         break;
1664
1665                                 default:
1666                                         if (svsp->dld_sixel_lower)
1667                                         {
1668                                                 if(ch >= '?' && ch <= '~')
1669                                                         svsp->sixel.lower[svsp->dld_sixelli] = ch - '?';
1670                                                 svsp->dld_sixelli =
1671                                                  (svsp->dld_sixelli+1 < MAXSIXEL) ?
1672                                                  svsp->dld_sixelli+1 : svsp->dld_sixelli;
1673                                         }
1674                                         else
1675                                         {
1676                                                 if(ch >= '?' && ch <= '~')
1677                                                         svsp->sixel.upper[svsp->dld_sixelui] = ch - '?';
1678                                                 svsp->dld_sixelui =
1679                                                  (svsp->dld_sixelui+1 < MAXSIXEL) ?
1680                                                  svsp->dld_sixelui+1 : svsp->dld_sixelui;
1681                                         }
1682                                         break;
1683                         }
1684                         break;
1685
1686                 case DCS_DLD_ESC:        /* DCS ... { dscs ... / ... ESC */
1687                         switch(ch)
1688                         {
1689                                 case '\\':      /* String Terminator ST */
1690                                         vt_dld(svsp);
1691                                         svsp->transparent = 0;
1692                                         svsp->state = STATE_INIT;
1693                                         svsp->dcs_state = DCS_INIT;
1694                                         break;
1695
1696                                 default:
1697                                         svsp->transparent = 0;
1698                                         svsp->state = STATE_INIT;
1699                                         svsp->dcs_state = DCS_INIT;
1700                                         svsp->dld_id[0] = '\0';
1701                                         break;
1702                         }
1703                         break;
1704
1705                 default:
1706                         svsp->transparent = 0;
1707                         svsp->state = STATE_INIT;
1708                         svsp->dcs_state = DCS_INIT;
1709                         break;
1710         }
1711 }
1712
1713 /*---------------------------------------------------------------------------*
1714  *      User Defineable Keys
1715  *---------------------------------------------------------------------------*/
1716 void
1717 vt_udk(struct video_state *svsp)
1718 {
1719         int key, start, max, i;
1720         int usedff = 0;
1721
1722         if(svsp->parms[0] != 1)         /* clear all ? */
1723         {
1724                 vt_clearudk(svsp);
1725                 svsp->parms[0] = 1;
1726         }
1727
1728         if(svsp->udk_fnckey < 17 || svsp->udk_fnckey > 34)
1729         {
1730                 init_udk(svsp);
1731                 return;
1732         }
1733
1734         key = svsp->udk_fnckey - 17;    /* index into table */
1735
1736         if(svsp->ukt.length[key] == 0)                  /* never used ? */
1737         {
1738                 if(svsp->udkff < MAXUDKDEF-2)           /* space available ? */
1739                 {
1740                         start = svsp->udkff;            /* next sequential */
1741                         max = MAXUDKDEF - svsp->udkff;  /* space available */
1742                         svsp->ukt.first[key] = start;   /* start entry */
1743                         usedff = 1;                     /* flag to update later */
1744                 }
1745                 else                                    /* no space */
1746                 {
1747                         init_udk(svsp);
1748                         return;
1749                 }
1750         }
1751         else                                            /* in use, redefine */
1752         {
1753                 start = svsp->ukt.first[key];           /* start entry */
1754                 max = svsp->ukt.length[key];            /* space available */
1755         }
1756
1757         if(max < 2)                             /* hmmm .. */
1758         {
1759                 init_udk(svsp);
1760                 return;
1761         }
1762
1763         max--;          /* adjust for tailing '\0' */
1764
1765         for(i = 0; i < max && i < svsp->udk_defi; i++)
1766                 svsp->udkbuf[start++] = svsp->udk_def[i];
1767
1768         svsp->udkbuf[start] = '\0';     /* make it a string, see pcvt_kbd.c */
1769         svsp->ukt.length[key] = i+1;    /* count for tailing '\0' */
1770         if(usedff)
1771                 svsp->udkff += (i+2);   /* new start location */
1772
1773         init_udk(svsp);
1774 }
1775
1776 /*---------------------------------------------------------------------------*
1777  *      clear all User Defineable Keys
1778  *---------------------------------------------------------------------------*/
1779 void
1780 vt_clearudk(struct video_state *svsp)
1781 {
1782         register int i;
1783
1784         for(i = 0; i < MAXUDKEYS; i++)
1785         {
1786                 svsp->ukt.first[i] = 0;
1787                 svsp->ukt.length[i] = 0;
1788         }
1789         svsp->udkff = 0;
1790 }
1791
1792 /*---------------------------------------------------------------------------*
1793  *      Down line LoaDable Fonts
1794  *---------------------------------------------------------------------------*/
1795 void
1796 vt_dld(struct video_state *svsp)
1797 {
1798         unsigned char vgacharset;
1799         unsigned char vgachar[16];
1800         unsigned char vgacharb[16];
1801
1802         if(vgacs[svsp->vga_charset].secondloaded)
1803                 vgacharset = vgacs[svsp->vga_charset].secondloaded;
1804         else
1805                 return;
1806
1807         svsp->parms[1] = (svsp->parms[1] < 1) ? 1 :
1808                 ((svsp->parms[1] > 0x7E) ? 0x7E : svsp->parms[1]);
1809
1810         if(svsp->parms[2] != 1)   /* Erase all characters ? */
1811         {
1812                 clear_dld(svsp);
1813                 svsp->parms[2] = 1;   /* Only erase all characters once per sequence */
1814         }
1815
1816         sixel_vga(&(svsp->sixel),vgachar);
1817
1818         switch(vgacs[vgacharset].char_scanlines & 0x1F)
1819         {
1820                 case 7:
1821                         vga10_vga8(vgachar,vgacharb);
1822                         break;
1823
1824                 case 9:
1825                 default:
1826                         vga10_vga10(vgachar,vgacharb);
1827                         break;
1828
1829                 case 13:
1830                         vga10_vga14(vgachar,vgacharb);
1831                         break;
1832
1833                 case 15:
1834                         vga10_vga16(vgachar,vgacharb);
1835                         break;
1836         }
1837
1838         loadchar(vgacharset, svsp->parms[1] + 0xA0, 16, vgacharb);
1839
1840         init_dld(svsp);
1841 }
1842
1843 /*---------------------------------------------------------------------------*
1844  *      select character attributes
1845  *---------------------------------------------------------------------------*/
1846 void
1847 vt_sca(struct video_state *svsp)
1848 {
1849         switch(svsp->parms[0])
1850         {
1851                 case 1:
1852                         svsp->selchar = 1;
1853                         break;
1854                 case 0:
1855                 case 2:
1856                 default:
1857                         svsp->selchar = 0;
1858                         break;
1859         }
1860 }
1861
1862 /*---------------------------------------------------------------------------*
1863  *      initalize selective attribute bit array
1864  *---------------------------------------------------------------------------*/
1865 void
1866 vt_initsel(struct video_state *svsp)
1867 {
1868         register int i;
1869
1870         for(i = 0;i < MAXDECSCA;i++)
1871                 svsp->decsca[i] = 0;
1872 }
1873
1874 /*---------------------------------------------------------------------------*
1875  *      DECSEL - selective erase in line
1876  *---------------------------------------------------------------------------*/
1877 void
1878 vt_sel(struct video_state *svsp)
1879 {
1880         switch(svsp->parms[0])
1881         {
1882                 case 0:
1883                         selective_erase(svsp, (svsp->Crtat + svsp->cur_offset),
1884                                          svsp->maxcol-svsp->col);
1885                         break;
1886
1887                 case 1:
1888                         selective_erase(svsp, (svsp->Crtat + svsp->cur_offset)-
1889                                         svsp->col, svsp->col + 1);
1890                         break;
1891
1892                 case 2:
1893                         selective_erase(svsp, (svsp->Crtat + svsp->cur_offset)-
1894                                         svsp->col, svsp->maxcol);
1895                         break;
1896         }
1897 }
1898
1899 /*---------------------------------------------------------------------------*
1900  *      DECSED - selective erase in display
1901  *---------------------------------------------------------------------------*/
1902 void
1903 vt_sed(struct video_state *svsp)
1904 {
1905         switch(svsp->parms[0])
1906         {
1907                 case 0:
1908                         selective_erase(svsp, (svsp->Crtat + svsp->cur_offset),
1909                               svsp->Crtat + (svsp->maxcol * svsp->screen_rows) -
1910                               (svsp->Crtat + svsp->cur_offset));
1911                         break;
1912
1913                 case 1:
1914                         selective_erase(svsp, svsp->Crtat,
1915                            (svsp->Crtat + svsp->cur_offset) - svsp->Crtat + 1 );
1916                         break;
1917
1918                 case 2:
1919                         selective_erase(svsp, svsp->Crtat,
1920                                 svsp->maxcol * svsp->screen_rows);
1921                         break;
1922         }
1923 }
1924
1925 /*---------------------------------------------------------------------------*
1926  *      scroll screen n lines up
1927  *---------------------------------------------------------------------------*/
1928 void
1929 roll_up(struct video_state *svsp, int n)
1930 {
1931
1932 #if (PCVT_NOFASTSCROLL==0)
1933
1934         if(svsp->scrr_beg == 0 &&       /* if scroll region is whole screen */
1935            svsp->scrr_len == svsp->screen_rows &&
1936            (svsp != vsp ||              /* and either running in memory */
1937             (svsp->screen_rows == svsp->screen_rowsize && /* or no fkeys */
1938              adaptor_type != MDA_ADAPTOR)))     /* and not on MDA/Hercules */
1939         {
1940                 u_short *Memory =
1941
1942 #if PCVT_USL_VT_COMPAT
1943                     (vsp != svsp || (vsp->vt_status & VT_GRAFX)) ?
1944 #else
1945                     (vsp != svsp) ?
1946 #endif
1947
1948                                 svsp->Memory : Crtat;
1949
1950                 if(svsp->Crtat > (Memory + (svsp->screen_rows - n) *
1951                                         svsp->maxcol))
1952                 {
1953                         bcopy(svsp->Crtat + svsp->maxcol * n, Memory,
1954                               svsp->maxcol * (svsp->screen_rows - n) * CHR);
1955
1956                         svsp->Crtat = Memory;
1957                 }
1958                 else
1959                 {
1960                         svsp->Crtat += n * svsp->maxcol;
1961                 }
1962
1963 #if PCVT_USL_VT_COMPAT
1964                 if(vsp == svsp && !(vsp->vt_status & VT_GRAFX))
1965 #else
1966                 if(vsp == svsp)
1967 #endif
1968
1969                 {
1970                         outb(addr_6845, CRTC_STARTADRH);
1971                         outb(addr_6845+1, (svsp->Crtat - Crtat) >> 8);
1972                         outb(addr_6845, CRTC_STARTADRL);
1973                         outb(addr_6845+1, (svsp->Crtat - Crtat));
1974                 }
1975         }
1976         else
1977 #endif
1978         {
1979                 bcopy(  svsp->Crtat + ((svsp->scrr_beg + n) * svsp->maxcol),
1980                         svsp->Crtat + (svsp->scrr_beg * svsp->maxcol),
1981                         svsp->maxcol * (svsp->scrr_len - n) * CHR );
1982         }
1983
1984         fillw(  user_attr | ' ',
1985                 svsp->Crtat + ((svsp->scrr_end - n + 1) * svsp->maxcol),
1986                 n * svsp->maxcol);
1987
1988 /*XXX*/ if(svsp->scroll_lock && svsp->openf && curproc)
1989                 tsleep((caddr_t)&(svsp->scroll_lock), PPAUSE, "scrlck", 0);
1990 }
1991
1992 /*---------------------------------------------------------------------------*
1993  *      scroll screen n lines down
1994  *---------------------------------------------------------------------------*/
1995 static void
1996 roll_down(struct video_state *svsp, int n)
1997 {
1998
1999 #if (PCVT_NOFASTSCROLL==0)
2000
2001         if(svsp->scrr_beg == 0 &&       /* if scroll region is whole screen */
2002            svsp->scrr_len == svsp->screen_rows &&
2003            (svsp != vsp ||              /* and either running in memory */
2004             (svsp->screen_rows == svsp->screen_rowsize && /* or no fkeys */
2005              adaptor_type != MDA_ADAPTOR)))     /* and not on MDA/Hercules */
2006         {
2007                 u_short *Memory =
2008
2009 #if PCVT_USL_VT_COMPAT
2010                     (vsp != svsp || (vsp->vt_status & VT_GRAFX)) ?
2011 #else
2012                     (vsp != svsp) ?
2013 #endif
2014                                 svsp->Memory : Crtat;
2015
2016                 if (svsp->Crtat < (Memory + n * svsp->maxcol))
2017                 {
2018                         bcopy(svsp->Crtat,
2019                               Memory + svsp->maxcol * (svsp->screen_rows + n),
2020                               svsp->maxcol * (svsp->screen_rows - n) * CHR);
2021
2022                         svsp->Crtat = Memory + svsp->maxcol * svsp->screen_rows;
2023                 }
2024                 else
2025                 {
2026                         svsp->Crtat -= n * svsp->maxcol;
2027                 }
2028
2029 #if PCVT_USL_VT_COMPAT
2030                 if(vsp == svsp && !(vsp->vt_status & VT_GRAFX))
2031 #else
2032                 if(vsp == svsp)
2033 #endif
2034
2035                 {
2036                         outb(addr_6845, CRTC_STARTADRH);
2037                         outb(addr_6845+1, (svsp->Crtat - Crtat) >> 8);
2038                         outb(addr_6845, CRTC_STARTADRL);
2039                         outb(addr_6845+1, (svsp->Crtat - Crtat));
2040                 }
2041         }
2042         else
2043 #endif
2044         {
2045                 bcopy(  svsp->Crtat + (svsp->scrr_beg * svsp->maxcol),
2046                         svsp->Crtat + ((svsp->scrr_beg + n) * svsp->maxcol),
2047                         svsp->maxcol * (svsp->scrr_len - n) * CHR );
2048         }
2049
2050         fillw(  user_attr | ' ',
2051                 svsp->Crtat + (svsp->scrr_beg * svsp->maxcol),
2052                 n * svsp->maxcol);
2053
2054 /*XXX*/ if(svsp->scroll_lock && svsp->openf && curproc)
2055                 tsleep((caddr_t)&(svsp->scroll_lock), PPAUSE, "scrlck", 0);
2056 }
2057
2058 /*---------------------------------------------------------------------------*
2059  *      switch charset pointers
2060  *---------------------------------------------------------------------------*/
2061 static void
2062 swcsp(struct video_state *svsp, u_short *ctp)
2063 {
2064         if(ctp == NULL)
2065                 return;
2066
2067         switch(svsp->state)
2068         {
2069                 case STATE_BROPN:       /* designate G0 */
2070                         svsp->G0 = ctp;
2071                         break;
2072
2073                 case STATE_BRCLO:       /* designate G1 */
2074                 case STATE_MINUS:       /* designate G1 (96) */
2075                         svsp->G1 = ctp;
2076                         break;
2077
2078                 case STATE_STAR:        /* designate G2 */
2079                 case STATE_DOT:         /* designate G2 (96) */
2080                         svsp->G2 = ctp;
2081                         break;
2082
2083                 case STATE_PLUS:        /* designate G3 */
2084                 case STATE_SLASH:       /* designate G3 (96) */
2085                         svsp->G3 = ctp;
2086                         break;
2087         }
2088 }
2089
2090 /*---------------------------------------------------------------------------*
2091  *      process terminal responses
2092  *---------------------------------------------------------------------------*/
2093 static void
2094 respond(struct video_state *svsp)
2095 {
2096         if(!(svsp->openf))              /* are we opened ? */
2097                 return;
2098
2099         while (*svsp->report_chars && svsp->report_count > 0)
2100         {
2101                 (*linesw[svsp->vs_tty->t_line].l_rint)
2102                         (*svsp->report_chars++ & 0xff, svsp->vs_tty);
2103                 svsp->report_count--;
2104         }
2105 }
2106
2107 /*---------------------------------------------------------------------------*
2108  *      Initialization for User Defineable Keys
2109  *---------------------------------------------------------------------------*/
2110 static void
2111 init_udk(struct video_state *svsp)
2112 {
2113         svsp->udk_defi = 0;
2114         svsp->udk_deflow = 0;
2115         svsp->udk_fnckey = 0;
2116 }
2117
2118 /*---------------------------------------------------------------------------*
2119  *      Clear loaded downloadable (DLD) character set
2120  *---------------------------------------------------------------------------*/
2121 static void
2122 clear_dld(struct video_state *svsp)
2123 {
2124         register int i;
2125         unsigned char vgacharset;
2126         unsigned char vgachar[16];
2127
2128         if(vgacs[svsp->vga_charset].secondloaded)
2129                 vgacharset = vgacs[svsp->vga_charset].secondloaded;
2130         else
2131                 return;
2132
2133         for(i=0;i < 16;i++)  /* A zeroed character, vt220 has inverted '?' */
2134                 vgachar[i] = 0x00;
2135
2136         for(i=1;i <= 94;i++) /* Load (erase) all characters */
2137                 loadchar(vgacharset, i + 0xA0, 16, vgachar);
2138 }
2139
2140 /*---------------------------------------------------------------------------*
2141  *      Initialization for Down line LoaDable Fonts
2142  *---------------------------------------------------------------------------*/
2143 static void
2144 init_dld(struct video_state *svsp)
2145 {
2146         register int i;
2147
2148         svsp->dld_dscsi = 0;
2149         svsp->dld_sixel_lower = 0;
2150         svsp->dld_sixelli = 0;
2151         svsp->dld_sixelui = 0;
2152
2153         for(i = 0;i < MAXSIXEL;i++)
2154                 svsp->sixel.lower[i] = svsp->sixel.upper[i] = 0;
2155 }
2156
2157 /*---------------------------------------------------------------------------*
2158  *      selective erase a region
2159  *---------------------------------------------------------------------------*/
2160 static void
2161 selective_erase(struct video_state *svsp, u_short *pcrtat, int length)
2162 {
2163         register int i, j;
2164
2165         for(j = pcrtat - svsp->Crtat, i = 0;i < length;i++,pcrtat++)
2166         {
2167                 if(!(svsp->decsca[INT_INDEX(j+i)] & (1 << BIT_INDEX(j+i))))
2168                 {
2169                         *pcrtat &= 0xFF00; /* Keep the video character attributes */
2170                         *pcrtat += ' ';    /* Erase the character */
2171                 }
2172         }
2173 }
2174
2175 #endif  /* NVT > 0 */
2176
2177 /* ------------------------- E O F ------------------------------------------*/
2178