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