scvtb.c revision 79702
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 79702 2001-07-14 03:26:02Z nyan $
2748187Skato */
2848187Skato
2948187Skato#include "opt_syscons.h"
3048187Skato
3148187Skato#include <sys/param.h>
3248187Skato#include <sys/systm.h>
3348187Skato#include <sys/malloc.h>
3466870Skato#include <sys/consio.h>
3566870Skato#include <sys/fbio.h>
3648187Skato
3748187Skato#include <machine/md_var.h>
3848187Skato
3948187Skato#include <dev/fb/fbreg.h>
4048187Skato#include <dev/syscons/syscons.h>
4148187Skato
4248187Skato#define ATTR_OFFSET	0x2000
4348187Skato
4448187Skato#define vtb_wrap(vtb, at, offset)				\
4548187Skato    (((at) + (offset) + (vtb)->vtb_size)%(vtb)->vtb_size)
4648187Skato
4748187Skatostatic u_int16_t	at2pc98(u_int16_t attr);
4848187Skatostatic vm_offset_t	sc_vtb_attr_pointer(sc_vtb_t *vtb, int at);
4948187Skato
5048187Skatostatic u_int16_t
5148187Skatoat2pc98(u_int16_t attr)
5248187Skato{
5348187Skato	static u_char ibmpc_to_pc98[16] = {
5448187Skato		0x01, 0x21, 0x81, 0xa1, 0x41, 0x61, 0xc1, 0xe1,
5548187Skato		0x09, 0x29, 0x89, 0xa9, 0x49, 0x69, 0xc9, 0xe9
5648187Skato	};
5748187Skato	static u_char ibmpc_to_pc98rev[16] = {
5848187Skato		0x05, 0x25, 0x85, 0xa5, 0x45, 0x65, 0xc5, 0xe5,
5948187Skato		0x0d, 0x2d, 0x8d, 0xad, 0x4d, 0x6d, 0xcd, 0xed
6048187Skato	};
6148187Skato	u_char fg_at, bg_at;
6248187Skato	u_int16_t at;
6348187Skato
6448187Skato	if (attr & 0x00FF)
6548187Skato		return (attr);
6648187Skato
6748187Skato	fg_at = ((attr >> 8) & 0x0F);
6848187Skato	bg_at = ((attr >> 12) & 0x0F);
6948187Skato
7048187Skato	if (bg_at) {
7148187Skato		if (bg_at & 0x08) {
7248187Skato			if (bg_at & 0x07) {
7348187Skato				/* reverse & blink */
7448187Skato				at = ibmpc_to_pc98rev[bg_at] | 0x02;
7548187Skato			} else {
7648187Skato				/* normal & blink */
7748187Skato				at = ibmpc_to_pc98[fg_at] | 0x02;
7848187Skato			}
7948187Skato		} else {
8048187Skato			/* reverse */
8148187Skato			at = ibmpc_to_pc98rev[bg_at];
8248187Skato		}
8348187Skato	} else {
8448187Skato		/* normal */
8548187Skato		at = ibmpc_to_pc98[fg_at];
8648187Skato	}
8748187Skato	at |= attr;
8848187Skato	return (at);
8948187Skato}
9048187Skato
9148187Skatovoid
9248187Skatosc_vtb_init(sc_vtb_t *vtb, int type, int cols, int rows, void *buf, int wait)
9348187Skato{
9448187Skato	vtb->vtb_flags = 0;
9548187Skato	vtb->vtb_type = type;
9648187Skato	vtb->vtb_cols = cols;
9748187Skato	vtb->vtb_rows = rows;
9848187Skato	vtb->vtb_size = cols*rows;
9948187Skato	vtb->vtb_buffer = NULL;
10048187Skato	vtb->vtb_tail = 0;
10148187Skato
10248187Skato	switch (type) {
10348187Skato	case VTB_MEMORY:
10448187Skato	case VTB_RINGBUFFER:
10548187Skato		if ((buf == NULL) && (cols*rows != 0)) {
10648187Skato			vtb->vtb_buffer =
10748187Skato				(vm_offset_t)malloc(cols*rows*sizeof(u_int16_t)*2,
10848187Skato						    M_DEVBUF,
10948187Skato						    (wait) ? M_WAITOK : M_NOWAIT);
11048187Skato			if (vtb->vtb_buffer != NULL) {
11148187Skato				bzero((void *)sc_vtb_pointer(vtb, 0),
11248187Skato				      cols*rows*sizeof(u_int16_t)*2);
11379702Snyan				vtb->vtb_flags |= VTB_ALLOCED;
11448187Skato			}
11548187Skato		} else {
11648187Skato			vtb->vtb_buffer = (vm_offset_t)buf;
11748187Skato		}
11848187Skato		vtb->vtb_flags |= VTB_VALID;
11948187Skato		break;
12048187Skato	case VTB_FRAMEBUFFER:
12148187Skato		vtb->vtb_buffer = (vm_offset_t)buf;
12248187Skato		vtb->vtb_flags |= VTB_VALID;
12348187Skato		break;
12448187Skato	default:
12548187Skato		break;
12648187Skato	}
12748187Skato}
12848187Skato
12948187Skatovoid
13048187Skatosc_vtb_destroy(sc_vtb_t *vtb)
13148187Skato{
13248187Skato	vm_offset_t p;
13348187Skato
13448187Skato	vtb->vtb_cols = 0;
13548187Skato	vtb->vtb_rows = 0;
13648187Skato	vtb->vtb_size = 0;
13748187Skato	vtb->vtb_tail = 0;
13848187Skato
13948187Skato	p = vtb->vtb_buffer;
14048187Skato	vtb->vtb_buffer = NULL;
14148187Skato	switch (vtb->vtb_type) {
14248187Skato	case VTB_MEMORY:
14348187Skato	case VTB_RINGBUFFER:
14479702Snyan		if ((vtb->vtb_flags & VTB_ALLOCED) && (p != NULL))
14548187Skato			free((void *)p, M_DEVBUF);
14648187Skato		break;
14748187Skato	default:
14848187Skato		break;
14948187Skato	}
15079702Snyan	vtb->vtb_flags = 0;
15148187Skato	vtb->vtb_type = VTB_INVALID;
15248187Skato}
15348187Skato
15448187Skatosize_t
15548187Skatosc_vtb_size(int cols, int rows)
15648187Skato{
15748187Skato	return (size_t)(cols*rows*sizeof(u_int16_t)*2);
15848187Skato}
15948187Skato
16048187Skatoint
16148187Skatosc_vtb_getc(sc_vtb_t *vtb, int at)
16248187Skato{
16348187Skato	if (vtb->vtb_type == VTB_FRAMEBUFFER)
16448187Skato		return (readw(sc_vtb_pointer(vtb, at)) & 0x00ff);
16548187Skato	else
16648187Skato		return (*(u_int16_t *)sc_vtb_pointer(vtb, at) & 0x00ff);
16748187Skato}
16848187Skato
16948187Skatoint
17048187Skatosc_vtb_geta(sc_vtb_t *vtb, int at)
17148187Skato{
17248187Skato	if (vtb->vtb_type == VTB_FRAMEBUFFER)
17348187Skato		return (readw(sc_vtb_attr_pointer(vtb, at)) & 0x00ff);
17448187Skato	else
17548187Skato		return (*(u_int16_t *)sc_vtb_attr_pointer(vtb, at) & 0x00ff);
17648187Skato}
17748187Skato
17848187Skatovoid
17948187Skatosc_vtb_putc(sc_vtb_t *vtb, int at, int c, int a)
18048187Skato{
18148187Skato	if (vtb->vtb_type == VTB_FRAMEBUFFER) {
18248187Skato		writew(sc_vtb_pointer(vtb, at), c);
18348187Skato		writew(sc_vtb_attr_pointer(vtb, at), at2pc98(a));
18448187Skato	} else {
18548187Skato		*(u_int16_t *)sc_vtb_pointer(vtb, at) = c;
18648187Skato		*(u_int16_t *)sc_vtb_attr_pointer(vtb, at) = at2pc98(a);
18748187Skato	}
18848187Skato}
18948187Skato
19048187Skatovm_offset_t
19148187Skatosc_vtb_putchar(sc_vtb_t *vtb, vm_offset_t p, int c, int a)
19248187Skato{
19348187Skato	if (vtb->vtb_type == VTB_FRAMEBUFFER) {
19448187Skato		writew(p, c);
19548187Skato		writew(p + ATTR_OFFSET, at2pc98(a));
19648187Skato	} else {
19748187Skato		*(u_int16_t *)p = c;
19848187Skato		*(u_int16_t *)(p + vtb->vtb_size*sizeof(u_int16_t)) = at2pc98(a);
19948187Skato	}
20048187Skato	return (p + sizeof(u_int16_t));
20148187Skato}
20248187Skato
20348187Skatovm_offset_t
20448187Skatosc_vtb_pointer(sc_vtb_t *vtb, int at)
20548187Skato{
20648187Skato	return (vtb->vtb_buffer + sizeof(u_int16_t)*(at));
20748187Skato}
20848187Skato
20948187Skatostatic vm_offset_t
21048187Skatosc_vtb_attr_pointer(sc_vtb_t *vtb, int at)
21148187Skato{
21248187Skato	return (vtb->vtb_buffer + sizeof(u_int16_t)*(at)
21348187Skato		+ ((vtb->vtb_type == VTB_FRAMEBUFFER) ?
21448187Skato			ATTR_OFFSET : vtb->vtb_size*sizeof(u_int16_t)));
21548187Skato}
21648187Skato
21748187Skatoint
21848187Skatosc_vtb_pos(sc_vtb_t *vtb, int pos, int offset)
21948187Skato{
22048187Skato	return ((pos + offset + vtb->vtb_size)%vtb->vtb_size);
22148187Skato}
22248187Skato
22348187Skatovoid
22448187Skatosc_vtb_clear(sc_vtb_t *vtb, int c, int attr)
22548187Skato{
22648187Skato	if (vtb->vtb_type == VTB_FRAMEBUFFER) {
22748187Skato		fillw_io(c, sc_vtb_pointer(vtb, 0), vtb->vtb_size);
22848187Skato		fillw_io(at2pc98(attr), sc_vtb_attr_pointer(vtb, 0), vtb->vtb_size);
22948187Skato	} else {
23048187Skato		fillw(c, (void *)sc_vtb_pointer(vtb, 0), vtb->vtb_size);
23148187Skato		fillw(at2pc98(attr), (void *)sc_vtb_attr_pointer(vtb, 0), vtb->vtb_size);
23248187Skato	}
23348187Skato}
23448187Skato
23548187Skatovoid
23648187Skatosc_vtb_copy(sc_vtb_t *vtb1, int from, sc_vtb_t *vtb2, int to, int count)
23748187Skato{
23848187Skato	if (vtb2->vtb_type == VTB_FRAMEBUFFER) {
23948187Skato		bcopy_toio(sc_vtb_pointer(vtb1, from),
24048187Skato			   sc_vtb_pointer(vtb2, to),
24148187Skato			   count*sizeof(u_int16_t));
24248187Skato		bcopy_toio(sc_vtb_attr_pointer(vtb1, from),
24348187Skato			   sc_vtb_attr_pointer(vtb2, to),
24448187Skato			   count*sizeof(u_int16_t));
24548187Skato	} else if (vtb1->vtb_type == VTB_FRAMEBUFFER) {
24648187Skato		bcopy_fromio(sc_vtb_pointer(vtb1, from),
24748187Skato			     sc_vtb_pointer(vtb2, to),
24848187Skato			     count*sizeof(u_int16_t));
24948187Skato		bcopy_fromio(sc_vtb_attr_pointer(vtb1, from),
25048187Skato			     sc_vtb_attr_pointer(vtb2, to),
25148187Skato			     count*sizeof(u_int16_t));
25248187Skato	} else {
25348187Skato		bcopy((void *)sc_vtb_pointer(vtb1, from),
25448187Skato		      (void *)sc_vtb_pointer(vtb2, to),
25548187Skato		      count*sizeof(u_int16_t));
25648187Skato		bcopy((void *)sc_vtb_attr_pointer(vtb1, from),
25748187Skato		      (void *)sc_vtb_attr_pointer(vtb2, to),
25848187Skato		      count*sizeof(u_int16_t));
25948187Skato	}
26048187Skato}
26148187Skato
26248187Skatovoid
26348187Skatosc_vtb_append(sc_vtb_t *vtb1, int from, sc_vtb_t *vtb2, int count)
26448187Skato{
26548187Skato	int len;
26648187Skato
26748187Skato	if (vtb2->vtb_type != VTB_RINGBUFFER)
26848187Skato		return;
26948187Skato
27048187Skato	while (count > 0) {
27148187Skato		len = imin(count, vtb2->vtb_size - vtb2->vtb_tail);
27248187Skato		if (vtb1->vtb_type == VTB_FRAMEBUFFER) {
27348187Skato			bcopy_fromio(sc_vtb_pointer(vtb1, from),
27448187Skato				     sc_vtb_pointer(vtb2, vtb2->vtb_tail),
27548187Skato				     len*sizeof(u_int16_t));
27648187Skato			bcopy_fromio(sc_vtb_attr_pointer(vtb1, from),
27748187Skato				     sc_vtb_attr_pointer(vtb2, vtb2->vtb_tail),
27848187Skato				     len*sizeof(u_int16_t));
27948187Skato		} else {
28048187Skato			bcopy((void *)sc_vtb_pointer(vtb1, from),
28148187Skato			      (void *)sc_vtb_pointer(vtb2, vtb2->vtb_tail),
28248187Skato			      len*sizeof(u_int16_t));
28348187Skato			bcopy((void *)sc_vtb_attr_pointer(vtb1, from),
28448187Skato			      (void *)sc_vtb_attr_pointer(vtb2, vtb2->vtb_tail),
28548187Skato			      len*sizeof(u_int16_t));
28648187Skato		}
28748187Skato		from += len;
28848187Skato		count -= len;
28948187Skato		vtb2->vtb_tail = vtb_wrap(vtb2, vtb2->vtb_tail, len);
29048187Skato	}
29148187Skato}
29248187Skato
29348187Skatovoid
29448187Skatosc_vtb_seek(sc_vtb_t *vtb, int pos)
29548187Skato{
29648187Skato	vtb->vtb_tail = pos%vtb->vtb_size;
29748187Skato}
29848187Skato
29948187Skatovoid
30048187Skatosc_vtb_erase(sc_vtb_t *vtb, int at, int count, int c, int attr)
30148187Skato{
30248187Skato	if (at + count > vtb->vtb_size)
30348187Skato		count = vtb->vtb_size - at;
30448187Skato	if (vtb->vtb_type == VTB_FRAMEBUFFER) {
30548187Skato		fillw_io(c, sc_vtb_pointer(vtb, at), count);
30648187Skato		fillw_io(at2pc98(attr), sc_vtb_attr_pointer(vtb, at), count);
30748187Skato	} else {
30848187Skato		fillw(c, (void *)sc_vtb_pointer(vtb, at), count);
30948187Skato		fillw(at2pc98(attr), (void *)sc_vtb_attr_pointer(vtb, at), count);
31048187Skato	}
31148187Skato}
31248187Skato
31348187Skatovoid
31448190Skatosc_vtb_move(sc_vtb_t *vtb, int from, int to, int count)
31548190Skato{
31648190Skato	if (from + count > vtb->vtb_size)
31748190Skato		count = vtb->vtb_size - from;
31848190Skato	if (to + count > vtb->vtb_size)
31948190Skato		count = vtb->vtb_size - to;
32048190Skato	if (count <= 0)
32148190Skato		return;
32248190Skato	if (vtb->vtb_type == VTB_FRAMEBUFFER) {
32348190Skato		bcopy_io(sc_vtb_pointer(vtb, from),
32448190Skato			 sc_vtb_pointer(vtb, to), count*sizeof(u_int16_t));
32548190Skato		bcopy_io(sc_vtb_attr_pointer(vtb, from),
32648190Skato			 sc_vtb_attr_pointer(vtb, to), count*sizeof(u_int16_t));
32748190Skato	} else {
32848190Skato		bcopy((void *)sc_vtb_pointer(vtb, from),
32948190Skato		      (void *)sc_vtb_pointer(vtb, to), count*sizeof(u_int16_t));
33048190Skato		bcopy((void *)sc_vtb_attr_pointer(vtb, from),
33148190Skato		      (void *)sc_vtb_attr_pointer(vtb, to), count*sizeof(u_int16_t));
33248190Skato	}
33348190Skato}
33448190Skato
33548190Skatovoid
33648187Skatosc_vtb_delete(sc_vtb_t *vtb, int at, int count, int c, int attr)
33748187Skato{
33848187Skato	int len;
33948187Skato
34048187Skato	if (at + count > vtb->vtb_size)
34148187Skato		count = vtb->vtb_size - at;
34248187Skato	len = vtb->vtb_size - at - count;
34348187Skato	if (len > 0) {
34448187Skato		if (vtb->vtb_type == VTB_FRAMEBUFFER) {
34548187Skato			bcopy_io(sc_vtb_pointer(vtb, at + count),
34648187Skato				 sc_vtb_pointer(vtb, at),
34748187Skato				 len*sizeof(u_int16_t));
34848187Skato			bcopy_io(sc_vtb_attr_pointer(vtb, at + count),
34948187Skato				 sc_vtb_attr_pointer(vtb, at),
35048187Skato				 len*sizeof(u_int16_t));
35148187Skato		} else {
35248187Skato			bcopy((void *)sc_vtb_pointer(vtb, at + count),
35348187Skato			      (void *)sc_vtb_pointer(vtb, at),
35448187Skato			      len*sizeof(u_int16_t));
35548187Skato			bcopy((void *)sc_vtb_attr_pointer(vtb, at + count),
35648187Skato			      (void *)sc_vtb_attr_pointer(vtb, at),
35748187Skato			      len*sizeof(u_int16_t));
35848187Skato		}
35948187Skato	}
36048187Skato	if (vtb->vtb_type == VTB_FRAMEBUFFER) {
36148187Skato		fillw_io(c, sc_vtb_pointer(vtb, at + len),
36248187Skato			 vtb->vtb_size - at - len);
36348187Skato		fillw_io(at2pc98(attr),
36448187Skato			 sc_vtb_attr_pointer(vtb, at + len),
36548187Skato			 vtb->vtb_size - at - len);
36648187Skato	} else {
36748187Skato		fillw(c, (void *)sc_vtb_pointer(vtb, at + len),
36848187Skato		      vtb->vtb_size - at - len);
36948187Skato		fillw(at2pc98(attr),
37048187Skato		      (void *)sc_vtb_attr_pointer(vtb, at + len),
37148187Skato		      vtb->vtb_size - at - len);
37248187Skato	}
37348187Skato}
37448187Skato
37548187Skatovoid
37648187Skatosc_vtb_ins(sc_vtb_t *vtb, int at, int count, int c, int attr)
37748187Skato{
37848187Skato	if (at + count > vtb->vtb_size) {
37948187Skato		count = vtb->vtb_size - at;
38048187Skato	} else {
38148187Skato		if (vtb->vtb_type == VTB_FRAMEBUFFER) {
38248187Skato			bcopy_io(sc_vtb_pointer(vtb, at),
38348187Skato				 sc_vtb_pointer(vtb, at + count),
38448187Skato				 (vtb->vtb_size - at - count)*sizeof(u_int16_t));
38548187Skato			bcopy_io(sc_vtb_attr_pointer(vtb, at),
38648187Skato				 sc_vtb_attr_pointer(vtb, at + count),
38748187Skato				 (vtb->vtb_size - at - count)*sizeof(u_int16_t));
38848187Skato		} else {
38948187Skato			bcopy((void *)sc_vtb_pointer(vtb, at),
39048187Skato			      (void *)sc_vtb_pointer(vtb, at + count),
39148187Skato			      (vtb->vtb_size - at - count)*sizeof(u_int16_t));
39248187Skato			bcopy((void *)sc_vtb_attr_pointer(vtb, at),
39348187Skato			      (void *)sc_vtb_attr_pointer(vtb, at + count),
39448187Skato			      (vtb->vtb_size - at - count)*sizeof(u_int16_t));
39548187Skato		}
39648187Skato	}
39748187Skato	if (vtb->vtb_type == VTB_FRAMEBUFFER) {
39848187Skato		fillw_io(c, sc_vtb_pointer(vtb, at), count);
39948187Skato		fillw_io(at2pc98(attr),
40048187Skato			 sc_vtb_attr_pointer(vtb, at), count);
40148187Skato	} else {
40248187Skato		fillw(c, (void *)sc_vtb_pointer(vtb, at), count);
40348187Skato		fillw(at2pc98(attr),
40448187Skato		      (void *)sc_vtb_attr_pointer(vtb, at), count);
40548187Skato	}
40648187Skato}
407