summaryrefslogtreecommitdiff
path: root/chips/bt459.c
diff options
context:
space:
mode:
authorThomas Bushnell <thomas@gnu.org>1997-02-25 21:28:37 +0000
committerThomas Bushnell <thomas@gnu.org>1997-02-25 21:28:37 +0000
commitf07a4c844da9f0ecae5bbee1ab94be56505f26f7 (patch)
tree12b07c7e578fc1a5f53dbfde2632408491ff2a70 /chips/bt459.c
Initial source
Diffstat (limited to 'chips/bt459.c')
-rw-r--r--chips/bt459.c384
1 files changed, 384 insertions, 0 deletions
diff --git a/chips/bt459.c b/chips/bt459.c
new file mode 100644
index 0000000..0bee2f1
--- /dev/null
+++ b/chips/bt459.c
@@ -0,0 +1,384 @@
+/*
+ * 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 Software.Distribution@CS.CMU.EDU
+ * 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);
+}