{"id":2251,"date":"2018-11-10T23:03:44","date_gmt":"2018-11-10T23:03:44","guid":{"rendered":"http:\/\/www.sydneysmith.com\/wordpress\/?p=2251"},"modified":"2018-11-10T23:03:44","modified_gmt":"2018-11-10T23:03:44","slug":"cpmfs-2-00","status":"publish","type":"post","link":"https:\/\/www.sydneysmith.com\/wordpress\/2251\/cpmfs-2-00\/","title":{"rendered":"cpmfs 2.00"},"content":{"rendered":"<p><img loading=\"lazy\" src=\"http:\/\/www.sydneysmith.com\/wordpress\/wp-content\/uploads\/2018\/11\/cpmfs-2.00-help.png\" alt=\"cpmfs tool to copy files to cpm disk images\" width=\"659\" height=\"432\" class=\"alignnone size-full wp-image-2252\" srcset=\"https:\/\/www.sydneysmith.com\/wordpress\/wp-content\/uploads\/2018\/11\/cpmfs-2.00-help.png 659w, https:\/\/www.sydneysmith.com\/wordpress\/wp-content\/uploads\/2018\/11\/cpmfs-2.00-help-300x197.png 300w\" sizes=\"(max-width: 659px) 100vw, 659px\" \/><\/p>\n<p>Version 2.00 of cpmfs has just been released, and it&#8217;s pretty good even if I do say so myself.<\/p>\n<p>Cpmfs is a tool that allows you to copy files to and from CP\/M disk images. It runs on Windows (but should easily port to linux) so you can set up disks for an old Operating System from the comfort of your current one. I use it in automated builds but it&#8217;s designed to be easy to use manually too. Here&#8217;s what you can do: <!--more--><\/p>\n<h2>TL;DR<\/h2>\n<p>&#8211; create CP\/M, CDOS or Cromix disk images.<br \/>\n&#8211; copy files on and off a CP\/M or CDOS disk image.<br \/>\n&#8211; erase, rename or list the files in a disk image.<br \/>\n&#8211; copy an operating system from a disk image or to one.<br \/>\n&#8211; patch the OS already in a disk image.<br \/>\n&#8211; work with CDOS disk labels.<br \/>\n&#8211; create a byte for a CP\/M BIOS to autoconfigure for the disk.<br \/>\n&#8211; work with mixed-mode (SD track 0) disk types.<br \/>\n&#8211; work with non-standard disk types (any number of tracks, any number of sectors).<br \/>\n&#8211; check a CP\/M (or CDOS) disk image for errors.<br \/>\n&#8211; has downloadable source code.<\/p>\n<h2>Create disks<\/h2>\n<pre><code>cpmfs -t <em>type<\/em> <em>filename<\/em> init<\/code><\/pre>\n<p>This creates <em>filename<\/em> as a disk image file. You can then use <em>filename<\/em> with your favourite CP\/M simulator. It also works for Cromemco CDOS disks so you can use <em>filename<\/em> there too. It should also work on other CP\/M-like operating systems.<\/p>\n<p>I use &#8220;.dsk&#8221; as the <em>filename<\/em> extension as that&#8217;s what z80sim and z80emu require, but you could use any other value if that&#8217;s better for what you use.<\/p>\n<p>The internal format is just a sequence of sectors (some bytes) starting from track 0 sector 1 to how ever many tracks you have. It has no header and there is no embedded information between sectors. The format is very simple and it&#8217;s easy to implement in a simulator. That&#8217;s probably why it&#8217;s very commonly used or supported by simulators.<\/p>\n<p>The lack of a header can be a nuisance &#8211; there&#8217;s lots of useful information I&#8217;d have liked to have seen tucked into a header &#8211; but it&#8217;s simplicity also serves as an inherent header. By this I mean simulators can look at the image size and determine the disk size. As an example: a disk image that is 256,256 bytes long is an image for a standard 8&#8243; SSSD disk (77 tracks x 26 sectors x 128 bytes). If you use smaller disks (5&#8243;) the number of tracks that the drive uses is smaller so the size is smaller and a simulator can notice and change its disk parameters.<\/p>\n<p>The same goes for double-sided (DS) and double-density (DD) disk images. Fortunately, every combination gives a different size.<\/p>\n<p>For cpmfs 2.00, I have standardised on the disk type names that Cromemco used in the day. Their software relied on the use of those names so all of their disks were formatted to use those names. On the CP\/M side of the fence, things were a lot more flexible and a lot less standardised. Cpmfs will write the disk type into the end of the boot sector, just as the Cromemco tools of the time did. This allows not just the emulator to determine the disk type; but the OS to do so too. That is particularly important for CDOS (and Cromix writing CDOS disks) but it can be useful for CP\/M too as a BIOS can be written to reconfigure on disk type changes. e.g to switch to double-density and a greater capacity if a double-density disk is inserted in the (virtual) drive.<\/p>\n<p>The disk types are: <\/p>\n<table>\n<tr>\n<td>Type<\/td>\n<td>Description<\/td>\n<\/tr>\n<tr>\n<td>LGSSSD<\/td>\n<td>Large (8&#8243;) single-sided single-density<\/td>\n<\/tr>\n<tr>\n<td>LGDSSD<\/td>\n<td>Large (8&#8243;) double-sided single-density<\/td>\n<\/tr>\n<tr>\n<td>LGSSDD<\/td>\n<td>Large (8&#8243;) single-sided double-density<\/td>\n<\/tr>\n<tr>\n<td>LGDSDD<\/td>\n<td>Large (8&#8243;) double-sided double-density<\/td>\n<\/tr>\n<tr>\n<td>SMSSSD<\/td>\n<td>Small (5&#8243;) single-sided single-density<\/td>\n<\/tr>\n<tr>\n<td>SMDSSD<\/td>\n<td>Small (5&#8243;) double-sided single-density<\/td>\n<\/tr>\n<tr>\n<td>SMSSDD<\/td>\n<td>Small (5&#8243;) single-sided double-density<\/td>\n<\/tr>\n<tr>\n<td>SMDSDD<\/td>\n<td>Small (5&#8243;) double-sided double-density<\/td>\n<\/tr>\n<\/table>\n<p>They&#8217;re pretty easy to remember after you&#8217;ve used them a few times.<\/p>\n<p>Notes:<br \/>\n1. Large uses 77 tracks per disk (the IBM \/ Digital Research 8&#8243; standard).<br \/>\n2. Single-density uses 128 byte sectors (the IBM \/ Digital Research 8&#8243; standard).<br \/>\n3. Small uses 40 tracks per disk (common, but there wasn&#8217;t a standard).<br \/>\n4. Double-density uses 512 byte sectors (standard).<\/p>\n<p>Cromemco, like many manufacturers of the time, actually used &#8220;mixed-mode&#8221; disks which have a single-density track 0 and then the remaining tracks in double-density; rather than all tracks in double-density. This combination allowed older hardware, that predated double-density, to still boot a single density boot sector like it always had. They didn&#8217;t need to replace boot ROMs (and customers didn&#8217;t need to pay for an upgrade).<\/p>\n<p>All of the &#8220;DD&#8221; formats mentioned above are suitable for Cromemco and similar hardware. Every one of those listed above has a single-density track 0.<\/p>\n<p>In case your hardware (simulator) requires full double-density (on all tracks), I have added the following:<\/p>\n<table>\n<tr>\n<td>Type<\/td>\n<td>Description<\/td>\n<\/tr>\n<tr>\n<td>8FSSDD<\/td>\n<td>8&#8243; full single-sided double-density<\/td>\n<\/tr>\n<tr>\n<td>8FDSDD<\/td>\n<td>8&#8243; full double-sided double-density<\/td>\n<\/tr>\n<tr>\n<td>5FSSDD<\/td>\n<td>5&#8243; full single-sided double-density<\/td>\n<\/tr>\n<tr>\n<td>5FDSDD<\/td>\n<td>5&#8243; full double-sided double-density<\/td>\n<\/tr>\n<\/table>\n<p>All of those will provide full double-density instead of a mixed-mode disk. None of them should work on CDOS; but they might if your simulator adapts and if CDOS skips reserved tracks rather than a number of sectors. They&#8217;d never work on Cromemco hardware in the real world.<\/p>\n<p>CP\/M will work with them provided the BIOS is set up for them. If you need them and can use them, they are there.<\/p>\n<p>These 4 <em>type<\/em>s and the earlier 8 make up the 12 basic floppy disk formats used by CP\/M.<\/p>\n<p>If you need a different number of tracks, or a different number of sectors per track, you can use the disk options included in cpmfs ver 2.00 to adjust these (see below). <\/p>\n<h2>Format disks<\/h2>\n<pre><code>cpmfs -t <em>type<\/em> <em>filename<\/em> init<\/code><\/pre>\n<p>Look familiar? We just covered this in the heading above. If you init-ialize an existing disk image, all content will be erased and it goes back to a pristine disk, just out of the virtual box. It even smells new. \ud83d\ude42<\/p>\n<h2>Copy files to and from CP\/M and CDOS disk images<\/h2>\n<pre><code>cpmfs [-t <em>type<\/em>] <em>filename<\/em> [opts] r file [file...] [dir]\r\ncpmfs [-t <em>type<\/em>] <em>filename<\/em> [opts] w [dir\\]file [[dir\\]file...]<\/code><\/pre>\n<p>Read one or more files from a CP\/M disk image to the host file system, or write them the other way.<\/p>\n<p>You can use ambiguous file names if your OS supports this. In Windows, you can use &#8220;*.com&#8221; (with the quotation marks) to read all .com files from a diskimage. The quotation marks are necessary or Windows will try to match your parameter to Windows files. Similar steps would be necessary on linux.<\/p>\n<p>If you &#8220;r&#8221; one or more files and include a directory name at the end, cpmfs will put all the files it reads from the imagefile into that directory.<\/p>\n<p>Here&#8217;s some examples:<code><\/p>\n<pre>\r\nC:\\Test\\cpmfs>mkdir 2\r\n\r\nC:\\Test\\cpmfs>cpmfs drivea.dsk r \"d*.com\" 2\r\nOK.\r\n\r\nC:\\Test\\cpmfs>dir 2\r\n Volume in drive C is Windows\r\n Volume Serial Number is FCBA-5187\r\n\r\n Directory of C:\\Test\\cpmfs\\2\r\n\r\n10\/11\/2018  18:14    &lt;DIR&gt;          .\r\n10\/11\/2018  18:14    &lt;DIR&gt;          ..\r\n10\/11\/2018  18:14             9,984 DEBUG.COM\r\n10\/11\/2018  18:14            11,008 DISKCOPY.COM\r\n10\/11\/2018  18:14             3,584 DUMP.COM\r\n               3 File(s)         24,576 bytes\r\n               2 Dir(s)  13,555,482,624 bytes free\r\n\r\nC:\\Test\\cpmfs>\r\n<\/pre>\n<p><\/code><\/p>\n<pre><code>\r\nC:\\Test\\cpmfs>cpmfs -t LGSSSD new.dsk init\r\nOK.\r\n\r\nC:\\Test\\cpmfs>cpmfs new.dsk w 2\\*.*\r\nOK.\r\n\r\nC:\\Test\\cpmfs>cpmfs new.dsk dir\r\nDEBUG.COM\r\nDISKCOPY.COM\r\nDUMP.COM\r\n\r\nC:\\Test\\cpmfs>\r\n<\/pre>\n<p><\/code><\/p>\n<h2>Copy to and from the System area of the disk image<\/h2>\n<pre><code>cpmfs [-t <em>type<\/em>] <em>filename<\/em> [opts] rs [<em>start<\/em> [<em>len<\/em> [<em>file<\/em>]]]\r\ncpmfs [-t <em>type<\/em>] <em>filename<\/em> [opts] ws [<em>start<\/em> [<em>len<\/em> [<em>file<\/em>]]]<\/code><\/pre>\n<p>This is the equivalent of the CP\/M GETSYS.COM, PUTSYS.COM and\/or SYSGEN.COM program.<\/p>\n<p>If you don't specify a filename, sysarea.sys will be used.<\/p>\n<p>If you don't specify a length, the entire system area will be used. This is based on the number of reserved tracks for the disk and it works for mixed-mode disks, as well as SD and full DD. You can \"rs\" from one disk type and then \"ws\" the file onto a different disk type. An \"rs\" reads all of the reserved area by default, and a \"ws\" only writes what's present and fits. It even respects \"data disks\" where the number of reserved tracks is zero (no system area).<\/p>\n<p>If you'd like to patch the boot sector, or read or replace the BIOS (for example), you can use the start and len parameters. Both of these are in records. Len can span tracks, even if the number of sectors per track and density changes. Records are always 128 (80H) bytes long. The boot sector is always record 0 (so use 0 1 as start and len to read or write the boot sector). For CP\/M 2.2, the CCP is 800H long, BDOS 0E00H long, and BIOS up to 380H long (on disk). In the case where the CCP, BDOS and BIOS are immediately after the boot sector; you'd use 1 16 for the CCP, 17 28 for the BDOS and 45 7 for the BIOS. Some CP\/Ms load the CCP from the data area. Some CP\/Ms have non-standard CCPs. If yours is non-standard, cpmfs is built so it will still work - you'll just have to adjust the start and len values to suit your needs.<\/p>\n<p>The easiest way to patch a few bytes in the boot sector is to open the entire disk image directly in a hex editor. The boot sector is the first 80H bytes of the disk image.<\/p>\n<p>If you need to modify the program rather than patch bytes, you are better off writing (or disassembling) the boot sector program, assembling it, and then writing the binary to the image using cpmfs ... ws 0 1 file.<\/p>\n<p>Here's some examples:<code><\/p>\n<pre>\r\nC:\\Test\\cpmfs>cpmfs drivea.dsk rs\r\n90 records read.\r\nOK.\r\n\r\nC:\\Test\\cpmfs>dump sysarea.sys\r\nDUMP (Dump File) version 00.01.gss\r\n\r\n         Record 0\r\n000000:  3E 01 D3 40  38 04 97 08  16 31 1E 7F  21 00 01 01   >.S@8....1..!...\r\n000010:  0F 02 7B D3  04 CB 4B 28  15 7A D3 34  79 D3 30 97   ..{S.KK(.zS4yS0.\r\n000020:  3D 20 FD DB  34 1F 30 FB  DB 30 E6 98  20 D2 78 D3   = }[4.0{[0f. RxS\r\n000030:  32 7A F6 80  D3 34 0E 33  3E 9C D3 30  DB 34 1F 38   2zv.S4.3>.S0[4.8\r\n000040:  04 ED A2 18  F7 DB 30 CB  67 28 B5 3E  04 95 3E 1A   .m\".w[0Kg(5>..>.\r\n000050:  9C 38 2D 3A  FC 00 FE 44  20 02 CB F2  06 01 3A FA   .8-:|.~D .Kr..:z\r\n000060:  00 FE 44 20  04 7B EE 02  5F 0E 5F 18  A5 00 00 00   .~D .{n._._.%...\r\n000070:  00 00 00 00  00 00 00 00  4C 47 44 53  44 44 E5 E5   ........LGDSDDee\r\n...\r\n<\/pre>\n<p><\/code><br \/>\nYou can see the disk type in bytes 120-125 of the boot sector.<\/p>\n<pre><code>\r\nC:\\Test\\cpmfs>z80asm -fb -sn -lboot.lis boot.z80\r\nZ80 - Assembler Release 1.7, Copyright (C) 1987-2016 by Udo Munk\r\nPass 1\r\n   Read    boot.z80\r\nPass 2\r\n   Read    boot.z80\r\n0 error(s)\r\n\r\nC:\\Test\\cpmfs>cpmfs drivea.dsk ws 0 1 boot.bin\r\n1 records written.\r\nOK.\r\n\r\nC:\\Test\\cpmfs>cpmfs drivea.dsk rs\r\n90 records read.\r\nOK.\r\n\r\nC:\\Test\\cpmfs>dump sysarea.sys\r\nDUMP (Dump File) version 00.01.gss\r\n\r\n         Record 0\r\n000000:  3E 01 D3 40  21 00 E4 DD  21 EE 00 DD  36 00 02 11   >.S@!.d]!n.]6...\r\n000010:  7F 31 01 0F  02 7B D3 04  CB 4B 28 15  7A D3 34 79   .1...{S.KK(.zS4y\r\n000020:  D3 30 97 3D  20 FD DB 34  1F 30 FB DB  30 E6 98 20   S0.= }[4.0{[0f.\r\n000030:  CF 78 D3 32  7A F6 80 D3  34 0E 33 3E  9C D3 30 DB   OxS2zv.S4.3>.S0[\r\n000040:  34 1F 38 04  ED A2 18 F7  DB 30 CB 67  28 B2 DD 35   4.8.m\".w[0Kg(2]5\r\n000050:  00 CA 00 FA  3A FC 00 FE  44 20 02 CB  F2 06 01 3A   .J.z:|.~D .Kr..:\r\n000060:  FA 00 FE 44  20 04 7B EE  02 5F 0E 5F  18 A7 FF FF   z.~D .{n._._.'..\r\n000070:  FF FF FF FF  FF FF FF FF  4C 47 44 53  53 44 E5 E5   ........LGDSSDee\r\n...\r\n<\/pre>\n<p><\/code><br \/>\nYou can see that the disk type in bytes 120-125 of the boot sector has changed. Also whilst both sectors start with 3E 01 and D3 40 (LD A,1 then OUT (40H),A); things differ from there.<\/p>\n<h2>DIR, ERA and REN<\/h2>\n<p>You can see what files are on a disk image by using DIR, just like in CP\/M. Likewise you can ERAse and REName files as you can in CP\/M. There are two versions of REN as there are two ways we're all used to using it. In Windows (or MSDOS) we do REN oldname newname. It's similar in *nix: mv oldname newname. However, in CP\/M it is REN newname=oldname. Both styles are accommodated in case you type either. The glitch though, is you have to type the three parts \"newname\", \"=\" and \"oldname\" with a space between them.<\/p>\n<p>The commands are:<\/p>\n<pre><code>\r\ncpmfs [-t type] imagefile [opts] dir [patn]\r\ncpmfs [-t type] imagefile [opts] era fn\r\ncpmfs [-t type] imagefile [opts] ren old new\r\ncpmfs [-t type] imagefile [opts] ren new = old\r\n<\/pre>\n<p><\/code><\/p>\n<p>Some examples are:<\/p>\n<pre><code>\r\nC:\\Test\\cpmfs>cpmfs new.dsk ren debug.com unbug.com\r\nOK.\r\n\r\nC:\\Test\\cpmfs>cpmfs new.dsk dir\r\nDISKCOPY.COM\r\nDUMP.COM\r\nUNBUG.COM\r\n\r\nC:\\Test\\cpmfs>cpmfs new.dsk ren xcopy.com=diskcopy.com\r\nError: ren new = old, or\r\n       ren old new\r\n\r\nC:\\Test\\cpmfs>cpmfs new.dsk ren xcopy.com = diskcopy.com\r\nOK.\r\n\r\nC:\\Test\\cpmfs>cpmfs new.dsk dir\r\nDUMP.COM\r\nUNBUG.COM\r\nXCOPY.COM\r\n\r\nC:\\Test\\cpmfs>cpmfs new.dsk era \"d*.com\"\r\nOK.\r\n\r\nC:\\Test\\cpmfs>cpmfs new.dsk dir\r\nUNBUG.COM\r\nXCOPY.COM\r\n\r\nC:\\Test\\cpmfs>cpmfs new.dsk era \"*.*\"\r\nOK.\r\n\r\nC:\\Test\\cpmfs>cpmfs new.dsk dir\r\nNo file(s) found\r\n\r\nC:\\Test\\cpmfs>\r\n<\/pre>\n<p><\/code><br \/>\nNote the use of quotes around the CP\/M ambiguous file names to ensure they make it into the cpmfs program and aren't converted to matching Windows filenames instead.<\/p>\n<h2>Add, Update or Remove CDOS Labels<\/h2>\n<p>If you're not using CDOS, this won't matter and you can skip the section.<\/p>\n<p>CDOS version 2 records information about the directory in a disk label at the start of the directory. It is mostly useful information like the name of the disk and the date of the disk. It opens up the way for a really useful disk cataloging system but it was also useful for using STAT to see which disk is in which drive - without having to open the drive, pull out the disk, look and put it back in again.<\/p>\n<p>However, it also records some vital information about the disk.<\/p>\n<p>Single sided 8\" disks, under CP\/M 1 and CDOS 1, were organised as 243 blocks of 1KB each. Two of the blocks were used for the directory and this was enough space for 64 directory entries. A File Control Block (FCB) contained a map of up to 16 blocks allocated to the file. There's a little more to it than this but there is room for 16 one-byte block numbers in each FCB.<\/p>\n<p>With the introduction of double-sided and\/or double-density disks, the capacity went up - which was the intent. However, CP\/M could only cope with up to 256 x 1KB blocks and the situation with CDOS was similar (up to 254 x 1KB blocks). Both Digital Research (that made CP\/M) and Cromemco (that made CDOS) went to 2KB blocks. This only worked to a degree as a LGDSDD disk has a 1216 KB data area and that is well over 256 x 2KB blocks. Both companies went to FCBs with 8 x 2-byte block numbers for really large disks.<\/p>\n<p>The main reason for a CDOS disk label is not to label the disk. It's major benefit is in providing somewhere to record the block size and whether the disk uses one-byte or two-byte block numbers in its FCBs. Without one, CDOS will assume it has a capacity of 254 KB.<\/p>\n<p>If you are going to use one of the larger capacity disks in CDOS, you need to label the disk. In CDOS STAT\/LBL will do that (and you'll see the disk size increase as you do it - do STAT before and after to see the size). You can also add a label using cpmfs. The command is:<br \/>\n<code><\/p>\n<pre>\r\ncpmfs [-t type] imagefile [opts] lbl [name]\r\n<\/pre>\n<p><\/code><br \/>\nLike CDOS, if you don't give a disk a name, the disk will be labelled \"Userdisk\".<br \/>\nRunning the above command will also store all the correct values in all the correct places for CDOS to access the disk properly.<\/p>\n<p>You can relabel a CDOS disk. With cpmfs only the disk name changes. The date and directory information is unchanged. Under CDOS it will ask to delete any existing data and rewrite, correct or change the directory information.<\/p>\n<p>A CDOS disk label appears to CP\/M as a used FCB entry belonging to user 129 (which never exists). It won't show up in DIR listings. It won't get deleted (even with ERA *.*). It should be safe to use in a CP\/M system (eg if you are transferring data).<\/p>\n<p>If you want to remove a CDOS label (perhaps so you can create a new timestamp for the disk, or to switch it from one style of FCB to a different one), you can use the following:<br \/>\n<code><\/p>\n<pre>\r\ncpmfs [-t type] imagefile [opts] rmlbl\r\n<\/pre>\n<p><\/code><\/p>\n<p>CP\/M also stores information about the disk, but in its case, this is hard-coded into the BIOS as disk parameter block (DPB) settings. If you insert a disk with different directory settings, CP\/M will ruin the disk. Some BIOSes try to identify the disk type and directory settings and change their DPB settings to match. This is a similar process to what CDOS does with the disk label.<\/p>\n<p>Use the DIR2 command to see if a CDOS label is present and what its settings are.<\/p>\n<h2>Examine the disk in more detail with DIR2<\/h2>\n<p>The command is:<code><\/p>\n<pre>\r\ncpmfs [-t type] imagefile [opts] dir2\r\n<\/pre>\n<p><\/code><br \/>\nIt shows you the boot sector, the CDOS label, a byte for similar purposes for CP\/M BIOSes, and a dump of every active FCB. This doesn't include erased files.<\/p>\n<p>Here's what it looks like on a disk with both a DPB byte and a CDOS label (neither get in the way of the other):<br \/>\n<code><\/p>\n<pre>\r\nC:\\Test\\cpmfs>cpmfs drivea.dsk dir2\r\n\r\nBoot Sector\r\n3E 01 D3 40 38 04 97 08 16 31 1E 7F 21 00 01 01 >..@8....1..!...\r\n0F 02 7B D3 04 CB 4B 28 15 7A D3 34 79 D3 30 97 ..{...K(.z.4y.0.\r\n3D 20 FD DB 34 1F 30 FB DB 30 E6 98 20 D2 78 D3 = ..4.0..0.. .x.\r\n32 7A F6 80 D3 34 0E 33 3E 9C D3 30 DB 34 1F 38 2z...4.3>..0.4.8\r\n04 ED A2 18 F7 DB 30 CB 67 28 B5 3E 04 95 3E 1A ......0.g(.>..>.\r\n9C 38 2D 3A FC 00 FE 44 20 02 CB F2 06 01 3A FA .8-:...D .....:.\r\n00 FE 44 20 04 7B EE 02 5F 0E 5F 18 A5 00 00 00 ..D .{.._._.....\r\n00 00 00 00 00 00 00 00 4C 47 44 53 44 44 E5 4A ........LGDSDD.J\r\n\r\nDPB\r\nReserved tracks: 2, Block size: 2K, Dir type: 2, Dir blocks: 4\r\n\r\nCDOS disk label: Userdisk\r\nDate on disk   : 2018-11-10\r\nCluster size   : 2K\r\nDirectory type : 2 byte block numbers\r\nDirectory size : 256 entries\r\n\r\nDirectory\r\n81 55 73 65 72 64 69 73 6B 0B 0A 76 10 80 00 40 .Userdisk..v...@\r\n00 00 01 00 02 00 03 00 00 00 00 00 00 00 00 00 ................\r\n00 43 44 4F 53 20 20 20 20 43 4F 4D 00 00 00 6F .CDOS    COM...o\r\n04 00 05 00 06 00 07 00 08 00 09 00 0A 00 00 00 ................\r\n00 49 4E 49 54 32 37 31 20 43 4F 4D 00 00 00 58 .INIT271 COM...X\r\n0B 00 0C 00 0D 00 0E 00 0F 00 10 00 00 00 00 00 ................\r\n00 58 46 45 52 20 20 20 20 43 4F 4D 00 00 00 3B .XFER    COM...;\r\n11 00 12 00 13 00 14 00 00 00 00 00 00 00 00 00 ................\r\n00 43 44 4F 53 47 45 4E 20 43 4F 4D 00 00 00 80 .CDOSGEN COM....\r\n15 00 16 00 17 00 18 00 19 00 1A 00 1B 00 1C 00 ................\r\n00 43 44 4F 53 47 45 4E 20 43 4F 4D 01 00 00 80 .CDOSGEN COM....\r\n1D 00 1E 00 1F 00 20 00 21 00 22 00 23 00 24 00 ...... .!.\".#.$.\r\n00 43 44 4F 53 47 45 4E 20 43 4F 4D 02 00 00 04 .CDOSGEN COM....\r\n25 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 %...............\r\n00 57 52 54 53 59 53 20 20 43 4F 4D 00 00 00 09 .WRTSYS  COM....\r\n26 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &...............\r\n00 53 54 41 54 20 20 20 20 43 4F 4D 00 00 00 48 .STAT    COM...H\r\n27 00 28 00 29 00 2A 00 2B 00 00 00 00 00 00 00 '.(.).*.+.......\r\n00 45 44 49 54 20 20 20 20 43 4F 4D 00 00 00 38 .EDIT    COM...8\r\n2C 00 2D 00 2E 00 2F 00 00 00 00 00 00 00 00 00 ,.-...\/.........\r\n00 44 55 4D 50 20 20 20 20 43 4F 4D 00 00 00 1C .DUMP    COM....\r\n30 00 31 00 00 00 00 00 00 00 00 00 00 00 00 00 0.1.............\r\n00 49 4E 49 54 32 38 32 20 43 4F 4D 00 00 00 5E .INIT282 COM...^\r\n32 00 33 00 34 00 35 00 36 00 37 00 00 00 00 00 2.3.4.5.6.7.....\r\n00 44 49 53 4B 43 4F 50 59 43 4F 4D 00 00 00 56 .DISKCOPYCOM...V\r\n38 00 39 00 3A 00 3B 00 3C 00 3D 00 00 00 00 00 8.9.:.;.<.=.....\r\n00 53 43 52 45 45 4E 20 20 43 4F 4D 00 00 00 57 .SCREEN  COM...W\r\n3E 00 3F 00 40 00 41 00 42 00 43 00 00 00 00 00 >.?.@.A.B.C.....\r\n00 44 45 42 55 47 20 20 20 43 4F 4D 00 00 00 4E .DEBUG   COM...N\r\n44 00 45 00 46 00 47 00 48 00 00 00 00 00 00 00 D.E.F.G.H.......\r\n00 4D 45 4D 54 53 54 38 20 43 4F 4D 00 00 00 1A .MEMTST8 COM....\r\n4B 00 4C 00 00 00 00 00 00 00 00 00 00 00 00 00 K.L.............\r\n00 4D 45 4D 54 53 54 43 20 43 4F 4D 00 00 00 1A .MEMTSTC COM....\r\n4D 00 4E 00 00 00 00 00 00 00 00 00 00 00 00 00 M.N.............\r\n00 58 20 20 20 20 20 20 20 43 4F 4D 00 00 00 03 .X       COM....\r\n49 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 I...............\r\n00 52 20 20 20 20 20 20 20 43 4F 4D 00 00 00 20 .R       COM...\r\n4A 00 4F 00 00 00 00 00 00 00 00 00 00 00 00 00 J.O.............\r\n00 57 20 20 20 20 20 20 20 43 4F 4D 00 00 00 20 .W       COM...\r\n50 00 51 00 00 00 00 00 00 00 00 00 00 00 00 00 P.Q.............\r\n00 49 4E 49 54 30 30 30 34 43 4F 4D 00 00 00 08 .INIT0004COM....\r\n52 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R...............\r\n\r\n\r\nC:\\Test\\cpmfs>\r\n<\/pre>\n<p><\/code><br \/>\ndrivea.dsk is the original version before we replaced the boot sector. I replaced an existing CDOS disk label and added the DPB byte. I'll cover that next.<\/p>\n<p>You can see the details saved in the DPB byte, those in CDOS disk label and the active content of the disk directory. You can plainly see the two byte block numbers in the second half of each FCB (eg INIT271 COM: 0B 00, 0C 00, 0D 00, 0E 00, 0F 00, 10 00). You can also see the CDOS disk label entry at the start (always at the start if there is one).<\/p>\n<p>The DPB byte is the last byte in the boot sector. This is a CP\/M equivalent of key parts of the CDOS disk label and it is discussed in more detail in the next section.<\/p>\n<h2>Add or Remove a DPB Byte<\/h2>\n<p>There are 12 basic disk types (mentioned and listed above). But, there are choices about how you use those disk types. Some people create \"data disks\". These have an empty system area (reserved tracks = 0) so the data area and directory start at track 0 (the start of the disk image file). When Cromemco and Digital Research both went to 256 x 2KB blocks, they implemented them independently (by the look of it) and certainly differently. Copying files by (virtual) disk from a (virtual) CDOS computer to a (virtual) CP\/M computer doesn't always work (but does sometimes). I'll cover that in a separate article after this one but, in short, the FCBs are slightly different.<\/p>\n<p>For cpmfs I wanted a mechanism where I could store the specific choices that affect the data area: how many reserved tracks, the block size, the FCB type and how many blocks are used by the directory. This would allow those settings to travel with the disk so, if cpmfs sees the disk again later, it knows the right values to use. For you, the user, you can simply use cpmfs to update such a disk without having to tack a series of options on the command line. The intent, with the disk type and the DPB byte at the end of the boot sector, is for you to be able to just use the imagefile name without a [-t type] and without any [opts].<\/p>\n<p>If your disks match the 12 types above and if you use one of the more common data area arrangements, the DPB byte should achieve that intent.<\/p>\n<p>The first bits (most significant) is a zero.<\/p>\n<p>The next three bits are the number of directory blocks. Normal values for this, for a floppy disk, are 1-4. Zero directory blocks gives an unusable disk. 4 x 2K blocks is 256 directory entries, which seems a reasonable maximum for a floppy disk.<\/p>\n<p>The next two bits encode the FCB type. The four values are: 0= 1K blocks, one-byte block numbers; 1= 2K blocks, one-byte block numbers, CP\/M 2K1 FCB; 2= 2K blocks, two-byte block numbers; or 3= 2K blocks, one-byte block numbers, CDOS 2K1 FCB. 0, 1 and 2 are CP\/M formats. 3 is a CDOS-only format. CDOS will work with 0, 2 or 3. Anything other than 0 requires a CDOS label if it is to be used by CDOS. You can't create a CDOS label if the FCB type is 1 (as that is CP\/M-only).<\/p>\n<p>The last two bits (least significant) are the number of reserved tracks. This defines the size of the system area and the start of the data area. It can be any reasonable value (0-3 tracks). The size of the system area was set in CP\/M 1 as 2 tracks for an 8\" (SSSD) disk. That was 2 x 26 sectors x 128 bytes. In order to fit the same amount of operating system on 5\" disks, the rule became 3 tracks (x 18 sectors x 128 bytes). CP\/M 2 was backward compatible with CP\/M 1 disks so it had to fit into the same (8\") two tracks. Double-density shook things up a bit but if track 0 remained SD you always needed at least a second track. Data disks have 0 system tracks so the most common values used are: 0 (data), 2 (8\") or 3 (5\"). A full DD 8\" disk has the equivalent of 64 x 128 bytes on a single track and the entire CP\/M OS would fit in that one track. 0-3 should work for all real world cases.<\/p>\n<p>If the DPB byte is present at the end of the boot sector, and if it is preceded by an E5 byte, and if it is in the range described above (10H-4FH); then cpmfs will use it to set the number of reserved tracks, the number of directory blocks, the block size and the directory (FCB) type.<\/p>\n<p>You can change any of the DPB related values by using the [opts] parameter.<\/p>\n<p>You can re\/write the new settings to the DPB byte by using the command:<code><\/p>\n<pre>\r\ncpmfs [-d dbg] [-t type] imagefile [opts] dpb\r\n<\/pre>\n<p><\/code><br \/>\nHere's a few examples:<code><\/p>\n<pre>\r\nC:\\Test\\cpmfs>cpmfs -t LGDSDD new.dsk init\r\nOK.\r\n\r\nC:\\Test\\cpmfs>cpmfs new.dsk dir2\r\n\r\nBoot Sector\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 4C 47 44 53 44 44 E5 E5 ........LGDSDD..\r\n\r\nDirectory\r\n\r\n\r\nC:\\Test\\cpmfs>cpmfs new.dsk dpb\r\nOK.\r\n\r\nC:\\Test\\cpmfs>cpmfs new.dsk dir2\r\n\r\nBoot Sector\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 4C 47 44 53 44 44 E5 4A ........LGDSDD.J\r\n\r\nDPB\r\nReserved tracks: 2, Block size: 2K, Dir type: 2, Dir blocks: 4\r\n\r\nDirectory\r\n\r\n\r\nC:\\Test\\cpmfs>cpmfs new.dsk -bs 1 -dt 1 -ds 2 dpb\r\nOK.\r\n\r\nC:\\Test\\cpmfs>cpmfs new.dsk dir2\r\n\r\nBoot Sector\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 4C 47 44 53 44 44 E5 22 ........LGDSDD.\"\r\n\r\nDPB\r\nReserved tracks: 2, Block size: 1K, Dir type: 1, Dir blocks: 2\r\n\r\nDirectory\r\n\r\n\r\nC:\\Test\\cpmfs>cpmfs new.dsk -bs 2 -dt 1 -ds 2 dpb\r\nOK.\r\n\r\nC:\\Test\\cpmfs>cpmfs new.dsk dir2\r\n\r\nBoot Sector\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 4C 47 44 53 44 44 E5 26 ........LGDSDD.&\r\n\r\nDPB\r\nReserved tracks: 2, Block size: 2K, Dir type: 1, Dir blocks: 2\r\n\r\nDirectory\r\n\r\n\r\nC:\\Test\\cpmfs>cpmfs new.dsk -bs 2 -dt 2 -ds 2 dpb\r\nOK.\r\n\r\nC:\\Test\\cpmfs>cpmfs new.dsk dir2\r\n\r\nBoot Sector\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 4C 47 44 53 44 44 E5 2A ........LGDSDD.*\r\n\r\nDPB\r\nReserved tracks: 2, Block size: 2K, Dir type: 2, Dir blocks: 2\r\n\r\nDirectory\r\n\r\n\r\nC:\\Test\\cpmfs>cpmfs new.dsk -bs 2 -dt 3 -ds 2 dpb\r\nOK.\r\n\r\nC:\\Test\\cpmfs>cpmfs new.dsk dir2\r\n\r\nBoot Sector\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 4C 47 44 53 44 44 E5 2E ........LGDSDD..\r\n\r\nDPB\r\nReserved tracks: 2, Block size: 2K, Dir type: 3, Dir blocks: 2\r\n\r\nDirectory\r\n\r\n\r\nC:\\Test\\cpmfs>cpmfs new.dsk -rsvd 3 -bs 2 -dt 2 -ds 2 dpb\r\nOK.\r\n\r\nC:\\Test\\cpmfs>cpmfs new.dsk dir2\r\n\r\nBoot Sector\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................\r\nE5 E5 E5 E5 E5 E5 E5 E5 4C 47 44 53 44 44 E5 2B ........LGDSDD.+\r\n\r\nDPB\r\nReserved tracks: 3, Block size: 2K, Dir type: 2, Dir blocks: 2\r\n\r\nDirectory\r\n\r\n\r\nC:\\Test\\cpmfs>\r\n<\/pre>\n<p><\/code><br \/>\nEach single disk type can have any of the 64 possible choices of directory settings. It is hardly surprising that we didn't end up with a workable standard for disk transfers beyond the original 8\" SSSD one (with 1K blocks, single-byte block numbers, 64 directory entries and 2 reserved tracks).<\/p>\n<p>In many ways, the DPB byte, in the last byte in the boot sector, is a CP\/M equivalent of key parts of the CDOS disk label. The byte is used by cpmfs and could be used by a CP\/M BIOS to automatically configure its internal DPB settings to match those of the disk currently in the drive.<\/p>\n<p>To remove the DPB byte use:<code><\/p>\n<pre>\r\ncpmfs [-d dbg] [-t type] imagefile [opts] rmdpb\r\n<\/pre>\n<p><\/code><\/p>\n<h2>Adjust Options to Match the Disk You Have<\/h2>\n<p>If your disk isn't one of the 12 standard ones you can use:<code><\/p>\n<pre>\r\ncpmfs [-d dbg] [-t type] imagefile [opts] cmd ...\r\nopts are one or more of:\r\n-tks num              : disk size in tracks\r\n-spt num              : sectors per track\r\n-siz bytes            : sector size in bytes (eg 128 or 512)\r\n-rsvd tracks          : system area in tracks\r\n-sk num               : skew factor\r\n-bs num               : block size in KB (1\/2\/4)\r\n-ds blocks            : dir size in blocks (1-8)\r\n-dt num               : directory type 1, 2 or 3(CDOS 2K 1byte)\r\n-spt0 num             : as above, for track 0\r\n-siz0 bytes           : as above, for track 0\r\n<\/pre>\n<p><\/code><br \/>\n-tks, -spt, -siz, -spt0 and -siz0 are related to adjusting the disk geometry.<br \/>\n-rsvd, -bs, -ds and -dt relate to the directory settings (see DPB heading above).<\/p>\n<p>-sk is the skew factor used by CP\/M (and CDOS) disks. The idea is to NOT read sectors sequentially so you have time to process the sector you just read, before the next one you need moves under the disk head. A skew factor of 0 or 1 is read the next sector. A skew factor of 2 gets every second sector. A skew factor of 3 gives every third. You'll see the simulated computer read sectors 1, 3, 5, 9, etc; or 1, 4, 7, 10, etc. Again, every manufacturer is different. Again, CP\/M allows you to pick any value so an image from a real machine of the era could have any value. I have used values that CDOS uses as these will have been optimised for reasonably typical and widely used hardware. If files have fragments from other files in them, or if the order seems to jump around within files; and if the directory settings are right, adjust the skew factor.<\/p>\n<p>If you look into the disk image with a hex viewer, you may be able to spot the skew factor the image is actually using. If the disk is single density and the first chunk of a file is 80H at 3400H and the next chunk is 300H after that, the skew factor is probably 6 (300H\/80H). For double-density, the sectors are 200H long so you're interested in how many 200Hs are skipped before the next part of the file is found. I hope this helps.<\/p>\n<p>With the \"-sk\" option, cpmfs can use any skew factor and you can create disk images with different skew factors and copy files between them.<\/p>\n<p>The skew factor isn't part of a CP\/M disk parameter block. It is handled externally. I haven't been able to fit skew factor into my DPB byte that can get written to the boot sector so \"-sk\" settings have to be remembered and used every time. This makes having the right default important. If you need to change the default, perhaps by adding a special disk type, you can modify and recompile the cpmfs program. The source code is freely available.<\/p>\n<h2>List the available disk types or that of a given disk image<\/h2>\n<p>The available disk types are:<code><\/p>\n<pre>\r\nC:\\Test\\cpmfs>cpmfs types\r\n\r\nCP\/M File System Utility Ver 2.00\r\nCopyright 2017-2018 Greg Sydney-Smith\r\n\r\nSupported imagefile types are:\r\n\r\nType       : Description\r\n---------------------------------------------------------------\r\nLGSSSD     :  77Tk  26sec128 skew06 1K  64Dir1\r\nLGDSSD     : 154Tk  26sec128 skew06 2K 128Dir1\r\nLGSSDD     :  77Tk  16sec512 skew11 2K 128Dir2 (Tk0  26sec128)\r\nLGDSDD     : 154Tk  16sec512 skew11 2K 256Dir2 (Tk0  26sec128)\r\nSMSSSD     :  40Tk  18sec128 skew05 1K  64Dir1\r\nSMDSSD     :  80Tk  18sec128 skew05 1K  64Dir1\r\nSMSSDD     :  40Tk  10sec512 skew04 1K  64Dir1 (Tk0  18sec128)\r\nSMDSDD     :  80Tk  10sec512 skew04 2K 128Dir1 (Tk0  18sec128)\r\nCLSSSD     :  77Tk  26sec128 skew06 0K Cromix\r\nCLDSSD     : 154Tk  26sec128 skew06 0K Cromix\r\nCLSSDD     :  77Tk  16sec512 skew11 0K Cromix  (Tk0  26sec128)\r\nCLDSDD     : 154Tk  16sec512 skew11 0K Cromix  (Tk0  26sec128)\r\nCSSSSD     :  40Tk  18sec128 skew05 0K Cromix\r\nCSDSSD     :  80Tk  18sec128 skew05 0K Cromix\r\nCSSSDD     :  40Tk  10sec512 skew04 0K Cromix  (Tk0  18sec128)\r\nCSDSDD     :  80Tk  10sec512 skew04 0K Cromix  (Tk0  18sec128)\r\n8_SSSD     :  77Tk  26sec128 skew06 1K  64Dir1\r\n8_DSSD     : 154Tk  26sec128 skew06 2K 128Dir2\r\n8_SSDD     :  77Tk  16sec512 skew11 2K 128Dir2 (Tk0  26sec128)\r\n8_DSDD     : 154Tk  16sec512 skew11 2K 256Dir2 (Tk0  26sec128)\r\n5_SSSD     :  40Tk  18sec128 skew05 1K  64Dir1\r\n5_DSSD     :  80Tk  18sec128 skew05 1K  64Dir1\r\n5_SSDD     :  40Tk  10sec512 skew04 1K  64Dir1 (Tk0  18sec128)\r\n5_DSDD     :  80Tk  10sec512 skew04 2K 128Dir2 (Tk0  18sec128)\r\n8FSSDD     :  77Tk  16sec512 skew11 2K 128Dir2\r\n8FDSDD     : 154Tk  16sec512 skew11 2K 128Dir2\r\n5FSSDD     :  40Tk  10sec512 skew04 2K 128Dir2\r\n5FDSDD     :  80Tk  10sec512 skew04 2K 128Dir2\r\nUM4        : 255Tk 128sec128 skew00 2K 256Dir2\r\n\r\nUse \"cpmfs -t (type) info\" for more detail.\r\n\r\nC:\\Test\\cpmfs>\r\n<\/pre>\n<p><\/code><br \/>\nYou can see 8 of the standard 12 at the top of the list.<\/p>\n<p>After that is the same 8 but with a Cromix ID in the boot sector. You can't read or write files from or to Cromix disks with a CP\/M File System program (such as cpmfs) because the Cromix file system is very different. However, you can use cpmfs to create disks that can be used by Cromix. You just use a Cromix type with \"cpmfs -t type diskimage init\". There is something very nice about being in Cromix and being able to mount more disk space.<\/p>\n<p>After the Cromix types are the same basic 8 again, but these have purely CP\/M FCB Directory settings. Most are identical to the earlier ones. The exceptions are the largest SMall disk and, aside from SSSD which is common to CP\/M and CDOS, the smallest LarGe disk. Those (SMDSDD and LGDSSD) are the only two disk types that the different choices by Cromemco and Digital Research affect. Both are 2K blocks and one-byte block numbers but the FCBs used are slightly different. If you're only using CP\/M and never CDOS, you may just opt to use the \"8_\" and \"5_\" disk types instead of the \"LG\" and \"SM\" ones and never have to remember the differences.<\/p>\n<p>For me, I just use the Cromemco type names and \"-dt 1\" if I want to make it a CP\/M one-byte FCB or \"-dt 2\" to make any of them use the compatible two-byte FCB.<\/p>\n<p>The next 4 disk types listed are the remaining of the 12 basic types. None of these should work in a real CDOS system so all of them use CP\/M FCB styles.<\/p>\n<p>The last one is for a disk I found in Udo's collection. He'd created a very large format for use in z80sim. It'd never work in the real world as a real world floppy (who can fold a 10\" or 15\" disk to fit inside an 8\" drive?); but it's very useful in modern times with emulators. For my convenience mainly, I just tacked that on to the end of the list. If you have other disk types like that, you can do the same and recompile cpmfs to include them.<\/p>\n<p>The startup code in cpmfs looks at the first 128 bytes of the disk image for a known disk type (one of the up-to-6-byte strings listed above: LGSSSD, ...) and, if the image is the right size for that type, it uses that type. The size check is to guard against disks that were SYSGENned from a different type without the boot sector having been corrected (see <a href=\"http:\/\/www.sydneysmith.com\/wordpress\/2239\/is-cp-m-sysgen-safe\/\">Is CP\/M SYSGEN safe?<\/a>).<\/p>\n<p>If the boot sector doesn't have a recognised disk type name in bytes 120-125, it picks the first one in the list that has the right size. If you want it pick something else, just use \"-t type\" with one of the other disk type names.<\/p>\n<p>If you want to see more detail about one of the disk types you can do something like:<code><\/p>\n<pre>\r\nC:\\Test\\cpmfs>cpmfs -t SMDSDD info\r\n\r\nName              : SMDSDD\r\nDescription       :  80Tk  10sec512 skew04 2K 128Dir1 (Tk0  18sec128)\r\nImage size        :  3178 records (406784 bytes)\r\nSystem area size  :    58 records\r\nData area size    :  3120 records (390K)\r\nBlock size        :    16 records (2K)\r\nDir size          :    32 records (128 entries, 2 blocks)\r\nDir type          :     3 (CDOS 8x 1 byte block numbers)\r\nTracks            :    80\r\nReserved tracks   :     2\r\nTrack 0           :    18 sectors x 128 bytes\r\nTrack 1...        :    10 sectors x 512 bytes\r\nSkew factor       : 4\r\nSkew table        :  1, 5, 9, 3, 7, 2, 6,10, 4, 8\r\n\r\nC:\\Test\\cpmfs>\r\n<\/pre>\n<p><\/code><br \/>\nHere you can see that it has 2K blocks, a CDOS-only directory type and a skew factor of 4; amongst other things.<\/p>\n<p>You can also use \"info\" with just a disk image name to see what cpmfs will use for that image. An example of that is:<code><\/p>\n<pre>\r\nC:\\Test\\cpmfs>cpmfs drivea.dsk info\r\n\r\nName              : LGDSDD\r\nDescription       : 154Tk  16sec512 skew11 2K 256Dir2 (Tk0  26sec128)\r\nImage size        :  9818 records (1256704 bytes)\r\nSystem area size  :    90 records\r\nData area size    :  9728 records (1216K)\r\nBlock size        :    16 records (2K)\r\nDir size          :    64 records (256 entries, 4 blocks)\r\nDir type          :     2 (2 byte block numbers)\r\nTracks            :   154\r\nReserved tracks   :     2\r\nTrack 0           :    26 sectors x 128 bytes\r\nTrack 1...        :    16 sectors x 512 bytes\r\nSkew factor       : 11\r\nSkew table        :  1,12, 7, 2,13, 8, 3,14, 9, 4,15,10, 5,16,11, 6\r\n\r\nC:\\Test\\cpmfs>\r\n<\/pre>\n<p><\/code><br \/>\nIf the image has a DPB byte and if you include any of the \"[opts]\", they will be included in the info display.<\/p>\n<h2>Check a disk image for free space or cross linked files<\/h2>\n<p><code><\/p>\n<pre>\r\nC:\\Test\\cpmfs>cpmfs drivea.dsk used\r\n\r\nBlocks in use:\r\nXXXX111111111111\r\n1111111111111111\r\n1111111111111111\r\n1111111111111111\r\n1111111111111111\r\n1110000000000000\r\n0000000000000000\r\n0000000000000000\r\n0000000000000000\r\n...\r\n0000000000000000\r\n\r\n83 of 608 blocks used\r\nOK.\r\n\r\nC:\\Test\\cpmfs>\r\n<\/pre>\n<p><\/code><br \/>\nYou can see how much space has been used and easily determine how much is left. Allocated blocks show as \"1\". Unallocated, as \"0\". Cross linked ones show as \"X\".<\/p>\n<p>The CDOS disk label assigns directory blocks to the FCB for the label. If you have a CDOS label on the disk, the directory blocks at the start will show up as being cross-linked (in this case in the directory and in a \"file\"). <\/p>\n<p>If you see an \"X\" other than at the start then you have a problem with the disk. Use \"DIR2\" to look at the directory in more detail and see which files are cross-linked. The CDOS version of STAT will also list any cross-linked files; provided the disk image isn't a CP\/M-only FCB type. The CP\/M 2.2 STAT doesn't include the same feature.<\/p>\n<h2>Where do I get it?<\/h2>\n<p>The windows executable is available from the cpmfs product page (<a href=\"http:\/\/www.sydneysmith.com\/wordpress\/cpmfs\/\">cpmfs<\/a>).<br \/>\nThe source code and build file are in <a href=\"http:\/\/www.sydneysmith.com\/products\/cpm\/cpmfs\/cpmfs-2.00.zip\">cpm\/cpmfs\/cpmfs-2.00.zip<\/a>.<\/p>\n<h2>More Information<\/h2>\n<p>This is part of the <a href=\"http:\/\/www.sydneysmith.com\/wordpress\/cpm-programs\/\">CP\/M Topic<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Version 2.00 of cpmfs has just been released, and it&#8217;s pretty good even if I do say so myself. Cpmfs is a tool that allows you to copy files to and from CP\/M disk images. It runs on Windows (but should easily port to linux) so you can set up disks for an old Operating &hellip; <a href=\"https:\/\/www.sydneysmith.com\/wordpress\/2251\/cpmfs-2-00\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">cpmfs 2.00<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[16,59],"tags":[75],"_links":{"self":[{"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/posts\/2251"}],"collection":[{"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/comments?post=2251"}],"version-history":[{"count":7,"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/posts\/2251\/revisions"}],"predecessor-version":[{"id":2259,"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/posts\/2251\/revisions\/2259"}],"wp:attachment":[{"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/media?parent=2251"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/categories?post=2251"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/tags?post=2251"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}