Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_posix/sys/src/cmd/aux/vga/tvp3020.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
#include <bio.h>
4
 
5
#include "pci.h"
6
#include "vga.h"
7
 
8
/*
9
 * Tvp302[056] Viewpoint Video Interface Palette.
10
 * Assumes hooked up to an S3 86C928 or S3 Vision964.
11
 */
12
enum {
13
	Index		= 0x06,		/* Index register */
14
	Data		= 0x07,		/* Data register */
15
 
16
	Id		= 0x3F,		/* ID Register */
17
	Tvp3020		= 0x20,
18
	Tvp3025		= 0x25,
19
	Tvp3026		= 0x26,
20
};
21
 
22
/*
23
 * The following two arrays give read (bit 0) and write (bit 1)
24
 * permissions on the direct and index registers. Bits 4 and 5
25
 * are for the Tvp3025. The Tvp3020 has only 8 direct registers.
26
 */
27
static uchar directreg[32] = {
28
	0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x33, 0x33,
29
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
30
	0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
31
	0x33, 0x33, 0x11, 0x33, 0x33, 0x33, 0x33, 0x33,
32
};
33
 
34
static uchar indexreg[64] = {
35
	0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x00,
36
	0x02, 0x02, 0x33, 0x00, 0x00, 0x00, 0x30, 0x30,
37
	0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
38
	0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x30, 0x00,
39
	0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
40
	0x33, 0x33, 0x33, 0x33, 0x30, 0x30, 0x30, 0x30,
41
	0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
42
	0x33, 0x30, 0x33, 0x11, 0x11, 0x11, 0x22, 0x11,
43
};
44
 
45
/*
46
 * Check the index register access is valid.
47
 * Return the number of direct registers.
48
 */
49
static uchar
50
checkindex(uchar index, uchar access)
51
{
52
	uchar crt55;
53
	static uchar id;
54
 
55
	if(id == 0){
56
		crt55 = vgaxi(Crtx, 0x55) & 0xFC;
57
		vgaxo(Crtx, 0x55, crt55|((Index>>2) & 0x03));
58
		vgao(dacxreg[Index & 0x03], Id);
59
 
60
		id = vgai(dacxreg[Data & 0x03]);
61
		vgaxo(Crtx, 0x55, crt55);
62
	}
63
 
64
	if(index == 0xFF)
65
		return id;
66
 
67
	access &= 0x03;
68
	switch(id){
69
 
70
	case Tvp3020:
71
		break;
72
 
73
	case Tvp3025:
74
	case Tvp3026:
75
		access = access<<4;
76
		break;
77
 
78
	default:
79
		Bprint(&stdout, "%s: unknown chip id - 0x%2.2X\n", tvp3020.name, id);
80
		break;
81
	}
82
 
83
	if(index > sizeof(indexreg) || (indexreg[index] & access) == 0)
84
		error("%s: bad register index - 0x%2.2X\n", tvp3020.name, index);
85
 
86
	return id;
87
}
88
 
89
static uchar
90
tvp3020io(uchar reg, uchar data)
91
{
92
	uchar crt55;
93
 
94
	crt55 = vgaxi(Crtx, 0x55) & 0xFC;
95
	vgaxo(Crtx, 0x55, crt55|((reg>>2) & 0x03));
96
	vgao(dacxreg[reg & 0x03], data);
97
 
98
	return crt55;
99
}
100
 
101
uchar
102
tvp3020i(uchar reg)
103
{
104
	uchar crt55, r;
105
 
106
	crt55 = vgaxi(Crtx, 0x55) & 0xFC;
107
	vgaxo(Crtx, 0x55, crt55|((reg>>2) & 0x03));
108
	r = vgai(dacxreg[reg & 0x03]);
109
	vgaxo(Crtx, 0x55, crt55);
110
 
111
	return r;
112
}
113
 
114
uchar
115
tvp3020xi(uchar index)
116
{
117
	uchar crt55, r;
118
 
119
	checkindex(index, 0x01);
120
 
121
	crt55 = tvp3020io(Index, index);
122
	r = vgai(dacxreg[Data & 0x03]);
123
	vgaxo(Crtx, 0x55, crt55);
124
 
125
	return r;
126
}
127
 
128
void
129
tvp3020o(uchar reg, uchar data)
130
{
131
	uchar crt55;
132
 
133
	crt55 = tvp3020io(reg, data);
134
	vgaxo(Crtx, 0x55, crt55);
135
}
136
 
137
void
138
tvp3020xo(uchar index, uchar data)
139
{
140
	uchar crt55;
141
 
142
	checkindex(index, 0x02);
143
 
144
	crt55 = tvp3020io(Index, index);
145
	vgao(dacxreg[Data & 0x03], data);
146
	vgaxo(Crtx, 0x55, crt55);
147
}
148
 
149
static void
150
options(Vga*, Ctlr* ctlr)
151
{
152
	ctlr->flag |= Hclk2|Hextsid|Hpvram|Henhanced|Foptions;
153
}
154
 
