]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/pc/vgaclgd542x.c
audiohda: first attempt on audio recording support for intel hda audio, distinguish...
[plan9front.git] / sys / src / 9 / 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         vgalinearpci(scr);
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 };