BPicture: Fix archive constructor.
[haiku.git] / src / add-ons / accelerants / s3 / savage_cursor.cpp
blob3e613fbd5aa06951f108051f575ef3e7cb7f079d
1 /*
2 Haiku S3 Savage driver adapted from the X.org Savage driver.
4 Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
5 Copyright (c) 2003-2006, X.Org Foundation
7 Copyright 2007-2008 Haiku, Inc. All rights reserved.
8 Distributed under the terms of the MIT license.
10 Authors:
11 Gerald Zajac 2006-2008
15 #include "accel.h"
16 #include "savage.h"
20 // Certain HW cursor operations seem to require a delay to prevent lockups.
22 static void
23 WaitHSync(int n)
25 while (n--) {
26 while (ReadReg8(SYSTEM_CONTROL_REG) & 0x01) {};
27 while ( ! ReadReg8(SYSTEM_CONTROL_REG) & 0x01) {};
32 void
33 Savage_ShowCursor(bool bShow)
35 // Turn cursor on/off.
37 if ( ! bShow && S3_SAVAGE4_SERIES(gInfo.sharedInfo->chipType))
38 WaitHSync(5);
40 WriteCrtcReg(0x45, bShow ? 0x01 : 0x00, 0x01);
44 void
45 Savage_SetCursorPosition(int x, int y)
47 SharedInfo& si = *gInfo.sharedInfo;
49 if (S3_SAVAGE4_SERIES(si.chipType))
50 WaitHSync(5);
52 // xOffset & yOffset are used for displaying partial cursors on screen edges.
54 uint8 xOffset = 0;
55 uint8 yOffset = 0;
57 if (x < 0) {
58 xOffset = (( -x) & 0xFE);
59 x = 0;
62 if (y < 0) {
63 yOffset = (( -y) & 0xFE);
64 y = 0;
68 // Note: when setting the cursor position, register 48 must be set last
69 // since setting register 48 activates the new cursor position.
71 WriteCrtcReg( 0x4e, xOffset );
72 WriteCrtcReg( 0x4f, yOffset );
74 WriteCrtcReg( 0x47, (x & 0xff) );
75 WriteCrtcReg( 0x46, (x & 0x0700) >> 8 );
77 WriteCrtcReg( 0x49, (y & 0xff) );
78 WriteCrtcReg( 0x48, (y & 0x0700) >> 8 );
82 bool
83 Savage_LoadCursorImage(int width, int height, uint8* andMask, uint8* xorMask)
85 SharedInfo& si = *gInfo.sharedInfo;
87 if (andMask == NULL || xorMask == NULL)
88 return false;
90 // Initialize the hardware cursor as completely transparent.
92 uint16* fbCursor16 = (uint16*)((addr_t)si.videoMemAddr + si.cursorOffset);
94 for (int i = 0; i < CURSOR_BYTES; i += 4) {
95 *fbCursor16++ = ~0; // and bits
96 *fbCursor16++ = 0; // xor bits
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
108 uint8* fbCursor = (uint8*)((addr_t)si.videoMemAddr + si.cursorOffset);
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++;
117 if (S3_SAVAGE4_SERIES(si.chipType)) {
119 // Bug in Savage4 Rev B requires us to do an MMIO read after
120 // loading the cursor.
122 volatile unsigned int k = ALT_STATUS_WORD0;
123 (void)k++; // Not to be optimised out
126 // Set cursor location in video memory.
128 WriteCrtcReg(0x4d, (0xff & si.cursorOffset / 1024));
129 WriteCrtcReg(0x4c, (0xff00 & si.cursorOffset / 1024) >> 8);
131 // Set the cursor colors which are black foreground and white background.
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);
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);
143 return true;