FreeBSD/Linux Kernel Cross Reference
sys/pc/vga3dfx.c
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 };
Cache object: af0c819eaff097402a537ed8dc3ff4a3
|