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