Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include "u.h"
2
#include "../port/lib.h"
3
#include "mem.h"
4
#include "dat.h"
5
#include "fns.h"
6
#include "io.h"
7
#include "../port/error.h"
8
 
9
#define	Image	IMAGE
10
#include <draw.h>
11
#include <memdraw.h>
12
#include <cursor.h>
13
#include "screen.h"
14
 
15
typedef struct Cursor3dfx Cursor3dfx;
16
struct Cursor3dfx {
17
	int	vidProcCfg;
18
	int	hwCurPatAddr;
19
	int	hwCurLoc;
20
	int	hwCurC0;
21
	int	hwCurC1;
22
};
23
 
24
enum {
25
	dramInit0	= 0x18,
26
	dramInit1	= 0x1C,
27
 
28
	hwCur		= 0x5C,
29
};
30
 
31
static void
32
tdfxenable(VGAscr* scr)
33
{
34
	Pcidev *p;
35
	int i, *mmio;
36
 
37
	if(scr->mmio)
38
		return;
39
	if(p = pcimatch(nil, 0x121A, 0)){
40
		switch(p->did){
41
		case 0x0003:		/* Banshee */
42
		case 0x0005:		/* Avenger (a.k.a. Voodoo3) */
43
			break;
44
		default:
45
			return;
46
		}
47
	}
48
	else
49
		return;
50
 
51
	scr->mmio = vmap(p->mem[0].bar&~0x0F, p->mem[0].size);
52
	if(scr->mmio == nil)
53
		return;
54
	scr->pci = p;
55
 
56
	addvgaseg("3dfxmmio", p->mem[0].bar&~0x0F, p->mem[0].size);
57
	vgalinearpci(scr);
58
	if(scr->apsize)
59
		addvgaseg("3dfxscreen", scr->paddr, scr->apsize);
60
 
61
	/*
62
	 * Find a place for the cursor data in display memory.
63
	 * If SDRAM then there's 16MB memory else it's SGRAM
64
	 * and can count it based on the power-on straps -
65
	 * chip size can be 8Mb or 16Mb, and there can be 4 or
66
	 * 8 of them.
67
	 * Use the last 1KB of the framebuffer.
68
	 */
69
	mmio = (void*)((uchar*)scr->mmio+dramInit0);
70
	if(*(mmio+1) & 0x40000000)
71
		i = 16*1024*1024;
72
	else{
73
		if(*mmio & 0x08000000)
74
			i = 16*1024*1024/8;
75
		else
76
			i = 8*1024*1024/8;
77
		if(*mmio & 0x04000000)
78
			i *= 8;
79
		else
80
			i *= 4;
81
	}
82
	scr->storage = i - 1024;
83
}
84
 
85
static void
86
tdfxcurdisable(VGAscr* scr)
87
{
88
	Cursor3dfx *cursor3dfx;
89
 
90
	if(scr->mmio == 0)
91
		return;
92
	cursor3dfx = (void*)((uchar*)scr->mmio+hwCur);
93
	cursor3dfx->vidProcCfg &= ~0x08000000;
94
}
95
 
96
static void
97
tdfxcurload(VGAscr* scr, Cursor* curs)
98
{
99
	int y;
100
	uchar *p;
101
	Cursor3dfx *cursor3dfx;
102
 
103
	if(scr->mmio == 0)
104
		return;
105
	cursor3dfx = (void*)((uchar*)scr->mmio+hwCur);
106
 
107
	/*
108
	 * Disable the cursor then load the new image in
109
	 * the top-left of the 64x64 array.
110
	 * The cursor data is stored in memory as 128-bit
111
	 * words consisting of plane 0 in the least significant 64-bits
112
	 * and plane 1 in the most significant.
113
	 * The X11 cursor truth table is:
114
	 *	p0 p1	colour
115
	 *	 0  0	transparent
116
	 *	 0  1	transparent
117
	 *	 1  0	hwCurC0
118
	 *	 1  1	hwCurC1
119
	 * Unused portions of the image have been initialised to be
120
	 * transparent.
121
	 */
122
	cursor3dfx->vidProcCfg &= ~0x08000000;
123
	p = (uchar*)scr->vaddr + scr->storage;
124
	for(y = 0; y < 16; y++){
125
		*p++ = curs->clr[2*y]|curs->set[2*y];
126
		*p++ = curs->clr[2*y+1]|curs->set[2*y+1];
127
		p += 6;
128
		*p++ = curs->set[2*y];
129
		*p++ = curs->set[2*y+1];
130
		p += 6;
131
	}
132
 
133
	/*
134
	 * Save the cursor hotpoint and enable the cursor.
135
	 * The 0,0 cursor point is bottom-right.
136
	 */
137
	scr->offset.x = 63+curs->offset.x;
138
	scr->offset.y = 63+curs->offset.y;
139
	cursor3dfx->vidProcCfg |= 0x08000000;
140
}
141
 
142
static int
143
tdfxcurmove(VGAscr* scr, Point p)
144
{
145
	Cursor3dfx *cursor3dfx;
146
 
147
	if(scr->mmio == 0)
148
		return 1;
149
	cursor3dfx = (void*)((uchar*)scr->mmio+hwCur);
150
 
151
	cursor3dfx->hwCurLoc = ((p.y+scr->offset.y)<<16)|(p.x+scr->offset.x);
152
 
153
	return 0;
154
}
155
 
156
static void
157
tdfxcurenable(VGAscr* scr)
158
{
159
	Cursor3dfx *cursor3dfx;
160
 
161
	tdfxenable(scr);
162
	if(scr->mmio == 0)
163
		return;
164
	cursor3dfx = (void*)((uchar*)scr->mmio+hwCur);
165
 
166
	/*
167
	 * Cursor colours.
168
	 */
169
	cursor3dfx->hwCurC0 = 0xFFFFFFFF;
170
	cursor3dfx->hwCurC1 = 0x00000000;
171
 
172
	/*
173
	 * Initialise the 64x64 cursor to be transparent (X11 mode).
174
	 */
175
	cursor3dfx->hwCurPatAddr = scr->storage;
176
	memset((uchar*)scr->vaddr + scr->storage, 0, 64*16);
177
 
178
	/*
179
	 * Load, locate and enable the 64x64 cursor in X11 mode.
180
	 */
181
	tdfxcurload(scr, &arrow);
182
	tdfxcurmove(scr, ZP);
183
	cursor3dfx->vidProcCfg |= 0x08000002;
184
}
185
 
186
VGAdev vga3dfxdev = {
187
	"3dfx",
188
 
189
	tdfxenable,
190
	nil,
191
	nil,
192
	nil,
193
};
194
 
195
VGAcur vga3dfxcur = {
196
	"3dfxhwgc",
197
 
198
	tdfxcurenable,
199
	tdfxcurdisable,
200
	tdfxcurload,
201
	tdfxcurmove,
202
};