Table of Contents
Early mid January work on the MCP
2026-01-18
This week I put some work into the Master Control Program (MCP), and a new helper utility called the Codified Likeness Utility (CLU). (Both, of course, named for programs in the Tron franchise.) The MCP is stored in a file named ldosmcp.com or ldosmcpz.com which contains the lDOS kernel, a triple-mode lDebug build, the lDOS pre-boot loader, the instsect tool to install boot sector loaders, the patldos tool to patch lDOS kernel files, an Extension for lDebug library with over 60 extensions, and newly a FreeCOM build.
CLU is in a file named clu.exe, which can be used as the file pointed to by the COMSPEC variable. It finds ldosmcp.com and replaces its own process with the MCP, with a special handshake so that the MCP will load its FreeCOM build.
patchini
- (Older changeset only uploaded this week.) Parse an initial number to select which block to operate on. This change only adds the parsing.
- Add the progress mode LIST to list all current choices of progress modes.
- Skip subsequent parsing of progress mode if progress mode LIST already selected.
- Support the lCFGMULT00 pointer block. This is a block that points to other lCFG blocks. It must be placed on a 16-byte boundary within the first 8 KiB of the file. It can point to lCFG blocks much farther into the file however. If multiple blocks are found and no block specifier was given, a hint is shown. If a nonzero block specifier was given, a different hint is shown which identifies the block that is in use. (This is used only for the Master Control Program.)
- When selecting first entry from an lCFGMULT00 block as default, also select its size.
- Store the lCFG00 signature into the big table, to prepare for different signatures.
- Support MCPCFG00 blocks, with the configurations TIMEOUT and MENUDEFAULT.
- If LIST is given without a filename, don't show message "lCFG block does not contain any known configuration".
- Allow to specify ALL instead of a number for the block selection.
- Allow to continue if a block isn't found or doesn't contain this configuration, if ALL blocks selected.
- Error out at end if ALL blocks selected and not a single block is found.
- Insert quote marks so the source file isn't accidentally matched as an MCPCFG00 block. (This actually happened.)
- Fix warning about a "left shift count >= width of type" on gcc-ia16, by inserting type casts into the getu32 and getu16 functions.
- patchqry.c: Use comparecaps function instead of the workaround.
- patchqry.c: Extract the function parsenumber, to parse number as decimal, hexadecimal, or binary, with optional plus or minus sign prefix.
- In the parsenumber function pass the second parameter as "replaceforbidden" instead, allowing the caller to evaluate the exact condition.
- patldos.c: Extract function parsenumber, pick from patchqry.c
- patldos.c: Include patchqry.c code as a subfunction accessed by specifying the QUERY keyword. This is another instance of the "go everywhere, do everything" mantra: Why use two separate programs when you can put them together into one?
- Call patchqrymain if listing the individual help pages.
- patchqry.c: Adjust command line help usage lines so they're more similar to the rest of patldos
- Also invoke patchqrymain if LIST and a filename is specified, to list the current query patch site.
tractest/convlist.pl
Properly process FreeCOM map and listing files, for the FreeCOM gcc-ia16 build. In particular, this includes:
- The gccsections indicator line may have something trailing after the second number.
- Filenames may be given as library files, where the actual file is specified in round parentheses.
- To find the relevant listing file, take the filename in parens.
As usual, the gcc-ia16 listing files generated by the FreeCOM build are not especially good, but they do save some work particularly in dumping the call destinations in plain text.
lDebug
- Disable _IMAGE_EXE for the loader build. This need wasn't anticipated for the debugger, so the solution is a little hackish.
- Fix: If kernel command line is supported but none specified, do not use a stale byte load_cmdline_first. This would lead to a spurious letter in the kernel command line.
- Fix: Enable GOTO command for loader build. (Was disabled because it needs to be checked for in gg, which was replaced for the loader build.)
- Document ELDUSE noun for ldmem Extension for lDebug.
- Update news-r10 with the loader AMIS signature and boot command line fix. Ordinarily a loader feature wouldn't be listed in the news, but the different signature does also affect the debugger build as it searches for the different signature in some places.
- In the loader manual list GOTO and IF commands as being the same as for the debugger.
- Update some attribution years to 2026.
- Add S MCB type 16h (init FCB SFT), and update attribution year to 2026.
FreeCOM
These changes live in the branch ecm-mcp (described in an issue), and are primarily intended for use in the Master Control Program.
- .gitignore: Add .rel, .tls, .swp, and mak.sh files.
- Use FREECOM_SKIP markers in the executable to find resources. This allows FreeCOM to find its resources within the ldosmcp.com file.
- Create listing and relocation files for C object files. These are for use by convlist.pl to create a trace listing (.tls) file. The objdump invocation comes with a new
|| truesuffix to avoid aborting the makefile on an unknown relocation type in some file. Other than that the change is copied from an earlier change to the FreeDOS kernel's SYS build. - Use the variable FREECOMFILE to find the file from which to load resources. COMSPEC is no longer preferred for this. If COMSPEC is set already, it is not changed. This helps CLU so that it can set COMSPEC to point to itself (clu.exe), but have FreeCOM set FREECOMFILE to point to ldosmcp.com
lDOS kernel
- Update manual descriptions of patldos.
- In manual section config-cmdline list VERBOSE and HALTFLAG commands.
- In the comloader for its MCP build:
- Include FreeCOM executable. This includes a FreeCOM skip marker that points from the end of the comloader to the end of the FreeCOM executable image.
- Support the CLU flag to fast track loading FreeCOM.
- Support CLU flag indication that CLU was loaded in the UMA, relocating our process (including the relocated FreeCOM program but excluding the full comloader) into the UMA if it fits.
- Fix to assemble movp also if _MCP build is selected, rather than only if _MZEXESUPPORT is enabled. In practice, both are enabled for the MCP build.
Master Control Program
- Include an lCFGMULT00 pointer block to point to other configuration blocks. Currently points to lDOS kernel, lDebug, and loader.
- Adjust entrypoint of the loader payload. This was 0:32 previously because the loader was build with _IMAGE_EXE enabled. With this option disabled, the kernel entrypoint is at 0:0.
- Add a description and attribution to the iniloadi.asm header comment.
- Add a boot menu default choice with a timeout. This also adds the MCPCFG00 header to configure both the timeout and the menu default choice. The MCPCFG00 block is also pointed to by the lCFGMULT00 header.
- Extract the function getdefault1 to get the menu default choice.
- Allow a kernel command line starting with CHOOSE DEFAULT. This acts like CHOOSE MENU if no default is configured, and selects the default without showing the menu otherwise.
- Copy over the FreeCOM executable for building the MCP.
- Add FreeCOM skip marker to point from the initial loader to the end of the comloader.
- Check that the FreeCOM skip marker fits within the first 8 KiB of the file.
- CLU launcher:
- Initial commit. Implements loading the MCP (using int 21h function 4B01h) and terminating CLU's own process so that the MCP effectively replaces CLU. Runs an ldosmcp.com file that must be found in the current working directory.
- Check for and set the CLU flag in MCP.
- Copy CLU's MCB name to the MCP process's MCB.
- Build clu.exe in the mak.sh script.
- Search for the MCP executable in CLU's directory, then in the root directory of the boot drive, and then in the current working directory.
- Detect whether CLU is (initially) loaded into the UMA, and indicate it in the CLU flag. This revision failed to actually detect the first UMCB, so it would use the fallback of the hardcoded value A000h as the UMA cutoff segment instead.
- Relocate the CLU process to the top of the Low Memory Area before loading the MCP. This reduces fragmentation if no UMA is available.
- If not yet found, set COMSPEC variable to point to clu.exe itself. There's a branch of the code commented out that would delete an existing COMSPEC variable if found. I think it's nicer to allow the user to override what COMSPEC to use.
ETA:
Extract function findvar to find an environment variable.
Parse a variable, %CLUMCPFLAG%, to select one of as yet 4 different flags:
- 1 = Override current
%COMSPEC%if it is already set. - 2 = Do not relocate CLU process before running exec. (The handover from CLU to the MCP still involves a type of process relocation, so to say. Disabling this isn't supported yet, though could be done by leaving a small shim CLU process resident.)
- 4 = Never set the "UMA flag" in the MCP's CLU flag.
- 8 = Always set the "UMA flag" in the MCP's CLU flag. If both 4 and 8 are set, 4 takes precedence.
