|
|
GNU Mach 1.0
/*
* Mach Operating System
* Copyright (c) 1991,1990,1989 Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or [email protected]
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie Mellon
* the rights to redistribute these changes.
*/
/*
* File: bt459.c
* Author: Alessandro Forin, Carnegie Mellon University
* Date: 9/90
*
* Routines for the bt459 RAMDAC
*/
#include <platforms.h>
#include <chips/bt459.h>
#include <chips/screen.h>
#ifdef DECSTATION
typedef struct {
volatile unsigned char addr_lo;
char pad0[3];
volatile unsigned char addr_hi;
char pad1[3];
volatile unsigned char addr_reg;
char pad2[3];
volatile unsigned char addr_cmap;
char pad3[3];
} bt459_ds_padded_regmap_t;
#define bt459_padded_regmap_t bt459_ds_padded_regmap_t
#define mb() /* no write/read reordering problems */
#endif /* DECSTATION */
#ifdef FLAMINGO
/* Sparse space ! */
typedef struct {
volatile unsigned int addr_lo;
int pad0;
volatile unsigned int addr_hi;
int pad1;
volatile unsigned int addr_reg;
int pad2;
volatile unsigned int addr_cmap;
int pad3;
} bt459_fl_padded_regmap_t;
#define bt459_padded_regmap_t bt459_fl_padded_regmap_t
#define mb() wbflush()
#endif /* FLAMINGO */
#ifndef bt459_padded_regmap_t
typedef bt459_regmap_t bt459_padded_regmap_t;
#define wbflush()
#endif
/*
* Generic register access
*/
#define bt459_select_reg_macro(r,n) \
(r)->addr_lo = (n); mb(); \
(r)->addr_hi = (n) >> 8; \
wbflush();
void
bt459_select_reg(
bt459_padded_regmap_t *regs,
int regno)
{
bt459_select_reg_macro( regs, regno);
}
void
bt459_write_reg(
bt459_padded_regmap_t *regs,
int regno,
unsigned char val)
{
bt459_select_reg_macro( regs, regno );
regs->addr_reg = val;
wbflush();
}
unsigned char
bt459_read_reg(
bt459_padded_regmap_t *regs,
int regno)
{
bt459_select_reg_macro( regs, regno );
return regs->addr_reg;
}
/*
* Color map
*/
bt459_load_colormap_entry(
bt459_padded_regmap_t *regs,
int entry,
color_map_t *map)
{
bt459_select_reg(regs, entry & 0xff);
regs->addr_cmap = map->red;
wbflush();
regs->addr_cmap = map->green;
wbflush();
regs->addr_cmap = map->blue;
wbflush();
}
bt459_init_colormap(
bt459_padded_regmap_t *regs)
{
register int i;
bt459_select_reg(regs, 0);
regs->addr_cmap = 0;
wbflush();
regs->addr_cmap = 0;
wbflush();
regs->addr_cmap = 0;
wbflush();
regs->addr_cmap = 0xff;
wbflush();
regs->addr_cmap = 0xff;
wbflush();
regs->addr_cmap = 0xff;
wbflush();
bt459_select_reg(regs, 255);
regs->addr_cmap = 0xff;
wbflush();
regs->addr_cmap = 0xff;
wbflush();
regs->addr_cmap = 0xff;
wbflush();
}
#if 1/*debug*/
bt459_print_colormap(
bt459_padded_regmap_t *regs)
{
register int i;
for (i = 0; i < 256; i++) {
register unsigned char red, green, blue;
bt459_select_reg(regs, i);
red = regs->addr_cmap; wbflush();
green = regs->addr_cmap; wbflush();
blue = regs->addr_cmap; wbflush();
printf("%x->[x%x x%x x%x]\n", i,
red, green, blue);
}
}
#endif
/*
* Video on/off
*
* It is unfortunate that X11 goes backward with white@0
* and black@1. So we must stash away the zero-th entry
* and fix it while screen is off. Also must remember
* it, sigh.
*/
struct vstate {
bt459_padded_regmap_t *regs;
unsigned short off;
};
bt459_video_off(
struct vstate *vstate,
user_info_t *up)
{
register bt459_padded_regmap_t *regs = vstate->regs;
unsigned char *save;
if (vstate->off)
return;
/* Yes, this is awful */
save = (unsigned char *)up->dev_dep_2.gx.colormap;
bt459_select_reg(regs, 0);
*save++ = regs->addr_cmap;
*save++ = regs->addr_cmap;
*save++ = regs->addr_cmap;
bt459_select_reg(regs, 0);
regs->addr_cmap = 0;
wbflush();
regs->addr_cmap = 0;
wbflush();
regs->addr_cmap = 0;
wbflush();
bt459_write_reg( regs, BT459_REG_PRM, 0);
bt459_write_reg( regs, BT459_REG_CCR, 0);
vstate->off = 1;
}
bt459_video_on(
struct vstate *vstate,
user_info_t *up)
{
register bt459_padded_regmap_t *regs = vstate->regs;
unsigned char *save;
if (!vstate->off)
return;
/* Like I said.. */
save = (unsigned char *)up->dev_dep_2.gx.colormap;
bt459_select_reg(regs, 0);
regs->addr_cmap = *save++;
wbflush();
regs->addr_cmap = *save++;
wbflush();
regs->addr_cmap = *save++;
wbflush();
bt459_write_reg( regs, BT459_REG_PRM, 0xff);
bt459_write_reg( regs, BT459_REG_CCR, 0xc0);
vstate->off = 0;
}
/*
* Cursor
*/
bt459_pos_cursor(
bt459_padded_regmap_t *regs,
register int x,
register int y)
{
#define lo(v) ((v)&0xff)
#define hi(v) (((v)&0xf00)>>8)
bt459_write_reg( regs, BT459_REG_CXLO, lo(x + 219));
bt459_write_reg( regs, BT459_REG_CXHI, hi(x + 219));
bt459_write_reg( regs, BT459_REG_CYLO, lo(y + 34));
bt459_write_reg( regs, BT459_REG_CYHI, hi(y + 34));
}
bt459_cursor_color(
bt459_padded_regmap_t *regs,
color_map_t *color)
{
register int i;
bt459_select_reg_macro( regs, BT459_REG_CCOLOR_2);
for (i = 0; i < 2; i++) {
regs->addr_reg = color->red;
wbflush();
regs->addr_reg = color->green;
wbflush();
regs->addr_reg = color->blue;
wbflush();
color++;
}
}
bt459_cursor_sprite(
bt459_padded_regmap_t *regs,
unsigned char *cursor)
{
register int i, j;
/*
* As per specs, must run a check to see if we
* had contention. If so, re-write the cursor.
*/
for (i = 0, j = 0; j < 2; j++) {
/* loop once to write */
for ( ; i < 1024; i++)
bt459_write_reg( regs, BT459_REG_CRAM_BASE+i, cursor[i]);
/* loop to check, if fail write again */
for (i = 0; i < 1024; i++)
if (bt459_read_reg( regs, BT459_REG_CRAM_BASE+i) != cursor[i])
break;
if (i == 1024)
break;/* all is well now */
}
}
/*
* Initialization
*/
bt459_init(
bt459_padded_regmap_t *regs,
volatile char *reset,
int mux)
{
if (bt459_read_reg(regs, BT459_REG_ID) != 0x4a)
panic("bt459");
if (mux == 4) {
/* use 4:1 input mux */
bt459_write_reg( regs, BT459_REG_CMD0, 0x40);
} else if (mux == 5) {
/* use 5:1 input mux */
bt459_write_reg( regs, BT459_REG_CMD0, 0xc0);
} /* else donno */
*reset = 0; /* force chip reset */
/* no zooming, no panning */
bt459_write_reg( regs, BT459_REG_CMD1, 0x00);
/* signature test, X-windows cursor, no overlays, SYNC* PLL,
normal RAM select, 7.5 IRE pedestal, do sync */
bt459_write_reg( regs, BT459_REG_CMD2, 0xc2);
/* get all pixel bits */
bt459_write_reg( regs, BT459_REG_PRM, 0xff);
/* no blinking */
bt459_write_reg( regs, BT459_REG_PBM, 0x00);
/* no overlay */
bt459_write_reg( regs, BT459_REG_ORM, 0x00);
/* no overlay blink */
bt459_write_reg( regs, BT459_REG_OBM, 0x00);
/* no interleave, no underlay */
bt459_write_reg( regs, BT459_REG_ILV, 0x00);
/* normal operation, no signature analysis */
bt459_write_reg( regs, BT459_REG_TEST, 0x00);
/* no blinking, 1bit cross hair, XOR reg&crosshair,
no crosshair on either plane 0 or 1,
regular cursor on both planes */
bt459_write_reg( regs, BT459_REG_CCR, 0xc0);
/* home cursor */
bt459_write_reg( regs, BT459_REG_CXLO, 0x00);
bt459_write_reg( regs, BT459_REG_CXHI, 0x00);
bt459_write_reg( regs, BT459_REG_CYLO, 0x00);
bt459_write_reg( regs, BT459_REG_CYHI, 0x00);
/* no crosshair window */
bt459_write_reg( regs, BT459_REG_WXLO, 0x00);
bt459_write_reg( regs, BT459_REG_WXHI, 0x00);
bt459_write_reg( regs, BT459_REG_WYLO, 0x00);
bt459_write_reg( regs, BT459_REG_WYHI, 0x00);
bt459_write_reg( regs, BT459_REG_WWLO, 0x00);
bt459_write_reg( regs, BT459_REG_WWHI, 0x00);
bt459_write_reg( regs, BT459_REG_WHLO, 0x00);
bt459_write_reg( regs, BT459_REG_WHHI, 0x00);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.