Imported Upstream version 2.10
[debian/cpmtools] / cpm.5
1 .\" Believe it or not, reportedly there are nroffs which do not know \(en
2 .if n .ds en -
3 .if t .ds en \(en
4 .TH CPM 5 "July 6, 2009" "CP/M tools" "File formats"
5 .SH NAME \"{{{roff}}}\"{{{
6 cpm \- CP/M disk and file system format
7 .\"}}}
8 .SH DESCRIPTION \"{{{
9 .SS "Characteristic sizes" \"{{{
10 Each CP/M disk format is described by the following specific sizes:
11 .RS
12 .sp
13 Sector size in bytes
14 .br
15 Number of tracks
16 .br
17 Number of sectors
18 .br
19 Block size
20 .br
21 Number of directory entries
22 .br
23 Logical sector skew
24 .br
25 Number of reserved system tracks
26 .sp
27 .RE
28 A block is the smallest allocatable storage unit.  CP/M supports block
29 sizes of 1024, 2048, 4096, 8192 and 16384 bytes.  Unfortunately, this
30 format specification is not stored on the disk and there are lots of
31 formats.  Accessing a block is performed by accessing its sectors, which
32 are stored with the given software skew.
33 .\"}}}
34 .SS "Device areas" \"{{{
35 A CP/M disk contains three areas:
36 .RS
37 .sp
38 System tracks (optional)
39 .br
40 Directory
41 .br
42 Data
43 .sp
44 .RE
45 The system tracks store the boot loader and CP/M itself.  In order to save
46 disk space, there are non-bootable formats which omit those system tracks.
47 The term \fIdisk capacity\fP always excludes the space for system tracks.
48 Note that there is no bitmap or list for free blocks.  When accessing a
49 drive for the first time, CP/M builds this bitmap in core from the directory.
50 .\"}}}
51 .SS "Directory entries" \"{{{
52 The directory is a sequence of directory entries (also called extents),
53 which contain 32 bytes of the following structure:
54 .RS
55 .sp
56 .ta 3n 6n 9n 12n 15n 18n 21n 24n 27n 30n 33n 36n 39n 42n 45n
57 St      F0      F1      F2      F3      F4      F5      F6      F7      E0      E1      E2      Xl      Bc      Xh      Rc
58 .br
59 Al      Al      Al      Al      Al      Al      Al      Al      Al      Al      Al      Al      Al      Al      Al      Al
60 .sp
61 .RE
62 .\"{{{ St     = status
63 \fBSt\fP is the status; possible values are:
64 .RS
65 .sp
66 0\*(en15: used for file, status is the user number
67 .br
68 16\*(en31: used for file, status is the user number (P2DOS)
69 or used for password extent (CP/M 3 or higher)
70 .br
71 32: disc label
72 .br
73 33: time stamp (P2DOS)
74 .br
75 0xE5: unused
76 .sp
77 .RE
78 .\"}}}
79 .LP
80 .\"{{{ F0-E2  = file name and extension
81 \fBF0\*(enE2\fP are the file name and its extension.  They may consist of
82 any printable 7 bit ASCII character but: \fB< > . , ; : = ? * [ ]\fP.
83 The file name must not be empty, the extension may be empty.  Both are
84 padded with blanks.  The highest bit of each character of the file name
85 and extension is used as attribute.  The attributes have the following
86 meaning:
87 .RS
88 .sp
89 F0: requires set wheel byte (Backgrounder II)
90 .br
91 F1: public file (P2DOS, ZSDOS), forground-only command (Backgrounder II)
92 .br
93 F2: date stamp (ZSDOS), background-only commands (Backgrounder II)
94 .br
95 F7: wheel protect (ZSDOS)
96 .br
97 E0: read-only
98 .br
99 E1: system file
100 .br
101 E2: archived
102 .sp
103 .RE
104 Public files (visible under each user number) are not supported by CP/M
105 2.2, but there is a patch and some free CP/M clones support them without
106 any patches.
107 .LP
108 The wheel byte is (by default) the memory location at 0x4b.  If it is
109 zero, only non-privileged commands may be executed.
110 .\"}}}
111 .LP
112 .\"{{{ Xl, Xh = extent number
113 \fBXl\fP and \fBXh\fP store the extent number.  A file may use more than
114 one directory entry, if it contains more blocks than an extent can hold.
115 In this case, more extents are allocated and each of them is numbered
116 sequentially with an extent number.  If a physical extent stores more than
117 16k, it is considered to contain multiple logical extents, each pointing
118 to 16k data, and the extent number of the last used logical extent
119 is stored.  Note: Some formats decided to always store only one logical
120 extent in a physical extent, thus wasting extent space.  CP/M 2.2 allows
121 512 extents per file, CP/M 3 and higher allow up to 2048.  Bit 5\*(en7 of
122 Xl are 0, bit 0\*(en4 store the lower bits of the extent number.  Bit 6
123 and 7 of Xh are 0, bit 0\*(en5 store the higher bits of the extent number.
124 .\"}}}
125 .LP
126 .\"{{{ Rc, Bc = record count, byte count
127 \fBRc\fP and \fBBc\fP determine the length of the data used by this extent.  The
128 physical extent is divided into logical extents, each of them being 16k
129 in size (a physical extent must hold at least one logical extent, e.g. a
130 blocksize of 1024 byte with two-byte block pointers is not allowed).
131 Rc stores the number of 128 byte records of the last used logical extent.
132 Bc stores the number of bytes in the last used record.  The value 0 means
133 128 for backward compatibility with CP/M 2.2, which did not support Bc.
134 .\"}}}
135 .LP
136 .\"{{{ Al     = allocated blocks
137 \fBAl\fP stores block pointers.  If the disk capacity is less than 256 blocks,
138 Al is interpreted as 16 byte-values, otherwise as 8 double-byte-values.
139 A block pointer of 0 marks a hole in the file.  If a hole
140 covers the range of a full extent, the extent will not be allocated.  In particular,
141 the first extent of a file does not neccessarily have extent number 0.
142 A file may not share blocks with other files, as its blocks would be freed
143 if the other files is erased without a following disk system reset.  CP/M returns
144 EOF when it reaches a hole, whereas UNIX returns zero-value bytes, which makes
145 holes invisible.
146 .\"}}}
147 .\"}}}
148 .SS "Time stamps" \"{{{
149 P2DOS and CP/M Plus support time stamps, which are stored in each fourth
150 directory entry.  This entry contains the time stamps for
151 the extents using the previous three directory entries.  Note that you
152 really have time stamps for each extent, no matter if it is the first
153 extent of a file or not.  The structure of time stamp entries is:
154 .RS
155 .sp
156 1 byte status 0x21
157 .br
158 8 bytes time stamp for third-last directory entry
159 .br
160 2 bytes unused
161 .br
162 8 bytes time stamp for second-last directory entry
163 .br
164 2 bytes unused
165 .br
166 8 bytes time stamp for last directory entry
167 .sp
168 .RE
169 A time stamp consists of two dates: Creation and modification date (the
170 latter being recorded when the file is closed).  CP/M Plus further
171 allows optionally to record the access instead of creation date as first
172 time stamp.
173 .RS
174 .sp
175 2 bytes (little-endian) days starting with 1 at 01-01-1978
176 .br
177 1 byte hour in BCD format
178 .br
179 1 byte minute in BCD format
180 .sp
181 .RE
182 .\"}}}
183 .SS "Disc labels" \"{{{
184 CP/M Plus support disc labels, which are stored in an arbitrary directory
185 entry.
186 The structure of disc labels is:
187 .RS
188 .sp
189 1 byte status 0x20
190 .br
191 \fBF0\*(enE2\fP are the disc label
192 .br
193 1 byte mode: bit 7 activates password protection, bit 6 causes time stamps on
194 access, but 5 causes time stamps on modifications, bit 4 causes time stamps on
195 creation and bit 0 is set when a label exists.  Bit 4 and 6 are exclusively set.
196 .br
197 1 byte password decode byte: To decode the password, xor this byte with the password
198 bytes in reverse order.  To encode a password, add its characters to get the
199 decode byte.
200 .br
201 2 reserved bytes
202 .br
203 8 password bytes
204 .br
205 4 bytes label creation time stamp
206 .br
207 4 bytes label modification time stamp
208 .sp
209 .RE
210 .\"}}}
211 .SS "Passwords" \"{{{
212 CP/M Plus supports passwords, which are stored in an arbitrary directory
213 entry.
214 The structure of these entries is:
215 .RS
216 .sp
217 1 byte status (user number plus 16)
218 .br
219 \fBF0\*(enE2\fP are the file name and its extension.
220 .br
221 1 byte password mode: bit 7 means password required for reading, bit 6 for writing
222 and bit 5 for deleting.
223 .br
224 1 byte password decode byte: To decode the password, xor this byte with the password
225 bytes in reverse order.  To encode a password, add its characters to get the
226 decode byte.
227 .br
228 2 reserved bytes
229 .br
230 8 password bytes
231 .sp
232 .RE
233 .\"}}}
234 .\"}}}
235 .SH "SEE ALSO" \"{{{
236 .IR mkfs.cpm (1),
237 .IR fsck.cpm (1),
238 .IR fsed.cpm (1),
239 .IR cpmls (1)
240 .\"}}}