Multitasking MS-DOS 4

Multitasking or European MS-DOS 4 refers to an intermediate operating system between MS-DOS and OS/2 released in the mid-1980s. Unlike its predecessors and even contemporary versions of Microsoft Windows, it implements preemptive multitasking with a time-sliced scheduler. It was only offered by certain original equipment manufacturers located in Europe.
The project was intended to be the successor to MS-DOS 2 and later MS-DOS 3, although it does not share much code with it. The system natively supports the New Executable format from Windows 1.0 in addition to older COM and MZ executables. However, only NE format executables can be multitasked, while running legacy MS-DOS applications will suspend all background tasks. A large part of the operating system was also rewritten in C, including the entirety of the command interpreter (COMMAND.COM), several utilities (such as FDISK.EXE, the disk partition tool) and parts of the DOS kernel (IBMDOS.COM). Documents suggest that many features, such as threading and named pipes, were also planned but removed or otherwise scrapped during development.
Most vendors did not adapt this version of MS-DOS due to IBM's lack of interest in the operating system, which preferred a multi-tasking environment that took advantage of the 80286 protected mode.Osterman, Larry. Did you know that OS/2 wasn't Microsoft's first non-Unix multi-tasking operating system?, Larry Osterman's WebLog. 22 March 2004. This led to IBM and Microsoft signing a Joint Development Agreement in August 1985, under which both companies cooperated on further development of the MS-DOS 4 codebase. The project, occasionally called "DOS 5.0" as the successor to MS-DOS 4,Letwin, Gordon. Inside OS/2 (pp. 11). would ultimately become OS/2.Osterman, Larry. 24 years ago today (1985), Larry Osterman's WebLog. 26 August 2009.Osterman, Larry. "1986: MS-DOS 4 forked into OS/2, but other customers were left behind who needed support. One of those was Goupil in France, so while the rest of MSFT was shut down moving to a new campus, a co-worker and I traveled to Paris for a weekend to fix bugs for Goupil." – via Twitter. 28 August 2020.
Several OEMs shipped the multitasking MS-DOS 4 with their computers: namely, International Computers Limited,MS-DOS Version 4.10 Fujitsu ICL OEM, http://www.16BitOS.com. Archived from the original on 6 October 2020.ICL DRS PWS M80 c1988, The ICL Computer Museum. Siemens,Brown, Ralf. x86/MS-DOS Interrupt List, Release 61. and SMT Goupil. It was also at the very least evaluated by Wang Laboratories in the US. Organizations that have deployed the operating system include the Australian governmenthttps://groups.google.com/g/comp.os.cpm/c/-1n4L4gT3dg/m/ulXs38XPlw4J and the French post.Williams, Dave. Programmer's Technical Reference for MSDOS and the IBM PC (Version 3.3) (ch. 4, sec. 11). 20 January 1994.
The operating system was considered lost until disk images of an internal build were uploaded to PCjs.org (then called JSMachines.net) on 11 March 2013. Internal documentation, as well as a beta build from 1984 and the source code for the DOS BIOS from that build was released on 25 April 2024, together with the full source code for the single-tasking MS-DOS 4.
== Known releases ==
There are currently five publicly available releases of Multitasking MS-DOS 4.0. The disk images originally uploaded to JSMachines.net contain an internal Microsoft build, most components of which have been compiled on 26 November 1985, shortly after the release of Windows 1.0. IBMDOS.COM contains the version string "[I]nternal revision 6.7, 85/11/26", although it has been patched to not display in output.
The second release is a SMT Goupil OEM version released in May 1986. While most of the OS is identical to the previous build, parts of the operating system were recompiled on 26 March 1986. It is largely the same as the non-OEM version albeit with extra utilities, which include PS.EXE (a Unix-style process status command), DEBUGDD.SYS (the kernel debugger), and DOSSIZE.exe (a utility to determine the layout of conventional memory and the amount taken up by DOS). The session manager (SM.EXE) is absent in this release and so there is no way to visually multitask, although the one from the previous build works fine if set as the default shell via the SHELL= statement in CONFIG.SYS. 
The third release is dated 17 November 1986 and is likely to be the ICL OEM version, or less likely, an original dump of the Goupil version. There are substantial changes from the previous two releases – the kernel was cut down in size, making it possibly the "scaled down" version that Osterman references in blog posts. The hard error daemon (HE_DAEM.EXE) and session manager are not included, and attempting to run applications from the earlier builds results in a * User Error 914F: Dynamic link loaded * error, possibly indicating that dynamic linking was removed from this version. Nevertheless, the system still retains support for preemptive multitasking. A native version of MS-Net for multitasking MS-DOS is also included, the only commercial product known to be released for the system. This is the only available release that is able to run Windows 1.0, which it achieves by applying custom patches to the Windows kernel when loading the fast boot blob (WIN100.BIN).
The fourth release, an external beta release compiled on 29 May 1984, was officially released by Microsoft, as well as internal documentation dated 30 October 1984 and the source code of MS-DOS 4.00, on 25 April 2024.
A fifth release, another beta release from 28 May 1985 was uploaded to a warez BBS on 2 May 1987 and recovered on 23 June 2024. 
An updated version, Multitasking MS-DOS 4.10, was developed for the ICL DRS Professional Workstation and is known to exist in private collections. It is currently unknown what changes it may include.
Wang Laboratories, an American computer company, apparently tested a version of Multitasking MS-DOS 4.0, described as an "alpha version", for an unnamed laptop project in 1985, but decided not to bundle it with the laptop because of poor compatibility with "ill-behaved" MS-DOS apps. A beta tester was quoted as saying that "the only thing it would run was COMMAND.COM".
=== List ===
 
 
== Emulator compatibility ==
There are some issues with booting this OS on some emulators, with some configurations; issues with Multitasking DOS 4 are possible even on emulators where a "regular" MS-DOS version will run and work perfectly fine.
 Emulator compatibility
