1 /*        $NetBSD: video.c,v 1.7 2005/12/11 12:17:04 christos Exp $   */
2 
3 /*-
4  * Copyright (C) 1995-1997 Gary Thomas (gdt@linuxppc.org)
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *      This product includes software developed by Gary Thomas.
18  * 4. The name of the author may not be used to endorse or promote products
19  *    derived from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 #ifdef CONS_BE
34 #include <lib/libsa/stand.h>
35 #include "boot.h"
36 #include "iso_font.h"
37 
38 #define   FONT_WIDTH          8
39 #define   FONT_HEIGHT         16
40 #define   VRAM_WIDTH          640
41 #define   VRAM_HEIGHT         480
42 #define   VRAM_SIZE (VRAM_WIDTH * VRAM_HEIGHT)
43 #define   ROW       (VRAM_WIDTH / FONT_WIDTH)
44 #define   COL       (VRAM_HEIGHT / FONT_HEIGHT)
45 
46 u_char *VramBase;
47 u_char save_cursor[FONT_WIDTH];
48 
49 /*
50  * The current state of virtual displays
51  */
52 struct screen {
53           enum state {
54                     NORMAL,             /* no pending escape */
55                     ESC,                /* saw ESC */
56                     EBRAC,              /* saw ESC[ */
57                     EBRACEQ             /* saw ESC[= */
58           } state;            /* command parser state */
59           int       cx;                 /* the first escape seq argument */
60           int       cy;                 /* the second escap seq argument */
61           int       *accp;              /* pointer to the current processed argument */
62           int       row;
63           int       col;
64           u_char fgcolor;
65           u_char bgcolor;
66 } screen;
67 
68 
69 void
video_init(u_char * buffer)70 video_init(u_char *buffer)
71 {
72           struct screen *d = &screen;
73 
74           VramBase = buffer;
75           d->fgcolor = 0x1f;  /* WHITE */
76           d->bgcolor = 0x00;  /* BLACK */
77           d->row = 0;
78           d->col = 0;
79           d->state = NORMAL;
80           memset(VramBase, d->bgcolor, VRAM_SIZE);
81           memset(save_cursor, d->bgcolor, FONT_WIDTH);
82 }
83 
84 static void
wrtchar(u_char c,struct screen * d)85 wrtchar(u_char c, struct screen *d)
86 {
87           u_char *p = VramBase +
88                     (d->col * VRAM_WIDTH * FONT_HEIGHT) + (d->row * FONT_WIDTH);
89           int fontbase = c * 16;
90           int x, y;
91 
92           for (y = 0; y < FONT_HEIGHT; y++) {
93                     for (x = 0; x < FONT_WIDTH; x++) {
94                               if ((font[fontbase + y] >> (FONT_WIDTH - x)) & 1)
95                                         *(p + x + (y * VRAM_WIDTH)) = d->fgcolor;
96                               else
97                                         *(p + x + (y * VRAM_WIDTH)) = d->bgcolor;
98                     }
99           }
100           d->row++;
101 }
102 
103 static void
cursor(struct screen * d,int flag)104 cursor(struct screen *d, int flag)
105 {
106           int x;
107           int y = FONT_HEIGHT - 1;
108 
109           u_char *p = VramBase +
110                     (d->col * VRAM_WIDTH * FONT_HEIGHT) + (d->row * FONT_WIDTH);
111           for (x = 0; x < FONT_WIDTH - 1; x++) {
112                     if (flag) {
113                               save_cursor[x] = *(p + x + (y * VRAM_WIDTH));
114                               *(p + x + (y * VRAM_WIDTH)) = d->fgcolor;
115                     } else {
116                               *(p + x + (y * VRAM_WIDTH)) = save_cursor[x];
117                     }
118           }
119 }
120 
121 /*
122  * vga_putc (nee sput) has support for emulation of the 'ibmpc' termcap entry.
123  * This is a bare-bones implementation of a bare-bones entry
124  * One modification: Change li#24 to li#25 to reflect 25 lines
125  * "ca" is the color/attributes value (left-shifted by 8)
126  * or 0 if the current regular color for that screen is to be used.
127  */
128 void
video_putc(int c)129 video_putc(int c)
130 {
131           struct screen *d = &screen;
132 
133           cursor(d, 0);
134 
135           switch (d->state) {
136           case NORMAL:
137                     switch (c) {
138                     case 0x0:           /* Ignore pad characters */
139                               return;
140 
141                     case 0x1B:
142                               d->state = ESC;
143                               break;
144 
145                     case '\t':
146                               do {
147                                         wrtchar(' ', d);
148                               } while (d->row % 8);
149                               break;
150 
151                     case '\b':  /* non-destructive backspace */
152                               d->row--;
153                               if (d->row < 0) {
154                                         if (d->col > 0) {
155                                                   d->col--;
156                                                   d->row += ROW;      /* prev column */
157                                         } else {
158                                                   d->row = 0;
159                                         }
160                               }
161                               break;
162 
163                     case '\n':
164                               d->col++;
165                               /* FALLTHROUGH */
166                     case '\r':
167                               d->row = 0;
168                               break;
169 
170                     case '\007':
171                               break;
172 
173                     default:
174                               wrtchar(c, d);
175                               if (d->row >= ROW) {
176                                         d->row = 0;
177                                         d->col++;
178                               }
179                               break;
180                     }
181                     break;
182 
183           case ESC:
184           case EBRAC:
185           case EBRACEQ:
186                     break;
187           }
188           if (d->col >= COL) {                    /* scroll check */
189                     memcpy(VramBase, VramBase + VRAM_WIDTH * FONT_HEIGHT,
190                               VRAM_SIZE - VRAM_WIDTH * FONT_WIDTH);
191                     memset(VramBase + VRAM_SIZE - VRAM_WIDTH * FONT_HEIGHT,
192                               d->bgcolor, VRAM_WIDTH * FONT_HEIGHT);
193                     d->col = COL - 1;
194           }
195           cursor(d, 1);
196 }
197 #endif
198