Ruud's Commodore Site: The file system for 1541IDE and C64IDE Home Email

The file system for 1541IDE and C64IDE


What is it

I have several projects using a hard disk drive: To be able to make use of a hard disk drive, you need a file system and the appropriate software to handle it. Commodore's original FS is only able to handle up to 16 MB. This is not enough for nowadays hard disk drives that can go up to 500 GB and more !!! So I developed a FS that can handle disks up to 2 TB.

This is a proposal for a file system and some proposals for handling it. The goal is to stay independent of the way how the HD is connected to the system and what kind of system it is.
Personal comment: I favour the system using a 1541-board. So it is possible that the idea is 'coloured' by this favouritism.

The size of a sector

a hard disk drive sector normally contains 512 bytes. Any Commodore drive is used to work with 256 bytes sized sectors (the 1581 uses a trick). Developing a new file system also means writing a new Kernal. Why not writing a Kernal that is able to handle bigger sectors?
The problem is that all existing software is only used to 256 bytes sized sectors. So for example if a program wants to read the data on a sector, it will read 256 bytes and nothing more. So even if we really want it, we have to stick to 256 bytes/sector for the moment.

The boot sector

The only function of the boot sector is to provide the Kernal of the drive with some data. This is necessary as the size of a hard disk drive can vary. The boot sector is located at the very first sector of a drive.
* identifier like "CBM-HD00"                                     8 bytes 
* version like "00.00.01"                                        8 bytes
                 |  |  |---> enhancement
                 |  |------> sub version
                 |---------> main version 

* number of sectors in LBA mode                                  4 bytes
* pointer to the root directory                                  4 bytes
* pointer to the Boot-PRG, all 0 when none. See: Boot-PRG        4 bytes

The BAM table

The BAM table starts at sector 2. The 1541 reserves 4 bytes for every track: one byte is used for the number of free sectors, the other three for marking the used sectors. But using the LBA mode means we don't have tracks anymore. So my idea is to reserve as many bits as needed; one bit for every sector. So no "free sectors" bytes as this number can be calculated anyway.

The Directory

The root directory starts at the first sector after the BAM table. Except this particular sector, I've no plans of dedicating other sectors to directories or files. The reason for this is that in my experience the root directory tends to remain relatively small.

The structure of a directory sector should look like this:
* pointer to next sector                                         4 bytes
* pointer to previous sector                                     4 bytes
* 6 entries of 41 bytes each                                   246 bytes
An entry should look like this:
* file type                                                        1 byte
* 00 = DELeted
* 01 = SEQuential
* 02 = PRoGram
* 03 = USeR
* 04 = RELative
* 05 = DIRectory (1581 compatibility, not used)
* 06 = DIRectory
* 07 = SYStem
* 08 = UEX, User EXtension
* 09 = EXE
* 0A = image (D64, D71, D80, D81, D82 etc.)
* 0B = ICOn
* 0C..0F = future use
The four bits of the highnibble are used as the 1541 uses them:
value:       1                0    
* bit 7: file is closed / not closed
* bit 6: file is locked / not locked 
* bit 5: used by 1541 for ???
* bit 4: used by 1541 for ??? 
File type 7, SYStem, is meant to enable the host (= C64/128, 1541-board) to create a swap file or whatever you want.
File type 8 enables a user to supply a file with its own extension. When listing such a file, the 1541 will send these three chars to the host instead of a predefined one. This feature also enables us to store well known Commodore images on the disk and to mark them as so. This on its turn can be used to let the HD emulate a specific Commodore drive. These three chars themselves can be found a little bit further in the list.
File type 9, EXEcutable: The first two bytes of a PRG describe the loading address. But the 65816 can handle 16 MB ie. needs 3 bytes and the new 65GZ032 even needs four bytes. The idea is to use this file type for these types of PRGs. The first four bytes describe the 32 bits loading address. If the EXE is meant to run on a 65816 equipped machine, the first byte is $00.
* name, 1541-format                                              16 bytes
* pointer to first sector                                         4 bytes
* number of sectors                                               4 bytes 
* entry side-sector-block relative file / icon                    4 bytes
* record length relative file                                     2 bytes 
* user supplied extension / image type                            3 bytes
* date/timestamp, YYYYMMDDHHMISS                                 7 bytes 
                                                              + ---
                                                                 41 bytes
As you can see the four bytes for pointing to the entry of the side-sector-block of a relative file can be used for pointing to an icon. This can be useful in a graphical orientated OS. If the file is not a REL file then these bytes point to the location of the icon file. If not used, they should be zero.
Then what about an icon for a REL file? My proposal: place it in the root and name it "REL.ICO".

