]> 4ch.mooo.com Git - 16.git/blob - src/lib/16_vl_1.c
forgot to add it to reinitlibs
[16.git] / src / lib / 16_vl_1.c
1 /* Project 16 Source Code~\r
2  * Copyright (C) 2012-2022 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover\r
3  *\r
4  * This file is part of Project 16.\r
5  *\r
6  * Project 16 is free software; you can redistribute it and/or  modify\r
7  * it under the terms of the GNU General Public License as published by\r
8  * the Free Software Foundation; either version 3 of the License, or\r
9  * (at your option) any later version.\r
10  *\r
11  * Project 16 is distributed in the hope that it will be useful,\r
12  * but WITHOUT ANY WARRANTY; without    even the implied warranty of\r
13  * MERCHANTABILITY or   FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14  * GNU General Public License for       more details.\r
15  *\r
16  * You should have received a copy of the GNU General Public License\r
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>, or\r
18  * write to the Free Software Foundation, Inc., 51 Franklin     Street,\r
19  * Fifth Floor, Boston, MA 02110-1301 USA.\r
20  *\r
21  */\r
22 \r
23 #include <conio.h>\r
24 #include <stdio.h>\r
25 #include <stdlib.h>\r
26 #include "src/lib/16_vl.h"\r
27 \r
28 static word far* clockw= (word far*) 0x046C; /* 18.2hz clock */\r
29 //#define VGASTRIDEVARIABLE     vga_state.vga_stride\r
30 #define VGASTRIDEVARIABLE       gvar->video.page[0].stridew\r
31 \r
32 //===========================================================================\r
33 \r
34 //==============\r
35 //\r
36 // VL_SetScreen\r
37 //\r
38 //==============\r
39 \r
40 void    VL_SetScreen (unsigned int crtc, int pelpan)\r
41 {\r
42 // PROC VL_SetScreen  crtc:WORD, pel:WORD\r
43 // PUBLIC       VL_SetScreen\r
44         word TimeCount = *clockw;\r
45         __asm {\r
46                 mov     cx,[TimeCount]          // if TimeCount goes up by two, the retrace\r
47                 add     cx,2                            // period was missed (an interrupt covered it)\r
48 \r
49                 mov     dx,STATUS_REGISTER_1\r
50 \r
51         // wait for     a display signal to make sure the raster isn't in       the middle\r
52         // of a sync\r
53 \r
54 #ifdef __BORLANDC__\r
55         }\r
56 #endif\r
57 SetScreen_waitdisplay:\r
58 #ifdef __BORLANDC__\r
59         __asm {\r
60 #endif\r
61                 in      al,dx\r
62                 test    al,1    //1 = display is disabled (HBL / VBL)\r
63                 jnz     SetScreen_waitdisplay\r
64 \r
65 #ifdef __BORLANDC__\r
66         }\r
67 #endif\r
68 SetScreen_loop:\r
69 #ifdef __BORLANDC__\r
70         __asm {\r
71 #endif\r
72                 sti\r
73                 jmp     SetScreen_skip1\r
74                 cli\r
75 #ifdef __BORLANDC__\r
76         }\r
77 #endif\r
78 SetScreen_skip1:\r
79 #ifdef __BORLANDC__\r
80         __asm {\r
81 #endif\r
82                 cmp     [TimeCount],cx          // will only happen if an interrupt is\r
83                 jae     SetScreen_setcrtc                       // straddling the entire retrace period\r
84 \r
85         // when several succesive display not enableds occur,\r
86         // the bottom of the screen has been hit\r
87 \r
88                 in      al,dx\r
89                 test    al,8\r
90                 jnz     SetScreen_waitdisplay\r
91                 test    al,1\r
92                 jz      SetScreen_loop\r
93 \r
94                 in      al,dx\r
95                 test    al,8\r
96                 jnz     SetScreen_waitdisplay\r
97                 test    al,1\r
98                 jz      SetScreen_loop\r
99 \r
100                 in      al,dx\r
101                 test    al,8\r
102                 jnz     SetScreen_waitdisplay\r
103                 test    al,1\r
104                 jz      SetScreen_loop\r
105 \r
106                 in      al,dx\r
107                 test    al,8\r
108                 jnz     SetScreen_waitdisplay\r
109                 test    al,1\r
110                 jz      SetScreen_loop\r
111 \r
112                 in      al,dx\r
113                 test    al,8\r
114                 jnz     SetScreen_waitdisplay\r
115                 test    al,1\r
116                 jz      SetScreen_loop\r
117 \r
118 #ifdef __BORLANDC__\r
119         }\r
120 #endif\r
121 SetScreen_setcrtc:\r
122 #ifdef __BORLANDC__\r
123         __asm {\r
124 #endif\r
125         // set CRTC start\r
126         // for  some reason, my XT's EGA card doesn't like word outs to the CRTC index...\r
127 \r
128                 mov     cx,[crtc]\r
129                 mov     dx,CRTC_INDEX\r
130                 mov     al,0ch          //start address high register\r
131                 out     dx,al\r
132                 inc     dx\r
133                 mov     al,ch\r
134                 out     dx,al\r
135                 dec     dx\r
136                 mov     al,0dh          //start address low register\r
137                 out     dx,al\r
138                 mov     al,cl\r
139                 inc     dx\r
140                 out     dx,al\r
141 \r
142 \r
143         // set horizontal panning\r
144 \r
145                 mov     dx,ATR_INDEX\r
146 //              mov     al,ATR_PELPAN or        20h\r
147                 out     dx,al\r
148                 jmp     SetScreen_done\r
149                 mov     al,[BYTE PTR pelpan]            //pel pan value\r
150                 out     dx,al\r
151 #ifdef __BORLANDC__\r
152         }\r
153 #endif\r
154 SetScreen_done:\r
155 #ifdef __BORLANDC__\r
156         __asm {\r
157 #endif\r
158 //              sti\r
159 \r
160 //              ret\r
161         }\r
162 }\r
163 \r
164 /*\r
165 ====================\r
166 =\r
167 = VL_SetLineWidth\r
168 =\r
169 = Line witdh is in      WORDS, 40 words is normal width for     vgaplanegr\r
170 =\r
171 ====================\r
172 */\r
173 #if 0\r
174 void VL_SetLineWidth (unsigned width, global_game_variables_t *gvar)\r
175 {\r
176         int i,offset;\r
177 \r
178 //\r
179 // set wide virtual screen\r
180 //\r
181         outport (CRTC_INDEX,CRTC_OFFSET+width*256);\r
182 \r
183 //\r
184 // set up lookup tables\r
185 //\r
186         gvar->video.ofs.linewidth = width*2;\r
187 \r
188         offset = 0;\r
189 \r
190         for     (i=0;i<MAXSCANLINES;i++)\r
191         {\r
192                 gvar->video.ofs.ylookup[i]=offset;\r
193                 offset += gvar->video.ofs.linewidth;\r
194         }\r
195 }\r
196 #endif\r
197 /*\r
198 =============================================================================\r
199 \r
200                                                 PALETTE OPS\r
201 \r
202                 To avoid snow, do a WaitVBL BEFORE calling these\r
203 \r
204 =============================================================================\r
205 */\r
206 \r
207 \r
208 /*\r
209 =================\r
210 =\r
211 = VL_FillPalette\r
212 =\r
213 =================\r
214 */\r
215 \r
216 void VL_FillPalette (int red, int green, int blue)\r
217 {\r
218         int     i;\r
219 \r
220         outportb (PAL_WRITE_REG,0);\r
221         for     (i=0;i<256;i++)\r
222         {\r
223                 outportb (PAL_DATA_REG,red);\r
224                 outportb (PAL_DATA_REG,green);\r
225                 outportb (PAL_DATA_REG,blue);\r
226         }\r
227 }\r
228 \r
229 //===========================================================================\r
230 \r
231 /*\r
232 =================\r
233 =\r
234 = VL_SetColor\r
235 =\r
236 =================\r
237 */\r
238 \r
239 void VL_SetColor        (int color, int red, int green, int blue)\r
240 {\r
241         outportb (PAL_WRITE_REG,color);\r
242         outportb (PAL_DATA_REG,red);\r
243         outportb (PAL_DATA_REG,green);\r
244         outportb (PAL_DATA_REG,blue);\r
245 }\r
246 \r
247 //===========================================================================\r
248 \r
249 /*\r
250 =================\r
251 =\r
252 = VL_GetColor\r
253 =\r
254 =================\r
255 */\r
256 \r
257 void VL_GetColor        (int color, int *red, int *green, int *blue)\r
258 {\r
259         outportb (PAL_READ_REG,color);\r
260         *red = inportb (PAL_DATA_REG);\r
261         *green = inportb (PAL_DATA_REG);\r
262         *blue = inportb (PAL_DATA_REG);\r
263 }\r
264 \r
265 //===========================================================================\r
266 \r
267 /*\r
268 =================\r
269 =\r
270 = VL_SetPalette\r
271 =\r
272 = If fast palette setting has been tested for, it is used\r
273 = (some cards don't like outsb palette setting)\r
274 =\r
275 =================\r
276 */\r
277 \r
278 void VL_SetPalette (byte far *palette, video_t *v)\r
279 {\r
280 //      int     i;\r
281         boolean fastpalette;\r
282         fastpalette=v->fastpalette;\r
283 \r
284 //      outportb (PAL_WRITE_REG,0);\r
285 //      for     (i=0;i<768;i++)\r
286 //              outportb(PAL_DATA_REG,*palette++);\r
287 \r
288         __asm {\r
289                 mov     dx,PAL_WRITE_REG\r
290                 mov     al,0\r
291                 out     dx,al\r
292                 mov     dx,PAL_DATA_REG\r
293                 lds     si,[palette]\r
294 \r
295                 test    [ss:fastpalette],1\r
296                 jz      slowset\r
297 //\r
298 // set palette fast for cards that can take it\r
299 //\r
300                 //mov   cx,768\r
301                 //rep outsb\r
302                 //jmp   done\r
303 \r
304 //\r
305 // set palette slowly for       some video cards\r
306 //\r
307 #ifdef __BORLANDC__\r
308         }\r
309 #endif\r
310 slowset:\r
311 #ifdef __BORLANDC__\r
312         __asm {\r
313 #endif\r
314                 mov     cx,256\r
315 #ifdef __BORLANDC__\r
316         }\r
317 #endif\r
318 setloop:\r
319 #ifdef __BORLANDC__\r
320         __asm {\r
321 #endif\r
322                 lodsb\r
323                 out     dx,al\r
324                 lodsb\r
325                 out     dx,al\r
326                 lodsb\r
327                 out     dx,al\r
328                 loop    setloop\r
329 #ifdef __BORLANDC__\r
330         }\r
331 #endif\r
332 done:\r
333 #ifdef __BORLANDC__\r
334         __asm {\r
335 #endif\r
336                 mov     ax,ss\r
337                         mov     ds,ax\r
338         }\r
339         v->fastpalette=fastpalette;\r
340 }\r
341 \r
342 \r
343 //===========================================================================\r
344 \r
345 /*\r
346 =================\r
347 =\r
348 = VL_GetPalette\r
349 =\r
350 = This does not use the port string instructions,\r
351 = due to some incompatabilities\r
352 =\r
353 =================\r
354 */\r
355 \r
356 void VL_GetPalette (byte far *palette)\r
357 {\r
358         int     i;\r
359 \r
360         outportb (PAL_READ_REG,0);\r
361         for     (i=0;i<768;i++)\r
362                 *palette++ = inportb(PAL_DATA_REG);\r
363 }\r
364 \r
365 \r
366 //===========================================================================\r
367 \r
368 /*\r
369 =================\r
370 =\r
371 = VL_FadeOut\r
372 =\r
373 = Fades the current palette to the given color  in      the given number of steps\r
374 =\r
375 =================\r
376 */\r
377 \r
378 void VL_FadeOut (int start, int end, int red, int green, int blue, int steps, video_t *v)\r
379 {\r
380         int             i,j,orig,delta;\r
381         byte    far *origptr, far *newptr;\r
382 \r
383         VL_WaitVBL(1);\r
384         VL_GetPalette (&v->palette1[0][0]);\r
385         _fmemcpy (v->palette2,v->palette1,PALSIZE);\r
386 \r
387 //\r
388 // fade through intermediate frames\r
389 //\r
390         for     (i=0;i<steps;i++)\r
391         {\r
392                 origptr = &v->palette1[start][0];\r
393                 newptr = &v->palette2[start][0];\r
394                 for     (j=start;j<=end;j++)\r
395                 {\r
396                         orig = *origptr++;\r
397                         delta = red-orig;\r
398                         *newptr++ = orig + delta * i / steps;\r
399                         orig = *origptr++;\r
400                         delta = green-orig;\r
401                         *newptr++ = orig + delta * i / steps;\r
402                         orig = *origptr++;\r
403                         delta = blue-orig;\r
404                         *newptr++ = orig + delta * i / steps;\r
405                 }\r
406 \r
407                 VL_WaitVBL(1);\r
408                 VL_SetPalette (&v->palette2[0][0], v);\r
409         }\r
410 \r
411 //\r
412 // final color\r
413 //\r
414         VL_FillPalette (red,green,blue);\r
415 \r
416         v->screenfaded = true;\r
417 }\r
418 \r
419 \r
420 /*\r
421 =================\r
422 =\r
423 = VL_FadeIn\r
424 =\r
425 =================\r
426 */\r
427 \r
428 void VL_FadeIn (int start, int end, byte far *palette, int steps, video_t *v)\r
429 {\r
430         int             i,j,delta;\r
431 \r
432         VL_WaitVBL(1);\r
433         VL_GetPalette (&v->palette1[0][0]);\r
434         _fmemcpy (&v->palette2[0][0],&v->palette1[0][0],sizeof(v->palette1));\r
435 \r
436         start *= 3;\r
437         end = end*3+2;\r
438 \r
439 //\r
440 // fade through intermediate frames\r
441 //\r
442         for     (i=0;i<steps;i++)\r
443         {\r
444                 for     (j=start;j<=end;j++)\r
445                 {\r
446                         delta = palette[j]-v->palette1[0][j];\r
447                         v->palette2[0][j] = v->palette1[0][j] + delta * i / steps;\r
448                 }\r
449 \r
450                 VL_WaitVBL(1);\r
451                 VL_SetPalette (&v->palette2[0][0], v);\r
452         }\r
453 \r
454 //\r
455 // final color\r
456 //\r
457         VL_SetPalette (palette, v);\r
458         v->screenfaded = false;\r
459 }\r
460 \r
461 \r
462 \r
463 /*\r
464 =================\r
465 =\r
466 = VL_TestPaletteSet\r
467 =\r
468 = Sets the palette with outsb, then reads it in and     compares\r
469 = If it compares ok, fastpalette is set to true.\r
470 =\r
471 =================\r
472 */\r
473 \r
474 void VL_TestPaletteSet (video_t *v)\r
475 {\r
476         int     i;\r
477 \r
478         for     (i=0;i<768;i++)\r
479                 v->palette1[0][i] = i;\r
480 \r
481         v->fastpalette = true;\r
482         VL_SetPalette (&v->palette1[0][0], v);\r
483         VL_GetPalette (&v->palette2[0][0]);\r
484         if (_fmemcmp (&v->palette1[0][0],&v->palette2[0][0],768))\r
485                 v->fastpalette = false;\r
486 }\r
487 \r
488 /*\r
489 ==================\r
490 =\r
491 = VL_ColorBorder\r
492 =\r
493 ==================\r
494 */\r
495 \r
496 void VL_ColorBorder (int color, video_t *v)\r
497 {\r
498         union REGS in, out;\r
499 \r
500         in.h.ah = 0x10;\r
501         in.h.al = 0x01;\r
502         in.h.bh = color;\r
503         int86(0x10, &in, &out);\r
504         v->bordercolor = color;\r
505 }\r
506 \r
507 \r
508 /*\r
509 =============================================================================\r
510 \r
511                                                         PIXEL OPS\r
512 \r
513 =============================================================================\r
514 */\r
515 \r
516 //byte  rightmasks[4] = {1,3,7,15};\r
517 \r
518 /*\r
519 =================\r
520 =\r
521 = VL_Plot\r
522 =\r
523 =================\r
524 */\r
525 \r
526 void VL_Plot (int x, int y, int color, global_game_variables_t *gvar)\r
527 {\r
528         byte mask;\r
529         VCLIPDEF\r
530 \r
531         if(!gvar->video.VL_Started) return;\r
532 \r
533         mask = pclip[x&3];\r
534         VGAMAPMASK(mask);\r
535         //*(byte far *)MK_FP(SCREENSEG,gvar->video.ofs.bufferofs+(gvar->video.ofs.ylookup[y]+(x>>2))) = color;\r
536         //*(byte far *)MK_FP(SCREENSEG,gvar->video.ofs.bufferofs+((y*VGASTRIDEVARIABLE)+(x>>2))) = color;\r
537         *(byte far *)MK_FP(SCREENSEG,BDOFSCONV gvar->video.BOFS+((y*VGASTRIDEVARIABLE)+(x>>2))) = color;\r
538         VGAMAPMASK(15);\r
539 }\r
540 \r
541 \r
542 /*\r
543 =================\r
544 =\r
545 = VL_Hlin\r
546 =\r
547 =================\r
548 */\r
549 \r
550 void VL_Hlin    (unsigned x, unsigned y, unsigned width, unsigned color, global_game_variables_t *gvar)\r
551 {\r
552         unsigned                xbyte;\r
553         byte                    far *dest;\r
554         byte                    leftmask,rightmask;\r
555         int                             midbytes;\r
556 \r
557         LRCLIPDEF\r
558 \r
559         if(!gvar->video.VL_Started) return;\r
560 \r
561         xbyte = x>>2;\r
562         leftmask = lclip[x&3];\r
563         rightmask = rclip[(x+width-1)&3];\r
564         midbytes = ((x+width+3)>>2) - xbyte - 2;\r
565 \r
566         //dest = MK_FP(SCREENSEG,gvar->video.ofs.bufferofs+gvar->video.ofs.ylookup[y]+xbyte);\r
567         dest = MK_FP(SCREENSEG,BDOFSCONV gvar->video.BOFS+(y*VGASTRIDEVARIABLE)+xbyte);\r
568 \r
569         if (midbytes<0)\r
570         {\r
571         // all in       one byte\r
572                 VGAMAPMASK(leftmask&rightmask);\r
573                 *dest = color;\r
574                 VGAMAPMASK(15);\r
575                 return;\r
576         }\r
577 \r
578         VGAMAPMASK(leftmask);\r
579         *dest++ = color;\r
580 \r
581         VGAMAPMASK(15);\r
582         _fmemset (dest,color,midbytes);\r
583         dest+=midbytes;\r
584 \r
585         VGAMAPMASK(rightmask);\r
586         *dest = color;\r
587 \r
588         VGAMAPMASK(15);\r
589 }\r
590 \r
591 \r
592 /*\r
593 =================\r
594 =\r
595 = VL_Vlin\r
596 =\r
597 =================\r
598 */\r
599 \r
600 void VL_Vlin    (int x, int y, int height, int color, global_game_variables_t *gvar)\r
601 {\r
602         byte    far *dest,mask;\r
603         VCLIPDEF\r
604 \r
605         if(!gvar->video.VL_Started) return;\r
606 \r
607         mask = pclip[x&3];\r
608         VGAMAPMASK(mask);\r
609 \r
610         //dest = MK_FP(SCREENSEG,gvar->video.ofs.bufferofs+gvar->video.ofs.ylookup[y]+(x>>2));\r
611         dest = MK_FP(SCREENSEG,BDOFSCONV gvar->video.BOFS+(y*VGASTRIDEVARIABLE)+(x>>2));\r
612 \r
613         while (height--)\r
614         {\r
615                 *dest = color;\r
616                 //dest += gvar->video.ofs.linewidth;\r
617                 dest += VGASTRIDEVARIABLE;\r
618         }\r
619 \r
620         VGAMAPMASK(15);\r
621 }\r
622 \r
623 \r
624 /*\r
625 =================\r
626 =\r
627 = VL_Bar\r
628 =\r
629 =================\r
630 */\r
631 \r
632 void VL_Bar (int x, int y, int width, int height, int color, global_game_variables_t *gvar)\r
633 {\r
634         byte    far *dest;\r
635         byte    leftmask,rightmask;\r
636         int             midbytes,linedelta;\r
637 \r
638         LRCLIPDEF\r
639 \r
640         if(!gvar->video.VL_Started) return;\r
641 \r
642         leftmask = lclip[x&3];\r
643         rightmask = rclip[(x+width-1)&3];\r
644         midbytes = ((x+width+3)>>2) - (x>>2) - 2;\r
645         //linedelta = gvar->video.ofs.linewidth-(midbytes+1);\r
646         linedelta = VGASTRIDEVARIABLE-(midbytes+1);\r
647 \r
648         //dest = MK_FP(SCREENSEG,gvar->video.ofs.bufferofs+gvar->video.ofs.ylookup[y]+(x>>2));\r
649         dest = MK_FP(SCREENSEG,BDOFSCONV gvar->video.BOFS+(y*VGASTRIDEVARIABLE)+(x>>2));\r
650 \r
651         if (midbytes<0)\r
652         {\r
653         // all in       one byte\r
654                 VGAMAPMASK(leftmask&rightmask);\r
655                 while (height--)\r
656                 {\r
657                         *dest = color;\r
658                         //dest += gvar->video.ofs.linewidth;\r
659                         dest += VGASTRIDEVARIABLE;\r
660                 }\r
661                 VGAMAPMASK(15);\r
662                 return;\r
663         }\r
664 \r
665         while (height--)\r
666         {\r
667                 VGAMAPMASK(leftmask);\r
668                 *dest++ = color;\r
669 \r
670                 VGAMAPMASK(15);\r
671                 _fmemset (dest,color,midbytes);\r
672                 dest+=midbytes;\r
673 \r
674                 VGAMAPMASK(rightmask);\r
675                 *dest = color;\r
676 \r
677                 dest+=linedelta;\r
678         }\r
679 \r
680         VGAMAPMASK(15);\r
681 }\r
682 \r
683 //==========================================================================\r
684 \r
685 /*\r
686 =================\r
687 =\r
688 = VL_MemToScreen\r
689 =\r
690 = Draws a block of data to the screen.\r
691 =\r
692 =================\r
693 */\r
694 \r
695 void VL_MemToScreen (byte far *source, int width, int height, int x, int y, global_game_variables_t *gvar)\r
696 {\r
697         byte    far *screen,far *dest,mask;\r
698         int             plane;\r
699 \r
700         width>>=2;\r
701         //dest = MK_FP(SCREENSEG,gvar->video.ofs.bufferofs+gvar->video.ofs.ylookup[y]+(x>>2));\r
702         dest = MK_FP(SCREENSEG,BDOFSCONV gvar->video.BOFS+(y*VGASTRIDEVARIABLE)+(x>>2));\r
703         mask = 1 << (x&3);\r
704 \r
705         for     (plane = 0; plane<4; plane++)\r
706         {\r
707                 VGAMAPMASK(mask);\r
708                 mask <<= 1;\r
709                 if (mask == 16)\r
710                         mask = 1;\r
711 \r
712                 screen = dest;\r
713                 //for   (y=0;y<height;y++,screen+=gvar->video.ofs.linewidth,source+=width)\r
714                 for     (y=0;y<height;y++,screen+=VGASTRIDEVARIABLE,source+=width)\r
715                         _fmemcpy (screen,source,width);\r
716         }\r
717 }\r
718 \r
719 //==========================================================================\r
720 \r
721 /*\r
722 ==============\r
723 \r
724  VL_WaitVBL                     ******** NEW *********\r
725 \r
726  Wait for       the vertical retrace (returns before the actual vertical sync)\r
727 \r
728 ==============\r
729 */\r
730 \r
731 void VL_WaitVBL(word num)\r
732 {\r
733 //PROC  VL_WaitVBL  num:WORD\r
734 //PUBLIC        VL_WaitVBL\r
735 #ifdef __WATCOMC__\r
736         __asm {\r
737 #endif\r
738         wait:\r
739 #ifdef __BORLANDC__\r
740         __asm {\r
741 #endif\r
742 \r
743                 mov     dx,STATUS_REGISTER_1\r
744 \r
745                 mov     cx,[num]\r
746         //\r
747         // wait for     a display signal to make sure the raster isn't in       the middle\r
748         // of a sync\r
749         //\r
750 #ifdef __BORLANDC__\r
751         }\r
752 #endif\r
753         waitnosync:\r
754 #ifdef __BORLANDC__\r
755         __asm {\r
756 #endif\r
757                 in      al,dx\r
758                 test    al,8\r
759                 jnz     waitnosync\r
760 \r
761 \r
762 #ifdef __BORLANDC__\r
763         }\r
764 #endif\r
765         waitsync:\r
766 #ifdef __BORLANDC__\r
767         __asm {\r
768 #endif\r
769                 in      al,dx\r
770                 test    al,8\r
771                 jz      waitsync\r
772 \r
773                 loop    waitnosync\r
774 \r
775                 ret\r
776         }\r
777 }\r
778 \r
779 //===========================================================================\r
780 #if 0\r
781 #define VGAWRITEMODE(x) asm{\r
782                 cli\r
783                 mov     dx,GC_INDEX\r
784                 mov     al,GC_MODE\r
785                 out     dx,al\r
786                 inc     dx\r
787                 in      al,dx\r
788                 and     al,252\r
789                 or      al,x\r
790                 out     dx,al\r
791                 sti\r
792 }\r
793 \r
794 #define VGAMAPMASK(x) asm{\r
795                 cli\r
796                 mov     dx,SC_INDEX\r
797                 mov     al,SC_MAPMASK\r
798                 mov     ah,x\r
799                 out     dx,ax\r
800                 sti\r
801 }\r
802 \r
803 #define VGAREADMAP(x) asm{\r
804                 cli\r
805                 mov     dx,GC_INDEX\r
806                 mov     al,GC_READMAP\r
807                 mov     ah,x\r
808                 out     dx,ax\r
809                 sti\r
810 }\r
811 \r
812 #define EGABITMASK(x) asm{\r
813                 mov     dx,GC_INDEX\r
814                 mov     ax,GC_BITMASK+256*x\r
815                 out     dx,ax\r
816                 sti\r
817 }\r
818 #endif\r
819 void VGAWRITEMODE(byte x)\r
820 {\r
821         __asm {\r
822                 cli\r
823                 mov     dx,GC_INDEX\r
824                 mov     al,GC_MODE\r
825                 out     dx,al\r
826                 inc     dx\r
827                 in      al,dx\r
828                 and     al,252\r
829                 or      al,x\r
830                 out     dx,al\r
831                 sti\r
832         }\r
833 }\r
834 \r
835 void VGAMAPMASK(byte x)\r
836 {\r
837         __asm {\r
838                 cli\r
839                 mov     dx,SC_INDEX\r
840                 mov     al,SC_MAPMASK\r
841                 mov     ah,x\r
842                 out     dx,ax\r
843                 sti\r
844         }\r
845 }\r
846 \r
847 void VGAREADMAP(byte x)\r
848 {\r
849         __asm {\r
850                 cli\r
851                 mov     dx,GC_INDEX\r
852                 mov     al,GC_READMAP\r
853                 mov     ah,x\r
854                 out     dx,ax\r
855                 sti\r
856         }\r
857 }\r
858 \r
859 void VGABITMASK(byte x)\r
860 {\r
861         word q = 256*x;\r
862         __asm {\r
863                 mov     dx,GC_INDEX\r
864                 mov     ax,GC_BITMASK+q\r
865                 out     dx,ax\r
866                 sti\r
867         }\r
868 }\r
869 \r
870 //===========================================================================\r