/CMD files are a series of tagged records. Some record types have meaning only for certain features of some of the TRS-80 DOSes. Only two seem important for loading and executing them.
byte: type
byte: size* in bytes
bytes[size]: data
*size
0 → 256 bytes
*size
for type 1
only, size
1 → 257 bytes, size
2 → 258 bytes
type 1: object code (load block)
data[0..1]: load address, 16-bit little-endian
data[2...]: the actual program code & data
type 2: transfer address (entry address)
data[0..1]: address execution begins, 16-bit little-endian
There should be one type 2
field, it should be the last field, and it indicates the end of the file.
All type
s up to 0x1F
can be otherwise skipped by using the size
field.
All type
s above 0x1F
are invalid. Perhaps the file is not really a /CMD file or is corrupt.
There is often garbage following the type 2
field. (Perhaps they were written to disk in sizes rounded to the next exact sector size?)
I think I might have found it. There's a "hex2cmd" command on Ubuntu:
hex2cmd - convert Intel hex format to TRS-80 CMD format
And it goes on to say
The LDOS Quarterly, April 1, 1982 (Vol 1, No 4)
⟨http://www.tim-mann.org/misosys.html⟩, has documentation of the
TRS-80 DOS CMD file format.
While I didn't find it in the link they gave, I did find the LDOS Quarterly they mention. It's in a column called Roy’s Technical Corner.
(ninjalj found another copy much faster than than me while I was writing up my answer.)
And now I've found a much more recent post on this topic by the blog of Jim Lawless: Understanding TRS-80 CMD Files
The post even includes the C source for Jim's own tool for scanning the CMD files. He also mentions some confusing aspects that the documentation didn't make clear.