|
|
1.1 root 1: #include "u.h"
2: #include "../port/lib.h"
3: #include "mem.h"
4: #include "dat.h"
5: #include "fns.h"
6: #include "../port/error.h"
7:
8: #include <libg.h>
9: #include <gnot.h>
10: #include "screen.h"
11: #include "vga.h"
12:
13: extern GBitmap gscreen;
14: extern GBitmap vgascreen;
15:
16: static Lock et4000pagelock;
17: static ulong storage;
18: static Point hotpoint;
19:
20: static void
21: setet4000page(int page)
22: {
23: uchar p;
24:
25: p = page & 0x0F;
26: p |= p<<4;
27: outb(0x3CD, p);
28:
29: p = (page & 0x30);
30: p |= p>>4;
31: outb(0x3CB, p);
32: }
33:
34: static void
35: disable(void)
36: {
37: uchar imaF7;
38:
39: outb(0x217A, 0xF7);
40: imaF7 = inb(0x217B) & ~0x80;
41: outb(0x217B, imaF7);
42: }
43:
44: static void
45: enable(void)
46: {
47: uchar imaF7;
48:
49: disable();
50:
51: /*
52: * Configure CRTCB for Sprite, 64x64,
53: * CRTC pixel overlay.
54: */
55: outb(0x217A, 0xEF);
56: outb(0x217B, 0x02);
57:
58: /*
59: * Cursor goes in the top left corner
60: * of the Sprite area, so the horizontal and
61: * vertical presets are 0.
62: */
63: outb(0x217A, 0xE2);
64: outb(0x217B, 0x00);
65: outb(0x217A, 0xE3);
66: outb(0x217B, 0x00);
67:
68: outb(0x217A, 0xE6);
69: outb(0x217B, 0x00);
70: outb(0x217A, 0xE7);
71: outb(0x217B, 0x00);
72:
73: /*
74: * Find a place for the cursor data in display memory.
75: * Must be on a "doubleword" boundary, but put it on a
76: * 1024-byte boundary so that there's no danger of it
77: * crossing a page.
78: */
79: storage = (gscreen.width*BY2WD*gscreen.r.max.y+1023)/1024;
80: storage *= 1024/4;
81: outb(0x217A, 0xE8);
82: outb(0x217B, storage & 0xFF);
83: outb(0x217A, 0xE9);
84: outb(0x217B, (storage>>8) & 0xFF);
85: outb(0x217A, 0xEA);
86: outb(0x217B, (storage>>16) & 0x0F);
87: storage *= 4;
88:
89: /*
90: * Row offset in "quadwords". Must be 2 for Sprite.
91: * Bag the pixel-panning.
92: * Colour depth, must be 2 for Sprite.
93: */
94: outb(0x217A, 0xEB);
95: outb(0x217B, 0x02);
96: outb(0x217A, 0xEC);
97: outb(0x217B, 0x00);
98:
99: outb(0x217A, 0xED);
100: outb(0x217B, 0x00);
101:
102: outb(0x217A, 0xEE);
103: if(vgascreen.ldepth == 3)
104: outb(0x217B, 0x01);
105: else
106: outb(0x217B, 0x00);
107:
108: /*
109: * Enable the CRTCB/Sprite.
110: */
111: outb(0x217A, 0xF7);
112: imaF7 = inb(0x217B);
113: outb(0x217B, 0x80|imaF7);
114: }
115:
116: static void
117: load(Cursor *c)
118: {
119: uchar p0, p1, *mem;
120: int i, x, y;
121: ushort p;
122: uchar clr[2*16], set[2*16];
123:
124: /*
125: * Lock the display memory so we can update the
126: * cursor bitmap if necessary.
127: */
128: lock(&et4000pagelock);
129:
130: /*
131: * Disable the cursor.
132: * Set the display page (do we need to restore
133: * the current contents when done?) and the
134: * pointer to the two planes. What if this crosses
135: * into a new page?
136: */
137: disable();
138:
139: setet4000page(storage>>16);
140: mem = ((uchar*)vgascreen.base) + (storage & 0xFFFF);
141:
142: /*
143: * Initialise the 64x64 cursor RAM array. There are 2 planes,
144: * p0 and p1. Data is written 4 pixels per byte, with p1 the
145: * MS bit of each pixel.
146: * The cursor mode gives the following truth table:
147: * p1 p0 colour
148: * 0 0 Sprite Colour 0 (defined as 0x00)
149: * 0 1 Sprite Colour 1 (defined as 0xFF)
150: * 1 0 Transparent (allow CRTC pixel pass through)
151: * 1 1 Invert (allow CRTC pixel invert through)
152: * Put the cursor into the top-left of the 64x64 array.
153: */
154: memmove(clr, c->clr, sizeof(clr));
155: pixreverse(clr, sizeof(clr), 0);
156: memmove(set, c->set, sizeof(set));
157: pixreverse(set, sizeof(set), 0);
158: for(y = 0; y < 64; y++){
159: for(x = 0; x < 64/8; x++){
160: if(x < 16/8 && y < 16){
161: p0 = clr[x+y*2];
162: p1 = set[x+y*2];
163:
164: p = 0x0000;
165: for(i = 0; i < 8; i++){
166: if(p1 & (1<<(7-i)))
167: ;
168: else if(p0 & (1<<(7-i)))
169: p |= 0x01<<(2*i);
170: else
171: p |= 0x02<<(2*i);
172: }
173: *mem++ = p & 0xFF;
174: *mem++ = (p>>8) & 0xFF;
175: }
176: else {
177: *mem++ = 0xAA;
178: *mem++ = 0xAA;
179: }
180: }
181: }
182:
183: /*
184: * Set the cursor hotpoint and enable the cursor.
185: */
186: hotpoint = c->offset;
187: outb(0x217A, 0xF7);
188: p = inb(0x217B)|0x80;
189: outb(0x217B, p);
190:
191: unlock(&et4000pagelock);
192: }
193:
194: static int
195: move(Point p)
196: {
197: int x, xo, y, yo;
198:
199: if(canlock(&et4000pagelock) == 0)
200: return 1;
201:
202: /*
203: * Mustn't position the cursor offscreen even partially,
204: * or it disappears. Therefore, if x or y is -ve, adjust the
205: * cursor presets instead.
206: */
207: if((x = p.x+hotpoint.x) < 0){
208: xo = -x;
209: x = 0;
210: }
211: else
212: xo = 0;
213: if((y = p.y+hotpoint.y) < 0){
214: yo = -y;
215: y = 0;
216: }
217: else
218: yo = 0;
219:
220: /*
221: * The cursor image is jerky if we don't do this.
222: * The cursor information is probably fetched from
223: * display memory during the horizontal blank active
224: * time and it doesn't like it if the coordinates
225: * are changed underneath.
226: */
227: while((vgai(Status1) & 0x08) == 0)
228: ;
229:
230: outb(0x217A, 0xE2);
231: outb(0x217B, xo);
232:
233: outb(0x217A, 0xE6);
234: outb(0x217B, yo);
235:
236: outb(0x217A, 0xE1);
237: outb(0x217B, (x>>8) & 0xFF);
238: outb(0x217A, 0xE0);
239: outb(0x217B, x & 0xFF);
240: outb(0x217A, 0xE5);
241: outb(0x217B, (y>>8) & 0xFF);
242: outb(0x217A, 0xE4);
243: outb(0x217B, y & 0xFF);
244:
245: unlock(&et4000pagelock);
246: return 0;
247: }
248:
249: static Hwgc et4000hwgc = {
250: "et4000hwgc",
251: enable,
252: load,
253: move,
254: disable,
255:
256: 0,
257: };
258:
259: static void
260: et4000page(int page)
261: {
262: if(hwgc == &et4000hwgc){
263: lock(&et4000pagelock);
264: setet4000page(page);
265: unlock(&et4000pagelock);
266: }
267: else
268: setet4000page(page);
269: }
270:
271: static Vgac et4000 = {
272: "et4000",
273: et4000page,
274:
275: 0,
276: };
277:
278: void
279: vgaet4000link(void)
280: {
281: addvgaclink(&et4000);
282: addhwgclink(&et4000hwgc);
283: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.