/* * Mach Operating System * Copyright (c) 1992 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: sfb_hdw.c * Author: Alessandro Forin, Carnegie Mellon University * Date: 11/92 * * Driver for the Smart Color Frame Buffer Display, * hardware-level operations. */ #include #if (NSFB > 0) #include #include #include #include #include #include #include typedef pm_softc_t sfb_softc_t; #ifdef DECSTATION #include #include #endif #ifdef FLAMINGO #include /* XXXX fixme */ #include #define sparsify(x) ((1L << 28) | (((x) & 0x7ffffff) << 1) | \ ((x) & ~0x7ffffffL)) #endif #ifndef sparsify #define sparsify(x) x #endif /* * Definition of the driver for the auto-configuration program. */ int sfb_probe(), sfb_intr(); void sfb_attach(); vm_offset_t sfb_std[NSFB] = { 0 }; struct bus_device *sfb_info[NSFB]; struct bus_driver sfb_driver = { sfb_probe, 0, sfb_attach, 0, sfb_std, "sfb", sfb_info, 0, 0, BUS_INTR_DISABLED}; /* * Probe/Attach functions */ sfb_probe( vm_offset_t addr, struct bus_device *device) { static probed_once = 0; /* * Probing was really done sweeping the TC long ago */ if (tc_probe("sfb") == 0) return 0; if (probed_once++ > 1) { printf("[mappable] "); device->address = addr; } return 1; } void sfb_attach( struct bus_device *ui) { /* ... */ printf(": smart frame buffer"); } /* * Interrupt routine */ sfb_intr( int unit, spl_t spllevel) { register volatile char *ack; /* acknowledge interrupt */ ack = (volatile char *) sfb_info[unit]->address + SFB_OFFSET_ICLR; *ack = 0; #if mips splx(spllevel); #endif lk201_led(unit); } sfb_vretrace( sfb_softc_t *sfb, boolean_t on) { sfb_regs *regs; regs = (sfb_regs *) ((char *)sfb->framebuffer - SFB_OFFSET_VRAM + SFB_OFFSET_REGS); regs->intr_enable = (on) ? 1 : 0; } /* * Boot time initialization: must make device * usable as console asap. */ #define sfb_set_status cfb_set_status extern int sfb_soft_reset(), sfb_set_status(), sfb_pos_cursor(), bt459_video_on(), bt459_video_off(), sfb_vretrace(), pm_get_status(), pm_char_paint(), pm_insert_line(), pm_remove_line(), pm_clear_bitmap(), pm_map_page(); static struct screen_switch sfb_sw = { screen_noop, /* graphic_open */ sfb_soft_reset, /* graphic_close */ sfb_set_status, /* set_status */ pm_get_status, /* get_status */ pm_char_paint, /* char_paint */ sfb_pos_cursor, /* pos_cursor */ pm_insert_line, /* insert_line */ pm_remove_line, /* remove_line */ pm_clear_bitmap, /* clear_bitmap */ bt459_video_on, /* video_on */ bt459_video_off, /* video_off */ sfb_vretrace, /* intr_enable */ pm_map_page /* map_page */ }; sfb_cold_init( int unit, user_info_t *up) { sfb_softc_t *sfb; screen_softc_t sc = screen(unit); vm_offset_t base = tc_probe("sfb"); int hor_p, ver_p; boolean_t makes_sense; bcopy(&sfb_sw, &sc->sw, sizeof(sc->sw)); sc->flags |= COLOR_SCREEN; /* * I am confused here by the documentation. One document * sez there are three boards: * "PMAGB-BA" can do 1280x1024 @66Hz or @72Hz * "PMAGB-BC" can do 1024x864 @60Hz or 1280x1024 @72Hz * "PMAGB-BE" can do 1024x768 @72Hz or 1280x1024 @72Hz * Another document sez things differently: * "PMAGB-BB" can do 1024x768 @72Hz * "PMAGB-BD" can do 1024x864 @60Hz or 1280x1024 @72Hz * * I would be inclined to believe the first one, which came * with an actual piece of hardware attached (a PMAGB-BA). * But I could swear I got a first board (which blew up * instantly) and it was calling itself PMAGB-BB... * * Since I have not seen any other hardware I will make * this code as hypothetical as I can. Should work :-)) */ makes_sense = FALSE; { sfb_regs *regs; regs = (sfb_regs *) ((char *)base + SFB_OFFSET_REGS); hor_p = (regs->vhor_setup & 0x1ff) * 4; ver_p = regs->vvert_setup & 0x7ff; if (((hor_p == 1280) && (ver_p == 1024)) || ((hor_p == 1024) && (ver_p == 864)) || ((hor_p == 1024) && (ver_p == 768))) makes_sense = TRUE; } if (makes_sense) { sc->frame_scanline_width = hor_p; sc->frame_height = ver_p; sc->frame_visible_width = hor_p; sc->frame_visible_height = ver_p; } else { sc->frame_scanline_width = 1280; sc->frame_height = 1024; sc->frame_visible_width = 1280; sc->frame_visible_height = 1024; } pm_init_screen_params(sc,up); (void) screen_up(unit, up); sfb = pm_alloc( unit, sparsify(base + SFB_OFFSET_BT459), base + SFB_OFFSET_VRAM, -1); screen_default_colors(up); sfb_soft_reset(sc); /* * Clearing the screen at boot saves from scrolling * much, and speeds up booting quite a bit. */ screen_blitc( unit, 'C'-'@');/* clear screen */ } #if 0 /* this is how you find out about a new screen */ fill(addr,n,c) char *addr; { while (n-- > 0) *addr++ = c; } #endif #endif (NSFB > 0)