PIC / WD1772 floppy project
Pages: 1 2
William (3140) 14 posts |
Hi, A while ago I created a USB floppy interface using a PIC18F4550 and a 1772 floppy controller chip. Version 1 exposed the 1772 to my PC as a USB serial device giving me full raw control and the ability to read, write and format any sector layout I wanted, including ADFS. Version 2 was a USB mass storage device, which let me read, write and format DOS 720K disks, It seemed to work quite well in Windows, I also found out how to make windows see it as a floppy drive and not a hard drive which was not obvious! I was thinking of altering Version 2 to read 1024 byte sectors for ADFS, I have a couple of questions… Thanks! |
Rick Murray (539) 13851 posts |
Yes, no, maybe.
Yes and no. USB drives present themselves as some sort of mass storage device, with the device itself handling the disc format part of it (this is why USB floppies speak FAT and not whatever the host understands). |
William (3140) 14 posts |
Thanks for giving it a try. USB mass storage devices use SCSI commands, when reading the host requests a sector by its address, its up to the drive to translate the address into actual track and sector numbers and up to the host to interpret the returned sectors as FAT, ADFS or whatever. The problem is that there is no standard way of describing disk layout, so the disk is seen as a big array of sectors and thats it (as you said). I can code my PIC to translate the address however I want, also there is some code to tell the host the sector size and total size if it asks for it, I need to know if RISC OS asks for the sector size. The way Windows determines if a USB mass storage device is a floppy and not a hard drive is by giving SCSI command READ_FORMAT_CAPACITIES (23), if it returns one of the sizes it knows are of a floppy it enumerates it as a floppy drive, it dosent mean that RISC OS does it that way. When RISC OS accesses a HDD it uses 512 byte sectors, but ADFS floppies have 1024 byte sectors. I will get my PI set up again with RISC OS, prehaps tomorrow and see what it does, but I need to buy a different PIC with more ram for the 1024 byte buffer. |
William (3140) 14 posts |
Ive set up my PIC micro to log all SCSI commands over a serial port, it seems that READ_FORMAT_CAPACITIES isn’t asked for by RISC OS, and it dosen’t ask for the size until the icon is clicked. I have been looking at filing systems in particular how SCSI works, I’m guessing it goes Fileswitch > FileCore > SCSIFS > SCSIDriver > SCSISwitch > SCSISoftUSB is this right? or should SCSISoft be in there somewhere? I assume its SCSIFS that actually translates a sector request into a SCSI command. Thanks |
Jeffrey Lee (213) 6048 posts |
I believe the correct structure is Fileswitch > FileCore > SCSIFS > SCSISwitch > SCSISoftUSB > USB modules. SCSISwitch implements the SCSI SWIs and passes them onto the relevant backend, e.g. if you had a RiscPC with a SCSI podule then SCSISwitch would talk to SCSIDriver instead of SCSISoftUSB. And if you had an Iyonix with a podule backplane then you could theoretically have both SCSIDriver and SCSISoftUSB active. SCSIFS is the right place to look for where the SCSI commands are generated. I think it’s currently limited to 512 byte sectors, but other than checking the source for any magic numbers I don’t think it would be too hard to raise the limit. If you’re going to raise it, please try increasing it to 4K so that HDDs with 4K sector size should work :-) https://www.riscosopen.org/forum/forums/11/topics/6714 |
William (3140) 14 posts |
I’ve ironed out a few bugs in my PIC code and managed to get RISC OS to read a DOS floppy, it comes up as FAT32FS. Thanks Rick for your answer before, what you said sounds right, its likely that like SCSIFS dosent accept a floppy layout, I didnt properly understand your answer until I had a look into how RISC OS filings systems work, so sorry if my reply missed your point. Thanks Jeffery for your answer, that made a lot of things clearer for me, although I dont think i have the skills to edit SCSIFS (have major trouble reading other peoples code and am not familiar with C on RISCOS, last time I wrote a module was 20ish years ago and it was in ARM code assembled from BASIC) I’ll have a look at it tho and see if it makes some sense to me. |
Jon Abbott (1421) 2651 posts |
You could write an ADFS Module that talks directly to the 1772 via your PIC and give native floppy support? Alternatively you could take the ADFS Module source and simply change the IOC writes to USB writes or 1772 commands wrapped in SCSIFS calls. |
William (3140) 14 posts |
Thanks Jon, Ive been looking through the source for your brilliant ADFFS, in partitcular the ADFS stub module which is a very easy to understand example of a filecore module. Ive been cross referencing it to the PRMs and its making sense. I noticed that in DiscOp if option bit 5 is set then I use a list of addresses (is that what you call a scatter list?) can this be disabled or must I impliment this? Before I continue with that I was looking at how to use USB, ive found that all USB devices appear as files within DeviceFS but in order to find my device (a CDC virtual serial port) I have to search for my VID/PID, I was looking at Service_USB https://www.riscosopen.org/wiki/documentation/show/Service_USB is this the right way to do it? Rick, I found this https://www.heyrick.co.uk/blog/index.php?diary=20130224 on your site, I’m trying to cross reference it with https://www.riscosopen.org/wiki/documentation/show/USB%20Service%20Call%20Block the offset values seem to be offset by 4, is this because the first 4 bytes are the address of the next block? and should I free each block pointed to by the first word with OS_Module 7? |
Rick Murray (539) 13851 posts |
I don’t know about the offset by four, but yes, you’re supposed to walk the entire list and free the memory claims when you’re done with them… |
Patrick M (2888) 126 posts |
I don’t have anything useful to add, but I just want to say, this is a really cool project. |
William (3140) 14 posts |
Thanks Patrick! This seems to work for enumerating USB devices and saving the blocks for later viewing, does it look correct?
|
Jon Abbott (1421) 2651 posts |
Yes, bit 5 indicates a scatterlist and you need to implement it. If you look in adffs.adfs.discop at Prevent_ScatterList_Adds, this forces the OS to stop adding to the scatterlist. I found them to be a total pain so forced them off when recording floppy access. Essentially they’re an array of < disc address>,< length>. If you hit <=-65536,0 you have to loop back to the start of the array by adding < disc address> to the scatterlist pointer. If you hit >-65536,0 you’ve hit the end of the scatterlist and can exit. Take a look at DiscOp_Read in adffs.adfs.discop within that is _Read_ScatterList which walks the list. |
Colin Ferris (399) 1818 posts |
An interesting project – some were asking if USB floppies could be used with new RISC OS machines. |
Steve Pampling (1551) 8172 posts |
I was thinking that provided the physical parts are readily available then William could actually sell the design via one or two of the RO equipment vendors. |
Chris Evans (457) 1614 posts |
If William would like to contact me at: chris@cjemicros.co.uk I’d be very interested in coming to an arrangement. |
William (3140) 14 posts |
Its just a hobby project I’m messing about with really, I’m not looking to sell it, but I’ll share all my findings, PCB (although much of it currently on stripboard) and PIC code to anyone that wants it. I would love to see a product and see that its helping others though. My PIC code is heavily based on sample code from Microchip so don’t know how that affects things. And of course I’m using a real 1772 chip which are rare now. Although I have found an FPGA implementation online. And lastly my code may have bugs that I’ve not found and wouldn’t want to be responsible for someone corrupting a disc that’s irreplaceable. |
William (3140) 14 posts |
Whats the best way to do bulk input on USB? Ive been looking through the forum and there are several topics on it. I have written a test program to set nopad and noblock and use OS_GBPB then wait for completion with a loop, this seems to work (a) for multitasking and (b) for unknown input size. I have also seen talk of using UpCall, can/should this be used instead? Or is there another way that Ive missed? I was hoping for some sort of event or callback on completion of a read so I don’t have to poll. |
Rick Murray (539) 13851 posts |
That’s how most of my stuff starts.
Nor was I, but the thing I’ve been working on seems to have an application, and if Chris can make a product out of it, then everybody benefits. Think of it like this – you design the product, somebody else makes it, and there’s a real ADFS compatible 1772-based floppy disc reader available for everybody to purchase. More accessible than “an idea to build” which will likely put a lot of people off right away.
Firstly, is there any licence for the sample code. Secondly, once you know what it is doing, can you not rewrite it to be more specific to your needs? I don’t know about you, but I often find sample code is a sort of jack of all trades; and once you get what it is doing, most of it can be dumped to let you refine the bits that you actually want.
I’ll bet Chris has ’em in stock. ;-)
Then wider testing can help there – especially behaviour with corrupt/damaged discs (because in this day and age I’m sure they’ll turn up).
That’s what the write protect tab is for. If the tab is in read only mode, and your software takes note of this, there will be no problem. If the user decides to write to an irreplaceable disc without first taking a copy of the data, well, that’s on them, isn’t it. It’s like “Which device do you want to write this SD image to?”, and you really better be sure the Pi’s SD card is inserted, not the one with all of yesterday’s irreplaceable wedding photos.
There is apparently some sort of event (upcall?) when a buffer crosses a threshold. I never ever got that to work, so my MIDI module just runs in a polling loop off of TickerV (it runs as a module so it is unaffected by what task is running, or even if the desktop is active). Not ideal, but it works. There are also some devices (non bulk storage) that work by repeatedly checking the extent of the input endpoint file, and if the extent is non-zero, there’s data. I had a USB joystick that worked like this. Unfortunately MIDI doesn’t work like this, and it seems that there’s a lot of zero padding happening in MIDI data (regardless of whether or not I specify nopad). Thankfully, MIDI transfers are four bytes starting with a non-zero byte, so I can just ignore zeroes until I encounter a non-zero, then that and the following three bytes are a MIDI packet. |
Steve Pampling (1551) 8172 posts |
And of course I’m using a real 1772 chip which are rare now. Later controllers? WD2791 – wd2797 Interestingly (or not) a google query with wd2791 alone threw up a set of links about dresses, which apparently have a stock code of … |
William (3140) 14 posts |
Do I still need to preserve flags in my DiscOp and MiscOp routines? (on a 32 bit system). |
Jon Abbott (1421) 2651 posts |
You don’t need to preserve flags in DiscOp or MiscOp. |
Timo Hartong (2813) 204 posts |
To add a little bit to this discussion the USB floppy drives you sometimes see for sale will ( most likely ) have a problem with the 800K format. ( See USB Mass Storage Class – UFI Command Specification – http://www.usb.org/developers/docs/devclass_docs/usbmass-ufi10.pdf ) which seems to state that the only mediums are supported are : |
Dave Higton (1515) 3534 posts |
One very important matter is the sector numbering – does it start from 0 or 1? I know this has been identified in the past as a problem. (And I don’t know which is which, though some reading of Wikipedia suggests that DOS – and therefore most drive systems out there – start at 1; and IIRC it was pointed out in the past that RISC OS is different, which suggests it may start numbering sectors from 0.) If more than one or two units are to be made, there is a question of availability of the floppy disc controller chips. If they can’t be sourced, it’s non-trivial logic to re-implement in something like an FPGA. |
William (3140) 14 posts |
My off the shelf USB floppy dosent even bring up an icon and Ricks says drive empty, so using one is a non starter. In answer to my own question about preserving flags and doing it in C, I have just bought the DDE from ROOL and it comes with manuals that tell you how to do it, its really simple, just use a veneer. I’ve written a filing system that is starting to work, I’m using a disc image in RAM at the moment for testing, it mounts,reads and shows free ok (free was a pain because it tries to use DiscOp64 which you have to either implement or reject, I didnt even know it exsisted until this happened!) but verify crashes ADFSFiler (*Verify works), ive hacked the ADFSFiler module so it wont crash and its saying bad drive, so just trying to pin that down. Ive still got to get scatter lists implemented on read, ive not done writing yet, when those are done then I can look at actually talking to my board over USB! Edit: Ive just fixed verify, its beacuse my swi handler wasnt preserving r8! |
David Feugey (2125) 2709 posts |
Cool! |
Pages: 1 2