home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpminfo / cpm-dir1.not < prev    next >
Text File  |  1994-07-13  |  21KB  |  494 lines

  1. Date: 12 Mar 88 01:51:27 GMT
  2. From: hubcap!ncrcae!ncr-sd!crash!mwilson@gatech.edu  (Marc Wilson)
  3. Subject: CP/M disk Directories
  4.  
  5. Ok, all you CP/M mavens, here's a good question for you.  Not anything earth-
  6. shattering, or anything like that... just irritating.
  7.  
  8. The scenario:  Disk B: is a DSDD 48 tpi drive.  It uses 8-bit allocation
  9. groups, so 16 groups can be allocated in one directory extent.  The group
  10. size is 2k, so each extent can address 32k.  That, I have no problem with.
  11. What I have problems with is how the damn files are represented in the
  12. directory.  A short example session follows.
  13.  
  14. ----------
  15.  
  16. B0:WORK>save 511 test.fil s                     ; create a file in 2 extents
  17.                                                 ; minus 1 record
  18. SAVE, Version 0.4 (loaded at B000H)
  19.   TEST    .FIL saved
  20. B0:WORK>
  21. B0:WORK>stat test.fil                           ; check it out
  22.  
  23.  
  24. Recs  Bytes  Ext Acc
  25.   511    64k    2 R/W B:TEST.FIL                ; Ok, 511 recs in 2 extents
  26. Bytes Remaining On B: 154k
  27.  
  28. B0:WORK>stat b:dsk:
  29.  
  30.  
  31.     B: Drive Characteristics
  32.  3120: 128 Byte Record Capacity
  33.   390: Kilobyte Drive  Capacity
  34.   128: 32  Byte Directory Entries
  35.   128: Checked  Directory Entries
  36.   256: Records/ Extent                          ; Wait!  How is this done?
  37.    16: Records/ Block                           ; Isn't the RC byte limited to
  38.    40: Sectors/ Track                           ; a maximum of 80h records?
  39.     2: Reserved Tracks
  40.  
  41. ; Ok, now we look at the directory...
  42.  
  43. B0:WORK>
  44.  
  45. DU3  B0? s5
  46. Group = 00:04, Track = 2, Sector = 5, Physical Sector = 4
  47.  
  48. DU3  B0? d
  49. 00  005A3830 444F5331  30444F43 01000001  |.Z80DOS10DOC....|
  50. 10  45464748 494A4B4C  4D000000 00000000  |EFGHIJKLM.......|
  51. 20  005A3830 444F5331  305A3830 00000004  |.Z80DOS10Z80....|
  52. 30  4F000000 00000000  00000000 00000000  |O...............|
  53. 40  005A3830 4454494D  455A3830 0000003E  |.Z80DTIMEZ80...>|
  54. 50  35363738 00000000  00000000 00000000  |5678............|
  55.                                 vv-------------- extent #1?
  56.                                 vv    vv-------- 80h records in this
  57.                                 vv    vv         extent?
  58.                                 vv    vv
  59. 60  00544553 54202020  2046494C 01000080  |.TEST    FIL....|
  60. 70  090A0B0C 0E0F101E  393A3B4E 5C5D5E5F  |........9:;N\]^_|
  61.  
  62. DU3  B0? +d
  63. Group = 00:05, Track = 2, Sector = 6, Physical Sector = 5
  64.                                 vv-------------- extent #3?
  65.                                 vv    vv-------- 7fh records in this
  66.                                 vv    vv-------- extent?
  67.                                 vv    vv
  68. 00  00544553 54202020  2046494C 0300007F  |.TEST    FIL....|
  69. 10  60616263 64656667  686E6F70 71727374  |`abcdefghnopqrst|
  70. 20  00444953 4B202020  20444F43 00000005  |.DISK    DOC....|
  71. 30  75000000 00000000  00000000 00000000  |u...............|
  72. 40  00434150 20202020  2046494C 00000000  |.CAP     FIL....|
  73. 50  00000000 00000000  00000000 00000000  |................|
  74. 60  E5E5E5E5 E5E5E5E5  E5E5E5E5 E5E5E5E5  |eeeeeeeeeeeeeeee|
  75. 70  E5E5E5E5 E5E5E5E5  E5E5E5E5 E5E5E5E5  |eeeeeeeeeeeeeeee|
  76.  
  77. ----------
  78.  
  79. What the @#^&$ happened to extent #0?  I thought I'd have two sequential
  80. extents, numbered zero and 1.  Instead, I get two extents, numbered 1 and
  81. 3.  The first one says it has 128 records in it, and the second says it has
  82. 127 records in it.  That's only 255 records.  Where'd the rest of 'em go?
  83.  
  84. And another oddity.  I've been playing with random files lately ( that's
  85. how I got into this mess, trying to prove that BDOS did things the way
  86. the manual says! ), and just for fun, I built a random file that only had
  87. records 0 and 0ffffh in it.  Lowest and highest.  Now, utilities like copy
  88. programs and the like can't deal with this, because there are holes in the
  89. allocation.  I see that.  But the directory above looks like it has holes in
  90. the allocation as well!  Yet PIP/ACOPY/PIPE et. al. can read and copy *this*
  91. file, *correctly*!
  92.  
  93. What's going on here?!
  94. --
  95. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  96. Marc Wilson
  97.      ARPA: ...!crash!mwilson@nosc.mil
  98.            ...!crash!pnet01!pro-sol!mwilson@nosc.mil
  99.      UUCP: [ cbosgd | hp-sdd!hplabs | sdcsvax | nosc ]!crash!mwilson
  100.      INET: mwilson@crash.CTS.COM
  101. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  102.  
  103. ------------------------------
  104.  
  105. Date: Mon 14 Mar 1988 11:46:02 EDT
  106. From: <SAGE@LL.ARPA>
  107. Subject: CP/M Directory Entries
  108.  
  109. This is the classic problem of logical vs physical.  In one case
  110. 'extent' is used to refer to the contents of one directory entry (32K or
  111. 256 logical records -- physical records probably only 32 or 64!).  The
  112. logical extent is always 16K, and thus there can be two logical extents
  113. in one physical extent, just as there can be 2 or 4 or 8 logical records
  114. (128 bytes) in each physical record.  The extent number in the directory
  115. entry is the number of the last extent in that directory, and the record
  116. count is the number of logical records in that last extent.  With larger
  117. block sizes on a hard disk it is quite possible to have 4 or probably
  118. even 8 logical extents per physical extent.  The same rules apply.
  119.  
  120.  
  121. ------------------------------
  122.  
  123. Date: Mon, 14 Mar 88 12:01:05 PST
  124. From: Bridger Mitchell <bridger%rcc@rand-unix.ARPA>
  125. Subject: CP/M directory extents
  126.  
  127. Yes, directory calculations are confusing, and not helped by confusing
  128. terminology!
  129.  
  130. The key point is to keep physical and logical extents distinct.
  131.  
  132. A CP/M LOGICAL extent holds 16K, or 80h = 128 records (each 128 bytes).
  133.  
  134. A CP/M file can have several directory entries.  Each DIRECTORY ENTRY
  135. (i.e. 32 bytes in the first group(s) on a disk) has 16 bytes of space
  136. for data group numbers; the group numbers must be words if there are
  137. >255 groups on a disk. Thus:
  138.  
  139. A CP/M PHYSICAL extent (i.e., a single DIRECTORY ENTRY) may be hold
  140. a multiple of 16K.
  141.  
  142.   The multiple depends on:
  143.         (a) whether a group number is a byte or word
  144.         (b) the size of one allocation group (1,2,4,8,16 K)
  145.         (c) whether the format designer used all of the 16 bytes
  146.             available in a single directory entry
  147.  
  148. The RECORD COUNT BYTE gives the number of records in the HIGHEST
  149. logical extent referenced by the physical extent/directory entry it
  150. appears in.
  151.  
  152. Similarly, the EXTENT BYTE (and its overflow into the low-order bits
  153. of the S2 byte) gives the number of the HIGHEST logical extent
  154. referenced by the physical extent/directory entry it appears in.
  155.  
  156.  
  157. examples:
  158. (with S2 and EXT appropriately masked to remove internal bdos flag bits)
  159.  
  160. #1      S2  = 0,  EXT = 1, RC = 7fh
  161.  
  162.         If there is 1 directory entry per logical extent, then
  163.         this is the second directory entry; its final record is 7f=127.
  164.  
  165.         If there are 2 or more directory entries per logical extent
  166.         this is the first directory entry; its final record is
  167.         80h + 7fh = 255.
  168.  
  169. #2      S2 = 0, EXT =1, RC = 80h
  170.  
  171.         If there is 1 directory entry per logical extent, then
  172. this is the second directory entry; its final record is 80h = 128
  173.  
  174.         If there are exactly 2 directory entries per logical extent
  175.         this is the first directory entry; its final record is
  176.         80h + 80h = 256, and this entry is full.
  177.  
  178.         If there are more than 2 entries per logical extent,
  179.         this entry is not full; the next record would result in
  180.         EXT = 2, RC = 1.
  181.  
  182. If the file is written sequentially, then we know in #1 that the file has
  183. 80h +7fh=255 total records.  If it is written randomly, all we know
  184. (without inspecting the group numbers) is that there is at least one
  185. record, the 255th; there may be others, including some in higher-numbered
  186. extents.
  187.  
  188. In #2, assuming for example exactly 2 logical extents per directory
  189. entry, there may be a second directory entry that is totally empty
  190. (EXT=2, RC = 0).  This can happen when a sequentially-written file
  191. is exactly 256 records long; the bdos internally closes the directory
  192. entry, creates a new one, and then is told by the program to close the
  193. file.
  194.  
  195. Regarding (c) above, several OEM's and ramdisk suppliers (Televideo,
  196. SWP, ...) have defined disk formats that do not use all 8/16 group
  197. slots in a single directory entry.  Apparently they weren't able to
  198. distinguish logical and physical extents!  The result is unnecessary
  199. extra directory entries for large files and additional headaches for
  200. programmers.
  201.  
  202. COPYING random files (ones containing holes) is not so
  203. straightforward, because the utility must determine how to handle a
  204. destination disk that has a different allocation group size.  In the
  205. general case, although the data records can be copied, I don't believe
  206. a "perfect copy" is possible, because the destination copy may not
  207. retain the same information about unwritten records that existed in
  208. the original.  (Information about unwritten records is mostly inferred
  209. from missing group numbers.)  This could conceiveably lead to errors
  210. in a database program that relied on the "unwritten-data" error from
  211. the bdos. (Consider, for example, copying a random-record database
  212. from a 2K to a 4K group disk, and then copying it back to a 2K disk.)
  213.  
  214.  
  215. --bridger mitchell
  216.  
  217. ------------------------------
  218.  
  219. Date: 13 Mar 88 18:01:57 GMT
  220. From: portal!cup.portal.com!dick_a_wotiz@uunet.uu.net
  221. Subject: CP/M disk Directories
  222.  
  223. > Ok, all you CP/M mavens, here's a good question for you.  Not anything earth-
  224. > shattering, or anything like that... just irritating.
  225. >
  226. >  . . . .
  227. >
  228. >                                 vv-------------- extent #1?
  229. >                                 vv    vv-------- 80h records in this
  230. >                                 vv    vv         extent?
  231. >                                 vv    vv
  232. > 60  00544553 54202020  2046494C 01000080  |.TEST    FIL....|
  233. > 70  090A0B0C 0E0F101E  393A3B4E 5C5D5E5F  |........9:;N\]^_|
  234. >
  235. >                                 vv-------------- extent #3?
  236. >                                 vv    vv-------- 7fh records in this
  237. >                                 vv    vv-------- extent?
  238. >                                 vv    vv
  239. > 00  00544553 54202020  2046494C 0300007F  |.TEST    FIL....|
  240. > 10  60616263 64656667  686E6F70 71727374  |`abcdefghnopqrst|
  241.  
  242.    Actually, the byte you are calling the 'extent #' is handled a
  243. little differently.  The LSB of this byte means 'add 80h records to
  244. the record count byte', and the upper 7 bits, when shifted once to
  245. the right, are the extent number.
  246.  
  247.    The '# of records' byte is never allowed to get larger than 80h,
  248. so this method is needed to allow up to 256 records per extent.
  249.  
  250. Some examples:                    vv    vv
  251.       extent 0,  127 records:     0000007F
  252.          "       128 records:     00000080
  253.          "       129 records:     01000001
  254.          "       256 records:     01000080
  255.       extent 1,  1   record:      02000001
  256.          "       129 records:     03000001
  257.          "       255 records:     0300007F
  258.  
  259. - - - - - - - - - - - - - - - - - - - - - -
  260. dick@portal.com                {uunet|sun|atari}!portal!dick
  261.      dick@cup.portal.com
  262.  
  263. ------------------------------
  264.  
  265. Date: 13 Mar 88 22:18:21 GMT
  266. From: portal!cup.portal.com!Robert_A_Freed@uunet.uu.net
  267. Subject: CP/M disk Directories
  268.  
  269. In message <2662@crash.cts.com> mwilson@crash.cts.com (Marc Wilson)
  270. writes in some detail about a 511-record file (just short of 64K
  271. bytes), which uses two directory entries on a floppy disk system with
  272. 2K-byte allocation block size (32K-byte extent size).
  273.  
  274. > What's going on here?!
  275.  
  276. What's going on is that you are confused about the RC (record count)
  277. and EX (extent number) bytes in a directory entry.  This is
  278. understandable, since the DRI (Digital Research, Inc.) CP/M 2.2
  279. documentation only describes the CP/M 1.x case of 1K allocation
  280. blocks and 16K extents.
  281.  
  282. In order to accommodate larger disk capacities, DRI altered the
  283. meaning of these bytes in CP/M version 2.  They did this in a way
  284. which is downward compatible with CP/M version 1.  The record count
  285. for an extent is now split between the low 7 bits of RC and the lower
  286. bits of EX.  The portion of EX which is used for the high part of the
  287. record count is specified by the "extent mask."  A full extent is
  288. still indicated by RC = 80h (with all extent mask bits in EX set).
  289. I.e., the high bit of RC serves as a flag rather than as part of the
  290. record count.  The true "extent number" is obtained by right-shifting
  291. EX by the number of bits in the extent mask.
  292.  
  293. > What the @#^&$ happened to extent #0?  I thought I'd have two sequential
  294. > extents, numbered zero and 1.  Instead, I get two extents, numbered 1 and
  295. > 3.  The first one says it has 128 records in it, and the second says it has
  296. > 127 records in it.  That's only 255 records.  Where'd the rest of 'em go?
  297.  
  298. In your case, the extent mask is 1.  The two EX bytes (01h and 03h)
  299. become 0 and 1 after shifting right by one bit.  The RC value (80h)
  300. for the first extent indicates it is full (256 records).  The RC
  301. value (7Fh) for the second extent is combined with the low bit of the
  302. EX value to yield record count FFh (255 records).  This is as you had
  303. expected.  No records are "lost" and the file is not "sparse" (no
  304. unallocated extents.)
  305.  
  306. Note:  The above description is sufficient for disks with no more
  307. than 512K-byte capacity.  However, two additional details must be
  308. noted to completely describe the situation for larger capacity disks.
  309. First, the upper 3 bits of the EX byte are always zero.  (The reason
  310. for this is somewhat obscure:  Since EX participates in directory
  311. scans by BDOS functions such as Open_File and Search_for_First, a
  312. valid EX value must not match 3Fh, the ASCII code for the ? character
  313. used as a "wildcard.")  Second, because the remaining 5 EX bits
  314. (less, due to the extent mask) are insufficient for specifying all
  315. extent numbers, the upper bits of the extent number overflow into the
  316. S2 byte, which was unused in CP/M version 1.
  317.  
  318. To me, it's always seemed a shame that DRI went to such lengths to
  319. preserve backward compatibility with older versions of CP/M and then
  320. failed to properly document the changes.  I was only able to fully
  321. understand the above by disassembling BDOS (many, many moons ago).
  322. And I have seen many public domain programs that manipulate directory
  323. entries break on hard disk systems due to a lack of understanding of
  324. these details.
  325.  
  326. Bob Freed
  327.  
  328. Internet:  Robert_A_Freed@cup.portal.com
  329. Uucp: ...!sun!portal!cup.portal.com!Robert_A_Freed
  330.  
  331. ------------------------------
  332.  
  333. Date: 13 Mar 88 20:02:21 GMT
  334. From: portal!cup.portal.com!dgood@uunet.uu.net
  335. Subject: CP/M disk Directories
  336.  
  337. > The scenario:  Disk B: is a DSDD 48 tpi drive.  It uses 8-bit allocation
  338. > groups, so 16 groups can be allocated in one directory extent.  The group
  339. > size is 2k, so each extent can address 32k.  That, I have no problem with.
  340. > What I have problems with is how the damn files are represented in the
  341. > directory.  A short example session follows.
  342.  
  343. There is some confusion here between about the concept of an extent.
  344.  
  345. Originally, in cp/m 1.x (how's that for comp.archaeology) an extent
  346. was, by definition, 16k.  This was because each dir entry showed the
  347. location of 16 groups x 1k per group.
  348.  
  349. With cp/m 2.x came a more flexible arrangement.  Groups can be up to
  350. 16k each.  It also became possible to use either eight or sixteen bit
  351. directory addressing for each group; each directory entry still
  352. contains 16 bytes of group addresses, which may now address either
  353. eight or sixteen groups.
  354.  
  355. Thus an extent (the amount of a file handled by a single directory
  356. entry) became variable.  However, to maintain compatibility with the
  357. earlier versions of cp/m, the physical directory entries continue
  358. to consider an extent as 16k (ALWAYS).  In other words, we now have
  359. a physical extent, which might contain as much as 128k (16k group x
  360. 8 groups/dir entry), but our directory extent byte shows logical
  361. extents, which are always 16k!  In your example the logical extent
  362. is 16k, but the physical extent is 32k.
  363.  
  364.  
  365. > B0:WORK>save 511 test.fil s                   ; create a file in 2 extents
  366. >                                               ; minus 1 record
  367.  
  368. Note that you have saved 2 physical extents, but 4 logical extents.
  369.  
  370. > B0:WORK>stat test.fil                         ; check it out
  371. >
  372. >  Recs  Bytes  Ext Acc
  373. >   511    64k    2 R/W B:TEST.FIL              ; Ok, 511 recs in 2 extents
  374. > Bytes Remaining On B: 154k
  375.  
  376. Yes, 2 physical, 4 logical extents
  377.  
  378. > B0:WORK>stat b:dsk:
  379. >
  380. >
  381. >     B: Drive Characteristics
  382. >  3120: 128 Byte Record Capacity
  383. >   390: Kilobyte Drive  Capacity
  384. >   128: 32  Byte Directory Entries
  385. >   128: Checked  Directory Entries
  386. >   256: Records/ Extent                        ; Wait!  How is this done?
  387. >    16: Records/ Block                         ; Isn't the RC byte limited to
  388. >    40: Sectors/ Track                         ; a maximum of 80h records?
  389. >     2: Reserved Tracks
  390.  
  391. The RC byte shows the number of records (max 80h) in the LAST logical
  392. extent for that directory entry.  Here, we'll have two logical extents,
  393. ext 0 & ext 1, for the first dir entry.
  394.  
  395. > ; Ok, now we look at the directory...
  396. >
  397. > B0:WORK>
  398. >
  399. > DU3  B0? s5
  400. > Group = 00:04, Track = 2, Sector = 5, Physical Sector = 4
  401. >
  402. >                                 vv-------------- extent #1?
  403. >                                 vv    vv-------- 80h records in this
  404. >                                 vv    vv         extent?
  405. >                                 vv    vv
  406. > 60  00544553 54202020  2046494C 01000080  |.TEST    FIL....|
  407. > 70  090A0B0C 0E0F101E  393A3B4E 5C5D5E5F  |........9:;N\]^_|
  408.  
  409.       ^ --extent #0-- ^  ^ --extent #1-- ^
  410.  
  411. Since we have filled logical ext #0 and are into logical ext #1,
  412. we know that we have 80h records in logical ext #0.  The RC byte
  413. shows 80h records in logical ext #1, the last logical extent in
  414. the dir entry.  Remember that the extent byte shows the LAST
  415. logical extent in that directory entry, and the RC byte shows
  416. the number of records in that last logical extent.
  417.  
  418. > DU3  B0? +d
  419. > Group = 00:05, Track = 2, Sector = 6, Physical Sector = 5
  420. >                                 vv-------------- extent #3?
  421. >                                 vv    vv-------- 7fh records in this
  422. >                                 vv    vv-------- extent?
  423. >                                 vv    vv
  424. > 00  00544553 54202020  2046494C 0300007F  |.TEST    FIL....|
  425. > 10  60616263 64656667  686E6F70 71727374  |`abcdefghnopqrst|
  426.  
  427.       ^ --extent #2-- ^  ^ --extent #3-- ^
  428.  
  429. Again, 80h records in (full) logical ext #2, 7Fh records in logical
  430. ext #3.
  431.  
  432.  
  433.                 Dave Goodman    dgood@cup.portal.com
  434.  
  435.  
  436. ------------------------------
  437.  
  438. Date: Tuesday, 15 March 1988  10:05-MST
  439. From: Bridger Mitchell <bridger%rcc@RAND-UNIX.ARPA>
  440. Subject: CP/M dir. extents - correction
  441.  
  442. In my posting yesterday:
  443.         Date: Mon, 14 Mar 88 12:01:05 PST
  444.         From: Bridger Mitchell <bridger%rcc@rand-unix.ARPA>
  445.         Subject: CP/M directory extents
  446.  
  447. I got my tongue (keyboard?) twisted in describing two
  448. examples.  Here's the corrected excerpt, in "<<<...>>>"
  449.  
  450. examples:
  451. (with S2 and EXT appropriately masked to remove internal bdos flag bits)
  452.  
  453. #1      S2  = 0,  EXT = 1, RC = 7fh
  454.  
  455.         If there is 1 <<<logical extent per directory entry>>>, then
  456.         this is the second directory entry; its final record is 7f=127.
  457.  
  458.         If there are 2 or more <<<logical extents per directory entry>>>
  459.         this is the first directory entry; its final record is
  460.         80h + 7fh = 255.
  461.  
  462. #2      S2 = 0, EXT =1, RC = 80h
  463.  
  464.         If there is 1 <<<logical extent per directory entry>>>, then
  465.         this is the second directory entry; its final record is 80h = 128
  466.  
  467.         If there are exactly 2 <<<logical extents per directory entry>>>
  468.         this is the first directory entry; its final record is
  469.         80h + 80h = 256, and this entry is full.
  470.  
  471.         If there are more than 2  <<<logical extents per directory entry>>>
  472.         this entry is not full; the next record would result in
  473.         EXT = 2, RC = 1.
  474.  
  475. --bridger
  476.  
  477. ------------------------------
  478.  
  479. Date: 14 Mar 88 21:58:51 GMT
  480. From: portal!cup.portal.com!David_Michael_McCord@uunet.uu.net
  481. Subject: SB180 help?
  482.  
  483. The Sb180 electronics and software make it virtually impossible to read
  484. or write 48tpi disks in a 96tpi drive.  However, an inexepensive solution
  485. is to add a 48tpi drive to the system, and then you can read and write
  486. 48tpi formats to your heart's content, including mushdos if you buy the
  487. UNIFORM product from Micromint.
  488.  
  489. I have an SB180 configured with 2 96tpi drives as A: and B:, and a 48tpi
  490. drive as C:.  Works great.
  491.  
  492. ------------------------------
  493.  
  494.