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 #define ror(x,n) ((x >> n)  | (x << (8-n)))
12 
13 #ifdef __STDC__
14 static void mode_1_box(int,int,int,int);
15 static void mode_2_box(int,int,int,int);
16 #else
17 static void mode_1_box();
18 static void mode_2_box();
19 #endif
20 
21 
22 void
MFBBox(x1,y1,x2,y2)23 MFBBox(x1,y1,x2,y2)
24 
25 int x1,y1,x2,y2;
26 {
27     if (pc.mfbMODE & 2)
28         mode_2_box(x1,y1,x2,y2);
29     else
30         mode_1_box(x1,y1,x2,y2);
31 }
32 
33 
34 static void
mode_1_box(xl,yl,xu,yu)35 mode_1_box(xl,yl,xu,yu)
36 
37 int xl, yl, xu, yu;
38 {
39     int lnum, dx, tx, dy, next, *st = NULL;
40     vidmptr rgen;
41     unsigned char left, right, cbuf;
42     union { unsigned short color2; unsigned char c[2]; } c;
43 
44     if (yu < yl) MFBSwapInt(yu,yl);
45     if (xu < xl) MFBSwapInt(xu,xl);
46 
47     /* expand box so that it covers a box formed of lines with the
48      * same coordinates
49      */
50     xu++;
51     yl--;
52 
53     if (pc.curfillpatt)
54         st = pc.stipples[pc.curfillpatt];
55 
56     c.c[0] = pc.curcolor;
57     c.c[1] = c.c[0];
58     lnum = (pc.ysize-1-yu);
59     dy = yu - yl;
60 
61     left  =  (0xff >> (xl & 7));
62     right = ~(0xff >> (xu & 7));
63     dx = (xu >> 3) - (xl >>= 3) - 1;
64     if (dx < 0) { left &= right; dx = 0; right = 0; }
65     rgen = pc.base + xl + (long) lnum*pc.bytpline;
66     next = pc.bytpline - 1 - dx;
67 
68     outpw(0x3ce,0x0b05); /* read mode 1, write mode 3 */
69     outpw(0x3ce,c.color2 & 0xff00); /* set/reset */
70     outpw(0x3ce,0x7); /* zero color dont care */
71     outpw(0x3ce,pc.alumode); /* set alu mode */
72 
73     cbuf = 0xff;
74 
75     if (!st) {
76 
77         while (dy--) {
78             mfb_trash = *rgen;
79             *rgen = left;
80             rgen++;
81             tx = dx;
82             while (tx--) {
83                 mfb_trash = *rgen;
84                 *rgen = cbuf;
85                 rgen++;
86             }
87             mfb_trash = *rgen;
88             *rgen = right;
89             rgen += next;
90         }
91     }
92     else {
93         while (dy--) {
94             cbuf = st[lnum++ & 7];
95             mfb_trash = *rgen;
96             *rgen = left & cbuf;
97             rgen++;
98             tx = dx;
99             while (tx--) {
100                 mfb_trash = *rgen;
101                 *rgen = cbuf;
102                 rgen++;
103             }
104             mfb_trash = *rgen;
105             *rgen = right & cbuf;
106             rgen += next;
107         }
108     }
109 
110     outpw(0x3ce,0x5);
111     outpw(0x3ce,0xff07);
112 }
113 
114 
115 #ifndef __GNUC__
116 
117 
118 static void
mode_2_box(xl,yl,xu,yu)119 mode_2_box(xl,yl,xu,yu)
120 
121 int xl, yl, xu, yu;
122 {
123     int lnum, dy, next, *st = NULL;
124     unsigned short dx, tx;
125     unsigned char left, right, cbuf;
126     union { unsigned short o[2]; long l; } p1, p2;
127     union { unsigned short color2; unsigned char c[2]; } c;
128     vidmptr rgen;
129 
130     if (yu < yl) MFBSwapInt(yu,yl);
131     if (xu < xl) MFBSwapInt(xu,xl);
132 
133     outpw(0x3ce,0xff08);     /* set bit mask */
134     outpw(0x3ce,pc.alumode); /* set alu mode */
135 
136     /* expand box so that it covers a box formed of lines with the
137      * same coordinates
138      */
139     xu++;
140     yl--;
141 
142     if (pc.curfillpatt)
143         st = pc.stipples[pc.curfillpatt];
144 
145     c.c[0] = pc.curcolor;
146     c.c[1] = c.c[0];
147     lnum = (pc.ysize-1-yu);
148     dy = yu - yl;
149     dx = xu - xl;
150     p1.l = xl + (long) lnum*pc.xsize;
151     p2.l = p1.l + dx;
152 
153     cbuf = inp(0x3cd);
154     cbuf |= (cbuf << 4);
155     next = pc.xsize;
156 
157     if (!st) {
158 
159         while (dy--) {
160             if ((cbuf & 0xf) != p1.o[1]) {
161                 cbuf = p1.o[1];
162                 cbuf |= (cbuf << 4);
163                 outp(0x3cd,cbuf);
164             }
165             if (p1.o[1] != p2.o[1])
166                 tx = ~(p1.o[0]) + 1;
167             else
168                 tx = dx;
169             rgen = pc.base + p1.o[0];
170 
171             if (pc.alumode == 0x3) {
172                 if ((unsigned)rgen & 1) {
173                     *rgen = c.c[0];
174                     rgen++;
175                     tx--;
176                 }
177                 if (tx & 1)
178                     *(rgen + tx - 1) = c.c[0];
179                 tx >>= 1;
180                 while (tx--) {
181                     *(short far *)rgen = c.color2;
182                     rgen += 2;
183                 }
184             }
185             else {
186                 while (tx--) {
187                     mfb_trash = *rgen;
188                     *rgen = c.c[0];
189                     rgen++;
190                 }
191             }
192             if (p1.o[1] != p2.o[1]) {
193                 cbuf += 0x11;
194                 outp(0x3cd,cbuf);
195                 tx = p2.o[0];
196                 rgen = pc.base;
197                 if (pc.alumode == 0x3) {
198                     if (tx & 1)
199                         *(rgen + tx - 1) = c.c[0];
200                     tx >>= 1;
201                     while (tx--) {
202                         *(short far *)rgen = c.color2;
203                         rgen += 2;
204                     }
205                 }
206                 else {
207                     while (tx--) {
208                         mfb_trash = *rgen;
209                         *rgen = c.c[0];
210                         rgen++;
211                     }
212                 }
213             }
214             p2.l += next;
215             p1.l += next;
216         }
217     }
218 
219     else {
220 
221         while (dy--) {
222             left = 0x80 >> (xl & 7);
223             right = st[lnum++ & 7];
224 
225             if ((cbuf & 0xf) != p1.o[1]) {
226                 cbuf = p1.o[1];
227                 cbuf |= (cbuf << 4);
228                 outp(0x3cd,cbuf);
229             }
230             if (p1.o[1] != p2.o[1])
231                 tx = ~(p1.o[0]) + 1;
232             else
233                 tx = dx;
234             rgen = pc.base + p1.o[0];
235 
236             while (tx--) {
237                 if (left & right) {
238                     if (pc.alumode != 3)
239                         mfb_trash = *rgen;
240                     *rgen = c.c[0];
241                 }
242                 left = ror(left,1);
243                 rgen++;
244             }
245 
246             if (p1.o[1] != p2.o[1]) {
247                 cbuf += 0x11;
248                 outp(0x3cd,cbuf);
249                 tx = p2.o[0];
250                 rgen = pc.base;
251                 while (tx--) {
252                     if (left & right) {
253                         if (pc.alumode != 3)
254                             mfb_trash = *rgen;
255                         *rgen = c.c[0];
256                     }
257                     left = ror(left,1);
258                     rgen++;
259                 }
260             }
261             p1.l += next;
262             p2.l += next;
263         }
264     }
265 }
266 
267 
268 #else /* __GNUC__ */
269 
270 
271 static void
mode_2_box(xl,yl,xu,yu)272 mode_2_box(xl,yl,xu,yu)
273 
274 int xl, yl, xu, yu;
275 {
276     int lnum, dx, tx, dy, next, *st = NULL;
277     unsigned char left, right;
278     union { unsigned short color2; unsigned char c[2]; } c;
279     vidmptr rgen;
280 
281     if (yu < yl) MFBSwapInt(yu,yl);
282     if (xu < xl) MFBSwapInt(xu,xl);
283 
284     outpw(0x3ce,0xff08);     /* set bit mask */
285     outpw(0x3ce,pc.alumode); /* set alu mode */
286 
287     /* expand box so that it covers a box formed of lines with the
288      * same coordinates
289      */
290     xu++;
291     yl--;
292 
293     if (pc.curfillpatt)
294         st = pc.stipples[pc.curfillpatt];
295 
296     c.c[0] = pc.curcolor;
297     c.c[1] = c.c[0];
298     lnum = (pc.ysize-1-yu);
299     dy = yu - yl;
300     dx = xu - xl;
301     rgen = pc.base + xl + (long) lnum*pc.xsize;
302     next = pc.xsize - dx;
303 
304     if (!st) {
305 
306         if (pc.alumode == 0x3) {
307 
308             while (dy--) {
309                 tx = dx;
310                 if ((unsigned)rgen & 1) {
311                     *rgen = c.c[0];
312                     rgen++;
313                     tx--;
314                 }
315                 left = tx & 1;
316                 tx >>= 1;
317                 while (tx--) {
318                     *(short*)rgen = c.color2;
319                     rgen += 2;
320                 }
321                 if (left) {
322                     *rgen = c.c[0];
323                     rgen++;
324                 }
325                 rgen += next;
326             }
327         }
328         else {
329 
330             while (dy--) {
331                 tx = dx;
332                 while (tx--) {
333                     mfb_trash = *rgen;
334                     *rgen = c.c[0];
335                     rgen++;
336                 }
337                 rgen += next;
338             }
339         }
340     }
341 
342     else {
343 
344         while (dy--) {
345             left = 0x80 >> (xl & 7);
346             right = st[lnum++ & 7];
347 
348             tx = dx;
349             while (tx--) {
350                 if (left & right) {
351                     if (pc.alumode != 3)
352                         mfb_trash = *rgen;
353                     *rgen = c.c[0];
354                 }
355                 left = ror(left,1);
356                 rgen++;
357             }
358             rgen += next;
359         }
360     }
361 }
362 
363 #endif /* __GNUC__ */
364