/*
* Copyright (c) 1995 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.
*/
/*
* Note that the order of this table *must* match the order of
* the table below!
*/
static struct tt_hwregs tt_hwregs[] = {
{ RES_STHIGH },
{ RES_TTHIGH },
{ RES_STMID },
{ RES_STLOW },
{ RES_TTMID },
{ RES_TTLOW }
};
/*
* XXX: called from ite console init routine.
* Initialize list of possible video modes.
*/
void
tt_probe_video(MODES *modelp)
{
dmode_t *dm;
int i;
int has_mono;
/*
* First find out what kind of monitor is attached. DMA-sound
* should be off because the 'sound-done' and 'monochrome-detect'
* are xor-ed together. I think that shutting it down here is the
* wrong place.
*/
has_mono = (MFP->mf_gpip & IA_MONO) == 0;
for (i = 0; (dm = &vid_modes[i])->name != NULL; i++) {
dm->data = (void *)&tt_hwregs[i];
if (has_mono && (vm_reg(dm) != RES_TTHIGH))
continue;
if (!has_mono && (vm_reg(dm) == RES_TTHIGH))
continue;
LIST_INSERT_HEAD(modelp, dm, link);
}
for (i=0; i < 16; i++)
VIDEO->vd_tt_rgb[i] = CM_L2TT(gra_def_color16[i]);
}
if (dm->current_view) {
/*
* Mark current view for this mode as no longer displayed
*/
dm->current_view->flags &= ~VF_DISPLAY;
}
dm->current_view = v;
v->flags |= VF_DISPLAY;
tt_use_colormap(v, v->colormap);
/* XXX: should use vbl for this */
VIDEO->vd_tt_res = vm_reg(dm);
VIDEO->vd_raml = (u_long)bm->hw_address & 0xff;
VIDEO->vd_ramm = ((u_long)bm->hw_address >> 8) & 0xff;
VIDEO->vd_ramh = ((u_long)bm->hw_address >> 16) & 0xff;
}
if (v) {
tt_remove_view(v);
if (v->colormap != &gra_con_cmap)
free(v->colormap, M_DEVBUF);
free_bitmap(v->bitmap);
if (v != &gra_con_view)
free(v, M_DEVBUF);
}
}
/*
* I guess it seems reasonable to require the maps to be
* of the same type...
*/
if (cm->type != vcm->type)
return(EINVAL);
/*
* First figure out where the actual colormap resides and
* howmany colors are in it.
*/
switch (vm_reg(dm)) {
case RES_STLOW:
creg = &VIDEO->vd_tt_rgb[0];
ncreg = 16;
break;
case RES_STMID:
creg = &VIDEO->vd_tt_rgb[0];
ncreg = 4;
break;
case RES_STHIGH:
creg = &VIDEO->vd_tt_rgb[254];
ncreg = 2;
break;
case RES_TTLOW:
creg = &VIDEO->vd_tt_rgb[0];
ncreg = 256;
break;
case RES_TTMID:
creg = &VIDEO->vd_tt_rgb[0];
ncreg = 16;
break;
case RES_TTHIGH:
return(0); /* No colors */
default:
panic("grf_tt:use_colormap: wrong mode!?");
}
/* If first entry specified beyond capabilities -> error */
if (cm->first >= ncreg)
return(EINVAL);
/*
* A little tricky, the actual colormap pointer will be NULL
* when view is not displaying, valid otherwise.
*/
if (v->flags & VF_DISPLAY)
creg = &creg[cm->first];
else
creg = NULL;
/*
* Sigh, it seems for mapping to work we need the bitplane data to
* 1: be aligned on a page boundary.
* 2: be n pages large.
*
* why? because the user gets a page aligned address, if this is before
* your allocation, too bad. Also it seems that the mapping routines
* do not watch to closely to the allowable length. so if you go over
* n pages by less than another page, the user gets to write all over
* the entire page. Since you did not allocate up to a page boundary
* (or more) the user writes into someone elses memory. -ch
*/
bm_size = m68k_round_page((width * height * depth) / NBBY);
total_size = bm_size + sizeof(bmap_t) + PAGE_SIZE;
if ((bm = (bmap_t*)alloc_stmem(total_size, &hw_address)) == NULL)
return(NULL);