CP/M pages
Home -> CP/M -> CMD file format

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:

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.

Return to archive listing