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