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