On at 2022-07-12 20:01 +0200, Jose Senna wrote:
Bret Johnson said:
> The way it works is to make a "copy" of
> itself at the top of conventional memory,
> terminates itself (using a normal DOS
> terminate process, which includes deleting
> the original PSP), and then continues
> running from the "copy". The "copy" decides
> where the best place in memory is to load
> the TSR (which can even be in one or more
> "memory holes" left by some other program
> or in upper memory),allocates appropriate
> memory block(s), and then installs itself
> in the allocated memory.
But when it terminates, the system would
not return to the parent of the utility,
(COMMAND or whatever called the utility) ?
So, how can the copy continue running
after termination ?
Good question! As I independently invented this method, I will answer
quickly. You can read my reference implementation in my TSR example [1].
Basically, it creates a new PSP (the system structure that makes up a
DOS process) in a temporary memory block, then bends that memory block
to "belong to itself" (as memory blocks used for PSPs usually do). This
means that when we terminate with service 4Ch, the temporary allocation
is not freed because it doesn't belong to the original process.
The actual "jump" over to the new temporary process is achieved by
twisting the parent process field and the Parent Return Address (aka
interrupt 22h) of the original process. Their original contents (which
refer to the shell or whatever other process EXECed our program) are
transferred into the new temporary PSP, so that upon its termination it
will actually return to the shell. The old original PSP is instead
modified to refer to the new PSP as its parent, and the original PSP's
PRA is also modified to jump into the code of the relocated process.
(Additionally, there is a field in the *parent* PSP which indicates what
stack to use when returning from DOS process termination to the parent.)
In part this was inspired by FreeDOS Debug (and before this actual
shells for DOS, too, I believe even MS-DOS COMMAND.COM does this). It
sets up its parent as itself, and its PRA to return into its own
resident code. DOS detects the special condition of a self-parented
process in its termination handling, and will not free memory nor close
the file handles in this case. (Just as for service 31h TSR termination
actually, it also neither frees memory nor closes handles, as I
mentioned in my longer reply earlier.) That allows the shell (and the
debugger, which touts itself a kind of shell [2]) to retain control
after it was aborted with Control-C or upon a critical error when
"Abort" was selected.
Regards,
ecm
[1]: https://hg.pushbx.org/ecm/tsr/file/daca203fa216/transien.asm#l988
[2]:
https://hg.pushbx.org/ecm/ldebug/file/d8d009634290/source/debug.asm#l1319
_______________________________________________
Freedos-devel mailing list
Freedos-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/freedos-devel