]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/pc/vga3dfx.c
kernel: cleanup makefile for $CONF.$O target
[plan9front.git] / sys / src / 9 / 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         p = scr->pci;
40         if(p == nil || p->vid != 0x121A)
41                 return;
42         scr->mmio = vmap(p->mem[0].bar&~0x0F, p->mem[0].size);
43         if(scr->mmio == nil)
44                 return;
45         
46         addvgaseg("3dfxmmio", p->mem[0].bar&~0x0F, p->mem[0].size);
47         vgalinearpci(scr);
48         if(scr->apsize)
49                 addvgaseg("3dfxscreen", scr->paddr, scr->apsize);
50
51         /*
52          * Find a place for the cursor data in display memory.
53          * If SDRAM then there's 16MB memory else it's SGRAM
54          * and can count it based on the power-on straps -
55          * chip size can be 8Mb or 16Mb, and there can be 4 or
56          * 8 of them.
57          * Use the last 1KB of the framebuffer.
58          */
59         mmio = (void*)((uchar*)scr->mmio+dramInit0);
60         if(*(mmio+1) & 0x40000000)
61                 i = 16*1024*1024;
62         else{
63                 if(*mmio & 0x08000000)
64                         i = 16*1024*1024/8;
65                 else
66                         i = 8*1024*1024/8;
67                 if(*mmio & 0x04000000)
68                         i *= 8;
69                 else
70                         i *= 4;
71         }
72         scr->storage = i - 1024;
73 }
74
75 static void
76 tdfxcurdisable(VGAscr* scr)
77 {
78         Cursor3dfx *cursor3dfx;
79
80         if(scr->mmio == 0)
81                 return;
82         cursor3dfx = (void*)((uchar*)scr->mmio+hwCur);
83         cursor3dfx->vidProcCfg &= ~0x08000000;
84 }
85
86 static void
87 tdfxcurload(VGAscr* scr, Cursor* curs)
88 {
89         int y;
90         uchar *p;
91         Cursor3dfx *cursor3dfx;
92
93         if(scr->mmio == 0)
94                 return;
95         cursor3dfx = (void*)((uchar*)scr->mmio+hwCur);
96
97         /*
98          * Disable the cursor then load the new image in
99          * the top-left of the 64x64 array.
100          * The cursor data is stored in memory as 128-bit
101          * words consisting of plane 0 in the least significant 64-bits
102          * and plane 1 in the most significant.
103          * The X11 cursor truth table is:
104          *      p0 p1   colour
105          *       0  0   transparent
106          *       0  1   transparent
107          *       1  0   hwCurC0
108          *       1  1   hwCurC1
109          * Unused portions of the image have been initialised to be
110          * transparent.
111          */
112         cursor3dfx->vidProcCfg &= ~0x08000000;
113         p = (uchar*)scr->vaddr + scr->storage;
114         for(y = 0; y < 16; y++){
115                 *p++ = curs->clr[2*y]|curs->set[2*y];
116                 *p++ = curs->clr[2*y+1]|curs->set[2*y+1];
117                 p += 6;
118                 *p++ = curs->set[2*y];
119                 *p++ = curs->set[2*y+1];
120                 p += 6;
121         }
122
123         /*
124          * Save the cursor hotpoint and enable the cursor.
125          * The 0,0 cursor point is bottom-right.
126          */
127         scr->offset.x = 63+curs->offset.x;
128         scr->offset.y = 63+curs->offset.y;
129         cursor3dfx->vidProcCfg |= 0x08000000;
130 }
131
132 static int
133 tdfxcurmove(VGAscr* scr, Point p)
134 {
135         Cursor3dfx *cursor3dfx;
136
137         if(scr->mmio == 0)
138                 return 1;
139         cursor3dfx = (void*)((uchar*)scr->mmio+hwCur);
140
141         cursor3dfx->hwCurLoc = ((p.y+scr->offset.y)<<16)|(p.x+scr->offset.x);
142
143         return 0;
144 }
145
146 static void
147 tdfxcurenable(VGAscr* scr)
148 {
149         Cursor3dfx *cursor3dfx;
150
151         tdfxenable(scr);
152         if(scr->mmio == 0)
153                 return;
154         cursor3dfx = (void*)((uchar*)scr->mmio+hwCur);
155
156         /*
157          * Cursor colours.
158          */
159         cursor3dfx->hwCurC0 = 0xFFFFFFFF;
160         cursor3dfx->hwCurC1 = 0x00000000;
161
162         /*
163          * Initialise the 64x64 cursor to be transparent (X11 mode).
164          */
165         cursor3dfx->hwCurPatAddr = scr->storage;
166         memset((uchar*)scr->vaddr + scr->storage, 0, 64*16);
167
168         /*
169          * Load, locate and enable the 64x64 cursor in X11 mode.
170          */
171         tdfxcurload(scr, &arrow);
172         tdfxcurmove(scr, ZP);
173         cursor3dfx->vidProcCfg |= 0x08000002;
174 }
175
176 VGAdev vga3dfxdev = {
177         "3dfx",
178
179         tdfxenable,
180         nil,
181         nil,
182         nil,
183 };
184
185 VGAcur vga3dfxcur = {
186         "3dfxhwgc",
187
188         tdfxcurenable,
189         tdfxcurdisable,
190         tdfxcurload,
191         tdfxcurmove,
192 };