Skip to content

Commit

Permalink
mcb_walk.c: try querying UMB link state even if not on DOS 5+
Browse files Browse the repository at this point in the history
Current lMS-DOS still reports its version as v4.00 but does fully
support a DOS-managed UMA. As of today lMS-DOS also supports the
SHELLHIGH= directive. Like FreeDOS's this is implemented using
the 21.4B80 extension. Although the internals differ, the outside
observable behaviour is the DOS executable loader allocates both
the environment and the process memory block into the UMA, if
there are free UMBs. However, unlike LH the UMB link state is not
enabled once the control flow is passed to the application. That
means an environment block in a UMB isn't reachable when walking
the MCBs without regard to proceeding past the first UMCB.

The MCB walker is used in FreeCOM's init to validate the
environment block passed to it upon its startup. Reference:
https://github.com/FDOS/freecom/blob/cede733377c454cb93e9038d476582f0d1fcbf0a/shell/init.c#L238

If this check fails, then the shell will prompt for the position
of its executable as follows. This patch makes the MCB walker
enable the UMB link even if the reported DOS version is below 5,
allowing it to find the environment block's UMCB and avoiding
the prompt.

Failed to load the strings resource into memory, the location
pointed to in %COMSPEC% seems to be invalid. Please specify another
location of FreeCOM to try to load the strings from, e.g.:
C:\COMMAND.COM
or just hit enter to cancel to load the strings.
  • Loading branch information
ecm-pushbx authored and PerditionC committed Feb 17, 2025
1 parent 86e951e commit 74eddec
Showing 1 changed file with 14 additions and 3 deletions.
17 changes: 14 additions & 3 deletions suppl/src/mcb_walk.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,22 @@ int mcb_walk(word mcb, const MCB_WALKFUNC fct, void * const arg)

/* for walking, link in UMB list */
UMBLink = 1; /* Don't unlink UMBs */
if(_osmajor >= 5) { /* UMBs since DOS 5 */
{
_AX = 0x5802; /* Get UMB Link state */
/* /// Modified to use __emit__(), which doesn't require an assembler,
if we're compiling with TurboC. - Ron Cemer */
#if defined(_TC_EARLY_)
__emit__((unsigned char)0xf9); /* stc */
#elif defined(__WATCOMC__) || defined(__GNUC__)
reg.x.flags |= 1;
#else
asm {
stc
}
#endif
geninterrupt(0x21);
UMBLink = _AL;
if(!_CFLAG && !UMBLink) { /* There are UMBs && not linked, yet */
if(!_CFLAG && !_AL) { /* There are UMBs && not linked, yet */
UMBLink = _AL;
DBG_STRING("Link in UMBs")
_BX = 1; /* Link them */
_AX = 0x5803; /* Set UMB Link state */
Expand Down

0 comments on commit 74eddec

Please sign in to comment.