729 lines
16 KiB
C
729 lines
16 KiB
C
/* $NetBSD: ite_tv.c,v 1.15 2007/03/11 06:01:05 isaki Exp $ */
|
|
|
|
/*
|
|
* Copyright (c) 1997 Masaru Oki.
|
|
* 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.
|
|
* 3. All advertising materials mentioning features or use of this software
|
|
* must display the following acknowledgement:
|
|
* This product includes software developed by Masaru Oki.
|
|
* 4. The name of the author may not be used to endorse or promote products
|
|
* derived from this software without specific prior written permission
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
#include <sys/cdefs.h>
|
|
__KERNEL_RCSID(0, "$NetBSD: ite_tv.c,v 1.15 2007/03/11 06:01:05 isaki Exp $");
|
|
|
|
#include <sys/param.h>
|
|
#include <sys/device.h>
|
|
#include <sys/proc.h>
|
|
#include <sys/systm.h>
|
|
|
|
#include <machine/bus.h>
|
|
#include <machine/grfioctl.h>
|
|
|
|
#include <arch/x68k/x68k/iodevice.h>
|
|
#include <arch/x68k/dev/itevar.h>
|
|
#include <arch/x68k/dev/grfvar.h>
|
|
#include <arch/x68k/dev/mfp.h>
|
|
|
|
/*
|
|
* ITE device dependent routine for X680x0 Text-Video framebuffer.
|
|
* Use X680x0 ROM fixed width font (8x16)
|
|
*/
|
|
|
|
#define CRTC (IODEVbase->io_crtc)
|
|
|
|
/*
|
|
* font constant
|
|
*/
|
|
#define FONTWIDTH 8
|
|
#define FONTHEIGHT 16
|
|
#define UNDERLINE 14
|
|
|
|
/*
|
|
* framebuffer constant
|
|
*/
|
|
#define PLANEWIDTH 1024
|
|
#define PLANEHEIGHT 1024
|
|
#define PLANELINES (PLANEHEIGHT / FONTHEIGHT)
|
|
#define ROWBYTES (PLANEWIDTH / FONTWIDTH)
|
|
#define PLANESIZE (PLANEHEIGHT * ROWBYTES)
|
|
|
|
u_int tv_top;
|
|
u_char *tv_row[PLANELINES];
|
|
char *tv_font[256];
|
|
volatile char *tv_kfont[0x7f];
|
|
|
|
u_char kern_font[256 * FONTHEIGHT];
|
|
|
|
#define PHYSLINE(y) ((tv_top + (y)) % PLANELINES)
|
|
#define ROWOFFSET(y) ((y) * FONTHEIGHT * ROWBYTES)
|
|
#define CHADDR(y, x) (tv_row[PHYSLINE(y)] + (x))
|
|
|
|
#define SETGLYPH(to,from) memcpy(&kern_font[(from)*16],&kern_font[(to)*16], 16)
|
|
#define KFONTBASE(left) ((left) * 32 * 0x5e - 0x21 * 32)
|
|
|
|
/* prototype */
|
|
void tv_init(struct ite_softc *);
|
|
void tv_deinit(struct ite_softc *);
|
|
void tv_putc(struct ite_softc *, int, int, int, int);
|
|
void tv_cursor(struct ite_softc *, int);
|
|
void tv_clear(struct ite_softc *, int, int, int, int);
|
|
void tv_scroll(struct ite_softc *, int, int, int, int);
|
|
|
|
inline static int expbits(int);
|
|
inline static void txrascpy(u_char, u_char, short, signed short);
|
|
|
|
static inline void
|
|
txrascpy(u_char src, u_char dst, short size, short mode)
|
|
{
|
|
/*int s;*/
|
|
u_short saved_r21 = CRTC.r21;
|
|
char d;
|
|
|
|
d = (mode < 0) ? -1 : 1;
|
|
src *= FONTHEIGHT / 4;
|
|
dst *= FONTHEIGHT / 4;
|
|
size *= 4;
|
|
if (d < 0) {
|
|
src += (FONTHEIGHT / 4) - 1;
|
|
dst += (FONTHEIGHT / 4) - 1;
|
|
}
|
|
|
|
/* specify same time write mode & page */
|
|
CRTC.r21 = (mode & 0x0f) | 0x0100;
|
|
/*mfp.ddr = 0;*/ /* port is input */
|
|
|
|
/*s = splhigh();*/
|
|
while (--size >= 0) {
|
|
/* wait for hsync */
|
|
mfp_wait_for_hsync ();
|
|
CRTC.r22 = (src << 8) | dst; /* specify raster number */
|
|
/* start raster copy */
|
|
CRTC.crtctrl = 8;
|
|
|
|
src += d;
|
|
dst += d;
|
|
}
|
|
/*splx(s);*/
|
|
|
|
/* wait for hsync */
|
|
mfp_wait_for_hsync ();
|
|
|
|
/* stop raster copy */
|
|
CRTC.crtctrl = 0;
|
|
|
|
CRTC.r21 = saved_r21;
|
|
}
|
|
|
|
/*
|
|
* Change glyphs from SRAM switch.
|
|
*/
|
|
void
|
|
ite_set_glyph(void)
|
|
{
|
|
u_char glyph = IODEVbase->io_sram[0x59];
|
|
|
|
if (glyph & 4)
|
|
SETGLYPH(0x82, '|');
|
|
if (glyph & 2)
|
|
SETGLYPH(0x81, '~');
|
|
if (glyph & 1)
|
|
SETGLYPH(0x80, '\\');
|
|
}
|
|
|
|
/*
|
|
* Initialize
|
|
*/
|
|
void
|
|
tv_init(struct ite_softc *ip)
|
|
{
|
|
short i;
|
|
|
|
/*
|
|
* initialize private variables
|
|
*/
|
|
tv_top = 0;
|
|
for (i = 0; i < PLANELINES; i++)
|
|
tv_row[i] = (void *)__UNVOLATILE(&IODEVbase->tvram[ROWOFFSET(i)]);
|
|
/* shadow ANK font */
|
|
memcpy(kern_font, (void *)&IODEVbase->cgrom0_8x16, 256 * FONTHEIGHT);
|
|
ite_set_glyph();
|
|
/* set font address cache */
|
|
for (i = 0; i < 256; i++)
|
|
tv_font[i] = &kern_font[i * FONTHEIGHT];
|
|
for (i = 0x21; i < 0x30; i++)
|
|
tv_kfont[i] = &IODEVbase->cgrom0_16x16[KFONTBASE(i-0x21)];
|
|
for (; i < 0x50; i++)
|
|
tv_kfont[i] = &IODEVbase->cgrom1_16x16[KFONTBASE(i-0x30)];
|
|
for (; i < 0x7f; i++)
|
|
tv_kfont[i] = &IODEVbase->cgrom2_16x16[KFONTBASE(i-0x50)];
|
|
|
|
/*
|
|
* initialize part of ip
|
|
*/
|
|
ip->cols = ip->grf->g_display.gd_dwidth / FONTWIDTH;
|
|
ip->rows = ip->grf->g_display.gd_dheight / FONTHEIGHT;
|
|
/* set draw routine dynamically */
|
|
ip->isw->ite_putc = tv_putc;
|
|
ip->isw->ite_cursor = tv_cursor;
|
|
ip->isw->ite_clear = tv_clear;
|
|
ip->isw->ite_scroll = tv_scroll;
|
|
|
|
/*
|
|
* Intialize colormap
|
|
*/
|
|
#define RED (0x1f << 6)
|
|
#define BLUE (0x1f << 1)
|
|
#define GREEN (0x1f << 11)
|
|
IODEVbase->tpalet[0] = 0; /* black */
|
|
IODEVbase->tpalet[1] = 1 | RED; /* red */
|
|
IODEVbase->tpalet[2] = 1 | GREEN; /* green */
|
|
IODEVbase->tpalet[3] = 1 | RED | GREEN; /* yellow */
|
|
IODEVbase->tpalet[4] = 1 | BLUE; /* blue */
|
|
IODEVbase->tpalet[5] = 1 | BLUE | RED; /* magenta */
|
|
IODEVbase->tpalet[6] = 1 | BLUE | GREEN; /* cyan */
|
|
IODEVbase->tpalet[7] = 1 | BLUE | RED | GREEN; /* white */
|
|
}
|
|
|
|
/*
|
|
* Deinitialize
|
|
*/
|
|
void
|
|
tv_deinit(struct ite_softc *ip)
|
|
{
|
|
ip->flags &= ~ITE_INITED; /* XXX? */
|
|
}
|
|
|
|
typedef void tv_putcfunc(struct ite_softc *, int, char *);
|
|
static tv_putcfunc tv_putc_nm;
|
|
static tv_putcfunc tv_putc_in;
|
|
static tv_putcfunc tv_putc_ul;
|
|
static tv_putcfunc tv_putc_ul_in;
|
|
static tv_putcfunc tv_putc_bd;
|
|
static tv_putcfunc tv_putc_bd_in;
|
|
static tv_putcfunc tv_putc_bd_ul;
|
|
static tv_putcfunc tv_putc_bd_ul_in;
|
|
|
|
static tv_putcfunc *putc_func[ATTR_ALL + 1] = {
|
|
tv_putc_nm,
|
|
tv_putc_in,
|
|
tv_putc_ul,
|
|
tv_putc_ul_in,
|
|
tv_putc_bd,
|
|
tv_putc_bd_in,
|
|
tv_putc_bd_ul,
|
|
tv_putc_bd_ul_in,
|
|
/* no support for blink */
|
|
tv_putc_nm,
|
|
tv_putc_in,
|
|
tv_putc_ul,
|
|
tv_putc_ul_in,
|
|
tv_putc_bd,
|
|
tv_putc_bd_in,
|
|
tv_putc_bd_ul,
|
|
tv_putc_bd_ul_in,
|
|
};
|
|
|
|
/*
|
|
* simple put character function
|
|
*/
|
|
void
|
|
tv_putc(struct ite_softc *ip, int ch, int y, int x, int mode)
|
|
{
|
|
char *p = CHADDR(y, x);
|
|
short fh;
|
|
|
|
/* multi page write mode */
|
|
CRTC.r21 = 0x0100 | ip->fgcolor << 4;
|
|
|
|
/* draw plane */
|
|
putc_func[mode](ip, ch, p);
|
|
|
|
/* erase plane */
|
|
CRTC.r21 ^= 0x00f0;
|
|
if (ip->save_char) {
|
|
for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
|
|
*(u_short *)p = 0;
|
|
} else {
|
|
for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
|
|
*p = 0;
|
|
}
|
|
|
|
/* crtc mode reset */
|
|
CRTC.r21 = 0;
|
|
}
|
|
|
|
void
|
|
tv_putc_nm(struct ite_softc *ip, int ch, char *p)
|
|
{
|
|
short fh, hi;
|
|
char *f;
|
|
volatile short *kf;
|
|
|
|
hi = ip->save_char & 0x7f;
|
|
|
|
if (hi >= 0x21 && hi <= 0x7e) {
|
|
/* multibyte character */
|
|
kf = (volatile short *)tv_kfont[hi];
|
|
kf += (ch & 0x7f) * FONTHEIGHT;
|
|
/* draw plane */
|
|
for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
|
|
*(u_short *)p = *kf++;
|
|
return;
|
|
}
|
|
|
|
/* singlebyte character */
|
|
if (*ip->GL == CSET_JISKANA)
|
|
ch |= 0x80;
|
|
f = tv_font[ch];
|
|
|
|
/* draw plane */
|
|
for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
|
|
*p = *f++;
|
|
}
|
|
|
|
void
|
|
tv_putc_in(struct ite_softc *ip, int ch, char *p)
|
|
{
|
|
short fh, hi;
|
|
char *f;
|
|
volatile short *kf;
|
|
|
|
hi = ip->save_char & 0x7f;
|
|
|
|
if (hi >= 0x21 && hi <= 0x7e) {
|
|
/* multibyte character */
|
|
kf = (volatile short *)tv_kfont[hi];
|
|
kf += (ch & 0x7f) * FONTHEIGHT;
|
|
/* draw plane */
|
|
for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
|
|
*(u_short *)p = ~*kf++;
|
|
return;
|
|
}
|
|
|
|
/* singlebyte character */
|
|
if (*ip->GL == CSET_JISKANA)
|
|
ch |= 0x80;
|
|
f = tv_font[ch];
|
|
|
|
/* draw plane */
|
|
for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
|
|
*p = ~*f++;
|
|
}
|
|
|
|
void
|
|
tv_putc_bd(struct ite_softc *ip, int ch, char *p)
|
|
{
|
|
short fh, hi;
|
|
char *f;
|
|
volatile short *kf;
|
|
|
|
hi = ip->save_char & 0x7f;
|
|
|
|
if (hi >= 0x21 && hi <= 0x7e) {
|
|
/* multibyte character */
|
|
kf = (volatile short *)tv_kfont[hi];
|
|
kf += (ch & 0x7f) * FONTHEIGHT;
|
|
/* draw plane */
|
|
for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES) {
|
|
ch = *kf++;
|
|
*(u_short *)p = ch | (ch >> 1);
|
|
}
|
|
return;
|
|
}
|
|
|
|
/* singlebyte character */
|
|
if (*ip->GL == CSET_JISKANA)
|
|
ch |= 0x80;
|
|
f = tv_font[ch];
|
|
|
|
/* draw plane */
|
|
for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES) {
|
|
ch = *f++;
|
|
*p = ch | (ch >> 1);
|
|
}
|
|
}
|
|
|
|
inline static int
|
|
expbits(int data)
|
|
{
|
|
int i, nd = 0;
|
|
if (data & 1)
|
|
nd |= 0x02;
|
|
for (i=1; i < 32; i++) {
|
|
if (data & (1 << i))
|
|
nd |= 0x5 << (i-1);
|
|
}
|
|
nd &= ~data;
|
|
return (~nd);
|
|
}
|
|
|
|
void
|
|
tv_putc_ul(struct ite_softc *ip, int ch, char *p)
|
|
{
|
|
short fh, hi;
|
|
char *f;
|
|
volatile short *kf;
|
|
|
|
hi = ip->save_char & 0x7f;
|
|
|
|
if (hi >= 0x21 && hi <= 0x7e) {
|
|
/* multibyte character */
|
|
kf = (volatile short *)tv_kfont[hi];
|
|
kf += (ch & 0x7f) * FONTHEIGHT;
|
|
/* draw plane */
|
|
for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES)
|
|
*(u_short *)p = *kf++;
|
|
*(u_short *)p = expbits(*kf++);
|
|
p += ROWBYTES;
|
|
for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES)
|
|
*(u_short *)p = *kf++;
|
|
return;
|
|
}
|
|
|
|
/* singlebyte character */
|
|
if (*ip->GL == CSET_JISKANA)
|
|
ch |= 0x80;
|
|
f = tv_font[ch];
|
|
|
|
/* draw plane */
|
|
for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES)
|
|
*p = *f++;
|
|
*p = expbits(*f++);
|
|
p += ROWBYTES;
|
|
for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES)
|
|
*p = *f++;
|
|
}
|
|
|
|
void
|
|
tv_putc_bd_in(struct ite_softc *ip, int ch, char *p)
|
|
{
|
|
short fh, hi;
|
|
char *f;
|
|
volatile short *kf;
|
|
|
|
hi = ip->save_char & 0x7f;
|
|
|
|
if (hi >= 0x21 && hi <= 0x7e) {
|
|
/* multibyte character */
|
|
kf = (volatile short *)tv_kfont[hi];
|
|
kf += (ch & 0x7f) * FONTHEIGHT;
|
|
/* draw plane */
|
|
for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES) {
|
|
ch = *kf++;
|
|
*(u_short *)p = ~(ch | (ch >> 1));
|
|
}
|
|
return;
|
|
}
|
|
|
|
/* singlebyte character */
|
|
if (*ip->GL == CSET_JISKANA)
|
|
ch |= 0x80;
|
|
f = tv_font[ch];
|
|
|
|
/* draw plane */
|
|
for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES) {
|
|
ch = *f++;
|
|
*p = ~(ch | (ch >> 1));
|
|
}
|
|
}
|
|
|
|
void
|
|
tv_putc_ul_in(struct ite_softc *ip, int ch, char *p)
|
|
{
|
|
short fh, hi;
|
|
char *f;
|
|
volatile short *kf;
|
|
|
|
hi = ip->save_char & 0x7f;
|
|
|
|
if (hi >= 0x21 && hi <= 0x7e) {
|
|
/* multibyte character */
|
|
kf = (volatile short *)tv_kfont[hi];
|
|
kf += (ch & 0x7f) * FONTHEIGHT;
|
|
/* draw plane */
|
|
for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES)
|
|
*(u_short *)p = ~*kf++;
|
|
*(u_short *)p = ~expbits(*kf++);
|
|
p += ROWBYTES;
|
|
for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES)
|
|
*(u_short *)p = ~*kf++;
|
|
return;
|
|
}
|
|
|
|
/* singlebyte character */
|
|
if (*ip->GL == CSET_JISKANA)
|
|
ch |= 0x80;
|
|
f = tv_font[ch];
|
|
|
|
/* draw plane */
|
|
for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES)
|
|
*p = ~*f++;
|
|
*p = ~expbits(*f++);
|
|
p += ROWBYTES;
|
|
for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES)
|
|
*p = ~*f++;
|
|
}
|
|
|
|
void
|
|
tv_putc_bd_ul(struct ite_softc *ip, int ch, char *p)
|
|
{
|
|
short fh, hi;
|
|
char *f;
|
|
volatile short *kf;
|
|
|
|
hi = ip->save_char & 0x7f;
|
|
|
|
if (hi >= 0x21 && hi <= 0x7e) {
|
|
/* multibyte character */
|
|
kf = (volatile short *)tv_kfont[hi];
|
|
kf += (ch & 0x7f) * FONTHEIGHT;
|
|
/* draw plane */
|
|
for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES) {
|
|
ch = *kf++;
|
|
*(u_short *)p = ch | (ch >> 1);
|
|
}
|
|
ch = *kf++;
|
|
*(u_short *)p = expbits(ch | (ch >> 1));
|
|
p += ROWBYTES;
|
|
for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES) {
|
|
ch = *kf++;
|
|
*(u_short *)p = ch | (ch >> 1);
|
|
}
|
|
return;
|
|
}
|
|
|
|
/* singlebyte character */
|
|
if (*ip->GL == CSET_JISKANA)
|
|
ch |= 0x80;
|
|
f = tv_font[ch];
|
|
|
|
/* draw plane */
|
|
for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES) {
|
|
ch = *f++;
|
|
*p = ch | (ch >> 1);
|
|
}
|
|
ch = *f++;
|
|
*p = expbits(ch | (ch >> 1));
|
|
p += ROWBYTES;
|
|
for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES) {
|
|
ch = *f++;
|
|
*p = ch | (ch >> 1);
|
|
}
|
|
}
|
|
|
|
void
|
|
tv_putc_bd_ul_in(struct ite_softc *ip, int ch, char *p)
|
|
{
|
|
short fh, hi;
|
|
char *f;
|
|
volatile short *kf;
|
|
|
|
hi = ip->save_char & 0x7f;
|
|
|
|
if (hi >= 0x21 && hi <= 0x7e) {
|
|
/* multibyte character */
|
|
kf = (volatile short *)tv_kfont[hi];
|
|
kf += (ch & 0x7f) * FONTHEIGHT;
|
|
/* draw plane */
|
|
for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES) {
|
|
ch = *kf++;
|
|
*(u_short *)p = ~(ch | (ch >> 1));
|
|
}
|
|
ch = *kf++;
|
|
*(u_short *)p = ~expbits(ch | (ch >> 1));
|
|
p += ROWBYTES;
|
|
for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES) {
|
|
ch = *kf++;
|
|
*(u_short *)p = ~(ch | (ch >> 1));
|
|
}
|
|
return;
|
|
}
|
|
|
|
/* singlebyte character */
|
|
if (*ip->GL == CSET_JISKANA)
|
|
ch |= 0x80;
|
|
f = tv_font[ch];
|
|
|
|
/* draw plane */
|
|
for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES) {
|
|
ch = *f++;
|
|
*p = ~(ch | (ch >> 1));
|
|
}
|
|
ch = *f++;
|
|
*p = ~expbits(ch | (ch >> 1));
|
|
p += ROWBYTES;
|
|
for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES) {
|
|
ch = *f++;
|
|
ch |= ch >> 1;
|
|
*p = ~(ch | (ch >> 1));
|
|
}
|
|
}
|
|
|
|
/*
|
|
* draw/erase/move cursor
|
|
*/
|
|
void
|
|
tv_cursor(struct ite_softc *ip, int flag)
|
|
{
|
|
u_char *p;
|
|
short fh;
|
|
|
|
/* erase */
|
|
switch (flag) {
|
|
/*case DRAW_CURSOR:*/
|
|
/*case ERASE_CURSOR:*/
|
|
/*case MOVE_CURSOR:*/
|
|
case START_CURSOROPT:
|
|
/*
|
|
* old: ip->cursorx, ip->cursory
|
|
* new: ip->curx, ip->cury
|
|
*/
|
|
p = CHADDR(ip->cursory, ip->cursorx);
|
|
for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
|
|
*p = ~*p;
|
|
break;
|
|
}
|
|
|
|
/* draw */
|
|
switch (flag) {
|
|
/*case MOVE_CURSOR:*/
|
|
case END_CURSOROPT:
|
|
/*
|
|
* Use exclusive-or.
|
|
*/
|
|
p = CHADDR(ip->cury, ip->curx);
|
|
for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
|
|
*p = ~*p;
|
|
|
|
ip->cursorx = ip->curx;
|
|
ip->cursory = ip->cury;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* clear rectangle
|
|
*/
|
|
void
|
|
tv_clear(struct ite_softc *ip, int y, int x, int height, int width)
|
|
{
|
|
char *p;
|
|
short fh;
|
|
|
|
/* XXX: reset scroll register on clearing whole screen */
|
|
if (y == 0 && x == 0 && height == ip->rows && width == ip->cols) {
|
|
CRTC.r10 = 0;
|
|
CRTC.r11 = tv_top * FONTHEIGHT;
|
|
}
|
|
|
|
CRTC.r21 = 0x01f0;
|
|
while (height--) {
|
|
p = CHADDR(y++, x);
|
|
for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
|
|
memset(p, 0, width);
|
|
}
|
|
/* crtc mode reset */
|
|
CRTC.r21 = 0;
|
|
}
|
|
|
|
/*
|
|
* scroll lines/columns
|
|
*/
|
|
void
|
|
tv_scroll(struct ite_softc *ip, int srcy, int srcx, int count, int dir)
|
|
{
|
|
int dst, siz, pl;
|
|
|
|
switch (dir) {
|
|
case SCROLL_UP:
|
|
/*
|
|
* src: srcy
|
|
* dst: (srcy - count)
|
|
* siz: (ip->bottom_margin - sy + 1)
|
|
*/
|
|
dst = srcy - count;
|
|
siz = ip->bottom_margin - srcy + 1;
|
|
if (dst == 0 && ip->bottom_margin == ip->rows - 1) {
|
|
/* special case, hardware scroll */
|
|
tv_top = (tv_top + count) % PLANELINES;
|
|
CRTC.r11 = tv_top * FONTHEIGHT;
|
|
} else {
|
|
srcy = PHYSLINE(srcy);
|
|
dst = PHYSLINE(dst);
|
|
txrascpy(srcy, dst, siz, 0x0f);
|
|
}
|
|
break;
|
|
|
|
case SCROLL_DOWN:
|
|
/*
|
|
* src: srcy
|
|
* dst: (srcy + count)
|
|
* siz: (ip->bottom_margin - dy + 1)
|
|
*/
|
|
dst = srcy + count;
|
|
siz = ip->bottom_margin - dst + 1;
|
|
if (srcy == 0 && ip->bottom_margin == ip->rows - 1) {
|
|
/* special case, hardware scroll */
|
|
tv_top = (tv_top + PLANELINES - count) % PLANELINES;
|
|
CRTC.r11 = tv_top * FONTHEIGHT;
|
|
} else {
|
|
srcy = PHYSLINE(srcy) + siz - 1;
|
|
dst = PHYSLINE(dst) + siz - 1;
|
|
txrascpy(srcy, dst, siz, 0x0f | 0x8000);
|
|
}
|
|
break;
|
|
|
|
case SCROLL_LEFT:
|
|
for (pl = 0; pl < PLANESIZE * 4; pl += PLANESIZE) {
|
|
short fh;
|
|
char *src = CHADDR(srcy, srcx) + pl;
|
|
char *dest = CHADDR(srcy, srcx - count) + pl;
|
|
|
|
siz = ip->cols - srcx;
|
|
for (fh = 0; fh < FONTHEIGHT; fh++) {
|
|
memcpy(dest, src, siz);
|
|
src += ROWBYTES;
|
|
dest += ROWBYTES;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case SCROLL_RIGHT:
|
|
for (pl = 0; pl < PLANESIZE * 4; pl += PLANESIZE) {
|
|
short fh;
|
|
char *src = CHADDR(srcy, srcx) + pl;
|
|
char *dest = CHADDR(srcy, srcx + count) + pl;
|
|
|
|
siz = ip->cols - (srcx + count);
|
|
for (fh = 0; fh < FONTHEIGHT; fh++) {
|
|
memcpy(dest, src, siz);
|
|
src += ROWBYTES;
|
|
dest += ROWBYTES;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|