2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer as
12 * the first lines of this file unmodified.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 * Copyright (c) 2000 Andrew Miklic
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
34 #include "opt_syscons.h"
36 #include "opt_ofwfb.h"
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/kernel.h>
43 #include <sys/consio.h>
45 #include <machine/bus.h>
47 #include <dev/fb/fbreg.h>
48 #include <dev/syscons/syscons.h>
50 #ifndef SC_RENDER_DEBUG
51 #define SC_RENDER_DEBUG 0
54 static vr_clear_t gfb_clear;
55 static vr_draw_border_t gfb_border;
56 static vr_draw_t gfb_draw;
57 static vr_set_cursor_t gfb_cursor_shape;
58 static vr_draw_cursor_t gfb_cursor;
59 static vr_blink_cursor_t gfb_blink;
60 #ifndef SC_NO_CUTPASTE
61 static vr_draw_mouse_t gfb_mouse;
63 #define gfb_mouse (vr_draw_mouse_t *)gfb_nop
66 static void gfb_nop(scr_stat *scp);
68 sc_rndr_sw_t txtrndrsw = {
76 (vr_set_mouse_t *)gfb_nop,
81 sc_rndr_sw_t gfbrndrsw = {
89 (vr_set_mouse_t *)gfb_nop,
92 #endif /* SC_PIXEL_MODE */
94 #ifndef SC_NO_MODE_CHANGE
95 sc_rndr_sw_t grrndrsw = {
97 (vr_clear_t *)gfb_nop,
100 (vr_set_cursor_t *)gfb_nop,
101 (vr_draw_cursor_t *)gfb_nop,
102 (vr_blink_cursor_t *)gfb_nop,
103 (vr_set_mouse_t *)gfb_nop,
104 (vr_draw_mouse_t *)gfb_nop,
106 #endif /* SC_NO_MODE_CHANGE */
108 #ifndef SC_NO_CUTPASTE
109 static u_char mouse_pointer[16] = {
110 0x00, 0x40, 0x60, 0x70, 0x78, 0x7c, 0x7e, 0x68,
111 0x0c, 0x0c, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00
116 gfb_nop(scr_stat *scp)
120 /* text mode renderer */
123 gfb_clear(scr_stat *scp, int c, int attr)
125 vidd_clear(scp->sc->adp);
129 gfb_border(scr_stat *scp, int color)
131 vidd_set_border(scp->sc->adp, color);
135 gfb_draw(scr_stat *scp, int from, int count, int flip)
140 video_adapter_t *adp;
145 Determine if we need to scroll based on the offset
146 and the number of characters to be displayed...
148 if (from + count > scp->xsize*scp->ysize) {
150 Calculate the number of characters past the end of the
153 count = (from + count) -
154 (adp->va_info.vi_width * adp->va_info.vi_height);
157 Calculate the number of rows past the end of the visible
160 n = (count / adp->va_info.vi_width) + 1;
162 /* Scroll to make room for new text rows... */
163 vidd_copy(adp, n, 0, n);
168 /* Display new text rows... */
170 (u_int16_t *)sc_vtb_pointer(&scp->vtb, from), count);
174 We don't need to scroll, so we can just put the characters
179 Determine the method by which we are to display characters
180 (are we going to print forwards or backwards?
181 do we need to do a character-by-character copy, then?)...
184 for (i = count; i-- > 0; ++from) {
185 c = sc_vtb_getc(&scp->vtb, from);
186 a = sc_vtb_geta(&scp->vtb, from) >> 8;
187 vidd_putc(adp, from, c,
188 (a >> 4) | ((a & 0xf) << 4));
192 (u_int16_t *)sc_vtb_pointer(&scp->vtb, from),
199 gfb_cursor_shape(scr_stat *scp, int base, int height, int blink)
201 if (base < 0 || base >= scp->font_size)
203 /* the caller may set height <= 0 in order to disable the cursor */
205 scp->cursor_base = base;
206 scp->cursor_height = height;
208 vidd_set_hw_cursor_shape(scp->sc->adp, base, height, scp->font_size,
212 static int pxlblinkrate = 0;
214 #if defined(SC_OFWFB)
216 gfb_cursor(scr_stat *scp, int at, int blink, int on, int flip)
218 video_adapter_t *adp;
221 if (scp->curs_attr.height <= 0) /* the text cursor is disabled */
226 scp->status |= VR_CURSOR_BLINK;
228 scp->status |= VR_CURSOR_ON;
229 vidd_set_hw_cursor(adp, at%scp->xsize, at/scp->xsize);
231 if (scp->status & VR_CURSOR_ON)
232 vidd_set_hw_cursor(adp, -1, -1);
233 scp->status &= ~VR_CURSOR_ON;
236 scp->status &= ~VR_CURSOR_BLINK;
238 scp->status |= VR_CURSOR_ON;
239 vidd_putc(scp->sc->adp, scp->cursor_oldpos,
240 sc_vtb_getc(&scp->vtb, scp->cursor_oldpos),
241 sc_vtb_geta(&scp->vtb, scp->cursor_oldpos) >> 8);
242 a = sc_vtb_geta(&scp->vtb, at) >> 8;
243 c = sc_vtb_getc(&scp->vtb, at);
244 vidd_putc(scp->sc->adp, at, c,
245 (a >> 4) | ((a & 0xf) << 4));
247 if (scp->status & VR_CURSOR_ON)
248 vidd_putc(scp->sc->adp, at,
249 sc_vtb_getc(&scp->vtb, at),
250 sc_vtb_geta(&scp->vtb, at) >> 8);
251 scp->status &= ~VR_CURSOR_ON;
257 gfb_cursor(scr_stat *scp, int at, int blink, int on, int flip)
259 video_adapter_t *adp;
262 if (scp->curs_attr.height <= 0)
263 /* the text cursor is disabled */
268 scp->status |= VR_CURSOR_ON;
269 vidd_set_hw_cursor(adp, at%scp->xsize, at/scp->xsize);
270 } else if (++pxlblinkrate & 4) {
272 scp->status ^= VR_CURSOR_ON;
273 if(scp->status & VR_CURSOR_ON)
274 vidd_set_hw_cursor(adp, at%scp->xsize,
277 vidd_set_hw_cursor(adp, -1, -1);
280 if (scp->status & VR_CURSOR_ON)
281 vidd_set_hw_cursor(adp, at%scp->xsize, at/scp->xsize);
282 scp->status &= ~VR_CURSOR_ON;
285 scp->status |= VR_CURSOR_BLINK;
287 scp->status &= ~VR_CURSOR_BLINK;
292 gfb_blink(scr_stat *scp, int at, int flip)
294 if (!(scp->status & VR_CURSOR_BLINK))
296 if (!(++pxlblinkrate & 4))
299 scp->status ^= VR_CURSOR_ON;
300 gfb_cursor(scp, at, scp->status & VR_CURSOR_BLINK,
301 scp->status & VR_CURSOR_ON, flip);
304 #ifndef SC_NO_CUTPASTE
307 gfb_mouse(scr_stat *scp, int x, int y, int on)
310 vidd_putm(scp->sc->adp, x, y, mouse_pointer,
313 /* XXX: removal is incomplete for h/w cursors and borders. */
317 #endif /* SC_NO_CUTPASTE */