Any system which analyses a CVF  must trace FAT chains and examine the
corresponding MdFatEntryRecs in the MDFAT.  Observe:

DirEntryRec              starting cluster number    
Entry      M Y F I L E   T X T a                     tim dat 003  size   
FAT 000  001  002   03  004  005  006  007  008  009  00a  00b ...
 mid  fff  000  004  006  fff  007  fff  000  000  000  000 ...
MDFAT n+000    n+001   n+002     n+003    n+004    n+005    n+006    n+007
                            f 3 08e  f 1 092  0 0 000  f 6 094  1 0 09b 
CVF Sector Heap                                             
.. 89 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 91 9b 9c 9d

This diagram illustrates how FAT entries correspond to MDFAT entries.

  MYFILE.TXT, starts at cluster 003H (as found in a Directory Entry).
The FAT chain shows that it occupies clusters 003, 004, 006, and 007
(cluster 005 is apparently in use by another file).

  To get the MdFatEntryRecs of interest, we add MdBpbRec.wFirstData to
each cluster number.  For instance, if wFirstData is 0010H, then we
are interested in MDFAT entries 013H, 014H, 016H, and 017H.

  To read a particular MdFatEntryRec, m, seek in the CVF to the start
of the MDFAT+(m*4) and read 4 bytes (the size of an MdFatEntryRec).
Each entry describes the physical location of the compressed data.

  The low 21 bits indicate a CVF logical sector number and bits 22-25
contain one less than the count of the sectors occupied by the
cluster.  To convert a CVF logical sector number to a file offset,
add 1 to it and multiply the sum by MdBpbRec.wSectSize (usually 512).

In the diagrammed example, we could access the first byte of the file as

wClusterNo       = 0003H                 (obtained from directory entry)
mdClusterNo      = wClusterNo + MdBpbRec.wFirstData

lMdFatFileOffset = (MdBpbRec.wMdFatStart+1) * MdBpbRec.wSectSize
lItemOffset      = lMdFatFileOffset + (wMdClusterNo * 4)

...we seek to lItemOffset and read the 4-byte MdFatEntryRec.  We find that
the low 21 bits contain 00008eH (the location) and that bits 22-25 contain
03H (sizCmpr) and bits 26-29 contain 0fH (sizRaw).  We calculate...

lClustStartSect = location+1
lCvfSectOffset  = lClustStartSect * MdBpbRec.wSectSize

wCmprsdBytes    = (sizCmpr + 1) * MdBpbRec.wSectSize
wUnCmprsdBytes  = (sizRaw + 1) * MdBpbRec.wSectSize

...and at last, we can seek to CVF offset lCvfSectOffset and read
wCmprsdBytes of data into an internal buffer.  If we bother to examine the
compressed data we'd see that the first four bytes are something like
'MD0 ' (4dH,44H,00H,02H).

We could use MRCI Fn 0002H (setting MRCRequestRec.wDestLen=wUnCmprsdBytes)
to decompress the data.

Notes:   COMMAND.COM accesses both the FAT and the MDFAT when you use
Dir /c.  In order to obtain the initial FAT entry, it uses the
long-obsolete fn 11H (find first file via FCB).  The advantage
of this over fn 4eH is that it returns a raw directory entry,
and therefore supplies a pointer into the FAT.

  As you trace a FAT chain, you may encounter a corresponding
MDFatEntryRec containing 00000000H.  Such an entry indicates
that no sectors are used by that cluster.

This can occur, for instance, if you open a file, seek at least
8K past the end of the last cluster in the file, then write at
least one byte.  To "decompress" such a cluster, just fill the
buffer with zeros.

- -

Mapping DOS FAT to MDFAT