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