/*
* Copyright (c) 1996 Leo Weppelman.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* only used in console init.
*/
static struct cfdata *cfdata_grf = NULL;
static int
grfetmatch(device_t parent, cfdata_t cf, void *aux)
{
static int card_probed = -1;
static int did_consinit = 0;
grf_auxp_t *grf_auxp = aux;
extern const struct cdevsw view_cdevsw;
if (card_probed <= 0) {
if (card_probed == 0) /* Probed but failed */
return 0;
card_probed = 0;
/*
* Check if the layers we depend on exist
*/
if (!(machineid & ATARI_HADES))
return 0;
if (!et_probe_card())
return 0;
if (grfabs_probe(&et_probe_video) == 0)
return 0;
viewprobe();
card_probed = 1; /* Probed and found */
}
if (atari_realconfig == 0) {
/*
* Early console init. Only match first unit.
*/
if (did_consinit)
return 0;
if ((*view_cdevsw.d_open)(cf->cf_unit, 0, 0, NULL))
return 0;
cfdata_grf = cf;
did_consinit = 1;
return 1;
}
/*
* Normal config. When we are called directly from the grfbus,
* we only match the first unit. The attach function will call us for
* the other configured units.
*/
if (grf_auxp->from_bus_match
&& ((did_consinit > 1) || !et_probe_card()))
return 0;
if (!grf_auxp->from_bus_match && (grf_auxp->unit != cf->cf_unit))
return 0;
/*
* Final constraint: each grf needs a view....
*/
if ((cfdata_grf == NULL) || (did_consinit > 1)) {
if ((*view_cdevsw.d_open)(cf->cf_unit, 0, 0, NULL))
return 0;
}
did_consinit = 2;
return 1;
}
/*
* attach: initialize the grf-structure and try to attach an ite to us.
* note : self is NULL during early console init.
*/
static void
grfetattach(device_t parent, device_t self, void *aux)
{
static struct grf_softc congrf;
static int first_attach = 1;
grf_auxp_t *grf_bus_auxp = aux;
grf_auxp_t grf_auxp;
struct grf_softc *sc;
int maj;
extern const struct cdevsw grf_cdevsw;
/*
* find our major device number
*/
maj = cdevsw_lookup_major(&grf_cdevsw);
/*
* Handle exception case: early console init
*/
if (self == NULL) {
struct device itedev;
/*
* try and attach an ite
*/
config_found(self, sc /* XXX */, grfetprint, CFARGS_NONE);
/*
* If attaching the first unit, go ahead and 'find' the rest of us
*/
if (first_attach) {
first_attach = 0;
grf_auxp.from_bus_match = 0;
for (grf_auxp.unit=0; grf_auxp.unit < NGRFET; grf_auxp.unit++) {
config_found(parent, (void*)&grf_auxp,
grf_bus_auxp->busprint, CFARGS_NONE);
}
}
}
static int
grfetprint(void *aux, const char *pnp)
{
if (pnp) /* XXX */
aprint_normal("ite at %s", pnp);
return UNCONF;
}
/*
* save new values so that future opens use them
* this may not be correct when we implement Virtual Consoles
*/
ite_default_height = view->display.height;
ite_default_width = view->display.width;
ite_default_x = view->display.x;
ite_default_y = view->display.y;
ite_default_depth = view->bitmap->depth;
ip->cursorx = ip->curx;
ip->cursory = ip->cury;
break;
case ERASE_CURSOR:
/*WCrt(ba, CRT_ID_CURSOR_START, | 0x20); */
case START_CURSOROPT:
case END_CURSOROPT:
default:
break;
}
}
void
et_putc(struct ite_softc *ip, int c, int dy, int dx, int mode)
{
view_t *v = viewview(ip->grf->g_viewdev);
u_char attr;
u_short *cp;
/*
* Handle DEC special graphics character by 'ESC ( B' sequence.
* Note we assume all font data (fontdata_8x8 and fontdata_8x16)
* contain DEC graphics glyph (for 0x5f to 0x7e) at 0x00 to 0x1F.
*/
if (*ip->GL == CSET_DECGRAPH) {
if (ip->font.font_lo == 0 && c >= 0x5f && c <= 0x7e)
c -= 0x5f;
}
void
et_clear(struct ite_softc *ip, int sy, int sx, int h, int w)
{
/* et_clear and et_scroll both rely on ite passing arguments
* which describe continuous regions. For a VT200 terminal,
* this is safe behavior.
*/
view_t *v = viewview(ip->grf->g_viewdev);
u_short *dest;
int len;
dest = (u_short *)v->bitmap->plane + (sy * ip->cols) + sx;
for (len = w * h; len-- ;)
*dest++ = 0x2007;
}
void
et_scroll(struct ite_softc *ip, int sy, int sx, int count, int dir)
{
view_t *v = viewview(ip->grf->g_viewdev);
u_short *fb;
u_short *src, *dst;
int len;
if (loadfont) { /* XXX: We should set the colormap */
/*
* set colors (B&W)
*/
vgaw(ba, VDAC_ADDRESS_W, 0);
for (z = 0; z < 256; z++) {
y = (z & 1) ? ((z > 7) ? 2 : 1) : 0;
/*
* load text font into beginning of display memory. Each
* character cell is 32 bytes long (enough for 4 planes)
*/
for (z = 0, c = fb; z < 256 * 32; z++)
*c++ = 0;
c = (unsigned char *) (fb) + (32 * fd->font_lo);
f = fd->font_p;
z = fd->font_lo;
for (; z <= fd->font_hi; z++, c += (32 - fd->height))
for (y = 0; y < fd->height; y++) {
*c++ = *f++;
}
}