<< Previous Message Main Index Next Message >>
<< Previous Message in Thread This Month Next Message in Thread >>
Date   : Sun, 13 Mar 1988 22:18:21 GMT
From   : portal!cup.portal.com!Robert_A_Freed@uunet.uu.net
Subject: CP/M disk Directories

In message <2662@crash.cts.com> mwilson@crash.cts.com (Marc Wilson)
writes in some detail about a 511-record file (just short of 64K
bytes), which uses two directory entries on a floppy disk system with
2K-byte allocation block size (32K-byte extent size).

> What's going on here?!

What's going on is that you are confused about the RC (record count)
and EX (extent number) bytes in a directory entry.  This is
understandable, since the DRI (Digital Research, Inc.) CP/M 2.2
documentation only describes the CP/M 1.x case of 1K allocation
blocks and 16K extents.

In order to accommodate larger disk capacities, DRI altered the
meaning of these bytes in CP/M version 2.  They did this in a way
which is downward compatible with CP/M version 1.  The record count
for an extent is now split between the low 7 bits of RC and the lower
bits of EX.  The portion of EX which is used for the high part of the
record count is specified by the "extent mask."  A full extent is
still indicated by RC = 80h (with all extent mask bits in EX set).
I.e., the high bit of RC serves as a flag rather than as part of the
record count.  The true "extent number" is obtained by right-shifting
EX by the number of bits in the extent mask.

> What the @#^&$ happened to extent #0?  I thought I'd have two sequential
> extents, numbered zero and 1.  Instead, I get two extents, numbered 1 and
> 3.  The first one says it has 128 records in it, and the second says it has
> 127 records in it.  That's only 255 records.  Where'd the rest of 'em go?

In your case, the extent mask is 1.  The two EX bytes (01h and 03h)
become 0 and 1 after shifting right by one bit.  The RC value (80h)
for the first extent indicates it is full (256 records).  The RC
value (7Fh) for the second extent is combined with the low bit of the
EX value to yield record count FFh (255 records).  This is as you had
expected.  No records are "lost" and the file is not "sparse" (no
unallocated extents.)

Note:  The above description is sufficient for disks with no more
than 512K-byte capacity.  However, two additional details must be
noted to completely describe the situation for larger capacity disks.
First, the upper 3 bits of the EX byte are always zero.  (The reason
for this is somewhat obscure:  Since EX participates in directory
scans by BDOS functions such as Open_File and Search_for_First, a
valid EX value must not match 3Fh, the ASCII code for the ? character
used as a "wildcard.")  Second, because the remaining 5 EX bits
(less, due to the extent mask) are insufficient for specifying all
extent numbers, the upper bits of the extent number overflow into the
S2 byte, which was unused in CP/M version 1.

To me, it's always seemed a shame that DRI went to such lengths to
preserve backward compatibility with older versions of CP/M and then
failed to properly document the changes.  I was only able to fully
understand the above by disassembling BDOS (many, many moons ago).
And I have seen many public domain programs that manipulate directory
entries break on hard disk systems due to a lack of understanding of
these details.

Bob Freed

Internet:  Robert_A_Freed@cup.portal.com
Uucp: ...!sun!portal!cup.portal.com!Robert_A_Freed

<< Previous Message Main Index Next Message >>
<< Previous Message in Thread This Month Next Message in Thread >>