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