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