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