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