Subversion Repositories planix.SVN

Rev

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
 * Tseng Labs Inc. ET4000 Video Controller.
10
 */
11
enum {
12
	Crtcbx		= 0x217A,	/* Secondary CRT controller */
13
 
14
	Sprite		= 0xE0,
15
	NSprite		= 0x10,
16
 
17
	Ima		= 0xF0,
18
	NIma		= 0x08,
19
};
20
 
21
static void
22
setkey(void)
23
{
24
	outportb(0x3BF, 0x03);
25
	outportb(0x3D8, 0xA0);
26
	outportb(0x3CD, 0x00);
27
}
28
 
29
static void
30
snarf(Vga* vga, Ctlr* ctlr)
31
{
32
	int i;
33
 
34
	setkey();
35
 
36
	vga->sequencer[0x06] = vgaxi(Seqx, 0x06);
37
	vga->sequencer[0x07] = vgaxi(Seqx, 0x07);
38
 
39
	for(i = 0x30; i < 0x38; i++)
40
		vga->crt[i] = vgaxi(Crtx, i);
41
	vga->crt[0x3F] = vgaxi(Crtx, 0x3F);
42
 
43
	vga->attribute[0x16] = vgaxi(Attrx, 0x16);
44
	vga->attribute[0x17] = vgaxi(Attrx, 0x17);
45
 
46
	/*
47
	 * Memory size.
48
	 */
49
	switch(vga->crt[0x37] & 0x03){
50
 
51
	case 1:
52
		vga->vmz = 256*1024;
53
		break;
54
 
55
	case 2:
56
		vga->vmz = 512*1024;
57
		break;
58
 
59
	case 3:
60
		vga->vmz = 1024*1024;
61
		break;
62
	}
63
	if(strncmp(ctlr->name, "et4000-w32", 10) == 0){
64
		if(vga->crt[0x32] & 0x80)
65
			vga->vmz *= 2;
66
	}
67
	else if(vga->crt[0x37] & 0x80)
68
		vga->vmz *= 2;
69
 
70
	ctlr->flag |= Fsnarf;
71
}
72
 
73
static void
74
options(Vga* vga, Ctlr* ctlr)
75
{
76
	/*
77
	 * The ET4000 does not need to have the vertical
78
	 * timing values divided by 2 for interlace mode.
79
	 */
80
	if(vga->mode->interlace == 'v')
81
		vga->mode->interlace = 'V';
82
 
83
	if(strncmp(ctlr->name, "et4000-w32", 10) == 0)
84
		ctlr->flag |= Hpclk2x8;
85
 
86
	ctlr->flag |= Hclkdiv|Foptions;
87
}
88
 
