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