Real Time Clock

As you can see, some bytes are reserved for a timestamp. This will only be possible if a Real Time Clock IC is installed in the drive. For the moment I favour the Motorola (or the compatible Dallas) one used in PCs for the simple reason I have quite some lying around, scrapped from old PCs.

The link system

I have chosen for using for the link system as used by Commodore and not for the FAT system as used by PCs. The idea is simple: the first four bytes of a sector are reserved for pointing to the next sector in the link. An extra addition to the original system is that next four bytes point to the previous sector. This doesn't only come in handy when searching backwards, but also gives one an extra mean of restoring links after a crash. The remaining 248 bytes are data.

The reasons for choosing the link system above the FAT system:
  • The link system is more robust. If you loose a FAT sector, you can loose a lot of files. MS-DOS has good reasons for maintaining a copy of the FAT table on every disk.
  • The link system is faster when loading a file. With FAT I have to read the FAT table every time to find out where to find the next sector. In case of a heavily fragmented file, I have to read a different FAT sector for every sector I want to load.
  • The FAT system isn't able to track a file backwards.
  • Last, but not least: sentimental reasons :)
A pessimist could say that link system needs more disk space. It does indeed: the room taken for the BAM tables to be precise. But if we would omit the pointers to the previous sector, the link system would be the big winner!


The idea behind supporting images is to remain as compatible as possible to the original Commodore drives. At least we should support D64 and D71 images but IMHO it should also be possible to support D81 (1581), D80 (8050), D82 (8250), D40 (3040) and D16/CMD in the future. The D16-image is "my own" invention and can be seen as a 1541-alike floppy with 255 tracks with each 256 sectors. As the original BAM is not big enough, it has one of his own. To remain a little bit compatible with the 1541, track 18/sector 1 is reserved for the directory but from then on the system is free to use any free sector. Of course D16 supports subdirectories but not like the 1581 does. A subdirectory is an ordinary file but its contents happen to have the same structure as a directory.
Somebody told me that this is exactly as how CMD does it on their hard disk drives. Once I know more about how a CMD partition looks like, I could use that instead of my own D16-image.

How do we store images? Storing the contents of the file as regular data means splitting the original sectors inside the image as we can only store 248 bytes in a regular sector. My idea is to store an image as one unfragmented file with _NO_ link-bytes. The directory tells us where to find the first sector. A "simple" calculation should tell us where to find any desired track/sector within the image.
I can imagine that creating a 16 MB sized D16/CMD image on a hard disk drive already in use for some time, can cause problems. This simply means we have to provide tools to defragment a hard disk drive.

To be able to handle an images the same commands as known by the original system must be implemented, if possible, or adapted to the HD. Example: Commands regarding the MFM mode of the 1571 are in fact impossible on a 1541-board and have to be "translated" or neglected.
Remark: I have no idea yet how to handle CP/M floppies. But I fear that it will cost a lot of ROM due to the number of formats. Don't forget, the ROM of a 1571 is 32 KB !!!

To be able to handle subdirectories and other HD related matters, I propose to add some commands:
command  :              ab.:    function:
CHANGEDIR:directory     CD      change directory
DEFRAG                  DF      defragments the drive.
DELETE:name             DEL     same as SCRATCH
DELTREE:directory       DT      like the MS-DOS command 'deltree': deletes
                                complete directory incl. subdirectories
FORMAT                  FO      format hard disk drive
HIDE:name               HI      makes a file invisible for listings 
LOCK                    LO      locks a file
MAKEDIR                 MD      make subdirectory
REMOVEDIR               RD      remove empty (!) directory
SETTIME                 ST      set the time/date of the internal RTC
START                   SA      start hard disk drive
STOP                    SO      stop hard disk drive
TIMEDATE                TD      supplies date and time to host through the
                                error message: "0, 2005-02-27 15:23:13, 0, 0"
UNHIDE:name             UH      makes file visible again
UNLOCK:name             UL      unlocks a file
XCOPY:new=old           XC      like MS-DOS command 'xcopy': copies complete
                                directories and subdirectories

The boot program

The old 1540 and early 1541 had a way to load and execute a program by manipulating the data and CLOCK line of the IEC bus. You can see this as executing the &-command immediately after a Reset. The 4 bytes in the very first sector can point to such an & file. If not used they are $00.

I'm thinking of using this feature to enable one to make patches to the original Kernal by loading software in the extra RAM and changing the RAM vectors. To avoid the problem that the drive keeps loading a faulty patch after every reset, the pointer in the boot sector is cleared after loading the software.

Having questions or comment? You want more information?
You can email me here.