Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | 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
 * ARK Logic ARK2000PV GUI accelerator.
10
 */
11
static void
12
snarf(Vga* vga, Ctlr* ctlr)
13
{
14
	int i;
15
 
16
	/*
17
	 * Unlock access to the extended I/O registers.
18
	 */
19
	vgaxo(Seqx, 0x1D, 0x01);
20
 
21
	for(i = 0x10; i < 0x2E; i++)
22
		vga->sequencer[i] = vgaxi(Seqx, i);
23
	for(i = 0x40; i < 0x47; i++)
24
		vga->crt[i] = vgaxi(Crtx, i);
25
	vga->crt[0x50] = vgaxi(Crtx, 0x50);
26
 
27
	/*
28
	 * A hidey-hole for the coprocessor status register.
29
	 */
30
	vga->crt[0xFF] = inportb(0x3CB);
31
 
32
	/*
33
	 * Memory size.
34
	 */
35
	switch((vga->sequencer[0x10]>>6) & 0x03){
36
 
37
	case 0x00:
38
		vga->vma = vga->vmz = 1*1024*1024;
39
		break;
40
 
41
	case 0x01:
42
		vga->vma = vga->vmz = 2*1024*1024;
43
		break;
44
 
45
	case 0x02:
46
		vga->vma = vga->vmz = 4*1024*1024;
47
		break;
48
	}
49
 
50
	ctlr->flag |= Fsnarf;
51
}
52
 
53
static void
54
options(Vga*, Ctlr* ctlr)
55
{
56
	ctlr->flag |= Hlinear|Hpclk2x8|Foptions;
57
}
58
 
59
static void
60
init(Vga* vga, Ctlr* ctlr)
61
{
62
	Mode *mode;
63
	ulong x;
64
 
65
	mode = vga->mode;
66
 
67
	vga->crt[0x46] = 0x00;
68
	if(ctlr->flag & Upclk2x8){
69
		vga->crt[0x00] = ((mode->ht/2)>>3)-5;
70
		vga->crt[0x01] = ((mode->x/2)>>3)-1;
71
		vga->crt[0x02] = ((mode->shb/2)>>3)-1;
72
 
73
		x = (mode->ehb/2)>>3;
74
		vga->crt[0x03] = 0x80|(x & 0x1F);
75
		vga->crt[0x04] = (mode->shs/2)>>3;
76
		vga->crt[0x05] = ((mode->ehs/2)>>3) & 0x1F;
77
		if(x & 0x20)
78
			vga->crt[0x05] |= 0x80;
79
		vga->crt[0x13] = mode->x/8;
80
 
81
		vga->crt[0x46] |= 0x04;
82
	}
83
 
84
	/*
85
	 * Overflow bits.
86
	 */
87
	vga->crt[0x40] = 0x00;
88
	if(vga->crt[0x18] & 0x400)
89
		vga->crt[0x40] |= 0x08;
90
	if(vga->crt[0x10] & 0x400)
91
		vga->crt[0x40] |= 0x10;
92
	if(vga->crt[0x15] & 0x400)
93
		vga->crt[0x40] |= 0x20;
94
	if(vga->crt[0x12] & 0x400)
95
		vga->crt[0x40] |= 0x40;
96
	if(vga->crt[0x06] & 0x400)
97
		vga->crt[0x40] |= 0x80;
98
 
99
	vga->crt[0x41] = 0x00;
100
	if(vga->crt[0x13] & 0x100)
101
		vga->crt[0x41] |= 0x08;
102
	if(vga->crt[0x04] & 0x100)
103
		vga->crt[0x41] |= 0x10;
104
	if(vga->crt[0x02] & 0x100)
105
		vga->crt[0x41] |= 0x20;
106
	if(vga->crt[0x01] & 0x100)
107
		vga->crt[0x41] |= 0x40;
108
	if(vga->crt[0x00] & 0x100)
109
		vga->crt[0x41] |= 0x80;
110
 
111
	/*
112
	 * Interlace.
113
	 */
114
	vga->crt[0x42] = 0x00;
115
	vga->crt[0x44] = 0x00;
116
	if(mode->interlace){
117
		vga->crt[0x42] = vga->crt[0]/2;
118
		vga->crt[0x44] |= 0x04;
119
	}
120
	vga->crt[0x45] = 0x00;
121
 
122
	/*
123
	 * Memory configuration:
124
	 * enable linear|coprocessor|VESA modes;
125
	 * set aperture to 64Kb, 0xA0000;
126
	 * set aperture index 0.
127
	 * Bugs: 1024x768x1 doesn't work (aperture not set correctly?);
128
	 *	 hwgc doesn't work in 1-bit modes (hardware?).
129
	 */
130
	vga->sequencer[0x10] &= ~0x3F;
131
	vga->sequencer[0x11] &= ~0x0F;
132
	switch(mode->z){
133
 
134
	case 1:
135
		vga->sequencer[0x10] |= 0x03;
136
		vga->sequencer[0x11] |= 0x01;
137
		cflag = 1;
138
		break;
139
 
140
	case 8:
141
		vga->sequencer[0x10] |= 0x0F;
142
		vga->sequencer[0x11] |= 0x06;
143
		if(vga->linear && (ctlr->flag & Hlinear) && vga->vmz)
144
			ctlr->flag |= Ulinear;
145
		break;
146
 
147
	default:
148
		error("depth %d not supported\n", mode->z);
149
	}
150
	vga->sequencer[0x12] &= ~0x03;
151
	vga->sequencer[0x13] = 0x0A;
152
	vga->sequencer[0x14] = 0x00;
153
	vga->sequencer[0x15] = 0x00;
154
	vga->sequencer[0x16] = 0x00;
155
 
156
	/*
157
	 * Frame Buffer Pitch and FIFO control.
158
	 * Set the FIFO to 32 deep and refill trigger when
159
	 * 6 slots empty.
160
	 */
161
	vga->sequencer[0x17] = 0x00;
162
	vga->sequencer[0x18] = 0x13;
163
	if(mode->x <= 640)
164
		vga->sequencer[0x17] = 0x00;
165
	else if(mode->x <= 800)
166
		vga->sequencer[0x17] |= 0x01;
167
	else if(mode->x <= 1024)
168
		vga->sequencer[0x17] |= 0x02;
169
	else if(mode->x <= 1280)
170
		vga->sequencer[0x17] |= 0x04;
171
	else if(mode->x <= 1600)
172
		vga->sequencer[0x17] |= 0x05;
173
	else if(mode->x <= 2048)
174
		vga->sequencer[0x17] |= 0x06;
175
 
176
	/*
177
	 * Clock select.
178
	 */
179
	vga->misc &= ~0x0C;
180
	vga->misc |= (vga->i[0] & 0x03)<<2;
181
	vga->sequencer[0x11] &= ~0xC0;
182
	vga->sequencer[0x11] |= (vga->i[0] & 0x0C)<<4;
183
 
184
	vga->attribute[0x11] = 0x00;	/* color map entry for black */
185
 
186
	ctlr->flag |= Finit;
187
}
188
 
