E01 vs E01S
First, the disclaimer...
I have an idea, I have an SD card. I have a soldering iron. What I don't have, unfortunately, is a copy of the E01S firmware source code.
The realisation of this project DEPENDS upon my successfully obtaining the source code, for I simply do not have the time (nor the expertise in 6502 code) to wade through a ROM dump and go from that.
Therefore, if you have the firmware sources (or know who does), please get in touch!
The first question anybody is likely to ask is, indeed, "why?". I mean, we are talking about melding modern technology into something that is two decades old and barely even used any more.
The funny irony here is that that is exactly why I want to do this. Those who are still using their FileStores, who still run a network of BBSs and Masters, they are all starting to crash into one insurmountable obstacle.
Harddiscs do not last forever.
Doubly so when we also consider that:
- The FileStore appears to be hardwired to communicate with a very specific type of Rodime drive (either a 20Mb version or a 40Mb version).
- Even worse, the drive has to be initialised in a specific Acorn way. I guess this was to prevent people doing DIY upgrades when they could pay Acorn a pretty penny for a harddisc in a fancy box? Somewhere I have a correct Rodime drive taken out of an old Apple Mac, but it's write-once internal controller page contains something other than "(c)Acorn" and, hence, the FileStore just doesn't want to know.
- We're talking MEGABYTES. 20 and 40 MEGABYTES, that's less than any normal person has on their video cards these days, and hence finding devices this puny is increasingly difficult. Especially considering our range has been effectivelly narrowed to two drives that aren't in production and a company no longer making the required hardware.
These problems are fairly insurmountable. If the drive you source is second-hand, it probably won't work. If you manage to get an unused one, good luck playing with the FileStore formatter tools. I bet Acorn had a SCSI interface hanging off the back of a Master, it'd be a hell of a lot easier than the manager's tools...
This leads us to a rather obvious conclusion. We need to rejig the system so that it can talk to more modern equipment. And we need it to be extremely simple in implementation.
The first solution
Upon receipt of the firmware source code, my first task will be to remove ALL dependency on the specific drive/markers that the FileStore is expecting. The maximum size of a SIN address is 4Gb, and the offsets/calculations are 24 bit thus meaning any single file is limited to 16Mb.
I do not - at current - know if it will be possible to use, say, a 1Gb SCSI harddisc; or if other factors prevent that. I have a 220Mb disc (rescued from my MDFS (if it still works?!)) which I will use to test. If/when it works, consider this release one.
[if you try sticking a huge disc in, it is likely to be hardwired to only 'see' what it can cope with]
The second solution
Once larger (and more recent) SCSI drives are working, it will be time to move on to the final solution. There are many ideas kicking around. Implementation of IDE, for example, as most of the affordable modern drives (and bucket loads of 'recycled' units) are IDE. IDE is so simple it is almost braindead, which is why practically every PC on the planet has onboard IDE.
But we are falling into a dangerous trap here. Sure, we could try to hobble the SCSI interface into some sort of 8 bit PIO version of IDE, but we are still placing a big dependency on ourselves - namely that orgasmic 300Gb harddiscs will never work in a FileStore. EVER. The sort of technology we could patch into our lovely 6502-based machine is, well, dead. Obsolete. I've given up trying to find a tiny (2.5") IDE drive for my old laptop. It has a dying 6Gb drive. I don't know if the BIOS can cope with anything over 8Gb and I just can't find anything that small. Our FileStore? Wants something smaller yet.
There is an answer, but one with a complication. The answer is the SD card. A year ago I had none. Now I have a 3mpix digital camera and a Creative Zen media player, I have a number of SD cards. Looking around, they seem to be the format of choice for lower-end consumer equipment. While they have maxed out at 2Gb (larger sizes require "SDHC"), that's still a fair whack. You ought to be able to source 1Gb for about €7 in a supermarket.
SD cards are funny little critters. They speak three languages. But for our purposes we shall be using the "SPI" protocol - a technical oddity in that all SD cards (and a lot of other stuff) speak it, but it hasn't ever been formalised. It is a simple protocol, but sufficient for our purposes.
The complications? SD cards clock at between 100kHz and 400kHz (in SPI mode). As we will be running the clock off a 6522 pin, maintaining 100kHz on a 2MHz machine means we have a mere 20 cycles between clock transitions. If we are to run slower, it may require a more tolerant SD card? I have not made any tests of this, but I do wish to point out during development of my IIC interface code for the parallel port in C on DOS, I ran the program in TurboC's debugger and single-stepped it manually while metering. The IIC bus, that was expecting a delay of 4.7µS between clock transitions actually worked with delays of seconds in between transitions. So with a big of luck (or flexible design parameters), a SD card will be able to run at the speed we want it to run; which, let's face it, is not going to over-clock the thing!
The second complication is that SD cards run at 3.3V, while the FileStore runs at 5V.
Above is a hastily scrawled diagram of an SD interface. As you can see, it is pretty simple. Six resistors (three 1.8K and three 3.3K), one capacitor (100µF), and a 3.3V regulator. The actual connection to the SD card is left up to you, but I advise you to find some sort of connector (perhaps a cobbled IDE edge connector?) because soldering onto the card is just asking for trouble.
The arrangement with the resistors is to create a simple potential divider to drop the 5V coming out of the 6522 to something suitable for the SD card. These values should provide just over 3V. In reverse it is simpler, for the 6522 is reasonably flexible in its inputs. The NMOS datasheet specifies that a 'high' is 2.4V or over. I don't have a CMOS datasheet to hand, however I am fairly confident that 3.3V will be sufficient.
As an alternative, MMC cards may be used. Identical wiring, only the two outer "non-connect" pads are not present on MMC cards.
I plan to remove all code to drive the SCSI interface, and where data is read from or written to the harddisc, instead SD card routines will be called instead. The card's block size is 512 bytes, which should be common with harddiscs. We'll see when we get that far. In any case, it is intended to simply and completely replace the SCSI system with an SD card.
For those who would like to copy their FileStore's SCSI drive onto the SD card, you will need to do it through an intermediary. That said, you DO back up the FileStore, don't you?
The printer port
The header for the printer cable is going to be appropriated for use by the SD interface, therefore printing via the FileStore will no longer be a possibility. As a result of this, all printer-specific code will be removed and if there is sufficient space, routines will be inserted to permit the easy formatting of SD cards to something the FileStore can work with.
Note that SD cards will be formatted to be FileStore specific. There is no intention whatsoever of retaining FAT compatibility or an 'image' file within a FAT filesystem. Both of these are possible, but would just be wasting valuable resources within the FileStore.
There are many little challenges to overcome along the way - device sizes, speeds, block sizes... however it is my intention to replace this document with full implementation details as soon as possible.
However, please note once again, that this relies on access to the FileStore source code.
Miscellaneous implementation notes
In no specific order:
- The data transfer is a clocked serial system that is peripherally similar to I²C.
- There is an internal register called "OCR" which specifies the correct voltage for powering the card, however there is the obvious problem that you need to already know the voltage in order to communicate with the card. It is fairly standard that 3.3V will work. Don't even try 5V...
- We need to be able to allow for a loading of around 50mA. This might be an issue on a tiny media device running off two AAAs, but for us - hacking into a 'traditional' 8 bit computer design, a hundred milliamps is probably nothing compared to formatting a floppy disc. ☺
- In order to work well with both SD and MMC (as an option), we should be using SPI mode 0, which is when registers "CPHA" and "CPOL" are both set to zero.
- For reference, the only 'valid' SD filesystem is FAT12 or FAT16. But since we are not interested in compatibility with anything, this can be ignored! [ps: SDHC over 4Gb uses FAT32]
- The data is bytewise serial. The command 'frame' to the card is six bytes. Once a command is sent, a response will be sent back from the card. As this is under the clocking of the host (i.e. us), we need to read back bytes until we have a response. For SD cards, the responses vary from zero to eight bytes; for MMC the responses vary from one to eight bytes.
There are three possible response types, which depend upon the command sent to the card. For most commands, a byte is returned which is a bitfield, with a zero value meaning the command was successful.
- During a communication (all parts), the CS line must be held low. Think of this as (not)"Chip Select" like on other parts of the 65xx chipset...
- When reading, the DI line must be high.
- If a command "takes longer", a busy status will be returned. We should wait for a 0xFF response to mean completed; however it appears that D0 is also held low (by the card) while internal processes are in action, so we could try polling this input instead of reading waiting for completion.
(though, in honesty, I think this is for high speed communications while writing data; I do not imagine our implementation will come across this... for if an SD card is slower than a 2MHz machine, imagine writing a series of 5Mb images from a digital camera!)
- CRC is optional in SPI, however its contents (even if bogus) are a required part of the command frame.
- When powered up (or reset?), the cards enter native mode. To switch to SPI mode, we must:
- After power has stabilised, we must wait a millisecond or two. This is of little relevance in power-up but should be taken into account for card reset if we have a reason to reset... (exiting Maintenance Mode?).
- Set CS and DI both high, and clock 80 pulses. The card will be ready to accept commands (in native mode).
- With a clock rate between 100kHz and 400kHz (!), we should send command zero ("CMD0") to the card with CS held low). This specific sequence will instruct the card to switch to SPI mode. The only caveat is that CMD0 is sent as a native command so it must have a valid CRC. I believe the value is 0x95, but I will need to check this.
In SPI mode, CRC is disabled and response is the bitfield byte with idle bit set (0x01).
- This would be a good time to check OCR to ensure the working voltage is correct? Is this necessary? Do ever cards work on 2.5V or something? As the SD card is likely to reside inside the FileStore (no, we won't be supporting hot-swapping!), this check is likely to be skipped.
- We must then send command one (CMD1) and wait until the idle bit is cleared and the response is 0x00. Apparently this can take "several hundred milliseconds", but then I can't imagine an ancient SCSI harddisc was any faster...
SD might work better with "(A)CMD41" instead? It is suggested we think about sending this first, and reverting to CMD1 if it is rejected so to best support a variety of card types.
- Due to our limited memory requirements, it is likely that we will be using single block reading and writing.
- To read...
We set up and send a command seventeen (CMD17). When this is accepted, the block (512 bytes) will be sent back to the host, followed by two CRC bytes.
If there was an error, the error response byte will be returned instead of data.
- To write...
When our write is accepted, via command twenty four (CMD24), we must send a padding byte and then our data to be written, and then two CRC bytes (which are ignored but still should be sent). When writing is in progress (internally), D0 will be held low. A possible optimisation for writing data is to check this before writing, instead of waiting afterwards - for when the data has been sent to the card, we don't care what the card does unless, of course, we have more to write...
- There is no planned support for either multiple cards, or for hot swapping.
- The internal block size of an SD card is considerably larger than 512 bytes. For smaller capacity cards (if you can find them...) you will find internal block sizes of 16K or 32K. For larger cards (say 1Gb upwards), the internal block size can run to 128K or so. To write a single 512 byte sector, the card needs to read the block into internal memory, clear it, then write it back.
I do not know how the FileStore handles disc writes internally. If we work a sector at a time, then we're a bit stuffed in this respect. If, however, there is support for multiple sector writing (even if only for *Load, *Save and OS_GBPB), it is to our benefit to try to take advantage of this.
- A design (on-line, Google it) patching the BBC DFS to use an SD card on the user port claims to have achieved access times of around 10K/sec. At least this means somebody got an SD working on BBC-era hardware, so with a little luck...
- Various reports on-line suggest smaller MMC cards are more responsive than smaller SD cards; and for small amounts of data as might be generated by microcontrollers and such, they are both faster than larger SD cards which are tailored more to vast data transfer (like copying a 450Mb XviD faster than 130K of source files). In our defence, 'fast' is not a word we can apply to the FileStore. ☺
- There appears to be some 'issue' regarding formatting an SD card with a natural block size (I guess they mean LFAU) that is different to the card's internal block size. This may affect our implementation, however given that Acorn's own documentation (E01S brochure) states that one FileStore can adequately serve twenty (yes, only twenty) users, memory is a premium and I intend to use an SD as a direct replacement for a real harddisc and not an image file sitting inside a FAT partition.
Incidentally, this is perhaps why some of you might have noticed that SD cards reformatted under Windows perform less well than they used to. It isn't a trick of your imagination. If you need to format an SD card, use some SD compliant hardware (like a digital camera) and let the card set itself up...