1*35db13eaSAxel Dörfler /*
2*35db13eaSAxel Dörfler Haiku S3 Virge driver adapted from the X.org Virge driver.
3*35db13eaSAxel Dörfler
4*35db13eaSAxel Dörfler Copyright (C) 1994-1999 The XFree86 Project, Inc. All Rights Reserved.
5*35db13eaSAxel Dörfler
6*35db13eaSAxel Dörfler Copyright 2007-2008 Haiku, Inc. All rights reserved.
7*35db13eaSAxel Dörfler Distributed under the terms of the MIT license.
8*35db13eaSAxel Dörfler
9*35db13eaSAxel Dörfler Authors:
10*35db13eaSAxel Dörfler Gerald Zajac 2007-2008
11*35db13eaSAxel Dörfler */
12*35db13eaSAxel Dörfler
13*35db13eaSAxel Dörfler #include "accel.h"
14*35db13eaSAxel Dörfler #include "virge.h"
15*35db13eaSAxel Dörfler
16*35db13eaSAxel Dörfler
17*35db13eaSAxel Dörfler
18*35db13eaSAxel Dörfler void
Virge_ShowCursor(bool bShow)19*35db13eaSAxel Dörfler Virge_ShowCursor(bool bShow)
20*35db13eaSAxel Dörfler {
21*35db13eaSAxel Dörfler // Turn cursor on/off.
22*35db13eaSAxel Dörfler
23*35db13eaSAxel Dörfler WriteCrtcReg(0x45, bShow ? 0x01 : 0x00, 0x01);
24*35db13eaSAxel Dörfler }
25*35db13eaSAxel Dörfler
26*35db13eaSAxel Dörfler
27*35db13eaSAxel Dörfler void
Virge_SetCursorPosition(int x,int y)28*35db13eaSAxel Dörfler Virge_SetCursorPosition(int x, int y)
29*35db13eaSAxel Dörfler {
30*35db13eaSAxel Dörfler uint8 xOffset = 0;
31*35db13eaSAxel Dörfler uint8 yOffset = 0;
32*35db13eaSAxel Dörfler
33*35db13eaSAxel Dörfler // xOffset & yOffset are used for displaying partial cursors on screen edges.
34*35db13eaSAxel Dörfler
35*35db13eaSAxel Dörfler if (x < 0) {
36*35db13eaSAxel Dörfler xOffset = (( -x) & 0xfe);
37*35db13eaSAxel Dörfler x = 0;
38*35db13eaSAxel Dörfler }
39*35db13eaSAxel Dörfler
40*35db13eaSAxel Dörfler if (y < 0) {
41*35db13eaSAxel Dörfler yOffset = (( -y) & 0xfe);
42*35db13eaSAxel Dörfler y = 0;
43*35db13eaSAxel Dörfler }
44*35db13eaSAxel Dörfler
45*35db13eaSAxel Dörfler // Note: when setting the cursor position, register 48 must be set last
46*35db13eaSAxel Dörfler // since setting register 48 activates the new cursor position.
47*35db13eaSAxel Dörfler
48*35db13eaSAxel Dörfler WriteCrtcReg( 0x4e, xOffset );
49*35db13eaSAxel Dörfler WriteCrtcReg( 0x4f, yOffset );
50*35db13eaSAxel Dörfler
51*35db13eaSAxel Dörfler WriteCrtcReg( 0x47, (x & 0xff) );
52*35db13eaSAxel Dörfler WriteCrtcReg( 0x46, (x & 0x0700) >> 8 );
53*35db13eaSAxel Dörfler
54*35db13eaSAxel Dörfler WriteCrtcReg( 0x49, (y & 0xff) );
55*35db13eaSAxel Dörfler WriteCrtcReg( 0x48, (y & 0x0700) >> 8 );
56*35db13eaSAxel Dörfler }
57*35db13eaSAxel Dörfler
58*35db13eaSAxel Dörfler
59*35db13eaSAxel Dörfler bool
Virge_LoadCursorImage(int width,int height,uint8 * andMask,uint8 * xorMask)60*35db13eaSAxel Dörfler Virge_LoadCursorImage(int width, int height, uint8* andMask, uint8* xorMask)
61*35db13eaSAxel Dörfler {
62*35db13eaSAxel Dörfler SharedInfo& si = *gInfo.sharedInfo;
63*35db13eaSAxel Dörfler
64*35db13eaSAxel Dörfler if (andMask == NULL || xorMask == NULL)
65*35db13eaSAxel Dörfler return false;
66*35db13eaSAxel Dörfler
67*35db13eaSAxel Dörfler // Initialize hardware cursor to be completely transparent.
68*35db13eaSAxel Dörfler
69*35db13eaSAxel Dörfler uint16* fbCursor16 = (uint16*)((addr_t)si.videoMemAddr + si.cursorOffset);
70*35db13eaSAxel Dörfler
71*35db13eaSAxel Dörfler for (int i = 0; i < CURSOR_BYTES; i += 4) {
72*35db13eaSAxel Dörfler *fbCursor16++ = ~0; // and bits
73*35db13eaSAxel Dörfler *fbCursor16++ = 0; // xor bits
74*35db13eaSAxel Dörfler }
75*35db13eaSAxel Dörfler
76*35db13eaSAxel Dörfler // Now load the AND & XOR masks for the cursor image into the cursor
77*35db13eaSAxel Dörfler // buffer. Note that a particular bit in these masks will have the
78*35db13eaSAxel Dörfler // following effect upon the corresponding cursor pixel:
79*35db13eaSAxel Dörfler // AND XOR Result
80*35db13eaSAxel Dörfler // 0 0 White pixel
81*35db13eaSAxel Dörfler // 0 1 Black pixel
82*35db13eaSAxel Dörfler // 1 0 Screen color (for transparency)
83*35db13eaSAxel Dörfler // 1 1 Reverse screen color to black or white
84*35db13eaSAxel Dörfler
85*35db13eaSAxel Dörfler uint8* fbCursor = (uint8*)((addr_t)si.videoMemAddr + si.cursorOffset);
86*35db13eaSAxel Dörfler
87*35db13eaSAxel Dörfler for (int row = 0; row < height; row++) {
88*35db13eaSAxel Dörfler for (int colByte = 0; colByte < width / 8; colByte++) {
89*35db13eaSAxel Dörfler fbCursor[row * 16 + colByte] = *andMask++;
90*35db13eaSAxel Dörfler fbCursor[row * 16 + colByte + 2] = *xorMask++;
91*35db13eaSAxel Dörfler }
92*35db13eaSAxel Dörfler }
93*35db13eaSAxel Dörfler
94*35db13eaSAxel Dörfler // Set cursor location in video memory.
95*35db13eaSAxel Dörfler
96*35db13eaSAxel Dörfler WriteCrtcReg(0x4d, (0xff & si.cursorOffset / 1024));
97*35db13eaSAxel Dörfler WriteCrtcReg(0x4c, (0x0f00 & si.cursorOffset / 1024) >> 8);
98*35db13eaSAxel Dörfler
99*35db13eaSAxel Dörfler // Set the cursor colors which are black foreground and white background.
100*35db13eaSAxel Dörfler
101*35db13eaSAxel Dörfler ReadCrtcReg(0x45); // reset cursor color stack pointer
102*35db13eaSAxel Dörfler WriteCrtcReg(0x4a, 0); // set foreground color stack low, mid, high bytes
103*35db13eaSAxel Dörfler WriteCrtcReg(0x4a, 0);
104*35db13eaSAxel Dörfler WriteCrtcReg(0x4a, 0);
105*35db13eaSAxel Dörfler
106*35db13eaSAxel Dörfler ReadCrtcReg(0x45); // reset cursor color stack pointer
107*35db13eaSAxel Dörfler WriteCrtcReg(0x4b, ~0); // set background color stack low, mid, high bytes
108*35db13eaSAxel Dörfler WriteCrtcReg(0x4b, ~0);
109*35db13eaSAxel Dörfler WriteCrtcReg(0x4b, ~0);
110*35db13eaSAxel Dörfler
111*35db13eaSAxel Dörfler return true;
112*35db13eaSAxel Dörfler }
113