scvtb.c revision 50477
148187Skato/*-
248516Skato * Copyright (c) 1999 FreeBSD(98) Porting Team.
348516Skato * All rights reserved.
448516Skato *
548516Skato * Redistribution and use in source and binary forms, with or without
648516Skato * modification, are permitted provided that the following conditions
748516Skato * are met:
848516Skato * 1. Redistributions of source code must retain the above copyright
948516Skato *    notice, this list of conditions and the following disclaimer as
1048516Skato *    the first lines of this file unmodified.
1148516Skato * 2. Redistributions in binary form must reproduce the above copyright
1248516Skato *    notice, this list of conditions and the following disclaimer in the
1348516Skato *    documentation and/or other materials provided with the distribution.
1448516Skato *
1548516Skato * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
1648516Skato * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1748516Skato * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1848516Skato * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
1948516Skato * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2048516Skato * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2148516Skato * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2248516Skato * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2348516Skato * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2448516Skato * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2548516Skato *
2650477Speter * $FreeBSD: head/sys/pc98/cbus/scvtb.c 50477 1999-08-28 01:08:13Z peter $
2748187Skato */
2848187Skato
2948187Skato#include "sc.h"
3048187Skato#include "opt_syscons.h"
3148187Skato
3248187Skato#if NSC > 0
3348187Skato
3448187Skato#include <sys/param.h>
3548187Skato#include <sys/systm.h>
3648187Skato#include <sys/kernel.h>
3748187Skato#include <sys/malloc.h>
3848187Skato
3948187Skato#include <machine/console.h>
4048187Skato#include <machine/md_var.h>
4148187Skato
4248187Skato#include <dev/fb/fbreg.h>
4348187Skato#include <dev/syscons/syscons.h>
4448187Skato
4548187Skato#define ATTR_OFFSET	0x2000
4648187Skato
4748187Skato#define vtb_wrap(vtb, at, offset)				\
4848187Skato    (((at) + (offset) + (vtb)->vtb_size)%(vtb)->vtb_size)
4948187Skato
5048187Skatostatic u_int16_t	at2pc98(u_int16_t attr);
5148187Skatostatic vm_offset_t	sc_vtb_attr_pointer(sc_vtb_t *vtb, int at);
5248187Skato
5348187Skatostatic u_int16_t
5448187Skatoat2pc98(u_int16_t attr)
5548187Skato{
5648187Skato	static u_char ibmpc_to_pc98[16] = {
5748187Skato		0x01, 0x21, 0x81, 0xa1, 0x41, 0x61, 0xc1, 0xe1,
5848187Skato		0x09, 0x29, 0x89, 0xa9, 0x49, 0x69, 0xc9, 0xe9
5948187Skato	};
6048187Skato	static u_char ibmpc_to_pc98rev[16] = {
6148187Skato		0x05, 0x25, 0x85, 0xa5, 0x45, 0x65, 0xc5, 0xe5,
6248187Skato		0x0d, 0x2d, 0x8d, 0xad, 0x4d, 0x6d, 0xcd, 0xed
6348187Skato	};
6448187Skato	u_char fg_at, bg_at;
6548187Skato	u_int16_t at;
6648187Skato
6748187Skato	if (attr & 0x00FF)
6848187Skato		return (attr);
6948187Skato
7048187Skato	fg_at = ((attr >> 8) & 0x0F);
7148187Skato	bg_at = ((attr >> 12) & 0x0F);
7248187Skato
7348187Skato	if (bg_at) {
7448187Skato		if (bg_at & 0x08) {
7548187Skato			if (bg_at & 0x07) {
7648187Skato				/* reverse & blink */
7748187Skato				at = ibmpc_to_pc98rev[bg_at] | 0x02;
7848187Skato			} else {
7948187Skato				/* normal & blink */
8048187Skato				at = ibmpc_to_pc98[fg_at] | 0x02;
8148187Skato			}
8248187Skato		} else {
8348187Skato			/* reverse */
8448187Skato			at = ibmpc_to_pc98rev[bg_at];
8548187Skato		}
8648187Skato	} else {
8748187Skato		/* normal */
8848187Skato		at = ibmpc_to_pc98[fg_at];
8948187Skato	}
9048187Skato	at |= attr;
9148187Skato	return (at);
9248187Skato}
9348187Skato
9448187Skatovoid
9548187Skatosc_vtb_init(sc_vtb_t *vtb, int type, int cols, int rows, void *buf, int wait)
9648187Skato{
9748187Skato	vtb->vtb_flags = 0;
9848187Skato	vtb->vtb_type = type;
9948187Skato	vtb->vtb_cols = cols;
10048187Skato	vtb->vtb_rows = rows;
10148187Skato	vtb->vtb_size = cols*rows;
10248187Skato	vtb->vtb_buffer = NULL;
10348187Skato	vtb->vtb_tail = 0;
10448187Skato
10548187Skato	switch (type) {
10648187Skato	case VTB_MEMORY:
10748187Skato	case VTB_RINGBUFFER:
10848187Skato		if ((buf == NULL) && (cols*rows != 0)) {
10948187Skato			vtb->vtb_buffer =
11048187Skato				(vm_offset_t)malloc(cols*rows*sizeof(u_int16_t)*2,
11148187Skato						    M_DEVBUF,
11248187Skato						    (wait) ? M_WAITOK : M_NOWAIT);
11348187Skato			if (vtb->vtb_buffer != NULL) {
11448187Skato				bzero((void *)sc_vtb_pointer(vtb, 0),
11548187Skato				      cols*rows*sizeof(u_int16_t)*2);
11648187Skato			}
11748187Skato		} else {
11848187Skato			vtb->vtb_buffer = (vm_offset_t)buf;
11948187Skato		}
12048187Skato		vtb->vtb_flags |= VTB_VALID;
12148187Skato		break;
12248187Skato	case VTB_FRAMEBUFFER:
12348187Skato		vtb->vtb_buffer = (vm_offset_t)buf;
12448187Skato		vtb->vtb_flags |= VTB_VALID;
12548187Skato		break;
12648187Skato	default:
12748187Skato		break;
12848187Skato	}
12948187Skato}
13048187Skato
13148187Skatovoid
13248187Skatosc_vtb_destroy(sc_vtb_t *vtb)
13348187Skato{
13448187Skato	vm_offset_t p;
13548187Skato
13648187Skato	vtb->vtb_flags = 0;
13748187Skato	vtb->vtb_cols = 0;
13848187Skato	vtb->vtb_rows = 0;
13948187Skato	vtb->vtb_size = 0;
14048187Skato	vtb->vtb_tail = 0;
14148187Skato
14248187Skato	p = vtb->vtb_buffer;
14348187Skato	vtb->vtb_buffer = NULL;
14448187Skato	switch (vtb->vtb_type) {
14548187Skato	case VTB_MEMORY:
14648187Skato	case VTB_RINGBUFFER:
14748187Skato		if (p != NULL)
14848187Skato			free((void *)p, M_DEVBUF);
14948187Skato		break;
15048187Skato	default:
15148187Skato		break;
15248187Skato	}
15348187Skato	vtb->vtb_type = VTB_INVALID;
15448187Skato}
15548187Skato
15648187Skatosize_t
15748187Skatosc_vtb_size(int cols, int rows)
15848187Skato{
15948187Skato	return (size_t)(cols*rows*sizeof(u_int16_t)*2);
16048187Skato}
16148187Skato
16248187Skatoint
16348187Skatosc_vtb_getc(sc_vtb_t *vtb, int at)
16448187Skato{
16548187Skato	if (vtb->vtb_type == VTB_FRAMEBUFFER)
16648187Skato		return (readw(sc_vtb_pointer(vtb, at)) & 0x00ff);
16748187Skato	else
16848187Skato		return (*(u_int16_t *)sc_vtb_pointer(vtb, at) & 0x00ff);
16948187Skato}
17048187Skato
17148187Skatoint
17248187Skatosc_vtb_geta(sc_vtb_t *vtb, int at)
17348187Skato{
17448187Skato	if (vtb->vtb_type == VTB_FRAMEBUFFER)
17548187Skato		return (readw(sc_vtb_attr_pointer(vtb, at)) & 0x00ff);
17648187Skato	else
17748187Skato		return (*(u_int16_t *)sc_vtb_attr_pointer(vtb, at) & 0x00ff);
17848187Skato}
17948187Skato
18048187Skatovoid
18148187Skatosc_vtb_putc(sc_vtb_t *vtb, int at, int c, int a)
18248187Skato{
18348187Skato	if (vtb->vtb_type == VTB_FRAMEBUFFER) {
18448187Skato		writew(sc_vtb_pointer(vtb, at), c);
18548187Skato		writew(sc_vtb_attr_pointer(vtb, at), at2pc98(a));
18648187Skato	} else {
18748187Skato		*(u_int16_t *)sc_vtb_pointer(vtb, at) = c;
18848187Skato		*(u_int16_t *)sc_vtb_attr_pointer(vtb, at) = at2pc98(a);
18948187Skato	}
19048187Skato}
19148187Skato
19248187Skatovm_offset_t
19348187Skatosc_vtb_putchar(sc_vtb_t *vtb, vm_offset_t p, int c, int a)
19448187Skato{
19548187Skato	if (vtb->vtb_type == VTB_FRAMEBUFFER) {
19648187Skato		writew(p, c);
19748187Skato		writew(p + ATTR_OFFSET, at2pc98(a));
19848187Skato	} else {
19948187Skato		*(u_int16_t *)p = c;
20048187Skato		*(u_int16_t *)(p + vtb->vtb_size*sizeof(u_int16_t)) = at2pc98(a);
20148187Skato	}
20248187Skato	return (p + sizeof(u_int16_t));
20348187Skato}
20448187Skato
20548187Skatovm_offset_t
20648187Skatosc_vtb_pointer(sc_vtb_t *vtb, int at)
20748187Skato{
20848187Skato	return (vtb->vtb_buffer + sizeof(u_int16_t)*(at));
20948187Skato}
21048187Skato
21148187Skatostatic vm_offset_t
21248187Skatosc_vtb_attr_pointer(sc_vtb_t *vtb, int at)
21348187Skato{
21448187Skato	return (vtb->vtb_buffer + sizeof(u_int16_t)*(at)
21548187Skato		+ ((vtb->vtb_type == VTB_FRAMEBUFFER) ?
21648187Skato			ATTR_OFFSET : vtb->vtb_size*sizeof(u_int16_t)));
21748187Skato}
21848187Skato
21948187Skatoint
22048187Skatosc_vtb_pos(sc_vtb_t *vtb, int pos, int offset)
22148187Skato{
22248187Skato	return ((pos + offset + vtb->vtb_size)%vtb->vtb_size);
22348187Skato}
22448187Skato
22548187Skatovoid
22648187Skatosc_vtb_clear(sc_vtb_t *vtb, int c, int attr)
22748187Skato{
22848187Skato	if (vtb->vtb_type == VTB_FRAMEBUFFER) {
22948187Skato		fillw_io(c, sc_vtb_pointer(vtb, 0), vtb->vtb_size);
23048187Skato		fillw_io(at2pc98(attr), sc_vtb_attr_pointer(vtb, 0), vtb->vtb_size);
23148187Skato	} else {
23248187Skato		fillw(c, (void *)sc_vtb_pointer(vtb, 0), vtb->vtb_size);
23348187Skato		fillw(at2pc98(attr), (void *)sc_vtb_attr_pointer(vtb, 0), vtb->vtb_size);
23448187Skato	}
23548187Skato}
23648187Skato
23748187Skatovoid
23848187Skatosc_vtb_copy(sc_vtb_t *vtb1, int from, sc_vtb_t *vtb2, int to, int count)
23948187Skato{
24048187Skato	if (vtb2->vtb_type == VTB_FRAMEBUFFER) {
24148187Skato		bcopy_toio(sc_vtb_pointer(vtb1, from),
24248187Skato			   sc_vtb_pointer(vtb2, to),
24348187Skato			   count*sizeof(u_int16_t));
24448187Skato		bcopy_toio(sc_vtb_attr_pointer(vtb1, from),
24548187Skato			   sc_vtb_attr_pointer(vtb2, to),
24648187Skato			   count*sizeof(u_int16_t));
24748187Skato	} else if (vtb1->vtb_type == VTB_FRAMEBUFFER) {
24848187Skato		bcopy_fromio(sc_vtb_pointer(vtb1, from),
24948187Skato			     sc_vtb_pointer(vtb2, to),
25048187Skato			     count*sizeof(u_int16_t));
25148187Skato		bcopy_fromio(sc_vtb_attr_pointer(vtb1, from),
25248187Skato			     sc_vtb_attr_pointer(vtb2, to),
25348187Skato			     count*sizeof(u_int16_t));
25448187Skato	} else {
25548187Skato		bcopy((void *)sc_vtb_pointer(vtb1, from),
25648187Skato		      (void *)sc_vtb_pointer(vtb2, to),
25748187Skato		      count*sizeof(u_int16_t));
25848187Skato		bcopy((void *)sc_vtb_attr_pointer(vtb1, from),
25948187Skato		      (void *)sc_vtb_attr_pointer(vtb2, to),
26048187Skato		      count*sizeof(u_int16_t));
26148187Skato	}
26248187Skato}
26348187Skato
26448187Skatovoid
26548187Skatosc_vtb_append(sc_vtb_t *vtb1, int from, sc_vtb_t *vtb2, int count)
26648187Skato{
26748187Skato	int len;
26848187Skato
26948187Skato	if (vtb2->vtb_type != VTB_RINGBUFFER)
27048187Skato		return;
27148187Skato
27248187Skato	while (count > 0) {
27348187Skato		len = imin(count, vtb2->vtb_size - vtb2->vtb_tail);
27448187Skato		if (vtb1->vtb_type == VTB_FRAMEBUFFER) {
27548187Skato			bcopy_fromio(sc_vtb_pointer(vtb1, from),
27648187Skato				     sc_vtb_pointer(vtb2, vtb2->vtb_tail),
27748187Skato				     len*sizeof(u_int16_t));
27848187Skato			bcopy_fromio(sc_vtb_attr_pointer(vtb1, from),
27948187Skato				     sc_vtb_attr_pointer(vtb2, vtb2->vtb_tail),
28048187Skato				     len*sizeof(u_int16_t));
28148187Skato		} else {
28248187Skato			bcopy((void *)sc_vtb_pointer(vtb1, from),
28348187Skato			      (void *)sc_vtb_pointer(vtb2, vtb2->vtb_tail),
28448187Skato			      len*sizeof(u_int16_t));
28548187Skato			bcopy((void *)sc_vtb_attr_pointer(vtb1, from),
28648187Skato			      (void *)sc_vtb_attr_pointer(vtb2, vtb2->vtb_tail),
28748187Skato			      len*sizeof(u_int16_t));
28848187Skato		}
28948187Skato		from += len;
29048187Skato		count -= len;
29148187Skato		vtb2->vtb_tail = vtb_wrap(vtb2, vtb2->vtb_tail, len);
29248187Skato	}
29348187Skato}
29448187Skato
29548187Skatovoid
29648187Skatosc_vtb_seek(sc_vtb_t *vtb, int pos)
29748187Skato{
29848187Skato	vtb->vtb_tail = pos%vtb->vtb_size;
29948187Skato}
30048187Skato
30148187Skatovoid
30248187Skatosc_vtb_erase(sc_vtb_t *vtb, int at, int count, int c, int attr)
30348187Skato{
30448187Skato	if (at + count > vtb->vtb_size)
30548187Skato		count = vtb->vtb_size - at;
30648187Skato	if (vtb->vtb_type == VTB_FRAMEBUFFER) {
30748187Skato		fillw_io(c, sc_vtb_pointer(vtb, at), count);
30848187Skato		fillw_io(at2pc98(attr), sc_vtb_attr_pointer(vtb, at), count);
30948187Skato	} else {
31048187Skato		fillw(c, (void *)sc_vtb_pointer(vtb, at), count);
31148187Skato		fillw(at2pc98(attr), (void *)sc_vtb_attr_pointer(vtb, at), count);
31248187Skato	}
31348187Skato}
31448187Skato
31548187Skatovoid
31648190Skatosc_vtb_move(sc_vtb_t *vtb, int from, int to, int count)
31748190Skato{
31848190Skato	if (from + count > vtb->vtb_size)
31948190Skato		count = vtb->vtb_size - from;
32048190Skato	if (to + count > vtb->vtb_size)
32148190Skato		count = vtb->vtb_size - to;
32248190Skato	if (count <= 0)
32348190Skato		return;
32448190Skato	if (vtb->vtb_type == VTB_FRAMEBUFFER) {
32548190Skato		bcopy_io(sc_vtb_pointer(vtb, from),
32648190Skato			 sc_vtb_pointer(vtb, to), count*sizeof(u_int16_t));
32748190Skato		bcopy_io(sc_vtb_attr_pointer(vtb, from),
32848190Skato			 sc_vtb_attr_pointer(vtb, to), count*sizeof(u_int16_t));
32948190Skato	} else {
33048190Skato		bcopy((void *)sc_vtb_pointer(vtb, from),
33148190Skato		      (void *)sc_vtb_pointer(vtb, to), count*sizeof(u_int16_t));
33248190Skato		bcopy((void *)sc_vtb_attr_pointer(vtb, from),
33348190Skato		      (void *)sc_vtb_attr_pointer(vtb, to), count*sizeof(u_int16_t));
33448190Skato	}
33548190Skato}
33648190Skato
33748190Skatovoid
33848187Skatosc_vtb_delete(sc_vtb_t *vtb, int at, int count, int c, int attr)
33948187Skato{
34048187Skato	int len;
34148187Skato
34248187Skato	if (at + count > vtb->vtb_size)
34348187Skato		count = vtb->vtb_size - at;
34448187Skato	len = vtb->vtb_size - at - count;
34548187Skato	if (len > 0) {
34648187Skato		if (vtb->vtb_type == VTB_FRAMEBUFFER) {
34748187Skato			bcopy_io(sc_vtb_pointer(vtb, at + count),
34848187Skato				 sc_vtb_pointer(vtb, at),
34948187Skato				 len*sizeof(u_int16_t));
35048187Skato			bcopy_io(sc_vtb_attr_pointer(vtb, at + count),
35148187Skato				 sc_vtb_attr_pointer(vtb, at),
35248187Skato				 len*sizeof(u_int16_t));
35348187Skato		} else {
35448187Skato			bcopy((void *)sc_vtb_pointer(vtb, at + count),
35548187Skato			      (void *)sc_vtb_pointer(vtb, at),
35648187Skato			      len*sizeof(u_int16_t));
35748187Skato			bcopy((void *)sc_vtb_attr_pointer(vtb, at + count),
35848187Skato			      (void *)sc_vtb_attr_pointer(vtb, at),
35948187Skato			      len*sizeof(u_int16_t));
36048187Skato		}
36148187Skato	}
36248187Skato	if (vtb->vtb_type == VTB_FRAMEBUFFER) {
36348187Skato		fillw_io(c, sc_vtb_pointer(vtb, at + len),
36448187Skato			 vtb->vtb_size - at - len);
36548187Skato		fillw_io(at2pc98(attr),
36648187Skato			 sc_vtb_attr_pointer(vtb, at + len),
36748187Skato			 vtb->vtb_size - at - len);
36848187Skato	} else {
36948187Skato		fillw(c, (void *)sc_vtb_pointer(vtb, at + len),
37048187Skato		      vtb->vtb_size - at - len);
37148187Skato		fillw(at2pc98(attr),
37248187Skato		      (void *)sc_vtb_attr_pointer(vtb, at + len),
37348187Skato		      vtb->vtb_size - at - len);
37448187Skato	}
37548187Skato}
37648187Skato
37748187Skatovoid
37848187Skatosc_vtb_ins(sc_vtb_t *vtb, int at, int count, int c, int attr)
37948187Skato{
38048187Skato	if (at + count > vtb->vtb_size) {
38148187Skato		count = vtb->vtb_size - at;
38248187Skato	} else {
38348187Skato		if (vtb->vtb_type == VTB_FRAMEBUFFER) {
38448187Skato			bcopy_io(sc_vtb_pointer(vtb, at),
38548187Skato				 sc_vtb_pointer(vtb, at + count),
38648187Skato				 (vtb->vtb_size - at - count)*sizeof(u_int16_t));
38748187Skato			bcopy_io(sc_vtb_attr_pointer(vtb, at),
38848187Skato				 sc_vtb_attr_pointer(vtb, at + count),
38948187Skato				 (vtb->vtb_size - at - count)*sizeof(u_int16_t));
39048187Skato		} else {
39148187Skato			bcopy((void *)sc_vtb_pointer(vtb, at),
39248187Skato			      (void *)sc_vtb_pointer(vtb, at + count),
39348187Skato			      (vtb->vtb_size - at - count)*sizeof(u_int16_t));
39448187Skato			bcopy((void *)sc_vtb_attr_pointer(vtb, at),
39548187Skato			      (void *)sc_vtb_attr_pointer(vtb, at + count),
39648187Skato			      (vtb->vtb_size - at - count)*sizeof(u_int16_t));
39748187Skato		}
39848187Skato	}
39948187Skato	if (vtb->vtb_type == VTB_FRAMEBUFFER) {
40048187Skato		fillw_io(c, sc_vtb_pointer(vtb, at), count);
40148187Skato		fillw_io(at2pc98(attr),
40248187Skato			 sc_vtb_attr_pointer(vtb, at), count);
40348187Skato	} else {
40448187Skato		fillw(c, (void *)sc_vtb_pointer(vtb, at), count);
40548187Skato		fillw(at2pc98(attr),
40648187Skato		      (void *)sc_vtb_attr_pointer(vtb, at), count);
40748187Skato	}
40848187Skato}
40948187Skato
41048187Skato#endif /* NSC */
411