/*
  This subroutine forces the LU module become TSR.

  CopyRight 1995. Nicholas Poljakov all rights reserved.

 */

#include <dos.h>
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <psp.h>

/* Stack and pointer checking off */
#pragma check_stack( off )
#pragma check_pointer( off )
#pragma intrinsic( _enable, _disable )

/* Prototypes for interrupt function */
void (_interrupt _far *oldint68)( void );
void _interrupt _far rout( unsigned _es, unsigned _ds, unsigned _di,
			       unsigned _si, unsigned _bp, unsigned _sp,
			       unsigned _bx, unsigned _dx, unsigned _cx,
			       unsigned _ax, unsigned _ip, unsigned _cs,
			       unsigned _flags );

/* Huge pointers force compiler to do segment arithmetic for us. */

extern char svarea;
extern struct psp psp_ini;
extern _interrupt _far prtable();

char _huge *tsrstack;
char _huge *altstack;
char _huge *tsrbottom;

unsigned ProgPrefix;

void main()
        {
            unsigned tsrsize;
            unsigned env_seg;
            unsigned *t_seg;
	    char _near *p;

            /* Initialize stack and bottom of program. */
	    _asm {
		     mov  ax, seg tsrstack
		     mov  es, ax
		     mov  WORD PTR es:tsrstack[0], sp
		     mov  WORD PTR es:tsrstack[2], ss
                     mov  ax, seg svarea
                     mov  es, ax
                     mov  ax, seg psp_ini
                     mov  WORD PTR es:svarea[22], ax
                     mov  ax, offset psp_ini
                     mov  WORD PTR es:svarea[20], ax
                 }

            FP_SEG( tsrbottom ) = _psp;
            FP_OFF( tsrbottom ) = 0;

            ProgPrefix = _psp;   /* Save PSP value */

            p = _psp;
            FP_SEG( t_seg ) = p;
            FP_OFF( t_seg ) = 0x2c;
            env_seg = *t_seg;    /* Segment of DOS env. */
            _dos_freemem( env_seg ); /* free it */

            /* Program size is:
             *     top of stack
             *   - bottom of program (converted to paragraphs)
             *   + one extra paragraph
             */
            tsrsize = ((tsrstack - tsrbottom) >> 4) + 1;


            /* Replace existing int68 routine with our. */
            oldint68 = _dos_getvect( 0x68 );
            _dos_setvect( 0x68, prtable );

            /* Free the PSP segment and terminate with program resident. */
            _dos_keep( 0, tsrsize );
        }