189
static void
190
load(Vga* vga, Ctlr* ctlr)
191
{
192
	ulong l;
193
 
194
	/*
195
	 * Ensure there are no glitches when selecting a new
196
	 * clock frequency.
197
	 * The sequencer toggle seems to matter on the Hercules
198
	 * Stingray 64/Video at 1280x1024x8. Without it the screen
199
	 * is fuzzy; a second load clears it up and there's no
200
	 * difference between the two register sets. A mystery.
201
	 */
202
	vgao(MiscW, vga->misc & ~0x0C);
203
	vgaxo(Seqx, 0x11, vga->sequencer[0x11]);
204
	vgao(MiscW, vga->misc);
205
	if(vga->ramdac && strncmp(vga->ramdac->name, "w30c516", 7) == 0){
206
		sequencer(vga, 1);
207
		sleep(500);
208
		sequencer(vga, 0);
209
	}
210
 
211
	if(ctlr->flag & Ulinear){
212
		vga->sequencer[0x10] |= 0x10;
213
		if(vga->vmz <= 1024*1024)
214
			vga->sequencer[0x12] |= 0x01;
215
		else if(vga->vmz <= 2*1024*1024)
216
			vga->sequencer[0x12] |= 0x02;
217
		else
218
			vga->sequencer[0x12] |= 0x03;
219
		l = vga->vmb>>16;
220
		vga->sequencer[0x13] = l & 0xFF;
221
		vga->sequencer[0x14] = (l>>8) & 0xFF;
222
	}
223
 
224
	vgaxo(Seqx, 0x10, vga->sequencer[0x10]);
225
	vgaxo(Seqx, 0x12, vga->sequencer[0x12]);
226
	vgaxo(Seqx, 0x13, vga->sequencer[0x13]);
227
	vgaxo(Seqx, 0x14, vga->sequencer[0x14]);
228
	vgaxo(Seqx, 0x15, vga->sequencer[0x15]);
229
	vgaxo(Seqx, 0x16, vga->sequencer[0x16]);
230
	vgaxo(Seqx, 0x17, vga->sequencer[0x17]);
231
	vgaxo(Seqx, 0x18, vga->sequencer[0x18]);
232
 
233
	vgaxo(Crtx, 0x40, vga->crt[0x40]);
234
	vgaxo(Crtx, 0x41, vga->crt[0x41]);
235
	vgaxo(Crtx, 0x42, vga->crt[0x42]);
236
	vgaxo(Crtx, 0x44, vga->crt[0x44]);
237
	vgaxo(Crtx, 0x45, vga->crt[0x45]);
238
	vgaxo(Crtx, 0x46, vga->crt[0x46]);
239
 
240
	ctlr->flag |= Fload;
241
}
242
 
243
static void
244
dump(Vga* vga, Ctlr* ctlr)
245
{
246
	int i;
247
 
248
	printitem(ctlr->name, "Seq10");
249
	for(i = 0x10; i < 0x2E; i++)
250
		printreg(vga->sequencer[i]);
251
	printitem(ctlr->name, "Crt40");
252
	for(i = 0x40; i < 0x47; i++)
253
		printreg(vga->crt[i]);
254
	printitem(ctlr->name, "Crt50");
255
	printreg(vga->crt[0x50]);
256
	printitem(ctlr->name, "Cop status");
257
	printreg(vga->crt[0xFF]);
258
}
259
 
260
Ctlr ark2000pv = {
261
	"ark2000pv",			/* name */
262
	snarf,				/* snarf */
263
	options,			/* options */
264
	init,				/* init */
265
	load,				/* load */
266
	dump,				/* dump */
267
};
268
 
269
Ctlr ark2000pvhwgc = {
270
	"ark2000pvhwgc",		/* name */
271
	0,				/* snarf */
272
	0,				/* options */
273
	0,				/* init */
274
	0,				/* load */
275
	0,				/* dump */
276
};