89
static void
90
init(Vga* vga, Ctlr* ctlr)
91
{
92
	Mode *mode;
93
	ulong x;
94
 
95
	if(vga->mode->z > 8)
96
		error("depth %d not supported\n", vga->mode->z);
97
 
98
	if(ctlr->flag & Upclk2x8){
99
		mode = vga->mode;
100
		vga->crt[0x00] = ((mode->ht/2)>>3)-5;
101
		vga->crt[0x01] = ((mode->x/2)>>3)-1;
102
		vga->crt[0x02] = ((mode->shb/2)>>3)-1;
103
 
104
		x = (mode->ehb/2)>>3;
105
		vga->crt[0x03] = 0x80|(x & 0x1F);
106
		vga->crt[0x04] = (mode->shs/2)>>3;
107
		vga->crt[0x05] = ((mode->ehs/2)>>3) & 0x1F;
108
		if(x & 0x20)
109
			vga->crt[0x05] |= 0x80;
110
	}
111
	/*
112
	 * Itth a mythtawee.
113
	 */
114
	if(vga->crt[0x14] & 0x20)
115
		vga->crt[0x17] |= 0x08;
116
	vga->crt[0x17] &= ~0x20;
117
 
118
	vga->crt[0x30] = 0x00;
119
	vga->crt[0x33] = 0x00;
120
 
121
	/*
122
	 * Overflow High.
123
	 */
124
	vga->crt[0x35] = 0x00;
125
	if(vga->crt[0x15] & 0x400)
126
		vga->crt[0x35] |= 0x01;
127
	if(vga->crt[0x06] & 0x400)
128
		vga->crt[0x35] |= 0x02;
129
	if(vga->crt[0x12] & 0x400)
130
		vga->crt[0x35] |= 0x04;
131
	if(vga->crt[0x10] & 0x400)
132
		vga->crt[0x35] |= 0x08;
133
	if(vga->crt[0x18] & 0x400)
134
		vga->crt[0x35] |= 0x10;
135
	if(vga->mode->interlace == 'V')
136
		vga->crt[0x35] |= 0x80;
137
 
138
	/*
139
	 * Horizontal Overflow.
140
	 */
141
	vga->crt[0x3F] = 0x00;
142
	if(vga->crt[0x00] & 0x100)
143
		vga->crt[0x3F] |= 0x01;
144
	if(vga->crt[0x02] & 0x100)
145
		vga->crt[0x3F] |= 0x04;
146
	if(vga->crt[0x04] & 0x100)
147
		vga->crt[0x3F] |= 0x10;
148
	if(vga->crt[0x13] & 0x100)
149
		vga->crt[0x3F] |= 0x80;
150
 
151
	/*
152
	 * Turn off MMU buffers, linear map
153
	 * and memory-mapped registers.
154
	 */
155
	vga->crt[0x36] &= ~0x38;
156
 
157
	if(strncmp(ctlr->name, "et4000-w32", 10) == 0)
158
		vga->crt[0x37] |= 0x80;
159
 
160
	vga->sequencer[0x06] = 0x00;
161
 
162
	/*
163
	 * Clock select.
164
	 */
165
	if(vga->f[0] > 86000000)
166
		error("%s: invalid pclk - %ld\n", ctlr->name, vga->f[0]);
167
	vga->misc &= ~0x0C;
168
	vga->misc |= (vga->i[0] & 0x03)<<2;
169
	if(vga->i[0] & 0x04)
170
		vga->crt[0x34] |= 0x02;
171
	else
172
		vga->crt[0x34] &= ~0x02;
173
	vga->crt[0x31] &= ~0xC0;
174
	vga->crt[0x31] |= (vga->i[0] & 0x18)<<3;
175
 
176
	vga->sequencer[0x07] &= ~0x41;
177
	if(vga->d[0] == 4)
178
		vga->sequencer[0x07] |= 0x01;
179
	else if(vga->d[0] == 2)
180
		vga->sequencer[0x07] |= 0x40;
181
 
182
	vga->attribute[0x10] &= ~0x40;
183
	vga->attribute[0x11] = Pblack;
184
	vga->attribute[0x16] = 0x80;
185
 
186
	if(ctlr->flag & Upclk2x8)
187
		vga->attribute[0x16] |= 0x20;
188
 
189
	ctlr->flag |= Finit;
190
}
191
 
192
static void
193
load(Vga* vga, Ctlr* ctlr)
194
{
195
	vgaxo(Crtx, 0x30, vga->crt[0x30]);
196
	vgaxo(Crtx, 0x31, vga->crt[0x31]);
197
	vgaxo(Crtx, 0x33, vga->crt[0x33]);
198
	vgaxo(Crtx, 0x34, vga->crt[0x34]);
199
	vgaxo(Crtx, 0x35, vga->crt[0x35]);
200
	vgaxo(Crtx, 0x36, vga->crt[0x36]);
201
	vgaxo(Crtx, 0x37, vga->crt[0x37]);
202
	vgaxo(Crtx, 0x3F, vga->crt[0x3F]);
203
 
204
	vgaxo(Seqx, 0x06, vga->sequencer[0x06]);
205
	vgaxo(Seqx, 0x07, vga->sequencer[0x07]);
206
 
207
	vgaxo(Attrx, 0x16, vga->attribute[0x16]);
208
 
209
	ctlr->flag |= Fload;
210
}
211
 
