1541IDE8
What is it?
The main idea is connecting an IDE hard disk drive to a Commodore 1541 floppy drive using a simple 8 bits interface. The floppy drive can be used as well, if needed.Related items
To make it easier for some software developers to find my software, I decided to place the links to the various sources on top of this page.But I also decided to stop distributing the newer 1541IDE source files on this page for the simple reason that it is a bit too much work to update them every day. If you want them, just email me.
Assembler
My freeware assembler.
Schematics:
As image
Eagle source
History
In the past, around Christmas 1998, I got interested in connecting an IDE hard disk drive to my C64 in one or another way. The result was an interface of just eight common available cheap ICs, 1541IDE. With some small changes you should be able to connect the interface to any other C= as well.But I soon found out that it was not 1541 compatible enough: too many games and utilities look for various reasons for a real 1541 connected to the IEC-bus. Then already the idea rose to use the interface in a 1541 to decrease the compatibility problem. But being more a hardware then a software guy, I discarded the idea.
In 2006 I decided to pay attention to this idea again. Here I ran into various problems. The first one was that there wasn't a well documented source code of the 1541 file system available. It turned out that I had to create it myself first.
In 1541IDE I wanted to add an IDE hard disk drive by means of one or more extra 6522's for the bit-banging method or by using a real 16 bits interface. And again two, more or less, problems:
- extra 6522's: bit-banging turned out to be too slow to my taste
- 16 bits interface: the needed hardware was more complex then I liked
The most interesting thing of the IDE-hard disk drive is that the command registers are only 8 bits wide. The data register is in fact the only 16 bits wide register. Technically seen there is no objection against only using eight bits of it. Already in 1999 I was thinking about using only an 8-bits interface but wasting half of the capacity of a disk in those days was almost a crime! But because more and more hard disk drives with a capacity of more then 10 GB became obsolete and free to get, I decide to give this idea another try.
Theory
There is no specific knowledge of the IDE-bus needed to understand how my interface works. The IDE-bus is based on the old MFM-, RLL- and ESDI-hard disk drives. The idea rose to integrate the controller on the board in the PC with the onboard controller of the hard disk drive and to attach the resulting board to the hard disk drive. The only signals needed for the resulting board would be the same signals as those after decoding the complete ISA-bus. These signals together form the IDE-bus.The signals we need for our interface are:
- 8 data bits, D0..D7 (D8..D15 are not used)
- 3 address lines, A0..A2
- 1 Register block-select lines: CS0 (CS1 is not used)
- 2 Read/write lines, IOW and IOR
- the Reset line
Remark regarding CS0 and CS1: The IDE-HD has two blocks of eight registers each: the "Command Block Registers" and the "Control Block Registers". The first block is chosen by negating CS0, the second by negating CS1. But so far I haven't found any use for CS1 at all.
There is one other line I use but is not needed for the correct working of the interface itself: DASP. The function of this line is to blink a LED when the HD is executing a command or reading/writing data. For me it was quite helpful during debugging.
Some hard disk drives and quite some, if not all, Compact Flash cards are capable of telling the system to use an 8 bits data register. But I haven't found any xx GB hard disk drive yet with this feature and therefore I decided not to pay it any attention yet.
The IDE 8 bits interface
Applying the right value to the address lines A0..2 and negating CS0 choose the correct register within the "Command Block Registers". Reading from or writing to a register is done by negating IOR or IOW, just like an Intel or Zilog IC. But where a 6522 has a PHI2 input for the timing and a R/W input for telling whether it is a Read or Write action, an Intel/Zilog IC has a RD and a WR input instead. One of these becoming (L) has the same effect on the IC as PHI2 becoming (H) for a 6522. Further either RD or WR becoming (L) tells the IC what action is needed.The main part of the interface is a 74LS139, dual 2-to-4 demultiplexer. One half is used to generate the needed RD and WR signals out of PHI2, R/W and the chip select signal coming from the onboard 74LS42.
In my original design the other half is used to generate CS0 and CS1 out of address line A3 and again the chip select signal coming from the onboard 74LS42. Not having found any use for CS1, this half can be used for other purposes.
My very first design blew up due to a faulty power supply. It didn't only fry the 1541 board but also a 6.4 GB hard disk drive :( That's why I decide to add two buffers, a 74LS245 for the data and a 74LS244 for the address lines and the reset signal. But I already have plans to build another 1541 with only a 74LS139 just to proof that a single chip interface can work as well.
The schematic can be found here. The Eagle source here. A photo of my self build interface can be found here.
The advantages of an 8 bits interface above the 16 bits one
Only using 8 bits means we are throwing away half of the capacity of a drive. But, as said before, having several x.x Gigabytes drives laying around just doing nothing at all, I thought I could afford it. And for those people who like numbers: an old 1.2 GB disk can store the equivalent of over 3000 1541 floppies, even when only used half.Only using 8 bits also solves the 512-bytes/sector problem. A Commodore floppy sector contains 256 bytes of data, a hard disk drive sector 512 bytes. So two Commodore floppy sectors fit in one hard disk drive sector one would say. But the problem is writing a hard disk drive sector; we have to write 512 bytes to the drive. This means, in order to write a single Commodore floppy sector, we first have to read the according hard disk drive sector to get the 256 bytes of the second Commodore floppy sector. Having read it, we now can write both the old and new Commodore floppy sector to the hard disk drive again. This will cost valuable time: instead of writing one single C= sector we have to read two first and then write two again.
However the main problem is: where to store these extra 256 bytes??? We could reserve another buffer for this purpose but there are circumstances that a program needs all available memory. This program now can run into trouble because we reserved a buffer where this program expected to find a free one. The only solution would be: extra RAM. And that is what I like to avoid for the moment, just to keep things as simple as possible.
Are there any disadvantages by only using 8 bits? Beside the capacity loss I ran into one only: it is possible to extract all kind of information from the drive, for example the number of LBA sectors. The problem is that the info is given in 16 bits format. And as my interface is only able to handle 8 bits.....
File system
Having solved the problem of the hardware, I still stuck with the problem of the file system. Some years ago I already proposed a file system and decided to use it as a base. The main feature of this file system is that it uses four bytes instead of the original two. These original two bytes, also known as link bytes, represent track and sector of the next sector. The four new ones the LBA value of a sector.My first try was a disaster. Instead of beginning from scratch, I decided to work in steps with the original Kernal as base. First step: use images!
Why images? The idea behind this is that I don't have to change any of the routines involving handling the files and sectors.
The idea is to store only D64 images on the hard disk drive. Or better, extended D64 images. As you know, the original 1541 disk has 35 tracks with a number of sectors ranging from 21 down to 17. Some programs enable you to format a disk up to 40 tracks and these extra sectors each contain 17 sectors as well. The original disk contains 683 sectors. Add these extra 85 sectors and you have 768 sectors. Or hexadecimal, $300 sectors. And using the number $300 will simplify calculations.
If this works out fine, the next step is a 1541 with a file system capable of handling 16 Megabyte disks and the ones in the Gigabyte size.
Testing the idea: 1541DC3 (Disk Copy Version 0.3)
Could this idea be tested? The idea rose to write a small ML program that could run on the 1541 and a Basic program that could upload and start it. Starting the ML on the 1541 causes it to create an image of the floppy on the hard disk drive. It only asks for the number of the image. Important: as the PRG has no knowledge of the size of the disk, it is up to the user to check the number!FYI: image 0 starts at sector 1, image 1 at sector 769, image 2 at sector 1537, etc. etc. etc. Sector = (image number - 1) * 768 + 1.
The Basic program in plain text
The sources of the ML part
It takes about 3 minutes to create an image and 4.5 to restore one. If you have a look at the ASM you'll see I only use the original 1541 routines. I'm convinced that things can be speeded up by using self written routines. A friend already suggested reading and storing the raw data. Circumventing the GCR routines one could save the data of one track in just one turn! Creating an image would only be limited by the speed of stepping and settling the head. Very nice idea but outside the scope of this project IMHO.
Only using images: 1541IDEx
Proven that the idea of images worked, the next step was to use the images themselves. The project 1541LPT proofed that the Kernal can rewritten in such a way that, when the data had to be written to the actual floppy drive, it could be rerouted to the LPT port of a PC. And the same for reading data. If it can be done with a LPT port of a PC, then why not with an image on a connected hard disk drive?The first step, 1541IDE1, was replacing all floppy routines by ones addressing the hard disk drive and removing all not needed routines like stepping the head (a short routine only emulates it).
That worked out fine but then I found out that some programs wouldn't cooperate with 1541IDE. In fact they were the same ones that wouldn't cooperate with 1541LPT as well. Generally these are programs that address the floppy hardware directly, like the Final Cartridge III. JiffyDOS (JD) and the Power Cartridge had no problems at all.
The next step, 1541IDE2, was removing all free space between the routines so I was able to create one big block of free space for future use. This worked out fine except that the Power Cartridge didn't accept this change as well. Apparently its speed loader calls some original 1541 routines that now had been moved by me. Again JD had no problems at all.
An IDE interface can support two hard disk drives so it was logical to implement two hard disk drives into the FS. But I soon found out that the FS for the 1541 was nothing more then a quick and dirty hack of the FS for the 4040: too many routines had been left out to be able to rebuild it again. So I thought I could use this misfortune to gain some more ROM and RAM by removing all references to the second drive: 1541IDE3. Unfortunately many versions later I found out that I removed too much, the COPY function didn't work anymore :( I never found out what I removed too much and after hours of debugging I decided too start over again using version 2 as base again.
Only using images: 1541JD1..3
At this point a discussion rose because it became clear that there were more copy tools that wouldn't cooperate with 1541IDE then I expected. Having the self generated sources of JiffyDOS I decided to create a JD compatible version of 1541IDE2. Not completely to my surprise, this worked out fine. But both versions still could only handle one image so it was time to move to version 4 (again): handling multiple images.Multiple images: 1541JD4 / 1541IDE4
My first attempt worked out fine with adding the CP command. With the command 'OPEN 1,8,15,"CP:xxxx":CLOSE 1' I let the drive point to image number xxxx. For JiffyDOS: @CP:xxxx. The number is only limited to the size of the hard disk drive.As said, it worked out fine but I had some trouble to keep track of the various images. So I decided to add a kind of meta-directory. For the moment the first 767 sectors can be filled with the headers of the first 12000 images (4 GB). The command 'LOAD "$$", 8' will show this meta-directory. There is only one problem: JiffyDOS can display the directory on screen without saving its contents in memory. The original Kernal of the C64 and Commodores will store it in memory first. And I have no idea what will happen if the computer tries to 'load' a program, the directory in this case, that is bigger then the memory reserved for BASIC programs.
Subdirectories: 1541JD5 / 1541IDE5
The next step introduces subdirectories. When a directory is 'loaded', the drive is told to start at track 18, sector 1. This info is hard coded. But when listing a subdirectory, the start of it is certainly not to be found at 18/1. My idea is to store this information in variables. After a reset these variables point to 18/1. But when switched to a subdirectory, these variables point to the start of it. The CD (Change Directory) command will take care of updating these variables.Only using track 18 for directories would limit us to only to 2040 entries. For this reason I got rid of reserving track 18 exclusively for directories and enabled 1541IDE to use other tracks as well.
I already mentioned the CP command that enables people to change the partition. I also enabled the MD (Make Directory) to use another partition as subdirectory.
Deleting a directory and its content is possible but only with an empty directory. I don't know yet if it is possible to implement a DOS equivalent of the DELTREE command, simply because I have no idea yet how much ROM and RAM this will cost. At this moment I have only about 150 bytes free in ROM, to less to implement this function IMHO.
16 MB images: 1541JD9
This step involves handling 16 MB images. A 16 MB images is nothing more then a 1541 image but then with 254 tracks and 256 sectors on each track.Why only 254 tracks? Track 0 is reserved in a link for telling the FS that this is the last sector in a row. And I'm not sure about track 255 yet. I noticed on some early attempts to handle a 16 MB image that the system hung on track 255. The value 255 has a special meaning in many variables and I think that some routines mistook the value for an error code or something like that.
You can imagine that the BAM info of this amount of tracks and sectors won't fit in a single sector anymore. It means that we need to reserve much more sectors for the BAM. I also planned not to store the information in the way it is done by the 1541 or other C= drives. Here the BAM is divided in fields and these fields store the bitwise representation of the allocation of sectors plus a number that tells the FS how many sectors are still free. To simplify things I decided not to store this last information at all! The few times I need to know how many free sectors are left on a track, I can calculate this number almost as fast as reading this information from a sector.
To save space I decided to store the BAM on track 0. That the FS doesn't use track 0 doesn't mean we cannot use it! It saved me 32 sectors.
The 1541 has only one BAM sector, stored on track 18, sector 0 (18/0). The 16 MB version needs 32 plus one for storing the disk name. This last one still can be found on 18/0 to remain compatible.
The 1541 reads the BAM once and writes it back to the disk only when needed. The idea was that with the 16 MB version, the 1541 would keep the one on 18/0 in memory and only would read another BAM sector when needed. After having used it and written back to disk when changed, 18/0 would be loaded in memory again. Unfortunately this idea didn't work out for one or another reason. And at the end this misfortune forced me to add another RAM IC to the design.
The Gigabyte File System
The last step is replacing all Track/Sector (TS) links by four byte LBA links. Not working with tracks anymore, I needed another way to tell the system that a sector is the last one in a row. Because only 4 bits of the last byte of the LBA link are used, I decided to use the most significant bit for this feature. If set, this sector is the last one in row. In that case the first byte tells how many bytes of this sector are actually used.One important change is that we now need the first four bytes of a sector for the link to the next sector. I have no idea yet what influence this has on the known file types. So far I can see now it has none, but this opinion can change after some tests.
Because the link has to be expanded to four bytes, we need more room for every directory entry. Instead of eight, we now only have room for seven entries on a sector. Another consequence is that a side-sector can only contain 63 links to the data sectors instead of the original 127.
Using the floppy drive
I already mentioned the idea to combine a floppy drive and a hard disk drive. In the beginning I dropped this idea as I didn't see any advantages, especially because I knew for certain that I would need extra RAM and ROM. Extra RAM to store hard disk drive related parameters and extra ROM to store the new routines. And all this wasn't worth the trouble IMHO.But then I got this idea: the floppy drive could make my 1541IDE 99.99% compatible again! The idea is:
- copy the image to floppy
- switch to "floppy mode"
- do what you have to do
- switch to "hard disk drive mode" again
- copy the contents back to the hard disk drive (if needed).
Unfortunately this trick won't work with floppy disks with special copy protections like using half-tracks. 1541IDE in "floppy mode" can work with these disks but cannot create images of them as the D64 format doesn't store information like half-tracks and extended gaps. Therefore 1541IDE can never reproduce the original disk again.
But to make things clear: AFAIK there is no limitation in handling disks of this kind when in "floppy mode".
The idea was realised by inserting JMP's or JSR's in the original code there where needed. The JMP's and JSR's all point to the extra ROM in the $8000/$BFFF area.
Because we keep the original ROM near to completely intact, as a bonus we can at least use the Power Cartridge again.
The hardware
The IDE interface has been described above already. If you want to use the 16 MB version or want to use the floppy drive as well, extra RAM is needed. The most simple way is to piggyback another 2 KB RAM (6116, 2016 or equivalent) on top of the original one with the exceptions of pin 18 (CS) and 20 (OE). You have to solder these two pins to the same wire that is connected to pin 3 of IC4, a 74LS42. This configuration will let you only use 1 KB of the 2 available in the RAM. Adding an AND gate that combines pin 3 and 4 of IC4 will give the complete 2 KB range.The "floppy version" requires extra ROM. But it depends on the type of 1541 how it is added. I installed 1541IDE in a brown 1541 and a 1541-II.
In the brown 1541 I piggybacked a socket on top of the second RAM and wired it in such a way that it could contain a 27256 EPROM (or equivalent EEPROM). I used the two original 2364 sockets for the IDE interface.
The 1541-II already contains a 27128. Pin 27, needed for address line 14, is connected to pin 28. Unfortunately it is connected to pin 28, not only at the solder side, but at the IC side as well. Now you have two options:
- desolder the original socket and cut both the connections.
- solder another socket on top of the original one but leave pin 27 free.
Now connect pin 27 to address line 14 of the 6502.
Commands
I added several commands to the original ones. For non-JiffyDOS users, these command look like the NEW or VALIDATE command: 'OPEN1,8,15,"command":CLOSE1'. There is one exception: 'LOAD"$$",8'.The commands:
- NCD : formats the complete disk. In reality it clears the image list and only formats the first image.
- $$ : gives you a list of the know images.
- AP:xxx : 'Add Partition' number xxx. Enables you to add previous partitions after having executed the NCD command.
- CP:xxx : 'Change Partition' to number xxx.
- CI:xxx,yyy : 'Copy Image' number xxx to number yyy. Enables you to create back-ups of a partition.
- MD:name : 'Make Directory'
- RD:name : 'Remove Directory'
- CD:name : 'Change Directory'. 'CD:..', parent directory and 'CD:/', root are supported as well.
In case of using the floppy drive as well:
- SF : 'Switch to the Floppy drive'
- SH : 'Switch to the hard disk drive drive'
- CFH:xxx : 'Copy Floppy to hard disk drive' using partition xxx
- CHF:xxx : 'Copy hard disk drive to Floppy' using partition xxx
Copying great amount of data to/from the disk
Being able to handle, let's say, 4.3 GB of data is nice. But how are we going to put this amount of data on the hard disk drive? I have several ideas but the most practical one IMHO is connecting the hard disk drive directly to a PC. Two removable hard disk drive docking stations can do the trick. No further explanation needed I think.But because Linux, Dos or Windows surely won't understand the layout of the disk, we need a program to do the actual copying. Except a test program not realized yet :(
Bugs
Probably a lot, but none I am aware of now :)Having questions or comment? You want more Info?
You can email me here.