davidgiven / fluxengine

PSOC5 floppy disk imaging interface
MIT License
357 stars 69 forks source link

Drive selection logic is wired up backwards (for setups using a single-drive FDD cable) #20

Open jgottula opened 5 years ago

jgottula commented 5 years ago

My brother @bgottula and I have been working through a bunch of our grandmother's old writings recently, many of which were preserved on ancient 120K Brother WP floppies. We decided to give FluxEngine a try before spending $100 on a KryoFlux or SuperCard Pro, and in a surprisingly short amount of time this weekend we managed to make loads of progress, with lots of success!

We did run into one fairly major issue while getting things set up, though. Any client operation that involved an actual drive command would do nothing, and then around 3 seconds later, the client program would exit with a libusb error message indicating device removal.

I was able to trace this behavior back to the watchdog timer expiring, which would cause the microcontroller to reboot, and therefore trigger a USB device removal and re-enumeration.

Using the debugger on the firmware, along with some multimeter probing of pins and trial-and-error modifications of things, I ultimately found that the firmware was getting stuck waiting for the drive to do stuff (e.g. waiting for the index interrupt after ostensibly starting the spindle motor), and the reason why the drive wasn't doing stuff is that the drive select and motor enable lines were being operated inversely from how they ought to have been.

In the PSoC Creator schematic, there's a demux coming off of MOTOR_REG, controlled by DRIVE_REG. The pair of NOT gates on the demux's output lines could be removed to fix things up.

(The hack I actually did, which was slightly different, but which ought to be equivalent, and which was still effective at making the firmware behave properly, was to shove a new NOT gate in between DRIVE_REG and the demux control line input. But that's a bit silly and sloppy.) demux_inverter

Bear in mind that we were working with just a single-FDC-connector cable and an individual drive, so I wouldn't be able to tell you if our fix breaks something for dual-drive setups. But it at least appears to be a pretty straightforward drive-selection-being-wired-up-backwards situation.

davidgiven commented 5 years ago

You built the hardware and it works? That's amaz... er, of course it works. cough

Anyway, thanks for trying it, and I'm glad it works! It's entirely possible the drive selection logic is wired up backwards, but floppy drive wiring's not quite that simple. You say you're using a cable rather than plugging the FluxEngine into the back of the drive; could you send me a picture of it, please?

I should probably also have some better error handling instead of just letting the watchdog timer reboot the board, too.

davidgiven commented 5 years ago

PS. If you have any disks which are giving bad reads, let me know (and potentially send me the flux files)? It should be pretty solid by now but there are probably still a few bugs to shake out. Also, I'm trying to collect data on the famous Brother misaligned drive issue. I've got a couple of images that could show symptoms and I'm trying to figure out how to positively identify them.

Also, on a semi-unrelated note, if you happen to have any Brother program disks --- containing software, not documents --- I would love to have copies of images. They're like hen's teeth these days.

bgottula commented 5 years ago

Hi @davidgiven,

First thanks for doing this project and making it freely available! I was totally surprised by our luck to find a project that is under active development, open source, cheap, has support for the exact arcane Brother word processor disk format we needed to decode, and gave us results within a few hours. You definitely saved us a lot of work, and what we recovered is meaningful.

Anyhow, here are photos of the way we wired things up, let me know if what you need to see isn't visible: https://photos.app.goo.gl/6mRxGKj4Zh9SwiGE8

We tried to wire it up pretty close to how you described in your documentation. Now that I'm thinking about this again, perhaps the disk select issue we ran into is because we used a floppy cable with the twist, since that would clearly map those pins differently than when you connected the board directly to the back of the floppy drive connector with no ribbon cable?

With regard to disks with bad reads, we did have some of those. The disks that were 2DD media all read perfectly, but all of the 2HD disks had issues. We suspect the issues with the 2HD disks may have more to do with magnetic coating incompatibility rather than alignment, since all of the 2DD disks written by the same WP-1 worked just fine. Let me check with family first before I promise flux files for those.

Unfortunately we don't have any Brother program disks. We have one that was a program disk but was overwritten with other data. :/

davidgiven commented 5 years ago

Okay, I know what's going on here: floppy disk cables typically have three connectors. One end for the motherboard, and then two FDD connectors each side of the twist. The one after the twist is drive A. The one before the twist is drive B.

However, FluxEngine considers drive B to be drive 0, and drive A to be drive 1. This is so that it can be plugged straight into the back of a floppy drive and work as drive 0.

So what I'd suggest is: either plug the drive into the other FDD connector (if your cable has one, some don't) or use -s :d=1 on the commend line to specify that you want to read from drive 1 (== A). Or, you know, just change the schematic the way you've done; that works fine too. I'm not sure of any way to resolve this which doesn't involve inconveniencing somebody, but it totally needs better documentation --- I'll get onto that.

