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 297706df26Smrg#ifdef HAVE_CONFIG_H 307706df26Smrg#include "config.h" 317706df26Smrg#endif 327706df26Smrg 337706df26Smrg/* tga_cursor.c */ 347706df26Smrg 357706df26Smrg#include "xf86.h" 367706df26Smrg#include "xf86PciInfo.h" 377706df26Smrg#include "xf86Pci.h" 387706df26Smrg#include "BT.h" 397706df26Smrg 407706df26Smrg#include "tga.h" 417706df26Smrg#include "tga_regs.h" 427706df26Smrg 437706df26Smrg/* defines */ 447706df26Smrg/* BT485 also supports 32 bit cursor, but why use it? */ 457706df26Smrg#define CURSOR_SIZE 64 467706df26Smrg 477706df26Smrg/* protos */ 487706df26Smrg 497706df26Smrgstatic void TGALoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src); 507706df26Smrgstatic void TGAShowCursor(ScrnInfoPtr pScrn); 517706df26Smrgstatic void TGAHideCursor(ScrnInfoPtr pScrn); 527706df26Smrgstatic void TGASetCursorPosition(ScrnInfoPtr pScrn, int x, int y); 537706df26Smrgstatic void TGASetCursorColors(ScrnInfoPtr pScrn, int bg, int fg); 547706df26Smrg 557706df26Smrgstatic void 567706df26SmrgTGALoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src) 577706df26Smrg{ 587706df26Smrg TGAPtr pTga = TGAPTR(pScrn); 597706df26Smrg int i; 607706df26Smrg 617706df26Smrg /* set 64 bit cursor */ 627706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_COMMAND_REG_0, 0x7F, 0x80); 637706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_WRITE_ADDR, 0x00, 0x01); 647706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_STATUS_REG, 0xF8, 0x04); 657706df26Smrg 667706df26Smrg /* first write address reg @ 0x0, then write 0xb with the data (for 32 bit 677706df26Smrg cursor) */ 687706df26Smrg 697706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_WRITE_ADDR, 0xFC, 0x00); 707706df26Smrg 717706df26Smrg for(i = 0; i < ((CURSOR_SIZE * CURSOR_SIZE) / 8); i++) 727706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_RAM_DATA, 0x00, *src++); 737706df26Smrg 747706df26Smrg for(i = 0; i < ((CURSOR_SIZE * CURSOR_SIZE) / 8); i++) 757706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_RAM_DATA, 0x00, *src++); 767706df26Smrg 777706df26Smrg/* pTga->RamDacRec->WriteDAC(pScrn, BT_WRITE_ADDR, 0xFC, 0x00); */ 787706df26Smrg 797706df26Smrg return; 807706df26Smrg} 817706df26Smrg 827706df26Smrg 837706df26Smrgstatic void 847706df26SmrgTGAShowCursor(ScrnInfoPtr pScrn) 857706df26Smrg{ 867706df26Smrg TGAPtr pTga = TGAPTR(pScrn); 877706df26Smrg 887706df26Smrg /* enable BT485 X11 cursor */ 897706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_COMMAND_REG_2, 0xFC, 0x03); 907706df26Smrg 917706df26Smrg return; 927706df26Smrg} 937706df26Smrg 947706df26Smrg 957706df26Smrgstatic void 967706df26SmrgTGAHideCursor(ScrnInfoPtr pScrn) 977706df26Smrg{ 987706df26Smrg TGAPtr pTga = TGAPTR(pScrn); 997706df26Smrg 1007706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_COMMAND_REG_2, 0xFC, 0x00); 1017706df26Smrg 1027706df26Smrg return; 1037706df26Smrg} 1047706df26Smrg 1057706df26Smrgstatic void 1067706df26SmrgTGASetCursorPosition(ScrnInfoPtr pScrn, int x, int y) 1077706df26Smrg{ 1087706df26Smrg TGAPtr pTga = TGAPTR(pScrn); 1097706df26Smrg unsigned int tmp_x, tmp_y; 1107706df26Smrg 1117706df26Smrg /* translate x && y to BT485 cursor addresses */ 1127706df26Smrg 1137706df26Smrg tmp_x = x + CURSOR_SIZE; 1147706df26Smrg tmp_x &= 0x0FFF; 1157706df26Smrg 1167706df26Smrg tmp_y = y + CURSOR_SIZE; 1177706df26Smrg tmp_y &= 0x0FFF; 1187706df26Smrg 1197706df26Smrg /* write out the addresses */ 1207706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_X_LOW, 0x00, (tmp_x & 0xFF)); 1217706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_X_HIGH, 0xF0, (tmp_x >> 8)); 1227706df26Smrg 1237706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_Y_LOW, 0x00, (tmp_y & 0xFF)); 1247706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_Y_HIGH, 0xF0, (tmp_y >> 8)); 1257706df26Smrg 1267706df26Smrg return; 1277706df26Smrg} 1287706df26Smrg 1297706df26Smrg 1307706df26Smrgstatic void 1317706df26SmrgTGASetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) 1327706df26Smrg /* set pScrn->cursor_fg and pScrn->cursor_bg */ 1337706df26Smrg{ 1347706df26Smrg TGAPtr pTga = TGAPTR(pScrn); 1357706df26Smrg 1367706df26Smrg /* first, load address register at 0x4 with 0x1, then write 3 color 1377706df26Smrg octets RGB to 0x5 (background), then write three octets to 0x5 1387706df26Smrg (foreground), then write to address register 0xFC */ 1397706df26Smrg 1407706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_WR_ADDR, 0xFC, 0x01); 1417706df26Smrg 1427706df26Smrg /* we don't seem to support the 6 bit DAC option as of 4.0, and why 1437706df26Smrg would we? */ 1447706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, (bg & 0x00FF0000) >> 16); 1457706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, (bg & 0x0000FF00) >> 8); 1467706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, (bg & 0x000000FF)); 1477706df26Smrg 1487706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, (fg & 0x00FF0000) >> 16); 1497706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, (fg & 0x0000FF00) >> 8); 1507706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, (fg & 0x000000FF)); 1517706df26Smrg 1527706df26Smrg/* pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_WR_ADDR, 0xFC, 0x00); */ 1537706df26Smrg 1547706df26Smrg return; 1557706df26Smrg} 1567706df26Smrg 1577706df26Smrg 1587706df26SmrgBool 1597706df26SmrgTGAHWCursorInit(ScreenPtr pScreen) 1607706df26Smrg{ 161b92e825aSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1627706df26Smrg TGAPtr pTga; 1637706df26Smrg xf86CursorInfoPtr infoPtr; 1647706df26Smrg 1657706df26Smrg pTga = TGAPTR(pScrn); 1667706df26Smrg 1677706df26Smrg infoPtr = xf86CreateCursorInfoRec(); 1687706df26Smrg if(!infoPtr) return FALSE; 1697706df26Smrg 1707706df26Smrg pTga->CursorInfoRec = infoPtr; 1717706df26Smrg 1727706df26Smrg infoPtr->MaxWidth = CURSOR_SIZE; 1737706df26Smrg infoPtr->MaxHeight = CURSOR_SIZE; 1747706df26Smrg infoPtr->Flags = HARDWARE_CURSOR_AND_SOURCE_WITH_MASK | 1757706df26Smrg HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | 1767706df26Smrg HARDWARE_CURSOR_TRUECOLOR_AT_8BPP; 1777706df26Smrg 1787706df26Smrg infoPtr->SetCursorColors = TGASetCursorColors; 1797706df26Smrg infoPtr->SetCursorPosition = TGASetCursorPosition; 1807706df26Smrg infoPtr->LoadCursorImage = TGALoadCursorImage; 1817706df26Smrg infoPtr->HideCursor = TGAHideCursor; 1827706df26Smrg infoPtr->ShowCursor = TGAShowCursor; 1837706df26Smrg infoPtr->UseHWCursor = NULL; 1847706df26Smrg 1857706df26Smrg return(xf86InitCursor(pScreen, infoPtr)); 1867706df26Smrg} 1877706df26Smrg 188