1 /* $NetBSD: vga.c,v 1.9 2009/03/14 15:36:04 dsl Exp $ */
4 * Copyright (C) 1995-1997 Gary Thomas (gdt@linuxppc.org)
7 * VGA 'glass TTY' emulator
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by Gary Thomas.
20 * 4. The name of the author may not be used to endorse or promote products
21 * derived from this software without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 #include <lib/libsa/stand.h>
42 #define MONO_BASE 0x3B4
43 #define MONO_BUF 0xB0000
44 #define CGA_BASE 0x3D4
45 #define CGA_BUF 0xB8000
47 static u_char background
= 0; /* Black */
48 static u_char foreground
= 7; /* White */
55 * The current state of virtual displays
58 u_short
*cp
; /* the current character address */
60 NORMAL
, /* no pending escape */
63 EBRACEQ
/* saw ESC[= */
64 } state
; /* command parser state */
65 int cx
; /* the first escape seq argument */
66 int cy
; /* the second escap seq argument */
67 int *accp
; /* pointer to the current processed argument */
68 int row
; /* current column */
69 int so
; /* standout mode */
70 u_short color
; /* normal character color */
71 u_short color_so
; /* standout color */
72 u_short save_color
; /* saved normal color */
73 u_short save_color_so
; /* saved standout color */
77 * Color and attributes for normal, standout and kernel output
78 * are stored in the least-significant byte of a u_short
79 * so they don't have to be shifted for use.
80 * This is all byte-order dependent.
82 #define CATTR(x) (x) /* store color/attributes un-shifted */
83 #define ATTR_ADDR(which) (((u_char *)&(which))+1) /* address of attributes */
85 u_short pccolor
; /* color/attributes for tty output */
86 u_short pccolor_so
; /* color/attributes, standout mode */
88 static void cursor(void);
89 static void initscreen(void);
90 void fillw(u_short
, u_short
*, int);
95 * cursor() sets an offset (0-1999) into the 80x25 text area
100 int pos
= screen
.cp
- Crtat
;
102 if (lastpos
!= pos
) {
104 outb(addr_6845
+1, pos
>> 8);
106 outb(addr_6845
+1, pos
);
114 struct screen
*d
= &screen
;
116 pccolor
= CATTR((background
<<4)|foreground
);
117 pccolor_so
= CATTR((foreground
<<4)|background
);
119 d
->save_color
= pccolor
;
120 d
->color_so
= pccolor_so
;
121 d
->save_color_so
= pccolor_so
;
125 #define wrtchar(c, d) { \
132 fillw(u_short val
, u_short
*buf
, int num
)
134 /* Need to byte swap value */
143 * vga_putc (nee sput) has support for emulation of the 'ibmpc' termcap entry.
144 * This is a bare-bones implementation of a bare-bones entry
145 * One modification: Change li#24 to li#25 to reflect 25 lines
146 * "ca" is the color/attributes value (left-shifted by 8)
147 * or 0 if the current regular color for that screen is to be used.
152 struct screen
*d
= &screen
;
162 case 0x0: /* Ignore pad characters */
171 wrtchar(d
->color
| ' ', d
);
172 } while (d
->row
% 8);
175 case '\b': /* non-destructive backspace */
180 d
->row
+= COL
; /* prev column */
196 wrtchar(d
->color_so
|(c
<<8), d
);
198 wrtchar(d
->color
| (c
<<8), d
);
208 * In this state, the action at the end of the switch
209 * on the character type is to go to NORMAL state,
210 * and intermediate states do a return rather than break.
217 case 'A': /* back one row */
218 if (d
->cp
>= base
+ COL
)
222 case 'B': /* down one row */
226 case 'C': /* right cursor */
231 case 'D': /* left cursor */
236 d
->row
+= COL
; /* prev column ??? */
240 case 'J': /* Clear to end of display */
241 fillw(d
->color
|(' '<<8), d
->cp
, base
+ COL
* ROW
- d
->cp
);
244 case 'K': /* Clear to EOL */
245 fillw(d
->color
|(' '<<8), d
->cp
, COL
- (d
->cp
- base
) % COL
);
248 case 'H': /* Cursor move */
253 if (d
->cx
== 0 || d
->cy
== 0) {
257 d
->cp
= base
+ (d
->cx
- 1) * COL
+ d
->cy
- 1;
262 case '_': /* set cursor */
264 d
->cx
= 1; /* block */
266 d
->cx
= 12; /* underline */
268 outb(addr_6845
+1, d
->cx
);
270 outb(addr_6845
+1, 13);
273 case ';': /* Switch params in cursor def */
277 case '=': /* ESC[= color change */
281 case 'L': /* Insert line */
282 i
= (d
->cp
- base
) / COL
;
283 /* avoid deficiency of bcopy implementation */
284 /* XXX: comment and hack relevant? */
285 pp
= base
+ COL
* (ROW
-2);
286 for (j
= ROW
- 1 - i
; j
--; pp
-= COL
)
287 memmove(pp
+ COL
, pp
, COL
* CHR
);
288 fillw(d
->color
|(' '<<8), base
+ i
* COL
, COL
);
291 case 'M': /* Delete line */
292 i
= (d
->cp
- base
) / COL
;
294 memmove(pp
, pp
+ COL
, (ROW
-1 - i
)*COL
*CHR
);
295 fillw(d
->color
|(' '<<8), base
+ COL
* (ROW
- 1), COL
);
298 default: /* Only numbers valid here */
299 if ((c
>= '0') && (c
<= '9')) {
301 *(d
->accp
) += c
- '0';
311 * In this state, the action at the end of the switch
312 * on the character type is to go to NORMAL state,
313 * and intermediate states do a return rather than break.
318 * Set foreground/background color
319 * for normal mode, standout mode
321 * Based on code from kentp@svmp03.
325 colp
= ATTR_ADDR(d
->color
);
327 *colp
= (*colp
& 0xf0) | (d
->cx
);
331 colp
= ATTR_ADDR(d
->color
);
333 *colp
= (*colp
& 0xf) | (d
->cx
<< 4);
337 colp
= ATTR_ADDR(d
->color_so
);
341 colp
= ATTR_ADDR(d
->color_so
);
345 d
->save_color
= d
->color
;
346 d
->save_color_so
= d
->color_so
;
350 d
->color
= d
->save_color
;
351 d
->color_so
= d
->save_color_so
;
354 default: /* Only numbers valid here */
355 if ((c
>= '0') && (c
<= '9')) {
368 case 'c': /* Clear screen & home */
369 fillw(d
->color
|(' '<<8), base
, COL
* ROW
);
374 case '[': /* Start ESC [ sequence */
380 default: /* Invalid, clear state */
386 if (d
->cp
>= base
+ (COL
* ROW
)) { /* scroll check */
387 memmove(base
, base
+ COL
, COL
* (ROW
- 1) * CHR
);
388 fillw(d
->color
|(' '<<8), base
+ COL
* (ROW
- 1), COL
);
409 outb(0x3C5, inb(0x3C5) & ~0x20);
418 outb(0x3C5, inb(0x3C5) | 0x20);
422 vga_init(u_char
*ISA_mem
)
424 struct screen
*d
= &screen
;
426 memset(d
, 0, sizeof (screen
));
429 d
->cp
= Crtat
= (u_short
*)&ISA_mem
[0x0B8000];
430 addr_6845
= CGA_BASE
;
432 fillw(pccolor
|(' '<<8), d
->cp
, COL
* ROW
);
434 #endif /* CONS_VGA */