CP/M pages
Home -> CP/M -> FAT filesystem

The FAT filesystem in 16-bit CP/M-86

Concurrent CP/M 3.1 and later, and single-user CP/M-86 with BDOS 3.3 and later (including DOS Plus), allow CP/M programs to access DOS-formatted discs via conventional BDOS calls, emulating (as far as possible) the behaviour of a normal CP/M filesystem. The behaviour is probably a good starting point for anyone writing a CP/M emulator which uses a hierarchical or non-CP/M filesystem.

Test for DOS media

The test used by the DOS Plus utilities is to perform a Search First (BDOS function 11h) with the first 12 bytes of the FCB containing '?' marks. On a DOS disc, this will return a "disc label" directory entry, and byte 0Fh of this entry will be 80h. On a CP/M disc, it may or may not return the label, but if it does byte 0Fh of the label entry will be zero.

FCB functions in general

If bit 7 of the "drive" byte in the FCB is set, then the call is assumed to apply to directories rather than files. The following calls appear to support directories:

Open. Changes to the specified subdirectory (can be ".."). The Extent byte should be 0 to set the current directory, or 1-3 to set a "floating" drive (N: O: or P:) to the specified directory.
Close. Changes to the root directory.
Search first. Will return directories and files.
Search next.
Delete. Will remove a subdirectory if it is empty.
Create. Creates a new subdirectory.

FCB functions behave normally, but the allocation area (16 bytes at FCB+10h) contains the following data:

  fl fl of 00 cc cc ci ci dd dd cl cl le le le le  ................


  fl = flags:
       d7 always set 
       d6 set if file is a directory 
       d5 set if file is hidden
       d4-d0 are high bits of file number
   of = file number, low 8 bits. Number is 0 for 1st dir entry, 1 for 2nd, etc.
   cc = current cluster, 0 if none
   ci = index of current cluster (0, 1, 2, ...) in file chain. Only meaningful
        if cc is nonzero.
   dd = DOS date
   cl = DOS cluster
   le = DOS length

Functions 11h and 12h

Functions 11h and 12h will return a fake directory record with:

The emulation goes to some pains to ensure that if a '?' is in byte 0Ch of the search FCB, a suitable list of "extents" is returned.

XIOS level

The XIOS returns an Extended DPB (call it an EDPB) for DOS media:

	DW	extflag	 ;On a DOS disc, this will be -1 for FAT12 
			 ;and -2 for FAT16 (CCP/M-86 3.1 only supports FAT12).
			 ;On a CP/M-86 disc, a normal DPB is returned, and 
			 ;this will be its SPT (Sectors per track) entry.
	DW	nfats	 ;Number of FATs (normally 2)
	DW	nfatrecs ;The number of physical sectors per FAT.
	DW	nclstrs	 ;The number of clusters on the disc.
	DW	clsize	 ;The number of bytes per cluster.
	DW	fatadd	 ;The number of the sector holding the start of
			 ;the first FAT.
; followed by a CP/M DPB:
	DW	spt	;Physical sectors per track
	DB	bsh	;Block shift. 3 => 1k, 4 => 2k, 5 => 4k, ...
	DB	blm	;Block mask. 7 => 1k, 0Fh => 2k, 1Fh => 4k,...
	DB	exm	;Extent mask. Must be 0 for DOS media.
	DW	dsm	;Number of clusters - 1
	DW	drm	;Root directory entries - 1
	DB	al0	;Not used for DOS media
	DB	al1	;Not used for DOS media
	DW	cks	;Checksum vector size: 0 or 8000h for a fixed disc,
			;else number of (root directory entries)/4,rounded up
	DW	off	;Number of reserved tracks
	DB	psh	;Physical sector shift 0 => 128-byte sectors,
			;1 => 256-byte sectors, 2 => 512-byte sectors,...
	DB	prm	;Physical record mask 0 => 128-byte sectors,
			;1 => 256-byte sectors, 3 => 512-byte sectors,...

The BDOS returns the normal DPB rather than the EDPB to function 1Fh, so this function can't be used to detect DOS-formatted discs.

John Elliott 16 July 2005