pull patches back in from 2.20-2 build
[debian/cpmtools] / cpm.5
diff --git a/cpm.5 b/cpm.5
index d844e48c14bc5860073932ba7807d07d1c0c1d66..4b14493dc6d2dff7d422a9021a4bcc4734250e5a 100644 (file)
--- a/cpm.5
+++ b/cpm.5
@@ -1,7 +1,7 @@
 .\" Believe it or not, reportedly there are nroffs which do not know \(en
 .if n .ds en -
 .if t .ds en \(en
-.TH CPM 5 "December 20, 2009" "CP/M tools" "File formats"
+.TH CPM 5 "October 10, 2022" "CP/M tools" "File formats"
 .SH NAME \"{{{roff}}}\"{{{
 cpm \- CP/M disk and file system format
 .\"}}}
@@ -22,19 +22,26 @@ Number of directory entries
 .br
 Logical sector skew
 .br
-Number of reserved system tracks
+Number of reserved system tracks (optional)
+.br
+Offset to start of volume (optional and not covered by operating system,
+but disk driver specific)
 .sp
 .RE
 A block is the smallest allocatable storage unit.  CP/M supports block
 sizes of 1024, 2048, 4096, 8192 and 16384 bytes.  Unfortunately, this
 format specification is not stored on the disk and there are lots of
 formats.  Accessing a block is performed by accessing its sectors, which
-are stored with the given software skew.
+are stored with the given software skew.  \fBcpmtools\fP always counts
+sectors starting with 0, as it deals with logical sectors.  CP/M uses physical
+sectors in the skew table, which often start with 1.
 .\"}}}
 .SS "Device areas" \"{{{
-A CP/M disk contains three areas:
+A CP/M disk contains four areas:
 .RS
 .sp
+Volume offset (optional and not covered by operating system, but disk driver specific)
+.br
 System tracks (optional)
 .br
 Directory
@@ -47,6 +54,28 @@ disk space, there are non-bootable formats which omit those system tracks.
 The term \fIdisk capacity\fP always excludes the space for system tracks.
 Note that there is no bitmap or list for free blocks.  When accessing a
 drive for the first time, CP/M builds this bitmap in core from the directory.
+.LP
+A hard disk can have the additional notion of a \fIvolume offset\fP to
+locate the start of the drive image (which may or may not have system
+tracks associated with it).  The base unit for volume offset is byte
+count from the beginning of the physical disk, but specifiers of
+\fIK\fP, \fIM\fP, \fIT\fP or \fIS\fP may be appended to denote
+kilobytes, megabytes, tracks or sectors.  If provided, a specifier
+must immediately follow the numeric value with no whitespace.  For
+convenience upper and lower case are both accepted and only the first
+letter is significant, thus 2KB, 8MB, 1000trk and 16sec are valid
+values.  The \fBoffset\fP must appear subsequent to track, sector and sector
+length values for the sector and track units to work.
+.LP
+Note that it is possible to reserve space between the directory and
+the beginning of data.  Although typically data follows the directory,
+some systems used this to store extra data instead of using more
+system tracks (see the fields \fBALV0\fP and \fBALV1\fP in the
+DPB).
+.LP
+There are disk formats that map multiple logical tracks onto a physical
+track, which allows a little bit more capacity in case the system image
+size does not match the physical track capacity well.
 .\"}}}
 .SS "Directory entries" \"{{{
 The directory is a sequence of directory entries (also called extents),
@@ -63,9 +92,10 @@ Al   Al      Al      Al      Al      Al      Al      Al      Al      Al      Al      Al      Al      Al      Al      Al
 \fBSt\fP is the status; possible values are:
 .RS
 .sp
-0\*(en15: used for file, status is the user number
+0\*(en15: used for file, status is the user number.  CP/M 2.2 only documents
+0\*(en15 and CCP and PIP only offer those, but the BDOS allows to use 0\*(en31.
 .br
-16\*(en31: used for file, status is the user number (P2DOS)
+16\*(en31: used for file, status is the user number (P2DOS, CP/M 2.2)
 or used for password extent (CP/M 3 or higher)
 .br
 32: disc label
@@ -131,21 +161,27 @@ blocksize of 1024 byte with two-byte block pointers is not allowed).
 Rc stores the number of 128 byte records of the last used logical extent.
 Bc stores the number of bytes in the last used record.  The value 0 means
 128 for backward compatibility with CP/M 2.2, which did not support Bc.
+ISX records the number of unused instead of used bytes in Bc.
+This only applies to files with allocated blocks.  For an empty file, no
+block is allocated and Bc 0 has no meaning.
 .\"}}}
 .LP
 .\"{{{ Al     = allocated blocks
-\fBAl\fP stores block pointers.  If the disk capacity is less than 256 blocks,
-Al is interpreted as 16 byte-values, otherwise as 8 double-byte-values.
-A block pointer of 0 marks a hole in the file.  If a hole
-covers the range of a full extent, the extent will not be allocated.  In particular,
-the first extent of a file does not neccessarily have extent number 0.
-A file may not share blocks with other files, as its blocks would be freed
-if the other files is erased without a following disk system reset.  CP/M returns
-EOF when it reaches a hole, whereas UNIX returns zero-value bytes, which makes
-holes invisible.
+\fBAl\fP stores block pointers.  If the disk capacity minus boot
+tracks but including the directory area is less than or equal to 256 blocks, Al
+is interpreted as 16 byte-values, otherwise as 8 double-byte-values.
+Since the directory area is not subtracted, the directory area starts
+with block 0 and files can never allocate block 0, which is why this
+value can be given a new meaning: A block pointer of 0 marks a hole in
+the file.  If a hole covers the range of a full extent, the extent will
+not be allocated.  In particular, the first extent of a file does not
+neccessarily have extent number 0.  A file may not share blocks with other
+files, as its blocks would be freed if the other files is erased without
+a following disk system reset.  CP/M returns EOF when it reaches a hole,
+whereas UNIX returns zero-value bytes, which makes holes invisible.
 .\"}}}
 .\"}}}
-.SS "Time stamps" \"{{{
+.SS "Native time stamps" \"{{{
 P2DOS and CP/M Plus support time stamps, which are stored in each fourth
 directory entry.  This entry contains the time stamps for
 the extents using the previous three directory entries.  Note that you
@@ -179,6 +215,45 @@ time stamp.
 1 byte minute in BCD format
 .sp
 .RE
+All time stamps are stored in local time.
+.\"}}}
+.SS "DateStamper time stamps" \"{{{
+The DateStamper software added functions to the BDOS to manage
+time stamps by allocating a read only file with the name "!!!TIME&.DAT"
+in the very first directory entry, covering the very first data
+blocks.  It contains one entry per directory entry with the
+following structure of 16 bytes:
+.RS
+.sp
+5 bytes create datefield
+.br
+5 bytes access datefield
+.br
+5 bytes modify datefield
+.br
+1 byte magic number/checksum
+.sp
+.RE
+The magic number is used for the first 7 entries of each 128-byte record
+and contains the characters \fB!\fP, \fB!\fP, \fB!\fP, \fBT\fP, \fBI\fP,
+\fBM\fP and \fBE\fP.  The checksum is used on every 8th entry (last entry
+in 128-byte record) and is the sum of the first 127 bytes of the record.
+Each datefield has this structure:
+.RS
+.sp
+1 byte BCD coded year (no century, so it is sane assuming any year < 70
+means 21st century)
+.br
+1 byte BCD coded month
+.br
+1 byte BCD coded day
+.br
+1 byte BCD coded hour or, if the high bit is set, the high byte of a
+counter for systems without real time clock
+.br
+1 byte BCD coded minute, or the low byte of the counter
+.sp
+.DE
 .\"}}}
 .SS "Disc labels" \"{{{
 CP/M Plus support disc labels, which are stored in an arbitrary directory