FreeBSD/Linux Kernel Cross Reference
sys/pc/vgaclgd542x.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 static int
16 clgd542xpageset(VGAscr*, int page)
17 {
18 uchar gr09;
19 int opage;
20
21 if(vgaxi(Seqx, 0x07) & 0xF0)
22 page = 0;
23 gr09 = vgaxi(Grx, 0x09);
24 if(vgaxi(Grx, 0x0B) & 0x20){
25 vgaxo(Grx, 0x09, page<<2);
26 opage = gr09>>2;
27 }
28 else{
29 vgaxo(Grx, 0x09, page<<4);
30 opage = gr09>>4;
31 }
32
33 return opage;
34 }
35
36 static void
37 clgd542xpage(VGAscr* scr, int page)
38 {
39 lock(&scr->devlock);
40 clgd542xpageset(scr, page);
41 unlock(&scr->devlock);
42 }
43
44 static void
45 clgd542xlinear(VGAscr* scr, int, int)
46 {
47 vgalinearpciid(scr, 0x1013, 0);
48 }
49
50 static void
51 clgd542xdisable(VGAscr*)
52 {
53 uchar sr12;
54
55 sr12 = vgaxi(Seqx, 0x12);
56 vgaxo(Seqx, 0x12, sr12 & ~0x01);
57 }
58
59 static void
60 clgd542xenable(VGAscr* scr)
61 {
62 uchar sr12;
63 int mem, x;
64
65 /*
66 * Disable the cursor.
67 */
68 sr12 = vgaxi(Seqx, 0x12);
69 vgaxo(Seqx, 0x12, sr12 & ~0x01);
70
71 /*
72 * Cursor colours.
73 * Can't call setcolor here as cursor is already locked.
74 */
75 vgaxo(Seqx, 0x12, sr12|0x02);
76 vgao(PaddrW, 0x00);
77 vgao(Pdata, Pwhite);
78 vgao(Pdata, Pwhite);
79 vgao(Pdata, Pwhite);
80 vgao(PaddrW, 0x0F);
81 vgao(Pdata, Pblack);
82 vgao(Pdata, Pblack);
83 vgao(Pdata, Pblack);
84 vgaxo(Seqx, 0x12, sr12);
85
86 mem = 0;
87 switch(vgaxi(Crtx, 0x27) & ~0x03){
88
89 case 0x88: /* CL-GD5420 */
90 case 0x8C: /* CL-GD5422 */
91 case 0x94: /* CL-GD5424 */
92 case 0x80: /* CL-GD5425 */
93 case 0x90: /* CL-GD5426 */
94 case 0x98: /* CL-GD5427 */
95 case 0x9C: /* CL-GD5429 */
96 /*
97 * The BIOS leaves the memory size in Seq0A, bits 4 and 3.
98 * See Technical Reference Manual Appendix E1, Section 1.3.2.
99 *
100 * The storage area for the 64x64 cursors is the last 16Kb of
101 * display memory.
102 */
103 mem = (vgaxi(Seqx, 0x0A)>>3) & 0x03;
104 break;
105
106 case 0xA0: /* CL-GD5430 */
107 case 0xA8: /* CL-GD5434 */
108 case 0xAC: /* CL-GD5436 */
109 case 0xB8: /* CL-GD5446 */
110 case 0x30: /* CL-GD7543 */
111 /*
112 * Attempt to intuit the memory size from the DRAM control
113 * register. Minimum is 512KB.
114 * If DRAM bank switching is on then there's double.
115 */
116 x = vgaxi(Seqx, 0x0F);
117 mem = (x>>3) & 0x03;
118 if(x & 0x80)
119 mem++;
120 break;
121
122 case 0xBC: /* CL-GD5480 */
123 mem = 2; /* 1024 = 256<<2 */
124 x = vgaxi(Seqx, 0x0F);
125 if((x & 0x18) == 0x18){
126 mem <<= 1; /* 2048 = 256<<3 */
127 if(x & 0x80)
128 mem <<= 2; /* 2048 = 256<<4 */
129 }
130 if(vgaxi(Seqx, 0x17) & 0x80)
131 mem <<= 1;
132 break;
133
134 default: /* uh, ah dunno */
135 break;
136 }
137 scr->storage = ((256<<mem)-16)*1024;
138
139 /*
140 * Set the current cursor to index 0
141 * and turn the 64x64 cursor on.
142 */
143 vgaxo(Seqx, 0x13, 0);
144 vgaxo(Seqx, 0x12, sr12|0x05);
145 }
146
147 static void
148 clgd542xinitcursor(VGAscr* scr, int xo, int yo, int index)
149 {
150 uchar *p, seq07;
151 uint p0, p1;
152 int opage, x, y;
153
154 /*
155 * Is linear addressing turned on? This will determine
156 * how we access the cursor storage.
157 */
158 seq07 = vgaxi(Seqx, 0x07);
159 opage = 0;
160 p = scr->vaddr;
161 if(!(seq07 & 0xF0)){
162 lock(&scr->devlock);
163 opage = clgd542xpageset(scr, scr->storage>>16);
164 p += (scr->storage & 0xFFFF);
165 }
166 else
167 p += scr->storage;
168 p += index*1024;
169
170 for(y = yo; y < 16; y++){
171 p0 = scr->set[2*y];
172 p1 = scr->set[2*y+1];
173 if(xo){
174 p0 = (p0<<xo)|(p1>>(8-xo));
175 p1 <<= xo;
176 }
177 *p++ = p0;
178 *p++ = p1;
179
180 for(x = 16; x < 64; x += 8)
181 *p++ = 0x00;
182
183 p0 = scr->clr[2*y]|scr->set[2*y];
184 p1 = scr->clr[2*y+1]|scr->set[2*y+1];
185 if(xo){
186 p0 = (p0<<xo)|(p1>>(8-xo));
187 p1 <<= xo;
188 }
189 *p++ = p0;
190 *p++ = p1;
191
192 for(x = 16; x < 64; x += 8)
193 *p++ = 0x00;
194 }
195 while(y < 64+yo){
196 for(x = 0; x < 64; x += 8){
197 *p++ = 0x00;
198 *p++ = 0x00;
199 }
200 y++;
201 }
202
203 if(!(seq07 & 0xF0)){
204 clgd542xpageset(scr, opage);
205 unlock(&scr->devlock);
206 }
207 }
208
209 static void
210 clgd542xload(VGAscr* scr, Cursor* curs)
211 {
212 uchar sr12;
213
214 /*
215 * Disable the cursor.
216 */
217 sr12 = vgaxi(Seqx, 0x12);
218 vgaxo(Seqx, 0x12, sr12 & ~0x01);
219
220 memmove(&scr->Cursor, curs, sizeof(Cursor));
221 clgd542xinitcursor(scr, 0, 0, 0);
222
223 /*
224 * Enable the cursor.
225 */
226 vgaxo(Seqx, 0x13, 0);
227 vgaxo(Seqx, 0x12, sr12|0x05);
228 }
229
230 static int
231 clgd542xmove(VGAscr* scr, Point p)
232 {
233 int index, x, xo, y, yo;
234
235 index = 0;
236 if((x = p.x+scr->offset.x) < 0){
237 xo = -x;
238 x = 0;
239 }
240 else
241 xo = 0;
242 if((y = p.y+scr->offset.y) < 0){
243 yo = -y;
244 y = 0;
245 }
246 else
247 yo = 0;
248
249 if(xo || yo){
250 clgd542xinitcursor(scr, xo, yo, 1);
251 index = 1;
252 }
253 vgaxo(Seqx, 0x13, index<<2);
254
255 vgaxo(Seqx, 0x10|((x & 0x07)<<5), (x>>3) & 0xFF);
256 vgaxo(Seqx, 0x11|((y & 0x07)<<5), (y>>3) & 0xFF);
257
258 return 0;
259 }
260
261 VGAdev vgaclgd542xdev = {
262 "clgd542x",
263
264 0,
265 0,
266 clgd542xpage,
267 clgd542xlinear,
268 };
269
270 VGAcur vgaclgd542xcur = {
271 "clgd542xhwgc",
272
273 clgd542xenable,
274 clgd542xdisable,
275 clgd542xload,
276 clgd542xmove,
277 };
Cache object: 83bb00f29dde8f03ba8cb2cda17cbcce
|