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