home *** CD-ROM | disk | FTP | other *** search
- //=====================================================================
- //
- // startup.cpp
- //
- // program initialization for protected mode Borland C applications
- //
- // Copyright (c) 1994, Kevin Morgan, All rights reserved.
- //
- //=====================================================================
- #include <stdio.h>
- #include <dos.h>
- #include <setjmp.h>
- #include "dpmish.h"
-
- extern "C" {
- int _startup( int, char **, char ** );
- void _initialize( void );
- void _cleanup( void ); /* call #pragma exit routines */
- void abort( void );
-
- void _terminate( int ); /* terminate program */
- void _checknull( void ); /* check for null pointer usage */
- void _restorezero( void ); /* restore interrupt vectors */
- void _setargv();
- void _setenvp();
-
- char *getenv(char *);
- int setenv(char *);
-
- int main(...);
- void _exit(int);
- }
-
- int C0argc = 0;
-
- char **C0argv = 0;
- char **C0environ = 0;
- unsigned _psp = 0;
- unsigned monoSeg = 0;
- unsigned colrSeg = 0;
- unsigned biosSeg = 0;
- unsigned _version= 0;
- unsigned _osversion = 0;
- unsigned char _osminor = 0;
- unsigned char _osmajor = 0;
-
- unsigned _40h;
- unsigned _B800h;
- unsigned _B000h;
- unsigned _F000h;
-
- unsigned _protected = 8;
- int errno = 0;
-
- unsigned _RealCvtVector = 0;
- unsigned _ScanTodVector[4] = { 0 };
-
- static int (far *mainaddr)(...) = main;
-
- static int exitCode = 0;
-
- static jmp_buf program;
-
-
- //=======================================================================
- // _startup
- // get the program running
- //=======================================================================
-
- int _startup(int argc, char **argv, char **env)
- {
- C0argc = argc;
- C0argv = argv;
- C0environ = env;
-
- asm {
- mov ax, 3000h
- int 21h
- mov _version, ax
- mov _osversion, ax
- mov _osmajor, ah
- mov _osminor, al
- }
-
- {
- DPMI_Regs iregs;
- iregs.eax = 0x5100; // get PSP
- iregs.reserved = 0;
- iregs.flags = _FLAGS;
- iregs.ss = 0;
- iregs.sp = 0;
- Dpmi.simulateRealInterrupt(0x21, &iregs);
- _psp = FP_SEG( Dpmi.makeDescriptor(iregs.ebx) );
- }
-
- // predefine a few selectors we need
- _40h = biosSeg = FP_SEG( Dpmi.makeDescriptor(0x0040) );
- _B000h = monoSeg = FP_SEG( Dpmi.makeDescriptor(0xb000) );
- _B800h = colrSeg = FP_SEG( Dpmi.makeDescriptor(0xb800) );
- _F000h = FP_SEG( Dpmi.makeDescriptor(0xf000) );
-
- _initialize();
- if (setjmp(program)==0)
- exitCode=(*mainaddr)(argc,argv,env);
- _cleanup();
- return exitCode;
- }
-
- //=======================================================================
- // _terminate
- // normal program termination
- //=======================================================================
- void _terminate(int res)
- {
- exitCode = res;
- longjmp( program, 1);
- }
-
- //=======================================================================
- // errorDisplay
- // display termination message
- //=======================================================================
- void errorDisplay(char near *msg)
- {
- int msglen = 0;
- char near *p = msg;
- while (*p++) msglen++;
- _asm {
- mov cx, msglen
- mov dx, msg
- mov ah, 040h
- mov bx, 2
- int 021h
- }
- }
-
- //=======================================================================
- // abort
- // abnormal program termination
- //=======================================================================
- void abort()
- {
- char near *msg = "Abnormal Termination\r\n";
- errorDisplay(msg);
- _exit(3);
- }
-
- void _checknull( void ) { } /* check for null pointer usage */
-
- void _restorezero( void ) { } /* restore interrupt vectors */
-
-
- //=======================================================================
- // Argv, Envp handling. Does nothing because our loader takes care of us
- //=======================================================================
- int _setargv__ = 0;
- int _setenvp__ = 0;
- void _setargv() { }
- void _setenvp() { }
-
-
- //=======================================================================
- // Startup Table Handling
- //=======================================================================
-
- const unsigned char PNEAR = 0;
- const unsigned char PFAR = 1;
- const unsigned char NOTUSED = 0xff;
-
- struct startup_table {
- unsigned char calltype, priority;
- void (far *funcptr)();
- };
-
- extern startup_table InitStart;
- extern startup_table InitEnd;
- extern startup_table ExitStart;
- extern startup_table ExitEnd;
-
-
- void _initialize()
- {
- startup_table *st;
- for (;;) {
- startup_table *lowent = 0;
- for (st = &InitStart;st<&InitEnd;st++) {
- if (st->calltype==PFAR||st->calltype==PNEAR) {
- if (lowent==0)
- lowent = st;
- else if (st->priority<lowent->priority)
- lowent = st;
- }
- else if (st->calltype!=NOTUSED) {
- // printf("Startup entry: %02x %02x %08lx\n", lowent->calltype, lowent->priority, lowent->funcptr);
- // fflush(stdout);
- }
- }
- if (lowent==0) break;
- // printf("Startup entry: %02x %02x %08lx\n", lowent->calltype, lowent->priority, lowent->funcptr);
- // fflush(stdout);
- switch (lowent->calltype) {
- case PFAR:
- lowent->calltype = NOTUSED;
- (*lowent->funcptr)();
- break;
- case PNEAR:
- lowent->calltype = NOTUSED;
- void (near *nfuncptr)();
- nfuncptr = ( void (near *)() ) FP_OFF(lowent->funcptr);
- (*nfuncptr)();
- break;
- default:
- ;
- }
- // printf("Startup entry done\n");
- // fflush(stdout);
- }
- }
-
- //=======================================================================
- // Cleanup Table Handling
- //=======================================================================
-
- void _cleanup()
- {
- startup_table *st;
- for (;;) {
- startup_table *lowent = 0;
- for (st = &ExitStart;st<&ExitEnd;st++) {
- if (st->calltype==PFAR||st->calltype==PNEAR) {
- if (lowent==0)
- lowent = st;
- else if (st->priority>=lowent->priority)
- lowent = st;
- }
- else if (st->calltype!=NOTUSED) {
- // printf("Cleanup entry: %02x %02x %08lx\n", lowent->calltype, lowent->priority, lowent->funcptr);
- // fflush(stdout);
- }
- }
- if (lowent==0) break;
- // printf("Cleanup entry: %02x %02x %08lx\n", lowent->calltype, lowent->priority, lowent->funcptr);
- // fflush(stdout);
- switch (lowent->calltype) {
- case PFAR:
- lowent->calltype = NOTUSED;
- (*lowent->funcptr)();
- break;
- case PNEAR:
- lowent->calltype = NOTUSED;
- void (near *nfuncptr)();
- nfuncptr = ( void (near *)() ) FP_OFF(lowent->funcptr);
- (*nfuncptr)();
- break;
- default:
- ;
- }
- // printf("Cleanup done\n");
- // fflush(stdout);
- }
- }