156818Sralph /*- 2*63208Sbostic * Copyright (c) 1992, 1993 3*63208Sbostic * 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*63208Sbostic * @(#)xcfb.c 8.1 (Berkeley) 06/10/93 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; 19756818Sralph caddr_t data; 19858974Sralph struct proc *p; 19956818Sralph { 20056818Sralph register struct pmax_fb *fp = &xcfbfb; 20156818Sralph int s; 20256818Sralph 20356818Sralph switch (cmd) { 20456818Sralph case QIOCGINFO: 20558974Sralph return (fbmmap(fp, dev, data, p)); 20656818Sralph 20756818Sralph case QIOCPMSTATE: 20856818Sralph /* 20956818Sralph * Set mouse state. 21056818Sralph */ 21156818Sralph fp->fbu->scrInfo.mouse = *(pmCursor *)data; 21256818Sralph xcfbPosCursor(fp->fbu->scrInfo.mouse.x, fp->fbu->scrInfo.mouse.y); 21356818Sralph break; 21456818Sralph 21556818Sralph case QIOCINIT: 21656818Sralph /* 21756818Sralph * Initialize the screen. 21856818Sralph */ 21956818Sralph xcfbScreenInit(); 22056818Sralph break; 22156818Sralph 22256818Sralph case QIOCKPCMD: 22356818Sralph { 22456818Sralph pmKpCmd *kpCmdPtr; 22556818Sralph unsigned char *cp; 22656818Sralph 22756818Sralph kpCmdPtr = (pmKpCmd *)data; 22856818Sralph if (kpCmdPtr->nbytes == 0) 22956818Sralph kpCmdPtr->cmd |= 0x80; 23056818Sralph if (!fp->GraphicsOpen) 23156818Sralph kpCmdPtr->cmd |= 1; 23256818Sralph (*fp->KBDPutc)(fp->kbddev, (int)kpCmdPtr->cmd); 23356818Sralph cp = &kpCmdPtr->par[0]; 23456818Sralph for (; kpCmdPtr->nbytes > 0; cp++, kpCmdPtr->nbytes--) { 23556818Sralph if (kpCmdPtr->nbytes == 1) 23656818Sralph *cp |= 0x80; 23756818Sralph (*fp->KBDPutc)(fp->kbddev, (int)*cp); 23856818Sralph } 23958974Sralph break; 24056818Sralph } 24156818Sralph 24256818Sralph case QIOCADDR: 24356818Sralph *(PM_Info **)data = &fp->fbu->scrInfo; 24456818Sralph break; 24556818Sralph 24656818Sralph case QIOWCURSOR: 24756818Sralph xcfbLoadCursor((unsigned short *)data); 24856818Sralph break; 24956818Sralph 25056818Sralph case QIOWCURSORCOLOR: 25156818Sralph xcfbCursorColor((unsigned int *)data); 25256818Sralph break; 25356818Sralph 25456818Sralph case QIOSETCMAP: 25556818Sralph xcfbLoadColorMap((ColorMap *)data); 25656818Sralph break; 25756818Sralph 25856818Sralph case QIOKERNLOOP: 25956818Sralph s = spltty(); 26056818Sralph dtopDivertXInput = xcfbKbdEvent; 26156818Sralph dtopMouseEvent = xcfbMouseEvent; 26256818Sralph dtopMouseButtons = xcfbMouseButtons; 26356818Sralph splx(s); 26456818Sralph break; 26556818Sralph 26656818Sralph case QIOKERNUNLOOP: 26756818Sralph s = spltty(); 26856818Sralph dtopDivertXInput = (void (*)())0; 26956818Sralph dtopMouseEvent = (void (*)())0; 27056818Sralph dtopMouseButtons = (void (*)())0; 27156818Sralph splx(s); 27256818Sralph break; 27356818Sralph 27456818Sralph case QIOVIDEOON: 27556818Sralph xcfbRestoreCursorColor(); 27656818Sralph ims332_video_on(); 27756818Sralph break; 27856818Sralph 27956818Sralph case QIOVIDEOOFF: 28056818Sralph ims332_video_off(); 28156818Sralph break; 28256818Sralph 28356818Sralph default: 28456818Sralph printf("xcfb0: Unknown ioctl command %x\n", cmd); 28556818Sralph return (EINVAL); 28656818Sralph } 28756818Sralph return (0); 28856818Sralph } 28956818Sralph 29058974Sralph /* 29158974Sralph * Return the physical page number that corresponds to byte offset 'off'. 29258974Sralph */ 29358974Sralph /*ARGSUSED*/ 29458974Sralph xcfbmap(dev, off, prot) 29558974Sralph dev_t dev; 29658974Sralph { 29758974Sralph int len; 29858974Sralph 29958974Sralph len = pmax_round_page(((vm_offset_t)&xcfbu & PGOFSET) + sizeof(xcfbu)); 30058974Sralph if (off < len) 30158974Sralph return pmax_btop(MACH_CACHED_TO_PHYS(&xcfbu) + off); 30258974Sralph off -= len; 30358974Sralph if (off >= xcfbfb.fr_size) 30458974Sralph return (-1); 30558974Sralph return pmax_btop(MACH_UNCACHED_TO_PHYS(xcfbfb.fr_addr) + off); 30658974Sralph } 30758974Sralph 30856818Sralph xcfbselect(dev, flag, p) 30956818Sralph dev_t dev; 31056818Sralph int flag; 31156818Sralph struct proc *p; 31256818Sralph { 31356818Sralph struct pmax_fb *fp = &xcfbfb; 31456818Sralph 31556818Sralph switch (flag) { 31656818Sralph case FREAD: 31756818Sralph if (fp->fbu->scrInfo.qe.eHead != fp->fbu->scrInfo.qe.eTail) 31856818Sralph return (1); 31956818Sralph selrecord(p, &fp->selp); 32056818Sralph break; 32156818Sralph } 32256818Sralph 32356818Sralph return (0); 32456818Sralph } 32556818Sralph 32656818Sralph static u_char cursor_RGB[6]; /* cursor color 2 & 3 */ 32756818Sralph 32856818Sralph /* 32956818Sralph * Routines for the Inmos IMS-G332 Colour video controller 33056818Sralph * Author: Alessandro Forin, Carnegie Mellon University 33156818Sralph */ 33256818Sralph static u_int 33356818Sralph ims332_read_register(regno) 33456818Sralph { 33556818Sralph register u_char *regs = (u_char *)IMS332_ADDRESS; 33656818Sralph unsigned char *rptr; 33756818Sralph register u_int val, v1; 33856818Sralph 33956818Sralph /* spec sez: */ 34056818Sralph rptr = regs + 0x80000 + (regno << 4); 34156818Sralph val = *((volatile u_short *) rptr ); 34256818Sralph v1 = *((volatile u_short *) regs ); 34356818Sralph 34456818Sralph return (val & 0xffff) | ((v1 & 0xff00) << 8); 34556818Sralph } 34656818Sralph 34756818Sralph static void 34856818Sralph ims332_write_register(regno, val) 34956818Sralph register unsigned int val; 35056818Sralph { 35156818Sralph register u_char *regs = (u_char *)IMS332_ADDRESS; 35256818Sralph u_char *wptr; 35356818Sralph 35456818Sralph /* spec sez: */ 35556818Sralph wptr = regs + 0xa0000 + (regno << 4); 35656818Sralph *((volatile u_int *)(regs)) = (val >> 8) & 0xff00; 35756818Sralph *((volatile u_short *)(wptr)) = val; 35856818Sralph } 35956818Sralph 36056818Sralph #define assert_ims332_reset_bit(r) *r &= ~0x40 36156818Sralph #define deassert_ims332_reset_bit(r) *r |= 0x40 36256818Sralph 36356818Sralph /* 36456818Sralph * Color map 36556818Sralph */ 36656818Sralph static void 36756818Sralph xcfbLoadColorMap(ptr) 36856818Sralph ColorMap *ptr; 36956818Sralph { 37056818Sralph register int i; 37156818Sralph 37256818Sralph if (ptr->index > 256) 37356818Sralph return; 37456818Sralph ims332_load_colormap_entry(ptr->index, ptr); 37556818Sralph } 37656818Sralph 37756818Sralph static void 37856818Sralph ims332_load_colormap_entry(entry, map) 37956818Sralph ColorMap *map; 38056818Sralph { 38156818Sralph /* ?? stop VTG */ 38256818Sralph ims332_write_register(IMS332_REG_LUT_BASE + (entry & 0xff), 38356818Sralph (map->Entry.blue << 16) | 38456818Sralph (map->Entry.green << 8) | 38556818Sralph (map->Entry.red)); 38656818Sralph } 38756818Sralph 38856818Sralph static void 38956818Sralph xcfbInitColorMap() 39056818Sralph { 39156818Sralph register int i; 39256818Sralph ColorMap m; 39356818Sralph 39456818Sralph m.Entry.red = m.Entry.green = m.Entry.blue = 0; 39556818Sralph ims332_load_colormap_entry(0, &m); 39656818Sralph 39756818Sralph m.Entry.red = m.Entry.green = m.Entry.blue = 0xff; 39856818Sralph for (i = 1; i < 256; i++) 39956818Sralph ims332_load_colormap_entry(i, &m); 40056818Sralph 40156818Sralph for (i = 0; i < 3; i++) { 40256818Sralph cursor_RGB[i] = 0x00; 40356818Sralph cursor_RGB[i + 3] = 0xff; 40456818Sralph } 40556818Sralph xcfbRestoreCursorColor(); 40656818Sralph } 40756818Sralph 40856818Sralph /* 40956818Sralph * Video on/off 41056818Sralph * 41156818Sralph * It is unfortunate that X11 goes backward with white@0 41256818Sralph * and black@1. So we must stash away the zero-th entry 41356818Sralph * and fix it while screen is off. Also must remember 41456818Sralph * it, sigh. 41556818Sralph */ 41656818Sralph static struct { 41756818Sralph u_int save; 41856818Sralph int off; 41956818Sralph } xcfb_vstate; 42056818Sralph 42156818Sralph static void 42256818Sralph ims332_video_off() 42356818Sralph { 42456818Sralph register u_int csr; 42556818Sralph 42656818Sralph if (xcfb_vstate.off) 42756818Sralph return; 42856818Sralph 42956818Sralph xcfb_vstate.save = ims332_read_register(IMS332_REG_LUT_BASE); 43056818Sralph 43156818Sralph ims332_write_register(IMS332_REG_LUT_BASE, 0); 43256818Sralph 43356818Sralph ims332_write_register(IMS332_REG_COLOR_MASK, 0); 43456818Sralph 43556818Sralph /* cursor now */ 43656818Sralph csr = ims332_read_register(IMS332_REG_CSR_A); 43756818Sralph csr |= IMS332_CSR_A_DISABLE_CURSOR; 43856818Sralph ims332_write_register(IMS332_REG_CSR_A, csr); 43956818Sralph 44056818Sralph xcfb_vstate.off = 1; 44156818Sralph } 44256818Sralph 44356818Sralph static void 44456818Sralph ims332_video_on() 44556818Sralph { 44656818Sralph register u_int csr; 44756818Sralph 44856818Sralph if (!xcfb_vstate.off) 44956818Sralph return; 45056818Sralph 45156818Sralph ims332_write_register(IMS332_REG_LUT_BASE, xcfb_vstate.save); 45256818Sralph 45356818Sralph ims332_write_register(IMS332_REG_COLOR_MASK, 0xffffffff); 45456818Sralph 45556818Sralph /* cursor now */ 45656818Sralph csr = ims332_read_register(IMS332_REG_CSR_A); 45756818Sralph csr &= ~IMS332_CSR_A_DISABLE_CURSOR; 45856818Sralph ims332_write_register(IMS332_REG_CSR_A, csr); 45956818Sralph 46056818Sralph xcfb_vstate.off = 0; 46156818Sralph } 46256818Sralph 46356818Sralph /* 46456818Sralph * Cursor 46556818Sralph */ 46656818Sralph void 46756818Sralph xcfbPosCursor(x, y) 46856818Sralph register int x, y; 46956818Sralph { 47057234Sralph register struct pmax_fb *fp = &xcfbfb; 47156818Sralph 47257234Sralph if (y < fp->fbu->scrInfo.min_cur_y || y > fp->fbu->scrInfo.max_cur_y) 47357234Sralph y = fp->fbu->scrInfo.max_cur_y; 47457234Sralph if (x < fp->fbu->scrInfo.min_cur_x || x > fp->fbu->scrInfo.max_cur_x) 47557234Sralph x = fp->fbu->scrInfo.max_cur_x; 47657234Sralph fp->fbu->scrInfo.cursor.x = x; /* keep track of real cursor */ 47757234Sralph fp->fbu->scrInfo.cursor.y = y; /* position, indep. of mouse */ 47856818Sralph ims332_write_register(IMS332_REG_CURSOR_LOC, 47956818Sralph ((x & 0xfff) << 12) | (y & 0xfff)); 48056818Sralph } 48156818Sralph 48256818Sralph /* 48356818Sralph * xcfbRestoreCursorColor 48456818Sralph */ 48556818Sralph static void 48656818Sralph xcfbRestoreCursorColor() 48756818Sralph { 48856818Sralph 48956818Sralph /* Bg is color[0], Fg is color[1] */ 49056818Sralph ims332_write_register(IMS332_REG_CURSOR_LUT_0, 49156818Sralph (cursor_RGB[2] << 16) | 49256818Sralph (cursor_RGB[1] << 8) | 49356818Sralph (cursor_RGB[0])); 49456818Sralph ims332_write_register(IMS332_REG_CURSOR_LUT_1, 0x7f0000); 49556818Sralph ims332_write_register(IMS332_REG_CURSOR_LUT_2, 49656818Sralph (cursor_RGB[5] << 16) | 49756818Sralph (cursor_RGB[4] << 8) | 49856818Sralph (cursor_RGB[3])); 49956818Sralph } 50056818Sralph 50156818Sralph /* 50256818Sralph * ---------------------------------------------------------------------------- 50356818Sralph * 50456818Sralph * xcfbCursorColor -- 50556818Sralph * 50656818Sralph * Set the color of the cursor. 50756818Sralph * 50856818Sralph * Results: 50956818Sralph * None. 51056818Sralph * 51156818Sralph * Side effects: 51256818Sralph * None. 51356818Sralph * 51456818Sralph * ---------------------------------------------------------------------------- 51556818Sralph */ 51656818Sralph static void 51756818Sralph xcfbCursorColor(color) 51856818Sralph unsigned int color[]; 51956818Sralph { 52056818Sralph register int i, j; 52156818Sralph 52256818Sralph for (i = 0; i < 6; i++) 52356818Sralph cursor_RGB[i] = (u_char)(color[i] >> 8); 52456818Sralph 52556818Sralph xcfbRestoreCursorColor(); 52656818Sralph } 52756818Sralph 52856818Sralph static void 52956818Sralph xcfbLoadCursor(cursor) 53056818Sralph u_short *cursor; 53156818Sralph { 53256818Sralph register int i, j, k, pos; 53356818Sralph register u_short ap, bp, out; 53456818Sralph 53556818Sralph /* 53656818Sralph * Fill in the cursor sprite using the A and B planes, as provided 53756818Sralph * for the pmax. 53856818Sralph * XXX This will have to change when the X server knows that this 53956818Sralph * is not a pmax display. 54056818Sralph */ 54156818Sralph pos = 0; 54256818Sralph for (k = 0; k < 16; k++) { 54356818Sralph ap = *cursor; 54456818Sralph bp = *(cursor + 16); 54556818Sralph j = 0; 54656818Sralph while (j < 2) { 54756818Sralph out = 0; 54856818Sralph for (i = 0; i < 8; i++) { 54957234Sralph out = ((out >> 2) & 0x3fff) | 55057234Sralph ((ap & 0x1) << 15) | 55157234Sralph ((bp & 0x1) << 14); 55256818Sralph ap >>= 1; 55356818Sralph bp >>= 1; 55456818Sralph } 55556818Sralph ims332_write_register(IMS332_REG_CURSOR_RAM + pos, out); 55656818Sralph pos++; 55756818Sralph j++; 55856818Sralph } 55956818Sralph while (j < 8) { 56056818Sralph ims332_write_register(IMS332_REG_CURSOR_RAM + pos, 0); 56156818Sralph pos++; 56256818Sralph j++; 56356818Sralph } 56456818Sralph cursor++; 56556818Sralph } 56656818Sralph while (pos < 512) { 56756818Sralph ims332_write_register(IMS332_REG_CURSOR_RAM + pos, 0); 56856818Sralph pos++; 56956818Sralph } 57056818Sralph } 57156818Sralph 57256818Sralph /* 57356818Sralph * Initialization 57456818Sralph */ 57556818Sralph int 57656818Sralph xcfbinit() 57756818Sralph { 57856818Sralph register u_int *reset = (u_int *)IMS332_RESET_ADDRESS; 57956818Sralph register struct pmax_fb *fp = &xcfbfb; 58056818Sralph 58156818Sralph fp->isMono = 0; 58257234Sralph 58357234Sralph /* 58457234Sralph * Or Cached? A comment in the Mach driver suggests that the X server 58557234Sralph * runs faster in cached address space, but the X server is going 58657234Sralph * to blow away the data cache whenever it updates the screen, so.. 58757234Sralph */ 58856818Sralph fp->fr_addr = (char *) 58957234Sralph MACH_PHYS_TO_UNCACHED(XINE_PHYS_CFB_START + VRAM_OFFSET); 59058974Sralph fp->fr_size = 0x100000; 59157234Sralph /* 59258974Sralph * Must be in Uncached space since the fbuaccess structure is 59358974Sralph * mapped into the user's address space uncached. 59457234Sralph */ 59557234Sralph fp->fbu = (struct fbuaccess *) 59657234Sralph MACH_PHYS_TO_UNCACHED(MACH_CACHED_TO_PHYS(&xcfbu)); 59756818Sralph fp->posCursor = xcfbPosCursor; 59856818Sralph fp->KBDPutc = dtopKBDPutc; 59956818Sralph fp->kbddev = makedev(DTOPDEV, DTOPKBD_PORT); 60056818Sralph 60156818Sralph /* 60256818Sralph * Initialize the screen. 60356818Sralph */ 60456818Sralph #ifdef notdef 60556818Sralph assert_ims332_reset_bit(reset); 60656818Sralph DELAY(1); /* specs sez 50ns.. */ 60756818Sralph deassert_ims332_reset_bit(reset); 60856818Sralph 60956818Sralph /* CLOCKIN appears to receive a 6.25 Mhz clock --> PLL 12 for 75Mhz monitor */ 61056818Sralph ims332_write_register(IMS332_REG_BOOT, 12 | IMS332_BOOT_CLOCK_PLL); 61156818Sralph 61256818Sralph /* initialize VTG */ 61356818Sralph ims332_write_register(IMS332_REG_CSR_A, 61456818Sralph IMS332_BPP_8 | IMS332_CSR_A_DISABLE_CURSOR); 61556818Sralph DELAY(50); /* spec does not say */ 61656818Sralph 61756818Sralph /* datapath registers (values taken from prom's settings) */ 61856818Sralph 61956818Sralph ims332_write_register(IMS332_REG_HALF_SYNCH, 0x10); 62056818Sralph ims332_write_register(IMS332_REG_BACK_PORCH, 0x21); 62156818Sralph ims332_write_register(IMS332_REG_DISPLAY, 0x100); 62256818Sralph ims332_write_register(IMS332_REG_SHORT_DIS, 0x5d); 62356818Sralph ims332_write_register(IMS332_REG_BROAD_PULSE, 0x9f); 62456818Sralph ims332_write_register(IMS332_REG_V_SYNC, 0xc); 62556818Sralph ims332_write_register(IMS332_REG_V_PRE_EQUALIZE, 2); 62656818Sralph ims332_write_register(IMS332_REG_V_POST_EQUALIZE, 2); 62756818Sralph ims332_write_register(IMS332_REG_V_BLANK, 0x2a); 62856818Sralph ims332_write_register(IMS332_REG_V_DISPLAY, 0x600); 62956818Sralph ims332_write_register(IMS332_REG_LINE_TIME, 0x146); 63056818Sralph ims332_write_register(IMS332_REG_LINE_START, 0x10); 63156818Sralph ims332_write_register(IMS332_REG_MEM_INIT, 0xa); 63256818Sralph ims332_write_register(IMS332_REG_XFER_DELAY, 0xa); 63356818Sralph 63456818Sralph ims332_write_register(IMS332_REG_COLOR_MASK, 0xffffff); 63556818Sralph #endif 63656818Sralph 63756818Sralph /* 63856818Sralph * Initialize screen info. 63956818Sralph */ 64056818Sralph fp->fbu->scrInfo.max_row = 50; 64156818Sralph fp->fbu->scrInfo.max_col = 80; 64256818Sralph fp->fbu->scrInfo.max_x = 1024; 64356818Sralph fp->fbu->scrInfo.max_y = 768; 64457234Sralph fp->fbu->scrInfo.max_cur_x = 1008; 64557234Sralph fp->fbu->scrInfo.max_cur_y = 752; 64656818Sralph fp->fbu->scrInfo.version = 11; 64756818Sralph fp->fbu->scrInfo.mthreshold = 4; 64856818Sralph fp->fbu->scrInfo.mscale = 2; 64956818Sralph fp->fbu->scrInfo.min_cur_x = -15; 65056818Sralph fp->fbu->scrInfo.min_cur_y = -15; 65156818Sralph fp->fbu->scrInfo.qe.timestamp_ms = TO_MS(time); 65256818Sralph fp->fbu->scrInfo.qe.eSize = PM_MAXEVQ; 65356818Sralph fp->fbu->scrInfo.qe.eHead = fp->fbu->scrInfo.qe.eTail = 0; 65456818Sralph fp->fbu->scrInfo.qe.tcSize = MOTION_BUFFER_SIZE; 65556818Sralph fp->fbu->scrInfo.qe.tcNext = 0; 65656818Sralph 65756818Sralph xcfbInitColorMap(); 65856818Sralph 65956818Sralph ims332_write_register(IMS332_REG_CSR_A, 66056818Sralph IMS332_BPP_8 | IMS332_CSR_A_DMA_DISABLE | IMS332_CSR_A_VTG_ENABLE); 66156818Sralph 66256818Sralph xcfbScreenInit(); 66356818Sralph fbScroll(fp); 66456818Sralph 66556818Sralph fp->initialized = 1; 66656818Sralph if (cn_tab.cn_fb == (struct pmax_fb *)0) 66756818Sralph cn_tab.cn_fb = fp; 66856818Sralph return (1); 66956818Sralph } 67056818Sralph 67156818Sralph /* 67256818Sralph * ---------------------------------------------------------------------------- 67356818Sralph * 67456818Sralph * xcfbScreenInit -- 67556818Sralph * 67656818Sralph * Initialize the screen. 67756818Sralph * 67856818Sralph * Results: 67956818Sralph * None. 68056818Sralph * 68156818Sralph * Side effects: 68256818Sralph * The screen is initialized. 68356818Sralph * 68456818Sralph * ---------------------------------------------------------------------------- 68556818Sralph */ 68656818Sralph static void 68756818Sralph xcfbScreenInit() 68856818Sralph { 68956818Sralph register struct pmax_fb *fp = &xcfbfb; 69056818Sralph 69156818Sralph /* 69256818Sralph * Home the cursor. 69356818Sralph * We want an LSI terminal emulation. We want the graphics 69456818Sralph * terminal to scroll from the bottom. So start at the bottom. 69556818Sralph */ 69656818Sralph fp->row = 49; 69756818Sralph fp->col = 0; 69856818Sralph 69956818Sralph /* 70056818Sralph * Load the cursor with the default values 70156818Sralph * 70256818Sralph */ 70356818Sralph xcfbLoadCursor(defCursor); 70456818Sralph } 70556818Sralph 70656818Sralph /* 70756818Sralph * xcfb keyboard and mouse input. Just punt to the generic ones in fb.c 70856818Sralph */ 70956818Sralph void 71056818Sralph xcfbKbdEvent(ch) 71156818Sralph int ch; 71256818Sralph { 71356818Sralph fbKbdEvent(ch, &xcfbfb); 71456818Sralph } 71556818Sralph 71656818Sralph void 71756818Sralph xcfbMouseEvent(newRepPtr) 71856818Sralph MouseReport *newRepPtr; 71956818Sralph { 72056818Sralph fbMouseEvent(newRepPtr, &xcfbfb); 72156818Sralph } 72256818Sralph 72356818Sralph void 72456818Sralph xcfbMouseButtons(newRepPtr) 72556818Sralph MouseReport *newRepPtr; 72656818Sralph { 72756818Sralph fbMouseButtons(newRepPtr, &xcfbfb); 72856818Sralph } 72956818Sralph #endif /* NDTOP */ 73056818Sralph #endif /* NXCFB */ 731