1/* $NetBSD: cons_fb.c,v 1.3 2007/02/22 05:31:53 thorpej Exp $ */ 2 3/*- 4 * Copyright (c) 2004 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by UCHIYAMA Yasushi. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32#include <sys/param.h> 33#include <sys/systm.h> 34 35#include <lib/libsa/stand.h> 36#include <lib/libkern/libkern.h> 37 38#include <machine/sbd.h> 39 40#include "console.h" 41 42struct fb fb; 43 44void 45fb_set_addr(uint32_t fb_addr, uint32_t fb_size, uint32_t font_addr) 46{ 47 48 fb.fb_addr = (uint8_t *)fb_addr; 49 fb.fb_size = fb_size; 50 fb.font_addr = (uint8_t *)font_addr; 51 52 cons.init = fb_init; 53 cons.putc = fb_drawchar; 54 cons.scroll = fb_scroll; 55 cons.cursor = fb_drawcursor; 56} 57 58void * 59fb_get_addr(void) 60{ 61 62 return fb.fb_addr; 63} 64 65void 66fb_init(void) 67{ 68 69 cons.x = X_INIT; 70 cons.y = Y_INIT; 71 fb.active = true; 72 fb_clear(0, 0, FB_WIDTH, FB_HEIGHT, CONS_BG); 73} 74 75void 76fb_active(bool on) 77{ 78 79 if (fb.active && !on) 80 printf("FB disabled.\n"); 81 82 fb.active = on; 83 84 if (fb.active && on) 85 printf("FB enabled.\n"); 86} 87 88void 89fb_scroll(void) 90{ 91 92 if (!fb.active) 93 return; 94#if 0 /* 1-line scroll */ 95 cons.y--; 96 fb_copy(0, ROM_FONT_HEIGHT, 0, 0, 97 FB_WIDTH, FB_HEIGHT * (CONS_HEIGHT - 1)); 98 fb_clear(0, cons.y * ROM_FONT_HEIGHT, FB_WIDTH, ROM_FONT_HEIGHT, 99 CONS_BG); 100#else /* jump scroll */ 101 cons.y /= 2; 102 fb_copy(0, cons.y * ROM_FONT_HEIGHT, 0, 0, FB_WIDTH, FB_HEIGHT / 2); 103 fb_clear(0, cons.y *ROM_FONT_HEIGHT, FB_WIDTH, FB_HEIGHT / 2, CONS_BG); 104#endif 105} 106 107#define MINMAX(x, min, max) \ 108 ((x) < (min) ? (min) : ((x) > (max) ? (max) : (x))) 109void 110fb_clear(int x, int y, int w, int h, int q) 111{ 112 uint8_t *p; 113 int i, j, k, xend, yend; 114 115 if (!fb.active) 116 return; 117 118 x = MINMAX(x, 0, FB_WIDTH); 119 y = MINMAX(y, 0, FB_HEIGHT); 120 xend = MINMAX(x + w, 0, FB_WIDTH); 121 yend = MINMAX(y + h , 0, FB_HEIGHT); 122 123 p = (uint8_t *)fb.fb_addr + x + y * FB_LINEBYTES; 124 125 j = xend - x; 126 k = j + FB_LINEBYTES - w; 127 for (i = y; i < yend; i++, p+= k) 128 memset(p, q, j); 129} 130 131void 132fb_copy(int x0, int y0, int x1, int y1, int w, int h) 133{ 134 int x1end, y1end, i, j, k; 135 uint8_t *p, *q; 136 137 if (!fb.active) 138 return; 139 140 x0 = MINMAX(x0, 0, FB_WIDTH); 141 y0 = MINMAX(y0, 0, FB_HEIGHT); 142 x1 = MINMAX(x1, 0, FB_WIDTH); 143 y1 = MINMAX(y1, 0, FB_HEIGHT); 144 x1end = MINMAX(x1 + w, 0, FB_WIDTH); 145 y1end = MINMAX(y1 + h, 0, FB_HEIGHT); 146 147 p = fb.fb_addr + x1 + y1 * FB_LINEBYTES; 148 q = fb.fb_addr + x0 + y0 * FB_LINEBYTES; 149 150 j = x1end - x1; 151 k = j + FB_LINEBYTES - w; 152 for (i = y1; i < y1end; i++, p += k, q += k) 153 memmove(p, q, j); 154} 155#undef MINMAX 156 157void 158fb_drawchar(int x, int y, int c) 159{ 160 uint16_t *font_addr; 161 int font_ofs; 162 163 if (!fb.active) 164 return; 165 166 if ((font_ofs = (c & 0x7f) - 0x20) < 0) 167 return; 168 169 font_addr = (uint16_t *)(fb.font_addr + 170 font_ofs * sizeof(uint16_t) * ROM_FONT_HEIGHT); 171 172 fb_drawfont(x, y, font_addr); 173} 174 175void 176fb_drawfont(int x, int y, uint16_t *font_addr) 177{ 178 uint8_t *fb_addr; 179 uint16_t bitmap; 180 int i, j; 181 182 if (!fb.active) 183 return; 184 185 fb_addr = fb.fb_addr + x + y * FB_LINEBYTES; 186 187 for (i = 0; i < 24; i++) { 188 bitmap = *font_addr++; 189 for (j = 0; j < 12; j++, bitmap <<= 1) 190 fb_addr[j] = bitmap & 0x8000 ? CONS_FG : CONS_BG; 191 fb_addr += FB_LINEBYTES; 192 } 193} 194 195void 196fb_drawcursor(int x, int y) 197{ 198 uint8_t *fb_addr; 199 int i, j; 200 201 if (!fb.active) 202 return; 203 204 fb_addr = fb.fb_addr + x + y * FB_LINEBYTES; 205 for (i = 0; i < 24; i++) { 206 for (j = 0; j < 12; j++) 207 fb_addr[j] = fb_addr[j] == CONS_FG ? CONS_BG : CONS_FG; 208 fb_addr += FB_LINEBYTES; 209 } 210} 211