156818Sralph /*- 263208Sbostic * Copyright (c) 1992, 1993 363208Sbostic * The Regents of the University of California. All rights reserved. 456818Sralph * 556818Sralph * This code is derived from software contributed to Berkeley by 656818Sralph * Ralph Campbell and Rick Macklem. 756818Sralph * 856818Sralph * %sccs.include.redist.c% 956818Sralph * 10*69799Sralph * @(#)xcfb.c 8.2 (Berkeley) 06/02/95 1156818Sralph */ 1256818Sralph 1356818Sralph /* 1456818Sralph * Mach Operating System 1556818Sralph * Copyright (c) 1991,1990,1989 Carnegie Mellon University 1656818Sralph * All Rights Reserved. 1756818Sralph * 1856818Sralph * Permission to use, copy, modify and distribute this software and its 1956818Sralph * documentation is hereby granted, provided that both the copyright 2056818Sralph * notice and this permission notice appear in all copies of the 2156818Sralph * software, derivative works or modified versions, and any portions 2256818Sralph * thereof, and that both notices appear in supporting documentation. 2356818Sralph * 2456818Sralph * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS 2556818Sralph * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 2656818Sralph * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 2756818Sralph * 2856818Sralph * Carnegie Mellon requests users of this software to return to 2956818Sralph * 3056818Sralph * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 3156818Sralph * School of Computer Science 3256818Sralph * Carnegie Mellon University 3356818Sralph * Pittsburgh PA 15213-3890 3456818Sralph * 3556818Sralph * any improvements or extensions that they make and grant Carnegie the 3656818Sralph * rights to redistribute these changes. 3756818Sralph */ 3856818Sralph /* 3956818Sralph * devGraphics.c -- 4056818Sralph * 4156818Sralph * This file contains machine-dependent routines for the graphics device. 4256818Sralph * 4356818Sralph * Copyright (C) 1989 Digital Equipment Corporation. 4456818Sralph * Permission to use, copy, modify, and distribute this software and 4556818Sralph * its documentation for any purpose and without fee is hereby granted, 4656818Sralph * provided that the above copyright notice appears in all copies. 4756818Sralph * Digital Equipment Corporation makes no representations about the 4856818Sralph * suitability of this software for any purpose. It is provided "as is" 4956818Sralph * without express or implied warranty. 5056818Sralph * 5156818Sralph * from: $Header: /sprite/src/kernel/dev/ds3100.md/RCS/devGraphics.c, 5256818Sralph * v 9.2 90/02/13 22:16:24 shirriff Exp $ SPRITE (DECWRL)"; 5356818Sralph */ 5456818Sralph 5556818Sralph #include <xcfb.h> 5656818Sralph #include <dtop.h> 5756818Sralph #if NXCFB > 0 5856818Sralph #if NDTOP == 0 5956818Sralph xcfb needs dtop device 6056818Sralph #else 6156818Sralph 6256818Sralph #include <sys/param.h> 6356818Sralph #include <sys/time.h> 6456818Sralph #include <sys/kernel.h> 6556818Sralph #include <sys/ioctl.h> 6656818Sralph #include <sys/file.h> 6756818Sralph #include <sys/errno.h> 6856818Sralph #include <sys/proc.h> 6956818Sralph #include <sys/mman.h> 7056818Sralph 7156818Sralph #include <vm/vm.h> 7256818Sralph 7356818Sralph #include <machine/machConst.h> 7456818Sralph #include <machine/pmioctl.h> 7556818Sralph 7656818Sralph #include <pmax/pmax/maxine.h> 7756818Sralph #include <pmax/pmax/cons.h> 7856818Sralph #include <pmax/pmax/pmaxtype.h> 7956818Sralph 8056818Sralph #include <pmax/dev/device.h> 8156818Sralph #include <pmax/dev/xcfbreg.h> 8256818Sralph #include <pmax/dev/dtopreg.h> 8356818Sralph #include <pmax/dev/fbreg.h> 8456818Sralph 8556818Sralph /* 8656818Sralph * These need to be mapped into user space. 8756818Sralph */ 8856818Sralph struct fbuaccess xcfbu; 8956818Sralph struct pmax_fb xcfbfb; 9056818Sralph 9156818Sralph /* 9256818Sralph * Forward references. 9356818Sralph */ 9456818Sralph static void xcfbScreenInit(); 9556818Sralph static void xcfbLoadCursor(); 9656818Sralph static void xcfbRestoreCursorColor(); 9756818Sralph static void xcfbCursorColor(); 9856818Sralph void xcfbPosCursor(); 9956818Sralph static void xcfbInitColorMap(); 10056818Sralph static void xcfbLoadColorMap(); 10156818Sralph static u_int ims332_read_register(); 10256818Sralph static void ims332_write_register(); 10356818Sralph static void ims332_load_colormap_entry(); 10456818Sralph static void ims332_video_off(); 10556818Sralph static void ims332_video_on(); 10656818Sralph 10756818Sralph void xcfbKbdEvent(), xcfbMouseEvent(), xcfbMouseButtons(); 10858974Sralph extern void dtopKBDPutc(); 10956818Sralph extern void (*dtopDivertXInput)(); 11056818Sralph extern void (*dtopMouseEvent)(); 11156818Sralph extern void (*dtopMouseButtons)(); 11256818Sralph extern int pmax_boardtype; 11356818Sralph extern u_short defCursor[32]; 11456818Sralph extern struct consdev cn_tab; 11556818Sralph 11656818Sralph int xcfbprobe(); 11756818Sralph struct driver xcfbdriver = { 11856818Sralph "xcfb", xcfbprobe, 0, 0, 11956818Sralph }; 12056818Sralph 12156818Sralph /* 12256818Sralph * Test to see if device is present. 12356818Sralph * Return true if found and initialized ok. 12456818Sralph */ 12556818Sralph /*ARGSUSED*/ 12656818Sralph xcfbprobe(cp) 12756818Sralph register struct pmax_ctlr *cp; 12856818Sralph { 12956818Sralph register struct pmax_fb *fp = &xcfbfb; 13056818Sralph 13156818Sralph if (pmax_boardtype != DS_MAXINE) 13256818Sralph return (0); 13356818Sralph if (!fp->initialized && !xcfbinit()) 13456818Sralph return (0); 13556818Sralph printf("xcfb0 (color display)\n"); 13656818Sralph return (1); 13756818Sralph } 13856818Sralph 13956818Sralph /*ARGSUSED*/ 14056818Sralph xcfbopen(dev, flag) 14156818Sralph dev_t dev; 14256818Sralph int flag; 14356818Sralph { 14456818Sralph register struct pmax_fb *fp = &xcfbfb; 14556818Sralph int s; 14656818Sralph 14756818Sralph if (!fp->initialized) 14856818Sralph return (ENXIO); 14956818Sralph if (fp->GraphicsOpen) 15056818Sralph return (EBUSY); 15156818Sralph 15256818Sralph fp->GraphicsOpen = 1; 15356818Sralph xcfbInitColorMap(); 15456818Sralph /* 15556818Sralph * Set up event queue for later 15656818Sralph */ 15756818Sralph fp->fbu->scrInfo.qe.eSize = PM_MAXEVQ; 15856818Sralph fp->fbu->scrInfo.qe.eHead = fp->fbu->scrInfo.qe.eTail = 0; 15956818Sralph fp->fbu->scrInfo.qe.tcSize = MOTION_BUFFER_SIZE; 16056818Sralph fp->fbu->scrInfo.qe.tcNext = 0; 16156818Sralph fp->fbu->scrInfo.qe.timestamp_ms = TO_MS(time); 16256818Sralph s = spltty(); 16356818Sralph dtopDivertXInput = xcfbKbdEvent; 16456818Sralph dtopMouseEvent = xcfbMouseEvent; 16556818Sralph dtopMouseButtons = xcfbMouseButtons; 16656818Sralph splx(s); 16756818Sralph return (0); 16856818Sralph } 16956818Sralph 17056818Sralph /*ARGSUSED*/ 17156818Sralph xcfbclose(dev, flag) 17256818Sralph dev_t dev; 17356818Sralph int flag; 17456818Sralph { 17556818Sralph register struct pmax_fb *fp = &xcfbfb; 17656818Sralph int s; 17756818Sralph 17856818Sralph if (!fp->GraphicsOpen) 17956818Sralph return (EBADF); 18056818Sralph 18156818Sralph fp->GraphicsOpen = 0; 18256818Sralph xcfbInitColorMap(); 18356818Sralph s = spltty(); 18456818Sralph dtopDivertXInput = (void (*)())0; 18556818Sralph dtopMouseEvent = (void (*)())0; 18656818Sralph dtopMouseButtons = (void (*)())0; 18756818Sralph splx(s); 18856818Sralph xcfbScreenInit(); 18956818Sralph bzero((caddr_t)fp->fr_addr, 1024 * 768); 19056818Sralph xcfbPosCursor(fp->col * 8, fp->row * 15); 19156818Sralph return (0); 19256818Sralph } 19356818Sralph 19456818Sralph /*ARGSUSED*/ 19558974Sralph xcfbioctl(dev, cmd, data, flag, p) 19656818Sralph dev_t dev; 197*69799Sralph u_long cmd; 19856818Sralph caddr_t data; 19958974Sralph struct proc *p; 20056818Sralph { 20156818Sralph register struct pmax_fb *fp = &xcfbfb; 20256818Sralph int s; 20356818Sralph 20456818Sralph switch (cmd) { 20556818Sralph case QIOCGINFO: 20658974Sralph return (fbmmap(fp, dev, data, p)); 20756818Sralph 20856818Sralph case QIOCPMSTATE: 20956818Sralph /* 21056818Sralph * Set mouse state. 21156818Sralph */ 21256818Sralph fp->fbu->scrInfo.mouse = *(pmCursor *)data; 21356818Sralph xcfbPosCursor(fp->fbu->scrInfo.mouse.x, fp->fbu->scrInfo.mouse.y); 21456818Sralph break; 21556818Sralph 21656818Sralph case QIOCINIT: 21756818Sralph /* 21856818Sralph * Initialize the screen. 21956818Sralph */ 22056818Sralph xcfbScreenInit(); 22156818Sralph break; 22256818Sralph 22356818Sralph case QIOCKPCMD: 22456818Sralph { 22556818Sralph pmKpCmd *kpCmdPtr; 22656818Sralph unsigned char *cp; 22756818Sralph 22856818Sralph kpCmdPtr = (pmKpCmd *)data; 22956818Sralph if (kpCmdPtr->nbytes == 0) 23056818Sralph kpCmdPtr->cmd |= 0x80; 23156818Sralph if (!fp->GraphicsOpen) 23256818Sralph kpCmdPtr->cmd |= 1; 23356818Sralph (*fp->KBDPutc)(fp->kbddev, (int)kpCmdPtr->cmd); 23456818Sralph cp = &kpCmdPtr->par[0]; 23556818Sralph for (; kpCmdPtr->nbytes > 0; cp++, kpCmdPtr->nbytes--) { 23656818Sralph if (kpCmdPtr->nbytes == 1) 23756818Sralph *cp |= 0x80; 23856818Sralph (*fp->KBDPutc)(fp->kbddev, (int)*cp); 23956818Sralph } 24058974Sralph break; 24156818Sralph } 24256818Sralph 24356818Sralph case QIOCADDR: 24456818Sralph *(PM_Info **)data = &fp->fbu->scrInfo; 24556818Sralph break; 24656818Sralph 24756818Sralph case QIOWCURSOR: 24856818Sralph xcfbLoadCursor((unsigned short *)data); 24956818Sralph break; 25056818Sralph 25156818Sralph case QIOWCURSORCOLOR: 25256818Sralph xcfbCursorColor((unsigned int *)data); 25356818Sralph break; 25456818Sralph 25556818Sralph case QIOSETCMAP: 25656818Sralph xcfbLoadColorMap((ColorMap *)data); 25756818Sralph break; 25856818Sralph 25956818Sralph case QIOKERNLOOP: 26056818Sralph s = spltty(); 26156818Sralph dtopDivertXInput = xcfbKbdEvent; 26256818Sralph dtopMouseEvent = xcfbMouseEvent; 26356818Sralph dtopMouseButtons = xcfbMouseButtons; 26456818Sralph splx(s); 26556818Sralph break; 26656818Sralph 26756818Sralph case QIOKERNUNLOOP: 26856818Sralph s = spltty(); 26956818Sralph dtopDivertXInput = (void (*)())0; 27056818Sralph dtopMouseEvent = (void (*)())0; 27156818Sralph dtopMouseButtons = (void (*)())0; 27256818Sralph splx(s); 27356818Sralph break; 27456818Sralph 27556818Sralph case QIOVIDEOON: 27656818Sralph xcfbRestoreCursorColor(); 27756818Sralph ims332_video_on(); 27856818Sralph break; 27956818Sralph 28056818Sralph case QIOVIDEOOFF: 28156818Sralph ims332_video_off(); 28256818Sralph break; 28356818Sralph 28456818Sralph default: 28556818Sralph printf("xcfb0: Unknown ioctl command %x\n", cmd); 28656818Sralph return (EINVAL); 28756818Sralph } 28856818Sralph return (0); 28956818Sralph } 29056818Sralph 29158974Sralph /* 29258974Sralph * Return the physical page number that corresponds to byte offset 'off'. 29358974Sralph */ 29458974Sralph /*ARGSUSED*/ 29558974Sralph xcfbmap(dev, off, prot) 29658974Sralph dev_t dev; 29758974Sralph { 29858974Sralph int len; 29958974Sralph 30058974Sralph len = pmax_round_page(((vm_offset_t)&xcfbu & PGOFSET) + sizeof(xcfbu)); 30158974Sralph if (off < len) 30258974Sralph return pmax_btop(MACH_CACHED_TO_PHYS(&xcfbu) + off); 30358974Sralph off -= len; 30458974Sralph if (off >= xcfbfb.fr_size) 30558974Sralph return (-1); 30658974Sralph return pmax_btop(MACH_UNCACHED_TO_PHYS(xcfbfb.fr_addr) + off); 30758974Sralph } 30858974Sralph 30956818Sralph xcfbselect(dev, flag, p) 31056818Sralph dev_t dev; 31156818Sralph int flag; 31256818Sralph struct proc *p; 31356818Sralph { 31456818Sralph struct pmax_fb *fp = &xcfbfb; 31556818Sralph 31656818Sralph switch (flag) { 31756818Sralph case FREAD: 31856818Sralph if (fp->fbu->scrInfo.qe.eHead != fp->fbu->scrInfo.qe.eTail) 31956818Sralph return (1); 32056818Sralph selrecord(p, &fp->selp); 32156818Sralph break; 32256818Sralph } 32356818Sralph 32456818Sralph return (0); 32556818Sralph } 32656818Sralph 32756818Sralph static u_char cursor_RGB[6]; /* cursor color 2 & 3 */ 32856818Sralph 32956818Sralph /* 33056818Sralph * Routines for the Inmos IMS-G332 Colour video controller 33156818Sralph * Author: Alessandro Forin, Carnegie Mellon University 33256818Sralph */ 33356818Sralph static u_int 33456818Sralph ims332_read_register(regno) 33556818Sralph { 33656818Sralph register u_char *regs = (u_char *)IMS332_ADDRESS; 33756818Sralph unsigned char *rptr; 33856818Sralph register u_int val, v1; 33956818Sralph 34056818Sralph /* spec sez: */ 34156818Sralph rptr = regs + 0x80000 + (regno << 4); 34256818Sralph val = *((volatile u_short *) rptr ); 34356818Sralph v1 = *((volatile u_short *) regs ); 34456818Sralph 34556818Sralph return (val & 0xffff) | ((v1 & 0xff00) << 8); 34656818Sralph } 34756818Sralph 34856818Sralph static void 34956818Sralph ims332_write_register(regno, val) 35056818Sralph register unsigned int val; 35156818Sralph { 35256818Sralph register u_char *regs = (u_char *)IMS332_ADDRESS; 35356818Sralph u_char *wptr; 35456818Sralph 35556818Sralph /* spec sez: */ 35656818Sralph wptr = regs + 0xa0000 + (regno << 4); 35756818Sralph *((volatile u_int *)(regs)) = (val >> 8) & 0xff00; 35856818Sralph *((volatile u_short *)(wptr)) = val; 35956818Sralph } 36056818Sralph 36156818Sralph #define assert_ims332_reset_bit(r) *r &= ~0x40 36256818Sralph #define deassert_ims332_reset_bit(r) *r |= 0x40 36356818Sralph 36456818Sralph /* 36556818Sralph * Color map 36656818Sralph */ 36756818Sralph static void 36856818Sralph xcfbLoadColorMap(ptr) 36956818Sralph ColorMap *ptr; 37056818Sralph { 37156818Sralph register int i; 37256818Sralph 37356818Sralph if (ptr->index > 256) 37456818Sralph return; 37556818Sralph ims332_load_colormap_entry(ptr->index, ptr); 37656818Sralph } 37756818Sralph 37856818Sralph static void 37956818Sralph ims332_load_colormap_entry(entry, map) 38056818Sralph ColorMap *map; 38156818Sralph { 38256818Sralph /* ?? stop VTG */ 38356818Sralph ims332_write_register(IMS332_REG_LUT_BASE + (entry & 0xff), 38456818Sralph (map->Entry.blue << 16) | 38556818Sralph (map->Entry.green << 8) | 38656818Sralph (map->Entry.red)); 38756818Sralph } 38856818Sralph 38956818Sralph static void 39056818Sralph xcfbInitColorMap() 39156818Sralph { 39256818Sralph register int i; 39356818Sralph ColorMap m; 39456818Sralph 39556818Sralph m.Entry.red = m.Entry.green = m.Entry.blue = 0; 39656818Sralph ims332_load_colormap_entry(0, &m); 39756818Sralph 39856818Sralph m.Entry.red = m.Entry.green = m.Entry.blue = 0xff; 39956818Sralph for (i = 1; i < 256; i++) 40056818Sralph ims332_load_colormap_entry(i, &m); 40156818Sralph 40256818Sralph for (i = 0; i < 3; i++) { 40356818Sralph cursor_RGB[i] = 0x00; 40456818Sralph cursor_RGB[i + 3] = 0xff; 40556818Sralph } 40656818Sralph xcfbRestoreCursorColor(); 40756818Sralph } 40856818Sralph 40956818Sralph /* 41056818Sralph * Video on/off 41156818Sralph * 41256818Sralph * It is unfortunate that X11 goes backward with white@0 41356818Sralph * and black@1. So we must stash away the zero-th entry 41456818Sralph * and fix it while screen is off. Also must remember 41556818Sralph * it, sigh. 41656818Sralph */ 41756818Sralph static struct { 41856818Sralph u_int save; 41956818Sralph int off; 42056818Sralph } xcfb_vstate; 42156818Sralph 42256818Sralph static void 42356818Sralph ims332_video_off() 42456818Sralph { 42556818Sralph register u_int csr; 42656818Sralph 42756818Sralph if (xcfb_vstate.off) 42856818Sralph return; 42956818Sralph 43056818Sralph xcfb_vstate.save = ims332_read_register(IMS332_REG_LUT_BASE); 43156818Sralph 43256818Sralph ims332_write_register(IMS332_REG_LUT_BASE, 0); 43356818Sralph 43456818Sralph ims332_write_register(IMS332_REG_COLOR_MASK, 0); 43556818Sralph 43656818Sralph /* cursor now */ 43756818Sralph csr = ims332_read_register(IMS332_REG_CSR_A); 43856818Sralph csr |= IMS332_CSR_A_DISABLE_CURSOR; 43956818Sralph ims332_write_register(IMS332_REG_CSR_A, csr); 44056818Sralph 44156818Sralph xcfb_vstate.off = 1; 44256818Sralph } 44356818Sralph 44456818Sralph static void 44556818Sralph ims332_video_on() 44656818Sralph { 44756818Sralph register u_int csr; 44856818Sralph 44956818Sralph if (!xcfb_vstate.off) 45056818Sralph return; 45156818Sralph 45256818Sralph ims332_write_register(IMS332_REG_LUT_BASE, xcfb_vstate.save); 45356818Sralph 45456818Sralph ims332_write_register(IMS332_REG_COLOR_MASK, 0xffffffff); 45556818Sralph 45656818Sralph /* cursor now */ 45756818Sralph csr = ims332_read_register(IMS332_REG_CSR_A); 45856818Sralph csr &= ~IMS332_CSR_A_DISABLE_CURSOR; 45956818Sralph ims332_write_register(IMS332_REG_CSR_A, csr); 46056818Sralph 46156818Sralph xcfb_vstate.off = 0; 46256818Sralph } 46356818Sralph 46456818Sralph /* 46556818Sralph * Cursor 46656818Sralph */ 46756818Sralph void 46856818Sralph xcfbPosCursor(x, y) 46956818Sralph register int x, y; 47056818Sralph { 47157234Sralph register struct pmax_fb *fp = &xcfbfb; 47256818Sralph 47357234Sralph if (y < fp->fbu->scrInfo.min_cur_y || y > fp->fbu->scrInfo.max_cur_y) 47457234Sralph y = fp->fbu->scrInfo.max_cur_y; 47557234Sralph if (x < fp->fbu->scrInfo.min_cur_x || x > fp->fbu->scrInfo.max_cur_x) 47657234Sralph x = fp->fbu->scrInfo.max_cur_x; 47757234Sralph fp->fbu->scrInfo.cursor.x = x; /* keep track of real cursor */ 47857234Sralph fp->fbu->scrInfo.cursor.y = y; /* position, indep. of mouse */ 47956818Sralph ims332_write_register(IMS332_REG_CURSOR_LOC, 48056818Sralph ((x & 0xfff) << 12) | (y & 0xfff)); 48156818Sralph } 48256818Sralph 48356818Sralph /* 48456818Sralph * xcfbRestoreCursorColor 48556818Sralph */ 48656818Sralph static void 48756818Sralph xcfbRestoreCursorColor() 48856818Sralph { 48956818Sralph 49056818Sralph /* Bg is color[0], Fg is color[1] */ 49156818Sralph ims332_write_register(IMS332_REG_CURSOR_LUT_0, 49256818Sralph (cursor_RGB[2] << 16) | 49356818Sralph (cursor_RGB[1] << 8) | 49456818Sralph (cursor_RGB[0])); 49556818Sralph ims332_write_register(IMS332_REG_CURSOR_LUT_1, 0x7f0000); 49656818Sralph ims332_write_register(IMS332_REG_CURSOR_LUT_2, 49756818Sralph (cursor_RGB[5] << 16) | 49856818Sralph (cursor_RGB[4] << 8) | 49956818Sralph (cursor_RGB[3])); 50056818Sralph } 50156818Sralph 50256818Sralph /* 50356818Sralph * ---------------------------------------------------------------------------- 50456818Sralph * 50556818Sralph * xcfbCursorColor -- 50656818Sralph * 50756818Sralph * Set the color of the cursor. 50856818Sralph * 50956818Sralph * Results: 51056818Sralph * None. 51156818Sralph * 51256818Sralph * Side effects: 51356818Sralph * None. 51456818Sralph * 51556818Sralph * ---------------------------------------------------------------------------- 51656818Sralph */ 51756818Sralph static void 51856818Sralph xcfbCursorColor(color) 51956818Sralph unsigned int color[]; 52056818Sralph { 52156818Sralph register int i, j; 52256818Sralph 52356818Sralph for (i = 0; i < 6; i++) 52456818Sralph cursor_RGB[i] = (u_char)(color[i] >> 8); 52556818Sralph 52656818Sralph xcfbRestoreCursorColor(); 52756818Sralph } 52856818Sralph 52956818Sralph static void 53056818Sralph xcfbLoadCursor(cursor) 53156818Sralph u_short *cursor; 53256818Sralph { 53356818Sralph register int i, j, k, pos; 53456818Sralph register u_short ap, bp, out; 53556818Sralph 53656818Sralph /* 53756818Sralph * Fill in the cursor sprite using the A and B planes, as provided 53856818Sralph * for the pmax. 53956818Sralph * XXX This will have to change when the X server knows that this 54056818Sralph * is not a pmax display. 54156818Sralph */ 54256818Sralph pos = 0; 54356818Sralph for (k = 0; k < 16; k++) { 54456818Sralph ap = *cursor; 54556818Sralph bp = *(cursor + 16); 54656818Sralph j = 0; 54756818Sralph while (j < 2) { 54856818Sralph out = 0; 54956818Sralph for (i = 0; i < 8; i++) { 55057234Sralph out = ((out >> 2) & 0x3fff) | 55157234Sralph ((ap & 0x1) << 15) | 55257234Sralph ((bp & 0x1) << 14); 55356818Sralph ap >>= 1; 55456818Sralph bp >>= 1; 55556818Sralph } 55656818Sralph ims332_write_register(IMS332_REG_CURSOR_RAM + pos, out); 55756818Sralph pos++; 55856818Sralph j++; 55956818Sralph } 56056818Sralph while (j < 8) { 56156818Sralph ims332_write_register(IMS332_REG_CURSOR_RAM + pos, 0); 56256818Sralph pos++; 56356818Sralph j++; 56456818Sralph } 56556818Sralph cursor++; 56656818Sralph } 56756818Sralph while (pos < 512) { 56856818Sralph ims332_write_register(IMS332_REG_CURSOR_RAM + pos, 0); 56956818Sralph pos++; 57056818Sralph } 57156818Sralph } 57256818Sralph 57356818Sralph /* 57456818Sralph * Initialization 57556818Sralph */ 57656818Sralph int 57756818Sralph xcfbinit() 57856818Sralph { 57956818Sralph register u_int *reset = (u_int *)IMS332_RESET_ADDRESS; 58056818Sralph register struct pmax_fb *fp = &xcfbfb; 58156818Sralph 58256818Sralph fp->isMono = 0; 58357234Sralph 58457234Sralph /* 58557234Sralph * Or Cached? A comment in the Mach driver suggests that the X server 58657234Sralph * runs faster in cached address space, but the X server is going 58757234Sralph * to blow away the data cache whenever it updates the screen, so.. 58857234Sralph */ 58956818Sralph fp->fr_addr = (char *) 59057234Sralph MACH_PHYS_TO_UNCACHED(XINE_PHYS_CFB_START + VRAM_OFFSET); 59158974Sralph fp->fr_size = 0x100000; 59257234Sralph /* 59358974Sralph * Must be in Uncached space since the fbuaccess structure is 59458974Sralph * mapped into the user's address space uncached. 59557234Sralph */ 59657234Sralph fp->fbu = (struct fbuaccess *) 59757234Sralph MACH_PHYS_TO_UNCACHED(MACH_CACHED_TO_PHYS(&xcfbu)); 59856818Sralph fp->posCursor = xcfbPosCursor; 59956818Sralph fp->KBDPutc = dtopKBDPutc; 60056818Sralph fp->kbddev = makedev(DTOPDEV, DTOPKBD_PORT); 60156818Sralph 60256818Sralph /* 60356818Sralph * Initialize the screen. 60456818Sralph */ 60556818Sralph #ifdef notdef 60656818Sralph assert_ims332_reset_bit(reset); 60756818Sralph DELAY(1); /* specs sez 50ns.. */ 60856818Sralph deassert_ims332_reset_bit(reset); 60956818Sralph 61056818Sralph /* CLOCKIN appears to receive a 6.25 Mhz clock --> PLL 12 for 75Mhz monitor */ 61156818Sralph ims332_write_register(IMS332_REG_BOOT, 12 | IMS332_BOOT_CLOCK_PLL); 61256818Sralph 61356818Sralph /* initialize VTG */ 61456818Sralph ims332_write_register(IMS332_REG_CSR_A, 61556818Sralph IMS332_BPP_8 | IMS332_CSR_A_DISABLE_CURSOR); 61656818Sralph DELAY(50); /* spec does not say */ 61756818Sralph 61856818Sralph /* datapath registers (values taken from prom's settings) */ 61956818Sralph 62056818Sralph ims332_write_register(IMS332_REG_HALF_SYNCH, 0x10); 62156818Sralph ims332_write_register(IMS332_REG_BACK_PORCH, 0x21); 62256818Sralph ims332_write_register(IMS332_REG_DISPLAY, 0x100); 62356818Sralph ims332_write_register(IMS332_REG_SHORT_DIS, 0x5d); 62456818Sralph ims332_write_register(IMS332_REG_BROAD_PULSE, 0x9f); 62556818Sralph ims332_write_register(IMS332_REG_V_SYNC, 0xc); 62656818Sralph ims332_write_register(IMS332_REG_V_PRE_EQUALIZE, 2); 62756818Sralph ims332_write_register(IMS332_REG_V_POST_EQUALIZE, 2); 62856818Sralph ims332_write_register(IMS332_REG_V_BLANK, 0x2a); 62956818Sralph ims332_write_register(IMS332_REG_V_DISPLAY, 0x600); 63056818Sralph ims332_write_register(IMS332_REG_LINE_TIME, 0x146); 63156818Sralph ims332_write_register(IMS332_REG_LINE_START, 0x10); 63256818Sralph ims332_write_register(IMS332_REG_MEM_INIT, 0xa); 63356818Sralph ims332_write_register(IMS332_REG_XFER_DELAY, 0xa); 63456818Sralph 63556818Sralph ims332_write_register(IMS332_REG_COLOR_MASK, 0xffffff); 63656818Sralph #endif 63756818Sralph 63856818Sralph /* 63956818Sralph * Initialize screen info. 64056818Sralph */ 64156818Sralph fp->fbu->scrInfo.max_row = 50; 64256818Sralph fp->fbu->scrInfo.max_col = 80; 64356818Sralph fp->fbu->scrInfo.max_x = 1024; 64456818Sralph fp->fbu->scrInfo.max_y = 768; 64557234Sralph fp->fbu->scrInfo.max_cur_x = 1008; 64657234Sralph fp->fbu->scrInfo.max_cur_y = 752; 64756818Sralph fp->fbu->scrInfo.version = 11; 64856818Sralph fp->fbu->scrInfo.mthreshold = 4; 64956818Sralph fp->fbu->scrInfo.mscale = 2; 65056818Sralph fp->fbu->scrInfo.min_cur_x = -15; 65156818Sralph fp->fbu->scrInfo.min_cur_y = -15; 65256818Sralph fp->fbu->scrInfo.qe.timestamp_ms = TO_MS(time); 65356818Sralph fp->fbu->scrInfo.qe.eSize = PM_MAXEVQ; 65456818Sralph fp->fbu->scrInfo.qe.eHead = fp->fbu->scrInfo.qe.eTail = 0; 65556818Sralph fp->fbu->scrInfo.qe.tcSize = MOTION_BUFFER_SIZE; 65656818Sralph fp->fbu->scrInfo.qe.tcNext = 0; 65756818Sralph 65856818Sralph xcfbInitColorMap(); 65956818Sralph 66056818Sralph ims332_write_register(IMS332_REG_CSR_A, 66156818Sralph IMS332_BPP_8 | IMS332_CSR_A_DMA_DISABLE | IMS332_CSR_A_VTG_ENABLE); 66256818Sralph 66356818Sralph xcfbScreenInit(); 66456818Sralph fbScroll(fp); 66556818Sralph 66656818Sralph fp->initialized = 1; 66756818Sralph if (cn_tab.cn_fb == (struct pmax_fb *)0) 66856818Sralph cn_tab.cn_fb = fp; 66956818Sralph return (1); 67056818Sralph } 67156818Sralph 67256818Sralph /* 67356818Sralph * ---------------------------------------------------------------------------- 67456818Sralph * 67556818Sralph * xcfbScreenInit -- 67656818Sralph * 67756818Sralph * Initialize the screen. 67856818Sralph * 67956818Sralph * Results: 68056818Sralph * None. 68156818Sralph * 68256818Sralph * Side effects: 68356818Sralph * The screen is initialized. 68456818Sralph * 68556818Sralph * ---------------------------------------------------------------------------- 68656818Sralph */ 68756818Sralph static void 68856818Sralph xcfbScreenInit() 68956818Sralph { 69056818Sralph register struct pmax_fb *fp = &xcfbfb; 69156818Sralph 69256818Sralph /* 69356818Sralph * Home the cursor. 69456818Sralph * We want an LSI terminal emulation. We want the graphics 69556818Sralph * terminal to scroll from the bottom. So start at the bottom. 69656818Sralph */ 69756818Sralph fp->row = 49; 69856818Sralph fp->col = 0; 69956818Sralph 70056818Sralph /* 70156818Sralph * Load the cursor with the default values 70256818Sralph * 70356818Sralph */ 70456818Sralph xcfbLoadCursor(defCursor); 70556818Sralph } 70656818Sralph 70756818Sralph /* 70856818Sralph * xcfb keyboard and mouse input. Just punt to the generic ones in fb.c 70956818Sralph */ 71056818Sralph void 71156818Sralph xcfbKbdEvent(ch) 71256818Sralph int ch; 71356818Sralph { 71456818Sralph fbKbdEvent(ch, &xcfbfb); 71556818Sralph } 71656818Sralph 71756818Sralph void 71856818Sralph xcfbMouseEvent(newRepPtr) 71956818Sralph MouseReport *newRepPtr; 72056818Sralph { 72156818Sralph fbMouseEvent(newRepPtr, &xcfbfb); 72256818Sralph } 72356818Sralph 72456818Sralph void 72556818Sralph xcfbMouseButtons(newRepPtr) 72656818Sralph MouseReport *newRepPtr; 72756818Sralph { 72856818Sralph fbMouseButtons(newRepPtr, &xcfbfb); 72956818Sralph } 73056818Sralph #endif /* NDTOP */ 73156818Sralph #endif /* NXCFB */ 732