home *** CD-ROM | disk | FTP | other *** search
-
- /* X0.c
-
- This is the startup module for external functions.
- Recompiling requires Borland C++ or Turbo C and Assembler.
-
- There is an alternate startup module in this file for external
- functions which do not require DS=SS. The math library, ld.lib,
- which has been provided, does not require DS=SS. Programs built
- with this save some disk space.
-
- Options.
-
- You must set Opt=1 or Opt=2.
-
- 1. External function sets up its own stack segment. This allows
- you to guarantee enough stack space, but more importantly, it allows
- DS=SS which is what the compiler expects in tiny model. Unfortunately,
- however, the floating point emulator doesn't work in a foreign stack
- segment. Do not use this option unless you are using a math coprocessor.
-
- 2. External function uses Mercury's stack segment. This is more efficient,
- but requires you to write your function in tiny model without using DS=SS,
- which Borland C tiny model normally assumes. Most simple functions in tiny
- model don't actually make use of DS=SS, but this option is dangerous unless
- you are familiar with the way Turbo C generates code.
-
- bcc -c -mt! -w -ox01 -DOpt=1 -Z -O x0
- bcc -c -mt! -w -ox02 -DOpt=2 -Z -O x0
-
- x01.obj uses stack swap
- x02.obj uses Mercury stack
-
- See the examples, GCD.C and ASINH.C, for instructions on how to link.
- Using Option 1 requires linking with F87.OBJ.
-
- If using Turbo, compile with "tcc -c -mt -w ...".
- */
-
-
- #pragma inline
-
- /* TC is not too happy about this, but it does the right thing. */
- #pragma warn -asm
- asm DGROUP group _TEXT,_DATA,_BSS
- #pragma warn .asm
-
- pascal xmain(double far *);
-
- /*
- To handle tiny model properly, must have CS=DS=SS.
- Simple programs, eg not passing addresses of local variables, don't need SS.
-
- */
-
- #ifndef Opt
- #error Must define Opt=1 or Opt=2.
- #endif
-
- #if Opt == 1
- #define SwapSS 1
- #endif
-
- #if Opt == 2
- #define SwapSS 0
- #endif
-
- #if !SwapSS
-
- /* Opt = 2 */
-
- static void far pascal start(double *a)
- {
-
- _ES = _SI = _DS;
- _DS = _CS;
-
- xmain((double _es *) a);
-
- _DS = _SI;
- return;
- }
-
- #else
-
- /* Opt = 1 */
-
- /* make external, so user can set it? */
- #define StackWords 1000
- int stack[StackWords] = { 0 };
-
- /*
- Must preserve bp, si, di, ds, ss.
- Called with ds = ss.
- */
-
- static void far pascal start(double *a)
- {
- _BX = (unsigned int) a;
- asm mov cx, sp
- asm mov dx, ss
-
- _AX = (unsigned int) (&stack[StackWords]);
-
- /* switch to local stack */
- asm push cs
- asm pop ss
- asm mov sp, ax
-
- /* save prior ss, sp */
- asm push dx
- asm push cx
-
- /* set ds=cs */
- asm push cs
- asm pop ds
-
- /* call xmain */
- asm mov es, dx
- xmain((double _es *) _BX);
-
- /* restore ss, sp, ds=ss */
- asm pop cx
- asm pop dx
- asm mov ss, dx
- asm mov sp, cx
- asm mov ds, dx
-
- return;
- }
-
- #endif
-