home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / server / ddx / mips / mips3230.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-07-18  |  10.1 KB  |  445 lines

  1. /*
  2.  * $XConsortium: mips3230.c,v 1.3 91/07/18 22:58:04 keith Exp $
  3.  *
  4.  * Copyright 1991 MIPS Computer Systems, Inc.
  5.  *
  6.  * Permission to use, copy, modify, distribute, and sell this software and its
  7.  * documentation for any purpose is hereby granted without fee, provided that
  8.  * the above copyright notice appear in all copies and that both that
  9.  * copyright notice and this permission notice appear in supporting
  10.  * documentation, and that the name of MIPS not be used in advertising or
  11.  * publicity pertaining to distribution of the software without specific,
  12.  * written prior permission.  MIPS makes no representations about the
  13.  * suitability of this software for any purpose.  It is provided "as is"
  14.  * without express or implied warranty.
  15.  *
  16.  * MIPS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  17.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL MIPS
  18.  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  19.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  20.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
  21.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22.  */
  23. #ident    "$Header: mips3230.c,v 1.3 91/07/18 22:58:04 keith Exp $"
  24.  
  25. #include <sys/types.h>
  26. #include <sysv/sys/grafreg.h>
  27. #include <sysv/sys/termio.h>
  28. #include <sysv/sys/kbd_ioctl.h>
  29.  
  30. #include <X.h>
  31. #include <Xproto.h>
  32. #include <misc.h>
  33. #include <cursorstr.h>
  34. #include <colormapst.h>
  35. #include <input.h>
  36. #include <scrnintstr.h>
  37. #include <servermd.h>
  38.  
  39. #include "mipsFb.h"
  40. #include "mips3230.h"
  41. #include "mipsKbd.h"
  42. #include "mipsIo.h"
  43.  
  44. extern char *mipsMapit();
  45.  
  46. static void Blank3230c();
  47. static void WriteCMap3230c();
  48. static void Close3230c();
  49.  
  50. static Bool RealizeCursor3230c();
  51. static void SetCursor3230c();
  52. static void MoveCursor3230c();
  53. static void RecolorCursor3230c();
  54.  
  55. static void Blank3230m();
  56.  
  57. /*
  58.  * Color frame buffer support
  59.  */
  60.  
  61. Bool
  62. mipsMap3230c(pm)
  63.     MipsScreenPtr pm;
  64. {
  65.     if (!pm->fbreg && (
  66.         !(pm->fbcache = (unsigned char *) mipsMapit((char *) 0,
  67.             GBFCKEY, R3030_GRAPHICS_FRAME_SIZE)) ||
  68.         !(pm->fbnocache = (unsigned char *) mipsMapit((char *) 0,
  69.             GBUFKEY, R3030_GRAPHICS_FRAME_SIZE)) ||
  70.         !(pm->fbspec = (unsigned char *) mipsMapit((char *) 0,
  71.             GBFVKEY, R3030_GRAPHICS_VECTOR_FRAME_SIZE)) ||
  72.         !(pm->fbreg = (unsigned char *) mipsMapit((char *) 0,
  73.             GREGKEY, R3030_GRAPHICS_REG_SIZE))))
  74.         return FALSE;
  75.  
  76.     pm->fbnorm = pm->fbcache;
  77.  
  78.     Close3230c(pm);
  79.     mipsInitColor(pm);
  80.  
  81.     /*
  82.      * Disable monochrome video to avoid performance degradation
  83.      * when running color-only on two headed system.
  84.      *
  85.      * (Depends on monochrome video being enabled later for real
  86.      * two headed operation, keyboard being open by this point, and
  87.      * Blank3230m() not needing the pm struct contents.)
  88.      */
  89.     Blank3230m((MipsScreenPtr) 0, SCREEN_SAVER_ON);
  90.  
  91.     pm->fb_width = RS3230C_BPSL;
  92.  
  93.     pm->cap = MIPS_SCR_CURSOR | MIPS_SCR_PACKED | MIPS_SCR_MASK;
  94.  
  95.     /* fill mode doesn't work on type 0 color boards */
  96.     if (((struct rs3230c_reg *) pm->fbreg)->kernel &
  97.                 RS3230C_KERNEL_IDMASK)
  98.         pm->cap |= MIPS_SCR_FILL;
  99.  
  100.     pm->Blank = Blank3230c;
  101.     pm->WriteCMap = WriteCMap3230c;
  102.     pm->Close = Close3230c;
  103.  
  104.     pm->RealizeCursor = RealizeCursor3230c;
  105.     pm->SetCursor = SetCursor3230c;
  106.     pm->MoveCursor = MoveCursor3230c;
  107.     pm->RecolorCursor = RecolorCursor3230c;
  108.  
  109.     {
  110.         struct bt459 *ramdac =
  111.             &((struct rs3230c_reg *) pm->fbreg)->ramdac;
  112.         int v;
  113.  
  114.         /*
  115.          * Set read mask for number of planes populated.
  116.          * XXX The PROM and/or kernel should take care of this.
  117.          * XXX All 3230s have 8 bit frame buffers anyway.
  118.          */
  119.         BT459_SETADDR(ramdac, BT459_READMASK);
  120.         ramdac->ctrl = (1 << pm->depth) - 1;
  121.  
  122.         /*
  123.          * Set HW cursor to "X mode"
  124.          */
  125.         BT459_SETADDR(ramdac, BT459_CR2);
  126.         v = ramdac->ctrl;
  127.         ramdac->adlo = BT459_CR2;
  128.         ramdac->ctrl = v | BT459_CR2_XCURS;
  129.     }
  130.  
  131.     return TRUE;
  132. }
  133.  
  134. static void
  135. Blank3230c(pm, on)
  136.     MipsScreenPtr pm;
  137.     Bool on;
  138. {
  139.     struct rs3230c_reg *reg = (struct rs3230c_reg *) pm->fbreg;
  140.  
  141.     if (on != SCREEN_SAVER_ON)
  142.         reg->xserver |= RS3230C_XSERVER_UNBLANK;
  143.     else
  144.         reg->xserver &= ~RS3230C_XSERVER_UNBLANK;
  145. }
  146.  
  147. /*
  148.  * KTCWRTCOLOR doesn't work on a 3230.  It doesn't even give an error,
  149.  * just prints "WARNING: No IRQ5 Interrupt Available" on the console.
  150.  */
  151. static void
  152. WriteCMap3230c(pm, pmap)
  153.     MipsScreenPtr pm;
  154.     ColormapPtr pmap;
  155. {
  156.     struct bt459 *ramdac =
  157.         &((struct rs3230c_reg *) pm->fbreg)->ramdac;
  158.     int n;
  159.     Entry *in;
  160.     volatile DACBITS *out = &ramdac->cmap;
  161.  
  162.     n = pmap->pVisual->ColormapEntries;
  163.     in = pmap->red;
  164.  
  165.     BT459_SETADDR(ramdac, BT459_CMAPRAM);
  166.  
  167.     while (--n >= 0) {
  168.         *out = in->co.local.red >> 8;
  169.         *out = in->co.local.green >> 8;
  170.         *out = in->co.local.blue >> 8;
  171.         in++;
  172.     }
  173. }
  174.  
  175. static void
  176. Close3230c(pm)
  177.     MipsScreenPtr pm;
  178. {
  179.     struct rs3230c_reg *reg = (struct rs3230c_reg *) pm->fbreg;
  180.  
  181.     /* clear mode bits in X server register */
  182.     reg->xserver &= RS3230C_XSERVER_UNBLANK;
  183.  
  184.     /* disable plane mask */
  185.     reg->mask = ~0;
  186.  
  187.     /* disable HW cursor */
  188.     SetCursor3230c(pm, (CursorPtr) 0, (pointer) 0, 0, 0);
  189. }
  190.  
  191. /*
  192.  * Convert cursor source and mask planes into fixed size Bt459 format
  193.  * buffer, so we can reload the cursor RAM more quickly.
  194.  *
  195.  * The Bt459 interleaves mask and source bits in each byte, with the leftmost
  196.  * pixel as the MSB:  <M0 S0 M1 S1 M2 S2 M3 S3>
  197.  */
  198. static Bool
  199. RealizeCursor3230c(pm, pCurs, pPriv)
  200.     MipsScreenPtr pm;
  201.     CursorPtr pCurs;
  202.     pointer *pPriv;
  203. {
  204.     CursorBitsPtr bits = pCurs->bits;
  205.     int w, h;
  206.     int x, y;
  207.     int bytes;
  208.     int soffset;
  209.     short *ram, rmask;
  210.     unsigned char *source, *mask;
  211.     int ramt, st, mt;
  212.     int bit;
  213.  
  214.     ram = (short *) xalloc(BT459_CURSBYTES);
  215.     *pPriv = (pointer) ram;
  216.     if (!ram)
  217.         return FALSE;
  218.  
  219.     h = bits->height;
  220.     if (h > BT459_CURSMAX)
  221.         h = BT459_CURSMAX;
  222.  
  223.     w = bits->width;
  224.  
  225.     /* line to line offset in source and mask bitmaps */
  226.     soffset = ((w + BITMAP_SCANLINE_PAD - 1) &
  227.         ~(BITMAP_SCANLINE_PAD - 1)) >> 3;
  228.  
  229.     if (w > BT459_CURSMAX)
  230.         w = BT459_CURSMAX;
  231.  
  232.     /* right edge mask for cursor RAM */
  233.     rmask = 0xffff0000 >> ((w & 7) << 1);
  234.  
  235.     /* bytes per line actually used in source and mask bitmaps */
  236.     bytes = (w + 7) >> 3;
  237.  
  238.     source = bits->source;
  239.     mask = bits->mask;
  240.  
  241.     for (y = 0; y < h; y++) {
  242.         for (x = 0; x < bytes; x++) {
  243.             /*
  244.              * Repack 1 mask byte and 1 source byte into
  245.              * 2 Bt459 cursor RAM bytes.
  246.              */
  247.             mt = mask[x] << 8;
  248.             st = source[x] << 7;
  249.             ramt = 0;
  250.             bit = 0x8000;
  251.             while (bit) {
  252.                 ramt |= (mt & bit);
  253.                 bit >>= 1;
  254.                 mt >>= 1;
  255.                 ramt |= (st & bit);
  256.                 bit >>= 1;
  257.                 st >>= 1;
  258.             }
  259.             *ram++ = ramt;
  260.         }
  261.  
  262.         /*
  263.          * Mask off garbage bits of partial word on right edge of
  264.          * cursor (if any).
  265.          */
  266.         if (rmask)
  267.             ram[-1] &= rmask;
  268.  
  269.         /* zero out blank space to right of cursor */
  270.         for (; x < BT459_CURSMAX / 8; x++)
  271.             *ram++ = 0;
  272.  
  273.         source += soffset;
  274.         mask += soffset;
  275.     }
  276.     /* zero out blank space below cursor */
  277.     for (; y < BT459_CURSMAX; y++) {
  278.         for (x = 0; x < BT459_CURSMAX / 8; x++)
  279.             ram[x] = 0;
  280.         ram += BT459_CURSMAX / 8;
  281.     }
  282.  
  283.     return TRUE;
  284. }
  285.  
  286. static void
  287. SetCursor3230c(pm, pCurs, priv, x, y)
  288.     MipsScreenPtr pm;
  289.     CursorPtr pCurs;
  290.     pointer priv;
  291.     int x, y;
  292. {
  293.     struct bt459 *ramdac =
  294.         &((struct rs3230c_reg *) pm->fbreg)->ramdac;
  295.     unsigned char *ram, c;
  296.     int i;
  297.  
  298.     /* turn cursor off */
  299.     BT459_SETADDR(ramdac, BT459_CURSCMD);
  300.     ramdac->ctrl = 0;
  301.  
  302.     if (!pCurs)
  303.         return;
  304.  
  305.     /* adjust hot spot values using magic constants from databook */
  306.     pm->xhot = BT459_CURSFIXX(pCurs->bits->xhot);
  307.     pm->yhot = BT459_CURSFIXY(pCurs->bits->yhot);
  308.  
  309.     /* position cursor */
  310.     MoveCursor3230c(pm, x, y);
  311.  
  312.     /* load colormap */
  313.     RecolorCursor3230c(pm, pCurs);
  314.  
  315.     ram = (unsigned char *) priv;
  316.  
  317.     /*
  318.      * Load cursor RAM from preformatted buffer
  319.      */
  320.     BT459_SETADDR(ramdac, BT459_CURSRAM);
  321.     for (i = 0; i < BT459_CURSBYTES; i++)
  322.         ramdac->ctrl = ram[i];
  323.  
  324.     /*
  325.      * Verify cursor RAM contents and correct any errors caused by
  326.      * internal bus contention in Bt459 Rev A parts...
  327.      */
  328.     BT459_SETADDR(ramdac, BT459_CURSRAM);
  329.     for (i = 0; i < BT459_CURSBYTES; i++)
  330.         while ((c = (unsigned char) ramdac->ctrl) != ram[i]) {
  331.             BT459_SETADDR(ramdac, BT459_CURSRAM + i);
  332.             ramdac->ctrl = (DACBITS) ram[i];
  333.             BT459_SETADDR(ramdac, BT459_CURSRAM + i);
  334.         }
  335.  
  336.     /* turn cursor on */
  337.     BT459_SETADDR(ramdac, BT459_CURSCMD);
  338.     ramdac->ctrl = BT459_CURSCMD_CURSEN;
  339. }
  340.  
  341. static void
  342. MoveCursor3230c(pm, x, y)
  343.     MipsScreenPtr pm;
  344.     int x, y;
  345. {
  346.     struct bt459 *ramdac =
  347.         &((struct rs3230c_reg *) pm->fbreg)->ramdac;
  348.  
  349.     x += pm->xhot;
  350.     y += pm->yhot;
  351.  
  352.     BT459_SETADDR(ramdac, BT459_CURSXLO);
  353.     ramdac->ctrl = x;
  354.     ramdac->ctrl = x >> 8;
  355.     ramdac->ctrl = y;
  356.     ramdac->ctrl = y >> 8;
  357. }
  358.  
  359. static void
  360. RecolorCursor3230c(pm, pCurs)
  361.     MipsScreenPtr pm;
  362.     CursorPtr pCurs;
  363. {
  364.     struct bt459 *ramdac =
  365.         &((struct rs3230c_reg *) pm->fbreg)->ramdac;
  366.  
  367.     BT459_SETADDR(ramdac, BT459_CURSCOL2);
  368.     ramdac->ctrl = pCurs->backRed >> 8;
  369.     ramdac->ctrl = pCurs->backGreen >> 8;
  370.     ramdac->ctrl = pCurs->backBlue >> 8;
  371.     ramdac->ctrl = pCurs->foreRed >> 8;
  372.     ramdac->ctrl = pCurs->foreGreen >> 8;
  373.     ramdac->ctrl = pCurs->foreBlue >> 8;
  374. }
  375.  
  376.  
  377. /*
  378.  * Monochrome frame buffer support
  379.  */
  380.  
  381. Bool
  382. mipsMap3230m(pm)
  383.     MipsScreenPtr pm;
  384. {
  385.     /* XXX should skip uncached mapping if unused */
  386.     if (!pm->fbcache && (
  387.         !(pm->fbcache = (unsigned char *) mipsMapit((char *) 0,
  388.         GBMONCH, MONO_FRAME_SIZE)) ||
  389.         !(pm->fbnocache = (unsigned char *) mipsMapit((char *) 0,
  390.         GBMNUNC, MONO_FRAME_SIZE))))
  391.         return FALSE;
  392.  
  393.     pm->fbnorm = pm->fbcache;
  394.  
  395.     pm->bitsPerPixel = 1;
  396.     pm->depth = 1;
  397.     pm->dpi = 100;    /* measured */
  398.     pm->scr_width = RS3230M_VISW;
  399.     pm->scr_height = RS3230M_VISH;
  400.     pm->fb_width = RS3230M_BPSL * 8;
  401.     pm->Blank = Blank3230m;
  402.  
  403.     /* need to open keyboard for blanking control */
  404.     openKeybd();
  405.  
  406.     return TRUE;
  407. }
  408.  
  409. static void
  410. Blank3230m(pm, on)
  411.     MipsScreenPtr pm;
  412.     Bool on;
  413. {
  414.     int value;
  415.  
  416.     value = on == SCREEN_SAVER_ON ? 1 : 0;
  417.  
  418.     if (keybdPriv.cap & DEV_BLANK)
  419.         if (sysvIoctl(keybdPriv.fd, KTMBLANK, &value) < 0) {
  420.             keybdPriv.cap &= ~DEV_BLANK;
  421.             Error("KTMBLANK ioctl failed");
  422.         }
  423. }
  424.  
  425. #define    RS3230_LINESIZE        32
  426. #define    RS3230_CACHESIZE    RS3230C_VISW
  427. #define    RS3230_ALIGN        (64 * 1024)
  428.  
  429. /* flush frame buffer data from cache */
  430. /* XXX method for computing flush address is hokey */
  431. mipsFlush3230()
  432. {
  433.     static volatile char *flush;
  434.     extern char *sbrk();
  435.     volatile char *p;
  436.     int i;
  437.  
  438.     if ((p = flush) == 0)
  439.         flush = p = (volatile char *)
  440.             (((int) sbrk(0) & ~(RS3230_ALIGN - 1)) - RS3230_ALIGN);
  441.  
  442.     for (i = 0; i < RS3230_CACHESIZE; i += RS3230_LINESIZE)
  443.         p[i];
  444. }
  445.