Also known as: MDC1200, MDC-1200, Motorola Data Communications
The MDC1200 frame is the on-air unit of Motorola Data Communications — the analog in-band data burst two-way radios key at the start or end of a transmission to signal the radio’s unit ID (ANI), emergency, status, call-alert and radio-check events on an otherwise-plain FM voice channel.1 It is a 40-bit synchronisation word followed by 112 interleaved payload bits, carried as a 1200-baud FFSK burst (mark 1200 Hz, space 1800 Hz) inside the narrowband-FM voice channel.2
How it works
MDC1200 rides the same modulation class GopherTrunk already demodulates for MPT 1327 and
APRS, but unlike APRS the line code is plain NRZ, not
NRZI. A receiver hunts the 40-bit sync word 0x07092A446F
(most-significant bit first), then captures the 112 payload bits that follow. Those bits are
column-interleaved over a 16×7 grid: GopherTrunk’s deinterleave reads them back in
bits[j*16+i] order for i in 0..15 and j in 0..6, then packs the result LSB-first into 14
bytes. The interleave spreads a fading burst across the codeword so the over-the-air redundancy
can recover it. Of the 14 recovered bytes, the header is op, arg, unit-ID (big-endian), CRC
(little-endian on the wire), and the trailing eight bytes are the redundancy field the frame’s
FEC uses.
Opcode table
The (op, arg) pair names the event. GopherTrunk’s opLabel resolves the widely-published
opcode conventions; the set is best-effort and intentionally non-exhaustive, since many
vendor-specific and extended opcodes exist:
| Op | Meaning |
|---|---|
0x01 |
PTT ID / ANI (arg 0x00 = keyed at tail) |
0x00 |
Emergency |
0x06 |
Status request |
0x12 |
Status N (arg is the status number) |
0x0A |
Call alert / page |
0x22 |
Message |
0x2B |
Radio inhibit (stun) |
0x2C |
Radio enable (revive) |
0x35 |
Voice selective call |
0x46 |
Remote monitor |
0x63 |
Radio check |
Opcodes 0x35 and 0x55 select an extended two-block message; GopherTrunk flags these as
double packets and preserves the second block’s raw bytes for a follow-up parse.
The CRC
MDC1200 protects its header with a reflected CRC-16/CCITT — polynomial 0x1021 used in its
reflected form 0x8408, initial value 0x0000, and a final XOR of 0xFFFF. GopherTrunk
computes it over the four header bytes (op, arg, and the two unit-ID bytes) and compares
against the received value. A CRC failure does not discard the burst outright: DecodeFrame
still returns the best-effort decode with CRCOK = false, so an operator can choose to surface
marginal bursts. The same 0x1021 polynomial appears across GopherTrunk’s other framers under
different init/reflect/xorout settings, catalogued under CRC-16/CCITT.
The whole MDC1200 package is a clean-room implementation from the public protocol description —
sync word, interleave geometry, CRC parameters and opcode semantics are protocol facts, with no
third-party decoder source incorporated.
Sources
-
MDC-1200 — Wikipedia, on Motorola’s in-band signalling burst and its ANI / emergency / status functions. ↩
-
Frame synchronization — Wikipedia, on locating a burst by its fixed sync word. ↩