Re HD disks: yeah, they may have degraded due to being incompatible media. I've heard differing reports of the success of using an HD disk with DD data. I'll add something to the Brother documentation about that.

Re program disks: figures... everyone did that, which is why they're so hard to find!

davidgiven commented 5 years ago

PS. I'm glad it's working for you --- there's been loads of interest in the Brother decode, by the way. I only did it because I picked a Swiss LW-30 up in a junk shop for five francs!

Also, do you have a blank (or at any rate, containing no private data) 120kB disk? If so, can you send me the flux file to add to my collection of samples? I don't have any of them.

jgottula commented 5 years ago

Okay, I know what's going on here: floppy disk cables typically have three connectors. One end for the motherboard, and then two FDD connectors each side of the twist. The one after the twist is drive A. The one before the twist is drive B.

However, FluxEngine considers drive B to be drive 0, and drive A to be drive 1. This is so that it can be plugged straight into the back of a floppy drive and work as drive 0.

D'oh! Yeah, actually, Brett texted me maybe 5 minutes after he posted his first comment here, with the realization that the difference between direct-pin-connection and indirect-connection-via-cable would add in the cable twist, and therefore we'd have a silent reversal of the drive-specific pins.

Unfortunately we were using one of those newfangled 1990's-and-newer single-connection-only FDD cables, so during our initial troubleshooting we didn't even think to try plugging into the "drive B" plug because we didn't have one. (I think we literally only own a single dual-connector FDD cable, compared to at least half a dozen different single-connector cables. And I'm pretty sure that cable also features an additional 5.25" style edge-connector plug, from what I remember, heh.)

I'm not sure of any way to resolve this which doesn't involve inconveniencing somebody, but it totally needs better documentation --- I'll get onto that.

Perhaps some form of auto-detection would work well here? For example, in cases where the user doesn't explicitly specify the drive they want, have the software attempt spin up both drive motors; then use the index pulse to detect which drive(s) slots seem to be populated/present, and then make reasonable inferences based on that?

Also, do you have a blank (or at any rate, containing no private data) 120kB disk? If so, can you send me the flux file to add to my collection of samples? I don't have any of them.

The WP-55 unit we're working with is the exact same unit our grandmother originally used back in the early 1990s(?) to type up her writings and stuff. It's actually fairly miraculous (a) that we still had it up in the rafters and hadn't gotten rid of it at any point, (b) that we'd never, like, destroyed it back when we were younger and had no idea what we were doing with it, and (c) that we were able to get it to mostly work once we got it down from the rafters a couple of months ago.

Our WP-55 is in reasonably good condition. The screen works perfectly. The keyboard works perfectly. Printing even works perfectly! (Albeit after some minor repairs to the carriage puller cable assembly, IIRC.)

Unfortunately, the one part that has consistently not worked, despite our best efforts, has been the unit's floppy drive. We did discover pretty quickly that the belt connecting the spindle motor to the spindle itself had degraded and broken apart, and we were able to replace that with a rubber band. But in spite of that, the software continued to refuse any sort of operation (loading, saving, formatting, anything).

So, sadly, we can't even do basic things like format a blank DD disk with the unit we have, let alone do anything else with that drive.

I suppose it's possible we could attempt further troubleshooting (e.g. by probing the bus lines between the FDD and the WP's mainboard), but I don't even know whether there's a documented pinout for that presumably proprietary bus connection.

I've also several times contemplated dumping the mainboard ROM and disassembling it, which could potentially be useful for various things if it's not a PITA to reverse engineer the code. Mostly I've been thinking about this in the context of figuring out the word processor's "file format" (basically just the meaning of the various non-ASCII special bytes that it inserts into the text for formatting purposes) to make it possible to write an open source tool to convert-to-RTF-or-whatever in a high-fidelity way. But RE'ing the software could also possibly be useful for debugging what it is or isn't seeing from the FDD that's making it error out all the time. (All of this has a high likelihood of being very time-consuming though...)

davidgiven commented 5 years ago

