xref: /plan9/sys/src/cmd/aux/vga/ark2000pv.c (revision 9a747e4fd48b9f4522c70c07e8f882a15030f964)
17dd7cddfSDavid du Colombier #include <u.h>
27dd7cddfSDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <bio.h>
47dd7cddfSDavid du Colombier 
5*9a747e4fSDavid du Colombier #include "pci.h"
67dd7cddfSDavid du Colombier #include "vga.h"
77dd7cddfSDavid du Colombier 
87dd7cddfSDavid du Colombier /*
97dd7cddfSDavid du Colombier  * ARK Logic ARK2000PV GUI accelerator.
107dd7cddfSDavid du Colombier  */
117dd7cddfSDavid du Colombier static void
snarf(Vga * vga,Ctlr * ctlr)127dd7cddfSDavid du Colombier snarf(Vga* vga, Ctlr* ctlr)
137dd7cddfSDavid du Colombier {
147dd7cddfSDavid du Colombier 	int i;
157dd7cddfSDavid du Colombier 
167dd7cddfSDavid du Colombier 	/*
177dd7cddfSDavid du Colombier 	 * Unlock access to the extended I/O registers.
187dd7cddfSDavid du Colombier 	 */
197dd7cddfSDavid du Colombier 	vgaxo(Seqx, 0x1D, 0x01);
207dd7cddfSDavid du Colombier 
217dd7cddfSDavid du Colombier 	for(i = 0x10; i < 0x2E; i++)
227dd7cddfSDavid du Colombier 		vga->sequencer[i] = vgaxi(Seqx, i);
237dd7cddfSDavid du Colombier 	for(i = 0x40; i < 0x47; i++)
247dd7cddfSDavid du Colombier 		vga->crt[i] = vgaxi(Crtx, i);
257dd7cddfSDavid du Colombier 	vga->crt[0x50] = vgaxi(Crtx, 0x50);
267dd7cddfSDavid du Colombier 
277dd7cddfSDavid du Colombier 	/*
287dd7cddfSDavid du Colombier 	 * A hidey-hole for the coprocessor status register.
297dd7cddfSDavid du Colombier 	 */
307dd7cddfSDavid du Colombier 	vga->crt[0xFF] = inportb(0x3CB);
317dd7cddfSDavid du Colombier 
327dd7cddfSDavid du Colombier 	/*
337dd7cddfSDavid du Colombier 	 * Memory size.
347dd7cddfSDavid du Colombier 	 */
357dd7cddfSDavid du Colombier 	switch((vga->sequencer[0x10]>>6) & 0x03){
367dd7cddfSDavid du Colombier 
377dd7cddfSDavid du Colombier 	case 0x00:
387dd7cddfSDavid du Colombier 		vga->vma = vga->vmz = 1*1024*1024;
397dd7cddfSDavid du Colombier 		break;
407dd7cddfSDavid du Colombier 
417dd7cddfSDavid du Colombier 	case 0x01:
427dd7cddfSDavid du Colombier 		vga->vma = vga->vmz = 2*1024*1024;
437dd7cddfSDavid du Colombier 		break;
447dd7cddfSDavid du Colombier 
457dd7cddfSDavid du Colombier 	case 0x02:
467dd7cddfSDavid du Colombier 		vga->vma = vga->vmz = 4*1024*1024;
477dd7cddfSDavid du Colombier 		break;
487dd7cddfSDavid du Colombier 	}
497dd7cddfSDavid du Colombier 
507dd7cddfSDavid du Colombier 	ctlr->flag |= Fsnarf;
517dd7cddfSDavid du Colombier }
527dd7cddfSDavid du Colombier 
537dd7cddfSDavid du Colombier static void
options(Vga *,Ctlr * ctlr)547dd7cddfSDavid du Colombier options(Vga*, Ctlr* ctlr)
557dd7cddfSDavid du Colombier {
567dd7cddfSDavid du Colombier 	ctlr->flag |= Hlinear|Hpclk2x8|Foptions;
577dd7cddfSDavid du Colombier }
587dd7cddfSDavid du Colombier 
597dd7cddfSDavid du Colombier static void
init(Vga * vga,Ctlr * ctlr)607dd7cddfSDavid du Colombier init(Vga* vga, Ctlr* ctlr)
617dd7cddfSDavid du Colombier {
627dd7cddfSDavid du Colombier 	Mode *mode;
637dd7cddfSDavid du Colombier 	ulong x;
647dd7cddfSDavid du Colombier 
657dd7cddfSDavid du Colombier 	mode = vga->mode;
667dd7cddfSDavid du Colombier 
677dd7cddfSDavid du Colombier 	vga->crt[0x46] = 0x00;
687dd7cddfSDavid du Colombier 	if(ctlr->flag & Upclk2x8){
697dd7cddfSDavid du Colombier 		vga->crt[0x00] = ((mode->ht/2)>>3)-5;
707dd7cddfSDavid du Colombier 		vga->crt[0x01] = ((mode->x/2)>>3)-1;
717dd7cddfSDavid du Colombier 		vga->crt[0x02] = ((mode->shb/2)>>3)-1;
727dd7cddfSDavid du Colombier 
737dd7cddfSDavid du Colombier 		x = (mode->ehb/2)>>3;
747dd7cddfSDavid du Colombier 		vga->crt[0x03] = 0x80|(x & 0x1F);
757dd7cddfSDavid du Colombier 		vga->crt[0x04] = (mode->shs/2)>>3;
767dd7cddfSDavid du Colombier 		vga->crt[0x05] = ((mode->ehs/2)>>3) & 0x1F;
777dd7cddfSDavid du Colombier 		if(x & 0x20)
787dd7cddfSDavid du Colombier 			vga->crt[0x05] |= 0x80;
797dd7cddfSDavid du Colombier 		vga->crt[0x13] = mode->x/8;
807dd7cddfSDavid du Colombier 
817dd7cddfSDavid du Colombier 		vga->crt[0x46] |= 0x04;
827dd7cddfSDavid du Colombier 	}
837dd7cddfSDavid du Colombier 
847dd7cddfSDavid du Colombier 	/*
857dd7cddfSDavid du Colombier 	 * Overflow bits.
867dd7cddfSDavid du Colombier 	 */
877dd7cddfSDavid du Colombier 	vga->crt[0x40] = 0x00;
887dd7cddfSDavid du Colombier 	if(vga->crt[0x18] & 0x400)
897dd7cddfSDavid du Colombier 		vga->crt[0x40] |= 0x08;
907dd7cddfSDavid du Colombier 	if(vga->crt[0x10] & 0x400)
917dd7cddfSDavid du Colombier 		vga->crt[0x40] |= 0x10;
927dd7cddfSDavid du Colombier 	if(vga->crt[0x15] & 0x400)
937dd7cddfSDavid du Colombier 		vga->crt[0x40] |= 0x20;
947dd7cddfSDavid du Colombier 	if(vga->crt[0x12] & 0x400)
957dd7cddfSDavid du Colombier 		vga->crt[0x40] |= 0x40;
967dd7cddfSDavid du Colombier 	if(vga->crt[0x06] & 0x400)
977dd7cddfSDavid du Colombier 		vga->crt[0x40] |= 0x80;
987dd7cddfSDavid du Colombier 
997dd7cddfSDavid du Colombier 	vga->crt[0x41] = 0x00;
1007dd7cddfSDavid du Colombier 	if(vga->crt[0x13] & 0x100)
1017dd7cddfSDavid du Colombier 		vga->crt[0x41] |= 0x08;
1027dd7cddfSDavid du Colombier 	if(vga->crt[0x04] & 0x100)
1037dd7cddfSDavid du Colombier 		vga->crt[0x41] |= 0x10;
1047dd7cddfSDavid du Colombier 	if(vga->crt[0x02] & 0x100)
1057dd7cddfSDavid du Colombier 		vga->crt[0x41] |= 0x20;
1067dd7cddfSDavid du Colombier 	if(vga->crt[0x01] & 0x100)
1077dd7cddfSDavid du Colombier 		vga->crt[0x41] |= 0x40;
1087dd7cddfSDavid du Colombier 	if(vga->crt[0x00] & 0x100)
1097dd7cddfSDavid du Colombier 		vga->crt[0x41] |= 0x80;
1107dd7cddfSDavid du Colombier 
1117dd7cddfSDavid du Colombier 	/*
1127dd7cddfSDavid du Colombier 	 * Interlace.
1137dd7cddfSDavid du Colombier 	 */
1147dd7cddfSDavid du Colombier 	vga->crt[0x42] = 0x00;
1157dd7cddfSDavid du Colombier 	vga->crt[0x44] = 0x00;
1167dd7cddfSDavid du Colombier 	if(mode->interlace){
1177dd7cddfSDavid du Colombier 		vga->crt[0x42] = vga->crt[0]/2;
1187dd7cddfSDavid du Colombier 		vga->crt[0x44] |= 0x04;
1197dd7cddfSDavid du Colombier 	}
1207dd7cddfSDavid du Colombier 	vga->crt[0x45] = 0x00;
1217dd7cddfSDavid du Colombier 
1227dd7cddfSDavid du Colombier 	/*
1237dd7cddfSDavid du Colombier 	 * Memory configuration:
1247dd7cddfSDavid du Colombier 	 * enable linear|coprocessor|VESA modes;
1257dd7cddfSDavid du Colombier 	 * set aperture to 64Kb, 0xA0000;
1267dd7cddfSDavid du Colombier 	 * set aperture index 0.
1277dd7cddfSDavid du Colombier 	 * Bugs: 1024x768x1 doesn't work (aperture not set correctly?);
1287dd7cddfSDavid du Colombier 	 *	 hwgc doesn't work in 1-bit modes (hardware?).
1297dd7cddfSDavid du Colombier 	 */
1307dd7cddfSDavid du Colombier 	vga->sequencer[0x10] &= ~0x3F;
1317dd7cddfSDavid du Colombier 	vga->sequencer[0x11] &= ~0x0F;
1327dd7cddfSDavid du Colombier 	switch(mode->z){
1337dd7cddfSDavid du Colombier 
1347dd7cddfSDavid du Colombier 	case 1:
1357dd7cddfSDavid du Colombier 		vga->sequencer[0x10] |= 0x03;
1367dd7cddfSDavid du Colombier 		vga->sequencer[0x11] |= 0x01;
1377dd7cddfSDavid du Colombier 		cflag = 1;
1387dd7cddfSDavid du Colombier 		break;
1397dd7cddfSDavid du Colombier 
1407dd7cddfSDavid du Colombier 	case 8:
1417dd7cddfSDavid du Colombier 		vga->sequencer[0x10] |= 0x0F;
1427dd7cddfSDavid du Colombier 		vga->sequencer[0x11] |= 0x06;
1437dd7cddfSDavid du Colombier 		if(vga->linear && (ctlr->flag & Hlinear) && vga->vmz)
1447dd7cddfSDavid du Colombier 			ctlr->flag |= Ulinear;
1457dd7cddfSDavid du Colombier 		break;
1467dd7cddfSDavid du Colombier 
1477dd7cddfSDavid du Colombier 	default:
1487dd7cddfSDavid du Colombier 		error("depth %d not supported\n", mode->z);
1497dd7cddfSDavid du Colombier 	}
1507dd7cddfSDavid du Colombier 	vga->sequencer[0x12] &= ~0x03;
1517dd7cddfSDavid du Colombier 	vga->sequencer[0x13] = 0x0A;
1527dd7cddfSDavid du Colombier 	vga->sequencer[0x14] = 0x00;
1537dd7cddfSDavid du Colombier 	vga->sequencer[0x15] = 0x00;
1547dd7cddfSDavid du Colombier 	vga->sequencer[0x16] = 0x00;
1557dd7cddfSDavid du Colombier 
1567dd7cddfSDavid du Colombier 	/*
1577dd7cddfSDavid du Colombier 	 * Frame Buffer Pitch and FIFO control.
1587dd7cddfSDavid du Colombier 	 * Set the FIFO to 32 deep and refill trigger when
1597dd7cddfSDavid du Colombier 	 * 6 slots empty.
1607dd7cddfSDavid du Colombier 	 */
1617dd7cddfSDavid du Colombier 	vga->sequencer[0x17] = 0x00;
1627dd7cddfSDavid du Colombier 	vga->sequencer[0x18] = 0x13;
1637dd7cddfSDavid du Colombier 	if(mode->x <= 640)
1647dd7cddfSDavid du Colombier 		vga->sequencer[0x17] = 0x00;
1657dd7cddfSDavid du Colombier 	else if(mode->x <= 800)
1667dd7cddfSDavid du Colombier 		vga->sequencer[0x17] |= 0x01;
1677dd7cddfSDavid du Colombier 	else if(mode->x <= 1024)
1687dd7cddfSDavid du Colombier 		vga->sequencer[0x17] |= 0x02;
1697dd7cddfSDavid du Colombier 	else if(mode->x <= 1280)
1707dd7cddfSDavid du Colombier 		vga->sequencer[0x17] |= 0x04;
1717dd7cddfSDavid du Colombier 	else if(mode->x <= 1600)
1727dd7cddfSDavid du Colombier 		vga->sequencer[0x17] |= 0x05;
1737dd7cddfSDavid du Colombier 	else if(mode->x <= 2048)
1747dd7cddfSDavid du Colombier 		vga->sequencer[0x17] |= 0x06;
1757dd7cddfSDavid du Colombier 
1767dd7cddfSDavid du Colombier 	/*
1777dd7cddfSDavid du Colombier 	 * Clock select.
1787dd7cddfSDavid du Colombier 	 */
1797dd7cddfSDavid du Colombier 	vga->misc &= ~0x0C;
1807dd7cddfSDavid du Colombier 	vga->misc |= (vga->i[0] & 0x03)<<2;
1817dd7cddfSDavid du Colombier 	vga->sequencer[0x11] &= ~0xC0;
1827dd7cddfSDavid du Colombier 	vga->sequencer[0x11] |= (vga->i[0] & 0x0C)<<4;
1837dd7cddfSDavid du Colombier 
1847dd7cddfSDavid du Colombier 	vga->attribute[0x11] = 0x00;	/* color map entry for black */
1857dd7cddfSDavid du Colombier 
1867dd7cddfSDavid du Colombier 	ctlr->flag |= Finit;
1877dd7cddfSDavid du Colombier }
1887dd7cddfSDavid du Colombier 
1897dd7cddfSDavid du Colombier static void
load(Vga * vga,Ctlr * ctlr)1907dd7cddfSDavid du Colombier load(Vga* vga, Ctlr* ctlr)
1917dd7cddfSDavid du Colombier {
1927dd7cddfSDavid du Colombier 	ulong l;
1937dd7cddfSDavid du Colombier 
1947dd7cddfSDavid du Colombier 	/*
1957dd7cddfSDavid du Colombier 	 * Ensure there are no glitches when selecting a new
1967dd7cddfSDavid du Colombier 	 * clock frequency.
1977dd7cddfSDavid du Colombier 	 * The sequencer toggle seems to matter on the Hercules
1987dd7cddfSDavid du Colombier 	 * Stingray 64/Video at 1280x1024x8. Without it the screen
1997dd7cddfSDavid du Colombier 	 * is fuzzy; a second load clears it up and there's no
2007dd7cddfSDavid du Colombier 	 * difference between the two register sets. A mystery.
2017dd7cddfSDavid du Colombier 	 */
2027dd7cddfSDavid du Colombier 	vgao(MiscW, vga->misc & ~0x0C);
2037dd7cddfSDavid du Colombier 	vgaxo(Seqx, 0x11, vga->sequencer[0x11]);
2047dd7cddfSDavid du Colombier 	vgao(MiscW, vga->misc);
2057dd7cddfSDavid du Colombier 	if(vga->ramdac && strncmp(vga->ramdac->name, "w30c516", 7) == 0){
2067dd7cddfSDavid du Colombier 		sequencer(vga, 1);
2077dd7cddfSDavid du Colombier 		sleep(500);
2087dd7cddfSDavid du Colombier 		sequencer(vga, 0);
2097dd7cddfSDavid du Colombier 	}
2107dd7cddfSDavid du Colombier 
2117dd7cddfSDavid du Colombier 	if(ctlr->flag & Ulinear){
2127dd7cddfSDavid du Colombier 		vga->sequencer[0x10] |= 0x10;
2137dd7cddfSDavid du Colombier 		if(vga->vmz <= 1024*1024)
2147dd7cddfSDavid du Colombier 			vga->sequencer[0x12] |= 0x01;
2157dd7cddfSDavid du Colombier 		else if(vga->vmz <= 2*1024*1024)
2167dd7cddfSDavid du Colombier 			vga->sequencer[0x12] |= 0x02;
2177dd7cddfSDavid du Colombier 		else
2187dd7cddfSDavid du Colombier 			vga->sequencer[0x12] |= 0x03;
2197dd7cddfSDavid du Colombier 		l = vga->vmb>>16;
2207dd7cddfSDavid du Colombier 		vga->sequencer[0x13] = l & 0xFF;
2217dd7cddfSDavid du Colombier 		vga->sequencer[0x14] = (l>>8) & 0xFF;
2227dd7cddfSDavid du Colombier 	}
2237dd7cddfSDavid du Colombier 
2247dd7cddfSDavid du Colombier 	vgaxo(Seqx, 0x10, vga->sequencer[0x10]);
2257dd7cddfSDavid du Colombier 	vgaxo(Seqx, 0x12, vga->sequencer[0x12]);
2267dd7cddfSDavid du Colombier 	vgaxo(Seqx, 0x13, vga->sequencer[0x13]);
2277dd7cddfSDavid du Colombier 	vgaxo(Seqx, 0x14, vga->sequencer[0x14]);
2287dd7cddfSDavid du Colombier 	vgaxo(Seqx, 0x15, vga->sequencer[0x15]);
2297dd7cddfSDavid du Colombier 	vgaxo(Seqx, 0x16, vga->sequencer[0x16]);
2307dd7cddfSDavid du Colombier 	vgaxo(Seqx, 0x17, vga->sequencer[0x17]);
2317dd7cddfSDavid du Colombier 	vgaxo(Seqx, 0x18, vga->sequencer[0x18]);
2327dd7cddfSDavid du Colombier 
2337dd7cddfSDavid du Colombier 	vgaxo(Crtx, 0x40, vga->crt[0x40]);
2347dd7cddfSDavid du Colombier 	vgaxo(Crtx, 0x41, vga->crt[0x41]);
2357dd7cddfSDavid du Colombier 	vgaxo(Crtx, 0x42, vga->crt[0x42]);
2367dd7cddfSDavid du Colombier 	vgaxo(Crtx, 0x44, vga->crt[0x44]);
2377dd7cddfSDavid du Colombier 	vgaxo(Crtx, 0x45, vga->crt[0x45]);
2387dd7cddfSDavid du Colombier 	vgaxo(Crtx, 0x46, vga->crt[0x46]);
2397dd7cddfSDavid du Colombier 
2407dd7cddfSDavid du Colombier 	ctlr->flag |= Fload;
2417dd7cddfSDavid du Colombier }
2427dd7cddfSDavid du Colombier 
2437dd7cddfSDavid du Colombier static void
dump(Vga * vga,Ctlr * ctlr)2447dd7cddfSDavid du Colombier dump(Vga* vga, Ctlr* ctlr)
2457dd7cddfSDavid du Colombier {
2467dd7cddfSDavid du Colombier 	int i;
2477dd7cddfSDavid du Colombier 
2487dd7cddfSDavid du Colombier 	printitem(ctlr->name, "Seq10");
2497dd7cddfSDavid du Colombier 	for(i = 0x10; i < 0x2E; i++)
2507dd7cddfSDavid du Colombier 		printreg(vga->sequencer[i]);
2517dd7cddfSDavid du Colombier 	printitem(ctlr->name, "Crt40");
2527dd7cddfSDavid du Colombier 	for(i = 0x40; i < 0x47; i++)
2537dd7cddfSDavid du Colombier 		printreg(vga->crt[i]);
2547dd7cddfSDavid du Colombier 	printitem(ctlr->name, "Crt50");
2557dd7cddfSDavid du Colombier 	printreg(vga->crt[0x50]);
2567dd7cddfSDavid du Colombier 	printitem(ctlr->name, "Cop status");
2577dd7cddfSDavid du Colombier 	printreg(vga->crt[0xFF]);
2587dd7cddfSDavid du Colombier }
2597dd7cddfSDavid du Colombier 
2607dd7cddfSDavid du Colombier Ctlr ark2000pv = {
2617dd7cddfSDavid du Colombier 	"ark2000pv",			/* name */
2627dd7cddfSDavid du Colombier 	snarf,				/* snarf */
2637dd7cddfSDavid du Colombier 	options,			/* options */
2647dd7cddfSDavid du Colombier 	init,				/* init */
2657dd7cddfSDavid du Colombier 	load,				/* load */
2667dd7cddfSDavid du Colombier 	dump,				/* dump */
2677dd7cddfSDavid du Colombier };
2687dd7cddfSDavid du Colombier 
2697dd7cddfSDavid du Colombier Ctlr ark2000pvhwgc = {
2707dd7cddfSDavid du Colombier 	"ark2000pvhwgc",		/* name */
2717dd7cddfSDavid du Colombier 	0,				/* snarf */
2727dd7cddfSDavid du Colombier 	0,				/* options */
2737dd7cddfSDavid du Colombier 	0,				/* init */
2747dd7cddfSDavid du Colombier 	0,				/* load */
2757dd7cddfSDavid du Colombier 	0,				/* dump */
2767dd7cddfSDavid du Colombier };
277