Acorn CP/M Filesystem Structure =============================== http://mdfs.net/Docs/Comp/Disk/Format/AcornCPM CP/M uses 128-byte records, which Acorn CP/M collects together into 512-byte logical disk sectors. These are mapped to 256-byte single-density physical disk sectors or 512-byte double-density physical disk sectors. Single density Acorn CP/M floppy disks are formatted to 2 sides, 80 tracks, 10 sectors, 256 bytes. Double density disks are formatted to 10 sectors of 512 bytes from track 3 onwards, with the system tracks formatted to 10 sectors of 256 bytes. Images of double-density disks have 256 bytes of padding after each 256 bytes of data in the first three tracks. Tracks are sequential, up and down; that is side 0 tracks 0 up to 79 are followed by side 1 tracks 79 down to 0. There are three reserved tracks (&1E00 bytes) used to hold the operating system on bootable floppy system disks before the filesystem. Hard drives use the track and sector numbers are an index into a hard drive image, with a 256-byte header at the start of the image. Acorn CP/M uses 2048-byte or 4096-byte logical disk blocks, counted with 16-bit numbers from the start of the filesystem, which are mapped to collections of 128-byte CP/M records. Block 0 is &1E00 bytes from the start of a single-density disk, &3C00 bytes from the start of a double-density disk, or &100 bytes from the start of a hard drive image. Acorn CP/M disks are defined with the following CP/M Disk Parameter Blocks: .DPB_Acorn400K ; DPB for AcornCPM 400K disk EQUW &0014 ; SPT=20 Records Per Track EQUB &04 ; BSH=4 Block Shift EQUB &0F ; BLM=15 Block Mask EQUB &01 ; EXM=1 Extent Mask EQUW &00C3 ; DSM=195 Disk Sector Max EQUW &007F ; DRM=127 Maximum directory entry number EQUB &C0 ; AL0=&C0 Directory occupies EQUB &00 ; AL1=&00 first two blocks EQUW &0020 ; CKS=32 Size of directory checksum vector EQUW &0003 ; OFF=3 Reserved tracks before logical start of disk ; Total disk size is 128*(BLM+1)*(DSM+1)=392K ; Physical disk size is 128*SPT*OFF+128*(BLM+1)*(DSM+1)=399.5K .DPB_Slogger800K ; DPB for Challenger/Slogger 800K disk EQUW &0028 ; SPT=40 Records Per Track EQUB &05 ; BSH=5 Block Shift EQUB &1F ; BLM=31 Block Mask EQUB &03 ; EXM=3 Extent Mask EQUW &00C3 ; DSM=195 Disk Sector Max EQUW &00FF ; DRM=255 Maximum directory entry number EQUB &C0 ; AL0=&C0 Directory occupies EQUB &00 ; AL1=&00 first two blocks EQUW &0040 ; CKS=64 Size of directory checksum vector EQUW &0003 ; OFF=3 Reserved tracks before logical start of disk ; Total disk size is 128*(BLM+1)*(DSM+1)=784K ; Physical disk size is 128*SPT*OFF+128*(BLM+1)*(DSM+1)=799K .DPB_HardDrive ; DPB for 8M Hard Drive DEFW &0100 ; SPT=256 Records Per Track DEFB &05 ; BSH=5 Block Shift DEFB &1F ; BLM=31 Block Mask DEFB &01 ; EXM=1 Extent Mask DEFW &07FF ; DSM=2047 Disk Sector Max DEFW &03FF ; DRM=1023 Maximum directory entry number DEFB &FF ; AL0=&FF Directory occupies DEFB &00 ; AL1=&00 first eight blocks DEFW &0000 ; CKS=0 Size of directory checksum vector DEFW &0000 ; OFF=0 Reserved tracks before logical start of disk ; Total disk size is 128*(BLM+1)*(DSM+1)=8192K ; Physical disk size is 128*SPT*OFF+128*(BLM+1)*(DSM+1)=8192K Floppy Disk Filesystem Layout ----------------------------- SD DD 00000 00000 DFS disk title, eg "Acorn CP", "Slogger " 00008 00008 DFS dummy file entry, eg "CPMDISC",&A4 00010 00010 BIOS code to be loaded to &EA00-&EAEF 00100 00200 DFS disk title, eg "/M ", "CP/M" 00104 00204 DFS disk cycle, eg &00 00105 00205 DFS entry index: &08 00106 00206 DFS disk size: &03,&20 00108 00208 DFS file addresses: EQUW &D400:EQUW &0000:EQUW &1E00:EQUW &0230 00110 00210 BIOS code to be loaded to &EAF0-&F1DF 00800 01000 CCP code to be loaded to &D400 01000 02000 BDOS code to be loaded to &DC00 01E00 03C00 Directory and file data Within the directory and file area logical disk blocks are mapped to pairs of physical disk sectors using the following mapping: Single-density disk Logical CP/M Logical disk Physical disk record sector sector (128 bytes) (512 bytes) (256 bytes) 0,1,2,3 0,0,0,0 0,0,1,1 4,5,6,7 1,1,1,1 4,4,5,5 8,9,10,11 2,2,2,2 8,8,9,9 12,13,14,15 3,3,3,3 2,2,3,3 16,17,18,19 4,4,4,4 6,6,7,7 Double-density disk Logical CP/M Logical disk Physical disk record sector sector (128 bytes) (512 bytes) (512 bytes) 0,1,2,3 0,0,0,0 0,0,0,0 4,5,6,7 1,1,1,1 2,2,2,2 8,9,10,11 2,2,2,2 4,4,4,4 12,13,14,15 3,3,3,3 6,6,6,6 16,17,18,19 4,4,4,4 8,8,8,8 20,21,22,23 5,5,5,5 1,1,1,1 24,25,26,27 6,6,6,6 3,3,3,3 28,29,30,31 7,7,7,7 5,5,5,5 32,33,34,35 8,8,8,8 7,7,7,7 36,37,38,39 9,9,9,9 9,9,9,9 This is probably made clearer with the following code: DEFPROCAccessCPMBlock(BlockNum%,DiskOp%) FOR part%=0 TO 3 :REM Do each block of 512 bytes sector256%=2*(BlockNum%*4+part%) :REM Physical sector offset Sector%=sector256% MOD 10 :REM Physical sector Sector%=(Sector%*2) MOD 10 :REM Deblock the physical sector Track%=(sector256% DIV 10)+Reserved% :REM Physical track Cylinder%=Track% DIV 80 Track%=Track% MOD 80 IF (Cylinder% AND 1):Track%=79-Track%:REM odd sides count downwards IF floppydisk THEN PROCAccessFDC(Cylinder%,Track%,Sector%) IF imagefile THEN PROCAccessFile(Sector%+Track%*10+Cylinder%*800) NEXT part% ENDPROC CP/M Directory ------------- Acorn CP/M disks start with a directory in the blocks specified in the DPB. This is blocks 0 and 1 on floppy disks and blocks 0 to 7 on hard drives. This gives a directory of 128 32-byte entries (4096 bytes) on single density disks, 256 32-byte entries (8192 bytes) on double density disks and 1024 32-byte entries (32768 bytes) on hard drives. The directory follows the standard CP/M layout. Each entry has an allocation table of 16 8-bit block numbers on disks with fewer than 256 total disk blocks (ie, floppy disks) or 8 16-bit block numbers on disk with 256 or more total disk blocks (ie hard drives). Directory Entry --------------- 00 : User number: 00-0F User Number 10-1F Password entry 20 Disk label 21 Date stamps E5 Erased File (usually only b7 significant) 01-08 : Filename 09-0B : Extension and attributes 0C : Extent 0D : Final byte count - if not &00, the number of bytes in the final record 0E : unused 0F : Record Count - total number of 128-byte records in this extent 10-1F : File allocation vector, 16x8-bit block numbers The file length can be calculated with: p%?15*128-128*(p%?13<>0)+p%?13+16384*(p%?12 AND exm%)-16384*(p%?15>127) where p% points to the directory entry, and exm% is the extent mask. Attributes ---------- File attributes are stored in b7 of the filename and extension. b7 of bytes 01 to 04 are reserved for user functions, b7 of bytes 05 to 08 are reserved for system functions. b7 of bytes 09 to 0B indicate the following: 09 b7 : Read-Only file 0A b7 : System file 0B b7 : Archive file cpmtools Disk Definition ------------------------ The following is the disk definition for AcornCPM disks. I don't know if this takes account of tracks 80-159 counting backwards on side 1 of the disk. diskdef acornsd seclen 512 tracks 160 sectrk 5 blocksize 2048 maxdir 128 skewtab 0,2,4,1,3 boottrk 3 os 2.2 end diskdef acorndd seclen 512 tracks 160 sectrk 10 blocksize 4096 maxdir 256 skewtab 0,2,4,6,8,1,3,5,7 boottrk 3 os 2.2 end diskdef acornhd seclen 512 tracks 64 sectrk 256 blocksize 4096 maxdir 1024 boottrk 0 os 2.2 end Version History --------------- 1.00 12-Nov-2002 First draft. 1.01 15-Nov-2010 Added hard drive disk definitions.