]> icculus.org git repositories - btb/d2x.git/blob - unused/vga/vga.jas
Import of d2x-0.0.8
[btb/d2x.git] / unused / vga / vga.jas
1 /*\r
2  * $Source: /cvs/cvsroot/d2x/unused/vga/vga.jas,v $\r
3  * $Revision: 1.1.1.1 $\r
4  * $Author: bradleyb $\r
5  * $Date: 2001-01-19 03:30:15 $\r
6  * \r
7  * VGA library code\r
8  * \r
9  * $Log: not supported by cvs2svn $\r
10  * Revision 1.14  1996/01/02  18:00:51  matt\r
11  * New parms for gr_init_screen\r
12  * \r
13  * Revision 1.13  1995/12/19  13:46:05  matt\r
14  * Use symbolic constant for special 3dmax mode\r
15  * \r
16  * Revision 1.12  1995/12/13  18:03:03  matt\r
17  * From JOHN: added code for special 3dbios mode\r
18  * \r
19  * Revision 1.11  1995/12/13  16:28:54  matt\r
20  * Use more legal way of checking screen mode\r
21  * \r
22  * Revision 1.10  1995/11/28  10:30:22  matt\r
23  * Added support for 1280x1024\r
24  * \r
25  * Revision 1.9  1995/11/22  12:52:42  matt\r
26  * Changed numeric literals to symbolic constants\r
27  * \r
28  * Revision 1.8  1995/11/16  12:00:17  jed\r
29  * killed some prototype stuff\r
30  * \r
31  * Revision 1.7  1995/11/14  18:11:07  jed\r
32  * added code to support linear frame buffering\r
33  * \r
34  * Revision 1.6  1995/08/30  21:11:26  matt\r
35  * Added global containing current VGA mode\r
36  * \r
37  * Revision 1.5  1995/06/05  12:41:37  samir\r
38  * Moved gr_palette_clear from gr.c to vga.c\r
39  * \r
40  * Revision 1.4  1995/05/31  10:54:26  matt\r
41  * Added RCS header\r
42  * \r
43  * \r
44  * \r
45  */\r
46 \r
47 #include <dos.h>\r
48 #include <stdlib.h>\r
49 #include <string.h>\r
50 #include <malloc.h>\r
51 #include <stdio.h>\r
52 #include <conio.h>\r
53 \r
54 #include "types.h"\r
55 #include "mem.h"\r
56 #include "error.h"\r
57 #include "mono.h"\r
58 \r
59 //      New for VGA Library.\r
60 #include "gr.h"\r
61 #include "vga.h"\r
62 #include "palette.h"\r
63 #include "grdef.h"\r
64 #include "fxvesa.h"\r
65 \r
66 \r
67 // Global Variables -----------------------------------------------------------\r
68 \r
69 ubyte *vga_screen_addr = NULL;\r
70 \r
71 unsigned char * vga_video_memory = (unsigned char *)0xA0000;\r
72 \r
73 char vga_pal_default[768];\r
74 \r
75 int vga_installed = 0;\r
76 \r
77 //extern int gr_palette_realized;\r
78 int vga_prevent_palette_loading = 0;\r
79 \r
80 ubyte * pVideoMode =  (volatile ubyte *)0x449;\r
81 uword * pNumColumns = (volatile uword *)0x44a;\r
82 ubyte * pNumRows = (volatile ubyte *)0x484;\r
83 uword * pCharHeight = (volatile uword *)0x485;\r
84 uword * pCursorPos = (volatile uword *)0x450;\r
85 uword * pCursorType = (volatile uword *)0x460;\r
86 uword * pTextMemory = (volatile uword *)0xb8000;\r
87 \r
88 ubyte saved_video_mode = 0;\r
89 uword saved_num_columns = 0;\r
90 ubyte saved_num_rows = 0;\r
91 uword saved_char_height = 0;\r
92 uword saved_cursor_pos = 0;\r
93 uword saved_cursor_type = 0;\r
94 ubyte saved_is_graphics = 0;\r
95 uword * saved_video_memory = NULL;\r
96 \r
97 int cga_show_screen_info = 0;\r
98 \r
99 \r
100 //      VGA Functions --------------------------------------------------------------\r
101 \r
102 ubyte vga_get_screen_mode( void )\r
103 {\r
104         union REGS regs;\r
105 \r
106         regs.w.ax = 0x0f00;\r
107         int386( 0x10, &regs, &regs );\r
108         return regs.w.ax & 0xff;\r
109 }\r
110 \r
111 void vga_set_cellheight( ubyte height )\r
112 {\r
113         ubyte temp;\r
114 \r
115    outp( 0x3d4, 9 );\r
116         temp = inp( 0x3d5 );\r
117    temp &= 0xE0;\r
118         temp |= height;\r
119         outp( 0x3d5, temp );\r
120 }\r
121 \r
122 void vga_set_linear()\r
123 {\r
124         outpw( 0x3c4, 0xE04 );            // enable chain4 mode\r
125         outpw( 0x3d4, 0x4014 );           // turn on dword mode\r
126         outpw( 0x3d4, 0xa317 );           // turn off byte mode\r
127 }\r
128 \r
129 void vga_16_to_256()\r
130 {\r
131         outpw( 0x3ce, 0x4005 );         // set Shift reg to 1\r
132 \r
133         inp( 0x3da );                                   // dummy input\r
134 \r
135         outp( 0x3c0, 0x30 );\r
136         outp( 0x3c0, 0x61 );               // turns on PCS & PCC\r
137 \r
138         inp( 0x3da );                                   // dummy input\r
139 \r
140         outp( 0x3c0, 0x33 );\r
141         outp( 0x3c0, 0 );\r
142 }\r
143 \r
144 void vga_turn_screen_off()\r
145 {\r
146         ubyte temp;\r
147         temp = inp( 0x3da );\r
148         outp( 0x3c0, 0 );\r
149 }\r
150 \r
151 void vga_turn_screen_on()\r
152 {\r
153         ubyte temp;\r
154         temp = inp( 0x3da );\r
155         outp( 0x3c0, 0x20 );\r
156 }\r
157 \r
158 void vga_set_misc_mode( uword mode )\r
159 {\r
160         union REGS regs;\r
161 \r
162         regs.w.ax = mode;\r
163         int386( 0x10, &regs, &regs );\r
164 \r
165 }\r
166 \r
167 void gr_set_3dbios_mode( uint mode )\r
168 {\r
169         union REGS regs;\r
170         memset( &regs, 0, sizeof(regs) );\r
171         regs.w.ax = 0x4fd0;\r
172         regs.w.bx = 0x3d00 | (mode & 0xff);\r
173         int386( 0x10, &regs, &regs );\r
174 }\r
175 \r
176 \r
177 void vga_set_text_25()\r
178 {\r
179         union REGS regs;\r
180 \r
181         regs.w.ax = 3;\r
182         int386( 0x10, &regs, &regs );\r
183 \r
184 }\r
185 \r
186 void vga_set_text_43()\r
187 {\r
188         union REGS regs;\r
189 \r
190         regs.w.ax = 0x1201;\r
191         regs.w.bx = 0x30;\r
192         int386( 0x10, &regs, &regs );\r
193 \r
194         regs.w.ax = 3;\r
195         int386( 0x10, &regs, &regs );\r
196 \r
197         regs.w.ax = 0x1112;\r
198         regs.w.bx = 0x0;\r
199         int386( 0x10, &regs, &regs );\r
200 }\r
201 \r
202 void vga_set_text_50()\r
203 {\r
204         union REGS regs;\r
205 \r
206         regs.w.ax = 0x1202;\r
207         regs.w.bx = 0x30;\r
208         int386( 0x10, &regs, &regs );\r
209 \r
210         regs.w.ax = 3;\r
211         int386( 0x10, &regs, &regs );\r
212 \r
213         regs.w.ax = 0x1112;\r
214         regs.w.bx = 0x0;\r
215         int386( 0x10, &regs, &regs );\r
216 }\r
217 \r
218 ubyte is_graphics_mode()\r
219 {\r
220         byte tmp;\r
221         tmp = inp( 0x3DA );             // Reset flip-flip\r
222         outp( 0x3C0, 0x30 );            // Select attr register 10\r
223         tmp = inp( 0x3C1 );     // Get graphics/text bit\r
224         return tmp & 1;\r
225 }\r
226 \r
227 int vga_save_mode()\r
228 {\r
229         int i;\r
230 \r
231         saved_video_mode = vga_get_screen_mode();\r
232         saved_num_columns = *pNumColumns;\r
233         saved_num_rows = *pNumRows+1;\r
234         saved_char_height = *pCharHeight;\r
235         saved_cursor_pos = *pCursorPos;\r
236         saved_cursor_type = *pCursorType;\r
237         saved_is_graphics = is_graphics_mode();\r
238 \r
239         if (saved_is_graphics==0)\r
240         {\r
241                 MALLOC(saved_video_memory,uword, saved_num_columns*saved_num_rows );\r
242 \r
243                 for (i=0; i < saved_num_columns*saved_num_rows; i++ )\r
244                         saved_video_memory[i] = pTextMemory[i];\r
245         }\r
246 \r
247         if (cga_show_screen_info )\r
248         {\r
249                 printf( "Current video mode 0x%x:\n",  saved_video_mode );\r
250                 if (saved_is_graphics)\r
251                         printf( "Graphics mode\n" );\r
252                 else\r
253                         printf( "Text mode\n" );\r
254         \r
255                 printf( "( %d columns by %d rows)\n", saved_num_columns, saved_num_rows );\r
256                 printf( "Char height is %d pixel rows\n", saved_char_height );\r
257                 printf( "Cursor of type 0x%x is at (%d, %d)\n", saved_cursor_type, saved_cursor_pos & 0xFF, saved_cursor_pos >> 8 );\r
258         }\r
259 \r
260         return 0;\r
261 }\r
262 \r
263 int isvga()\r
264 {\r
265         union REGS regs;\r
266 \r
267         regs.w.ax = 0x1a00;\r
268         int386( 0x10, &regs, &regs );\r
269 \r
270         if ( regs.h.al != 0x1a ) return 0;\r
271         if ( (regs.h.bl==7) || (regs.h.bl==8)) return 1;\r
272         return 0;\r
273 }\r
274 \r
275 void vga_set_cursor_type( uword ctype )\r
276 {\r
277         union REGS regs;\r
278 \r
279         regs.w.ax = 0x0100;\r
280         regs.w.cx = ctype;\r
281         int386( 0x10, &regs, &regs );\r
282 }\r
283 \r
284 void vga_enable_default_palette_loading()\r
285 {\r
286         union REGS regs;\r
287         regs.w.ax = 0x1200;\r
288         regs.w.bx = 0x31;\r
289         int386( 0x10, &regs, &regs );\r
290         vga_prevent_palette_loading = 0;\r
291 }\r
292 \r
293 void vga_disable_default_palette_loading()\r
294 {\r
295         union REGS regs;\r
296         regs.w.ax = 0x1201;\r
297         regs.w.bx = 0x31;\r
298         int386( 0x10, &regs, &regs );\r
299         vga_prevent_palette_loading = 1;\r
300 }\r
301 \r
302 void vga_set_cursor_position( uword position )\r
303 {\r
304         union REGS regs;\r
305 \r
306         regs.w.ax = 0x0200;\r
307         regs.w.bx = 0;\r
308         regs.w.dx = position;\r
309         int386( 0x10, &regs, &regs );\r
310 \r
311 }\r
312 \r
313 void vga_restore_mode()\r
314 {\r
315         int i;\r
316 \r
317         if ( saved_video_mode == 3 )\r
318         {\r
319                 switch( saved_num_rows )\r
320                 {\r
321                         case 43:        vga_set_text_43(); break;\r
322                         case 50:        vga_set_text_50(); break;\r
323                         default:        vga_set_text_25(); break;\r
324                 }\r
325         } else {\r
326                 vga_set_misc_mode(saved_video_mode);    \r
327         }\r
328 \r
329         if (saved_is_graphics==0)\r
330         {\r
331                 for (i=0; i < saved_num_columns*saved_num_rows; i++ )\r
332                         pTextMemory[i]=saved_video_memory[i];\r
333                 vga_set_cursor_type( saved_cursor_type );\r
334                 vga_set_cursor_position( saved_cursor_pos );\r
335         }\r
336 }\r
337 \r
338 short vga_close()\r
339 {\r
340 \r
341         if (vga_installed==1)\r
342         {\r
343                 vga_installed = 0;\r
344                 vga_restore_mode();\r
345                 if( saved_video_memory )\r
346                         free(saved_video_memory);\r
347         }\r
348 \r
349         return 0;\r
350 }\r
351 \r
352 int LinearSVGABuffer=0;\r
353 \r
354 int vga_vesa_setmode( short mode )\r
355 {\r
356         int retcode;\r
357 \r
358         if (VesaInit (mode))  // if there is an error with linear support\r
359          {\r
360                 LinearSVGABuffer=1;\r
361                 return(0);\r
362          }\r
363         \r
364    LinearSVGABuffer=0;\r
365         retcode=gr_vesa_checkmode( mode );              // do the old banking way\r
366         if ( retcode ) return retcode;\r
367         return gr_vesa_setmodea( mode );\r
368 }\r
369 \r
370 int VGA_current_mode = SM_ORIGINAL;\r
371 \r
372 #define VIRGE\r
373 #ifdef VIRGE\r
374 extern int Virge_enabled;\r
375 #endif\r
376 \r
377 short vga_set_mode(short mode)\r
378 {\r
379         int retcode;\r
380         unsigned int w,h,t,data, r;\r
381 \r
382         LinearSVGABuffer=0; \r
383            \r
384         if (!vga_installed)\r
385                 return 1;\r
386    \r
387 #ifdef VIRGE\r
388         Virge_enabled = 0;\r
389 #endif\r
390   \r
391         switch(mode)\r
392         {\r
393         case SM_ORIGINAL:\r
394                 return 0;\r
395 \r
396         case SM_320x200C:\r
397                 if (!isvga()) return 1;\r
398                 vga_set_misc_mode(0x13);        \r
399                 w = 320; r = 320; h = 200; t=BM_LINEAR; data = 0xA0000;\r
400                 break;\r
401         \r
402         case SM_640x400V:\r
403                 retcode = vga_vesa_setmode( 0x100 ); \r
404                 //gr_enable_default_palette_loading();\r
405                 if (retcode !=0 ) return retcode;\r
406                 w = 640; r = 640; h = 400; t=BM_SVGA; data = 0;\r
407                 break;\r
408 \r
409         case SM_640x480V:\r
410                 retcode = vga_vesa_setmode( 0x101 ); \r
411                 //gr_enable_default_palette_loading();\r
412                 if (retcode !=0 ) return retcode;\r
413                 w = 640; r = 640; h = 480; t=BM_SVGA; data = 0;\r
414                 break;\r
415 \r
416         case SM_800x600V:\r
417                 retcode = vga_vesa_setmode( 0x103 ); \r
418                 //gr_enable_default_palette_loading();\r
419                 if (retcode !=0 ) return retcode;\r
420                 w = 800; r = 800; h = 600; t=BM_SVGA; data = 0;\r
421                 break;\r
422 \r
423         case SM_1024x768V:\r
424                 retcode = vga_vesa_setmode( 0x105 ); \r
425                 //gr_enable_default_palette_loading();\r
426                 if (retcode !=0 ) return retcode;\r
427                 w = 1024; r = 1024; h = 768; t=BM_SVGA; data = 0;\r
428                 break;\r
429 \r
430         case SM_1280x1024V:\r
431                 retcode = vga_vesa_setmode( 0x107 ); \r
432                 //gr_enable_default_palette_loading();\r
433                 if (retcode !=0 ) return retcode;\r
434                 w = 1280; r = 1280; h = 1024; t=BM_SVGA; data = 0;\r
435                 break;\r
436 \r
437         case SM_640x480V15:\r
438                 retcode = vga_vesa_setmode( 0x110 ); \r
439                 //gr_enable_default_palette_loading();\r
440                 if (retcode !=0 ) return retcode;\r
441                 w = 640; r = 640*2; h=480; t=BM_SVGA15; data = 0;\r
442                 break;\r
443 \r
444         case SM_800x600V15:\r
445                 retcode = vga_vesa_setmode( 0x113 ); \r
446                 //gr_enable_default_palette_loading();\r
447                 if (retcode !=0 ) return retcode;\r
448                 w = 800; r = 800*2; h=600; t=BM_SVGA15; data = 0;\r
449                 break;\r
450 \r
451         //super-special code for 3dmax high-res mode\r
452         case SM_320x400_3DMAX:                  // 3dmax 320x400\r
453                 if (!isvga()) return 1;\r
454                 gr_set_3dbios_mode(0x31);\r
455                 //w = 320; r = 320/4; h = 400; t=BM_MODEX; data = 0;\r
456                 w = 320; r = 320; h = 400; t=BM_SVGA; data = 0;\r
457                 break;\r
458 \r
459         //@@case 19:\r
460         //@@    if (!isvga()) return 1;\r
461         //@@    vga_set_misc_mode(0x13);        \r
462         //@@    vga_set_cellheight( 3 );\r
463         //@@    w = 320; r = 320; h = 200; t=BM_LINEAR; data = 0xA0000;\r
464         //@@    break;\r
465         //@@\r
466         //@@case 20:\r
467         //@@    retcode = vga_vesa_setmode( 0x102 ); \r
468         //@@    //gr_enable_default_palette_loading();\r
469         //@@    if (retcode !=0 ) return retcode;\r
470         //@@    vga_16_to_256();\r
471         //@@    vga_set_linear();\r
472         //@@    //gr_set_cellheight( 1 );\r
473         //@@    gr_vesa_setlogical( 400 );\r
474         //@@    w = 400; r = 400; h = 600; t=BM_SVGA; data = 0;\r
475         //@@    break;\r
476         //@@\r
477         //@@case 21:\r
478         //@@    if (!isvga()) return 1;\r
479         //@@    vga_set_misc_mode(0xd); \r
480         //@@    vga_16_to_256();\r
481         //@@    vga_set_linear();\r
482         //@@    //gr_set_cellheight( 3 );\r
483         //@@    w = 160; r = 160; h = 200; t=BM_LINEAR; data = 0xA0000;\r
484         //@@    break;\r
485 \r
486         case SM_320x200U:\r
487         case SM_320x240U:\r
488         case SM_360x200U:\r
489         case SM_360x240U:\r
490         case SM_376x282U:\r
491         case SM_320x400U:\r
492         case SM_320x480U:\r
493         case SM_360x400U:\r
494         case SM_360x480U:\r
495         case SM_360x360U:\r
496         case SM_376x308U:\r
497         case SM_376x564U:               //mode X modes\r
498 \r
499                 if (!isvga()) return 1;\r
500                 w = gr_modex_setmode( mode );\r
501                 //gr_enable_default_palette_loading();\r
502                 h = w & 0xffff; w = w >> 16; r = w / 4;t = BM_MODEX; data = 0;\r
503                 break;\r
504 \r
505         default:                        //unknown mode!!!  Very bad!!\r
506                 Error("Unknown mode %d in vga_set_mode()",mode);\r
507         }\r
508 \r
509 //      if (vga_palette_realized  && (vga_prevent_palette_loading==0))\r
510 //              gr_pal_setblock( 0, 256, gr_palette);\r
511 \r
512 //      return 0;\r
513 \r
514         VGA_current_mode = mode;\r
515         if (LinearSVGABuffer)\r
516                 {\r
517                         mprintf ((0,"GREEEEAT!\n"));\r
518                         t=BM_LINEAR;\r
519                         vga_screen_addr=(ubyte *)VesaGetPtr();\r
520                 }\r
521         else\r
522                 vga_screen_addr=(ubyte *)0xa0000;\r
523 \r
524         gr_palette_clear();\r
525         return gr_init_screen( t,w,h,0,0,r,vga_screen_addr);\r
526 }\r
527 \r
528 \r
529 short vga_init()\r
530 {\r
531         // Only do this function once!\r
532         if (vga_installed==1)\r
533                 return 1;\r
534 \r
535         if (gr_init_A0000())\r
536                 return 10;\r
537 \r
538         vga_screen_addr = (ubyte *)0xa0000;             //address in memory of screen\r
539 \r
540         // Save the current text screen mode\r
541         if (vga_save_mode()==1)\r
542                 return 1;\r
543 \r
544 /*      if (get_selector( &vga_fade_table, 256*GR_FADE_LEVELS, &vga_fade_table_selector ))\r
545                 Error( "Error allocating fade table selector!" );\r
546 \r
547         if (get_selector( &vga_palette, 256*3, &vga_palette_selector ))\r
548                 Error( "Error allocating palette selector!" );\r
549 \r
550         if (get_selector( &vga_inverse_table, 32*32*32, &vga_inverse_table_selector ))\r
551                 Error( "Error allocating inverse table selector!" );\r
552 */\r
553 \r
554         // Set flags indicating that this is installed.\r
555         gr_palette_clear();\r
556         vga_installed = 1;\r
557         atexit(vga_close);\r
558 \r
559         return 0;\r
560 }\r
561 \r
562 short vga_mode13_checkmode()\r
563 {\r
564         if (isvga()) \r
565                 return 0;\r
566         else\r
567                 return 1;\r
568 }\r
569 \r
570 //  0=Mode set OK\r
571 //  1=No VGA adapter installed\r
572 //  2=Program doesn't support this VESA granularity\r
573 //  3=Monitor doesn't support that VESA mode.:\r
574 //  4=Video card doesn't support that VESA mode.\r
575 //  5=No VESA driver found.\r
576 //  6=Bad Status after VESA call/\r
577 //  7=Not enough DOS memory to call VESA functions.\r
578 //  8=Error using DPMI.\r
579 //  9=Error setting logical line width.\r
580 // 10=Error allocating selector for A0000h\r
581 // 11=Not a valid mode support by gr.lib\r
582 \r
583 short vga_check_mode(short mode)\r
584 {\r
585         switch(mode)\r
586         {\r
587         case 19:\r
588         case SM_320x200C:\r
589         case SM_320x200U:\r
590         case SM_320x240U:\r
591         case SM_360x200U:\r
592         case SM_360x240U:\r
593         case SM_376x282U:\r
594         case SM_320x400U:\r
595         case SM_320x480U:\r
596         case SM_360x400U:\r
597         case SM_360x480U:\r
598         case SM_360x360U:\r
599         case SM_376x308U:\r
600         case SM_376x564U:               return vga_mode13_checkmode();\r
601         case SM_640x400V:               return gr_vesa_checkmode( 0x100 ); \r
602         case SM_640x480V:       return gr_vesa_checkmode( 0x101 ); \r
603         case SM_800x600V:       return gr_vesa_checkmode( 0x103 ); \r
604         case SM_1024x768V:      return vga_vesa_setmode( 0x105 ); \r
605         case SM_640x480V15:     return vga_vesa_setmode( 0x110 ); \r
606         case SM_800x600V15:     return vga_vesa_setmode( 0x113 ); \r
607         }\r
608         return 11;\r
609 }\r
610 \1a\r
611 \1a