jchvr@ihlpb.ATT.COM (Schipaanboord) (09/25/88)
Here is some source code you can compile that shows how to determine the size the program needs before calling the TSR routine, it should work for any normal compiler which has a small memory model. ===== CUT HERE =========== /* This program must be compiled and linked as SMALL memory model, As such it is a demo showing how to determine the memory needed by this program in case you want to go TSR. Submitted by: ihnp4!ihlpb!hvlpa!hvriets Use or abuse at your own risk! */ /* Generic Small memory model, known for MSC and Lattice-C: Where Small means: ONE segment for program code pointed to by CS and ONE segment for data (all kinds), pointed to by DS LOMEM +---------------+ | PSP | 256 bytes +---------------+ CS -> | program code | knows as _TEXT in MSC +---------------+ | Optional junk | in MSC called NULL +---------------+ DS -> | global data | static data, in MSC: _DATA,CONST,_BSS +---------------+ | local data | in Lattice-C size given by extern int _stack | | in MSC known as STACK +---------------+ | malloc area | created by calling malloc(), in MSC: HEAP ptr -> +---------------+ HIMEM Total size in paragraphs is basically (ptr-CS+PSP_SIZE) / 16 provided that malloc gives increasing values. Every time you call malloc() the 'malloc area' is increased in size with N bytes, where N is 2 larger than the argument given to malloc(). These 2 bytes are used for a pointer to the next malloc block This however might differ in different compilers. */ #include <stdio.h> #include <dos.h> /* to define SREGS */ #define PSP_SIZE 256 /* 0xFF bytes for PSP */ #define PAR_SIZE 16 /* paragraph size */ #define PAR_ROUND 15 /* vaue to round to next paragraph boundary */ #if LATTICE extern int _TSIZE; /* Lattice-C value for memsize in paragraphs */ #endif extern char *malloc(); struct SREGS sregs; main() { char *ptr,*ptr2; int malloc_overhead; int size; /* first determine value of ptr and malloc_overhead*/ ptr = malloc(2); ptr2 = malloc(2); malloc_overhead = (int)ptr2 - (int)ptr -2; printf("\nMalloc overhead is %d bytes\n",malloc_overhead); if ( malloc_overhead < 0 ) { printf("Your malloc does not work as expected\n"); exit(1); } /* read value of CS and DS segments */ segread(&sregs); printf("SS=%d ES=%d DS=%d CS=%d\n",sregs.ss,sregs.es,sregs.ds,sregs.cs); printf("SS=0x%x ES=0x%x DS=0x%x CS=0x%x\n",sregs.ss,sregs.es,sregs.ds,sregs.cs); /* ds*PAR_SIZE converts paragraph address into real address */ /* +ptr adds offset to last data item */ /* +PAR_ROUND rounds it off to next paragraph boundary */ /* -malloc_overhead to correct for malloc info */ /* +PSP_SIZE to leave room for PSP */ /* /PAR_SIZE to convert back into paragraphs */ size = (sregs.ds*PAR_SIZE +(int)ptr +PAR_ROUND -malloc_overhead + PSP_SIZE -sregs.cs*PAR_SIZE)/PAR_SIZE; printf("Size in paragraphs=%d 0x%x\n",size,size); #if LATTICE printf("\nSize according to _TSIZE=%d 0x%x\n",_TSIZE,_TSIZE); printf("This size is one larger than our size, because we do\n"); printf("NOT count the malloced() area, and LATTICE does\n"); #endif printf("\nAnd as subroutine: %d\n",parsize()); printf("Please notice that when you call parsize()\n"); printf("The memory gets larger, due to call to malloc()\n"); printf("Since parsize() frees memory afterwards, this effect is\n"); printf("NOT compounding, as you can see be the next call\n"); printf("\nAnd as subroutine 2nd time: %d\n",parsize()); }/*main*/ /* as subroutine, ignoring malloc_overhead */ int parsize() { struct SREGS srg; char * ptr; int res; ptr = malloc(2); segread(&srg); res = (srg.ds-srg.cs) + ( ((int)ptr+15) >> 4) +16; free(ptr); return(res); }/*parsize*/ /* once you have allocated enough memory via malloc() for your program you can use the value of parsize(), as argument for the TSR call in INT21 Good luck, but be aware that many library routines routinely still try to call malloc for more memory, once you have gone TSR, you cannot use these routines anymore, so be careful */ TSR() { union REGS rg; /* defined in dos.h */ rg.x.ax = 0x3100; /* int21 TSR function */ rg.x.dx = parsize(); /* set size in pars. */ intdos(&rg,&rg); /* does not return */ }/*TSR*/