2 * Copyright (c) 1999 FreeBSD(98) Porting Team.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer as
10 * the first lines of this file unmodified.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #include "opt_syscons.h"
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/kernel.h>
37 #include <sys/malloc.h>
39 #include <machine/console.h>
40 #include <machine/md_var.h>
42 #include <dev/fb/fbreg.h>
43 #include <dev/syscons/syscons.h>
45 #define ATTR_OFFSET 0x2000
47 #define vtb_wrap(vtb, at, offset) \
48 (((at) + (offset) + (vtb)->vtb_size)%(vtb)->vtb_size)
50 static u_int16_t at2pc98(u_int16_t attr);
51 static vm_offset_t sc_vtb_attr_pointer(sc_vtb_t *vtb, int at);
54 at2pc98(u_int16_t attr)
56 static u_char ibmpc_to_pc98[16] = {
57 0x01, 0x21, 0x81, 0xa1, 0x41, 0x61, 0xc1, 0xe1,
58 0x09, 0x29, 0x89, 0xa9, 0x49, 0x69, 0xc9, 0xe9
60 static u_char ibmpc_to_pc98rev[16] = {
61 0x05, 0x25, 0x85, 0xa5, 0x45, 0x65, 0xc5, 0xe5,
62 0x0d, 0x2d, 0x8d, 0xad, 0x4d, 0x6d, 0xcd, 0xed
70 fg_at = ((attr >> 8) & 0x0F);
71 bg_at = ((attr >> 12) & 0x0F);
77 at = ibmpc_to_pc98rev[bg_at] | 0x02;
80 at = ibmpc_to_pc98[fg_at] | 0x02;
84 at = ibmpc_to_pc98rev[bg_at];
88 at = ibmpc_to_pc98[fg_at];
95 sc_vtb_init(sc_vtb_t *vtb, int type, int cols, int rows, void *buf, int wait)
100 vtb->vtb_rows = rows;
101 vtb->vtb_size = cols*rows;
102 vtb->vtb_buffer = NULL;
108 if ((buf == NULL) && (cols*rows != 0)) {
110 (vm_offset_t)malloc(cols*rows*sizeof(u_int16_t)*2,
112 (wait) ? M_WAITOK : M_NOWAIT);
113 if (vtb->vtb_buffer != NULL) {
114 bzero((void *)sc_vtb_pointer(vtb, 0),
115 cols*rows*sizeof(u_int16_t)*2);
118 vtb->vtb_buffer = (vm_offset_t)buf;
120 vtb->vtb_flags |= VTB_VALID;
122 case VTB_FRAMEBUFFER:
123 vtb->vtb_buffer = (vm_offset_t)buf;
124 vtb->vtb_flags |= VTB_VALID;
132 sc_vtb_destroy(sc_vtb_t *vtb)
143 vtb->vtb_buffer = NULL;
144 switch (vtb->vtb_type) {
148 free((void *)p, M_DEVBUF);
153 vtb->vtb_type = VTB_INVALID;
157 sc_vtb_size(int cols, int rows)
159 return (size_t)(cols*rows*sizeof(u_int16_t)*2);
163 sc_vtb_getc(sc_vtb_t *vtb, int at)
165 if (vtb->vtb_type == VTB_FRAMEBUFFER)
166 return (readw(sc_vtb_pointer(vtb, at)) & 0x00ff);
168 return (*(u_int16_t *)sc_vtb_pointer(vtb, at) & 0x00ff);
172 sc_vtb_geta(sc_vtb_t *vtb, int at)
174 if (vtb->vtb_type == VTB_FRAMEBUFFER)
175 return (readw(sc_vtb_attr_pointer(vtb, at)) & 0x00ff);
177 return (*(u_int16_t *)sc_vtb_attr_pointer(vtb, at) & 0x00ff);
181 sc_vtb_putc(sc_vtb_t *vtb, int at, int c, int a)
183 if (vtb->vtb_type == VTB_FRAMEBUFFER) {
184 writew(sc_vtb_pointer(vtb, at), c);
185 writew(sc_vtb_attr_pointer(vtb, at), at2pc98(a));
187 *(u_int16_t *)sc_vtb_pointer(vtb, at) = c;
188 *(u_int16_t *)sc_vtb_attr_pointer(vtb, at) = at2pc98(a);
193 sc_vtb_putchar(sc_vtb_t *vtb, vm_offset_t p, int c, int a)
195 if (vtb->vtb_type == VTB_FRAMEBUFFER) {
197 writew(p + ATTR_OFFSET, at2pc98(a));
200 *(u_int16_t *)(p + vtb->vtb_size*sizeof(u_int16_t)) = at2pc98(a);
202 return (p + sizeof(u_int16_t));
206 sc_vtb_pointer(sc_vtb_t *vtb, int at)
208 return (vtb->vtb_buffer + sizeof(u_int16_t)*(at));
212 sc_vtb_attr_pointer(sc_vtb_t *vtb, int at)
214 return (vtb->vtb_buffer + sizeof(u_int16_t)*(at)
215 + ((vtb->vtb_type == VTB_FRAMEBUFFER) ?
216 ATTR_OFFSET : vtb->vtb_size*sizeof(u_int16_t)));
220 sc_vtb_pos(sc_vtb_t *vtb, int pos, int offset)
222 return ((pos + offset + vtb->vtb_size)%vtb->vtb_size);
226 sc_vtb_clear(sc_vtb_t *vtb, int c, int attr)
228 if (vtb->vtb_type == VTB_FRAMEBUFFER) {
229 fillw_io(c, sc_vtb_pointer(vtb, 0), vtb->vtb_size);
230 fillw_io(at2pc98(attr), sc_vtb_attr_pointer(vtb, 0), vtb->vtb_size);
232 fillw(c, (void *)sc_vtb_pointer(vtb, 0), vtb->vtb_size);
233 fillw(at2pc98(attr), (void *)sc_vtb_attr_pointer(vtb, 0), vtb->vtb_size);
238 sc_vtb_copy(sc_vtb_t *vtb1, int from, sc_vtb_t *vtb2, int to, int count)
240 if (vtb2->vtb_type == VTB_FRAMEBUFFER) {
241 bcopy_toio(sc_vtb_pointer(vtb1, from),
242 sc_vtb_pointer(vtb2, to),
243 count*sizeof(u_int16_t));
244 bcopy_toio(sc_vtb_attr_pointer(vtb1, from),
245 sc_vtb_attr_pointer(vtb2, to),
246 count*sizeof(u_int16_t));
247 } else if (vtb1->vtb_type == VTB_FRAMEBUFFER) {
248 bcopy_fromio(sc_vtb_pointer(vtb1, from),
249 sc_vtb_pointer(vtb2, to),
250 count*sizeof(u_int16_t));
251 bcopy_fromio(sc_vtb_attr_pointer(vtb1, from),
252 sc_vtb_attr_pointer(vtb2, to),
253 count*sizeof(u_int16_t));
255 bcopy((void *)sc_vtb_pointer(vtb1, from),
256 (void *)sc_vtb_pointer(vtb2, to),
257 count*sizeof(u_int16_t));
258 bcopy((void *)sc_vtb_attr_pointer(vtb1, from),
259 (void *)sc_vtb_attr_pointer(vtb2, to),
260 count*sizeof(u_int16_t));
265 sc_vtb_append(sc_vtb_t *vtb1, int from, sc_vtb_t *vtb2, int count)
269 if (vtb2->vtb_type != VTB_RINGBUFFER)
273 len = imin(count, vtb2->vtb_size - vtb2->vtb_tail);
274 if (vtb1->vtb_type == VTB_FRAMEBUFFER) {
275 bcopy_fromio(sc_vtb_pointer(vtb1, from),
276 sc_vtb_pointer(vtb2, vtb2->vtb_tail),
277 len*sizeof(u_int16_t));
278 bcopy_fromio(sc_vtb_attr_pointer(vtb1, from),
279 sc_vtb_attr_pointer(vtb2, vtb2->vtb_tail),
280 len*sizeof(u_int16_t));
282 bcopy((void *)sc_vtb_pointer(vtb1, from),
283 (void *)sc_vtb_pointer(vtb2, vtb2->vtb_tail),
284 len*sizeof(u_int16_t));
285 bcopy((void *)sc_vtb_attr_pointer(vtb1, from),
286 (void *)sc_vtb_attr_pointer(vtb2, vtb2->vtb_tail),
287 len*sizeof(u_int16_t));
291 vtb2->vtb_tail = vtb_wrap(vtb2, vtb2->vtb_tail, len);
296 sc_vtb_seek(sc_vtb_t *vtb, int pos)
298 vtb->vtb_tail = pos%vtb->vtb_size;
302 sc_vtb_erase(sc_vtb_t *vtb, int at, int count, int c, int attr)
304 if (at + count > vtb->vtb_size)
305 count = vtb->vtb_size - at;
306 if (vtb->vtb_type == VTB_FRAMEBUFFER) {
307 fillw_io(c, sc_vtb_pointer(vtb, at), count);
308 fillw_io(at2pc98(attr), sc_vtb_attr_pointer(vtb, at), count);
310 fillw(c, (void *)sc_vtb_pointer(vtb, at), count);
311 fillw(at2pc98(attr), (void *)sc_vtb_attr_pointer(vtb, at), count);
316 sc_vtb_move(sc_vtb_t *vtb, int from, int to, int count)
318 if (from + count > vtb->vtb_size)
319 count = vtb->vtb_size - from;
320 if (to + count > vtb->vtb_size)
321 count = vtb->vtb_size - to;
324 if (vtb->vtb_type == VTB_FRAMEBUFFER) {
325 bcopy_io(sc_vtb_pointer(vtb, from),
326 sc_vtb_pointer(vtb, to), count*sizeof(u_int16_t));
327 bcopy_io(sc_vtb_attr_pointer(vtb, from),
328 sc_vtb_attr_pointer(vtb, to), count*sizeof(u_int16_t));
330 bcopy((void *)sc_vtb_pointer(vtb, from),
331 (void *)sc_vtb_pointer(vtb, to), count*sizeof(u_int16_t));
332 bcopy((void *)sc_vtb_attr_pointer(vtb, from),
333 (void *)sc_vtb_attr_pointer(vtb, to), count*sizeof(u_int16_t));
338 sc_vtb_delete(sc_vtb_t *vtb, int at, int count, int c, int attr)
342 if (at + count > vtb->vtb_size)
343 count = vtb->vtb_size - at;
344 len = vtb->vtb_size - at - count;
346 if (vtb->vtb_type == VTB_FRAMEBUFFER) {
347 bcopy_io(sc_vtb_pointer(vtb, at + count),
348 sc_vtb_pointer(vtb, at),
349 len*sizeof(u_int16_t));
350 bcopy_io(sc_vtb_attr_pointer(vtb, at + count),
351 sc_vtb_attr_pointer(vtb, at),
352 len*sizeof(u_int16_t));
354 bcopy((void *)sc_vtb_pointer(vtb, at + count),
355 (void *)sc_vtb_pointer(vtb, at),
356 len*sizeof(u_int16_t));
357 bcopy((void *)sc_vtb_attr_pointer(vtb, at + count),
358 (void *)sc_vtb_attr_pointer(vtb, at),
359 len*sizeof(u_int16_t));
362 if (vtb->vtb_type == VTB_FRAMEBUFFER) {
363 fillw_io(c, sc_vtb_pointer(vtb, at + len),
364 vtb->vtb_size - at - len);
365 fillw_io(at2pc98(attr),
366 sc_vtb_attr_pointer(vtb, at + len),
367 vtb->vtb_size - at - len);
369 fillw(c, (void *)sc_vtb_pointer(vtb, at + len),
370 vtb->vtb_size - at - len);
372 (void *)sc_vtb_attr_pointer(vtb, at + len),
373 vtb->vtb_size - at - len);
378 sc_vtb_ins(sc_vtb_t *vtb, int at, int count, int c, int attr)
380 if (at + count > vtb->vtb_size) {
381 count = vtb->vtb_size - at;
383 if (vtb->vtb_type == VTB_FRAMEBUFFER) {
384 bcopy_io(sc_vtb_pointer(vtb, at),
385 sc_vtb_pointer(vtb, at + count),
386 (vtb->vtb_size - at - count)*sizeof(u_int16_t));
387 bcopy_io(sc_vtb_attr_pointer(vtb, at),
388 sc_vtb_attr_pointer(vtb, at + count),
389 (vtb->vtb_size - at - count)*sizeof(u_int16_t));
391 bcopy((void *)sc_vtb_pointer(vtb, at),
392 (void *)sc_vtb_pointer(vtb, at + count),
393 (vtb->vtb_size - at - count)*sizeof(u_int16_t));
394 bcopy((void *)sc_vtb_attr_pointer(vtb, at),
395 (void *)sc_vtb_attr_pointer(vtb, at + count),
396 (vtb->vtb_size - at - count)*sizeof(u_int16_t));
399 if (vtb->vtb_type == VTB_FRAMEBUFFER) {
400 fillw_io(c, sc_vtb_pointer(vtb, at), count);
401 fillw_io(at2pc98(attr),
402 sc_vtb_attr_pointer(vtb, at), count);
404 fillw(c, (void *)sc_vtb_pointer(vtb, at), count);
406 (void *)sc_vtb_attr_pointer(vtb, at), count);