OSDN Git Service

p16 is being worked on a bunch by me wwww [16_ca needs huge amounts of work and I...
[proj16/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 \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         gvar->video.ofs.displayofs = 0;\r
194         gvar->video.ofs.bufferofs = gvar->video.page[0].width*gvar->video.page[0].height;//gvar->video.page[0].pagesize;\r
195 }\r
196 \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 \r
492                                                         PIXEL OPS\r
493 \r
494 =============================================================================\r
495 */\r
496 \r
497 //byte  rightmasks[4] = {1,3,7,15};\r
498 \r
499 /*\r
500 =================\r
501 =\r
502 = VL_Plot\r
503 =\r
504 =================\r
505 */\r
506 \r
507 void VL_Plot (int x, int y, int color, ofs_t *ofs)\r
508 {\r
509         byte mask;\r
510         VCLIPDEF\r
511 \r
512         mask = pclip[x&3];\r
513         VGAMAPMASK(mask);\r
514         *(byte far *)MK_FP(SCREENSEG,ofs->bufferofs+(ofs->ylookup[y]+(x>>2))) = color;\r
515         VGAMAPMASK(15);\r
516 }\r
517 \r
518 \r
519 /*\r
520 =================\r
521 =\r
522 = VL_Hlin\r
523 =\r
524 =================\r
525 */\r
526 \r
527 void VL_Hlin    (unsigned x, unsigned y, unsigned width, unsigned color, ofs_t *ofs)\r
528 {\r
529         unsigned                xbyte;\r
530         byte                    far *dest;\r
531         byte                    leftmask,rightmask;\r
532         int                             midbytes;\r
533 \r
534         LRCLIPDEF\r
535 \r
536         xbyte = x>>2;\r
537         leftmask = lclip[x&3];\r
538         rightmask = rclip[(x+width-1)&3];\r
539         midbytes = ((x+width+3)>>2) - xbyte - 2;\r
540 \r
541         dest = MK_FP(SCREENSEG,ofs->bufferofs+ofs->ylookup[y]+xbyte);\r
542 \r
543         if (midbytes<0)\r
544         {\r
545         // all in       one byte\r
546                 VGAMAPMASK(leftmask&rightmask);\r
547                 *dest = color;\r
548                 VGAMAPMASK(15);\r
549                 return;\r
550         }\r
551 \r
552         VGAMAPMASK(leftmask);\r
553         *dest++ = color;\r
554 \r
555         VGAMAPMASK(15);\r
556         _fmemset (dest,color,midbytes);\r
557         dest+=midbytes;\r
558 \r
559         VGAMAPMASK(rightmask);\r
560         *dest = color;\r
561 \r
562         VGAMAPMASK(15);\r
563 }\r
564 \r
565 \r
566 /*\r
567 =================\r
568 =\r
569 = VL_Vlin\r
570 =\r
571 =================\r
572 */\r
573 \r
574 void VL_Vlin    (int x, int y, int height, int color, ofs_t *ofs)\r
575 {\r
576         byte    far *dest,mask;\r
577         VCLIPDEF\r
578 \r
579         mask = pclip[x&3];\r
580         VGAMAPMASK(mask);\r
581 \r
582         dest = MK_FP(SCREENSEG,ofs->bufferofs+ofs->ylookup[y]+(x>>2));\r
583 \r
584         while (height--)\r
585         {\r
586                 *dest = color;\r
587                 dest += ofs->linewidth;\r
588         }\r
589 \r
590         VGAMAPMASK(15);\r
591 }\r
592 \r
593 \r
594 /*\r
595 =================\r
596 =\r
597 = VL_Bar\r
598 =\r
599 =================\r
600 */\r
601 \r
602 void VL_Bar (int x, int y, int width, int height, int color, ofs_t *ofs)\r
603 {\r
604         byte    far *dest;\r
605         byte    leftmask,rightmask;\r
606         int             midbytes,linedelta;\r
607 \r
608         LRCLIPDEF\r
609 \r
610         leftmask = lclip[x&3];\r
611         rightmask = rclip[(x+width-1)&3];\r
612         midbytes = ((x+width+3)>>2) - (x>>2) - 2;\r
613         linedelta = ofs->linewidth-(midbytes+1);\r
614 \r
615         dest = MK_FP(SCREENSEG,ofs->bufferofs+ofs->ylookup[y]+(x>>2));\r
616 \r
617         if (midbytes<0)\r
618         {\r
619         // all in       one byte\r
620                 VGAMAPMASK(leftmask&rightmask);\r
621                 while (height--)\r
622                 {\r
623                         *dest = color;\r
624                         dest += ofs->linewidth;\r
625                 }\r
626                 VGAMAPMASK(15);\r
627                 return;\r
628         }\r
629 \r
630         while (height--)\r
631         {\r
632                 VGAMAPMASK(leftmask);\r
633                 *dest++ = color;\r
634 \r
635                 VGAMAPMASK(15);\r
636                 _fmemset (dest,color,midbytes);\r
637                 dest+=midbytes;\r
638 \r
639                 VGAMAPMASK(rightmask);\r
640                 *dest = color;\r
641 \r
642                 dest+=linedelta;\r
643         }\r
644 \r
645         VGAMAPMASK(15);\r
646 }\r
647 \r
648 //==========================================================================\r
649 \r
650 /*\r
651 =================\r
652 =\r
653 = VL_MemToScreen\r
654 =\r
655 = Draws a block of data to the screen.\r
656 =\r
657 =================\r
658 */\r
659 \r
660 void VL_MemToScreen (byte far *source, int width, int height, int x, int y, ofs_t *ofs)\r
661 {\r
662         byte    far *screen,far *dest,mask;\r
663         int             plane;\r
664 \r
665         width>>=2;\r
666         dest = MK_FP(SCREENSEG,ofs->bufferofs+ofs->ylookup[y]+(x>>2) );\r
667         mask = 1 << (x&3);\r
668 \r
669         for     (plane = 0; plane<4; plane++)\r
670         {\r
671                 VGAMAPMASK(mask);\r
672                 mask <<= 1;\r
673                 if (mask == 16)\r
674                         mask = 1;\r
675 \r
676                 screen = dest;\r
677                 for     (y=0;y<height;y++,screen+=ofs->linewidth,source+=width)\r
678                         _fmemcpy (screen,source,width);\r
679         }\r
680 }\r
681 \r
682 //==========================================================================\r
683 \r
684 /*\r
685 ==============\r
686 \r
687  VL_WaitVBL                     ******** NEW *********\r
688 \r
689  Wait for       the vertical retrace (returns before the actual vertical sync)\r
690 \r
691 ==============\r
692 */\r
693 \r
694 void VL_WaitVBL(word num)\r
695 {\r
696 //PROC  VL_WaitVBL  num:WORD\r
697 //PUBLIC        VL_WaitVBL\r
698 #ifdef __WATCOMC__\r
699         __asm {\r
700 #endif\r
701         wait:\r
702 #ifdef __BORLANDC__\r
703         __asm {\r
704 #endif\r
705 \r
706                 mov     dx,STATUS_REGISTER_1\r
707 \r
708                 mov     cx,[num]\r
709         //\r
710         // wait for     a display signal to make sure the raster isn't in       the middle\r
711         // of a sync\r
712         //\r
713 #ifdef __BORLANDC__\r
714         }\r
715 #endif\r
716         waitnosync:\r
717 #ifdef __BORLANDC__\r
718         __asm {\r
719 #endif\r
720                 in      al,dx\r
721                 test    al,8\r
722                 jnz     waitnosync\r
723 \r
724 \r
725 #ifdef __BORLANDC__\r
726         }\r
727 #endif\r
728         waitsync:\r
729 #ifdef __BORLANDC__\r
730         __asm {\r
731 #endif\r
732                 in      al,dx\r
733                 test    al,8\r
734                 jz      waitsync\r
735 \r
736                 loop    waitnosync\r
737 \r
738                 ret\r
739         }\r
740 }\r
741 \r
742 //===========================================================================\r
743 #if 0\r
744 #define VGAWRITEMODE(x) asm{\r
745                 cli\r
746                 mov     dx,GC_INDEX\r
747                 mov     al,GC_MODE\r
748                 out     dx,al\r
749                 inc     dx\r
750                 in      al,dx\r
751                 and     al,252\r
752                 or      al,x\r
753                 out     dx,al\r
754                 sti\r
755 }\r
756 \r
757 #define VGAMAPMASK(x) asm{\r
758                 cli\r
759                 mov     dx,SC_INDEX\r
760                 mov     al,SC_MAPMASK\r
761                 mov     ah,x\r
762                 out     dx,ax\r
763                 sti\r
764 }\r
765 \r
766 #define VGAREADMAP(x) asm{\r
767                 cli\r
768                 mov     dx,GC_INDEX\r
769                 mov     al,GC_READMAP\r
770                 mov     ah,x\r
771                 out     dx,ax\r
772                 sti\r
773 }\r
774 \r
775 #define EGABITMASK(x) asm{\r
776                 mov     dx,GC_INDEX\r
777                 mov     ax,GC_BITMASK+256*x\r
778                 out     dx,ax\r
779                 sti\r
780 }\r
781 #endif\r
782 void VGAWRITEMODE(byte x)\r
783 {\r
784         __asm {\r
785                 cli\r
786                 mov     dx,GC_INDEX\r
787                 mov     al,GC_MODE\r
788                 out     dx,al\r
789                 inc     dx\r
790                 in      al,dx\r
791                 and     al,252\r
792                 or      al,x\r
793                 out     dx,al\r
794                 sti\r
795         }\r
796 }\r
797 \r
798 void VGAMAPMASK(byte x)\r
799 {\r
800         __asm {\r
801                 cli\r
802                 mov     dx,SC_INDEX\r
803                 mov     al,SC_MAPMASK\r
804                 mov     ah,x\r
805                 out     dx,ax\r
806                 sti\r
807         }\r
808 }\r
809 \r
810 void VGAREADMAP(byte x)\r
811 {\r
812         __asm {\r
813                 cli\r
814                 mov     dx,GC_INDEX\r
815                 mov     al,GC_READMAP\r
816                 mov     ah,x\r
817                 out     dx,ax\r
818                 sti\r
819         }\r
820 }\r
821 \r
822 void VGABITMASK(byte x)\r
823 {\r
824         word q = 256*x;\r
825         __asm {\r
826                 mov     dx,GC_INDEX\r
827                 mov     ax,GC_BITMASK+q\r
828                 out     dx,ax\r
829                 sti\r
830         }\r
831 }\r
832 \r
833 //===========================================================================\r