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