xref: /plan9-contrib/sys/src/9/pc/vgax.c (revision 4de34a7edde43207e841ec91ecd12e6cf5f5ebe7)
17dd7cddfSDavid du Colombier #include "u.h"
27dd7cddfSDavid du Colombier #include "../port/lib.h"
37dd7cddfSDavid du Colombier #include "mem.h"
47dd7cddfSDavid du Colombier #include "dat.h"
57dd7cddfSDavid du Colombier #include "fns.h"
6*4de34a7eSDavid du Colombier #include "io.h"
77dd7cddfSDavid du Colombier #include "../port/error.h"
87dd7cddfSDavid du Colombier 
97dd7cddfSDavid du Colombier #define	Image	IMAGE
107dd7cddfSDavid du Colombier #include <draw.h>
117dd7cddfSDavid du Colombier #include <memdraw.h>
127dd7cddfSDavid du Colombier #include <cursor.h>
137dd7cddfSDavid du Colombier #include "screen.h"
147dd7cddfSDavid du Colombier 
157dd7cddfSDavid du Colombier static Lock vgaxlock;			/* access to index registers */
167dd7cddfSDavid du Colombier 
177dd7cddfSDavid du Colombier int
vgaxi(long port,uchar index)187dd7cddfSDavid du Colombier vgaxi(long port, uchar index)
197dd7cddfSDavid du Colombier {
207dd7cddfSDavid du Colombier 	uchar data;
217dd7cddfSDavid du Colombier 
227dd7cddfSDavid du Colombier 	ilock(&vgaxlock);
237dd7cddfSDavid du Colombier 	switch(port){
247dd7cddfSDavid du Colombier 
257dd7cddfSDavid du Colombier 	case Seqx:
267dd7cddfSDavid du Colombier 	case Crtx:
277dd7cddfSDavid du Colombier 	case Grx:
287dd7cddfSDavid du Colombier 		outb(port, index);
297dd7cddfSDavid du Colombier 		data = inb(port+1);
307dd7cddfSDavid du Colombier 		break;
317dd7cddfSDavid du Colombier 
327dd7cddfSDavid du Colombier 	case Attrx:
337dd7cddfSDavid du Colombier 		/*
347dd7cddfSDavid du Colombier 		 * Allow processor access to the colour
357dd7cddfSDavid du Colombier 		 * palette registers. Writes to Attrx must
367dd7cddfSDavid du Colombier 		 * be preceded by a read from Status1 to
377dd7cddfSDavid du Colombier 		 * initialise the register to point to the
387dd7cddfSDavid du Colombier 		 * index register and not the data register.
397dd7cddfSDavid du Colombier 		 * Processor access is allowed by turning
407dd7cddfSDavid du Colombier 		 * off bit 0x20.
417dd7cddfSDavid du Colombier 		 */
427dd7cddfSDavid du Colombier 		inb(Status1);
437dd7cddfSDavid du Colombier 		if(index < 0x10){
447dd7cddfSDavid du Colombier 			outb(Attrx, index);
457dd7cddfSDavid du Colombier 			data = inb(Attrx+1);
467dd7cddfSDavid du Colombier 			inb(Status1);
477dd7cddfSDavid du Colombier 			outb(Attrx, 0x20|index);
487dd7cddfSDavid du Colombier 		}
497dd7cddfSDavid du Colombier 		else{
507dd7cddfSDavid du Colombier 			outb(Attrx, 0x20|index);
517dd7cddfSDavid du Colombier 			data = inb(Attrx+1);
527dd7cddfSDavid du Colombier 		}
537dd7cddfSDavid du Colombier 		break;
547dd7cddfSDavid du Colombier 
557dd7cddfSDavid du Colombier 	default:
567dd7cddfSDavid du Colombier 		iunlock(&vgaxlock);
577dd7cddfSDavid du Colombier 		return -1;
587dd7cddfSDavid du Colombier 	}
597dd7cddfSDavid du Colombier 	iunlock(&vgaxlock);
607dd7cddfSDavid du Colombier 
617dd7cddfSDavid du Colombier 	return data & 0xFF;
627dd7cddfSDavid du Colombier }
637dd7cddfSDavid du Colombier 
647dd7cddfSDavid du Colombier int
vgaxo(long port,uchar index,uchar data)657dd7cddfSDavid du Colombier vgaxo(long port, uchar index, uchar data)
667dd7cddfSDavid du Colombier {
677dd7cddfSDavid du Colombier 	ilock(&vgaxlock);
687dd7cddfSDavid du Colombier 	switch(port){
697dd7cddfSDavid du Colombier 
707dd7cddfSDavid du Colombier 	case Seqx:
717dd7cddfSDavid du Colombier 	case Crtx:
727dd7cddfSDavid du Colombier 	case Grx:
737dd7cddfSDavid du Colombier 		/*
747dd7cddfSDavid du Colombier 		 * We could use an outport here, but some chips
757dd7cddfSDavid du Colombier 		 * (e.g. 86C928) have trouble with that for some
767dd7cddfSDavid du Colombier 		 * registers.
777dd7cddfSDavid du Colombier 		 */
787dd7cddfSDavid du Colombier 		outb(port, index);
797dd7cddfSDavid du Colombier 		outb(port+1, data);
807dd7cddfSDavid du Colombier 		break;
817dd7cddfSDavid du Colombier 
827dd7cddfSDavid du Colombier 	case Attrx:
837dd7cddfSDavid du Colombier 		inb(Status1);
847dd7cddfSDavid du Colombier 		if(index < 0x10){
857dd7cddfSDavid du Colombier 			outb(Attrx, index);
867dd7cddfSDavid du Colombier 			outb(Attrx, data);
877dd7cddfSDavid du Colombier 			inb(Status1);
887dd7cddfSDavid du Colombier 			outb(Attrx, 0x20|index);
897dd7cddfSDavid du Colombier 		}
907dd7cddfSDavid du Colombier 		else{
917dd7cddfSDavid du Colombier 			outb(Attrx, 0x20|index);
927dd7cddfSDavid du Colombier 			outb(Attrx, data);
937dd7cddfSDavid du Colombier 		}
947dd7cddfSDavid du Colombier 		break;
957dd7cddfSDavid du Colombier 
967dd7cddfSDavid du Colombier 	default:
977dd7cddfSDavid du Colombier 		iunlock(&vgaxlock);
987dd7cddfSDavid du Colombier 		return -1;
997dd7cddfSDavid du Colombier 	}
1007dd7cddfSDavid du Colombier 	iunlock(&vgaxlock);
1017dd7cddfSDavid du Colombier 
1027dd7cddfSDavid du Colombier 	return 0;
1037dd7cddfSDavid du Colombier }
104