/*
* Copyright (c) 2005, Miodrag Vallat
*
* 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.
*/
/*
* Copyright (c) 1988 University of Utah.
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* the Systems Programming Group of the University of Utah Computer
* Science Department.
*
* 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.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
*/
if (fb->regaddr >= (uint8_t *)DIOII_BASE) {
/*
* For DIO-II space the fbaddr just computed is
* the offset from the select code base (regaddr)
* of the framebuffer. Hence it is also implicitly
* the size of the set.
*/
regsize = (uintptr_t)fb->fbaddr;
fb->fbaddr = fb->regaddr + (uintptr_t)fb->fbaddr;
fb->fbkva = (uint8_t *)fbr + regsize;
} else {
/*
* For internal or DIO-I space we need to map the separate
* framebuffer.
*/
fb->fbkva = iomap(fb->fbaddr, fb->fbsize);
if (fb->fbkva == NULL)
return ENOMEM;
}
if (fb->dwidth == 0 || fb->dheight == 0) {
fb->dwidth = (fbr->dwmsb << 8) | fbr->dwlsb;
fb->dheight = (fbr->dhmsb << 8) | fbr->dhlsb;
}
/*
* Some displays, such as the DaVinci, appear to return a display
* height larger than the frame buffer height.
*/
if (fb->dwidth > fb->fbwidth)
fb->dwidth = fb->fbwidth;
if (fb->dheight > fb->fbheight)
fb->dheight = fb->fbheight;
/*
* Pretend we are an 8bpp frame buffer, unless ri_depth is already
* initialized, since this is how it is supposed to be addressed.
* (Hyperion forces 1bpp because it is really 1bpp addressed).
*/
if (ri->ri_depth == 0)
ri->ri_depth = 8;
ri->ri_stride = (fb->fbwidth * ri->ri_depth) / 8;
ri->ri_flg = RI_CENTER | RI_FULLCLEAR;
/* We don't really support colors on less than 4bpp frame buffers */
if (fb->planes < 4)
ri->ri_flg |= RI_FORCEMONO;
if (fb == &diofb_cn)
ri->ri_flg |= RI_NO_AUTO;
ri->ri_bits = fb->fbkva;
ri->ri_width = fb->dwidth;
ri->ri_height = fb->dheight;
ri->ri_hw = fb;
/*
* Ask for an unholy big display, rasops will trim this to more
* reasonable values.
*/
rasops_init(ri, 160, 160);
diofb_resetcmap(fb);
/*
* For low depth frame buffers, since we have faked a 8bpp frame buffer
* to rasops, we actually have to remove capabilities.
*/
if (fb->planes == 4) {
ri->ri_ops.allocattr = diofb_allocattr;
ri->ri_caps &= ~WSSCREEN_HILIT;
}
/* start with the rasops colormap */
color = (const u_char *)rasops_cmap;
for (i = 0; i < 256; i++) {
fb->cmap.r[i] = *color++;
fb->cmap.g[i] = *color++;
fb->cmap.b[i] = *color++;
}
/*
* Tweak colormap
*
* Due to the way rasops cursor work, we need to provide
* copies of the 8 or 16 basic colors at extra locations
* in 4bpp and 6bpp mode. This is because missing planes
* accept writes but read back as zero.
*
* So, in 6bpp mode:
* 00 gets inverted to ff, read back as 3f
* 3f gets inverted to c0, read back as 00
* and in 4bpp mode:
* 00 gets inverted to ff, read back as 0f
* 0f gets inverted to f0, read back as 00
*/
void
diofb_erasecols(void *cookie, int row, int col, int num, long attr)
{
struct rasops_info *ri = cookie;
struct diofb *fb = ri->ri_hw;
int fg, bg;
int snum, scol, srow;
int fontwidth = fb->wsd.fontwidth;
rasops_unpack_attr(attr, &fg, &bg, NULL);
snum = num * fontwidth;
scol = col * fontwidth + ri->ri_xorigin;
srow = row * ri->ri_font->fontheight + ri->ri_yorigin;
/*
* If this is too tricky for the simple raster ops engine,
* pass the fun to rasops.
*/
if ((*fb->bmv)(fb, scol, srow, scol, srow, snum,
ri->ri_font->fontheight, RR_CLEAR, 0xff ^ bg) != 0)
rasops_erasecols(cookie, row, col, num, attr);
}
void
diofb_eraserows(void *cookie, int row, int num, long attr)
{
struct rasops_info *ri = cookie;
struct diofb *fb = ri->ri_hw;
int fg, bg;
int srow, snum;
int rc;