home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / tvision / dpmi / clib / startup.cpp < prev   
Encoding:
C/C++ Source or Header  |  1994-05-29  |  7.0 KB  |  262 lines

  1. //=====================================================================
  2. //
  3. //  startup.cpp
  4. //
  5. //  program initialization for protected mode Borland C applications
  6. //
  7. //  Copyright (c) 1994, Kevin Morgan, All rights reserved.
  8. //
  9. //=====================================================================
  10. #include <stdio.h>
  11. #include <dos.h>
  12. #include <setjmp.h>
  13. #include "dpmish.h"
  14.  
  15. extern "C" {
  16.     int  _startup( int, char **, char ** );
  17.     void _initialize( void );
  18.     void _cleanup( void );                  /* call #pragma exit routines */
  19.     void abort( void );
  20.  
  21.     void _terminate( int );                 /* terminate program */
  22.     void _checknull( void );                /* check for null pointer usage */
  23.     void _restorezero( void );              /* restore interrupt vectors */
  24.     void _setargv();
  25.     void _setenvp();
  26.  
  27.     char *getenv(char *);
  28.     int  setenv(char *);
  29.  
  30.     int main(...);
  31.     void _exit(int);
  32. }
  33.  
  34. int C0argc = 0;
  35.  
  36. char **C0argv = 0;
  37. char **C0environ = 0;
  38. unsigned _psp    = 0;
  39. unsigned monoSeg = 0;
  40. unsigned colrSeg = 0;
  41. unsigned biosSeg = 0;
  42. unsigned _version= 0;
  43. unsigned _osversion = 0;
  44. unsigned char _osminor = 0;
  45. unsigned char _osmajor = 0;
  46.  
  47. unsigned _40h;
  48. unsigned _B800h;
  49. unsigned _B000h;
  50. unsigned _F000h;
  51.  
  52. unsigned _protected = 8;
  53. int     errno = 0;
  54.  
  55. unsigned _RealCvtVector = 0;
  56. unsigned _ScanTodVector[4] = { 0 };
  57.  
  58. static int (far *mainaddr)(...) = main;
  59.  
  60. static int exitCode = 0;
  61.  
  62. static jmp_buf program;
  63.  
  64.  
  65. //=======================================================================
  66. // _startup
  67. // get the program running
  68. //=======================================================================
  69.  
  70. int _startup(int argc, char **argv, char **env)
  71. {
  72.     C0argc = argc;
  73.     C0argv = argv;
  74.     C0environ = env;
  75.  
  76.     asm {
  77.         mov ax, 3000h
  78.         int 21h
  79.         mov _version, ax
  80.         mov _osversion, ax
  81.         mov _osmajor, ah
  82.         mov _osminor, al
  83.     }
  84.  
  85.     {
  86.         DPMI_Regs iregs;
  87.         iregs.eax = 0x5100;     // get PSP
  88.         iregs.reserved = 0;
  89.         iregs.flags = _FLAGS;
  90.         iregs.ss = 0;
  91.         iregs.sp = 0;
  92.         Dpmi.simulateRealInterrupt(0x21, &iregs);
  93.         _psp    = FP_SEG( Dpmi.makeDescriptor(iregs.ebx)   );
  94.     }
  95.  
  96.     // predefine a few selectors we need
  97.     _40h = biosSeg = FP_SEG( Dpmi.makeDescriptor(0x0040) );
  98.     _B000h = monoSeg = FP_SEG( Dpmi.makeDescriptor(0xb000) );
  99.     _B800h = colrSeg = FP_SEG( Dpmi.makeDescriptor(0xb800) );
  100.     _F000h = FP_SEG( Dpmi.makeDescriptor(0xf000) );
  101.  
  102.     _initialize();
  103.     if (setjmp(program)==0)
  104.         exitCode=(*mainaddr)(argc,argv,env);
  105.     _cleanup();
  106.     return exitCode;
  107. }
  108.  
  109. //=======================================================================
  110. // _terminate
  111. // normal program termination
  112. //=======================================================================
  113. void _terminate(int res)
  114. {
  115.     exitCode = res;
  116.     longjmp( program, 1);
  117. }
  118.  
  119. //=======================================================================
  120. // errorDisplay
  121. // display termination message
  122. //=======================================================================
  123. void errorDisplay(char near *msg)
  124. {
  125.     int msglen = 0;
  126.     char near *p = msg;
  127.     while (*p++) msglen++;
  128.     _asm {
  129.             mov     cx, msglen
  130.             mov     dx, msg
  131.             mov     ah, 040h
  132.             mov     bx, 2
  133.             int     021h
  134.     }
  135. }
  136.  
  137. //=======================================================================
  138. // abort
  139. // abnormal program termination
  140. //=======================================================================
  141. void abort()
  142. {
  143.     char near *msg = "Abnormal Termination\r\n";
  144.     errorDisplay(msg);
  145.     _exit(3);
  146. }
  147.  
  148. void _checknull( void ) { }                /* check for null pointer usage */
  149.  
  150. void _restorezero( void ) { }              /* restore interrupt vectors */
  151.  
  152.  
  153. //=======================================================================
  154. // Argv, Envp handling.  Does nothing because our loader takes care of us
  155. //=======================================================================
  156. int _setargv__ = 0;
  157. int _setenvp__ = 0;
  158. void _setargv() { }
  159. void _setenvp() { }
  160.  
  161.  
  162. //=======================================================================
  163. // Startup Table Handling
  164. //=======================================================================
  165.  
  166. const unsigned char PNEAR = 0;
  167. const unsigned char PFAR  = 1;
  168. const unsigned char NOTUSED = 0xff;
  169.  
  170. struct startup_table {
  171.     unsigned char calltype, priority;
  172.     void (far *funcptr)();
  173. };
  174.  
  175. extern startup_table InitStart;
  176. extern startup_table InitEnd;
  177. extern startup_table ExitStart;
  178. extern startup_table ExitEnd;
  179.  
  180.  
  181. void _initialize()
  182. {
  183.     startup_table *st;
  184.     for (;;) {
  185.         startup_table *lowent = 0;
  186.         for (st = &InitStart;st<&InitEnd;st++) {
  187.             if (st->calltype==PFAR||st->calltype==PNEAR) {
  188.                 if (lowent==0)
  189.                     lowent = st;
  190.                 else if (st->priority<lowent->priority) 
  191.                     lowent = st;
  192.             }
  193.             else if (st->calltype!=NOTUSED) {
  194. //                printf("Startup entry: %02x %02x %08lx\n", lowent->calltype, lowent->priority, lowent->funcptr);
  195. //              fflush(stdout);
  196.             }
  197.         }
  198.         if (lowent==0) break;
  199. //      printf("Startup entry: %02x %02x %08lx\n", lowent->calltype, lowent->priority, lowent->funcptr);
  200. //      fflush(stdout);
  201.         switch (lowent->calltype) {
  202.             case PFAR:
  203.                 lowent->calltype = NOTUSED;
  204.                 (*lowent->funcptr)();
  205.                 break;
  206.             case PNEAR:
  207.                 lowent->calltype = NOTUSED;
  208.                 void (near *nfuncptr)();
  209.                 nfuncptr = ( void (near *)() ) FP_OFF(lowent->funcptr);
  210.                 (*nfuncptr)();
  211.                 break;
  212.             default:
  213.                 ;
  214.         }
  215. //      printf("Startup entry done\n");
  216. //      fflush(stdout);
  217.     }
  218. }
  219.  
  220. //=======================================================================
  221. // Cleanup Table Handling
  222. //=======================================================================
  223.  
  224. void _cleanup()
  225. {
  226.     startup_table *st;
  227.     for (;;) {
  228.         startup_table *lowent = 0;
  229.         for (st = &ExitStart;st<&ExitEnd;st++) {
  230.             if (st->calltype==PFAR||st->calltype==PNEAR) {
  231.                 if (lowent==0)
  232.                     lowent = st;
  233.                 else if (st->priority>=lowent->priority) 
  234.                     lowent = st;
  235.             }
  236.             else if (st->calltype!=NOTUSED) {
  237. //                 printf("Cleanup entry: %02x %02x %08lx\n", lowent->calltype, lowent->priority, lowent->funcptr);
  238. //              fflush(stdout);
  239.             }
  240.         }
  241.         if (lowent==0) break;
  242. //      printf("Cleanup entry: %02x %02x %08lx\n", lowent->calltype, lowent->priority, lowent->funcptr);
  243. //      fflush(stdout);
  244.         switch (lowent->calltype) {
  245.             case PFAR:
  246.                 lowent->calltype = NOTUSED;
  247.                 (*lowent->funcptr)();
  248.                 break;
  249.             case PNEAR:
  250.                 lowent->calltype = NOTUSED;
  251.                 void (near *nfuncptr)();
  252.                 nfuncptr = ( void (near *)() ) FP_OFF(lowent->funcptr);
  253.                 (*nfuncptr)();
  254.                 break;
  255.             default:
  256.                 ;
  257.         }
  258. //      printf("Cleanup done\n");
  259. //      fflush(stdout);
  260.     }
  261. }
  262.