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