xref: /plan9-contrib/sys/src/cmd/aux/vga/s3928.c (revision 9a747e4fd48b9f4522c70c07e8f882a15030f964)
1219b2ee8SDavid du Colombier #include <u.h>
2219b2ee8SDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <bio.h>
4219b2ee8SDavid du Colombier 
5*9a747e4fSDavid du Colombier #include "pci.h"
6219b2ee8SDavid du Colombier #include "vga.h"
7219b2ee8SDavid du Colombier 
8219b2ee8SDavid du Colombier /*
9219b2ee8SDavid du Colombier  * S3 86C928 GUI Accelerator.
10219b2ee8SDavid du Colombier  */
11219b2ee8SDavid du Colombier static void
snarf(Vga * vga,Ctlr * ctlr)12219b2ee8SDavid du Colombier snarf(Vga* vga, Ctlr* ctlr)
13219b2ee8SDavid du Colombier {
147dd7cddfSDavid du Colombier 	s3generic.snarf(vga, ctlr);
15219b2ee8SDavid du Colombier }
16219b2ee8SDavid du Colombier 
17219b2ee8SDavid du Colombier static void
options(Vga *,Ctlr * ctlr)187dd7cddfSDavid du Colombier options(Vga*, Ctlr* ctlr)
19219b2ee8SDavid du Colombier {
207dd7cddfSDavid du Colombier 	ctlr->flag |= Hlinear|Henhanced|Foptions;
21219b2ee8SDavid du Colombier }
22219b2ee8SDavid du Colombier 
23219b2ee8SDavid du Colombier static void
init(Vga * vga,Ctlr * ctlr)24219b2ee8SDavid du Colombier init(Vga* vga, Ctlr* ctlr)
25219b2ee8SDavid du Colombier {
26219b2ee8SDavid du Colombier 	Mode *mode;
27219b2ee8SDavid du Colombier 	ulong x;
28219b2ee8SDavid du Colombier 
29219b2ee8SDavid du Colombier 	/*
307dd7cddfSDavid du Colombier 	 * s3generic.init() will perform the same test.
31219b2ee8SDavid du Colombier 	 * We need to do it here too so that the Crt registers
327dd7cddfSDavid du Colombier 	 * will be correct when s3generic.init() calculates
33219b2ee8SDavid du Colombier 	 * the overflow bits.
34219b2ee8SDavid du Colombier 	 */
357dd7cddfSDavid du Colombier 	if(vga->mode->z > 8)
367dd7cddfSDavid du Colombier 		error("depth %d not supported\n", vga->mode->z);
377dd7cddfSDavid du Colombier 
38219b2ee8SDavid du Colombier 	mode = vga->mode;
39219b2ee8SDavid du Colombier 	if((ctlr->flag & Henhanced) && mode->x >= 1024 && mode->z == 8){
40219b2ee8SDavid du Colombier 		resyncinit(vga, ctlr, Uenhanced, 0);
41219b2ee8SDavid du Colombier 		vga->crt[0x00] = ((mode->ht/4)>>3)-5;
42219b2ee8SDavid du Colombier 		vga->crt[0x01] = ((mode->x/4)>>3)-1;
43219b2ee8SDavid du Colombier 		vga->crt[0x02] = ((mode->shb/4)>>3)-1;
44219b2ee8SDavid du Colombier 
45219b2ee8SDavid du Colombier 		x = (mode->ehb/4)>>3;
46219b2ee8SDavid du Colombier 		vga->crt[0x03] = 0x80|(x & 0x1F);
477dd7cddfSDavid du Colombier 		vga->crt[0x04] = (mode->shs/4)>>3;
487dd7cddfSDavid du Colombier 		vga->crt[0x05] = ((mode->ehs/4)>>3) & 0x1F;
49219b2ee8SDavid du Colombier 		if(x & 0x20)
50219b2ee8SDavid du Colombier 			vga->crt[0x05] |= 0x80;
51219b2ee8SDavid du Colombier 
52219b2ee8SDavid du Colombier 		vga->crt[0x13] = mode->x/8;
53219b2ee8SDavid du Colombier 		if(mode->z == 1)
54219b2ee8SDavid du Colombier 			vga->crt[0x13] /= 8;
55219b2ee8SDavid du Colombier 	}
567dd7cddfSDavid du Colombier 	s3generic.init(vga, ctlr);
57219b2ee8SDavid du Colombier 	vga->crt[0x3B] = (vga->crt[0]+vga->crt[4]+1)/2;
58219b2ee8SDavid du Colombier 
59219b2ee8SDavid du Colombier 	/*
60219b2ee8SDavid du Colombier 	 * Set up write-posting and read-ahead-cache.
61219b2ee8SDavid du Colombier 	 */
62219b2ee8SDavid du Colombier 	vga->crt[0x54] = 0xA7;
63219b2ee8SDavid du Colombier 	if(ctlr->flag & Uenhanced){
64219b2ee8SDavid du Colombier 		vga->crt[0x58] |= 0x04;
65219b2ee8SDavid du Colombier 		vga->crt[0x40] |= 0x08;
66219b2ee8SDavid du Colombier 	}
67219b2ee8SDavid du Colombier 	else{
68219b2ee8SDavid du Colombier 		vga->crt[0x58] &= ~0x04;
69219b2ee8SDavid du Colombier 		vga->crt[0x40] &= ~0x08;
70219b2ee8SDavid du Colombier 	}
71219b2ee8SDavid du Colombier 
72219b2ee8SDavid du Colombier 	/*
73219b2ee8SDavid du Colombier 	 * Set up parallel VRAM and the external
74219b2ee8SDavid du Colombier 	 * SID enable on the 86C928
75219b2ee8SDavid du Colombier 	 */
76219b2ee8SDavid du Colombier 	vga->crt[0x53] &= ~0x20;			/* parallel VRAM */
77219b2ee8SDavid du Colombier 	vga->crt[0x55] &= ~0x48;			/* external SID */
78219b2ee8SDavid du Colombier 	vga->crt[0x65] &= ~0x60;			/* 2 86C928 E-step chip bugs */
79219b2ee8SDavid du Colombier 	if(ctlr->flag & Uenhanced){
80219b2ee8SDavid du Colombier 		if(vga->ramdac->flag & Hpvram)
81219b2ee8SDavid du Colombier 			vga->crt[0x53] |= 0x20;
82219b2ee8SDavid du Colombier 		if(vga->ramdac->flag & Hextsid)
83219b2ee8SDavid du Colombier 			vga->crt[0x55] |= 0x48;
84219b2ee8SDavid du Colombier 		vga->crt[0x65] |= 0x60;
85219b2ee8SDavid du Colombier 	}
86219b2ee8SDavid du Colombier }
87219b2ee8SDavid du Colombier 
88219b2ee8SDavid du Colombier static void
load(Vga * vga,Ctlr * ctlr)89219b2ee8SDavid du Colombier load(Vga* vga, Ctlr* ctlr)
90219b2ee8SDavid du Colombier {
91219b2ee8SDavid du Colombier 	ushort advfunc;
92219b2ee8SDavid du Colombier 
93219b2ee8SDavid du Colombier 	(*s3generic.load)(vga, ctlr);
94219b2ee8SDavid du Colombier 	vgaxo(Crtx, 0x65, vga->crt[0x65]);
95219b2ee8SDavid du Colombier 
96219b2ee8SDavid du Colombier 	advfunc = 0x0000;
97219b2ee8SDavid du Colombier 	if(ctlr->flag & Uenhanced){
98219b2ee8SDavid du Colombier 		if(vga->mode->x == 1024 || vga->mode->x == 800)
99219b2ee8SDavid du Colombier 			advfunc = 0x0057;
100219b2ee8SDavid du Colombier 		else
101219b2ee8SDavid du Colombier 			advfunc = 0x0053;
102219b2ee8SDavid du Colombier 	}
103219b2ee8SDavid du Colombier 	outportw(0x4AE8, advfunc);
104219b2ee8SDavid du Colombier }
105219b2ee8SDavid du Colombier 
106219b2ee8SDavid du Colombier static void
dump(Vga * vga,Ctlr * ctlr)107219b2ee8SDavid du Colombier dump(Vga* vga, Ctlr* ctlr)
108219b2ee8SDavid du Colombier {
109219b2ee8SDavid du Colombier 	(*s3generic.dump)(vga, ctlr);
110219b2ee8SDavid du Colombier }
111219b2ee8SDavid du Colombier 
112219b2ee8SDavid du Colombier Ctlr s3928 = {
113219b2ee8SDavid du Colombier 	"s3928",			/* name */
114219b2ee8SDavid du Colombier 	snarf,				/* snarf */
115219b2ee8SDavid du Colombier 	options,			/* options */
116219b2ee8SDavid du Colombier 	init,				/* init */
117219b2ee8SDavid du Colombier 	load,				/* load */
118219b2ee8SDavid du Colombier 	dump,				/* dump */
119219b2ee8SDavid du Colombier };
120