home *** CD-ROM | disk | FTP | other *** search
/ PC Extra Super CD 1998 January / PCPLUS131.iso / DJGPP / V2 / DJLSR201.ZIP / src / libc / crt0 / crt1.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-01  |  4.1 KB  |  159 lines

  1. /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
  2. /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  3. #include <libc/stubs.h>
  4. #include <crt0.h>
  5. #include <string.h>
  6. #include <libc/internal.h>
  7. #include <stdlib.h>
  8. #include <go32.h>
  9. #include <stubinfo.h>
  10. #include <dpmi.h>
  11. #include <libc/farptrgs.h>
  12. #include <pc.h>
  13. #include <libc/bss.h>
  14. #include <fcntl.h>
  15. #include <libc/environ.h>
  16.  
  17. /* Global variables */
  18.  
  19. #define ds _my_ds()
  20.  
  21. /* This gets incremented each time the program is started.
  22.    Programs (such as Emacs) which dump their code to create
  23.    a new executable, cause this to be larger than 2.  Library
  24.    functions that cache info in static variables should check
  25.    the value of `__bss_count' if they need to reinitialize
  26.    the static storage.  */
  27. int __bss_count = 1;
  28.  
  29. char **environ;
  30. int _crt0_startup_flags;    /* default to zero unless app overrides them */
  31.  
  32. int __crt0_argc;
  33. char **__crt0_argv;
  34.  
  35. /* Local variables */
  36.  
  37. static void
  38. setup_core_selector(void)
  39. {
  40.   int c = __dpmi_allocate_ldt_descriptors(1);
  41.   if (c == -1)
  42.   {
  43.     _dos_ds = 0;
  44.     return;
  45.   }
  46.   _dos_ds = c;
  47.  
  48.   __dpmi_set_segment_limit(_dos_ds, -1);
  49. }
  50.  
  51. static void
  52. setup_screens(void)
  53. {
  54.   if(_farpeekw(_dos_ds, 0xffff3) == 0xfd80)    /* NEC PC98 ? */
  55.   {
  56.     ScreenPrimary = ScreenSecondary = 0xa0000;
  57.   }
  58.   else if (_farpeekb(_dos_ds, 0x449) == 7)
  59.   {
  60.     ScreenPrimary = 0xb0000;
  61.     ScreenSecondary = 0xb8000;
  62.   }
  63.   else
  64.   {
  65.     ScreenPrimary = 0xb8000;
  66.     ScreenSecondary = 0xb0000;
  67.   }
  68. }
  69.  
  70. static void
  71. setup_go32_info_block(void)
  72. {
  73.   __dpmi_version_ret ver;
  74.  
  75.   __dpmi_get_version(&ver);
  76.  
  77.   _go32_info_block.size_of_this_structure_in_bytes = sizeof(_go32_info_block);
  78.   __tb = _stubinfo->ds_segment * 16;
  79.   _go32_info_block.size_of_transfer_buffer = _stubinfo->minkeep;
  80.   _go32_info_block.pid = _stubinfo->psp_selector;
  81.   _go32_info_block.master_interrupt_controller_base = ver.master_pic;
  82.   _go32_info_block.slave_interrupt_controller_base = ver.slave_pic;
  83.   _go32_info_block.linear_address_of_stub_info_structure = 0xffffffffU; /* force error */
  84.   __dpmi_get_segment_base_address(_stubinfo->psp_selector,
  85.     &_go32_info_block.linear_address_of_original_psp);
  86.   _go32_info_block.run_mode = _GO32_RUN_MODE_DPMI;
  87.   _go32_info_block.run_mode_info = (ver.major << 8) | (ver.minor);
  88. }
  89.  
  90. char *__dos_argv0;
  91.  
  92. static void
  93. setup_environment(void)
  94. {
  95.   char *dos_environ = alloca(_stubinfo->env_size), *cp;
  96.   short env_selector;
  97.   int env_count=0;
  98.   movedata(_stubinfo->psp_selector, 0x2c, ds, (int)&env_selector, 2);
  99.   movedata(env_selector, 0, ds, (int)dos_environ, _stubinfo->env_size);
  100.   cp = dos_environ;
  101.   do {
  102.     env_count++;
  103.     while (*cp) cp++; /* skip to NUL */
  104.     cp++; /* skip to next character */
  105.   } while (*cp); /* repeat until two NULs */
  106.   environ = (char **)malloc((env_count+1) * sizeof(char *));
  107.   if (environ == 0)
  108.     return;
  109.  
  110.   cp = dos_environ;
  111.   env_count = 0;
  112.   do {
  113.     /* putenv assumes each string is malloc'd */
  114.     environ[env_count] = (char *)malloc(strlen(cp)+1);
  115.     strcpy(environ[env_count], cp);
  116.     env_count++;
  117.     while (*cp) cp++; /* skip to NUL */
  118.     cp++; /* skip to next character */
  119.   } while (*cp); /* repeat until two NULs */
  120.   environ[env_count] = 0;
  121.   
  122.   __dos_argv0 = (char *)malloc(strlen(cp + 3)+1);
  123.   if (__dos_argv0 == 0)
  124.     abort();
  125.   strcpy(__dos_argv0, cp+3);
  126. }
  127.  
  128. extern void __main(void);
  129. extern int  main(int, char **, char **);
  130. extern void _crt0_init_mcount(void);    /* For profiling */
  131.  
  132. char __PROXY[] = " !proxy";
  133. size_t __PROXY_LEN = sizeof(__PROXY)-1;
  134.  
  135. void
  136. __crt1_startup(void)
  137. {
  138.   char *pn;
  139.   __bss_count ++;
  140.   __crt0_argv = 0;
  141.   setup_core_selector();
  142.   setup_screens();
  143.   setup_go32_info_block();
  144.   __djgpp_exception_setup();
  145.   setup_environment();
  146.   __environ_changed++;
  147.   /* Make so rest of startup could use LFN.  */
  148.   (void)_USE_LFN;
  149.   __crt0_setup_arguments();
  150.   pn = __crt0_argv ? __crt0_argv[0] : __dos_argv0;
  151.   __crt0_load_environment_file(pn);
  152.   (void)_USE_LFN;    /* DJGPP.ENV might have set $LFN */
  153.   _npxsetup(pn);
  154.   _crt0_init_mcount();
  155.   __main();
  156.   exit(main(__crt0_argc, __crt0_argv, environ));
  157. }
  158.  
  159.