CP/M-86 executables (.CMD)
The .CMD file is the general executable format used by CP/M-86 and its derivatives. As well as standalone executable files, it is also used for other files containing code under CP/M-86, such as:
- System files — for example, the DOS Plus boot file DOSPLUS.SYS is in this format.
- GSX-86 drivers for both CP/M and DOS.
The filetype for a standalone program is usually .CMD. Under "Speedstart CP/M", a cut-down version of CP/M-86 intended for embedded use, it is instead .STM, and the first group is obfuscated (see below).
A .CMD file begins with a 128-byte header. The first byte will always be 1-9, of which 1 is by far the most common. If a file has a .CMD extension and starts with any other byte, it is most likely a Windows NT script file rather than a CMD file in this format.
Offset 0: 8 group descriptors [72 bytes]. Each descriptor is: DB type ;1-4 for Code/Data/Extra/Stack ;5-8 for Aux1/Aux2/Aux3/Aux4 ;9 for "pure" code (that can be shared ;between processes). DW length ;} DW base ;} In paragraphs DW minimum size ;} DW maximum size ;} ; ; The "base" of a group is 0 if a segment is relocatable. Normally it is ;nonzero only in the operating system file (DOSPLUS.SYS / PCPM.SYS / CPM.SYS). ; ; ; The following fields are not supported in CP/M-86 v1.x, but are in the 4.x ; kernel: ; Offset 7Bh: DW RSX index record, 0 if no RSX index Offset 7Dh: DW 1st record with fixups, 0 if no fixups Offset 7Fh: DB flags Bit 4 set: This file is an RSX, not a CMD file Bit 5 set: Attempt to allocate the 8087 to this program, but only if there is an 8087 present. Bit 6 set: Attempt to allocate the 8087 to this program. Even if there isn't one in the computer, allocate an imaginary resource for it. Bit 7 set: Do segment fixups.
The specified groups then follow the header. In the .STM variant files used by SpeedStart CP/M-86, the first group (usually the code group) is obfuscated by having every word XORed with 0xA5B4. That is, even-numbered bytes are XORed with 0xB4, and odd-numbered bytes with 0xA5.
If there are any fixups, these begin at a 128-byte boundary, and appear as a sequence of 4-byte records:
DB xyH ;x=Source group, 1-8. y=Dest group, 1-8. DW offset to add to source segment register DB offset to add to source offset, 0-15.The loader adds the destination group segment address to the word specified. CP/M-86 v1.1 does not support files with fixups; a separate program (R.CMD or RUN.CMD) is used to load them.
If this program contains RSXs, the "RSX index" record contains a number of 16-byte entries:
DW xxxx ;Offset of RSX from the end of the CMD header, ;in the file, in 128-byte records minus 1. ;0000h indicates the RSX is linked ; dynamically and must be loaded from ; disc when the file is loaded. ;0FFFFh indicates end of list DB 'RSXNAME ' ;Name of the .RSX. If the RSX is linked ;dynamically, this is its filename on disc. DW 0,0,0 ;Unused
GENRSX only allows 7 RSXs to be attached to a file, since this is all that will fit in one 128-byte record and allow space for the terminating 0xFFFF.