212
static void
213
dump(Vga* vga, Ctlr* ctlr)
214
{
215
	int i;
216
	char *name;
217
	ushort shb, vrs, x;
218
 
219
	name = ctlr->name;
220
 
221
	printitem(name, "Seq06");
222
	printreg(vga->sequencer[0x06]);
223
	printreg(vga->sequencer[0x07]);
224
 
225
	printitem(name, "Crt30");
226
	for(i = 0x30; i < 0x38; i++)
227
		printreg(vga->crt[i]);
228
	printitem(name, "Crt3F");
229
	printreg(vga->crt[0x3F]);
230
 
231
	printitem(name, "Attr16");
232
	printreg(vga->attribute[0x16]);
233
	printreg(vga->attribute[0x17]);
234
 
235
	if(strncmp(name, "et4000-w32", 10) == 0){
236
		printitem(name, "SpriteE0");
237
		for(i = Sprite; i < Sprite+NSprite; i++){
238
			outportb(Crtcbx, i);
239
			printreg(inportb(Crtcbx+1));
240
		}
241
		printitem(name, "ImaF0");
242
		for(i = Ima; i < Ima+NIma; i++){
243
			outportb(Crtcbx, i);
244
			printreg(inportb(Crtcbx+1));
245
		}
246
	}
247
 
248
	/*
249
	 * Try to disassemble the snarfed values into
250
	 * understandable numbers.
251
	 * Only do this if we weren't called after Finit.
252
	 */
253
	if(ctlr->flag & Finit)
254
		return;
255
 
256
	x = (vga->crt[0x01]+1)<<3;
257
	printitem(name, "hde");
258
	printreg(x);
259
	Bprint(&stdout, "%6ud", x);
260
 
261
	shb = ((((vga->crt[0x3F] & 0x04)<<6)|vga->crt[0x02])+1)<<3;
262
	printitem(name, "shb");
263
	printreg(shb);
264
	Bprint(&stdout, "%6ud", shb);
265
 
266
	x = (((vga->crt[0x05] & 0x80)>>2)|(vga->crt[0x03] & 0x1F))<<3;
267
	printitem(name, "ehb");
268
	printreg(x);
269
	for(i = 0; x < shb; i++)
270
		x |= 0x200<<i;
271
	Bprint(&stdout, "%6ud", x);
272
 
273
	x = ((((vga->crt[0x3F] & 0x01)<<8)|vga->crt[0x00])+5)<<3;
274
	printitem(name, "ht");
275
	printreg(x);
276
	Bprint(&stdout, "%6ud", x);
277
 
278
	x = vga->crt[0x12];
279
	if(vga->crt[0x07] & 0x02)
280
		x |= 0x100;
281
	if(vga->crt[0x07] & 0x40)
282
		x |= 0x200;
283
	if(vga->crt[0x35] & 0x04)
284
		x |= 0x400;
285
	x += 1;
286
	printitem(name, "vde");
287
	printreg(x);
288
	Bprint(&stdout, "%6ud", x);
289
 
290
	vrs = vga->crt[0x10];
291
	if(vga->crt[0x07] & 0x04)
292
		vrs |= 0x100;
293
	if(vga->crt[0x07] & 0x80)
294
		vrs |= 0x200;
295
	if(vga->crt[0x35] & 0x08)
296
		vrs |= 0x400;
297
	printitem(name, "vrs");
298
	printreg(vrs);
299
	Bprint(&stdout, "%6ud", vrs);
300
 
301
	x = (vrs & ~0x0F)|(vga->crt[0x11] & 0x0F);
302
	printitem(name, "vre");
303
	printreg(x);
304
	Bprint(&stdout, "%6ud", x);
305
 
306
	x = vga->crt[0x06];
307
	if(vga->crt[0x07] & 0x01)
308
		x |= 0x100;
309
	if(vga->crt[0x07] & 0x20)
310
		x |= 0x200;
311
	if(vga->crt[0x35] & 0x02)
312
		x |= 0x400;
313
	x += 2;
314
	printitem(name, "vt");
315
	printreg(x);
316
	Bprint(&stdout, "%6ud", x);
317
 
318
	printitem(name, "d i");
319
	if(vga->sequencer[0x07] & 0x01)
320
		x = 4;
321
	else if(vga->sequencer[0x07] & 0x40)
322
		x = 2;
323
	else
324
		x = 0;
325
	Bprint(&stdout, "%9ud", x);
326
	x = (vga->misc & 0x0C)>>2;
327
	if(vga->crt[0x34] & 0x02)
328
		x |= 0x04;
329
	x |= (vga->crt[0x31] & 0xC0)>>3;
330
	Bprint(&stdout, "%8ud\n", x);
331
}
332
 
333
Ctlr et4000 = {
334
	"et4000",			/* name */
335
	snarf,				/* snarf */
336
	options,			/* options */
337
	init,				/* init */
338
	load,				/* load */
339
	dump,				/* dump */
340
};