scvtb.c revision 66870
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 66870 2000-10-09 11:07:18Z kato $ 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); 11348187Skato } 11448187Skato } else { 11548187Skato vtb->vtb_buffer = (vm_offset_t)buf; 11648187Skato } 11748187Skato vtb->vtb_flags |= VTB_VALID; 11848187Skato break; 11948187Skato case VTB_FRAMEBUFFER: 12048187Skato vtb->vtb_buffer = (vm_offset_t)buf; 12148187Skato vtb->vtb_flags |= VTB_VALID; 12248187Skato break; 12348187Skato default: 12448187Skato break; 12548187Skato } 12648187Skato} 12748187Skato 12848187Skatovoid 12948187Skatosc_vtb_destroy(sc_vtb_t *vtb) 13048187Skato{ 13148187Skato vm_offset_t p; 13248187Skato 13348187Skato vtb->vtb_flags = 0; 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: 14448187Skato if (p != NULL) 14548187Skato free((void *)p, M_DEVBUF); 14648187Skato break; 14748187Skato default: 14848187Skato break; 14948187Skato } 15048187Skato vtb->vtb_type = VTB_INVALID; 15148187Skato} 15248187Skato 15348187Skatosize_t 15448187Skatosc_vtb_size(int cols, int rows) 15548187Skato{ 15648187Skato return (size_t)(cols*rows*sizeof(u_int16_t)*2); 15748187Skato} 15848187Skato 15948187Skatoint 16048187Skatosc_vtb_getc(sc_vtb_t *vtb, int at) 16148187Skato{ 16248187Skato if (vtb->vtb_type == VTB_FRAMEBUFFER) 16348187Skato return (readw(sc_vtb_pointer(vtb, at)) & 0x00ff); 16448187Skato else 16548187Skato return (*(u_int16_t *)sc_vtb_pointer(vtb, at) & 0x00ff); 16648187Skato} 16748187Skato 16848187Skatoint 16948187Skatosc_vtb_geta(sc_vtb_t *vtb, int at) 17048187Skato{ 17148187Skato if (vtb->vtb_type == VTB_FRAMEBUFFER) 17248187Skato return (readw(sc_vtb_attr_pointer(vtb, at)) & 0x00ff); 17348187Skato else 17448187Skato return (*(u_int16_t *)sc_vtb_attr_pointer(vtb, at) & 0x00ff); 17548187Skato} 17648187Skato 17748187Skatovoid 17848187Skatosc_vtb_putc(sc_vtb_t *vtb, int at, int c, int a) 17948187Skato{ 18048187Skato if (vtb->vtb_type == VTB_FRAMEBUFFER) { 18148187Skato writew(sc_vtb_pointer(vtb, at), c); 18248187Skato writew(sc_vtb_attr_pointer(vtb, at), at2pc98(a)); 18348187Skato } else { 18448187Skato *(u_int16_t *)sc_vtb_pointer(vtb, at) = c; 18548187Skato *(u_int16_t *)sc_vtb_attr_pointer(vtb, at) = at2pc98(a); 18648187Skato } 18748187Skato} 18848187Skato 18948187Skatovm_offset_t 19048187Skatosc_vtb_putchar(sc_vtb_t *vtb, vm_offset_t p, int c, int a) 19148187Skato{ 19248187Skato if (vtb->vtb_type == VTB_FRAMEBUFFER) { 19348187Skato writew(p, c); 19448187Skato writew(p + ATTR_OFFSET, at2pc98(a)); 19548187Skato } else { 19648187Skato *(u_int16_t *)p = c; 19748187Skato *(u_int16_t *)(p + vtb->vtb_size*sizeof(u_int16_t)) = at2pc98(a); 19848187Skato } 19948187Skato return (p + sizeof(u_int16_t)); 20048187Skato} 20148187Skato 20248187Skatovm_offset_t 20348187Skatosc_vtb_pointer(sc_vtb_t *vtb, int at) 20448187Skato{ 20548187Skato return (vtb->vtb_buffer + sizeof(u_int16_t)*(at)); 20648187Skato} 20748187Skato 20848187Skatostatic vm_offset_t 20948187Skatosc_vtb_attr_pointer(sc_vtb_t *vtb, int at) 21048187Skato{ 21148187Skato return (vtb->vtb_buffer + sizeof(u_int16_t)*(at) 21248187Skato + ((vtb->vtb_type == VTB_FRAMEBUFFER) ? 21348187Skato ATTR_OFFSET : vtb->vtb_size*sizeof(u_int16_t))); 21448187Skato} 21548187Skato 21648187Skatoint 21748187Skatosc_vtb_pos(sc_vtb_t *vtb, int pos, int offset) 21848187Skato{ 21948187Skato return ((pos + offset + vtb->vtb_size)%vtb->vtb_size); 22048187Skato} 22148187Skato 22248187Skatovoid 22348187Skatosc_vtb_clear(sc_vtb_t *vtb, int c, int attr) 22448187Skato{ 22548187Skato if (vtb->vtb_type == VTB_FRAMEBUFFER) { 22648187Skato fillw_io(c, sc_vtb_pointer(vtb, 0), vtb->vtb_size); 22748187Skato fillw_io(at2pc98(attr), sc_vtb_attr_pointer(vtb, 0), vtb->vtb_size); 22848187Skato } else { 22948187Skato fillw(c, (void *)sc_vtb_pointer(vtb, 0), vtb->vtb_size); 23048187Skato fillw(at2pc98(attr), (void *)sc_vtb_attr_pointer(vtb, 0), vtb->vtb_size); 23148187Skato } 23248187Skato} 23348187Skato 23448187Skatovoid 23548187Skatosc_vtb_copy(sc_vtb_t *vtb1, int from, sc_vtb_t *vtb2, int to, int count) 23648187Skato{ 23748187Skato if (vtb2->vtb_type == VTB_FRAMEBUFFER) { 23848187Skato bcopy_toio(sc_vtb_pointer(vtb1, from), 23948187Skato sc_vtb_pointer(vtb2, to), 24048187Skato count*sizeof(u_int16_t)); 24148187Skato bcopy_toio(sc_vtb_attr_pointer(vtb1, from), 24248187Skato sc_vtb_attr_pointer(vtb2, to), 24348187Skato count*sizeof(u_int16_t)); 24448187Skato } else if (vtb1->vtb_type == VTB_FRAMEBUFFER) { 24548187Skato bcopy_fromio(sc_vtb_pointer(vtb1, from), 24648187Skato sc_vtb_pointer(vtb2, to), 24748187Skato count*sizeof(u_int16_t)); 24848187Skato bcopy_fromio(sc_vtb_attr_pointer(vtb1, from), 24948187Skato sc_vtb_attr_pointer(vtb2, to), 25048187Skato count*sizeof(u_int16_t)); 25148187Skato } else { 25248187Skato bcopy((void *)sc_vtb_pointer(vtb1, from), 25348187Skato (void *)sc_vtb_pointer(vtb2, to), 25448187Skato count*sizeof(u_int16_t)); 25548187Skato bcopy((void *)sc_vtb_attr_pointer(vtb1, from), 25648187Skato (void *)sc_vtb_attr_pointer(vtb2, to), 25748187Skato count*sizeof(u_int16_t)); 25848187Skato } 25948187Skato} 26048187Skato 26148187Skatovoid 26248187Skatosc_vtb_append(sc_vtb_t *vtb1, int from, sc_vtb_t *vtb2, int count) 26348187Skato{ 26448187Skato int len; 26548187Skato 26648187Skato if (vtb2->vtb_type != VTB_RINGBUFFER) 26748187Skato return; 26848187Skato 26948187Skato while (count > 0) { 27048187Skato len = imin(count, vtb2->vtb_size - vtb2->vtb_tail); 27148187Skato if (vtb1->vtb_type == VTB_FRAMEBUFFER) { 27248187Skato bcopy_fromio(sc_vtb_pointer(vtb1, from), 27348187Skato sc_vtb_pointer(vtb2, vtb2->vtb_tail), 27448187Skato len*sizeof(u_int16_t)); 27548187Skato bcopy_fromio(sc_vtb_attr_pointer(vtb1, from), 27648187Skato sc_vtb_attr_pointer(vtb2, vtb2->vtb_tail), 27748187Skato len*sizeof(u_int16_t)); 27848187Skato } else { 27948187Skato bcopy((void *)sc_vtb_pointer(vtb1, from), 28048187Skato (void *)sc_vtb_pointer(vtb2, vtb2->vtb_tail), 28148187Skato len*sizeof(u_int16_t)); 28248187Skato bcopy((void *)sc_vtb_attr_pointer(vtb1, from), 28348187Skato (void *)sc_vtb_attr_pointer(vtb2, vtb2->vtb_tail), 28448187Skato len*sizeof(u_int16_t)); 28548187Skato } 28648187Skato from += len; 28748187Skato count -= len; 28848187Skato vtb2->vtb_tail = vtb_wrap(vtb2, vtb2->vtb_tail, len); 28948187Skato } 29048187Skato} 29148187Skato 29248187Skatovoid 29348187Skatosc_vtb_seek(sc_vtb_t *vtb, int pos) 29448187Skato{ 29548187Skato vtb->vtb_tail = pos%vtb->vtb_size; 29648187Skato} 29748187Skato 29848187Skatovoid 29948187Skatosc_vtb_erase(sc_vtb_t *vtb, int at, int count, int c, int attr) 30048187Skato{ 30148187Skato if (at + count > vtb->vtb_size) 30248187Skato count = vtb->vtb_size - at; 30348187Skato if (vtb->vtb_type == VTB_FRAMEBUFFER) { 30448187Skato fillw_io(c, sc_vtb_pointer(vtb, at), count); 30548187Skato fillw_io(at2pc98(attr), sc_vtb_attr_pointer(vtb, at), count); 30648187Skato } else { 30748187Skato fillw(c, (void *)sc_vtb_pointer(vtb, at), count); 30848187Skato fillw(at2pc98(attr), (void *)sc_vtb_attr_pointer(vtb, at), count); 30948187Skato } 31048187Skato} 31148187Skato 31248187Skatovoid 31348190Skatosc_vtb_move(sc_vtb_t *vtb, int from, int to, int count) 31448190Skato{ 31548190Skato if (from + count > vtb->vtb_size) 31648190Skato count = vtb->vtb_size - from; 31748190Skato if (to + count > vtb->vtb_size) 31848190Skato count = vtb->vtb_size - to; 31948190Skato if (count <= 0) 32048190Skato return; 32148190Skato if (vtb->vtb_type == VTB_FRAMEBUFFER) { 32248190Skato bcopy_io(sc_vtb_pointer(vtb, from), 32348190Skato sc_vtb_pointer(vtb, to), count*sizeof(u_int16_t)); 32448190Skato bcopy_io(sc_vtb_attr_pointer(vtb, from), 32548190Skato sc_vtb_attr_pointer(vtb, to), count*sizeof(u_int16_t)); 32648190Skato } else { 32748190Skato bcopy((void *)sc_vtb_pointer(vtb, from), 32848190Skato (void *)sc_vtb_pointer(vtb, to), count*sizeof(u_int16_t)); 32948190Skato bcopy((void *)sc_vtb_attr_pointer(vtb, from), 33048190Skato (void *)sc_vtb_attr_pointer(vtb, to), count*sizeof(u_int16_t)); 33148190Skato } 33248190Skato} 33348190Skato 33448190Skatovoid 33548187Skatosc_vtb_delete(sc_vtb_t *vtb, int at, int count, int c, int attr) 33648187Skato{ 33748187Skato int len; 33848187Skato 33948187Skato if (at + count > vtb->vtb_size) 34048187Skato count = vtb->vtb_size - at; 34148187Skato len = vtb->vtb_size - at - count; 34248187Skato if (len > 0) { 34348187Skato if (vtb->vtb_type == VTB_FRAMEBUFFER) { 34448187Skato bcopy_io(sc_vtb_pointer(vtb, at + count), 34548187Skato sc_vtb_pointer(vtb, at), 34648187Skato len*sizeof(u_int16_t)); 34748187Skato bcopy_io(sc_vtb_attr_pointer(vtb, at + count), 34848187Skato sc_vtb_attr_pointer(vtb, at), 34948187Skato len*sizeof(u_int16_t)); 35048187Skato } else { 35148187Skato bcopy((void *)sc_vtb_pointer(vtb, at + count), 35248187Skato (void *)sc_vtb_pointer(vtb, at), 35348187Skato len*sizeof(u_int16_t)); 35448187Skato bcopy((void *)sc_vtb_attr_pointer(vtb, at + count), 35548187Skato (void *)sc_vtb_attr_pointer(vtb, at), 35648187Skato len*sizeof(u_int16_t)); 35748187Skato } 35848187Skato } 35948187Skato if (vtb->vtb_type == VTB_FRAMEBUFFER) { 36048187Skato fillw_io(c, sc_vtb_pointer(vtb, at + len), 36148187Skato vtb->vtb_size - at - len); 36248187Skato fillw_io(at2pc98(attr), 36348187Skato sc_vtb_attr_pointer(vtb, at + len), 36448187Skato vtb->vtb_size - at - len); 36548187Skato } else { 36648187Skato fillw(c, (void *)sc_vtb_pointer(vtb, at + len), 36748187Skato vtb->vtb_size - at - len); 36848187Skato fillw(at2pc98(attr), 36948187Skato (void *)sc_vtb_attr_pointer(vtb, at + len), 37048187Skato vtb->vtb_size - at - len); 37148187Skato } 37248187Skato} 37348187Skato 37448187Skatovoid 37548187Skatosc_vtb_ins(sc_vtb_t *vtb, int at, int count, int c, int attr) 37648187Skato{ 37748187Skato if (at + count > vtb->vtb_size) { 37848187Skato count = vtb->vtb_size - at; 37948187Skato } else { 38048187Skato if (vtb->vtb_type == VTB_FRAMEBUFFER) { 38148187Skato bcopy_io(sc_vtb_pointer(vtb, at), 38248187Skato sc_vtb_pointer(vtb, at + count), 38348187Skato (vtb->vtb_size - at - count)*sizeof(u_int16_t)); 38448187Skato bcopy_io(sc_vtb_attr_pointer(vtb, at), 38548187Skato sc_vtb_attr_pointer(vtb, at + count), 38648187Skato (vtb->vtb_size - at - count)*sizeof(u_int16_t)); 38748187Skato } else { 38848187Skato bcopy((void *)sc_vtb_pointer(vtb, at), 38948187Skato (void *)sc_vtb_pointer(vtb, at + count), 39048187Skato (vtb->vtb_size - at - count)*sizeof(u_int16_t)); 39148187Skato bcopy((void *)sc_vtb_attr_pointer(vtb, at), 39248187Skato (void *)sc_vtb_attr_pointer(vtb, at + count), 39348187Skato (vtb->vtb_size - at - count)*sizeof(u_int16_t)); 39448187Skato } 39548187Skato } 39648187Skato if (vtb->vtb_type == VTB_FRAMEBUFFER) { 39748187Skato fillw_io(c, sc_vtb_pointer(vtb, at), count); 39848187Skato fillw_io(at2pc98(attr), 39948187Skato sc_vtb_attr_pointer(vtb, at), count); 40048187Skato } else { 40148187Skato fillw(c, (void *)sc_vtb_pointer(vtb, at), count); 40248187Skato fillw(at2pc98(attr), 40348187Skato (void *)sc_vtb_attr_pointer(vtb, at), count); 40448187Skato } 40548187Skato} 406