155
static void
156
init(Vga* vga, Ctlr* ctlr)
157
{
158
	ulong grade;
159
	char *p;
160
 
161
	/*
162
	 * Work out the part speed-grade from name. Name can have,
163
	 * e.g. '-135' on the end  for 135MHz part.
164
	 */
165
	grade = 110000000;
166
	if(p = strrchr(ctlr->name, '-'))
167
		grade = strtoul(p+1, 0, 0) * 1000000;
168
 
169
	/*
170
	 * If we don't already have a desired pclk,
171
	 * take it from the mode.
172
	 * Check it's within range.
173
	 */
174
	if(vga->f[0] == 0)
175
		vga->f[0] = vga->mode->frequency;
176
	if(vga->f[0] > grade)
177
		error("%s: invalid pclk - %ld\n", ctlr->name, vga->f[0]);
178
 
179
	/*
180
	 * Determine whether to use clock-doubler or not.
181
	 */
182
	if(vga->f[0] > 85000000){
183
		vga->f[0] /= 2;
184
		resyncinit(vga, ctlr, Uclk2, 0);
185
	}
186
 
187
	ctlr->flag |= Finit;
188
}
189
 
190
static void
191
load(Vga* vga, Ctlr* ctlr)
192
{
193
	uchar x;
194
 
195
	/*
196
	 * Input Clock Selection:
197
	 *	VGA		CLK0
198
	 * 	enhanced	CLK1
199
	 * doubled if necessary.
200
	 */
201
	x = 0x00;
202
	if(ctlr->flag & Uenhanced)
203
		x |= 0x01;
204
	if(ctlr->flag & Uclk2)
205
		x |= 0x10;
206
	tvp3020xo(0x1A, x);
207
 
208
	/*
209
	 * Output Clock Selection:
210
	 *	VGA		default VGA
211
	 *	enhanced	RCLK=SCLK=/8, VCLK/4
212
	 */
213
	x = 0x3E;
214
	if(ctlr->flag & Uenhanced)
215
		x = 0x53;
216
	tvp3020xo(0x1B, x);
217
 
218
	/*
219
	 * Auxiliary Control:
220
	 *	default settings - self-clocked, palette graphics, no zoom
221
	 * Colour Key Control:
222
	 *	default settings - pointing to palette graphics
223
	 * Mux Control Register 1:
224
	 *	pseudo colour
225
	 */
226
	tvp3020xo(0x29, 0x09);
227
	tvp3020xo(0x38, 0x10);
228
	tvp3020xo(0x18, 0x80);
229
 
230
	/*
231
	 * Mux Control Register 2:
232
	 *	VGA		default VGA
233
	 *	enhanced	8-bpp, 8:1 mux, 64-bit pixel-bus width
234
	 */
235
	x = 0x98;
236
	if(ctlr->flag & Uenhanced){
237
		if(vga->mode->z == 8)
238
			x = 0x1C;
239
		else if(vga->mode->z == 1)
240
			x = 0x04;
241
	}
242
	tvp3020xo(0x19, x);
243
 
244
	/*
245
	 * General Control:
246
	 *	output sync polarity
247
	 * It's important to set this properly and to turn off the
248
	 * VGA controller H and V syncs. Can't be set in VGA mode.
249
	 */
250
	x = 0x00;
251
	if((vga->misc & 0x40) == 0)
252
		x |= 0x01;
253
	if((vga->misc & 0x80) == 0)
254
		x |= 0x02;
255
	tvp3020xo(0x1D, x);
256
	vga->misc |= 0xC0;
257
	vgao(MiscW, vga->misc);
258
 
259
	/*
260
	 * Select the DAC via the General Purpose I/O
261
	 * Register and Pins.
262
	 * Guesswork by looking at register dumps.
263
	 */
264
	tvp3020xo(0x2A, 0x1F);
265
	if(ctlr->flag & Uenhanced)
266
		x = 0x1D;
267
	else
268
		x = 0x1C;
269
	tvp3020xo(0x2B, x);
270
 
271
	ctlr->flag |= Fload;
272
}
273
 
274
static void
275
dump(Vga*, Ctlr* ctlr)
276
{
277
	uchar access;
278
	int i;
279
 
280
	access = 0x01;
281
	if(checkindex(0x00, 0x01) != Tvp3020)
282
		access <<= 4;
283
 
284
	printitem(ctlr->name, "direct");
285
	for(i = 0; i < 8; i++){
286
		if(directreg[i] & access)
287
			printreg(tvp3020i(i));
288
		else
289
			printreg(0xFF);
290
	}
291
 
292
	printitem(ctlr->name, "index");
293
	for(i = 0; i < sizeof(indexreg); i++){
294
		if(indexreg[i] & access)
295
			printreg(tvp3020xi(i));
296
		else
297
			printreg(0xFF);
298
	}
299
}
300
 
301
Ctlr tvp3020 = {
302
	"tvp3020",			/* name */
303
	0,				/* snarf */
304
	options,			/* options */
305
	init,				/* init */
306
	load,				/* load */
307
	dump,				/* dump */
308
};