Image Map Image Map
Page 2 of 2 FirstFirst 12
Results 11 to 17 of 17

Thread: Floppy disk MFM low-level encoding

  1. #11
    Join Date
    Feb 2017
    Location
    Zürich, Switzerland
    Posts
    79

    Default

    Re record detection:

    What I want to do is to decouple my MFM decode logic from my record parsing logic --- because I know there are multiple MFM record schemes out there, and I don't want to have to have my MFM decoder parse as it goes. That way I can decode the stream into a neat set of records, which can then be handed off to the parser, which will know how to handle them.

    I know that real FDD controllers do parse as they go; they know how big each record is from the identification byte at the beginning, so they know how much to read (or in the case of DAM, from the sector size in the preceding IDAM). Can I avoid doing this? (I'm thinking not.)

    Re precompensation:

    Oh, ah. That looks fairly straightforward. I assume in the 010|010 case, the bit being written doesn't get shifted at all. I'll try that and see what happens.

    Re weirdo Brother disk format:

    It's FM, but is either written with a really shoddy controller (possible) or my capture hardware has gone nuts (also possible)... I'm not sure it's IBM scheme, though.

    Capture.jpg

  2. #12
    Join Date
    Sep 2006
    Location
    Silicon Valley
    Posts
    1,566

    Default

    Quote Originally Posted by hjalfi View Post
    they know how big each record is from the identification byte at the beginning, so they know how much to read (or in the case of DAM, from the sector size in the preceding IDAM). Can I avoid doing this? (I'm thinking not.)
    How do you do error checking of the data using the CRC at the end if you don't deal with a finite record length?
    And.. you REALLY want to verify that what you've read so that you can attempt retries.

  3. #13
    Join Date
    Jan 2007
    Location
    Pacific Northwest, USA
    Posts
    28,503
    Blog Entries
    20

    Default

    No, Brother is Brother and not anyone else's. There's also a bit of GCR going on there, so it's a little confusing. Also, Brother floppies are sort of on-the-fly alignment--there's no Track 0 sensor. The software just bangs the carriage out to the stop and then micro-steps in until it sees recognizable data. If it's formatting a floppy, it goes out to the stop then steps a fixed number of microsteps in. If you've got regular floppy drives that have been carefully aligned, you can be in for a world of head-scratching as the alignment can differ greatly from one batch to another.

    The traditional way to do AM recognition is to shift both the clock and data into a longer (e.g. 32 bit) shift register and then compare against a 32-bit pattern--i.e., you want at least one preamble byte as well as the AM. No match? Just shift in another bit and try again. Easy in hardware.

  4. #14

    Default

    Quote Originally Posted by hjalfi View Post
    Hmm, did not get email notification from the forum software...

    The thing about detecting the sector gap is that there may not actually be one. I was expecting that each record would have a gap between them, a place where no MFM pulsetrain was generated, due to the erase head coming on before the write head --- those are easy to detect.

    But some of the disks I've found don't have these gaps. I suspect that when doing multisector writes they keep generating a continuous and valid MFM pulsetrain and simply rewrite the sector IDs and data records. Either that, or the drives are capable of replacing a data record so precisely that the pulsetrain simply keeps going!
    The erase head also turns off before the write head, and gaps are filled with 0x4E during formatting.

    The other option, as I can see it, is that I detect the deliberately-incorrectly-encoded 0xC1/0xA1 marker bytes. But if I lose MFM cell sync, so that instead of getting cells like 01 00 10 I instead misread it as 10 01 0..., then those marker bytes parse absolutely correctly. Normally I'd expect to have the correct phase because I locked onto the sync sequence before each record, but obviously I have to have the sync lock system disabled when reading actual data. (Or else risk misinterpreting user data as a sync sequence.)
    There is no MFM encoding that produces the same pattern as the 0xA1 marker. If you shift it so that clock and data bits are swapped, you get another missing clock transition instead:

    "data" : 0 0 0 0 1 0 1 0 0
    "clock" : 1<0>1 0 0 0 0 1

    A 16 bit shift register is all you need to reliably detect it, and shouldn't be a problem to implement in either hardware or software.

    For the 0xC2 starting the IAM, you would need to compare at least 17 bits however, since a byte value of 0x14 followed by a '1' bit would look identical. As the IAM only occurs once, and always at the beginning of the track, it is probably best to make it a special case.

    The 12 sync bytes aren't intended for decoding, but - as far as I understand it - to allow the PLL to "lock on" to the length of a single bit (to compensate for motor and clock speed variations). I don't know if or how you are implementing this, but on the MFM level you should only pay attention to the A1 & C2 patterns. When these are encountered you know which bit is data and also where the next byte begins.

  5. #15
    Join Date
    Feb 2017
    Location
    Zürich, Switzerland
    Posts
    79

    Default

    Oh, for the love of...

    Code:
    0xC2  is:
    data:    1  1  0  0  0  0  1 0
    mfm:     01 01 00 10 10 10 01 00
    special: 01 01 00 10 00 10 01 00
                       ^^^^
    
    0xA1  is:
    data:    1  0  1  0  0  0  0  1
    mfm:     01 00 01 00 10 10 10 01
    special: 01 00 01 00 00 10 10 01
                      ^^^^^
    I'd drawn it out for 0xC2, observed that the gap was three clocks long, and then just assumed this was true for 0xA1 without actually sitting down and figuring it out. Yes, of course there's a four clock gap, and of course I can use that to detect the beginning of a record and to correct the clock phase...

    The only trouble with using these for detection is that it requires a rather more sophisticated clock than I currently have; what I'm currently doing is waiting until I see a sequence of 16 or so evenly spaced pulses, setting the clock according to that, and then locking it until the end of the record at which point I start looking for the next record. However if I'm using these invalid sequences to detect records, then that's not good enough, as I won't be able to tell the difference between a clock sync sequence and actual data; so clock variations from record to record may prevent me from reliably detecting the 0xA1s.

    So I think I'll have to actively search for the first clock sync sequence, to figure out the overall approximate clock rate (which may be very weird if this is a CLV disk in a CAV drive), and then implement a proper autocorrecting DPLL or something for the rest of the track.

    Anyway, that very nicely solves my problem. Thanks you very much!

    (The best thing about problems caused by me doing something stupid is that they're frequently very easy to fix...)

  6. #16
    Join Date
    Jan 2007
    Location
    Pacific Northwest, USA
    Posts
    28,503
    Blog Entries
    20

    Default

    This is the reason that I recommend shifting a bit at a time into a 32-bit shift register. 16 for the A1 and 16 for the address mark. When it matches, you're properly synced up. If you're using a 32 bit MCU to do the job, it's just as fast to work with 32 bits as it is with 16. You could also do the same work with a state machine, a la Apple, but it's not worth the work IMOHO, when you have cheap silicon.

  7. #17
    Join Date
    Feb 2017
    Location
    Zürich, Switzerland
    Posts
    79

    Default

    It works beautifully --- thanks very much! Turns out that turning the pulsetrain from a series of intervals to a nice regular clocked bitmap made everything much easier; I just clock it into the fifo and read off every other bit. Detecting record headers from the 0xA1 is utterly easy. I managed to throw away most of my MFM state machine and record parser (I'll put the parser back in somewhere else later). It all seems rock solid, too, although I haven't done the CRC checker yet. Thank you all for the help!

    In the interests of clarity, my diagram above is wrong --- I put the clock transition for the 0xA1 in the wrong place. It should be:


    Code:
             * 0xA1  is:
             * data:    1  0  1  0  0  0  0  1
             * mfm:     01 00 01 00 10 10 10 01 = 0x44A9
             * special: 01 00 01 00 10 00 10 01 = 0x4489
             *                       ^^^^^
             * shifted: 10 00 10 01 00 01 00 1
    Phase shifted I get an invalid bitstream, which means I can reliably detect it regardless of phase.

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •