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