|
|
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 Cursor curcursor;
14:
15: /*
16: * TVP3020 Viewpoint Video Interface Pallette.
17: * Assumes hooked up to an S3 86C928.
18: */
19: enum {
20: AddrW = 0x00, /* Palette address register - write mode */
21: Palette = 0x01, /* Color palette holding register */
22: Pmask = 0x02, /* Pixel read mask */
23: AddrR = 0x03, /* Palette address register - read mode */
24:
25: Index = 0x06, /* Index register */
26: Data = 0x07, /* Data register */
27: };
28:
29: /*
30: * Lower 2-bits of indirect DAC register
31: * addressing.
32: */
33: static ushort dacxreg[4] = {
34: PaddrW, Pdata, Pixmask, PaddrR
35: };
36:
37: static uchar
38: tvp3020io(uchar reg, uchar data)
39: {
40: uchar crt55;
41:
42: crt55 = vgaxi(Crtx, 0x55) & 0xFC;
43: vgaxo(Crtx, 0x55, crt55|((reg>>2) & 0x03));
44: vgao(dacxreg[reg & 0x03], data);
45:
46: return crt55;
47: }
48:
49: static void
50: tvp3020xo(uchar index, uchar data)
51: {
52: uchar crt55;
53:
54: crt55 = tvp3020io(Index, index);
55: vgao(dacxreg[Data & 0x03], data);
56: vgaxo(Crtx, 0x55, crt55);
57: }
58:
59: static void
60: load(Cursor *c)
61: {
62: uchar p, p0, p1;
63: int x, y;
64: uchar clr[2*16], set[2*16];
65:
66: /*
67: * Lock the DAC registers so we can update the
68: * cursor bitmap if necessary.
69: * If it's the same as the last cursor we loaded,
70: * just make sure it's enabled.
71: */
72: lock(&palettelock);
73: #ifdef notdef
74: if(memcmp(c, &curcursor, sizeof(Cursor)) == 0){
75: tvp3020xo(0x06, 0x40|0x10); /* Cursor Control Register */
76: unlock(&palettelock);
77: return;
78: }
79: memmove(&curcursor, c, sizeof(Cursor));
80: #endif /* notdef */
81:
82: /*
83: * Make sure cursor is off by initialising the cursor
84: * control to defaults + X-Windows cursor mode.
85: */
86: tvp3020xo(0x06, 0x10); /* Cursor Control Register */
87:
88: /*
89: * Initialise the cursor RAM LS and MS address
90: * (LS must be first).
91: */
92: tvp3020xo(0x08, 0x00); /* Cursor RAM LS Address */
93: tvp3020xo(0x09, 0x00); /* Cursor RAM MS Address */
94:
95: /*
96: * Initialise the 64x64 cursor RAM array. There are 2 planes,
97: * p0 and p1. Data is written 4 pixels per byte, with p1 the
98: * MS bit of each pixel.
99: * The cursor is set in X-Windows mode which gives the following
100: * truth table:
101: * p1 p0 colour
102: * 0 0 underlying pixel colour
103: * 0 1 underlying pixel colour
104: * 1 0 cursor colour 1
105: * 1 1 cursor colour 2
106: * Put the cursor into the top-left of the 64x64 array.
107: */
108: memmove(clr, c->clr, sizeof(clr));
109: pixreverse(clr, sizeof(clr), 0);
110: memmove(set, c->set, sizeof(set));
111: pixreverse(set, sizeof(set), 0);
112: for(y = 0; y < 64; y++){
113: for(x = 0; x < 64/8; x++){
114: if(x < 16/8 && y < 16){
115: p0 = clr[x+y*2];
116: p1 = set[x+y*2];
117:
118: p = 0x00;
119: if(p1 & 0x10)
120: p |= 0x03;
121: else if(p0 & 0x10)
122: p |= 0x02;
123: if(p1 & 0x20)
124: p |= 0x0C;
125: else if(p0 & 0x20)
126: p |= 0x08;
127: if(p1 & 0x40)
128: p |= 0x30;
129: else if(p0 & 0x40)
130: p |= 0x20;
131: if(p1 & 0x80)
132: p |= 0xC0;
133: else if(p0 & 0x80)
134: p |= 0x80;
135: tvp3020xo(0x0A, p); /* Cursor RAM Data */
136:
137: p = 0x00;
138: if(p1 & 0x01)
139: p |= 0x03;
140: else if(p0 & 0x01)
141: p |= 0x02;
142: if(p1 & 0x02)
143: p |= 0x0C;
144: else if(p0 & 0x02)
145: p |= 0x08;
146: if(p1 & 0x04)
147: p |= 0x30;
148: else if(p0 & 0x04)
149: p |= 0x20;
150: if(p1 & 0x08)
151: p |= 0xC0;
152: else if(p0 & 0x08)
153: p |= 0x80;
154: tvp3020xo(0x0A, p); /* Cursor RAM Data */
155: }
156: else{
157: tvp3020xo(0x0A, 0x00); /* Cursor RAM Data */
158: tvp3020xo(0x0A, 0x00);
159: }
160: }
161: }
162:
163: /*
164: * Initialise the cursor hot-point
165: * and enable the cursor.
166: */
167: tvp3020xo(0x04, -c->offset.x); /* Sprite Origin X */
168: tvp3020xo(0x05, -c->offset.y); /* Sprite Origin Y */
169:
170: tvp3020xo(0x06, 0x40|0x10); /* Cursor Control Register */
171:
172: unlock(&palettelock);
173: }
174:
175: static void
176: enable(void)
177: {
178: uchar r;
179:
180: lock(&palettelock);
181:
182: /*
183: * Make sure cursor is off by initialising the cursor
184: * control to defaults + X-Windows cursor mode.
185: */
186: tvp3020xo(0x06, 0x10); /* Cursor Control Register */
187:
188: /*
189: * Overscan colour,
190: * cursor colour 1 (white),
191: * cursor colour 2 (black).
192: */
193: tvp3020xo(0x20, 0x00); tvp3020xo(0x21, 0x00); tvp3020xo(0x22, 0x00);
194: tvp3020xo(0x23, 0x00); tvp3020xo(0x24, 0x00); tvp3020xo(0x25, 0x00);
195: tvp3020xo(0x26, 0xFF); tvp3020xo(0x27, 0xFF); tvp3020xo(0x28, 0xFF);
196:
197: unlock(&palettelock);
198:
199: /*
200: * Finally, enable
201: * the hardware cursor external operation mode;
202: * cursor control enable for Bt485 DAC (!).
203: */
204: r = vgaxi(Crtx, 0x55)|0x20;
205: vgaxo(Crtx, 0x55, r);
206:
207: r = vgaxi(Crtx, 0x45)|0x20;
208: vgaxo(Crtx, 0x45, r);
209: }
210:
211: static int
212: move(Point p)
213: {
214: if(canlock(&palettelock) == 0)
215: return 1;
216:
217: tvp3020xo(0x00, p.x & 0xFF); /* Cursor Position X LSB */
218: tvp3020xo(0x01, (p.x>>8) & 0x0F); /* Cursor Position X MSB */
219: tvp3020xo(0x02, p.y & 0xFF); /* Cursor Position Y LSB */
220: tvp3020xo(0x03, (p.y>>8) & 0x0F); /* Cursor Position Y MSB */
221:
222: unlock(&palettelock);
223: return 0;
224: }
225:
226: static void
227: disable(void)
228: {
229: uchar r;
230:
231: /*
232: * Disable
233: * cursor;
234: * cursor control enable for Bt485 DAC (!);
235: * the hardware cursor external operation mode.
236: */
237: lock(&palettelock);
238: tvp3020xo(0x06, 0x10); /* Cursor Control Register */
239: unlock(&palettelock);
240:
241: r = vgaxi(Crtx, 0x45) & ~0x20;
242: vgaxo(Crtx, 0x45, r);
243:
244: r = vgaxi(Crtx, 0x55) & ~0x20;
245: vgaxo(Crtx, 0x55, r);
246: }
247:
248: static Hwgc tvp3020hwgc = {
249: "tvp3020hwgc",
250: enable,
251: load,
252: move,
253: disable,
254:
255: 0,
256: };
257:
258: void
259: vgatvp3020link(void)
260: {
261: addhwgclink(&tvp3020hwgc);
262: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.