This page describes the detection mechanisms used by CP/M-86. I have studied four versions:
Track 0, head 0, sector 1 is read in. The last byte of this sector is the identity byte (see below).
The DPBs for these formats are given in the 4.x form, where the SPT field is physical sectors. To bring the DPB into the form used by versions 1-3 of CP/M, multiply SPT by 4.
DPB field | 160k | 320k | 360k | 720k (PCP/M) | 720k (144FEAT) | 1.2Mb (144FEAT) | 1.4Mb (144FEAT) |
---|---|---|---|---|---|---|---|
ID byte | 0 | 1 | 10h* | 11h | 48h | 0Ch | 90h |
SPT | 8 | 8 | 9 | 9 | 9 | 0Fh | 12h |
BSH | 3 | 4 | 4 | 4 | 4 | 5 | 5 |
BLM | 7 | 0Fh | 0Fh | 0Fh | 0Fh | 1Fh | 1Fh |
EXM | 0 | 1 | 1 | 0 | 0 | 1 | 1 |
DSM | 9Bh | 9Dh | 0Ahh | 15Eh | 162h | 127h | 162h |
DRM | 3Fh | 3Fh | 3Fh | 0FFh | 0FFh | 0FFh | 0FFh |
AL0 | 0C0h | 80h | 80h | 0F0h | 0F0h | 0C0h | 0C0h |
AL1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
CKS | 10h | 10h | 10h | 40h | 40h | 40h | 40h |
OFF | 1 | 1 | 4 | 4 | 2 | 2 | 2 |
PSH | 2 | 2 | 2 | 2 | 2 | 2 | 2 |
PHM | 3 | 3 | 3 | 3 | 3 | 3 | 3 |
Supported by CP/M-86 1.1 | Y | Y | N | with 144FEAT | with 144FEAT | with 144FEAT | with 144FEAT |
Supported by Personal CP/M-86 2.0/4 | Y | Y | Y | Y | N | N | N |
Supported by DOSPLUS 1.2 | Y | Y | N | N | N | N | N |
The Personal CP/M-86 720k format uses flip sides:
track 0 is cylinder 0 head 0 track 1 is cylinder 0 head 1 track 2 is cylinder 1 head 0 ... track 158 is cylinder 79 head 0 track 159 is cylinder 79 head 1whereas the three 144FEAT formats use up-and-over:
track 0 is cylinder 0 head 0 track 1 is cylinder 1 head 0 track 2 is cylinder 2 head 0 ... track 78 is cylinder 78 head 0 track 79 is cylinder 79 head 0 track 80 is cylinder 79 head 1 track 81 is cylinder 78 head 1 ... track 157 is cylinder 2 head 1 track 158 is cylinder 1 head 1 track 159 is cylinder 0 head 1
If the byte has other values, 160k format is used.
The partition table is read to locate any partitions of type 0DBh (CP/M). If such a partition is found at cylinder n, then cylinder n, head 0, sector 4 is read into memory. This sector is formed:
+0: DW checksum word. If this sector is treated as 256 words and they are all summed, the total must = 0. +2: DS 1Fh ;Copyright message +21h: DW first cylinder in partition +23h: DW no. of cylinders in partition +25h: DB no. of hard drive heads +26h: DB no. of physical sectors / track +27h: DB options ;Not used by CP/M-86 BIOS or loader ; CCP/M-86 uses bit 0 nonzero for 'verify on write'. +28h: DB sector size / 128 +29h: DW spt ;This is a DPB for the drive +2Bh: DB bsh ; | +2Ch: DB blm ; | +2Dh: DB exm ; | +2Eh: DW dsm ; | +30h: DW drm ; | +32h: DW al0 ; | +33h: DW al1 ; | +34h: DW cks ; v +36h: DW off ;--- no. of tracks from start of drive to ; the directory. +38h: DW 0 ;} +3Ah: DW 0 ;} Not used by CP/M-86 BIOS or loader +3Ch: DW 0 ;} +3Eh: DW 0 ;} +40h: DW block size / 128 +42h: DW max. number of words in the bad block list +44h: DW number of words in the bad block list +46h: DW First block beyond the replacements for bad blocks - ie, the layout is: ;[normal blocks] ;[substitute n] ;... ;[substitute 0] ;[block pointed to by this word] +48h: DW bad0, bad1, ... ;list of bad blocks - end of sector
The substitute for the first bad block is at the very end of the partition. The next substitute comes before it, and so on.
This list is handled transparently to the remainder of the filesystem. Directory entries will still refer to the blocks marked as "bad"; redirection to the substitute blocks is done by the BIOS.