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$
2748187Skato */
2848187Skato
2948187Skato#include "opt_syscons.h"
3048187Skato#include "opt_gdc.h"
3148187Skato
3248187Skato#include <sys/param.h>
3383875Snyan#include <sys/systm.h>
3448187Skato#include <sys/kernel.h>
35130070Sphk#include <sys/module.h>
3683875Snyan#include <sys/fbio.h>
3766870Skato#include <sys/consio.h>
3848187Skato
3948187Skato#include <dev/fb/fbreg.h>
4048187Skato#include <dev/syscons/syscons.h>
4148187Skato
4248187Skato#ifndef SC_RENDER_DEBUG
4348187Skato#define SC_RENDER_DEBUG		0
4448187Skato#endif
4548187Skato
4648187Skatostatic vr_clear_t		gdc_txtclear;
4748187Skatostatic vr_draw_border_t		gdc_txtborder;
4848187Skatostatic vr_draw_t		gdc_txtdraw;
4948187Skatostatic vr_set_cursor_t		gdc_txtcursor_shape;
5048187Skatostatic vr_draw_cursor_t		gdc_txtcursor;
5148187Skato#ifndef SC_NO_CUTPASTE
5248187Skatostatic vr_draw_mouse_t		gdc_txtmouse;
5348187Skato#else
5448187Skato#define gdc_txtmouse		(vr_draw_mouse_t *)gdc_nop
5548187Skato#endif
5648187Skato
5748187Skato#ifndef SC_NO_MODE_CHANGE
5848187Skatostatic vr_draw_border_t		gdc_grborder;
5948187Skato#endif
6048187Skato
6148187Skatostatic void			gdc_nop(scr_stat *scp, ...);
6248187Skato
6348187Skatostatic sc_rndr_sw_t txtrndrsw = {
64146744Snyan	(vr_init_t *)gdc_nop,
6548187Skato	gdc_txtclear,
6648187Skato	gdc_txtborder,
6748187Skato	gdc_txtdraw,
6848187Skato	gdc_txtcursor_shape,
6948187Skato	gdc_txtcursor,
7048187Skato	(vr_blink_cursor_t *)gdc_nop,
7148187Skato	(vr_set_mouse_t *)gdc_nop,
7248187Skato	gdc_txtmouse,
7348187Skato};
7456337SkatoRENDERER(gdc, 0, txtrndrsw, gdc_set);
7548187Skato
7648187Skato#ifndef SC_NO_MODE_CHANGE
7748187Skatostatic sc_rndr_sw_t grrndrsw = {
78146744Snyan	(vr_init_t *)gdc_nop,
7948187Skato	(vr_clear_t *)gdc_nop,
8048187Skato	gdc_grborder,
8148187Skato	(vr_draw_t *)gdc_nop,
8248187Skato	(vr_set_cursor_t *)gdc_nop,
8348187Skato	(vr_draw_cursor_t *)gdc_nop,
8448187Skato	(vr_blink_cursor_t *)gdc_nop,
8548187Skato	(vr_set_mouse_t *)gdc_nop,
8648187Skato	(vr_draw_mouse_t *)gdc_nop,
8748187Skato};
8856337SkatoRENDERER(gdc, GRAPHICS_MODE, grrndrsw, gdc_set);
8948187Skato#endif /* SC_NO_MODE_CHANGE */
9048187Skato
9156337SkatoRENDERER_MODULE(gdc, gdc_set);
9256337Skato
9348187Skatostatic void
9448187Skatogdc_nop(scr_stat *scp, ...)
9548187Skato{
9648187Skato}
9748187Skato
9848187Skato/* text mode renderer */
9948187Skato
10048187Skatostatic void
10148187Skatogdc_txtclear(scr_stat *scp, int c, int attr)
10248187Skato{
10348187Skato	sc_vtb_clear(&scp->scr, c, attr);
10448187Skato}
10548187Skato
10648187Skatostatic void
10748187Skatogdc_txtborder(scr_stat *scp, int color)
10848187Skato{
109174985Swkoszek	vidd_set_border(scp->sc->adp, color);
11048187Skato}
11148187Skato
11248187Skatostatic void
11348187Skatogdc_txtdraw(scr_stat *scp, int from, int count, int flip)
11448187Skato{
11548187Skato	vm_offset_t p;
11648187Skato	int c;
11748187Skato	int a;
11848187Skato
11948187Skato	if (from + count > scp->xsize*scp->ysize)
12048187Skato		count = scp->xsize*scp->ysize - from;
12148187Skato
12248187Skato	if (flip) {
12390464Snyan		for (p = sc_vtb_pointer(&scp->scr, from); count-- > 0; ++from) {
12448187Skato			c = sc_vtb_getc(&scp->vtb, from);
12590464Snyan			a = sc_vtb_geta(&scp->vtb, from);
12690464Snyan#if 0
12790464Snyan			a ^= 0x0800;
12890464Snyan#else
12990464Snyan			a = (a & 0x8800) | ((a & 0x7000) >> 4)
13090464Snyan				| ((a & 0x0700) << 4);
13190464Snyan#endif
13287886Snyan			p = sc_vtb_putchar(&scp->scr, p, c, a);
13348187Skato		}
13448187Skato	} else {
13548187Skato		sc_vtb_copy(&scp->vtb, from, &scp->scr, from, count);
13648187Skato	}
13748187Skato}
13848187Skato
13948187Skatostatic void
14048187Skatogdc_txtcursor_shape(scr_stat *scp, int base, int height, int blink)
14148187Skato{
14248187Skato	if (base < 0 || base >= scp->font_size)
14348187Skato		return;
14448187Skato	/* the caller may set height <= 0 in order to disable the cursor */
145174985Swkoszek	vidd_set_hw_cursor_shape(scp->sc->adp, base, height, scp->font_size,
146174985Swkoszek	    blink);
14748187Skato}
14848187Skato
14948187Skatostatic void
15048187Skatogdc_txtcursor(scr_stat *scp, int at, int blink, int on, int flip)
15148187Skato{
15248187Skato	if (on) {
15348187Skato		scp->status |= VR_CURSOR_ON;
154174985Swkoszek		vidd_set_hw_cursor(scp->sc->adp, at%scp->xsize,
155174985Swkoszek		    at/scp->xsize);
15648187Skato	} else {
15748187Skato		if (scp->status & VR_CURSOR_ON)
158174985Swkoszek			vidd_set_hw_cursor(scp->sc->adp, -1, -1);
15948187Skato		scp->status &= ~VR_CURSOR_ON;
16048187Skato	}
16148187Skato}
16248187Skato
16348187Skato#ifndef SC_NO_CUTPASTE
16448187Skato
16548187Skatostatic void
16648187Skatodraw_txtmouse(scr_stat *scp, int x, int y)
16748187Skato{
16848187Skato	int at;
16990464Snyan	int a;
17048187Skato
17148187Skato	at = (y/scp->font_size - scp->yoff)*scp->xsize + x/8 - scp->xoff;
17290464Snyan	a = sc_vtb_geta(&scp->vtb, at);
17390464Snyan#if 0
17490464Snyan	a ^= 0x0800;
17590464Snyan#else
17690464Snyan	a = (a & 0x8800) | ((a & 0x7000) >> 4)
17790464Snyan		| ((a & 0x0700) << 4);
17890464Snyan#endif
17990464Snyan	sc_vtb_putc(&scp->scr, at, sc_vtb_getc(&scp->scr, at), a);
18048187Skato}
18148187Skato
18248187Skatostatic void
18348187Skatoremove_txtmouse(scr_stat *scp, int x, int y)
18448187Skato{
18548187Skato}
18648187Skato
18748187Skatostatic void
18848187Skatogdc_txtmouse(scr_stat *scp, int x, int y, int on)
18948187Skato{
19048187Skato	if (on)
19148187Skato		draw_txtmouse(scp, x, y);
19248187Skato	else
19348187Skato		remove_txtmouse(scp, x, y);
19448187Skato}
19548187Skato
19648187Skato#endif /* SC_NO_CUTPASTE */
19748187Skato
19848187Skato#ifndef SC_NO_MODE_CHANGE
19948187Skato
20048187Skato/* graphics mode renderer */
20148187Skato
20248187Skatostatic void
20348187Skatogdc_grborder(scr_stat *scp, int color)
20448187Skato{
205174985Swkoszek	vidd_set_border(scp->sc->adp, color);
20648187Skato}
20748187Skato
20848187Skato#endif /* SC_NO_MODE_CHANGE */
209