|
|
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: /*
14: * Hardware graphics cursor support for
15: * Brooktree Bt485 Monolithic True-Color RAMDAC.
16: * Assumes hooked up to an S3 86C928.
17: *
18: * BUGS:
19: * 64x64x2 cursor always used;
20: * no support for interlaced mode.
21: */
22: enum {
23: AddrW = 0x00, /* Address register; palette/cursor RAM write */
24: Palette = 0x01, /* 6/8-bit color palette data */
25: Pmask = 0x02, /* Pixel mask register */
26: AddrR = 0x03, /* Address register; palette/cursor RAM read */
27: ColorW = 0x04, /* Address register; cursor/overscan color write */
28: Color = 0x05, /* Cursor/overscan color data */
29: Cmd0 = 0x06, /* Command register 0 */
30: ColorR = 0x07, /* Address register; cursor/overscan color read */
31: Cmd1 = 0x08, /* Command register 1 */
32: Cmd2 = 0x09, /* Command register 2 */
33: Status = 0x0A, /* Status */
34: Cmd3 = 0x1A, /* Command register 3 */
35: Cram = 0x0B, /* Cursor RAM array data */
36: Cxlr = 0x0C, /* Cursor x-low register */
37: Cxhr = 0x0D, /* Cursor x-high register */
38: Cylr = 0x0E, /* Cursor y-low register */
39: Cyhr = 0x0F, /* Cursor y-high register */
40:
41: Nreg = 0x10,
42: };
43:
44: /*
45: * Lower 2-bits of indirect DAC register
46: * addressing.
47: */
48: static ushort dacxreg[4] = {
49: PaddrW, Pdata, Pixmask, PaddrR
50: };
51:
52: static uchar
53: bt485io(uchar reg)
54: {
55: uchar crt55, cr0;
56:
57: crt55 = vgaxi(Crtx, 0x55) & 0xFC;
58: if((reg & 0x0F) == Status){
59: /*
60: * 1,2: Set indirect addressing for Status or
61: * Cmd3 - set bit7 of Cr0.
62: */
63: vgaxo(Crtx, 0x55, crt55|((Cmd0>>2) & 0x03));
64: cr0 = vgai(dacxreg[Cmd0 & 0x03])|0x80;
65: vgao(dacxreg[Cmd0 & 0x03], cr0);
66:
67: /*
68: * 3,4: Set the index into the Write register,
69: * index == 0x00 for Status, 0x01 for Cmd3.
70: */
71: vgaxo(Crtx, 0x55, crt55|((AddrW>>2) & 0x03));
72: vgao(dacxreg[AddrW & 0x03], (reg == Status) ? 0x00: 0x01);
73:
74: /*
75: * 5,6: Get the contents of the appropriate
76: * register at 0x0A.
77: */
78: }
79:
80: return crt55;
81: }
82:
83: static uchar
84: bt485i(uchar reg)
85: {
86: uchar crt55, r;
87:
88: crt55 = bt485io(reg);
89: vgaxo(Crtx, 0x55, crt55|((reg>>2) & 0x03));
90: r = vgai(dacxreg[reg & 0x03]);
91: vgaxo(Crtx, 0x55, crt55);
92:
93: return r;
94: }
95:
96: static void
97: bt485o(uchar reg, uchar data)
98: {
99: uchar crt55;
100:
101: crt55 = bt485io(reg);
102: vgaxo(Crtx, 0x55, crt55|((reg>>2) & 0x03));
103: vgao(dacxreg[reg & 0x03], data);
104: vgaxo(Crtx, 0x55, crt55);
105: }
106:
107: static Point hotpoint;
108:
109: static void
110: load(Cursor *c)
111: {
112: uchar r;
113: int x, y;
114: uchar clr[2*16], set[2*16];
115:
116:
117: lock(&palettelock);
118:
119: /*
120: * Turn cursor off;
121: * put cursor into 64x64x2 mode and clear MSBs of address;
122: * clear LSBs of address;
123: */
124: r = bt485i(Cmd2) & 0xFC;
125: bt485o(Cmd2, r);
126:
127: r = (bt485i(Cmd3) & 0xFC)|0x04;
128: bt485o(Cmd3, r);
129:
130: bt485o(AddrW, 0x00);
131:
132: /*
133: * Now load the cursor RAM array, both planes.
134: * The cursor is 16x16, the array 64x64; put
135: * the cursor in the top left. The 0,0 cursor
136: * point is bottom-right, so positioning will
137: * have to take that into account.
138: */
139: memmove(clr, c->clr, sizeof(clr));
140: pixreverse(clr, sizeof(clr), 0);
141: memmove(set, c->set, sizeof(set));
142: pixreverse(set, sizeof(set), 0);
143: for(y = 0; y < 64; y++){
144: for(x = 0; x < 64/8; x++){
145: if(x < 16/8 && y < 16)
146: bt485o(Cram, clr[x+y*2]);
147: else
148: bt485o(Cram, 0x00);
149: }
150: }
151: for(y = 0; y < 64; y++){
152: for(x = 0; x < 64/8; x++){
153: if(x < 16/8 && y < 16)
154: bt485o(Cram, set[x+y*2]);
155: else
156: bt485o(Cram, 0x00);
157: }
158: }
159:
160: /*
161: * Initialise the cursor hot-point
162: * and enable the cursor.
163: */
164: hotpoint.x = 64+c->offset.x;
165: hotpoint.y = 64+c->offset.y;
166:
167: r = (bt485i(Cmd2) & 0xFC)|0x01;
168: bt485o(Cmd2, r);
169:
170: unlock(&palettelock);
171: }
172:
173: static void
174: enable(void)
175: {
176: uchar r;
177:
178: lock(&palettelock);
179:
180: /*
181: * Turn cursor off.
182: */
183: r = bt485i(Cmd2) & 0xFC;
184: bt485o(Cmd2, r);
185:
186: /*
187: * Overscan colour,
188: * cursor colour 1 (white),
189: * cursor colour 2, 3 (black).
190: */
191: bt485o(ColorW, 0x00);
192: bt485o(Color, 0xFF); bt485o(Color, 0xFF); bt485o(Color, 0xFF);
193:
194: bt485o(Color, 0xFF); bt485o(Color, 0xFF); bt485o(Color, 0xFF);
195:
196: bt485o(Color, 0x00); bt485o(Color, 0x00); bt485o(Color, 0x00);
197: bt485o(Color, 0x00); bt485o(Color, 0x00); bt485o(Color, 0x00);
198:
199: unlock(&palettelock);
200:
201: /*
202: * Finally, enable
203: * the hardware cursor external operation mode;
204: * cursor control enable for Bt485 DAC.
205: * The #9GXE cards seem to need the 86C928 Bt485 support
206: * enabled in order to work at all in enhanced mode.
207: */
208:
209: r = vgaxi(Crtx, 0x55)|0x20;
210: vgaxo(Crtx, 0x55, r);
211:
212: r = vgaxi(Crtx, 0x45)|0x20;
213: vgaxo(Crtx, 0x45, r);
214: }
215:
216: static int
217: move(Point p)
218: {
219: int x, y;
220:
221: if(canlock(&palettelock) == 0)
222: return 1;
223:
224: x = p.x+hotpoint.x;
225: y = p.y+hotpoint.y;
226:
227: bt485o(Cxlr, x & 0xFF);
228: bt485o(Cxhr, (x>>8) & 0x0F);
229: bt485o(Cylr, y & 0xFF);
230: bt485o(Cyhr, (y>>8) & 0x0F);
231:
232: unlock(&palettelock);
233: return 0;
234: }
235:
236: static void
237: disable(void)
238: {
239: uchar r;
240:
241: /*
242: * Disable
243: * cursor mode 3;
244: * cursor control enable for Bt485 DAC;
245: * the hardware cursor external operation mode.
246: */
247: lock(&palettelock);
248: r = bt485i(Cmd2) & ~0x03;
249: bt485o(Cmd2, r);
250: unlock(&palettelock);
251:
252: r = vgaxi(Crtx, 0x45) & ~0x20;
253: vgaxo(Crtx, 0x45, r);
254:
255: r = vgaxi(Crtx, 0x55) & ~0x20;
256: vgaxo(Crtx, 0x55, r);
257: }
258:
259: static Hwgc bt485hwgc = {
260: "bt485hwgc",
261: enable,
262: load,
263: move,
264: disable,
265:
266: 0,
267: };
268:
269: void
270: vgabt485link(void)
271: {
272: addhwgclink(&bt485hwgc);
273: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.