xref: /plan9/sys/src/9/pc/vgact65545.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 void
ct65545page(VGAscr *,int page)16 ct65545page(VGAscr*, int page)
17 {
18 	outb(0x3D6, 0x10);
19 	outb(0x3D7, page<<6);
20 }
21 
22 static void
ct65545disable(VGAscr *)23 ct65545disable(VGAscr*)
24 {
25 	outl(0xA3D0, 0);
26 }
27 
28 static void
ct65545enable(VGAscr * scr)29 ct65545enable(VGAscr* scr)
30 {
31 	ulong storage;
32 
33 	/*
34 	 * Find a place for the cursor data in display memory.
35 	 * Must be on a 1024-byte boundary.
36 	 */
37 	storage = ROUND(scr->gscreen->width*BY2WD*scr->gscreen->r.max.y, 1024);
38 	outl(0xB3D0, storage);
39 	scr->storage = storage;
40 
41 	/*
42 	 * Set the colours.
43 	 * Enable the cursor.
44 	 */
45 	outl(0xA7D0, 0xFFFF0000);
46 	outl(0xA3D0, 2);
47 }
48 
49 static void
ct65545initcursor(VGAscr * scr,int xo,int yo,int index)50 ct65545initcursor(VGAscr* scr, int xo, int yo, int index)
51 {
52 	uchar *mem;
53 	uint and, clr, set, xor;
54 	int i, x, y;
55 
56 	mem = scr->vaddr;
57 	mem += scr->storage + index*1024;
58 
59 	for(y = yo; y < 16; y++){
60 		clr = (scr->clr[2*y]<<8)|scr->clr[2*y+1];
61 		set = (scr->set[2*y]<<8)|scr->set[2*y+1];
62 		if(xo){
63 			clr <<= xo;
64 			set <<= xo;
65 		}
66 
67 		and = 0;
68 		xor = 0;
69 		for(i = 0; i < 16; i++){
70 			if(set & (1<<i)){
71 				/* nothing to do */
72 			}
73 			else if(clr & (1<<i))
74 				xor |= 1<<i;
75 			else
76 				and |= 1<<i;
77 		}
78 		*mem++ = and>>8;
79 		*mem++ = xor>>8;
80 		*mem++ = and;
81 		*mem++ = xor;
82 
83 		for(x = 16; x < 64; x += 8){
84 			*mem++ = 0xFF;
85 			*mem++ = 0x00;
86 		}
87 	}
88 	while(y < 64+yo){
89 		for(x = 0; x < 64; x += 8){
90 			*mem++ = 0xFF;
91 			*mem++ = 0x00;
92 		}
93 		y++;
94 	}
95 }
96 
97 static void
ct65545load(VGAscr * scr,Cursor * curs)98 ct65545load(VGAscr* scr, Cursor* curs)
99 {
100 	memmove(&scr->Cursor, curs, sizeof(Cursor));
101 	ct65545initcursor(scr, 0, 0, 0);
102 }
103 
104 static int
ct65545move(VGAscr * scr,Point p)105 ct65545move(VGAscr* scr, Point p)
106 {
107 	int index, x, xo, y, yo;
108 
109 	index = 0;
110 	if((x = p.x+scr->offset.x) < 0){
111 		xo = -x;
112 		x = 0;
113 	}
114 	else
115 		xo = 0;
116 	if((y = p.y+scr->offset.y) < 0){
117 		yo = -y;
118 		y = 0;
119 	}
120 	else
121 		yo = 0;
122 
123 	if(xo || yo){
124 		ct65545initcursor(scr, xo, yo, 1);
125 		index = 1;
126 	}
127 	outl(0xB3D0, scr->storage + index*1024);
128 
129 	outl(0xAFD0, (y<<16)|x);
130 
131 	return 0;
132 }
133 
134 VGAdev vgact65545dev = {
135 	"ct65540",				/* BUG: really 65545 */
136 
137 	0,
138 	0,
139 	ct65545page,
140 	0,
141 };
142 
143 VGAcur vgact65545cur = {
144 	"ct65545hwgc",
145 
146 	ct65545enable,
147 	ct65545disable,
148 	ct65545load,
149 	ct65545move,
150 };
151