tga_cursor.c revision 7706df26
17706df26Smrg/*
27706df26Smrg * Copyright 1999 by Matthew Grossman, Seattle, USA.
37706df26Smrg *
47706df26Smrg * Permission to use, copy, modify, distribute, and sell this software
57706df26Smrg * and its documentation for any purpose is hereby granted without
67706df26Smrg * fee, provided that the above copyright notice appear in all copies
77706df26Smrg * and that both that copyright notice and this permission notice
87706df26Smrg * appear in supporting documentation, and that the name of Matthew
97706df26Smrg * Grossman not be used in advertising or publicity pertaining to
107706df26Smrg * distribution of the software without specific, written prior
117706df26Smrg * permission.  Matthew Grossman makes no representations about the
127706df26Smrg * suitability of this software for any purpose.  It is provided "as
137706df26Smrg * is" without express or implied warranty.
147706df26Smrg *
157706df26Smrg * MATTHEW GROSSMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
167706df26Smrg * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
177706df26Smrg * FITNESS, IN NO EVENT SHALL MATTHEW GROSSMAN BE LIABLE FOR ANY
187706df26Smrg * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
197706df26Smrg * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
207706df26Smrg * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
217706df26Smrg * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
227706df26Smrg * SOFTWARE.
237706df26Smrg *
247706df26Smrg * Author:  Matthew Grossman, mattg@oz.net
257706df26Smrg *
267706df26Smrg * DEC TGA hardware cursor using BT485 ramdac
277706df26Smrg */
287706df26Smrg/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/tga_cursor.c,v 1.1 1999/04/17 07:06:58 dawes Exp $ */
297706df26Smrg
307706df26Smrg#ifdef HAVE_CONFIG_H
317706df26Smrg#include "config.h"
327706df26Smrg#endif
337706df26Smrg
347706df26Smrg/* tga_cursor.c */
357706df26Smrg
367706df26Smrg#include "xf86.h"
377706df26Smrg#include "xf86PciInfo.h"
387706df26Smrg#include "xf86Pci.h"
397706df26Smrg#include "BT.h"
407706df26Smrg
417706df26Smrg#include "tga.h"
427706df26Smrg#include "tga_regs.h"
437706df26Smrg
447706df26Smrg/* defines */
457706df26Smrg/* BT485 also supports 32 bit cursor, but why use it? */
467706df26Smrg#define CURSOR_SIZE 64
477706df26Smrg
487706df26Smrg/* protos */
497706df26Smrg
507706df26Smrgstatic void TGALoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src);
517706df26Smrgstatic void TGAShowCursor(ScrnInfoPtr pScrn);
527706df26Smrgstatic void TGAHideCursor(ScrnInfoPtr pScrn);
537706df26Smrgstatic void TGASetCursorPosition(ScrnInfoPtr pScrn, int x, int y);
547706df26Smrgstatic void TGASetCursorColors(ScrnInfoPtr pScrn, int bg, int fg);
557706df26Smrg
567706df26Smrgstatic void
577706df26SmrgTGALoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
587706df26Smrg{
597706df26Smrg  TGAPtr pTga = TGAPTR(pScrn);
607706df26Smrg  int i;
617706df26Smrg
627706df26Smrg  /* set 64 bit cursor */
637706df26Smrg  pTga->RamDacRec->WriteDAC(pScrn, BT_COMMAND_REG_0, 0x7F, 0x80);
647706df26Smrg  pTga->RamDacRec->WriteDAC(pScrn, BT_WRITE_ADDR, 0x00, 0x01);
657706df26Smrg  pTga->RamDacRec->WriteDAC(pScrn, BT_STATUS_REG, 0xF8, 0x04);
667706df26Smrg
677706df26Smrg  /* first write address reg @ 0x0, then write 0xb with the data (for 32 bit
687706df26Smrg     cursor) */
697706df26Smrg
707706df26Smrg  pTga->RamDacRec->WriteDAC(pScrn, BT_WRITE_ADDR, 0xFC, 0x00);
717706df26Smrg
727706df26Smrg  for(i = 0; i < ((CURSOR_SIZE * CURSOR_SIZE) / 8); i++)
737706df26Smrg    pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_RAM_DATA, 0x00, *src++);
747706df26Smrg
757706df26Smrg  for(i = 0; i < ((CURSOR_SIZE * CURSOR_SIZE) / 8); i++)
767706df26Smrg    pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_RAM_DATA, 0x00, *src++);
777706df26Smrg
787706df26Smrg/*    pTga->RamDacRec->WriteDAC(pScrn, BT_WRITE_ADDR, 0xFC, 0x00); */
797706df26Smrg
807706df26Smrg  return;
817706df26Smrg}
827706df26Smrg
837706df26Smrg
847706df26Smrgstatic void
857706df26SmrgTGAShowCursor(ScrnInfoPtr pScrn)
867706df26Smrg{
877706df26Smrg  TGAPtr pTga = TGAPTR(pScrn);
887706df26Smrg
897706df26Smrg  /* enable BT485 X11 cursor */
907706df26Smrg  pTga->RamDacRec->WriteDAC(pScrn, BT_COMMAND_REG_2, 0xFC, 0x03);
917706df26Smrg
927706df26Smrg  return;
937706df26Smrg}
947706df26Smrg
957706df26Smrg
967706df26Smrgstatic void
977706df26SmrgTGAHideCursor(ScrnInfoPtr pScrn)
987706df26Smrg{
997706df26Smrg  TGAPtr pTga = TGAPTR(pScrn);
1007706df26Smrg
1017706df26Smrg  pTga->RamDacRec->WriteDAC(pScrn, BT_COMMAND_REG_2, 0xFC, 0x00);
1027706df26Smrg
1037706df26Smrg  return;
1047706df26Smrg}
1057706df26Smrg
1067706df26Smrgstatic void
1077706df26SmrgTGASetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
1087706df26Smrg{
1097706df26Smrg   TGAPtr pTga = TGAPTR(pScrn);
1107706df26Smrg   unsigned int tmp_x, tmp_y;
1117706df26Smrg
1127706df26Smrg   /* translate x && y to BT485 cursor addresses */
1137706df26Smrg
1147706df26Smrg   tmp_x = x + CURSOR_SIZE;
1157706df26Smrg   tmp_x &= 0x0FFF;
1167706df26Smrg
1177706df26Smrg   tmp_y = y + CURSOR_SIZE;
1187706df26Smrg   tmp_y &= 0x0FFF;
1197706df26Smrg
1207706df26Smrg   /* write out the addresses */
1217706df26Smrg   pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_X_LOW, 0x00, (tmp_x & 0xFF));
1227706df26Smrg   pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_X_HIGH, 0xF0, (tmp_x >> 8));
1237706df26Smrg
1247706df26Smrg   pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_Y_LOW, 0x00, (tmp_y & 0xFF));
1257706df26Smrg   pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_Y_HIGH, 0xF0, (tmp_y >> 8));
1267706df26Smrg
1277706df26Smrg   return;
1287706df26Smrg}
1297706df26Smrg
1307706df26Smrg
1317706df26Smrgstatic void
1327706df26SmrgTGASetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
1337706df26Smrg     /* set pScrn->cursor_fg and pScrn->cursor_bg */
1347706df26Smrg{
1357706df26Smrg  TGAPtr pTga = TGAPTR(pScrn);
1367706df26Smrg
1377706df26Smrg    /* first, load address register at 0x4 with 0x1, then write 3 color
1387706df26Smrg       octets RGB to 0x5 (background), then write three octets to 0x5
1397706df26Smrg       (foreground), then write to address register 0xFC */
1407706df26Smrg
1417706df26Smrg  pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_WR_ADDR, 0xFC, 0x01);
1427706df26Smrg
1437706df26Smrg  /* we don't seem to support the 6 bit DAC option as of 4.0, and why
1447706df26Smrg     would we? */
1457706df26Smrg  pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, (bg & 0x00FF0000) >> 16);
1467706df26Smrg  pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, (bg & 0x0000FF00) >> 8);
1477706df26Smrg  pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, (bg & 0x000000FF));
1487706df26Smrg
1497706df26Smrg  pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, (fg & 0x00FF0000) >> 16);
1507706df26Smrg  pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, (fg & 0x0000FF00) >> 8);
1517706df26Smrg  pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, (fg & 0x000000FF));
1527706df26Smrg
1537706df26Smrg/*    pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_WR_ADDR, 0xFC, 0x00); */
1547706df26Smrg
1557706df26Smrg  return;
1567706df26Smrg}
1577706df26Smrg
1587706df26Smrg
1597706df26SmrgBool
1607706df26SmrgTGAHWCursorInit(ScreenPtr pScreen)
1617706df26Smrg{
1627706df26Smrg    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
1637706df26Smrg    TGAPtr pTga;
1647706df26Smrg    xf86CursorInfoPtr infoPtr;
1657706df26Smrg
1667706df26Smrg    pTga = TGAPTR(pScrn);
1677706df26Smrg
1687706df26Smrg    infoPtr = xf86CreateCursorInfoRec();
1697706df26Smrg    if(!infoPtr) return FALSE;
1707706df26Smrg
1717706df26Smrg    pTga->CursorInfoRec = infoPtr;
1727706df26Smrg
1737706df26Smrg    infoPtr->MaxWidth = CURSOR_SIZE;
1747706df26Smrg    infoPtr->MaxHeight = CURSOR_SIZE;
1757706df26Smrg    infoPtr->Flags =  HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
1767706df26Smrg      HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
1777706df26Smrg      HARDWARE_CURSOR_TRUECOLOR_AT_8BPP;
1787706df26Smrg
1797706df26Smrg    infoPtr->SetCursorColors = TGASetCursorColors;
1807706df26Smrg    infoPtr->SetCursorPosition = TGASetCursorPosition;
1817706df26Smrg    infoPtr->LoadCursorImage = TGALoadCursorImage;
1827706df26Smrg    infoPtr->HideCursor = TGAHideCursor;
1837706df26Smrg    infoPtr->ShowCursor = TGAShowCursor;
1847706df26Smrg    infoPtr->UseHWCursor = NULL;
1857706df26Smrg
1867706df26Smrg    return(xf86InitCursor(pScreen, infoPtr));
1877706df26Smrg}
1887706df26Smrg
189