]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/pc/vgahiqvideo.c
Import sources from 2011-03-30 iso image
[plan9front.git] / sys / src / 9 / pc / vgahiqvideo.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 enum {
16         Xrx             = 0x3D6,        /* Configuration Extensions Index */
17 };
18
19 static uchar
20 hiqvideoxi(long port, uchar index)
21 {
22         uchar data;
23
24         outb(port, index);
25         data = inb(port+1);
26
27         return data;
28 }
29
30 static void
31 hiqvideoxo(long port, uchar index, uchar data)
32 {
33         outb(port, index);
34         outb(port+1, data);
35 }
36
37 static void
38 hiqvideolinear(VGAscr*, int, int)
39 {
40 }
41
42 static void
43 hiqvideoenable(VGAscr* scr)
44 {
45         Pcidev *p;
46         int vmsize;
47
48         /*
49          * Only once, can't be disabled for now.
50          */
51         if(scr->mmio)
52                 return;
53         if(p = pcimatch(nil, 0x102C, 0)){
54                 switch(p->did){
55                 case 0x00C0:            /* 69000 HiQVideo */
56                         vmsize = 2*1024*1024;
57                         break;
58                 case 0x00E0:            /* 65550 HiQV32 */
59                 case 0x00E4:            /* 65554 HiQV32 */
60                 case 0x00E5:            /* 65555 HiQV32 */
61                         switch((hiqvideoxi(Xrx, 0x43)>>1) & 0x03){
62                         default:
63                         case 0:
64                                 vmsize = 1*1024*1024;
65                                 break;
66                         case 1:
67                                 vmsize = 2*1024*1024;
68                                 break;
69                         }
70                         break;
71                 default:
72                         return;
73                 }
74         }
75         else
76                 return;
77
78         scr->pci = p;
79         vgalinearpci(scr);
80         
81         if(scr->paddr) {
82                 addvgaseg("hiqvideoscreen", scr->paddr, scr->apsize);
83         }
84
85         /*
86          * Find a place for the cursor data in display memory.
87          * Must be on a 4096-byte boundary.
88          * scr->mmio holds the virtual address of the cursor
89          * storage area in the framebuffer region.
90          */
91         scr->storage = vmsize-4096;
92         scr->mmio = (ulong*)((uchar*)scr->vaddr+scr->storage);
93 }
94
95 static void
96 hiqvideocurdisable(VGAscr*)
97 {
98         hiqvideoxo(Xrx, 0xA0, 0x10);
99 }
100
101 static void
102 hiqvideocurload(VGAscr* scr, Cursor* curs)
103 {
104         uchar *p;
105         int x, y;
106
107         /*
108          * Disable the cursor.
109          */
110         hiqvideocurdisable(scr);
111
112         if(scr->mmio == 0)
113                 return;
114         p = (uchar*)scr->mmio;
115
116         for(y = 0; y < 16; y += 2){
117                 *p++ = ~(curs->clr[2*y]|curs->set[2*y]);
118                 *p++ = ~(curs->clr[2*y+1]|curs->set[2*y+1]);
119                 *p++ = 0xFF;
120                 *p++ = 0xFF;
121                 *p++ = ~(curs->clr[2*y+2]|curs->set[2*y+2]);
122                 *p++ = ~(curs->clr[2*y+3]|curs->set[2*y+3]);
123                 *p++ = 0xFF;
124                 *p++ = 0xFF;
125                 *p++ = curs->set[2*y];
126                 *p++ = curs->set[2*y+1];
127                 *p++ = 0x00;
128                 *p++ = 0x00;
129                 *p++ = curs->set[2*y+2];
130                 *p++ = curs->set[2*y+3];
131                 *p++ = 0x00;
132                 *p++ = 0x00;
133         }
134         while(y < 32){
135                 for(x = 0; x < 64; x += 8)
136                         *p++ = 0xFF;
137                 for(x = 0; x < 64; x += 8)
138                         *p++ = 0x00;
139                 y += 2;
140         }
141
142         /*
143          * Save the cursor hotpoint and enable the cursor.
144          */
145         scr->offset = curs->offset;
146         hiqvideoxo(Xrx, 0xA0, 0x11);
147 }
148
149 static int
150 hiqvideocurmove(VGAscr* scr, Point p)
151 {
152         int x, y;
153
154         if(scr->mmio == 0)
155                 return 1;
156
157         if((x = p.x+scr->offset.x) < 0)
158                 x = 0x8000|(-x & 0x07FF);
159         if((y = p.y+scr->offset.y) < 0)
160                 y = 0x8000|(-y & 0x07FF);
161
162         hiqvideoxo(Xrx, 0xA4, x & 0xFF);
163         hiqvideoxo(Xrx, 0xA5, (x>>8) & 0xFF);
164         hiqvideoxo(Xrx, 0xA6, y & 0xFF);
165         hiqvideoxo(Xrx, 0xA7, (y>>8) & 0xFF);
166
167         return 0;
168 }
169
170 static void
171 hiqvideocurenable(VGAscr* scr)
172 {
173         uchar xr80;
174
175         hiqvideoenable(scr);
176         if(scr->mmio == 0)
177                 return;
178
179         /*
180          * Disable the cursor.
181          */
182         hiqvideocurdisable(scr);
183
184         /*
185          * Cursor colours.
186          * Can't call setcolor here as cursor is already locked.
187          * When done make sure the cursor enable in Xr80 is set.
188          */
189         xr80 = hiqvideoxi(Xrx, 0x80);
190         hiqvideoxo(Xrx, 0x80, xr80|0x01);
191         vgao(PaddrW, 0x04);
192         vgao(Pdata, Pwhite);
193         vgao(Pdata, Pwhite);
194         vgao(Pdata, Pwhite);
195         vgao(Pdata, Pblack);
196         vgao(Pdata, Pblack);
197         vgao(Pdata, Pblack);
198         hiqvideoxo(Xrx, 0x80, xr80|0x10);
199
200         hiqvideoxo(Xrx, 0xA2, (scr->storage>>12)<<4);
201         hiqvideoxo(Xrx, 0xA3, (scr->storage>>16) & 0x3F);
202
203         /*
204          * Load, locate and enable the 32x32 cursor.
205          * Cursor enable in Xr80 better be set already.
206          */
207         hiqvideocurload(scr, &arrow);
208         hiqvideocurmove(scr, ZP);
209         hiqvideoxo(Xrx, 0xA0, 0x11);
210 }
211
212 VGAdev vgahiqvideodev = {
213         "hiqvideo",
214
215         hiqvideoenable,                 /* enable */
216         nil,                            /* disable */
217         nil,                            /* page */
218         hiqvideolinear,                 /* linear */
219 };
220
221 VGAcur vgahiqvideocur = {
222         "hiqvideohwgc",
223
224         hiqvideocurenable,              /* enable */
225         hiqvideocurdisable,             /* disable */
226         hiqvideocurload,                /* load */
227         hiqvideocurmove,                /* move */
228 };