1 /* $NetBSD: cons_fb.c,v 1.4 2008/04/28 20:23:18 martin 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 42 struct fb fb; 43 44 void 45 fb_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 58 void * 59 fb_get_addr(void) 60 { 61 62 return fb.fb_addr; 63 } 64 65 void 66 fb_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 75 void 76 fb_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 88 void 89 fb_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))) 109 void 110 fb_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 131 void 132 fb_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 157 void 158 fb_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 175 void 176 fb_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 195 void 196 fb_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