I've updated the documentation regarding the drive twist. I should reorganise at some point...

Re Brother word processors: I was lucky, and my LW-30 works perfectly. I even found a new carbon ribbon for it in stock in an office supply shop in Zurich. I've taken the lid off and the main board inside is depressingly simple --- I think it's even single-sided. The main interesting thing is that the RAM is piggybacked on top of the ROM, or maybe vice versa, which makes it impossible to read. The drive is incredibly proprietary and I didn't even bother checking the pinout. (It's got a really nice keyboard too. https://www.youtube.com/watch?v=eL2A411Z36U)

Apparently the WP-55 (I love that rectangular CRT!) uses Brother WP-1 format files, which someone from the Swiss National Library claims WinConv will turn into RTF. For money, of course. https://www.macdisk.com/conven.php The files look chunked and I'm not convinced all the blocks of text in them are in file order.

Incidentally, I reverse engineered the incredibly simple file system of the 120kB disks. .obj/brother120tool will extract files from decoded images. Possibly even correctly.

jgottula commented 5 years ago

Apparently the WP-55 (I love that rectangular CRT!) uses Brother WP-1 format files, which someone from the Swiss National Library claims WinConv will turn into RTF. For money, of course. https://www.macdisk.com/conven.php The files look chunked and I'm not convinced all the blocks of text in them are in file order.

Yeah, we've taken a look at some of our files in a hex editor, and there are some interesting features there. One of which being occasional runs of 0xF4 that I'm half-convinced are possibly just gaps in the file that are skipped over... perhaps as a way to make quick-saving small modifications possible? (e.g. if you were to backspace 10 characters in the middle of a document and then type 4 new characters to replace them, and then tell it to save, my assumption is that it would replace the original 10 characters with the 4 new chars followed immediately by 6 0xF4 bytes, which would let it avoid having to "shift everything over" due to a small change; but I have no direct proof for this.)

And also, thinking about this from the perspective of "how would I program a word processor that uses a horribly slow floppy drive, and make it not be an awful experience to insert new text into the middle of an existing long document", allowing for out-of-order document chunks would absolutely make a ton of sense. Just shove that new chunk of text onto the end of the file and make a small update to some bitmaps or whatever to let the WP software remember where to insert that particular chunk. I really wish our WP-55 FDD worked so we could do real interactive testing of this sort of stuff...

@bgottula has been looking into WinConv already. And I've been thinking about possibly taking a... closer... look at it today. (With some reverse engineering tools.)

Incidentally, I reverse engineered the incredibly simple file system of the 120kB disks. .obj/brother120tool will extract files from decoded images. Possibly even correctly.

We've used it, and by all accounts it does seem to do the job!

pelrun commented 5 years ago

Ha! Thanks, I couldn't figure out why my board was resetting until I read this. Watchdog reset instead of timeout and useful error message, tut tut! (I can't talk, I'd totally do the same thing...)

I'm currently hooked up to an Amstrad CPC 3" internal drive, which follows the older shugart pinout (MOTEB is a shared motor enable, and MOTEA is actually a drive select) so I ended up munging things until the correct signals were present when d=0.

I'm not sure of any way to resolve this which doesn't involve inconveniencing somebody, but it totally needs better documentation

Rather than hardwiring the drive/motor select in the programmable pin design, it'd be useful if the pins were directly exposed to the software side, and the PC software just sends through a raw value that specifies which pins are set/cleared. The default d=0/1 can be emulated by sending through a predetermined value, or an end user can set the raw value directly. That'll be completely flexible but still supports the old behaviour. Depending on how things go, I might have a poke at implementing it.

davidgiven commented 5 years ago

Really for the Shugart setup it needs a way to tell the FluxEngine that it's a Shugart drive and it reconfigures the pinout accordingly. That's all quite feasible; it only uses logic to set the pinout because it was easier than doing it in software.

It occurs to me that the best solution for the drive 0/1 thing is a way to autodetect which drives are available. I'm not sure if this is possible without actually spinning the disks and seeing whether index pulses happen.

Is there a way to electronically detect whether a drive is Shugart or not?

pelrun commented 5 years ago

I don't see how you can autodetect it short of running through all the possible combinations of asserted signals and seeing if you get pulses.

Of course, the super dumb way to get things to work is to just assert all the ds/motor pins, which is guaranteed to work if you have only one drive connected regardless of how, and guaranteed to fail if there's more than one.