1 /* 2 Haiku S3 Savage driver adapted from the X.org Savage driver. 3 4 Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. 5 Copyright (c) 2003-2006, X.Org Foundation 6 7 Copyright 2007-2008 Haiku, Inc. All rights reserved. 8 Distributed under the terms of the MIT license. 9 10 Authors: 11 Gerald Zajac 2006-2008 12 */ 13 14 15 #include "accel.h" 16 #include "savage.h" 17 18 19 20 // Certain HW cursor operations seem to require a delay to prevent lockups. 21 22 static void 23 WaitHSync(int n) 24 { 25 while (n--) { 26 while (ReadReg8(SYSTEM_CONTROL_REG) & 0x01) {}; 27 while ( ! ReadReg8(SYSTEM_CONTROL_REG) & 0x01) {}; 28 } 29 } 30 31 32 void 33 Savage_ShowCursor(bool bShow) 34 { 35 // Turn cursor on/off. 36 37 if ( ! bShow && S3_SAVAGE4_SERIES(gInfo.sharedInfo->chipType)) 38 WaitHSync(5); 39 40 WriteCrtcReg(0x45, bShow ? 0x01 : 0x00, 0x01); 41 } 42 43 44 void 45 Savage_SetCursorPosition(int x, int y) 46 { 47 SharedInfo& si = *gInfo.sharedInfo; 48 49 if (S3_SAVAGE4_SERIES(si.chipType)) 50 WaitHSync(5); 51 52 // xOffset & yOffset are used for displaying partial cursors on screen edges. 53 54 uint8 xOffset = 0; 55 uint8 yOffset = 0; 56 57 if (x < 0) { 58 xOffset = (( -x) & 0xFE); 59 x = 0; 60 } 61 62 if (y < 0) { 63 yOffset = (( -y) & 0xFE); 64 y = 0; 65 } 66 67 68 // Note: when setting the cursor position, register 48 must be set last 69 // since setting register 48 activates the new cursor position. 70 71 WriteCrtcReg( 0x4e, xOffset ); 72 WriteCrtcReg( 0x4f, yOffset ); 73 74 WriteCrtcReg( 0x47, (x & 0xff) ); 75 WriteCrtcReg( 0x46, (x & 0x0700) >> 8 ); 76 77 WriteCrtcReg( 0x49, (y & 0xff) ); 78 WriteCrtcReg( 0x48, (y & 0x0700) >> 8 ); 79 } 80 81 82 bool 83 Savage_LoadCursorImage(int width, int height, uint8* andMask, uint8* xorMask) 84 { 85 SharedInfo& si = *gInfo.sharedInfo; 86 87 if (andMask == NULL || xorMask == NULL) 88 return false; 89 90 // Initialize the hardware cursor as completely transparent. 91 92 uint16* fbCursor16 = (uint16*)((addr_t)si.videoMemAddr + si.cursorOffset); 93 94 for (int i = 0; i < CURSOR_BYTES; i += 4) { 95 *fbCursor16++ = ~0; // and bits 96 *fbCursor16++ = 0; // xor bits 97 } 98 99 // Now load the AND & XOR masks for the cursor image into the cursor 100 // buffer. Note that a particular bit in these masks will have the 101 // following effect upon the corresponding cursor pixel: 102 // AND XOR Result 103 // 0 0 White pixel 104 // 0 1 Black pixel 105 // 1 0 Screen color (for transparency) 106 // 1 1 Reverse screen color to black or white 107 108 uint8* fbCursor = (uint8*)((addr_t)si.videoMemAddr + si.cursorOffset); 109 110 for (int row = 0; row < height; row++) { 111 for (int colByte = 0; colByte < width / 8; colByte++) { 112 fbCursor[row * 16 + colByte] = *andMask++; 113 fbCursor[row * 16 + colByte + 2] = *xorMask++; 114 } 115 } 116 117 if (S3_SAVAGE4_SERIES(si.chipType)) { 118 119 // Bug in Savage4 Rev B requires us to do an MMIO read after 120 // loading the cursor. 121 122 volatile unsigned int k = ALT_STATUS_WORD0; 123 (void)k++; // Not to be optimised out 124 } 125 126 // Set cursor location in video memory. 127 128 WriteCrtcReg(0x4d, (0xff & si.cursorOffset / 1024)); 129 WriteCrtcReg(0x4c, (0xff00 & si.cursorOffset / 1024) >> 8); 130 131 // Set the cursor colors which are black foreground and white background. 132 133 ReadCrtcReg(0x45); // reset cursor color stack pointer 134 WriteCrtcReg(0x4a, 0); // set foreground color stack low, mid, high bytes 135 WriteCrtcReg(0x4a, 0); 136 WriteCrtcReg(0x4a, 0); 137 138 ReadCrtcReg(0x45); // reset cursor color stack pointer 139 WriteCrtcReg(0x4b, ~0); // set background color stack low, mid, high bytes 140 WriteCrtcReg(0x4b, ~0); 141 WriteCrtcReg(0x4b, ~0); 142 143 return true; 144 } 145