xref: /plan9-contrib/sys/src/9/pc/vgax.c (revision 4de34a7edde43207e841ec91ecd12e6cf5f5ebe7)
1 #include "u.h"
2 #include "../port/lib.h"
3 #include "mem.h"
4 #include "dat.h"
5 #include "fns.h"
6 #include "io.h"
7 #include "../port/error.h"
8 
9 #define	Image	IMAGE
10 #include <draw.h>
11 #include <memdraw.h>
12 #include <cursor.h>
13 #include "screen.h"
14 
15 static Lock vgaxlock;			/* access to index registers */
16 
17 int
vgaxi(long port,uchar index)18 vgaxi(long port, uchar index)
19 {
20 	uchar data;
21 
22 	ilock(&vgaxlock);
23 	switch(port){
24 
25 	case Seqx:
26 	case Crtx:
27 	case Grx:
28 		outb(port, index);
29 		data = inb(port+1);
30 		break;
31 
32 	case Attrx:
33 		/*
34 		 * Allow processor access to the colour
35 		 * palette registers. Writes to Attrx must
36 		 * be preceded by a read from Status1 to
37 		 * initialise the register to point to the
38 		 * index register and not the data register.
39 		 * Processor access is allowed by turning
40 		 * off bit 0x20.
41 		 */
42 		inb(Status1);
43 		if(index < 0x10){
44 			outb(Attrx, index);
45 			data = inb(Attrx+1);
46 			inb(Status1);
47 			outb(Attrx, 0x20|index);
48 		}
49 		else{
50 			outb(Attrx, 0x20|index);
51 			data = inb(Attrx+1);
52 		}
53 		break;
54 
55 	default:
56 		iunlock(&vgaxlock);
57 		return -1;
58 	}
59 	iunlock(&vgaxlock);
60 
61 	return data & 0xFF;
62 }
63 
64 int
vgaxo(long port,uchar index,uchar data)65 vgaxo(long port, uchar index, uchar data)
66 {
67 	ilock(&vgaxlock);
68 	switch(port){
69 
70 	case Seqx:
71 	case Crtx:
72 	case Grx:
73 		/*
74 		 * We could use an outport here, but some chips
75 		 * (e.g. 86C928) have trouble with that for some
76 		 * registers.
77 		 */
78 		outb(port, index);
79 		outb(port+1, data);
80 		break;
81 
82 	case Attrx:
83 		inb(Status1);
84 		if(index < 0x10){
85 			outb(Attrx, index);
86 			outb(Attrx, data);
87 			inb(Status1);
88 			outb(Attrx, 0x20|index);
89 		}
90 		else{
91 			outb(Attrx, 0x20|index);
92 			outb(Attrx, data);
93 		}
94 		break;
95 
96 	default:
97 		iunlock(&vgaxlock);
98 		return -1;
99 	}
100 	iunlock(&vgaxlock);
101 
102 	return 0;
103 }
104