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