Emulator 	Result
86Box 4.0	Internal revision 6.7: Will not boot on 808x configurations. Requires an 80286 or later to boot. Otherwise, seems to run fine.
PCjs 	Internal revision 6.7: Runs fine on 8086, 80286 and 80386 configurations.
MartyPC 	
Internal revision 6.7 and later: Requires at least version 0.2.0 to boot. This is due to two separate bugs - the bug causing a failure to boot is due to inaccurate PIC ICW2 (initialization command word 2) emulation causing a hang midway through boot, after displaying the "MS-DOS Version 4.00" screen, waiting for an interrupt to arrive that never does due to aforementioned inaccurate emulation; the bug causing a failure to boot from a hard drive is aparately failing to boot during a hard disk read (most likely to discover the drives in the system) if the Xebec IBM 5150 HDD controller is configured. 
Internal revision 4.11 and earlier: Does not work. A bug report has been filed on stable 0.2.2. 2.06 experiences a hard error and 4.11 spews multicoloured garbage all over the screen.
PCem v17 	Internal revision 6.7: Runs fine on 8086, 80286 and 80386 configurations.
== Relationship to OS/2 ==
The operating system has numerous similarities to OS/2, to the point where it almost certainly is based on the same codebase for it:
* Identical strings in the bootloader, kernel, shell, and apps (such as the Top level process aborted, cannot continue string) with early builds of OS/2, including the May 1987 SDK build and revision 7.68.
* The same version number format (Internal revision...) and even date format in the version number as OS/2.
* C Library strings in numerous parts of the OS, indicating that the OS was largely rewritten in C. This is the case for the shell, parts of the kernel, and many utilities such as FDISK. 
* Identical source file names in the bootloader, IBMBIO.COM (msinit.asm 6.7 85/11/26 in this build, msinit.asm 8.11 86/10/21 in IBM OS/2 1.0 revision 7.68)
* Identical names for operating system concepts (PS.EXE in the Goupil OEM version of this build references the Per-Task Data Area, PTDA, which is the primary process information structure in OS/2)
* The same New Executable binary format is used.
* The same manner of calling system APIs (exports from New Executable files) is used, although Multitasking MS-DOS 4.0 uses INT 21h as well.
* The same directory name for shared memory (/SHAREMEM) internally in the kernel.
* The same signal system used for killing processes as OS/2, with some signal numbers being the same (signal 1 for + is identical, but other signals were moved around)
* Pre-emptive multitasking and child process support using a quantum scheduler.
* DOSCALLS being used for kernel exported APIs, identically to OS/2 (although actually as a part of IBMDOS.COM and not "farmed out" to DOSCALLS.EXE).
* IBM OS/2 having the same bootloader and kernel filenames as Multitasking MS-DOS 4.0, and by proxy legacy MS-DOS.
* Approximately forty percent of the functions with a substantial implementation in the kernel (18 NE import functions are ignored) have been matched with IBM OS/2 1.0 revision 7.68.17; these primarily deal with the FAT driver (and disk management in general), utility functions (such as the string library)
* The source code in the slack space of IBM OS/2 1.0 revision 7.68.17 directly mentioning "MT-MSDOS" and being copyrighted 1983 to 1984:
PAGE ,132 
TITLE 
LOADSTE - segment loading routines 
NAME LOADSTE 
;*** MT-MSDOS Segment loading routines 
; 
; Copyright (c) 1983, 1984 by Microsoft 
; 
; SCCSID = @(#)loadste.asm 10.3 87/02/26 
; 
; 
; The segment loading routines handle the loading of 
; new .EXE file format segments. 
; 
; The module table entry is allocated in the file LOAD.ASM
This evidence is further cemented by a quote from Gordon Letwin, the primary architect of both operating systems in part one, chapter one of Inside OS/2:
Another quote supporting this is from an internal meeting with Ray Ozzie of Iris Software on 1 April 1985 (the meeting notes of which were released by Ray Ozzie in 2010), a question on the upcoming changes for DOS 5.0 was asked. Microsoft's response was:
All of these, notably the protected mode nature, were a part of OS/2 1.0 (except installable file systems, which were added in OS/2 1.2). Therefore, it is effectively certain that Multitasking MS-DOS 4.0 was the predecessor project to, is based on the same codebase as, and eventually morphed into what would become OS/2. This also implies that OS/2 is a direct derivative of MS-DOS, as MS-DOS 4.0 was originally forked from MS-DOS 2.0, although almost all of the code would be eventually rewritten by the time OS/2 2.0 was in development.
It is also explicitly stated by Larry Osterman, a long-time Microsoft employee who worked on Multitasking DOS 4.0 and 4.1, as well as numerous versions of LAN Manager and Windows NT-based operating systems, in a comment on a 2004 blog post that Multitasking MS-DOS 4.0 became OS/2:
 
He restated this in a 2009 blog post:
And, most succinctly and directly, again in a 2020 tweet:
== Architectural changes ==
=== Multitasking ===
The single-tasking nature of the operating system was replaced by a preemptive scheduler with priorities, child process support, and a UNIX and OS/2-style signaling system (although the signal numbers themselves are not identical to UNIX, with signal 8 being the equivalent of Unix SIGTERM). This also means that the operating system is now reentrant (albeit only for applications compiled as New Executables intended for DOS 4), as this is a requirement for a preemptive design. The first app that runs has a parent process ID (Ppid) of zero and is referred to as a "top-level process" by the kernel. If it quits, the operating system will simply freeze, although COMMAND.COM has code to print a message (Top-level process aborted, cannot continue).
The multitasking abilities of the operating system are exposed to the user via the Session Manager (SM.EXE), which is configured as the shell via the SHELL statement in CONFIG.SYS. The actual shell is also spawned by the Session Manager, using COMMAND.COM by default, although it is also possible to use a custom shell by providing its path as an argument to SM.EXE. If SM.EXE is ever unable to start a program, the message Unable to start program, press a key to continue. is printed to the screen, and the SM menu is returned to if any key is pressed. The kernel provides slots for a maximum of 31 processes; attempting to start another process after 31 have been started (the internal limit is likely 32, but the kernel may count itself as a process) causes the following User Error to be issued:
* User Error E9CE *
No Proc Slots
It is worth noting that these 31 processes must share a maximum of sixteen console devices; these console devices can be optionally grouped using the concept of the "screen group" – a "screen group" is a set of processes that all share the same console device – for example, if a nested instance of command.com was launched, that instance will share the same "screen group" as the instance that created it, even if it created a new console device (which is simply referred to as a "screen device"). However, if a new instance of COMMAND.COM were launched through a different application such as SM.EXE, that instance will be allocated a new screen group. If there are already sixteen console devices (as opposed to logical screen groups) and an attempt to create a new one is made, the screen group will not be created, and the following User Error will be issued:
* User Error 7691 *
DOS Screen Limit
This is not possible in an stock install of Multitasking DOS 4.0 using only the provided applications as SM.EXE only allows the starting of six different apps (which only take six different screen groups), possibly due to its limited screen space. Additionally, attempting to start a process with an ID of 65,535, or 0xFFFF – this is also the 65,536th process started, as Process IDs are never reclaimed after they are used, will simply lead to a EXEC failure message – the next process then appeared to have a PID of 41, instead of wrapping around to zero as expected due to the two-byte value nature of Process IDs. The kernel was not skipping already used process IDs, as there were only five processes running on the system, with a maximum Process ID of 8)
As ordinary DOS apps are not written with multitasking in mind, the internal command MEMSET allows a partition of foreground memory to be reserved for "old" apps (either temporarily with the MEMSET OVERRIDE=<value> parameter, or permanently with the DEFAULT=<value>, with <value> being the number of kilobytes to dedicate to old applications when in use. The default value of this, 127 KB, is far too small for almost all DOS applications made after the mid-1980s, and it should be increased to allow newer applications to run correctly. When an "old" app is running, it permanently takes up the size of the "foreground" partition multitasking is suspended; the entirety of the CPU is being used by the legacy app, and the legacy app is immediately suspended as soon as another app is switched to.
==== Process management ====
Regular MS-DOS has a basic process information structure (the Program Segment Prefix) that is only suitable for running a single task at a time; this structure has been extended and replaced with the kernel's 16-byte Module Table Entry (MTE), an entry in a linked list, the Module Table, containing the list of all loaded segments (one process can have several segments, which all get their own MTEs), and the process' Per-Task Data Area (PTDA); these structures were carried on into OS/2 1.x. The PTDA ("TD" header, for Task Data) is a very long (at least 400 bytes, and possibly up to 1172) structure containing almost all information about a running process, as well as a pointer to the process' MTE; both the MTE and PTDA are always referenced by a segment address and therefore can only exist on a paragraph boundary; the kernel has an internal structure with a list of all PTDAs in the system (called a "process slot").
When a new (NE) program is loaded into memory (the kernel being an exception to this rule), it is typically split up – the NE header is loaded into memory (and a module table entry is created for it, being placed immediately before), which is immediately followed by the module table entry for the code segment and PTDA of the process (the NE header can be accessed again by the kernel by using the segment address stored at 0x17 in the PTDA structure); in the case where an instance of the process already exists, the code segment of the new instance is discarded and the first instance's code segment is used in order to save memory (although a new data segment is still allocated for every new instance of a process). The PTDA is then followed by the process' data segment, which is pointed to by the DS register at startup, as one would expect) – the stack is then stored immediately after the data segment, with the value of the register pair SS:SP starting one byte past the end of the program's data segment – presumably, each data segment used by the program (in the case of compact or large model applications) is loaded one after the other. The program's code segment is split off from its data segment and loaded in a separate location, usually in upper memory – it seems program code segments are designed to load in from the bottom of RAM up, and data segments, headers, and PTDAs from the top of memory down (in order to reduce memory fragmentation?); a "placeholder" PTDA is located within the kernel binary and copied from its data segment to the running application (both during kernel initialization, for POPUP.EXE, and by the DOS EXEC call), containing placeholder values that are later replaced with values obtained from the application's NE header; any segment can be relocated anywhere by the memory manager, possibly partially dictated by the relocation table in the NE header generated by LINK4.EXE.
The first and last module table entries is always a dummy and has a type of 0xFF; it seems to always be created by the kernel.
The value of the AX register on entry to any New Executable program is set to the word contained at 0x01. of the PTDA – this is then typically copied into the DX register in order to allocate a segment; it seems to be related to the amount of memory (in paragraphs), taken up by the application's code segment the significance of this is presently unknown.
 MTE format
