[comp.sys.ibm.pc.programmer] TSR Heap problem, estxrah@???

pipkins@qmsseq.imagen.com (Jeff Pipkins) (03/16/90)

A guy named Stu from estxrah@<somewhere in the uk> sent me a question about
how to keep your heap after going TSR.  After SEVERAL different attempts
to reach him at any address, I've decided to post the reply here, since it
may be of general interest.  Stu, if you read this, send a good address or
two, along with a phone number or something to pipkins@imagen.com

Synopsis of problem:
  Stu was using the _edata segment name to decide how much memory to keep
  after going TSR.  Of course, this released his heap and therefore caused
  his popup to quit working when his heap data was eventually overwritten.
  I suggested that he use the MCB (memory control block) right above his
  PSP (program segment prefix) to determine how much memory his program
  had actually allocated.


>[Stu's first question about obtaining the PSP address.] 

Function 62h is not available under DOS 2.xx.
Function 51h will do the same thing, and is available under
DOS 2.xx - 4.xx.  It's an undocumented call, but at least
it is always available.

A legitimate, documented way to access your PSP under any
version of DOS, if your program is in MSC, is to reference
the _psp variable, which is set by the MSC startup code.

         Mov     ES, __psp    ; Get PSP Segment

>[Stu's code to decide how much to save.]
>        Will this chunk of memory cover the buffer variables? This code
>doesn't seem to work!

I think you've misunderstood the information available.  Let me start over...

_do_tsr     Proc     Near

            Mov      AX, Word Ptr [__psp]    ; Get segment of PSP
            Dec      AX                      ; Get segment of MCB
            Mov      ES, AX                  ;   (Memory Control Block)
            Mov      DX, Word Ptr ES:[3]     ; Get size of MCB in paragraphs
            Mov      AX, 3100h               ; TSR
            Int      21h

            Ret                              ; Freak if you ever get here...
_do_tsr     EndP


This memory block should have EVERYTHING in it.  Including your global data
and stack.

I haven't tested the above code, but it's pretty simple.  I have used this
principle before under different circumstances, and it worked nicely.


-Jeff Pipkins
pipkins@imagen.com