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