1 /*
2 * Written by Matthew Parker and released to the public domain.
3 */
4
5 #ifdef __DJGPP__
6
7 #include <conio.h>
8 #include <dpmi.h>
9 #include <sys/farptr.h>
10
11 #define mypokew(a,b,c) _farpokew(a,(b)<<1,c)
12 #define mypeekw(a,b) _farpeekw(a,(b)<<1)
13
14 #else
15
16 #ifdef __FLAT__
17 #include <i86.h>
18 #include "rmi.h"
19 extern struct rminfo RMINF;
20 #define MKSEG(a) ((unsigned short *)(a << 4))
21 #else
22 #include <dos.h>
23 #define MKSEG(a) MK_FP(vseg, 0)
24 #endif
25
26 #ifndef MK_FP
27 #define MK_FP(x,y) ((void *)(((unsigned long)(x) << 16) | (unsigned)(y)))
28 #endif
29
30 #define mypokew(a,b,c) *((a) + (b)) = (c)
31 #define mypeekw(a,b) *((a) + (b))
32
33 #endif
34
35 #include "vio.h"
36
37 static unsigned short vseg = 0xb000;
38 static unsigned char vmode = 0;
39 static unsigned short x = 0;
40 static unsigned short y = 0;
41 static unsigned char color = 7;
42 static unsigned short ofs = 0;
43 static unsigned char xhite = 8;
44
45 struct VIOinfo
46 {
47 unsigned char level;
48 unsigned char level1;
49 unsigned short level2;
50 unsigned short flags;
51 unsigned char mode;
52 unsigned char mode1;
53 unsigned short colors;
54 unsigned short pixcol;
55 unsigned short pixrow;
56 unsigned short txtcol;
57 unsigned short txtrow;
58 }
59 info =
60 {
61 0, 0, 14, 1, 0, 0, 2, 0, 0, 80, 25
62 };
63
VIOheight(void)64 unsigned short VIOheight(void)
65 {
66 return xhite;
67 }
68
VIOopen(void)69 unsigned short VIOopen(void)
70 {
71 #ifndef __FLAT__
72 struct SREGS s;
73 #endif
74 #ifdef __DJGPP__
75 __dpmi_regs r;
76 #else
77 union REGS r;
78 unsigned short temp;
79 #endif
80
81 #if defined(__DJGPP__)
82 r.x.ax = 0x0f00;
83 __dpmi_int(0x10, &r);
84 #elif defined(__FLAT__)
85 r.w.ax = 0xf00;
86 int386(0x10, &r, &r);
87 #else
88 r.x.ax = 0xf00;
89 int86(0x10, &r, &r);
90 #endif
91 vmode = r.h.al;
92
93 if (r.h.al == 7)
94 {
95 return 0;
96 }
97 else
98 {
99 info.txtcol = r.h.ah;
100 vseg = 0xb800;
101 #if defined(__DJGPP__)
102 r.x.ax = 0xfe00;
103 r.x.es = vseg;
104 r.x.di = 0;
105 __dpmi_int(0x10, &r);
106 vseg = r.x.es;
107 #elif defined(__FLAT__)
108 RMINF.EAX = 0xfe00;
109 RMINF.ES = vseg;
110 temp = RMINF.EDI;
111 RMINF.EDI = 0;
112 int86x(0x10);
113 RMINF.EDI = temp;
114 vseg = RMINF.ES;
115 #else
116 r.x.ax = 0xfe00;
117 s.es = vseg;
118 temp = r.x.di;
119 r.x.di = 0;
120 int86x(0x10, &r, &r, &s);
121 r.x.di = temp;
122 vseg = s.es;
123 #endif
124 #if defined(__DJGPP__)
125 r.x.ax = 0x1130;
126 r.h.bh = 0x1;
127 r.x.dx = 0;
128 __dpmi_int(0x10, &r);
129 #elif defined(__FLAT__)
130 r.w.ax = 0x1130;
131 r.h.bh = 0x1;
132 r.w.dx = 0;
133 int386(0x10, &r, &r);
134 #else
135 r.x.ax = 0x1130;
136 r.h.bh = 0x1;
137 r.x.dx = 0;
138 int86(0x10, &r, &r);
139 #endif
140 if (r.h.dl == 0) /* cga */
141 {
142 info.txtrow = 25;
143 return 0;
144 }
145 xhite = r.h.cl;
146 info.txtrow = r.h.dl + 1;
147 }
148 return 0;
149 }
150
VIOclose(void)151 void VIOclose(void)
152 {
153 }
154
VIOcolumns(void)155 unsigned short VIOcolumns(void)
156 {
157 return info.txtcol;
158 }
159
VIOrows(void)160 unsigned short VIOrows(void)
161 {
162 return info.txtrow;
163 }
164
VIOmode(void)165 unsigned short VIOmode(void)
166 {
167 return vmode;
168 }
169
VIOwherex(void)170 unsigned short VIOwherex(void)
171 {
172 return x;
173 }
174
VIOwherey(void)175 unsigned short VIOwherey(void)
176 {
177 return y;
178 }
179
VIOscrollright(int x1,int y1,int x2,int y2,int count)180 void VIOscrollright(int x1, int y1, int x2, int y2, int count)
181 {
182 #if defined(__DJGPP__)
183 int vid = __dpmi_segment_to_descriptor(vseg);
184 #else
185 unsigned short *vid = MKSEG(vseg);
186 #endif
187 int far_right = y1 * info.txtcol + x2;
188 int width = x2 - x1;
189 int depth = y2 - y1 + 2;
190 int i, t;
191
192 while (depth--)
193 {
194 for (i = 0; i < count; i++)
195 {
196 for (t = 0; t < width; t++)
197 {
198 mypokew(vid, far_right + t, mypeekw(vid, far_right + t - 1));
199 }
200 mypokew(vid, far_right + t, (color << 8) | 0x20);
201 }
202 far_right += info.txtcol;
203 }
204 }
205
VIOscrollleft(int x1,int y1,int x2,int y2,int count)206 void VIOscrollleft(int x1, int y1, int x2, int y2, int count)
207 {
208 #if defined(__DJGPP__)
209 int vid = __dpmi_segment_to_descriptor(vseg);
210 #else
211 unsigned short *vid = MKSEG(vseg);
212 #endif
213 int far_right = y1 * info.txtcol + x2;
214 int width = x2 - x1;
215 int depth = y2 - y1 + 2;
216 int i, t;
217
218 while (depth--)
219 {
220 for (i = 0; i < count; i++)
221 {
222 for (t = 0; t < width; t++)
223 {
224 mypokew(vid, far_right + t - 1, mypeekw(vid, far_right + t));
225 }
226 mypokew(vid, far_right + width, (color << 8) | 0x20);
227 }
228 far_right += info.txtcol;
229 }
230 }
231
VIOscrollup(int x1,int y1,int x2,int y2,int count)232 void VIOscrollup(int x1, int y1, int x2, int y2, int count)
233 {
234 #if defined(__DJGPP__)
235 int vid = __dpmi_segment_to_descriptor(vseg);
236 #else
237 unsigned short *vid = MKSEG(vseg);
238 #endif
239 int far_right = y1 * info.txtcol + x1;
240 int width = x2 - x1;
241 int depth = y2 - y1;
242 int screen_width = info.txtcol;
243 int i;
244
245 while (count--)
246 {
247 while (depth--)
248 {
249 for (i = 0; i < width; i++)
250 {
251 mypokew(vid, far_right + i, mypeekw(vid, far_right + screen_width + i));
252 }
253 far_right += screen_width;
254 }
255
256 for (i = 0; i < width; i++)
257 {
258 mypokew(vid, far_right + i, (color << 8) | 0x20);
259 }
260 }
261 }
262
VIOscrolldown(int x1,int y1,int x2,int y2,int count)263 void VIOscrolldown(int x1, int y1, int x2, int y2, int count)
264 {
265 #if defined(__DJGPP__)
266 int vid = __dpmi_segment_to_descriptor(vseg);
267 #else
268 unsigned short *vid = MKSEG(vseg);
269 #endif
270 int far_right = y2 * info.txtcol + x1;
271 int width = x2 - x1;
272 int depth = y2 - y1;
273 int screen_width = info.txtcol;
274 int i;
275
276 while (count--)
277 {
278 while (depth--)
279 {
280 for (i = 0; i < width; i++)
281 {
282 mypokew(vid, far_right + i, mypeekw(vid, far_right - screen_width + i));
283 }
284 far_right -= screen_width;
285 }
286
287 for (i = width; i > 0; i--)
288 {
289 mypokew(vid, far_right + i - 1, (color << 8) | 0x20);
290 }
291 }
292 }
293
VIOclear(int x1,int y1,int x2,int y2)294 void VIOclear(int x1, int y1, int x2, int y2)
295 {
296 #if defined(__DJGPP__)
297 int vid = __dpmi_segment_to_descriptor(vseg);
298 #else
299 unsigned short *vid = MKSEG(vseg);
300 #endif
301 int far_right = y1 * info.txtcol + x1;
302 int width = x2 - x1 + 1;
303 int depth = y2 - y1 + 1;
304 int i;
305
306 while (depth--)
307 {
308 for (i = 0; i < width; i++)
309 {
310 mypokew(vid, far_right + i, (color << 8) | 0x20);
311 }
312 far_right += info.txtcol;
313 }
314 }
315
VIOputc(const char c)316 void VIOputc(const char c)
317 {
318 #if defined(__DJGPP__)
319 int vid = __dpmi_segment_to_descriptor(vseg);
320 #else
321 unsigned short *vid = MKSEG(vseg);
322 #endif
323
324 mypokew(vid, ofs, c+(color<<8));
325 ofs++;
326 x++;
327
328 if (x >= info.txtcol)
329 {
330 y++;
331 x = x - info.txtcol;
332 }
333 }
334
VIOputs(const char * s)335 void VIOputs(const char *s)
336 {
337 #if defined(__DJGPP__)
338 int vid = __dpmi_segment_to_descriptor(vseg);
339 #else
340 unsigned short *vid = MKSEG(vseg);
341 #endif
342
343 while (*s != '\0')
344 {
345 mypokew(vid, ofs, *s+(color<<8));
346 s++;
347 x++;
348 ofs++;
349 }
350
351 if (x >= info.txtcol)
352 {
353 y++;
354 x = x - info.txtcol;
355 }
356 }
357
VIOgetca(const int x,const int y)358 unsigned short VIOgetca(const int x, const int y)
359 {
360 #if defined(__DJGPP__)
361 int vid = __dpmi_segment_to_descriptor(vseg);
362 #else
363 unsigned short *vid = MKSEG(vseg);
364 #endif
365 int far_right = y * info.txtcol + x;
366 return mypeekw(vid, far_right);
367 }
368
VIOgetra(int x1,int y1,int x2,int y2,unsigned short * b)369 void VIOgetra(int x1, int y1, int x2, int y2, unsigned short *b)
370 {
371 #if defined(__DJGPP__)
372 int vid = __dpmi_segment_to_descriptor(vseg);
373 #else
374 unsigned short *vid = MKSEG(vseg);
375 #endif
376 int far_right = y1 * info.txtcol + x1;
377 int width = x2 - x1 + 1;
378 int depth = y2 - y1 + 1;
379 int i;
380
381 while (depth--)
382 {
383 for (i = 0; i < width; i++)
384 {
385 *b = mypeekw(vid, far_right + i);
386 b++;
387 }
388 far_right += info.txtcol;
389 }
390 }
391
VIOputr(int x,int y,int w,int h,unsigned short * b)392 void VIOputr(int x, int y, int w, int h, unsigned short *b)
393 {
394 #if defined(__DJGPP__)
395 int vid = __dpmi_segment_to_descriptor(vseg);
396 #else
397 unsigned short *vid = MKSEG(vseg);
398 #endif
399 int far_right = y * info.txtcol + x;
400 int screen_length = info.txtcol;
401 int i;
402
403 while (h--)
404 {
405 for (i = 0; i < w; i++)
406 {
407 mypokew(vid, far_right + i, *b);
408 b++;
409 }
410 far_right += screen_length;
411 }
412 }
413
VIOsetfore(const int c)414 void VIOsetfore(const int c)
415 {
416 color = (unsigned char)((c & 0x0f) | (color & 0xf0));
417 }
418
VIOsetback(const int c)419 void VIOsetback(const int c)
420 {
421 color = (unsigned char)(((c & 0x0f) << 4) | (color & 0x0f));
422 }
423
VIOgetfore(void)424 unsigned short VIOgetfore(void)
425 {
426 return (int)(color & 0x0f);
427 }
428
VIOgetback(void)429 unsigned short VIOgetback(void)
430 {
431 return (int)((color & 0xf0) >> 4);
432 }
433
VIOgotoxy(int x1,int y1)434 void VIOgotoxy(int x1, int y1)
435 {
436 x = x1;
437 y = y1;
438 ofs = y1 * info.txtcol + x1;
439 }
440
VIOupdate(void)441 void VIOupdate(void)
442 {
443 #ifdef __DJGPP__
444 __dpmi_regs r;
445 #else
446 union REGS r;
447 #endif
448 r.h.ah = 2;
449 r.h.bh = 0;
450 r.h.dl = x;
451 r.h.dh = y;
452 #if defined(__DJGPP__)
453 __dpmi_int(0x10, &r);
454 #elif defined(__FLAT__)
455 int386(0x10, &r, &r);
456 #else
457 int86(0x10, &r, &r);
458 #endif
459 }
460
VIOcursor(int * x,int * y,int * shape)461 void VIOcursor(int *x, int *y, int *shape)
462 {
463 #ifdef __DJGPP__
464 __dpmi_regs r;
465 #else
466 union REGS r;
467 #endif
468 r.h.ah = 3;
469 r.h.bh = 0;
470 #if defined(__DJGPP__)
471 __dpmi_int(0x10, &r);
472 #elif defined(__FLAT__)
473 int386(0x10, &r, &r);
474 #else
475 int86(0x10, &r, &r);
476 #endif
477 *x = (unsigned int)r.h.dl;
478 *y = (unsigned int)r.h.dh;
479 #if defined(__FLAT__) && !defined(__DJGPP__)
480 *shape = r.w.cx;
481 #else
482 *shape = r.x.cx;
483 #endif
484 }
485
VIOsegment(void)486 unsigned short VIOsegment(void)
487 {
488 return vseg;
489 }
490
VIOsetSegment(unsigned int s)491 void VIOsetSegment(unsigned int s)
492 {
493 vseg = s;
494 }
495
VIOsetRows(int r)496 void VIOsetRows(int r)
497 {
498 info.txtrow = r;
499 }
500
VIOsetCols(int c)501 void VIOsetCols(int c)
502 {
503 info.txtcol = c;
504 }
505