]> 4ch.mooo.com Git - 16.git/blob - src/lib/modex16.c
fe997dd741b8a7853c29465064de95b1fc396230
[16.git] / src / lib / modex16.c
1 /* Project 16 Source Code~\r
2  * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669\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 verson 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/modex16.h"\r
27 \r
28 byte far* VGA=(byte far*) 0xA0000000;   /* this points to video memory. */\r
29 \r
30 static void fadePalette(sbyte fade, sbyte start, word iter, byte *palette);\r
31 static byte tmppal[PAL_SIZE];\r
32 \r
33 /////////////////////////////////////////////////////////////////////////////\r
34 //                                                                                                                                                                                                                                              //\r
35 // setvideo() - This function Manages the video modes                                                                                           //\r
36 //                                                                                                                                                                                                                                              //\r
37 /////////////////////////////////////////////////////////////////////////////\r
38 void VGAmodeX(sword vq, boolean cmem, global_game_variables_t *gv)\r
39 {\r
40         union REGS in, out;\r
41 \r
42         switch (vq)\r
43         {\r
44                 case 0: // deinit the video\r
45                         // change to the video mode we were in before we switched to mode 13h\r
46                         modexLeave();\r
47                         in.h.ah = 0x00;\r
48                         in.h.al = gv->video.old_mode;\r
49                         int86(0x10, &in, &out);\r
50                 break;\r
51                 default: // init the video\r
52                         // get old video mode\r
53                         //in.h.ah = 0xf;\r
54                         //int86(0x10, &in, &out);\r
55                         gv->video.old_mode = vgaGetMode();//out.h.al;\r
56                         // enter mode\r
57                         modexEnter(vq, cmem, gv);\r
58                 break;\r
59         }\r
60 }\r
61 \r
62 static void\r
63 vgaSetMode(byte mode)\r
64 {\r
65   int10_setmode(mode);\r
66 }\r
67 \r
68 //---------------------------------------------------\r
69 //\r
70 // Use the bios to get the current video mode\r
71 //\r
72 \r
73 byte/*FIXME: why long? "long" is 32-bit datatype, VGA modes are 8-bit numbers. */\r
74 vgaGetMode()\r
75 {\r
76     return int10_getmode();\r
77 }\r
78 \r
79 /* -========================= Entry  Points ==========================- */\r
80 void modexEnter(sword vq, boolean cmem, global_game_variables_t *gv)\r
81 {\r
82         word i;\r
83         struct vga_mode_params cm;\r
84         int CRTParmCount;\r
85 \r
86         vgaSetMode(VGA_256_COLOR_MODE);\r
87         vga_enable_256color_modex();\r
88         update_state_from_vga();\r
89         vga_read_crtc_mode(&cm);\r
90 \r
91         switch(vq)\r
92         {\r
93                 case 1:\r
94                         //CRTParmCount = sizeof(ModeX_320x240regs) / sizeof(ModeX_320x240regs[0]);\r
95                         /*for(i=0; i<CRTParmCount; i++) {\r
96                                 outpw(CRTC_INDEX, ModeX_320x240regs[i]);\r
97                         }*/\r
98                         /* width and height */\r
99                         gv->video.page[0].sw = vga_state.vga_width = 320; // VGA lib currently does not update this\r
100                         gv->video.page[0].sh = vga_state.vga_height = 240; // VGA lib currently does not update this\r
101                         /* virtual width and height. match screen, at first */\r
102                         gv->video.page[0].height = gv->video.page[0].sh;\r
103                         gv->video.page[0].width = gv->video.page[0].sw;\r
104 \r
105                         // mode X BYTE mode\r
106                         cm.word_mode = 0;\r
107                         cm.dword_mode = 0;\r
108                         // 320x240 mode 60Hz\r
109                         cm.horizontal_total=0x5f + 5; /* CRTC[0]             -5 */\r
110                         cm.horizontal_display_end=0x4f + 1; /* CRTC[1]       -1 */\r
111                         cm.horizontal_blank_start=0x50 + 1; /* CRTC[2] */\r
112                         cm.horizontal_blank_end=0x82 + 1;   /* CRTC[3] bit 0-4 & CRTC[5] bit 7 */\r
113                         cm.horizontal_start_retrace=0x54;/* CRTC[4] */\r
114                         cm.horizontal_end_retrace=0x80; /* CRTC[5] bit 0-4 */\r
115                         //cm.horizontal_start_delay_after_total=0x3e; /* CRTC[3] bit 5-6 */\r
116                         //cm.horizontal_start_delay_after_retrace=0x41; /* CRTC[5] bit 5-6 */\r
117                         cm.vertical_total = 0x20D + 2;\r
118                         cm.vertical_start_retrace = 0x1EA;\r
119                         cm.vertical_end_retrace = 0x1EC;\r
120                         cm.vertical_display_end = 480;\r
121                         cm.vertical_blank_start = 0x1E7 + 1;\r
122                         cm.vertical_blank_end = 0x206 + 1;\r
123                         cm.clock_select = 0; /* misc register = 0xE3  25MHz */\r
124                         cm.vsync_neg = 1;\r
125                         cm.hsync_neg = 1;\r
126                         cm.offset = (vga_state.vga_width / (4 * 2)); // 320 wide (40 x 4 pixel groups x 2)\r
127                         break;\r
128                 case 2: // TODO: 160x120 according to ModeX_160x120regs\r
129                         return;\r
130                 case 3: // TODO: 160x120 according to ModeX_320x200regs\r
131                         return;\r
132                 case 4: // TODO: 160x120 according to ModeX_192x144regs\r
133                         return;\r
134                 case 5: // TODO: 160x120 according to ModeX_256x192regs\r
135                         return;\r
136                 default:\r
137                         return;\r
138         }\r
139 \r
140         vga_state.vga_stride = cm.offset * 2;\r
141         vga_write_crtc_mode(&cm,0);\r
142 \r
143         /* clear video memory */\r
144         switch (cmem)\r
145         {\r
146                 case 1: {\r
147                         /* clear video memory */\r
148                         dword far*ptr=(dword far*)vga_state.vga_graphics_ram;//VGA;      /* used for faster screen clearing */\r
149                         vga_write_sequencer(2/*map mask register*/,0xf/*all 4 planes*/);\r
150                         for(i = 0;i < 0x4000; i++) ptr[i] = 0x0000; // 0x4000 x dword = 64KB\r
151                 }\r
152                 break;\r
153         }\r
154 \r
155 //      gv->video.page[0].tw = gv->video.page[0].sw/TILEWH;\r
156 //      gv->video.page[0].th = gv->video.page[0].sh/TILEWH;\r
157 \r
158         //TODO MAKE FLEXIBLE~\r
159 //      gv->video.page[0].tilemidposscreenx = gv->video.page[0].tilesw;\r
160 //      gv->video.page[0].tilemidposscreeny = (gv->video.page[0].tilesh/2)+1;\r
161 }\r
162 \r
163 void\r
164 modexLeave() {\r
165         /* VGAmodeX restores original mode and palette */\r
166         vgaSetMode(TEXT_MODE);\r
167 }\r
168 \r
169 page_t\r
170 modexDefaultPage(page_t *p)\r
171 {\r
172     page_t page;\r
173 \r
174     /* default page values */\r
175         //page.data = VGA;\r
176         //page.data = (byte far *)(vga_state.vga_graphics_ram);\r
177         page.data = (vga_state.vga_graphics_ram);\r
178     page.dx = 0;\r
179     page.dy = 0;\r
180         page.sw = p->sw;\r
181         page.sh = p->sh;\r
182         page.width = p->sw+TILEWHD;\r
183         page.height = p->sh+TILEWHD;\r
184         page.tw = page.sw/TILEWH;\r
185         page.th = page.sh/TILEWH;\r
186         page.tilesw=page.width/TILEWH;\r
187         page.tilesh=page.height/TILEWH;\r
188         page.tilemidposscreenx = page.tw/2;\r
189         page.tilemidposscreeny = (page.th/2)+1;\r
190         page.stridew=page.width/4;\r
191         page.pagesize = (sdiword)(page.width/4)*page.height;\r
192         page.id = 0;\r
193 \r
194     return page;\r
195 }\r
196 \r
197 /* returns the next page in contiguous memory\r
198  * the next page will be the same size as p, by default\r
199  */\r
200 page_t\r
201 modexNextPage(page_t *p) {\r
202     page_t result;\r
203 \r
204     result.data = p->data + (p->pagesize);\r
205     result.dx = 0;\r
206     result.dy = 0;\r
207         result.sw = p->sw;\r
208         result.sh = p->sh;\r
209     result.width = p->width;\r
210     result.height = p->height;\r
211         result.tw = p->tw;\r
212         result.th = p->th;\r
213         result.tilesw = p->tilesw;\r
214         result.tilesh = p->tilesh;\r
215         result.id = p->id+1;\r
216         result.stridew=p->stridew;\r
217         result.pagesize = p->pagesize;\r
218 \r
219         return result;\r
220 }\r
221 \r
222 //next page with defined dimentions~\r
223 page_t\r
224 modexNextPageFlexibleSize(page_t *p, word x, word y)\r
225 {\r
226         page_t result;\r
227 \r
228         result.data = p->data + (p->pagesize);  /* compute the offset */\r
229         result.dx = 0;\r
230         result.dy = 0;\r
231         result.sw = x;\r
232         result.sh = y;\r
233         result.width = x;\r
234         result.height = y;\r
235         result.tw = result.sw/TILEWH;\r
236         result.th = result.sh/TILEWH;\r
237         result.tilesw=result.width/TILEWH;\r
238         result.tilesh=result.height/TILEWH;\r
239         result.id = p->id+1;\r
240         result.stridew=result.width/4;\r
241         result.pagesize = (sdiword)(result.width/4)*result.height;\r
242 \r
243         return result;\r
244 }\r
245 \r
246 void modexCalcVmemRemain(video_t *video)\r
247 {\r
248         byte i;\r
249         //printf("\n\n  1st vmem_remain=%ld\n", video->vmem_remain);\r
250         for(i=0; i<=video->num_of_pages-1; i++)\r
251         {\r
252                 video->vmem_remain-=video->page[i].pagesize;\r
253                 //printf("              [%u], video->page[i].pagesize=%ld\n", i, video->page[i].pagesize);\r
254                 //printf("              [%u], vmem_remain=%ld\n", i, video->vmem_remain);\r
255         }\r
256 }\r
257 \r
258 void modexHiganbanaPageSetup(video_t *video)\r
259 {\r
260         video->vmem_remain=262144L;\r
261         video->num_of_pages=0;\r
262         (video->page[0]) = modexDefaultPage(&(video->page[0])); video->num_of_pages++;\r
263         //video->page[0].width += (TILEWHD); video->page[0].height += (TILEWHD);\r
264         (video->page[1]) = modexNextPage(&(video->page[0]));    video->num_of_pages++;\r
265         //(video->page[2]) = modexNextPageFlexibleSize(&(video->page[1]), video->page[0].width, video->page[0].sh-40);  video->num_of_pages++;\r
266         //(video->page[3]) = modexNextPageFlexibleSize(&(video->page[2]), TILEWH, TILEWH);      video->num_of_pages++;\r
267         modexCalcVmemRemain(video);\r
268         video->p=0;\r
269 }\r
270 \r
271 void\r
272 modexShowPage(page_t *page) {\r
273     word high_address;\r
274     word low_address;\r
275     word offset;\r
276     byte crtcOffset;\r
277 \r
278     /* calculate offset */\r
279     offset = (word) page->data;\r
280     offset += page->dy * (page->width >> 2 );\r
281     offset += page->dx >> 2;\r
282 \r
283     /* calculate crtcOffset according to virtual width */\r
284     crtcOffset = page->width >> 3;\r
285 \r
286     high_address = HIGH_ADDRESS | (offset & 0xff00);\r
287     low_address  = LOW_ADDRESS  | (offset << 8);\r
288 \r
289     /* wait for appropriate timing and then program CRTC */\r
290     while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));\r
291     outpw(CRTC_INDEX, high_address);\r
292     outpw(CRTC_INDEX, low_address);\r
293     outp(CRTC_INDEX, 0x13);\r
294     outp(CRTC_DATA, crtcOffset);\r
295 \r
296     /*  wait for one retrace */\r
297     while (!(inp(INPUT_STATUS_1) & VRETRACE));\r
298 \r
299     /* do PEL panning here */\r
300     outp(AC_INDEX, 0x33);\r
301     outp(AC_INDEX, (page->dx & 0x03) << 1);\r
302 }\r
303 \r
304 void\r
305 modexPanPage(page_t *page, int dx, int dy) {\r
306     page->dx = dx;\r
307     page->dy = dy;\r
308 }\r
309 \r
310 void\r
311 modexSelectPlane(byte plane) {\r
312     outp(SC_INDEX, MAP_MASK);     /* select plane */\r
313     outp(SC_DATA,  plane);\r
314 }\r
315 \r
316 void\r
317 modexClearRegion(page_t *page, int x, int y, int w, int h, byte  color) {\r
318     word pageOff = (word) page->data;\r
319     word xoff=x/4;       /* xoffset that begins each row */\r
320     word scanCount=w/4;  /* number of iterations per row (excluding right clip)*/\r
321     word poffset = pageOff + y*(page->stridew) + xoff; /* starting offset */\r
322     word nextRow = page->stridew-scanCount-1;  /* loc of next row */\r
323     byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08};  /* clips for rectangles not on 4s */\r
324     byte rclip[] = {0x00, 0x01, 0x03, 0x07};\r
325     byte left = lclip[x&0x03];\r
326     byte right = rclip[(x+w)&0x03];\r
327 \r
328     /* handle the case which requires an extra group */\r
329     if((x & 0x03) && !((x+w) & 0x03)) {\r
330       right=0x0f;\r
331     }\r
332 \r
333     __asm {\r
334             PUSHF\r
335             PUSH ES\r
336             PUSH AX\r
337             PUSH BX\r
338             PUSH CX\r
339             PUSH DX\r
340             PUSH SI\r
341             PUSH DI\r
342                 MOV AX, SCREEN_SEG      ; go to the VGA memory\r
343                 MOV ES, AX\r
344                 MOV DI, poffset  ; go to the first pixel\r
345                 MOV DX, SC_INDEX        ; point to the map mask\r
346                 MOV AL, MAP_MASK\r
347                 OUT DX, AL\r
348                 INC DX\r
349                 MOV AL, color      ; get ready to write colors\r
350         SCAN_START:\r
351                 MOV CX, scanCount       ; count the line\r
352                 MOV BL, AL            ; remember color\r
353                 MOV AL, left        ; do the left clip\r
354                 OUT DX, AL            ; set the left clip\r
355                 MOV AL, BL            ; restore color\r
356                 STOSB              ; write the color\r
357                 DEC CX\r
358                 JZ SCAN_DONE        ; handle 1 group stuff\r
359 \r
360                 ;-- write the main body of the scanline\r
361                 MOV BL, AL            ; remember color\r
362                 MOV AL, 0x0f        ; write to all pixels\r
363                 OUT DX, AL\r
364                 MOV AL, BL            ; restore color\r
365                 REP STOSB              ; write the color\r
366         SCAN_DONE:\r
367                 MOV BL, AL            ; remeber color\r
368                 MOV AL, right\r
369                 OUT DX, AL            ; do the right clip\r
370                 MOV AL, BL            ; restore color\r
371                 STOSB              ; write pixel\r
372                 ADD DI, nextRow  ; go to the next row\r
373                 DEC h\r
374                 JNZ SCAN_START\r
375             POP DI\r
376             POP SI\r
377             POP DX\r
378             POP CX\r
379             POP BX\r
380             POP AX\r
381             POP ES\r
382             POPF\r
383     }\r
384 }\r
385 \r
386 /* moved to src/lib/modex16/16render.c */\r
387 \r
388 /* copy a region of video memory from one page to another.\r
389  * It assumes that the left edge of the tile is the same on both\r
390  * regions and the memory areas do not overlap.\r
391  */\r
392 void\r
393 modexCopyPageRegion(page_t *dest, page_t *src,\r
394                     word sx, word sy,\r
395                     word dx, word dy,\r
396                     word width, word height)\r
397 {\r
398     word doffset = (word)dest->data + dy*(dest->stridew) + dx/4;\r
399     word soffset = (word)src->data + sy*(src->stridew) + sx/4;\r
400     word scans   = vga_state.vga_stride;\r
401     word nextSrcRow = src->stridew - scans - 1;\r
402     word nextDestRow = dest->stridew - scans - 1;\r
403     byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08};  /* clips for rectangles not on 4s */\r
404     byte rclip[] = {0x0f, 0x01, 0x03, 0x07};\r
405     byte left = lclip[sx&0x03];\r
406     byte right = rclip[(sx+width)&0x03];\r
407 \r
408     __asm {\r
409             PUSHF\r
410             PUSH ES\r
411             PUSH AX\r
412             PUSH BX\r
413             PUSH CX\r
414             PUSH DX\r
415             PUSH SI\r
416             PUSH DI\r
417 \r
418                 MOV AX, SCREEN_SEG      ; work in the vga space\r
419                 MOV ES, AX            ;\r
420                 MOV DI, doffset  ;\r
421                 MOV SI, soffset  ;\r
422 \r
423                 MOV DX, GC_INDEX        ; turn off cpu bits\r
424                 MOV AX, 0008h      ;\r
425                 OUT DX, AX\r
426 \r
427                 MOV AX, SC_INDEX        ; point to the mask register\r
428                 MOV DX, AX            ;\r
429                 MOV AL, MAP_MASK        ;\r
430                 OUT DX, AL            ;\r
431                 INC DX            ;\r
432 \r
433         ROW_START:\r
434                 PUSH DS\r
435                 MOV AX, ES\r
436                 MOV DS, AX\r
437                 MOV CX, scans      ; the number of latches\r
438 \r
439                 MOV AL, left        ; do the left column\r
440                 OUT DX, AL            ;\r
441                 MOVSB              ;\r
442                 DEC CX            ;\r
443 \r
444                 MOV AL, 0fh          ; do the inner columns\r
445                 OUT DX, AL\r
446                 REP MOVSB              ; copy the pixels\r
447 \r
448                 MOV AL, right      ; do the right column\r
449                 OUT DX, AL\r
450                 MOVSB\r
451                 POP DS\r
452 \r
453                 MOV AX, SI            ; go the start of the next row\r
454                 ADD AX, nextSrcRow      ;\r
455                 MOV SI, AX            ;\r
456                 MOV AX, DI            ;\r
457                 ADD AX, nextDestRow     ;\r
458                 MOV DI, AX            ;\r
459 \r
460                 DEC height            ; do the rest of the actions\r
461                 JNZ ROW_START      ;\r
462 \r
463                 MOV DX, GC_INDEX+1      ; go back to CPU data\r
464                 MOV AL, 0ffh        ; none from latches\r
465                 OUT DX, AL            ;\r
466 \r
467             POP DI\r
468             POP SI\r
469             POP DX\r
470             POP CX\r
471             POP BX\r
472             POP AX\r
473             POP ES\r
474             POPF\r
475     }\r
476 }\r
477 \r
478 \r
479 /* fade and flash */\r
480 void\r
481 modexFadeOn(word fade, byte *palette) {\r
482     fadePalette(-fade, 64, 64/fade+1, palette);\r
483 }\r
484 \r
485 \r
486 void\r
487 modexFadeOff(word fade, byte *palette) {\r
488     fadePalette(fade, 0, 64/fade+1, palette);\r
489 }\r
490 \r
491 \r
492 void\r
493 modexFlashOn(word fade, byte *palette) {\r
494     fadePalette(fade, -64, 64/fade+1, palette);\r
495 }\r
496 \r
497 \r
498 void\r
499 modexFlashOff(word fade, byte *palette) {\r
500     fadePalette(-fade, 0, 64/fade+1, palette);\r
501 }\r
502 \r
503 \r
504 static void\r
505 fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {\r
506     word i;\r
507     byte dim = start;\r
508 \r
509     /* handle the case where we just update */\r
510     if(iter == 0) {\r
511         modexPalUpdate1(palette);\r
512         return;\r
513     }\r
514 \r
515     while(iter > 0) {  /* FadeLoop */\r
516         for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */\r
517             tmppal[i] = palette[i] - dim;\r
518             if(tmppal[i] > 127) {\r
519                 tmppal[i] = 0;\r
520             } else if(tmppal[i] > 63) {\r
521                 tmppal[i] = 63;\r
522             }\r
523         }\r
524         modexPalUpdate1(tmppal);\r
525         iter--;\r
526         dim += fade;\r
527     }\r
528 }\r
529 \r
530 \r
531 /* save and load */\r
532 void\r
533 modexPalSave(byte *palette) {\r
534     int  i;\r
535 \r
536     outp(PAL_READ_REG, 0);      /* start at palette entry 0 */\r
537     for(i=0; i<PAL_SIZE; i++) {\r
538         palette[i] = inp(PAL_DATA_REG); /* read the palette data */\r
539     }\r
540 }\r
541 \r
542 \r
543 byte *\r
544 modexNewPal() {\r
545     byte *ptr;\r
546     ptr = malloc(PAL_SIZE);\r
547 \r
548     /* handle errors */\r
549     if(!ptr) {\r
550         printf("Could not allocate palette.\n");\r
551         exit(-1);\r
552     }\r
553 \r
554     return ptr;\r
555 }\r
556 \r
557 \r
558 void\r
559 modexLoadPalFile(byte *filename, byte **palette) {\r
560     FILE *file;\r
561     byte *ptr;\r
562 \r
563     /* free the palette if it exists */\r
564     if(*palette) {\r
565         free(*palette);\r
566     }\r
567 \r
568     /* allocate the new palette */\r
569     *palette = modexNewPal();\r
570 \r
571     /* open the file */\r
572     file = fopen(filename, "rb");\r
573     if(!file) {\r
574         printf("Could not open palette file: %s\n", filename);\r
575         exit(-2);\r
576     }\r
577 \r
578     /* read the file */\r
579     ptr = *palette;\r
580     while(!feof(file)) {\r
581         *ptr++ = fgetc(file);\r
582     }\r
583 \r
584     fclose(file);\r
585 }\r
586 \r
587 \r
588 void\r
589 modexSavePalFile(char *filename, byte *pal) {\r
590     unsigned int i;\r
591     FILE *file;\r
592 \r
593     /* open the file for writing */\r
594     file = fopen(filename, "wb");\r
595     if(!file) {\r
596         printf("Could not open %s for writing\n", filename);\r
597         exit(-2);\r
598     }\r
599 \r
600     /* write the data to the file */\r
601     fwrite(pal, 1, PAL_SIZE, file);\r
602     fclose(file);\r
603 }\r
604 \r
605 \r
606 /* blanking */\r
607 void\r
608 modexPalBlack() {\r
609     fadePalette(-1, 64, 1, tmppal);\r
610 }\r
611 \r
612 \r
613 void\r
614 modexPalWhite() {\r
615     fadePalette(-1, -64, 1, tmppal);\r
616 }\r
617 \r
618 \r
619 /* utility */\r
620 void\r
621 modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)\r
622 {\r
623         byte *p = bmp->palette;\r
624         word w=0;\r
625         word q=0;\r
626         word qq=0;\r
627         static word a[PAL_SIZE];        //palette array of change values!\r
628         word z=0, aq=0, aa=0, pp=0;\r
629 \r
630         //modexWaitBorder();\r
631         vga_wait_for_vsync();\r
632         if((*i)==0)\r
633         {\r
634                 memset(a, -1, sizeof(a));\r
635                 outp(PAL_WRITE_REG, 0);  /* start at the beginning of palette */\r
636         }\r
637         else if(qp==0)\r
638         {\r
639                 q=(*i);\r
640         }\r
641         else\r
642         {\r
643                 q=(*i);\r
644                 qq=(*i)/3;\r
645 //            printf("q: %02d\n", (q));\r
646 //            printf("qq: %02d\n", (qq));\r
647                 //printf("      (*i)-q=%02d\n", (*i)-q);\r
648                 outp(PAL_WRITE_REG, qq);  /* start at the beginning of palette */\r
649         }\r
650         if((*i)<PAL_SIZE/2 && w==0)\r
651         {\r
652                 for(; (*i)<PAL_SIZE/2; (*i)++)\r
653                 {\r
654                         //if(i%3==0 && (p[i+5]==p[i+4] && p[i+4]==p[i+3] && p[i+3]==p[i+2] && p[i+2]==p[i+1] && p[i+1]==p[i] && p[i+5]==p[i]))\r
655 //____            if((qp>0)&&((*i)-q)%3==0 && (p[((*i)-q)]==p[((*i)-q)+3] && p[((*i)-q)+1]==p[((*i)-q)+4] && p[((*i)-q)+2]==p[((*i)-q)+5])) outp(PAL_DATA_REG, p[(*i)-q]); else\r
656                         if(((((*i)-q)%3==0)) && (p[((*i)-q)]==p[((*i)-q)+3] && p[((*i)-q)+1]==p[((*i)-q)+4] && p[((*i)-q)+2]==p[((*i)-q)+5]))\r
657                         {\r
658                                 w++;\r
659                                 break;\r
660                         }\r
661                         else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))\r
662                         {\r
663                                 //printf("qp=%d\n", qp);\r
664                                 //printf("            (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);\r
665                                 printf("                %d's color=%d\n", (*i), (a[qp])-(bmp->offset*3)+qp);\r
666                                 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!\r
667                                 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }\r
668                         }\r
669                         else\r
670                         {\r
671                                 if(bmp->offset==0 && (*i)<3 && q==0) outp(PAL_DATA_REG, 0);\r
672                                 else\r
673                                 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);\r
674                                 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);\r
675                                 printf("p[]=%d  qp=%d   p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }\r
676                         }\r
677                 }\r
678                 //if(qp>0) printf("qp=%d\n", qp);\r
679                 //if(qp>0) printf("                                          (*i)=%d\n", (*i)/3);\r
680         }\r
681         //modexWaitBorder();      /* waits one retrace -- less flicker */\r
682         vga_wait_for_vsync();\r
683         if((*i)>=PAL_SIZE/2 && w==0)\r
684         {\r
685                 for(; (*i)<PAL_SIZE; (*i)++)\r
686                 {\r
687 //____            if((qp>0)&&((*i)-q)%3==0 && (p[((*i)-q)]==p[((*i)-q)+3] && p[((*i)-q)+1]==p[((*i)-q)+4] && p[((*i)-q)+2]==p[((*i)-q)+5])) outp(PAL_DATA_REG, p[(*i)-q]); else\r
688                         if(((((*i)-q)%3==0)) && (p[((*i)-q)]==p[((*i)-q)+3] && p[((*i)-q)+1]==p[((*i)-q)+4] && p[((*i)-q)+2]==p[((*i)-q)+5]))\r
689                         {\r
690                                 w++;\r
691                                 break;\r
692                         }\r
693                         else if(qp>0 && (*i)>=(qp) && (*i)<((qp)+3))\r
694                         {\r
695                                 //printf("qp=%d\n", qp);\r
696                                 //printf("            (*i)=%d a[%d]=%d\n", (*i), qp, a[qp]);\r
697                                 printf("                %d's color=%d\n", (*i), (a[qp]-(bmp->offset*3)+qp));\r
698                                 //outp(PAL_DATA_REG, p[((a[qp])-(bmp->offset*3)+qp)]);// fix this shit!\r
699                                 if((*i)+1==(qp)+3){ w++; /*(*i)++;*/ break; }\r
700                         }\r
701                         else\r
702                         {\r
703                                 if(qp==0) outp(PAL_DATA_REG, p[(*i)-q]);\r
704                                 else{ //outp(PAL_DATA_REG, p[((*i)-(bmp->offset*3)+qp)]);\r
705                                 printf("p[]=%d  qp=%d   p[]-qp=%d\n", ((*i)-(bmp->offset*3)), qp, ((*i)-(bmp->offset*3))+qp); }\r
706                         }\r
707                 }\r
708                 //printf("                                            (*i)=%d\n", (*i)/3);\r
709         }\r
710 \r
711 printf("\nqqqqqqqq\n\n");\r
712 \r
713         //palette checker~\r
714         if(q>0 && qp==0)\r
715         {\r
716                 long lq;\r
717                 long bufSize = (bmp->width * bmp->height);\r
718                 pp = q;\r
719                 //printf("1(*i)=%02d\n", (*i)/3);\r
720                 //printf("1z=%02d\n", z/3);\r
721                 modexchkcolor(bmp, &q, &a, &aa, &z, i);\r
722                 //printf("2(*i)=%02d\n", (*i)/3);\r
723                 //printf("2z=%02d\n", z/3);\r
724                 aq=0;\r
725 aqpee:\r
726                 while(aq<=aa)\r
727                 {\r
728 //                    printf("a[%02d]=(%d)\n", aq, a[aq]);\r
729                         if(a[aq]==-1) aq++;\r
730                         else { aqoffset++; break; }\r
731                 }\r
732 //update the image data here!\r
733         for(lq=0; lq<bufSize; lq++)\r
734         {\r
735                                 /*\r
736                                                                         note to self\r
737                                                                         use a[qp] instead of bmp->offset for this spot!\r
738                                                                         NO! wwww\r
739                                 */\r
740 \r
741                                 /*\r
742                                 Facking bloody point the values of the changed palette to correct values.... major confusion! wwww\r
743                                 */\r
744 \r
745                 //(offset/bmp->offset)*bmp->offset\r
746 \r
747 \r
748                 //printf("%02d ",bmp->data[lq]+bmp->offset);\r
749                 //if(lq > 0 && lq%bmp->width==0) printf("\n");\r
750                 //printf("%02d_", bmp->data[lq]+bmp->offset);\r
751                 /*if(bmp->data[lq]+bmp->offset==aq)\r
752                 {\r
753                         //printf("%02d", bmp->data[lq]);\r
754                         //printf("\n%02d\n", bmp->offset);\r
755                         printf("aq=%02d ", aq);\r
756                         printf("a[aq]=%02d      ", a[aq]);\r
757                         printf("a[aq]+aqpp=%02d ", a[aq]+aqpp);\r
758                         printf("a[aq]-aqpp=%02d\n", a[aq]-aqpp);\r
759                         //bmp->data[lq]=((bmp->data[lq]+bmp->offset)-a[aq]);\r
760 //++++            bmp->data[lq]=a[aq]-aqpp;\r
761 //                    printf("_%d ", bmp->data[lq]);\r
762                         //if(lq > 0 && lq%bmp->width==0) printf("\n");\r
763                 }\r
764                 else if(bmp->data[lq]+bmp->offset < ((*i)/3)-aqpp)\r
765                 {\r
766                         if(bmp->data[lq]+bmp->offset >= aq)\r
767                         {\r
768                                 bmp->data[lq]=(bmp->data[lq]+bmp->offset)-aqpp;//-((z-(*i))/3);\r
769                                 //printf("_%d ", bmp->data[lq]+bmp->offset)-aqpp-((z-(*i))/3);\r
770                         }\r
771                         else bmp->data[lq]+=(bmp->offset-aqpp);\r
772                 }*/\r
773 \r
774                 //printf("%02d`", bmp->data[lq]);\r
775                 //if(lq > 0 && lq%bmp->width==0) printf("\n");\r
776         }\r
777 \r
778 //printf("            aq=%02d\n", aq);\r
779 //printf("            aa=%02d\n", aa);\r
780 \r
781         //update the palette~\r
782         modexPalUpdate(bmp, &pp, aq, aqoffset);\r
783         (*i)=pp;\r
784 \r
785         if(aq<aa){ pp=q; aq++; goto aqpee; }\r
786         }\r
787 }\r
788 \r
789 void\r
790 modexPalUpdate1(byte *p)\r
791 {\r
792         int i;\r
793         //modexWaitBorder();\r
794         vga_wait_for_vsync();\r
795         outp(PAL_WRITE_REG, 0);  /* start at the beginning of palette */\r
796         for(i=0; i<PAL_SIZE/2; i++)\r
797         {\r
798                 outp(PAL_DATA_REG, p[i]);\r
799         }\r
800         //modexWaitBorder();      /* waits one retrace -- less flicker */\r
801         vga_wait_for_vsync();\r
802         for(; i<PAL_SIZE; i++)\r
803         {\r
804                 outp(PAL_DATA_REG, p[(i)]);\r
805         }\r
806 }\r
807 \r
808 void\r
809 modexPalUpdate0(byte *p)\r
810 {\r
811         int i;\r
812         //modexWaitBorder();\r
813         vga_wait_for_vsync();\r
814         outp(PAL_WRITE_REG, 0);  /* start at the beginning of palette */\r
815         for(i=0; i<PAL_SIZE/2; i++)\r
816         {\r
817                 outp(PAL_DATA_REG, rand());\r
818         }\r
819         //modexWaitBorder();      /* waits one retrace -- less flicker */\r
820         vga_wait_for_vsync();\r
821         for(; i<PAL_SIZE; i++)\r
822         {\r
823                 outp(PAL_DATA_REG, rand());\r
824         }\r
825 }\r
826 \r
827 void\r
828 modexPalOverscan(byte *p, word col)\r
829 {\r
830         //modexWaitBorder();\r
831         vga_wait_for_vsync();\r
832         outp(PAL_WRITE_REG, 0);  /* start at the beginning of palette */\r
833         outp(PAL_DATA_REG, col);\r
834 }\r
835 \r
836 //color checker~\r
837 //i want to make another vesion that checks the palette when the palette is being appened~\r
838 void modexchkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)\r
839 {\r
840                 byte *pal;\r
841                 word zz=0;\r
842                 pal = modexNewPal();\r
843                 modexPalSave(pal);\r
844                 //printf("q: %02d\n", (*q));\r
845                 printf("chkcolor start~\n");\r
846                 printf("1                              (*z): %d\n", (*z)/3);\r
847                 printf("1                              (*i): %d\n", (*i)/3);\r
848 //            printf("1 offset of color in palette    (*q): %d\n", (*q)/3);\r
849                 printf("wwwwwwwwwwwwwwww\n");\r
850                 //check palette for dups\r
851                 for(; (*z)<PAL_SIZE; (*z)+=3)\r
852                 {\r
853                         //printf("\n        z: %d\n", (*z));\r
854                         //printf("            q: %d\n", (*q));\r
855                         //printf("            z+q: %d\n\n", ((*z)+(*q)));\r
856                         //if((*z)%3==0)\r
857                         //{\r
858 //----                    if(pal[(*z)]==pal[(*z)+3] && pal[(*z)+1]==pal[(*z)+4] && pal[(*z)+2]==pal[(*z)+5])\r
859                                 if((*z)==(*i))\r
860                                 {\r
861 //                                    printf("\n%d    [%02d][%02d][%02d]\n", (*z), pal[(*z)], pal[(*z)+1], pal[(*z)+2]);\r
862 //                                    printf("%d      [%02d][%02d][%02d]\n\n", (*z)+3, pal[(*z)+3], pal[(*z)+4], pal[(*z)+5]);\r
863 //0000                            (*z)-=3;\r
864                                         break;\r
865                                 }\r
866                                 else for(zz=0; zz<(*q); zz+=3)\r
867                                 {\r
868                                         //printf("zz: %02d\n", zz/3);\r
869                                         if(zz%3==0)\r
870                                         {\r
871                                                 if(pal[((*z)+(*q))]==pal[((*z)+(*q))+3] && pal[((*z)+(*q))+1]==pal[((*z)+(*q))+4] && pal[((*z)+(*q))+2]==pal[((*z)+(*q))+5])    //break if duplicate colors found in palette because it have reached the end of the current data of the palette\r
872                                                 {\r
873 //                                                    (*z)-=3;\r
874 //                                                    (*i)-=3;\r
875 //                                                    printf("\nzq1:%d[%02d][%02d][%02d]\n", (zz+q), pal[(zz+q)], pal[(zz+q)+1], pal[(zz+q)+2]);\r
876 //                                                    printf("zq2:%d[%02d][%02d][%02d]\n\n", (zz+q)+3, pal[(zz+q)+3], pal[(zz+q)+4], pal[(zz+q)+5]);\r
877                                                         break;\r
878                                                 }\r
879                                                 else if(pal[zz]==pal[((*z)+(*q))] && pal[zz+1]==pal[((*z)+(*q))+1] && pal[zz+2]==pal[((*z)+(*q))+2])\r
880                                                 {\r
881 //                                                    printf("\n\nwwwwwwwwwwwwwwww\n");\r
882 //                                                    printf("  zq: %d  [%02d][%02d][%02d] value that is needing to be changed~\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);\r
883 //                                                    printf("  zz: %d  [%02d][%02d][%02d] value that the previous value is going to change to~\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);\r
884 //                                                    //printf("      zv: %d  [%02d][%02d][%02d] wwww\n", (zz-z+q)/3, pal[(zz-z+q)], pal[(zz-z+q)+1], pal[(zz-z+q)+2]);\r
885 //                                                    printf("  z : %d  [%02d][%02d][%02d] offset value~\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);\r
886 //++++                                            (*i)--;\r
887 //                                                    (*z)--;\r
888                                                         //expand dong here\r
889 /*\r
890 planned features that i plan to implement~\r
891 image that has values on the pallete list!\r
892 wwww\r
893 no... wait.... no wwww\r
894 */\r
895                                                         //for(zzii=0; zzii<3; zzii++)\r
896                                                         //{\r
897                                                                 //printf("z+q: %d\n\n", ((*z)+(*q)));\r
898                                                                 a[(((*z)+(*q)))]=zz;\r
899                                                         //}\r
900                                                         (*aa)=(((*z)+(*q)));\r
901                                                         printf("!!                                    a[%02d]: %d\n", (((*z)+(*q))/3), zz/3);\r
902 //                                                    printf("\n              aa: %d\n\n", (*aa));\r
903 //                                                    printf("  a[%02d]=(%02d) offset array i think the palette should be updated again~\n", ((*z)+(*q))/3, a[((*z)+(*q))/3]);\r
904 //                                                    printf("wwwwwwwwwwwwwwww\n\n");\r
905                                                 }\r
906                                                 /*else\r
907                                                 {\r
908                                                         printf("================\n");\r
909                                                         printf("zq: %d  [%02d][%02d][%02d]\n", ((*z)+(*q))/3, pal[((*z)+(*q))], pal[((*z)+(*q))+1], pal[((*z)+(*q))+2]);\r
910                                                         printf("zz: %d  [%02d][%02d][%02d]\n", (zz)/3, pal[zz], pal[zz+1], pal[zz+2]);\r
911                                                         printf("z : %d  [%02d][%02d][%02d]\n", (*z)/3, pal[(*z)], pal[(*z)+1], pal[(*z)+2]);\r
912                                                         printf("================\n");\r
913                                                 }*/\r
914                                                 //printf("[%d]", (zz+q));\r
915                                         }\r
916                                 }\r
917                 }\r
918                 printf("wwwwwwwwwwwwwwww\n");\r
919                 printf("2                              (*z): %d\n", (*z)/3);\r
920                 printf("2                              (*i): %d\n", (*i)/3);\r
921 //            printf("2 offset of color in palette    (*q): %d\n", (*q)/3);\r
922                 printf("chkcolor end~\n");\r
923                 free(pal);\r
924 }\r
925 \r
926 void modexputPixel(page_t *page, int x, int y, byte color)\r
927 {\r
928         word pageOff = (word) page->data;\r
929         /* Each address accesses four neighboring pixels, so set\r
930            Write Plane Enable according to which pixel we want\r
931            to modify.  The plane is determined by the two least\r
932            significant bits of the x-coordinate: */\r
933         modexSelectPlane(PLANE(x));\r
934         //outp(SC_INDEX, 0x02);\r
935         //outp(SC_DATA, 0x01 << (x & 3));\r
936 \r
937         /* The offset of the pixel into the video segment is\r
938            offset = (width * y + x) / 4, and write the given\r
939            color to the plane we selected above.  Heed the active\r
940            page start selection. */\r
941         VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;\r
942 \r
943 }\r
944 \r
945 byte modexgetPixel(page_t *page, int x, int y)\r
946 {\r
947         word pageOff = (word) page->data;\r
948         /* Select the plane from which we must read the pixel color: */\r
949         outpw(GC_INDEX, 0x04);\r
950         outpw(GC_INDEX+1, x & 3);\r
951 \r
952         return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];\r
953 \r
954 }\r
955 \r
956 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)\r
957 {\r
958         word s, o, w;\r
959         word x_draw = x;\r
960         word addr = (word) romFontsData.l;\r
961         word addrq = (page->width/4) * y + (x / 4) + ((word)page->data);\r
962         word addrr = addrq;\r
963         byte c;\r
964 \r
965         s=romFonts[t].seg;\r
966         o=romFonts[t].off;\r
967         w=romFonts[t].charSize;\r
968         romFontsData.chw=0;\r
969 \r
970         for(; *str != '\0'; str++)\r
971         {\r
972         c = (*str);\r
973         if(c=='\n')\r
974         {\r
975                 x = x_draw;\r
976                 romFontsData.chw = 0;\r
977                 addrq += (page->width / 4) * 8;\r
978                 addrr = addrq;\r
979                 y += 8;\r
980                 continue;\r
981         }\r
982 \r
983         // load the character into romFontsData.l\r
984         // no need for inline assembly!\r
985         // NTS: It might even be faster to just let the modexDrawChar point directly at ROM font than to copy per char! --J.C.\r
986                 _fmemcpy(romFontsData.l,MK_FP(s,o+(w*c))/*ROM font location*/,w/*char size*/);\r
987                 modexDrawChar(page, x_draw/*for mode X planar use*/, t, col, bgcol, addrr);\r
988                 x_draw += 8; /* track X for edge of screen */\r
989                 addrr += 2; /* move 8 pixels over (2 x 4 planar pixels per byte) */\r
990         }\r
991 }\r
992 \r
993 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)\r
994 {\r
995         word i, s, o, w, j, xp;\r
996         byte l[1024];\r
997         word addr = (word) l;\r
998         word chw=0;\r
999         byte c;\r
1000 \r
1001         switch(t)\r
1002         {\r
1003                 case 0:\r
1004                         w=14;\r
1005                 break;\r
1006                 case 1:\r
1007                         w=8;\r
1008                 break;\r
1009                 case 2:\r
1010                         w=8;\r
1011                 break;\r
1012                 case 3:\r
1013                         w=16;\r
1014                 break;\r
1015                 default:\r
1016                         t=3;\r
1017                         w=16;\r
1018                 break;\r
1019         }\r
1020 \r
1021         s=romFonts[t].seg;\r
1022         o=romFonts[t].off;\r
1023 \r
1024         for(; *str != '\0'; str++)\r
1025         {\r
1026         c = (*str);\r
1027         if((c=='\n'/* || c=="\\r
1028 "*/)/* || chw>=page->width*/)\r
1029         {\r
1030                 chw=0;\r
1031                 y+=w;\r
1032                 continue;\r
1033         }\r
1034         //load the letter 'A'\r
1035         __asm {\r
1036             PUSHF\r
1037             PUSH ES\r
1038             PUSH AX\r
1039             PUSH BX\r
1040             PUSH CX\r
1041             PUSH DX\r
1042             PUSH SI\r
1043             PUSH DI\r
1044 \r
1045                 MOV DI, addr\r
1046                 MOV SI, o\r
1047                 MOV ES, s\r
1048                 SUB AH, AH\r
1049                 MOV AL, c       ; the letter\r
1050                 MOV CX, w\r
1051                 MUL CX\r
1052                 ADD SI, AX      ;the address of charcter\r
1053         L1:     MOV AX, ES:SI\r
1054                 MOV DS:DI, AX\r
1055                 INC SI\r
1056                 INC DI\r
1057                 DEC CX\r
1058                 JNZ L1\r
1059 \r
1060             POP DI\r
1061             POP SI\r
1062             POP DX\r
1063             POP CX\r
1064             POP BX\r
1065             POP AX\r
1066             POP ES\r
1067             POPF\r
1068         }\r
1069 \r
1070                 for(i=0; i<w; i++)\r
1071                 {\r
1072                         j=1<<8;\r
1073                         xp=0;\r
1074                         while(j)\r
1075                         {\r
1076                                 //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);\r
1077                                 modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);\r
1078                                 xp++;\r
1079                                 j>>=1;\r
1080                         }\r
1081                 }\r
1082                 chw += xp;\r
1083         }\r
1084 }\r
1085 \r
1086 /* palette dump on display! */\r
1087 void modexpdump(page_t *pee)\r
1088 {\r
1089         int mult=(QUADWH);\r
1090         int palq=(mult)*TILEWH;\r
1091         int palcol=0;\r
1092         int palx, paly;\r
1093         for(paly=0; paly<palq; paly+=mult){\r
1094                 for(palx=0; palx<palq; palx+=mult){\r
1095                                 modexClearRegion(pee, palx+TILEWH, paly+TILEWH, mult, mult, palcol);\r
1096                         palcol++;\r
1097                 }\r
1098         }\r
1099 }\r
1100 \r
1101 /////////////////////////////////////////////////////////////////////////////\r
1102 //                                                                                                                                               //\r
1103 // cls() - This clears the screen to the specified color, on the VGA or on //\r
1104 //               the Virtual screen.                                                                                     //\r
1105 //                                                                                                                                               //\r
1106 /////////////////////////////////////////////////////////////////////////////\r
1107 void modexcls(page_t *page, byte color, byte *Where)\r
1108 {\r
1109         //modexClearRegion(page, 0, 0, page->width, page->height, color);\r
1110         /* set map mask to all 4 planes */\r
1111         outpw(SC_INDEX, 0xff02);\r
1112         //_fmemset(VGA, color, 16000);\r
1113         _fmemset(Where, color, page->width*(page->height)/4);\r
1114 }\r
1115 \r
1116 void\r
1117 modexWaitBorder() {\r
1118     while(inp(INPUT_STATUS_1)  & 8)  {\r
1119         // spin\r
1120     }\r
1121 \r
1122     while(!(inp(INPUT_STATUS_1)  & 8))  {\r
1123         // spin\r
1124     }\r
1125 }\r
1126 \r
1127 void bios_cls() {\r
1128         VGA_ALPHA_PTR ap;\r
1129         VGA_RAM_PTR rp;\r
1130         unsigned char m;\r
1131 \r
1132         m = int10_getmode();\r
1133         if ((rp=vga_state.vga_graphics_ram) != NULL && !(m <= 3 || m == 7)) {\r
1134                 unsigned int i,im;\r
1135 \r
1136                 im = (FP_SEG(vga_state.vga_graphics_ram_fence) - FP_SEG(vga_state.vga_graphics_ram));\r
1137                 if (im > 0xFFE) im = 0xFFE;\r
1138                 im <<= 4;\r
1139                 for (i=0;i < im;i++) vga_state.vga_graphics_ram[i] = 0;\r
1140         }\r
1141         else if ((ap=vga_state.vga_alpha_ram) != NULL) {\r
1142                 unsigned int i,im;\r
1143 \r
1144                 im = (FP_SEG(vga_state.vga_alpha_ram_fence) - FP_SEG(vga_state.vga_alpha_ram));\r
1145                 if (im > 0x7FE) im = 0x7FE;\r
1146                 im <<= 4 - 1; /* because ptr is type uint16_t */\r
1147                 for (i=0;i < im;i++) vga_state.vga_alpha_ram[i] = 0x0720;\r
1148         }\r
1149         else {\r
1150                 printf("WARNING: bios cls no ptr\n");\r
1151         }\r
1152 }\r