Offset 	Type
0x00 	Magic ("MT", sometimes "M")
0x01 – 0x05	0x01 may indicate type (often "T" – seems to be used before the header, code, and data (primary segments only?) segments of NE programs, 0xFF, 0x00 and 0x28 also seen); the significance of the rest of the bytes unknown.
0x06 	Pointer (segment address) to previous module table entry. If this is the same as the current, we are at the start of the module table; the first entry in the list seems to be a dummy entry (possibly for the kernel itself).
0x08 	Pointer (segment address) to next module table entry. If this is the same as the current, we are at the end of the module table
0x0A – 0x0F	Presently unknown.
=== Shell ===
The shell (COMMAND.COM) is an entirely different codebase from the previous MS-DOS versions and is now written in C and compiled using Microsoft C 3.0; despite its filename (which is likely to remain COMMAND.COM for compatibility reasons – in OS/2 it was renamed to CMD.EXE), the shell is a native New Executable binary. The codebase continued into OS/2, where by IBM OS/2 1.0 revision 7.68 in October 1986 it was already renamed to CMD.EXE; as the OS/2 shell was ported to NT, it may have eventually become (although almost certainly not a huge amount of code would have been left by this time) the Command Prompt in Windows NT. It is also capable of nesting instances of itself, detaching applications (using the DETACH command) and managing memory for old apps (using the MEMSET command). autoexec.bat is also now parsed and run on the starting of any instance of the shell, even long after the system has booted; this is not indicated to the user in any way, even when it affects system-wide settings. CONFIG.SYS is parsed by the kernel and is independent of any shell.
There is a string for a EXTPROC command, but it does not appear to be referenced anywhere or recognized in any way by the shell (presumably it would do something related to "external processes"; it is implemented, or at least recognized as a valid command, in IBM OS/2 1.0 build 7.68.17) a SHIFT command also exists and is recognized, but its functionality has not been determined.
=== Memory manager ===
The kernel memory manager has been rewritten due to the requirement for a multitasking system – a "segment loader" (in this case a "segment", unlike the real-mode x86 memory concept, is just an arbitrary region of memory that can be allocated for the use of an application) – has been implemented to handle memory allocation for DOS 4 applications. Segments can be managed using kernel system calls (ALLOCSEG, REALLOCSEG and FREESEG are all present for allocation, reallocation and freeing of segments). In order to use a segment, it must be "locked" in order to allow the memory to be accessed, much like "locking" a graphics primitive in graphics APIs like SDL – this was most likely done in order to prevent other processes from using them in a crude, and likely ineffective due to the nature of the 808x processors without an MMU Multitasking DOS is designed for, form of memory protection) using LOCKSEG and UNLOCKSEG. It is also possible to discard a code segment allocated to the current app (DOSDISCARDCODE). Freed memory seems to be overwritten in some cases with the string ms (for Microsoft?); this is usually used in debugging environments and would presumably further indicate that build 6.7 is a pre-release build. 
There is also a "handle" API that seems to be separate to the normal DOS file API (which is still implemented via the legacy INT 21h method), but it seems to be part of the memory manager due to function names such as GETDSHANDLE. . The kernel incorporates a garbage collector for internal use, implemented using the internal garbage_collect function located at 0xB7B5 (0xB5B5 in IDA) in IBMDOS.COM. 
The MS-DOS 4 memory manager was also adapted for use in Windows 1.0. The part of the memory manager that deals with global allocations is nearly identical between Windows 1.0 and MS-DOS 4, while other parts were changed to accommodate for the different multitasking model. Despite the documentation for Development Release #4 states that the memory manager would be rewritten "in the October release", suggessting that that the first release with the new memory manager was Development Release #5 from October 1984, the reality is that this version has a completely separate memory manager seemingly unique to it implemented in its KERNEL, with the Alpha release from January 1985 being the first with a version of the Multitasking DOS 4 memory manager.
=== API ===
The DOS API has been massively extended, with at least 31 additional system calls (most of which take up the 80h through 99h values in the AH register when calling the INT 21h API – a far higher value than any other DOS version, where INT 21h services only ever went up to 63h); these APIs have been implemented for tasks added for tasks such as running and blocking processes, modifying the amount of memory given to legacy DOS apps, sending signals to processes, blocking and running processes, getting process IDs and handles, and various other functionality.
A list of "4.0 new multitasking calls", containing most (but not all) of the system calls implemented for Multitasking MS-DOS 4.0, dated 30 August 1986, was found in the slack space of an early build of OS/2 1.0.
 Multitasking MS-DOS 4.0 API (Legacy INT 21)
