home *** CD-ROM | disk | FTP | other *** search
- #include <alloc.h>
- #include <dos.h>
- #include <stdlib.h>
-
- /*
- Determine if we are using a large data model
- (COMPACT, LARGE, or HUGE). The memory map for a
- large data model differs from that for a small data
- model in that the heap comes after, not before, the
- stack. This code will compile and run for the
- correct memory model.
- */
- #if sizeof(void far *) == sizeof(void *)
- #define LARGE_DATA
- #endif
-
- /*
- This is a Turbo C variable that determines the size
- of the stack at startup.
- */
- extern unsigned _stklen;
-
- /*
- These variables define the stack segment and offset
- to be used by the TSR.
- */
- unsigned my_ss, my_sp;
-
- /*
- Minimum number of paragraphs required for TSR's
- stack.
- */
- #define MIN_STACK 0x40
-
- /*
- Install a TSR.
- */
- void install_tsr(unsigned heap, unsigned stack)
- {
- char *_eodata;
- unsigned EODATA, keeplen;
-
- /*
- In a large data model, the size of the stack cannot
- be changed since it is "sandwiched" between the
- global data segment and the heap. To set the size
- of the stack (which is initialized by the startup
- code), use the following declaration somewhere in
- your code:
-
- unsigned _stklen = STACK_SIZE;
-
- e.g. To allocate a 1k stack:
- unsigned _stklen = 1024;
-
- Changing _stklen itself will not change the size of
- the stack and may have disastrous results, as it is
- used by this routine.
- */
- #if !defined(LARGE_DATA)
- /*
- Make sure we have enough stack space.
- */
- stack = max(MIN_STACK, stack);
- #endif
-
- /*
- Get end-of-data segment. If the end of the data
- segment is not on a paragraph boundary, adding 15
- (0xF) bytes will push it over to the next paragraph.
- */
- _eodata = sbrk(0);
- _eodata += 0xF;
-
- /*
- Find the next paragraph available after the TSR.
-
- FP_SEG() and FP_OFF() are Turbo C macros that
- determine the segment and offset of a far pointer.
- If the pointer is a near pointer, FP_SEG() casts it
- to a far pointer and returns the value of the
- appropriate segment register (DS). The paragraph
- number is normalized by adding the number of
- paragraphs included in the offset.
- */
- EODATA = FP_SEG(_eodata) + (FP_OFF(_eodata) >> 4);
-
- #if defined(LARGE_DATA)
- /*
- Amount of memory required is (program size + heap).
- */
- keeplen = EODATA - _psp + heap;
-
- /*
- Use existing stack (i.e. stack that was set up by
- the startup code).
- */
- my_ss = _SS;
- my_sp = _stklen;
-
- #else
-
- /*
- Amount of memory required is (program size + heap +
- stack).
- */
- keeplen = EODATA - _psp + heap + stack;
-
- /*
- Stack comes after data segment and heap and grows
- down in memory.
- */
- my_ss = EODATA;
- my_sp = (heap + stack) * 16;
- #endif
-
- keep(0, keeplen);
- }