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