Register values	Register values	Register values 	Name 	Description 	 	
AH 	AL 	BX 	Name 	Description 	 	
44h 	0Ch 	 	EXEC 	Unknown IOCTL (Screen switching?), not defined in regular DOS. Listed as "Generic character device request" on Ralf Brown's Interrupt List, but listed as different on "European MS-DOS 4.0, OS/2". 
Category (indicated by CH register) 04h), function (indicated by CL register) 06h ("reserved for keyboard" in regular DOS) seems to be used to create a new console device (not screen group as PS.EXE is in the same screen group as its parent process – screen groups seem to be managed by the kernel); PS.EXE only calls this function if its -S (fullscreen) option is used, where it creates a new console device (but one that can have the same screen group).
Needs more testing.	 	
4Bh 	04h 	 	EXEC 	Load and execute program in background (legacy MS-DOS only defines subfunctions 00 to 03h) 	 	
4Bh 	08h 	 	EXEC 	Unknown subfunction, used by SM.EXE 	 	
4Bh 	0Ch 	 	EXEC 	Unknown subfunction, used by SM.EXE; seems to be the default option used by COMMAND.COM to launch programs. 	 	
4Bh 	0Fh 	 	EXEC 	Unknown subfunction; EXEC checks for this and errors out if the subfunction is any higher – presumably this is the highest subfunction.	 	
59h 	 	0001h 	Get Hard Error	Offset 	Size	Description
00h 	WORD 	contents of AX at system entry 	 	 	 	
02h 	WORD 	Process ID which encountered error	 	 	 	
04h 	WORD 	contents of AX at time of error 	 	 	 	
06h 	BYTE 	error type
*00h physical I/O error
*01h disk change request
*02h file sharing violation
*03h FCB problem
*04h file locking violation
*05h bad FAT
*06h network detected error	 	 	 	
07h 	BYTE 	INT 24 error code 	 	 	 	
08h 	WORD 	extended error code (see #01680) 	 	 	 	
0Ah 	DWORD 	pointer to associated device 	 	 	 	
All API calls above are followed by a call to INT 21, the standard DOS API handler. 
Additionally, there is a second set of API functions, primarily for managing multitasking primitives such as critical sections (implemented using the CRITENTER and CRITLEAVE and the similarly named, but with unknown differences, FCRITENTER and FCRITLEAVE functions), managing segments (which are not identical to the 16-bit x86 architectural concept of "segments", but instead an arbitrarily-sized area of memory) and general memory, and other general utility functions (such as "subscreens" to theoretically allow multiple apps to display on the screen at once). These are implemented through the DOSCALLS library in the kernel as New Executable exports (there is a dummy NE header at offset 0x1190 of IBMDOS.COM whose sole purpose is providing said exports to other applications and nothing else), although several other functions are additionally exported from POPUP.EXE, which is a dynamic-link library (the .DLL extension not existing until 1987) for providing various types of popups. It allows several predefined types of popups (or "subscreens") to be drawn to the screen (using the SSAP, SSHE, SSLO, and SS_WRITE functions, as well as several undocumented functions exported only by ordinal). 
Import resolution is done at runtime. The linker encodes calls to imported function libraries as far calls, starting at the segment-offset address 0123h:0001h for the first import from the first imported module (or more correctly, the first imported *NE library*). For each module imported, the segment address is incremented by one (i.e. the second module would start at 0124h:0001h, the third at 0125h:0001h and so on); for each function imported from that module, the offset part of the address is incremented by one – so 0123h:0002h, 0123h:0003h and so on for functions imported from the "first" library (usually the kernel's DOSCALLS library); for example, a call to the 7th import from the third module would be encoded as a far jump to 0125h:0007h in hexadecimal. While the kernel is loading the binary, it reads the NE header for the imports, determines which dummy calls correspond to which function, loads the library being imported if required, and replaces those far jumps with far jumps to the actual code the program is intending to call; in the kernel's case, the kernel is always loaded at a static segment address of 0506h:0000h, or a linear address of 0x5060, so all kernel calls will use that segment address of 506h after they have been fixed up.
 NE exports
File 	Function name 	Description
IBMDOS.COM	ALLOCSEG 	Allocates a segment, similar to C malloc – needs more research.
IBMDOS.COM	REALLOCSEG 	Reallocates a segment (presumably changes its size), similar to C realloc – needs more research.
IBMDOS.COM	LOCKSEG 	"Locks" a segment so that it can actually be used by the current program; returns a pointer to the first byte of the provided memory block. The dx register may contain the size in paragraphs of the segment – 16 (but in an NE this would usually be a C argument, so it needs to be matched to an argument); on return the segment seems to be pointed to by the es register, presumably returning a C void* (or char* in this era of C) and increments its lock count – needs more research.
IBMDOS.COM	UNLOCKSEG 	"Unlocks" a segment when use is done (the DX register, in compiled programs, seems to contain a pointer to the segment); decrements its lock count – needs more research.
IBMDOS.COM	GETSEGSIZE 	Returns the size of a segment – needs more research.
IBMDOS.COM	GETDSHANDLE 	Returns a handle to a data segment.
IBMDOS.COM	CRITENTER 	Enters a critical section – needs more research.
IBMDOS.COM	CRITLEAVE 	Leaves a critical section – needs more research.
IBMDOS.COM	FCRITENTER 	Similar to CRITENTER (possibly related to INT 21h,AH=93h "FinalAlloc" function)
IBMDOS.COM	FCRITLEAVE 	Similar to CRITENTER (possibly related to "FinalAlloc" INT 21h,AH=93h function)
IBMDOS.COM	PBLOCK 	Blocks a process from running – possibly replaced the INT 21h,AH=99h legacy DOS API; requires more research.
IBMDOS.COM	PRUN 	Allows a process to run – possibly replaced the INT 21h,AH=99h legacy DOS API; requires more research.
IBMDOS.COM	SUBSCREEN 	Manages subscreens (always called internally by the SS* functions located within POPUP.EXE; requires more research.
IBMDOS.COM	GETPIDS 	Gets a list of process IDs running in the current system; after returning in a compiled application, the DS is set to some kind of internal kernel structure (the pointer to which is located at 0x562 from the kernel code segment start, with AX, BX, and CX all having words (equivalent to 0x08, 0x09 and 0x0C from the start of the kernel code segment; requires more research.
IBMDOS.COM	DOSDISCARDCODE	Discards a previously obtained code segment; requires more research.
IBMDOS.COM	DOSGETHANDLE 	Gets a handle to a code segment (as code segment sharing is supported); requires more research.
IBMDOS.COM	DOSHANDLEJUMP 	Unknown (presumably handles a jump); requires more research.
POPUP.EXE 	SSLO 	Subscreen utility function (take lower half of screen?); requires more research.
POPUP.EXE 	SSHE 	Subscreen utility function (take upper half of screen?); requires more research.
POPUP.EXE 	SSAP 	Subscreen utility function; requires more research.
POPUP.EXE 	SS_WRITE 	Possibly writes the content of a subscreen; requires more research!
POPUP.EXE 	PREAD 	Presumably takes user input from a popup.
POPUP.EXE 	Ordinal 7 	Unknown
POPUP.EXE 	Ordinal 8 	Unknown
POPUP.EXE 	Ordinal 9 	Unknown
POPUP.EXE 	Ordinal 10 	Unknown
POPUP.EXE 	Ordinal 11 	Unknown
The MS-DOS Terminate & Stay Resident functionality (INT 27H or INT 21H, AH=31h) has been disabled by default (a setting can be set in the Program Information File for a program to re-enable it), with an attempt to call one resulting in a User Error code 983F being issued, and the following information being printed to the current shell:
* User Error 983F *
Cannot set private vector
and the current process being terminated. This is most likely due to TSRs not making sense in a multitasking system – it would be preferable to simply start a child process, with a system call (CWAIT, INT 21H, AH=81H) allowing the current process to block until the child process terminates itself; they would almost certainly not take very well to being preempted by the kernel while running.
=== Hard Error Daemon and system crash ===
MDOS 4 implements the concept of a hard error, as opposed to DOS 3.0+ "extended errors". The last hard error can be acquired using the INT 21h, AH=59h, BL=01h API. It appears to replace the standard INT 24h handling, which has been moved from the kernel to its own dedicated binary that is started and installed at boot by the kernel, called the Hard Error Daemon (HE_DAEM.EXE). Upon being started, the daemon will call the SLEEP system call, INT 21h, AH=89h for 65000 seconds in a loop until a hard error (an error that would usually cause a Abort, Retry, Fail? to be delivered to the user in regular MS-DOS) occurs (possibly using an INT 24h handler or some kind of special invocation by the kernel). When this occurs, the daemon determines the error information based on some kind of system structure and seven broad "error categories" (category zero being a general I/O error, one not an error but instead a disk change request, two a file sharing violation, three an issue with a DOS File Control Block, four a file locking violation, five a bad FAT and six a network error), provides an error description (which may include what the system was trying to do when the error occurred), the process ID of the process that caused the error, what the process was doing when the error occurred (which, in some cases, can simply print that the program was ???ing a device, for example when attempting to use the shell to echo to the built-in SCREEN$ device), the hexadecimal number of the system call that triggered it. The user is then provided with a Abort Retry Ignore Fail (or in some cases, just Abort Retry Fail) prompt. If an invalid entry is selected, Huh? is printed to the screen and the prompt repeated. An exception for this is the ? character, which then prints more detailed information about what each option does.
If the system crashes, for example by corrupting kernel memory, the kernel will stop the system and print a string of the format * Internal Error XXXX *, with XXXX replaced by the four byte position within the kernel code segment where the error string starts (this was likely intended to be where the call to the IntErr or UsrErr strings came from, but due to a bug or oversight the start of the error string is used instead). There is a similar (using the same scheme for error codes), but non-fatal (the current process is terminated) "User Error" string, as well as a message with what went wrong, which has experimentally been triggered by processes attempting to call a system call with invalid parameters and running out of process slots. If the hard error daemon itself is not found it will simply print Hard Error daemon not found. to the console upon trying to call it. This function is located at 0x9581 (0x9381 in IDA) for internal errors (IntErr) and 0x9595 (0x9395 in IDA) for user errors (UsrErr), with the shared error code, the ErrPrnt function, located at 0x95C1 (0x93C1 in IDA), which is called by both functions in order to display the error and/or halt the system if required. Most of the calls to this function are for impossible situations within the multitasking code inside the kernel. Interestingly, there is often a 24h byte after this, as if calls to INT 24h were overwritten with calls to this function. 
COMMAND.COM implements its own mechanism for fatal errors, with "COMMAND Internal Error", followed by a single character (F and S have been seen in the code) determined by the function causing the error (which has no unified function, but is implemented in several different places). COMMAND.COM then, instead of terminating, simply jumps into an endless loop, which seems rather strange for a multitasking system; however, the fact that the code seems to check for MS-DOS 3.0, as well as 4.0, and allows itself to run in that case, may imply it was either intended to also run on legacy DOS or, more likely, that the code stems back from when MS-DOS 4.0 was called MS-DOS 3.0
=== Built-in DOS devices ===
While most of the default built-in MS-DOS devices (such as CON, PRN, AUX and NUL) are still accessible by using their classic MS-DOS names (albeit the LPT4 throughLPT9 and COM3 through COM9 devices, representing the third through ninth communications and fourth through ninth printer port respectively, have been removed from the operating system – most likely due to such a high number of ports being an incredibly unrealistic configuration), it is also possible to access them via UNIX-style names (for example, /dev/con, /dev/prn, /dev/aux, and /dev/nul). There are also several additional devices that do not exist in regular MS-DOS, accessible by both the legacy and \dev mechanisms – SCREEN$ (representing the screen, likely for the detachable console feature), KEYBD$ (for the keyboard), and PRNTARB$, possibly for managing printing between multiple processes at the same time. These device names are located in the bootloader and driver blob, IBMBIO.COM instead of the kernel where almost all other operating system functionality is. This is due to the fact that it deals with interfacing directly with the hardware – it makes up the "BIOS" in IBMBIO.COM. The addition of the ability to access these devices through a Unix-style /dev folder is likely related to Microsoft's long-term plan, prior to the signing of the Joint Development Agreement with IBM to develop OS/2, to gradually enhance MS-DOS into a single-user variant of their Unix-based XENIX operating system, called XEDOS, gradually integrating UNIXisms to make the two OSes more similar until they were effectively identical; various other UNIXisms can be seen throughout this era of Microsoft, such as the \bin directory early Windows 1.0 builds, such as DR5 and Alpha, as well as Multitasking DOS 4.0 itself, dump many of their binaries into.
=== Detachable consoles & batch changes ===
Support for multiple consoles has been added to the OS. This is primarily exposed to the user the command DETACH (or DET), followed by a program to run – this program will now run "headless" and not attached to any shell. The shell instance that launched the application will resume when the application exits. Multiple instances of COMMAND.COM can be running at any one time and using multiple console devices. As a side effect of the rewriting of the shell (COMMAND.COM) in C, a new batch parser was written. This batch parser has a limitation that the regular DOS batch file parser does not: batch files will stop running (the user will be asked by the system to provide the location of the batch file) if they are on a floppy disk and the floppy disk is changed. This is unlike regular DOS, where they will continue running on a disk change as long as they are in memory.
Furthermore, this is the first Microsoft OS, and apparently the only version of MS-DOS, to implement the SETLOCAL and ENDLOCAL batch commands to temporarily change environment variables while a batch file is running.
=== PIF file support === 
Multitasking MS-DOS 4.0 adds PIF file support to the operating system for managing the behavior of legacy MS-DOS apps, similar to 16-bit Windows (in fact, it uses a similar "extended PIF" format to Windows, as opposed to the original 253-byte TopView format); in fact, they are used for some of the OSes inbuilt apps (and, for some reason, HE_DAEM.EXE, which is a New Executable and therefore should not need a PIF file). There is a text-mode PIF editor, PIFEDIT.EXE, which allows users to graphically edit PIF files (which is described in full detail later in the "Included utilities" section).
== Kernel debugger ==
The kernel debugger (DEBUGDD.SYS, which identifies itself as System Debug 070185) included in the Goupil OEM release can be installed by adding a DEVICE= statement to CONFIG.SYS, and will only function if attached via passthrough or a real serial port to the second COM port (COM2) of the system; it has been successfully tested with the default settings and 9600 baud speed using 86Box passthrough. It is similar to and therefore has a similar command set to MS-DOS DEBUG, real-mode Windows SYMDEB, and the OS/2 KDB debugger (which is the direct successor of System Debug); although, due to its older heritage its command set and overall functionality is between the former and the latter two, and there appears to be no commands to bring up a command list or any other type of online help. Additionally, some of DEBUG.EXE's functionality has been removed – it is impossible to quit the kernel debugger, and the disk read/write functionality of MS-DOS DEBUG has also been removed. Like DEBUG, only 808x instructions are supported. However, several other commands to manage and deal with breakpoints have been added, as well as descriptions of the type (near or far) when a pointer is being used and support for assigning types (such as floating-point numbers) to variables. While the debugger is enabled, the system will automatically break into the debugger during boot (after the sign-on message is printed), which means the system will appear to freeze; the g must be issued to allow the system to run at all while the kernel debugger is loaded. A g command must be sent to continue booting – the system can then be frozen at any time by either executing an INT 3 instruction or pressing + on the serial console while the system is running; the kernel debugger will automatically be broken into upon an invalid instruction being executed while it is loaded. In this state, attempting to continue will simply cause the OS to hang – attempting to break into the kernel debugger again will result in nothing happening.
For all commands except for bp, it is required to refer to the breakpoints by their numbers; it is also possible to view the breakpoint numbers with the bl command, which will list the ID, position, and number of each breakpoint. It is possible to set a maximum of 10 breakpoints, with a BR Error message being printed if attempting to add a new breakpoint after already adding ten. The wildcard * can also be used to affect all breakpoints, such as using the bc * to clear all breakpoints.
 DEBUGDD.SYS additional commands
Command 	Description
bc <breakpoint numbers>	Clears a breakpoint; providing more than one number (separated by a space) will clear more than one breakpoint.
bd <breakpoint numbers>	Disables a breakpoint; providing more than one number (separated by a space) will clear more than one breakpoint.
be <num> <num> 	Enables a breakpoint; providing more than one number (separated by a space) will clear more than one breakpoint.
bl 	Lists breakpoints – their number, if they are disabled or enabled (the former represented by "d" and the latter "e"), the position and several others.
bp <seg:off> 	Sets a new debug breakpoint at segment:offset address.
All other commands are identical to MS-DOS DEBUG.EXE, except for the aforementioned l (load from disk), n (set filename for disk write), q (quit) and w, (write to disk), which have been removed when compared to regular DEBUG. Research into any additional commands that may exist is ongoing. 
=== Oddities ===
DEBUGDD.SYS uses – but only in some parts of the code (other parts use traditional MS-DOS "$" string terminators) – the extremely obscure (primarily only used on machines made prior to 1980) method of "high bit set" (also known as "Microsoft Basic", as it was used in Microsoft Disk Basic) for string termination, where the highest bit of the last character is set to indicate a string being terminated; the reason this was no longer used is the transition of computers from 7-bit to 8-bit ASCII based character sets, as high bits being used for string termination would effectively limit the number of characters that can be used to 128, which is not sufficient to represent many languages (as IBM needed to do on the PC). They are also used in the IBM PC-DOS 1.0 boot sector but are removed from all future versions. The command list itself is stored with all bytes having their high bit set, which makes it unreadable in a normal hex editor; this was most likely done to save space, as not having null-terminated strings saves one byte per string (which in memory-constrained environments was quite a lot); the terminator is only used on strings that needed to be duplicated substantially, such as instruction names and register names – this was in fact inherited directly from MS-DOS DEBUG, which DEBUGDD.SYS seems to be forked from. The kernel debugger additionally seems to hook INT 31H, which if executed while DEBUGDD.SYS is loaded to the system and attached causes an immediate system reboot. However, executing this without prior setup restarts the system unexpectedly and leaves it in a corrupted state where it will likely immediately crash.
== Application compatibility ==
For a legacy DOS app to work on Multitasking DOS 4.0 without issues, it must:
* Exclusively use the documented INT 21h APIs except for functions that launch other apps and are not the functions with subtle differences listed below.
* Not use Terminate-and-Stay-Resident functionality, which is disabled by default (unless a special bit is flipped in a PIF file attached to the application that allows it to use TSRs).
* Not launch any other apps (although chaining as practiced by the Microsoft C Compiler appears to work)
* Not use the internal INDOS flag to determine when to call DOS APIs (the OS becoming reentrant means this flag is effectively deprecated and is always set to the value FFh, which legacy apps will interpret as DOS always performing a system call – which means from their perspective it is never safe to call DOS APIs and they therefore will not call them) 
* Not depend on internal DOS structures or undocumented DOS INT 21 APIs.
* Not attempt to attach itself to another program. This is because the EXEC system call (INT 21h, AH=4Bh) is completely different and partially incompatible with other versions of DOS.
* Not use the handles to standard in, standard out and standard error, as well as the first serial and parallel ports (COM1 and LPT1 respectively), normally found within the Job File Table of the Program Segment Prefix (PSP), the process information structure, of legacy MS-DOS applications. These are all NULL in Multitasking DOS 4 and therefore all attempts to access them will lead to reads to and writes from null, and the program crashing. 
* Not write directly to the disk. This will cause User Error DAF3 – "System cannot write directly to disk."; this, like the TSR restriction, can be negated using a PIF file for the application.
* Not be a mixed (or "family" mode) DOS/NE executable, of any type – even the "This program requires Microsoft Windows" / "DOS mode" stub does not work. The DOS 4 binary loader cannot deal with these applications (the programs built-in with DOS 4 do not have stubs) and the EXEC system call will fail, leading to COMMAND.COM issuing a EXEC failure message.
* Not be dependent on the MS-DOS SYSVARS table, which has changed from other DOS versions (normally, newer versions of MS-DOS); notably, there are extra device pointers (for the new included devices), and the pointer to the CDS (current directory structure) structure (usually located at 1Ah) is always set to NULL; this may be due to how a program's current directory is represented being completely rewritten (it appears to be stored per-process in each process' Per-Task Data Area) and therefore not requiring a position in the SYSVARS table.
* Not be dependent on the INT 21h, AH=58h "Set Allocation Strategy" function (which allows the user to modify how MS-DOS allocates memory blocks – a first-fit, best-fit and last-fit, which is basically first-fit but starting from high memory and not low, can be used) – in Multitasking MS-DOS 4, this function is stubbed and its entry in the kernel syscall dispatch table simply points to the global "invalid function" code; this is most likely done as the operating system is designed to handle the memory allocation strategy "on its own".
* Not be dependent on the SYSVARS table's pointer to the CDS (Current Drive Structure) internal system structure; this has been replaced with a per-process pointer in each task's PTDA, and the system-wide pointer is replaced with a null pointer (any attempt to access it causes a null pointer to dereference)
These restrictions mean that regular DOS apps that depend on internal DOS structures, most DOS extender apps (such as later versions of IDA for DOS and many DOS apps made during and after the early 1990s), 16-bit Windows, and the Undocumented DOS tools, do not work (with either an EXEC failure message being printed to the screen, garbage being printed instead of their intended output, nothing happening, the program exiting immediately, a system crash, or a User Error message being issued). Additionally, old apps, in particular IDA 0.1, that are not aware of written to "cooperate" with Multitasking DOS R are known to corrupt system structures, which may lead to a crash.
There are also subtle differences with how some other MS-DOS API calls, such as INT 21H,AH=25h to set interrupt vectors – which no longer directly sets interrupt vectors – and the undocumented functions at INT 21H,AH=1Fh (get pointer to current drive parameter table) and INT 21H,AH=32h (get pointer to arbitrary drive parameter table), which directly copy the BIOS Parameter Block (a data structure on legacy BIOS based systems that describes the layout of a volume) into the memory address represented by the register pair DS:BX, instead of returning a pointer to DOS's copy of that structure using the register pair DS:BX. Additionally, the INT 12H BIOS API (which returns the amount of conventional memory in the system) is trapped by the operating system and modified to only return the amount of memory provided by the MEMSET command; these changes further worsen application compatibility.
Due to all of these factors, application compatibility between older (and newer) versions of MS-DOS and Multitasking MS-DOS 4.0, due to the fact that large amounts of the operating system were rewritten, is very poor, and many apps have severe issues that prevent their use, refuse to start at all, or even crash the operating system (either causing an Internal Error, or simply freezing – in both cases this essentially means a hard reset). 
=== Tested applications ===
==== Microsoft C ====
Microsoft C 3.0 (the operating system appears to be itself compiled with some version of Microsoft C 3.0, with the C Library string having a 1985 copyright) produces working object files that can be linked using LINK4.EXE. Requires MEMSET DEFAULT=256 or more to increase the amount of foreground memory allocated to "old" apps. Requires header files (that are not provided) for MDOS functionality, as well as for DOSCALLS.LIB to be extracted from the kernel using a library manager. Basic apps have been compiled, but DOS 4 specific functionality has not successfully been used and there are issues with instability in the built-in libraries and headers. For more complex functionality, it can be attempted to set the size of the stack to 46000 bytes or larger as a workaround for unknown memory management issues. However, this stack segment will be permanently leaked and after several runs, no more applications can be launched. Interestingly, at least trivial apps compiled for Multitasking DOS 4 appear to not cause an error message and not crash the system when run on Windows 1.0. 
Retail Microsoft C 4.0 is not compatible with the version of LINK4.EXE provided by the operating system and will not produce object files compatible with it (and even if it was, DOS 4's LINK4.EXE cannot link against the provided MSC 4.0 libraries). The version of LINK4.EXE on Disk 8 (which is listed as being intended to compile for Windows 1.0) must be used to produce functioning executables at all, and even then a EXEC failure message is produced upon trying to run the program.
==== Macro Assembler (MASM) ====
MASM 4.0 works as long as an Automatic Data Group segment of 512 bytes is declared in the application's code, which is required by the New Executable spec.
==== Interactive Disassembler (IDA) ====
IDA 0.1 appears to work and can be used for disassembly but is very slow (due to being written long after this OS). It may also corrupt system structures leading to Internal Errors and system instability. IDA 2.8 does not work (EXEC failure), as it uses DOS extenders.
==== "Legacy" MS-DOS built in utilities ====
DEBUG.EXE from MS-DOS 3.21 partially works, but it can only attach to legacy DOS apps (not New Executable apps, which cause DEBUG to issue a EXEC failure message) cannot be used to trace through the OS's INT 21h handler for unknown reasons (it somehow ends up returning to the wrong location after the initial processing, possibly due to DEBUG.EXE somehow interfering with the OS scheduler), and may at any time pin 100% of the CPU, leading to extreme system slowdown.
CHOICE.COM from MS-DOS 6.0 works. The "country-specific file name" call that requires "normal" MS-DOS 4.0 seems to not inhibit the operation of the program.
==== Symbolic Debugging Utility (SYMDEB) ====
The Microsoft Symbolic Debugging Utility, used for debugging early versions of Windows and a predecessor of the Windows 3.0 and Windows 3.1 enhanced mode, as well as Windows 9x, debugger, WDEB386.EXE, works except when attached to another program. Attempting to attach to another app will completely freeze the OS, requiring a hard reset.
==== Microsoft Windows ====
There were plans to have Windows 1.0 running as a GUI layer on top of this operating system, with Windows using the preemptive scheduler of multitasking MS-DOS instead of its original cooperative scheduler. The release of the combined environment ("Win+4") was scheduled for Q2 1986, but it was eventually cancelled, likely due to the signing of the Joint Development Agreement between Microsoft and IBM to develop what would ultimately become OS/2.
No version of Windows is known to run on build 6.7 of Multitasking MS-DOS (the 17 November 1986 build patches KERNEL.EXE, and possibly other parts of the system during initialization in order to remove incompatibilities), as most versions fail at boot with "Cannot find Windows startup files." or a similar error message. This is caused by DOS not recognizing the Windows kernel (KERNEL.EXE), after it is loaded from (WIN100.BIN) as a valid executable file when WIN.COM tries to run it using the EXEC system call; this initially happens because according to the version of the New Executable specification understood by build 6.7 of Multitasking DOS 4.0, the flag word in the NE header set by the Windows kernel indicates it to be a dynamic link library (which were not distinguished by file extension until later builds of OS/2 1.0) being executed as if it was an executable file, which causes the DOS EXEC function to refuse to load it; if this is patched, binary loading still fails for presently unknown reason. Since WIN.COM does not account for the EXEC system call failing for this reason, it ends up triggering a code path that prints out a misleading error message.
However, even if the 1985 builds of Multitasking DOS 4.0 were to recognize the Windows kernel as a valid binary, the kernel immediately terminates if it detects a DOS major revision above 3 (or below 2). This is why, on later versions of MS-DOS, SETVER is required to run these versions of Windows; forcing the kernel to run anyways results in the system crashing (with garbage being printed to the screen) early in KERNEL initialization, pointing to serious, OS-level incompatibility between Windows and Multitasking DOS 4.0. This, as well as the description of the kernel NE being Microsoft Windows Kernel Environment for 2.x and 3.x, as well as the function that calls int 21h being explicitly labelled DOS3CALL (as well as commit logs from 1986 in the Windows NT 3.5 build 782 source code referencing support for DOS 5 and 286DOS, aka OS/2), may indicate that support for Multitasking DOS 4 on Windows was set by some kind of compile option.
A version of Windows 1.03 was bundled with the ICL DRS Professional Workstation alongside multitasking MS-DOS 4.10, which suggests that the EXEC system call was fixed in the later revision to allow Windows to run.
Larry Osterman, in a 2004 blog post, recollected why KERNEL.EXE patches were required for Windows 1.0 to work:
==== Undocumented DOS, 2nd Edition developer tools ====
Nearly all of these tools (except the INTRVIEW.EXE tool, used to view Ralf Brown's Interrupt List, which requires MEMSET DEFAULT=640 to run) do not run correctly – they crash the system, hog the CPU, print garbage, loop endlessly, or freeze halfway through and must be terminated. All of the provided TSRs in the toolkit fail to install with User Error 983F, as TSR functionality is disabled by default.
Additionally, the operating system is not recognized as MS-DOS by the MSDETECT.EXE tool, which recreates Microsoft's AARD test code to determine if it is running on "real" MS-DOS or a clone of it.
==== QEdit ====
QEdit 3.0 works perfectly, except for an issue where the state of the NumLock key is somehow tied to the state of the Shift key (when Shift is set, NumLock is off, and vice versa); the tool can still be used for editing, with minor complications.
== Provided utilities ==
Multitasking MS-DOS 4.0 comes with numerous utility applications. Many of these are very unique and are not included with any other version of MS-DOS or OS/2; only utilities that are unique to Multitasking DOS or have other noteworthy changes will be covered in this section.
=== Standard changes ===
* APPEND, ASSIGN, ATTRIB, JOIN, LABEL, PRINT, and SUBST have been rewritten in C and are native New Executables intended for Multitasking DOS 4.0.
* FDISK is a special case – while it identifies as "Version 0.01", is clearly a new codebase, and has been rewritten in C like most of the other utilities, it is not a New Executable and has been compiled as a regular DOS binary.
=== Included in build 6.7 ===
==== pifedit.exe (PIF Editor) ====
A text-mode version of the PIF Editor often included with 16-bit Windows installations; it can either be provided a PIF file as a command-line argument, where it will enter a screen where settings can be modified, or it can be provided a /a parameter where several more advanced settings, such as the program having the ability to directly write to disk, using the "old" signal system, and being allowed to terminate and stay resident. It also supports batch operations with the /h option. Interestingly, unlike the Windows PIF editor (which is a native Windows application); the PIF Editor included in Multitasking DOS 4.0 is a legacy MS-DOS application (although written in C like almost all of the new applications written for Multitasking DOS 4) and in fact is explicitly allowed to run on any version of regular MS-DOS from 2.0 on upwards. 
==== swapper.exe (Swapper Daemon) ====
In theory, allows swapping to disk; processes that are presently swapped to disk PS.EXE show a status of [ Swapped ] after reading from an app's PTDA, but in practice (despite the existence of a SWAPPER.DOC file instructing how to start the swapper), the swapper cannot work. This is because it calls the int 21h,AH=94h ("init swapping?") API, which while being defined as a valid INT 21 API, it points to the "invalid function" code, so the function will always fail with DOS error code 01h ("Invalid function"), so the swapper will remove its signal handlers and terminate. 
==== queuer.exe (Print Queuer) ====
A utility that implements a print queue; it has currently not been coaxed into running, but it uses shared memory areas. 
=== Only included in Goupil OEM version === 
==== ps.exe (Process Status) ====
A Unix-style "Process Status" utility (in fact, it may be a direct port from XENIX or some other Unix distribution, as it exclusively uses Unix-style command-line switches (-) and does not even recognize MS-DOS style ones (/). 
By default, only process ID, process status (which can be Run (currently running), Ready (ready to run), Wait, processes that are waiting for a scheduler timeslice, Froze, usually for "old" processes that are not swapped in, Dead, for processes that have crashed, and [ Swapped ] , used for processes currently swapped to disk), and process name are shown for every process running on the system except the POPUP.EXE DLL, which runs at all times and is started by the kernel's boot code (with a static Process ID of 0).
===== Command-line options =====
 Caption
Option	Result
-S 	Detach PS.EXE; run fullscreen and take exclusive use of the current console device.
-s 	Adds timeslice information (Slice), process priority (Pri), "Bmod", "Upri", "Use", and "Deny" (currently unknown), screen number (Scrn), and tics use, TicsUsed, to every process.
-l 	Adds child process ID, Csid (unknown, child process ID?), priority (again), screen group (as opposed to screen number – screen number is the number of console devices, screen group is a logical kernel concept), segment address of the processes' PTDA, command-line (Cmd) and Misc (unknown).
-t 	Seems to provide all command-line options provided to an app, instead of just the first one; requires -s or -t to have any visual effect.
-q 	Seems to have something to do with printing the process type (new or old), but no visual effect has been identified; definitely implemented in the code.
==== dossize.exe (DOS Size) ====
Prints the amount of memory currently taken up by DOS and running programs, across various parts of the system, how much space is free, and how much total RAM exists in the system.
 dossize.exe categories
Category 	Purpose
"BIOS size" 	Amount of space taken up by the bootloader and drivers contained within IBMBIO.COM.
"DOS size" 	Amount of space taken up by the kernel.
"DOS tables" 	Amount of space taken up by the kernel's internal system structures, such as the scheduler and list of lists (which has a somewhat non-standard layout).
"Old exe program space"	Amount of space taken up by non-native NE binaries; this is usually equivalent to the memory reserved for them using the MEMSET command.
"New exe program space"	Amount of space taken up by all native MDOS4 apps running on the system.
"Free space size" 	The amount of space free on the system.
"Total space size" 	The total amount of system memory.
Note that the total amount of system memory cannot exceed 640 kilobytes due to the system's real-mode nature and the fact that 360 kilobytes of the memory map is taken up by various peripherals.
== Bugs ==
* The system will sometimes search all drives for files, even if they have no disk inserted. This will sometimes lead to "Sector not found" errors from the Hard Error Daemon.
* The MKDIR command will sometimes print "Unable to create directory" even if the directory was successfully created.
* Very rarely, when switching drives, the system may maintain the current directory, even if it does not exist on the current disk.
* Trying to DETACH COMMAND.COM will lead to endless + 's being issued by the new COMMAND.COM instance, as well as the Process ID of COMMAND being printed.
* Although autoexec.bat is run for each new COMMAND.COM instance created (and this can have effects on system-wide settings such as the old app memory partition set by the MEMSET command), there is no visual indication of this.
== Gallery ==
Multitasking MS-DOS 4 First Boot Internal.png|Internal Revision string
Multitasking MS-DOS 4 Command Prompt.png|Command Interpreter
Multitasking MS-DOS 4 DOS Size.png|DOS Size
Multitasking MS-DOS 4 Processes.png|Processes
Multitasking MS-DOS 4 Task Switch.png|Task Switch
Multitasking MS-DOS 4 VER Command.png|VER command
MDOS4-pifedit.png|PIF Editor
Multitasking-MS-DOS-4-Goupil.png|Multitasking MS-DOS 4 Goupil OEM
MSMeeting19850401_Page19.png|The relevant meeting page with the features of "MS-DOS 5" (which later became OS/2).|alt=Summary of 4/1/85 Microsoft Meeting, Page 19; (Could not determine the answer to this question, since swapping was removed from the product at the time of discussion). If the answer to the above is "No, we are just going to swap the Global Heap to a RAMDISK file", I would like to discuss the levels of inefficiencies involved in having the memory manager swap through the file system (when it really doesn't have to). (GL,AS,CL) It is agreed that swapping, if implemented, would require special file system support, such as contiguous files, so that it could use direct disk I/O. (GL,SW) With regard to the issue of swapping, and after much discussion as to providing hooks for Iris to implement swapping (much as it was done by SW for our use under Windows), it was basically determined that, in effect, Iris was merely going to end up writing a piece of code that should in fact be in the 4.0 Kernel. We expressed a great need for swapping, and GL has delegated himself to once again look into the issue of putting swapping into 4.0. 5.7 Virtual Consoles; It seems as though, in order to allow 4.0 to switch virtual consoles, you will be needing additional OEM support with regard to text displays. I saw nothing of this in the 4.0 preliminary documentation; can we discuss this issue? I am particularly interested in the case where Windows is running (with the user's screen in graphics mode), and the user strikes ALT-F10 to get back to the "monitor" program. How do you know what to save, how to switch, and so on? Since any application (such as 1-2-3 or Symphony) can, at any time, switch the screen to graphics mode, will you be providing calls that Symphony can call to notify 4.0 that the screen is now in graphics mode? (GL,CL) See the updated documentation. Well-behaved applications will issue IOCTLs to the console device to notify it of their current screen behavior. For non-well-behaved applications, certain assumptions have to be made. For example, on the Hercules card, when switching from text mode back to graphics mode, 4.0 will always switch to the first graphics page, because it really has no other choice. (It turns out that most people use the first page anyway.) Again, here is a place where Lotus may have missed the boat. Microsoft had called Lotus a while back to make sure that Lotus would stuff EGA setup parameters in a "standard place" so that 4.0 would later be able to restore the EGA to its original state. When Lotus recently issued its 123 drivers for the EGA, it was stated to Microsoft that they did not conform to the spec. Thus, under 4.0, 123 and Symphony may not work properly without a re-release of the drivers. 5.8 Notes about DOS 5.0; DOS 5.0 will include: protected mode, pipes, threads, asynchronous I/O, demand execution, possibly installable file systems, sound services, >32MB file systems.
== Notes ==
== References ==
4
Category:Multitasking MS-DOS