Acorn CPM Filesystem Structure ============================== http://mdfs.net/Docs/Comp/Disk/Format/AcornCPM CPM uses 128-byte records, which Acorn CPM collects together into 512-byte logical disk sectors. These are mapped to 256-byte physical disk sectors. Acorn CPM 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 CPM records. Acorn CPM floppy disks are formatted to 2 sides, 80 tracks, 10 sectors, 256 bytes. Tracks are sequential, up and down; that is side 0 tracks 0 up 79 are followed by side 1 tracks 79 down to 0. There are three reserved tracks (&1E00 bytes) before the filesystem used to hold the operating system on bootable system disks. Double density disks are formatted to 16 sectors of 256 bytes from track 3 onwards, with the system tracks formatted to 10 sectors of 256 bytes. Acorn CPM disks are defined with the following CPM Disk Parameter Blocks: .DPB_Acorn400K ; DPB for AcornCPM 400K disk EQUW &0014 ; SPT=20 Sectors 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 .DPB_Slogger800K ; DPB for Challenger/Slogger 800K disk EQUW &0028 ; SPT=40 Sectors 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 Filesystem Layout ----------------- 00000 DFS disk title, eg "Acorn CP", "Slogger " 00008 DFS dummy file entry, eg "CPMDISC",&A4 00010 BIOS code to be loaded to &EA00-&EAEF 00100 DFS disk title, eg "/M ", "CP/M" 00104 DFS disk cycle, eg &00 00105 DFS entry index: &08 00106 DFS disk size: &03,&20 00108 DFS file addresses: EQUW &D400:EQUW &0000:EQUW &1E00:EQUW &0230 00110 BIOS code to be loaded to &EAF0-&F1DF 00800 CCP code to be loaded to &D400 01000 BDOS code to be loaded to &DC00 01E00 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: Logical CP/M Logical disk Physical disk record sector sector (128 bytes) (512 byte) (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 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 CPM Directory ------------- Acorn CPM disks start with a directory in blocks 0 and 1 as specified in the DPB. This is 128 32-byte entries (4096 bytes) on single density disks and 256 32-byte entries (8192 bytes) on double density disks. The directory is folows the standard CP/M layout. Each entry has an alocation table of 16 8-bit block numbers. 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 Version History --------------- 1.00 12-Nov-2002 First draft.