diff options
Diffstat (limited to 'chips/xcfb_misc.c')
-rw-r--r-- | chips/xcfb_misc.c | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/chips/xcfb_misc.c b/chips/xcfb_misc.c new file mode 100644 index 00000000..e7a08c33 --- /dev/null +++ b/chips/xcfb_misc.c @@ -0,0 +1,246 @@ +/* + * 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: xcfb_misc.c + * Author: Alessandro Forin, Carnegie Mellon University + * Date: 1/92 + * + * Driver for the MAXine color framebuffer + * + */ + +#include <xcfb.h> +#if (NXCFB > 0) + +/* + * NOTE: This driver relies heavily on the pm one. + */ + +#include <device/device_types.h> + +#include <chips/screen_defs.h> + +#include <chips/xcfb_monitor.h> +#include <chips/pm_defs.h> +typedef pm_softc_t xcfb_softc_t; + +#include <chips/ims332.h> +#define ims332 cursor_registers + + +/* + * Initialize color map, for kernel use + */ +xcfb_init_colormap(sc) + screen_softc_t sc; +{ + xcfb_softc_t *xcfb = (xcfb_softc_t*)sc->hw_state; + user_info_t *up = sc->up; + color_map_t Bg_Fg[2]; + register int i; + + ims332_init_colormap( xcfb->ims332 ); + + /* init bg/fg colors */ + for (i = 0; i < 3; i++) { + up->dev_dep_2.pm.Bg_color[i] = 0x00; + up->dev_dep_2.pm.Fg_color[i] = 0xff; + } + + Bg_Fg[0].red = Bg_Fg[0].green = Bg_Fg[0].blue = 0x00; + Bg_Fg[1].red = Bg_Fg[1].green = Bg_Fg[1].blue = 0xff; + ims332_cursor_color( xcfb->ims332, Bg_Fg); +} + +/* + * Large viz small cursor + */ +xcfb_small_cursor_to_large(up, cursor) + user_info_t *up; + cursor_sprite_t cursor; +{ + unsigned short new_cursor[32]; + unsigned char *cursor_bytes; + char *sprite; + register int i; + + /* Clear out old cursor */ + bzero( up->dev_dep_2.pm.cursor_sprite, + sizeof(up->dev_dep_2.pm.cursor_sprite)); + + /* small cursor is 32x2 bytes, fg first */ + cursor_bytes = (unsigned char *) cursor; + + /* use the upper left corner of the large cursor + * as a 64x1 cursor, fg&bg alternated */ + for (i = 0; i < 32; i++) { + register short nc = 0; + register unsigned char fg, bg; + register int j, k; + + fg = cursor_bytes[i]; + bg = cursor_bytes[i + 32]; + bg &= ~fg; + for (j = 1, k = 0; j < 256; j <<= 1) { + nc |= (bg & j) << (k++); + nc |= (fg & j) << (k); + } + new_cursor[i] = nc; + } + + /* Now stick it in the proper place */ + + cursor_bytes = (unsigned char *) new_cursor; + sprite = up->dev_dep_2.pm.cursor_sprite; + for (i = 0; i < 64; i += 4) { + *sprite++ = cursor_bytes[i + 0]; + *sprite++ = cursor_bytes[i + 1]; + *sprite++ = cursor_bytes[i + 2]; + *sprite++ = cursor_bytes[i + 3]; + sprite += 12; /* skip rest of the line */ + } +} + + +/* + * Device-specific set status + */ +xcfb_set_status(sc, flavor, status, status_count) + screen_softc_t sc; + int flavor; + dev_status_t status; + unsigned int status_count; +{ + xcfb_softc_t *xcfb = (xcfb_softc_t*) sc->hw_state; + + switch (flavor) { + + case SCREEN_ADJ_MAPPED_INFO: + return pm_set_status(sc, flavor, status, status_count); + + case SCREEN_LOAD_CURSOR: + + if (status_count < sizeof(cursor_sprite_t)/sizeof(int)) + return D_INVALID_SIZE; + + xcfb_small_cursor_to_large(sc->up, (cursor_sprite_t*) status); + + /* Fall through */ + + case SCREEN_LOAD_CURSOR_LONG: /* 3max only */ + + sc->flags |= SCREEN_BEING_UPDATED; + ims332_cursor_sprite(xcfb->ims332, sc->up->dev_dep_2.pm.cursor_sprite); + sc->flags &= ~SCREEN_BEING_UPDATED; + + break; + + case SCREEN_SET_CURSOR_COLOR: { + color_map_t c[2]; + register cursor_color_t *cc = (cursor_color_t*) status; + + c[0].red = cc->Bg_rgb[0]; + c[0].green = cc->Bg_rgb[1]; + c[0].blue = cc->Bg_rgb[2]; + c[1].red = cc->Fg_rgb[0]; + c[1].green = cc->Fg_rgb[1]; + c[1].blue = cc->Fg_rgb[2]; + + sc->flags |= SCREEN_BEING_UPDATED; + ims332_cursor_color (xcfb->ims332, c ); + sc->flags &= ~SCREEN_BEING_UPDATED; + + break; + } + + case SCREEN_SET_CMAP_ENTRY: { + color_map_entry_t *e = (color_map_entry_t*) status; + + if (e->index < 256) { + sc->flags |= SCREEN_BEING_UPDATED; + ims332_load_colormap_entry( xcfb->ims332, e->index, &e->value); + sc->flags &= ~SCREEN_BEING_UPDATED; + } + break; + } + + default: + return D_INVALID_OPERATION; + } + return D_SUCCESS; +} + +/* + * Hardware initialization + */ +xcfb_init_screen(xcfb) + xcfb_softc_t *xcfb; +{ + extern xcfb_monitor_type_t xcfb_get_monitor_type(); + + ims332_init( xcfb->ims332, xcfb->vdac_registers, xcfb_get_monitor_type()); +} + +/* + * Do what's needed when X exits + */ +xcfb_soft_reset(sc) + screen_softc_t sc; +{ + xcfb_softc_t *xcfb = (xcfb_softc_t*) sc->hw_state; + user_info_t *up = sc->up; + extern cursor_sprite_t dc503_default_cursor; + + /* + * Restore params in mapped structure + */ + pm_init_screen_params(sc,up); + up->row = up->max_row - 1; + + up->dev_dep_2.pm.x26 = 2; /* you do not want to know */ + up->dev_dep_1.pm.x18 = (short*)2; + + /* + * Restore RAMDAC chip to default state + */ + xcfb_init_screen(xcfb); + + /* + * Load kernel's cursor sprite: just use the same pmax one + */ + xcfb_small_cursor_to_large(up, dc503_default_cursor); + ims332_cursor_sprite(xcfb->ims332, up->dev_dep_2.pm.cursor_sprite); + + /* + * Color map and cursor color + */ + xcfb_init_colormap(sc); +} + + + + +#endif (NXCFB > 0) |