Mapping DOS FAT to MDFAT

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

           DirEntryRec              starting cluster number ══╗
Directory ╓───────────────────┬─┬───────────────────┬───┬───┬──┬───────╖
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 ...
                  ╚═╦═╝╚═╦═╝     ╚═╦═╝╚══╩═════════════════════════╗
                        ╚═══════╗ ╚══════════════════════╗        
                    ╚══════════╗ ╚══════╗                         
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│
(n=MdBpbRec.wFirstData) ╔════════════╝             ╔═══════════╝        
                                           ╔══════╝     ╔══════════════╝
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.

See Also: CVF Region: MDFAT
          CVF Layout
          DoubleSpace Overview
          DoubleSpace API
          DOS Functions