470 lines
9.6 KiB
C
470 lines
9.6 KiB
C
/* $NetBSD: fbbm_253.c,v 1.3 1999/02/15 04:36:34 hubertf Exp $ */
|
|
/*
|
|
* Copyright (c) 1992, 1993
|
|
* The Regents of the University of California. All rights reserved.
|
|
*
|
|
* This code is derived from software contributed to Berkeley by
|
|
* Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc.
|
|
*
|
|
* 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 the University of
|
|
* California, Berkeley and its contributors.
|
|
* 4. 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.
|
|
*
|
|
* from: $Hdr: fbbm_253.c,v 4.300 91/06/09 06:33:12 root Rel41 $ SONY;
|
|
*
|
|
* @(#)fbbm_253.c 8.1 (Berkeley) 6/11/93
|
|
*/
|
|
|
|
/*
|
|
* NWB-253 frame buffer driver
|
|
*/
|
|
|
|
#include "fb.h"
|
|
#define NNWB253 NFB /* XXX */
|
|
|
|
#if NNWB253 > 0
|
|
#include <sys/param.h>
|
|
|
|
#include <machine/framebuf.h>
|
|
#include <machine/locore.h>
|
|
|
|
#include <newsmips/dev/fbreg.h>
|
|
#include <newsmips/dev/fbdefs.h>
|
|
|
|
extern int fb_error();
|
|
extern int nofunc();
|
|
extern char *ext_fnt24_addr[];
|
|
extern char *ext_fnt_addr[];
|
|
|
|
extern short zero[];
|
|
|
|
#define NOP { int j; for (j = 0; j < 40; j++); }
|
|
|
|
#define VRAM_START (unsigned int *)(0x88000000)
|
|
#define VRAM_WIDTH (2048/32)
|
|
|
|
void
|
|
nwb253attach(i)
|
|
{
|
|
/* temporary hack for pseudo-device initialization */;
|
|
}
|
|
|
|
static caddr_t
|
|
fb253_Krom_addr(fb, c, sr)
|
|
struct fbdev *fb;
|
|
register int c;
|
|
lRectangle *sr;
|
|
{
|
|
unsigned int cvcode16();
|
|
|
|
if ((c >= 0x20) && (c <= 0x7e)) {
|
|
/*
|
|
* ASCII char
|
|
*/
|
|
c -= ' ';
|
|
c = ((c & 0x1f) | ((c & 0xe0) << 2)) << 7;
|
|
return (caddr_t)(c + fb->Krom_base + (sr->extent.y > 16 ? 0 : 96));
|
|
} else if ((c >= 0xa1) && (c <= 0xdf)) {
|
|
/*
|
|
* KANA char
|
|
*/
|
|
if (sr->extent.y > 16)
|
|
return ((caddr_t)ext_fnt24_addr[c + 64]);
|
|
else
|
|
return ((caddr_t)ext_fnt_addr[c + 64]);
|
|
} else if ((c >= 0x2020) && (c <= 0x7e7e)) {
|
|
/*
|
|
* KANJI char
|
|
*/
|
|
switch (c & 0x7000) {
|
|
case 0x2000:
|
|
c = ((c&0x1f)|((c&0x60)<<5)|((c&0x700)>>1))<<7;
|
|
break;
|
|
case 0x3000:
|
|
case 0x4000:
|
|
c = ((c&0x7f)|((c&0xf00)>>1)|((c&0x4000)>>3))<<7;
|
|
break;
|
|
case 0x5000:
|
|
case 0x6000:
|
|
c = ((c&0x7f)|((c&0xf00)>>1)|((c&0x2000)>>2)|0x1000)<<7;
|
|
break;
|
|
case 0x7000:
|
|
c = ((c&0x1f)|((c&0x60)<<5)|((c&0x700)>>1)|0x1000)<<7;
|
|
break;
|
|
}
|
|
return (caddr_t)(c + fb->Krom_base + (sr->extent.y > 16 ? 0 : 96));
|
|
} else {
|
|
/*
|
|
* UNKNOWN char
|
|
*/
|
|
return (caddr_t)zero;
|
|
}
|
|
}
|
|
|
|
static int
|
|
fb253_set_dimmer(fb, dim)
|
|
struct fbdev *fb;
|
|
int dim;
|
|
{
|
|
fb->status_flag = (fb->status_flag & 0xf3) | ((dim & 3) << 2);
|
|
*(volatile u_short *)(0xb8ff0000) = fb->status_flag;
|
|
|
|
return (FB_ROK);
|
|
}
|
|
|
|
static int
|
|
fb253_get_dimmer(fb)
|
|
struct fbdev *fb;
|
|
{
|
|
int dim;
|
|
|
|
dim = (fb->status_flag >> 2) & 3;
|
|
return (dim);
|
|
}
|
|
|
|
int
|
|
fb253_get_pixel(fb, pixel)
|
|
struct fbdev *fb;
|
|
register int pixel;
|
|
{
|
|
return (pixel);
|
|
}
|
|
|
|
int
|
|
fb253_ioctl(fb, cmd, data)
|
|
struct fbdev *fb;
|
|
int cmd;
|
|
int *data;
|
|
{
|
|
register int result = 0;
|
|
|
|
switch (cmd) {
|
|
case FB_INTCHECK:
|
|
if (*(volatile u_short *)(0xb8ff0000) & 0x08)
|
|
result |= FB_INT_VSYNC;
|
|
break;
|
|
case FB_INTENABLE:
|
|
if (*data & FB_INT_VSYNC) {
|
|
fb->status_flag |= 1;
|
|
*(volatile u_short *)(0xb8ff0000) = fb->status_flag;
|
|
WB_FLUSH;
|
|
}
|
|
break;
|
|
case FB_INTCLEAR:
|
|
if (*data & FB_INT_VSYNC) {
|
|
fb->status_flag &= ~1;
|
|
*(volatile u_short *)(0xb8ff0000) = fb->status_flag;
|
|
WB_FLUSH;
|
|
}
|
|
break;
|
|
case FB_STATUSCHECK:
|
|
break;
|
|
default:
|
|
result = -1;
|
|
}
|
|
return (result);
|
|
}
|
|
|
|
int
|
|
fb253_get_page(fb, off)
|
|
struct fbdev *fb;
|
|
int off;
|
|
{
|
|
if (off < 2048/8 * 2048) /* X/8 * Y */
|
|
return (((unsigned int)0x8000000 + off) >> PGSHIFT);
|
|
else
|
|
return (-1);
|
|
}
|
|
|
|
int
|
|
fb253_probe(unit)
|
|
int unit;
|
|
{
|
|
extern int badaddr __P((caddr_t, int));
|
|
|
|
if (unit >= NNWB253)
|
|
return 0;
|
|
if (badaddr((caddr_t)0xb8ff0000, 2) || badaddr((caddr_t)0xb8e00000, 2))
|
|
return 0;
|
|
if ((*(volatile u_short *)(0xb8ff0000) & 7) == 4)
|
|
return FB_NWB253;
|
|
return 0;
|
|
}
|
|
|
|
void fbmem_rop_init();
|
|
void fbmem_rop_copy();
|
|
void fbmem_rop_winit();
|
|
void fbmem_rop_write();
|
|
void fbmem_rop_read();
|
|
void fbmem_rop_cinit();
|
|
void fbmem_rop_clear();
|
|
void fbmem_rop_vect();
|
|
void fbmem_rop_dot();
|
|
|
|
static struct fbdev_ops
|
|
fb253_ops = {
|
|
fbmem_rop_init,
|
|
fbmem_rop_copy,
|
|
fbmem_rop_winit,
|
|
fbmem_rop_write,
|
|
fbmem_rop_read,
|
|
fbmem_rop_cinit,
|
|
fbmem_rop_clear,
|
|
fbmem_rop_vect,
|
|
fbmem_rop_dot,
|
|
(void (*)())nofunc,
|
|
(void (*)())fb_error,
|
|
(void (*)())fb_error,
|
|
fb253_Krom_addr,
|
|
(void (*)())fb_error,
|
|
fb_error,
|
|
fb_error,
|
|
fb253_get_pixel,
|
|
fb253_set_dimmer,
|
|
fb253_get_dimmer,
|
|
nofunc,
|
|
nofunc,
|
|
fb253_ioctl,
|
|
fb253_get_page,
|
|
(void (*)())nofunc,
|
|
(void (*)())nofunc,
|
|
(void (*)())nofunc,
|
|
(void (*)())nofunc,
|
|
};
|
|
|
|
static u_short
|
|
nwp512_data1[] = {
|
|
0x00, 0x44,
|
|
0x01, 0x33,
|
|
0x02, 0x3c,
|
|
0x03, 0x38,
|
|
0x04, 0x84,
|
|
0x05, 0x03,
|
|
0x06, 0x80,
|
|
0x07, 0x80,
|
|
0x08, 0x10,
|
|
0x09, 0x07,
|
|
0x0a, 0x20,
|
|
0x0c, 0x00,
|
|
0x0d, 0x00,
|
|
0x1b, 0x03
|
|
};
|
|
|
|
static u_short
|
|
nwp512_data2[] = {
|
|
0x1e, 0x08,
|
|
0x20, 0x08,
|
|
0x21, 0x0d
|
|
};
|
|
|
|
static u_short
|
|
nwp518_data1[] = {
|
|
0x00, 0x52,
|
|
0x01, 0x40,
|
|
0x02, 0x4a,
|
|
0x03, 0x49,
|
|
0x04, 0x63,
|
|
0x05, 0x02,
|
|
0x06, 0x60,
|
|
0x07, 0x60,
|
|
0x08, 0x10,
|
|
0x09, 0x07,
|
|
0x0a, 0x20,
|
|
0x0c, 0x00,
|
|
0x0d, 0x00,
|
|
0x1b, 0x04
|
|
};
|
|
|
|
static u_short
|
|
nwp518_data2[] = {
|
|
0x1e, 0x08,
|
|
0x20, 0x00,
|
|
0x21, 0x00
|
|
};
|
|
|
|
static u_short
|
|
nwe501_data1[] = {
|
|
0x00, 0x4b,
|
|
0x01, 0x40,
|
|
0x02, 0x4a,
|
|
0x03, 0x43,
|
|
0x04, 0x64,
|
|
0x05, 0x02,
|
|
0x06, 0x60,
|
|
0x07, 0x60,
|
|
0x08, 0x10,
|
|
0x09, 0x07,
|
|
0x0a, 0x20,
|
|
0x0c, 0x00,
|
|
0x0d, 0x00,
|
|
0x1b, 0x04
|
|
};
|
|
|
|
static u_short
|
|
nwe501_data2[] = {
|
|
0x1e, 0x08,
|
|
0x20, 0x00,
|
|
0x21, 0x00
|
|
};
|
|
|
|
static u_short
|
|
*crtc_data[3][2] = {
|
|
{ nwp512_data1, nwp512_data2 },
|
|
{ nwp518_data1, nwp518_data2 },
|
|
{ nwe501_data1, nwe501_data2 },
|
|
};
|
|
|
|
static void
|
|
fb253_init(fb, id)
|
|
struct fbdev *fb;
|
|
int id;
|
|
{
|
|
register int i;
|
|
register volatile u_short *ctlreg = (u_short *)(0xb8ff0000);
|
|
register volatile u_short *crtreg = (u_short *)(0xb8fe0000);
|
|
register volatile u_short *p;
|
|
|
|
*ctlreg = 0; /* stop crtc */
|
|
NOP;
|
|
|
|
/* initialize crtc without R3{0,1,2} */
|
|
p = crtc_data[id][0];
|
|
for (i = 0; i < 28; i++) {
|
|
*crtreg++ = *p++;
|
|
NOP;
|
|
}
|
|
|
|
*ctlreg = 0x02; /* start crtc */
|
|
NOP;
|
|
|
|
/* set crtc control reg */
|
|
p = crtc_data[id][1];
|
|
for (i = 0; i < 6; i++) {
|
|
*crtreg++ = *p++;
|
|
NOP;
|
|
}
|
|
}
|
|
|
|
struct mfbdev fb253 = { (caddr_t)VRAM_START, VRAM_WIDTH };
|
|
|
|
void
|
|
fb253_setup(fb)
|
|
struct fbdev *fb;
|
|
{
|
|
int id;
|
|
|
|
if (fb->type) {
|
|
fb->Mono = 1;
|
|
fb->Colorwidth = 1;
|
|
fb->fbNplane = 1;
|
|
fb->planemask = 0x1;
|
|
fb->Dimmer = 1;
|
|
|
|
id = ((*(volatile u_short *)(0xb8ff0000)) >> 8) & 0xf;
|
|
|
|
switch (id) {
|
|
case 0:
|
|
fb->FrameRect.extent.x = 2048;
|
|
fb->FrameRect.extent.y = 2048;
|
|
fb->VisRect.extent.x = 816;
|
|
fb->VisRect.extent.y = 1024;
|
|
fb->cursorP.x = 816/2;
|
|
fb->cursorP.y = 1024/2;
|
|
fb->font_w = 8;
|
|
fb->font_h = 16;
|
|
fb->char_w = 10;
|
|
fb->char_h = 24;
|
|
fb->scr_w = 816;
|
|
fb->scr_h = 1024;
|
|
fb->ch_pos = 5;
|
|
fb->ul_pos = 22;
|
|
fb->x_offset = 8;
|
|
fb->y_offset = 8;
|
|
fb->rit_m = 80;
|
|
fb->btm_m = 42;
|
|
break;
|
|
case 1:
|
|
case 2:
|
|
fb->FrameRect.extent.x = 2048;
|
|
fb->FrameRect.extent.y = 2048;
|
|
fb->VisRect.extent.x = 1024;
|
|
fb->VisRect.extent.y = 768;
|
|
fb->cursorP.x = 1024/2;
|
|
fb->cursorP.y = 768/2;
|
|
fb->font_w = 8;
|
|
fb->font_h = 16;
|
|
fb->char_w = 12;
|
|
fb->char_h = 22;
|
|
fb->scr_w = 1024;
|
|
fb->scr_h = 768;
|
|
fb->ch_pos = 2;
|
|
fb->ul_pos = 20;
|
|
fb->x_offset = 32;
|
|
fb->y_offset = 21;
|
|
fb->rit_m = 80;
|
|
fb->btm_m = 33;
|
|
break;
|
|
}
|
|
fb->FrameRect.origin.x = 0;
|
|
fb->FrameRect.origin.y = 0;
|
|
fb->VisRect.origin.x = 0;
|
|
fb->VisRect.origin.y = 0;
|
|
fb->Krom_BM0.type = BM_MEM;
|
|
fb->Krom_BM0.depth = 1;
|
|
fb->Krom_BM0.width = 1;
|
|
fb->Krom_BM0.rect.origin.x = 0;
|
|
fb->Krom_BM0.rect.origin.y = 0;
|
|
fb->Krom_BM0.rect.extent.x = 16;
|
|
fb->Krom_BM0.rect.extent.y = 16;
|
|
fb->Krom_BM1.type = BM_MEM;
|
|
fb->Krom_BM1.depth = 1;
|
|
fb->Krom_BM1.width = 2;
|
|
fb->Krom_BM1.rect.origin.x = 0;
|
|
fb->Krom_BM1.rect.origin.y = 0;
|
|
fb->Krom_BM1.rect.extent.x = 24;
|
|
fb->Krom_BM1.rect.extent.y = 24;
|
|
fb->Krom_base = (char *)(0xb8e00000);
|
|
fb->Krom_font_extent0.x = 16;
|
|
fb->Krom_font_extent0.y = 16;
|
|
fb->Krom_font_extent1.x = 24;
|
|
fb->Krom_font_extent1.y = 24;
|
|
fb->cursorSet = 0;
|
|
fb->cursorVis = 0;
|
|
fb->cursorShow = 0;
|
|
fb->status_flag = 2;
|
|
fb->run_flag = 0;
|
|
fb->hard_cursor = 0;
|
|
|
|
fb->fbbm_op = &fb253_ops;
|
|
|
|
fb->private = (caddr_t)&fb253;
|
|
|
|
fb253_init(fb, id);
|
|
}
|
|
}
|
|
#endif /* NNWB253 > 0 */
|