]> icculus.org git repositories - btb/d2x.git/blob - arch/dos/init.c
This commit was generated by cvs2svn to compensate for changes in r2,
[btb/d2x.git] / arch / dos / init.c
1 #include <stdio.h>
2 #include <string.h>
3 #ifdef __DJGPP__
4 #define _BORLAND_DOS_REGS 1
5 #endif
6 #include <dos.h>
7
8 #include "../../main/inferno.h"
9 #include "../../main/text.h"
10 #include "args.h"
11 #include "error.h"
12
13 #include "joy.h"
14 #include "timer.h"
15 #include "key.h"
16 #include "mono.h"
17 #include "u_dpmi.h"
18 #include "mouse.h"
19
20 //added on 9/15/98 by Victor Rachels to add cd controls
21 #include "bcd.h"
22 //end this section addition - Victor Rachels
23
24 int WVIDEO_running=0;           //debugger can set to 1 if running
25
26 void install_int3_handler(void);
27
28 #ifdef __WATCOMC__
29 int __far descent_critical_error_handler( unsigned deverr, unsigned errcode, unsigned far * devhdr );
30 #endif
31
32 #ifndef NDEBUG
33 #ifdef __WATCOMC__
34 void do_heap_check()
35 {
36         int heap_status;
37
38         heap_status = _heapset( 0xFF );
39         switch( heap_status )
40         {
41         case _HEAPBADBEGIN:
42                 mprintf((1, "ERROR - heap is damaged\n"));
43                 Int3();
44                 break;
45         case _HEAPBADNODE:
46                 mprintf((1, "ERROR - bad node in heap\n" ));
47                 Int3();
48                 break;
49         }
50 }
51 #endif
52 #endif
53
54
55
56 #ifdef VR_DEVICES
57 int is_3dbios_installed()
58 {
59         dpmi_real_regs rregs;
60         memset(&rregs,0,sizeof(dpmi_real_regs));
61         rregs.eax = 0x4ed0;
62         //rregs.ebx = 0x3d10;   
63         dpmi_real_int386x( 0x10, &rregs );
64         if ( (rregs.edx & 0xFFFF) != 0x3344 )
65                 return 0;
66         else
67                 return 1;
68 }
69 #endif
70
71 // Returns 1 if ok, 0 if failed...
72 int init_gameport()
73 {
74         union REGS regs;
75
76         memset(&regs,0,sizeof(regs));
77         regs.x.eax = 0x8400;
78         regs.x.edx = 0xF0;
79         int386( 0x15, &regs, &regs );
80         if ( ( regs.x.eax & 0xFFFF ) == 0x4753 /*'SG'*/ )
81                 return 1;
82         else
83                 return 0;
84 }
85
86 void check_dos_version()
87 {
88         int major, minor;
89         union REGS regs;
90
91         memset(&regs,0,sizeof(regs));
92         regs.x.eax = 0x3000;                                                    // Get MS-DOS Version Number
93         int386( 0x21, &regs, &regs );
94
95         major = regs.h.al;
96         minor = regs.h.ah;
97         
98         if ( major < 5 )        {
99                 printf( "Using MS-DOS version %d.%d\nThis is not compatable with Descent.", major, minor);
100                 exit(1);
101         }
102         //printf( "\nUsing MS-DOS %d.%d...\n", major, minor );
103 }
104
105 void dos_check_file_handles(int num_required)
106 {
107         int i, n;
108         FILE * fp[16];
109
110         if ( num_required > 16 )
111                 num_required = 16;
112
113         n = 0;  
114         for (i=0; i<16; i++ )
115                 fp[i] = NULL;
116         for (i=0; i<16; i++ )   {
117                 fp[i] = fopen( "nul", "wb" );
118                 if ( !fp[i] ) break;
119         }
120         n = i;
121         for (i=0; i<16; i++ )   {
122                 if (fp[i])
123                         fclose(fp[i]);
124         }
125         if ( n < num_required ) {
126                 printf( "\n%s\n", TXT_NOT_ENOUGH_HANDLES );
127                 printf( "------------------------\n" );
128                 printf( "%d/%d %s\n", n, num_required, TXT_HANDLES_1 );
129                 printf( "%s\n", TXT_HANDLES_2);
130                 printf( "%s\n", TXT_HANDLES_3);
131                 exit(1);
132         }
133 }
134
135 #define NEEDED_DOS_MEMORY                       ( 300*1024)             // 300 K
136 #define NEEDED_LINEAR_MEMORY                    (7680*1024)             // 7.5 MB
137 #define LOW_PHYSICAL_MEMORY_CUTOFF      (5*1024*1024)   // 5.0 MB
138 #define NEEDED_PHYSICAL_MEMORY          (2000*1024)             // 2000 KB
139
140 extern int piggy_low_memory;
141
142 void mem_int_to_string( int number, char *dest )
143 {
144         int i,l,c;
145         char buffer[20],*p;
146
147         sprintf( buffer, "%d", number );
148
149         l = strlen(buffer);
150         if (l<=3) {
151                 // Don't bother with less than 3 digits
152                 sprintf( dest, "%d", number );
153                 return;
154         }
155
156         c = l % 3;
157         p=dest;
158         for (i=0; i<l; i++ ) {
159                 if (c==0) {
160                         if (i) *p++=',';
161             c = 3;
162         }
163         c--;
164         *p++ = buffer[i];
165     }
166         *p++ = '\0';
167 }
168
169 void check_memory()
170 {
171         char text[32];
172
173         printf( "\n%s\n", TXT_AVAILABLE_MEMORY);
174         printf( "----------------\n" );
175         mem_int_to_string( dpmi_dos_memory/1024, text );
176         printf( "Conventional: %7s KB\n", text );
177         mem_int_to_string( dpmi_physical_memory/1024, text );
178         printf( "Extended:     %7s KB\n", text );
179         if ( dpmi_available_memory > dpmi_physical_memory )     {
180                 mem_int_to_string( (dpmi_available_memory-dpmi_physical_memory)/1024, text );
181         } else {
182                 mem_int_to_string( 0, text );
183         }
184         printf( "Virtual:      %7s KB\n", text );
185         printf( "\n" );
186
187         if ( dpmi_dos_memory < NEEDED_DOS_MEMORY )      {
188                 printf( "%d %s\n", NEEDED_DOS_MEMORY - dpmi_dos_memory, TXT_MEMORY_CONFIG );
189                 exit(1);
190         }
191
192         if ( dpmi_available_memory < NEEDED_LINEAR_MEMORY )     {
193                 if ( dpmi_virtual_memory )      {
194                         printf( "%d %s\n", NEEDED_LINEAR_MEMORY - dpmi_available_memory, TXT_RECONFIGURE_VMM );
195                 } else {
196                         printf( "%d %s\n", NEEDED_LINEAR_MEMORY - dpmi_available_memory, TXT_MORE_MEMORY );
197                         printf( "%s\n", TXT_MORE_MEMORY_2);
198                 }
199                 exit(1);
200         }
201
202         if ( dpmi_physical_memory < NEEDED_PHYSICAL_MEMORY )    {
203                 printf( "%d %s\n", NEEDED_PHYSICAL_MEMORY - dpmi_physical_memory, TXT_PHYSICAL_MEMORY );
204                 if ( dpmi_virtual_memory )      {       
205                         printf( "%s\n", TXT_PHYSICAL_MEMORY_2);
206                 }
207                 exit(1);
208         }
209
210         if ( dpmi_physical_memory < LOW_PHYSICAL_MEMORY_CUTOFF )        {
211                 piggy_low_memory = 1;
212         }
213 }
214
215 extern int Inferno_verbose;
216
217 //NO_STACK_SIZE_CHECK uint * stack, *stack_ptr;
218 //NO_STACK_SIZE_CHECK int stack_size, unused_stack_space;
219 //NO_STACK_SIZE_CHECK int sil;
220 //NO_STACK_SIZE_CHECK 
221 //NO_STACK_SIZE_CHECK int main(int argc,char **argv)
222 //NO_STACK_SIZE_CHECK {
223 //NO_STACK_SIZE_CHECK   uint ret_value;
224 //NO_STACK_SIZE_CHECK   
225 //NO_STACK_SIZE_CHECK   unused_stack_space = 0;
226 //NO_STACK_SIZE_CHECK   stack = &ret_value;
227 //NO_STACK_SIZE_CHECK   stack_size = stackavail()/4;
228 //NO_STACK_SIZE_CHECK 
229 //NO_STACK_SIZE_CHECK   for ( sil=0; sil<stack_size; sil++ )    {
230 //NO_STACK_SIZE_CHECK           stack--;
231 //NO_STACK_SIZE_CHECK           *stack = 0xface0123;
232 //NO_STACK_SIZE_CHECK   }
233 //NO_STACK_SIZE_CHECK
234 //NO_STACK_SIZE_CHECK   ret_value = descent_main( argc, argv );         // Rename main to be descent_main
235 //NO_STACK_SIZE_CHECK 
236 //NO_STACK_SIZE_CHECK   for ( sil=0; sil<stack_size; sil++ )    {
237 //NO_STACK_SIZE_CHECK           if ( *stack == 0xface0123 )     
238 //NO_STACK_SIZE_CHECK                   unused_stack_space++;
239 //NO_STACK_SIZE_CHECK           stack++;
240 //NO_STACK_SIZE_CHECK   }
241 //NO_STACK_SIZE_CHECK 
242 //NO_STACK_SIZE_CHECK   mprintf(( 0, "Program used %d/%d stack space\n", (stack_size - unused_stack_space)*4, stack_size*4 ));
243 //NO_STACK_SIZE_CHECK   key_getch();
244 //NO_STACK_SIZE_CHECK 
245 //NO_STACK_SIZE_CHECK   return ret_value;
246 //NO_STACK_SIZE_CHECK }
247
248 extern int digi_timer_rate;
249
250 #ifdef __WATCOMC__
251 #pragma off (check_stack)
252 int __far descent_critical_error_handler(unsigned deverror, unsigned errcode, unsigned __far * devhdr )
253 {
254         devhdr = devhdr;
255         descent_critical_error++;
256         descent_critical_deverror = deverror;
257         descent_critical_errcode = errcode;
258         return _HARDERR_FAIL;
259 }
260 void chandler_end (void)  // dummy functions
261 {
262 }
263 #pragma on (check_stack)
264 #endif
265
266 void arch_init_start() {
267         // Initialize DPMI before anything else!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
268         // (To check memory size and availbabitliy and allocate some low DOS memory)
269         // adb: no TXT_... loaded yet
270         //if (Inferno_verbose) printf( "%s... ", TXT_INITIALIZING_DPMI);
271         if (Inferno_verbose) printf( "Initializing DPMI services... ");
272         dpmi_init(Inferno_verbose);             // Before anything
273         if (Inferno_verbose) printf( "\n" );
274
275 #ifndef __GNUC__
276         if (Inferno_verbose) printf( "\n%s...", TXT_INITIALIZING_CRIT);
277         if (!dpmi_lock_region((void near *)descent_critical_error_handler,(char *)chandler_end - (char near *)descent_critical_error_handler))  {
278                 Error( "Unable to lock critial error handler" );
279         }
280         if (!dpmi_lock_region(&descent_critical_error,sizeof(int)))     {
281                 Error( "Unable to lock critial error handler" );
282         }
283         if (!dpmi_lock_region(&descent_critical_deverror,sizeof(unsigned)))     {
284                 Error( "Unable to lock critial error handler" );
285         }
286         if (!dpmi_lock_region(&descent_critical_errcode,sizeof(unsigned)))      {
287                 Error( "Unable to lock critial error handler" );
288         }
289         _harderr((void *) descent_critical_error_handler );
290         //Above line modified by KRB, added (void *) cast
291         //for the compiler.
292 #endif
293 }
294
295 void arch_init() {
296         if ( !FindArg( "-nodoscheck" ))
297                 check_dos_version();
298         
299         if ( !FindArg( "-nofilecheck" ))
300                 dos_check_file_handles(5);
301
302         if ( !FindArg( "-nomemcheck" ))
303                 check_memory();
304
305         #ifndef NDEBUG
306                 minit();
307                 mopen( 0, 9, 1, 78, 15, "Debug Spew");
308                 mopen( 1, 2, 1, 78,  5, "Errors & Serious Warnings");
309         #endif
310
311         if (!WVIDEO_running)
312                 mprintf((0,"WVIDEO_running = %d\n",WVIDEO_running));
313
314         //if (!WVIDEO_running) install_int3_handler();
315
316
317         if (Inferno_verbose) printf( "\n%s", TXT_VERBOSE_2);
318         timer_init();
319         timer_set_rate( digi_timer_rate );                      // Tell our timer how fast to go (120 Hz)
320         joy_set_timer_rate( digi_timer_rate );      // Tell joystick how fast timer is going
321
322         if (Inferno_verbose) printf( "\n%s", TXT_VERBOSE_3);
323         key_init();
324         if (!FindArg( "-nomouse" ))     {
325                 if (Inferno_verbose) printf( "\n%s", TXT_VERBOSE_4);
326                 if (FindArg( "-nocyberman" ))
327                         mouse_init(0);
328                 else
329                         mouse_init(1);
330         } else {
331                 if (Inferno_verbose) printf( "\n%s", TXT_VERBOSE_5);
332         }
333         if (!FindArg( "-nojoystick" ))  {
334                 if (Inferno_verbose) printf( "\n%s", TXT_VERBOSE_6);
335                 joy_init();
336                 if ( FindArg( "-joyslow" ))     {
337                         if (Inferno_verbose) printf( "\n%s", TXT_VERBOSE_7);
338                         joy_set_slow_reading(JOY_SLOW_READINGS);
339                 }
340                 if ( FindArg( "-joypolled" ))   {
341                         if (Inferno_verbose) printf( "\n%s", TXT_VERBOSE_8);
342                         joy_set_slow_reading(JOY_POLLED_READINGS);
343                 }
344                 if ( FindArg( "-joybios" ))     {
345                         if (Inferno_verbose) printf( "\n%s", TXT_VERBOSE_9);
346                         joy_set_slow_reading(JOY_BIOS_READINGS);
347                 }
348                 if ( FindArg( "-joynice" ))     {
349                         if (Inferno_verbose) printf( "\n%s", "Using nice joystick poller..." );
350                         joy_set_slow_reading(JOY_FRIENDLY_READINGS);
351                 }
352                 if ( FindArg( "-gameport" ))    {
353                         if ( init_gameport() )  {                       
354                                 joy_set_slow_reading(JOY_BIOS_READINGS);
355                         } else {
356                                 Error( "\nCouldn't initialize the Notebook Gameport.\nMake sure the NG driver is loaded.\n" );
357                         }
358                 }
359         } else {
360                 if (Inferno_verbose) printf( "\n%s", TXT_VERBOSE_10);
361         }
362         #if 0 // no divzero
363         if (Inferno_verbose) printf( "\n%s", TXT_VERBOSE_11);
364         div0_init(DM_ERROR);
365         #endif
366 }