FreeBSD/Linux Kernel Cross Reference
sys/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 };
Cache object: dd0443747be54fc0e49db271890ffc00
|