1 /*************************************************************************
2 MFB graphics and miscellaneous library
3 Copyright (c) Stephen R. Whiteley 1992
4 Author: Stephen R. Whiteley
5 *************************************************************************/
6
7 #include "mfb.h"
8 #include "mfbP.h"
9 #include <dos.h>
10
11 /* in real mode, the mode_?_... functions are used in the dp driver */
12 #ifdef __STDC__
13 extern void mode_1_mark(int,int);
14 extern void mode_2_mark(int,int);
15 extern void mode_1_clear(int,int);
16 extern void mode_2_clear(int,int);
17 #else
18 extern void mode_1_mark();
19 extern void mode_2_mark();
20 extern void mode_1_clear();
21 extern void mode_2_clear();
22 #endif
23
24
25 void
MFBDrawCursor(x,y)26 MFBDrawCursor(x,y)
27
28 /* draw cursor */
29 int x,y;
30 {
31 int oldalu;
32
33 if (pc.drawghost) {
34 /* draw any rubber-banding */
35 oldalu = pc.alumode;
36 pc.alumode = 0x1803;
37 (*pc.drawghost)(x+8,y-7,pc.refx,pc.refy);
38 pc.alumode = oldalu;
39 }
40 if (pc.mfbMODE & 2)
41 mode_2_mark(x,y);
42 else
43 mode_1_mark(x,y);
44 }
45
46
47 void
MFBEraseCursor(x,y)48 MFBEraseCursor(x,y)
49
50 /* erase cursor */
51 int x,y;
52 {
53 int oldalu;
54
55 if (pc.mfbMODE & 2)
56 mode_2_clear(x,y);
57 else
58 mode_1_clear(x,y);
59 if (pc.drawghost) {
60 /* undraw any rubber-banding */
61 oldalu = pc.alumode;
62 pc.alumode = 0x1803;
63 (*pc.drawghost)(x+8,y-7,pc.refx,pc.refy);
64 pc.alumode = oldalu;
65 }
66 }
67
68
69 void
mode_1_mark(x,y)70 mode_1_mark(x,y)
71
72 /* display cursor 16 color modes */
73 int x, y;
74 {
75 int i, j, next;
76 unsigned short *amap, *xmap;
77 unsigned char bitmask, mode, datarot, esetreset, cdontcare;
78 unsigned char readplane, planemask, rem, *px;
79 vidmptr rgen, rgen0;
80 union {long l; unsigned short i; char s[4]; } afld, xfld;
81 int stop;
82
83 outp(0x3ce,0x5); /* read mode 0, write mode 0 */
84 mode = inp(0x3cf);
85 outp(0x3cf,0);
86
87 outp(0x3ce,0x4); /* read plane */
88 readplane = inp(0x3cf);
89
90 amap = (unsigned short *) vgacur.map;
91 xmap = amap + 16;
92
93 px = vgacur.pbs;
94
95 rem = x & 7;
96 x >>= 3;
97 next = pc.bytpline;
98 rgen0 = pc.base + x + (long) (pc.ysize-1-y)*next;
99 stop = 16;
100 while (rgen0 < pc.base) {
101 rgen0 += next;
102 amap++;
103 xmap++;
104 stop--;
105 }
106 next -= 2;
107
108 /* store background */
109 for (j = 0; j < 4; j++) {
110 rgen = rgen0;
111 outp(0x3cf,j); /* read plane select */
112 for (i = 0; i < stop; i++) {
113 *px++ = *rgen++;
114 *px++ = *rgen++;
115 *px++ = *rgen;
116 rgen += next;
117 }
118 px += 16;
119 }
120 next += 2;
121
122 outp(0x3c4,0x2); /* write plane enable */
123 planemask = inp(0x3c5);
124
125 outp(0x3ce,0x1); /* enable set reset */
126 esetreset = inp(0x3cf);
127 outp(0x3cf,0x0);
128
129 outp(0x3ce,0x8); /* bit mask */
130 bitmask = inp(0x3cf);
131 outp(0x3cf,0xff);
132
133 outp(0x3ce,0x7); /* color dont care */
134 cdontcare = inp(0x3cf);
135 outp(0x3cf,0x00);
136
137 outp(0x3ce,0x5); /* read mode 1, write mode 0 */
138 outp(0x3cf,8);
139
140 outp(0x3ce,0x3); /* data rotate */
141 datarot = inp(0x3cf);
142
143 rgen = rgen0;
144
145 for (i = 0; i < stop; i++) {
146 afld.i = *(amap++);
147 afld.s[2] = 0xff;
148 afld.l <<= 8-rem;
149 afld.s[0] |= 0xff >> rem;
150
151 xfld.i = *(xmap++);
152 xfld.s[2] = 0;
153 xfld.l <<= 8-rem;
154
155 /* xcnt is unsigned */
156 if ((unsigned) x+2 >= next) {
157 afld.s[0] = 0xff;
158 xfld.s[0] = 0x0;
159 }
160 if ((unsigned) x+1 >= next) {
161 afld.s[1] = 0xff;
162 xfld.s[1] = 0x0;
163 }
164 if ((unsigned) x >= next) {
165 afld.s[2] = 0xff;
166 xfld.s[2] = 0x0;
167 }
168
169 outp(0x3c5,0xf);
170 outp(0x3cf,0x08); /* AND */
171 *rgen &= afld.s[2];
172 rgen++;
173 *rgen &= afld.s[1];
174 rgen++;
175 *rgen &= afld.s[0];
176 rgen -= 2;
177
178 outp(0x3c5,pc.cursor_color);
179 outp(0x3cf,0x18); /* XOR */
180 *rgen &= xfld.s[2];
181 rgen++;
182 *rgen &= xfld.s[1];
183 rgen++;
184 *rgen &= xfld.s[0];
185 rgen += next - 2;
186 }
187 outp(0x3c5,planemask);
188 outp(0x3ce,0x1); outp(0x3cf,esetreset); /* enable set reset */
189 outp(0x3ce,0x3); outp(0x3cf,datarot); /* data rotate */
190 outp(0x3ce,0x4); outp(0x3cf,readplane); /* read plane */
191 outp(0x3ce,0x5); outp(0x3cf,mode); /* write mode */
192 outp(0x3ce,0x7); outp(0x3cf,cdontcare); /* color dont care */
193 outp(0x3ce,0x8); outp(0x3cf,bitmask); /* bit mask */
194 }
195
196
197 #ifndef __GNUC__
198
199
200 void
mode_2_mark(x,y)201 mode_2_mark(x,y)
202
203 /* display cursor 256 color modes */
204 int x, y;
205 {
206 int i, j, next;
207 unsigned short xcnt, *amap, *xmap;
208 unsigned char cbuf, pix, color, segsel, *px;
209 union {long l; unsigned short i; char s[4]; } afld, xfld;
210 union { unsigned short o[2]; long l; } p1;
211
212 segsel = inp(0x3cd); /* Tseng Labs segment selector */
213
214 amap = (unsigned short *) vgacur.map;
215 xmap = amap + 16;
216
217 px = vgacur.pbs;
218 next = pc.xsize;
219 p1.l = x + (long) (pc.ysize-1-y)*next;
220
221 cbuf = p1.o[1];
222 outp(0x3cd,(cbuf << 4) | cbuf);
223 color = pc.cursor_color;
224 outpw(0x3ce,0x3); /* set alu mode */
225
226 j = x;
227 i = 16;
228 while (i--) {
229
230 afld.i = *(amap++);
231 xfld.i = *(xmap++);
232
233 xcnt = 0x8000;
234 while (xcnt) {
235 if (p1.o[1] != cbuf) {
236 cbuf = p1.o[1];
237 outp(0x3cd,(cbuf << 4) | cbuf);
238 }
239 pix = *(pc.base + p1.o[0]);
240 *px++ = pix;
241 if (j < 0 || j >= next)
242 goto skip;
243 if (afld.i & xfld.i & xcnt)
244 *(pc.base+p1.o[0]) = color ^ pix;
245 else if (~afld.i & xfld.i & xcnt)
246 *(pc.base+p1.o[0]) = color;
247 else if (~afld.i & ~xfld.i & xcnt)
248 *(pc.base+p1.o[0]) = 0;
249 skip:
250 p1.l++;
251 j++;
252 xcnt >>= 1;
253 }
254 j -= 16;
255 p1.l += next - 16;
256 }
257 outp(0x3cd,segsel);
258 }
259
260
261 #else /* __GNUC__ */
262
263
264 void
mode_2_mark(x,y)265 mode_2_mark(x,y)
266
267 /* display cursor 256 color modes */
268 int x, y;
269 {
270 int i, next;
271 unsigned short xcnt, *amap, *xmap;
272 unsigned char pix, color, *px;
273 union {long l; unsigned short i; char s[4]; } afld, xfld;
274 vidmptr rgen;
275
276 amap = (unsigned short *) vgacur.map;
277 xmap = amap + 16;
278
279 px = vgacur.pbs;
280 next = pc.xsize;
281 rgen = pc.base + x + (long) (pc.ysize-1-y)*next;
282
283 color = pc.cursor_color;
284 outpw(0x3ce,0x3); /* set alu mode */
285
286 i = 16;
287 while (i--) {
288
289 afld.i = *(amap++);
290 xfld.i = *(xmap++);
291
292 xcnt = 0x8000;
293 while (xcnt) {
294
295 if (rgen >= pc.base) {
296 pix = *rgen;
297 if (x >= 0 && x < next) {
298 if (afld.i & xfld.i & xcnt)
299 *rgen = color ^ pix;
300 else if (~afld.i & xfld.i & xcnt)
301 *rgen = color;
302 else if (~afld.i & ~xfld.i & xcnt)
303 *rgen = 0;
304 }
305 *px++ = pix;
306 }
307 else
308 *px++ = 0;
309 rgen++;
310 x++;
311 xcnt >>= 1;
312 }
313 x -= 16;
314 rgen += next - 16;
315 }
316 }
317
318
319 #endif /* __GNUC__ */
320
321
322 void
mode_1_clear(x,y)323 mode_1_clear(x,y)
324
325 /* overwrite cursor 16 color modes */
326 int x, y;
327 {
328 int i, next;
329 unsigned char bitmask, mode, datarot, esetreset, planemask, rem, *px;
330 vidmptr rgen, rgen0;
331 int stop;
332
333 outp(0x3ce,0x5);
334 mode = inp(0x3cf);
335 outp(0x3cf,0x0); /* write mode 0 */
336
337 outp(0x3ce,0x3);
338 datarot = inp(0x3cf);
339 outp(0x3cf,0x0); /* straight thru */
340
341 outp(0x3ce,0x1);
342 esetreset = inp(0x3cf);
343 outp(0x3cf,0x0); /* enable set reset */
344
345 outp(0x3ce,0x8);
346 bitmask = inp(0x3cf);
347 outp(0x3cf,0xff); /* bit mask */
348
349 outp(0x3c4,0x2);
350 planemask = inp(0x3c5);
351
352 px = vgacur.pbs;
353
354 next = pc.bytpline;
355 rgen0 = pc.base + (x >> 3) + (long) (pc.ysize-y-1)*next;
356 stop = 16;
357 while (rgen0 < pc.base) {
358 rgen0 += next;
359 stop--;
360 }
361 next -= 2;
362
363 rem = 1;
364 while (rem & 0xf) {
365 rgen = rgen0;
366 outp(0x3c5,rem); /* write plane select */
367 for (i = 0; i < stop; i++) {
368
369 *rgen++ = *px++;
370 *rgen++ = *px++;
371 *rgen = *px++;
372
373 rgen += next;
374 }
375 px += 16;
376 rem <<= 1;
377 }
378
379 outp(0x3c5,planemask); /* write plane */
380 outp(0x3ce,0x1); outp(0x3cf,esetreset); /* enable set reset */
381 outp(0x3ce,0x3); outp(0x3cf,datarot); /* data rotate */
382 outp(0x3ce,0x5); outp(0x3cf,mode); /* write mode */
383 outp(0x3ce,0x8); outp(0x3cf,bitmask); /* bit mask */
384 }
385
386
387 #ifndef __GNUC__
388
389
390 void
mode_2_clear(x,y)391 mode_2_clear(x,y)
392
393 /* overwrite cursor 256 color modes */
394 int x, y;
395 {
396 int i, j, next;
397 unsigned char segsel, cbuf, *px;
398 union { unsigned short o[2]; long l; } p1;
399
400 segsel = inp(0x3cd); /* Tseng Labs segment selector */
401
402 px = vgacur.pbs;
403
404 next = pc.xsize;
405 p1.l = x + (long) (pc.ysize-1-y)*next;
406 next -= 16;
407
408 outp(0x3cd,cbuf = p1.o[1]);
409 outpw(0x3ce,0x3); /* set alu mode */
410 for (i = 0; i < 16; i++) {
411 for (j = 0; j < 16; j++) {
412 if (cbuf != p1.o[1])
413 outp(0x3cd,cbuf = p1.o[1]);
414 *(pc.base + p1.o[0]) = *px++;
415 p1.l++;
416 }
417 p1.l += next;
418 }
419 outp(0x3cd,segsel);
420 }
421
422
423 #else /* __GNUC__ */
424
425
426 void
mode_2_clear(x,y)427 mode_2_clear(x,y)
428
429 /* overwrite cursor 256 color modes */
430 int x, y;
431 {
432 int i, j, next;
433 unsigned char *px;
434 vidmptr rgen;
435
436 px = vgacur.pbs;
437 next = pc.xsize;
438 rgen = pc.base + x + (long) (pc.ysize-1-y)*next;
439 next -= 16;
440
441 outpw(0x3ce,0x3); /* set alu mode */
442
443 i = 16;
444 while (i--) {
445 j = 16;
446 while (j--) {
447 if (rgen >= pc.base)
448 *rgen = *px;
449 px++;
450 rgen++;
451 }
452 rgen += next;
453 }
454 }
455
456 #endif /* __GNUC__ */
457