I hestitate to jump to conclusions, but I think I just passed a crucial first step in getting this to work!@#!#
After adjusting some timing on my new code on the SX, I’ve found my first 0x4489 0x4489 pattern. This is first time I’m seeing at least some partial correct data. Here’s the output from the file
The full signature is 0xAAAA 0xAAAA 0x4489 0x4489. I found (2) of them in about 100kb of code. This sounds light, there should be more, but I’m close!!!
I’m not sure how accurate the rest of the data is, but the pure fact that we are seeing this signature tells me that I’m stinkin’ CLOSE to having this work at a low level.
I’ve just ran across your blog. Seems you’re into Amiga MFM stuff 🙂
Being a proud A500+ owner for a month now, I’m going to build some sort of floppy emulator: a MCU, some SRAM and CF interface with .ADF files.
The emulator should be able to mount/unmount selected .ADF and then form MFM stream on the fly, feeding it into Amiga’s floppy connector as if it were coming from real drive.
However, I am quite confused with that MFM track format. If you could’ve shed some light onto it, that’d be just terrific!
Yeah, I’m knee-deep in Amiga floppy stuff. The Amiga’s MFM format is pretty convoluted, and I don’t claim to be an expert on any of it. Right now, I’m primarily concerned with the hardware-level stuff so I haven’t made it up the chain yet to the other topics, but here’s what I can tell you:
The raw MFM data rate is 500kbps, which yields 250kbps of actual real data. Your hardware has to be pretty quick —- using a small PIC or something isn’t going to fly. This is one reason why I had to go to the SX microntroller.
Half of the bits coming from (or going to) the drive are used for clocking purposes to keep the hardware in sync. Although this is synchronous communication (vs async), there is no clock lead — and so the only way to provide a method to know when to receive(ie sample) bits is to embed the clock into the data, and this is what MFM is used for. Here’s the way the hardware signalling works:
A bitcell is 2us, and the absolute smallest group of bitcells is two. Ie you are writing at least one actual bit, two bits encoded in MFM.
An idle line is a HIGH (5v), and it transitions low at the beginning of new data. The number of HIGHs before the next transition defines the raw MFM data, there can be a minimum of (1) high to a maximum of (3) high’s. After three highs in a row, if there is no following transition, is the idle state.
A transition to low is a ‘1’ data bit.
A high is a ‘0’ data bit.
Look at this post https://techtravels.org/?p=8
Take a look at the picture, the data shown on the scope images in order is:
10 (transition, followed by one high) —– 4 us total, 2 cells
100 (transition, followed by two highs) —– 6 us total, 3 cells
1000 (transition, followed by three highs) —– 8 us total, 4 cells
In order to create the MFM raw data, you have to do some wierd manipulations on the real data. It involves breaking up the data in sets of odd bits and even bits, and interleaving the clocking bits in between the actual data bits. You work on “blocks” of data, processing 16 or 32 bits at a time.
The Amiga floppy system is very very basic, and the TIMING IS CRITICAL. The motor is handled manually, and so the amiga literally raises a lead that says, “MOTOR ON”, and then sends a “STEP OUT” or “STEP IN”, or “SIDE 0” “SIDE 1” lead. The good news is that everything is hardware lead based, and there is no complicated “command” protocol language or anything. The bad news is that everything is hardware lead based! 🙂
I’d suggest at least flipping through my blog and taking a look at the pictures, I have quite a few. The traces show what the data is supposed to look like.
Does this help get you started? How fast of a MCU are you using?
Eventually, I’m going to be putting up various documents, summaries of what I know, etc —There really isn’t a definitive resource yet on this stuff. Everything I have, I’ve either learned myself, or collected from a variety of books, source codes, etc.
Oh yeah, I almost forgot.
Ignore the bulk of the “generic” MFM documents that talk about floppy MFM encoding methods.
Some of the CONCEPTS they present are good to know, but they don’t generally apply to the Amiga.
Even the original engineers that wrote the amiga floppy drive code pointed out that Amiga MFM is non-standard.
Thanks for your thorough reply.
(I’ve browsed through all your blog in the first place, it is of my favorite DIY-and-here-are-screenshots type.)
Most of the info on the subject I got from Amiga .ADF Faq ) and from Google newsgroups.
My design probably will be based on ATmega128 or similar MCU. It is capable of running at 16MHz, and delivers up to 16MIPS in one instruction commands. That is, if I program a tight loop (in assembler, of course) using only two-instruction commands, I can get me as much as 16 commands per bit cell. Seems quite achievable so far.
Of course, the MCU will be 100% busy delivering the MFM flow. That means that the whole track (some 22K?) has to be put in SRAM in advance, but that part can be easily done in C together with CompactFlash/FAT support.
Yeah I guess I’m spoiled with a true 50MIPS chip. I’m using SX/B (ie BASIC) which is fairly powerful, and not too bad because it’s compiled & assembled. The assembly it produces is quite readable, and outside of the normal overhead associated with a higher-level language, fairly efficient. You can even code assembly right in the middle of the BASIC code.
I’m not really that adverse to assembly, but with 50mips, and if I can use something high level, why not? Since its not interpreted, there is no token-izing, required libraries/ROMs, etc. Quite lightweight considering.
This mcu/embedded stuff is new to me, and I’m dangerous with a soldering iron, but it’s a lot of fun — and this is a fun project to work on. I’m a geek with a solid CS background, so this is right up my alley.
I’m not sure how deep you are yet, and I didn’t want to overwhelm you with details if you aren’t at that stage of the game.
The data coming out of the drive is anything but squarewaves, the low-going pulse is only at 0v for 1st 1/4 of the bitcell, and then it transitions to 5v by the end of 2us cell. This might be important, because the amiga hardware might do some funky sampling. Also, it appears that many amiga drives(and the amiga itself) sometimes screw up the first four bits of a sector. This is related to everything coming up and online, and some chips simply aren’t ready to start functioning as fast as the data is moving. FYI, the amiga handles this, and so the sector header is sometimes screwed up, where the first 2 bytes are 0x2AAA or 0x4AAA instead of 0xAAAA.
I’m guessing you’ve seen this before, but if not https://techtravels.org/wp-content/uploads/pefiles/afr10f.zip
also, https://techtravels.org/wp-content/uploads/pefiles/amiga.html too.
Your project sounds pretty cool —- let me know if you make big strides on it.
The reason I’ve chosen Atmel AVR chip is mostly because it is quite cheap, and I think I am somewhat familiar with how to toggle its ports’ bits and turn some LED on and off. With $5 for the microcontroller and a breadboard it sounds like a good start.
The MCU also has hardware UART which makes interfacing it with PC via serial port very easy.
Besides, having it hard-synched to the 16MHz clock is cool enough – no problem with generating exact timing, which is appealing, too.
I think I will start with producing simple TTL-level MFM flow, just the way Paula does, doesn’t it?. I believe its Write Data output that goes to floppy drive is the same. It is always possible to play with pulse duty cycle to emulate if necessary.
On first sector data corruption – I believe it is no big deal. According to what the FAQ says, the first two 0xAAAAs will produce mere word of zeroes (0x0000) and are not used at all – it is 0x4489 sync labels that are sought for.
So these 0xAAAAs probably are used to give PLL a clue, and even if there will be 0xAAA or even 0xAA there still will be good chance for PLL to sync.
Here’s what I’ve managed to get so far:
This waveform is generated by microcontroller (Atmel ATmega161). I have got a testbench built mostly for LED/LCD fun, and this runs at only 4MHz.
The tight loop is really tight – only 8 clocks per bit 2us cell. There are still from 3 to 5 clocks available for next byte fetching.
On the screenshot there’s a part of MFM sequence for 0xA1 byte (0x4489 in MFM). It can be read as 0001 binary sequence (unfortunately my scope’s next grade is 5us and the picture becomes rather difficult to analyze).
Tightening loop led to a negative pulse width of 0.5us, or 1/8 of bit cell. I hope this is OK since it is the first front of negative pulse that counts.
I tried to verify the code using binary patterns like 00000001, 11001100 and such. As much as I can tell the MFM coding works perfectly, but that can be proved only in practice.
Do you have a sampled MFM track readout that can be used as a reference? A short track (0x0000 preamble, 0xA1 sync and only one sector of data) can be than put into MCU’s flash memory to generate MFM flow. This can well be hooked to Amiga’s external floppy connector for testing.
Sorry about the delay in posting, I’m out of town on vacation.
Yeah, I dont know exactly how the amiga goes in ‘sensing’ the front edge, or the details of how it ‘samples’ or detects the incoming data. With that being said, 1/8 of a cell, which is 250ns…….yeah, that should probably be ok.
So you want just a raw MFM output from the drive? Sure, I can get you some data. It’ll come with the disclaimer that I’m not sure how well it was actually read —– and that I havent got far enough to delineate where sectors start and stop.
May 31st was the really the first day I made some progress…… im anxious to manually decode the MFM and see if my solution is working at basic level.
i gotta get some remote access to my machine at home, that might take me a little while, but I’ll put up what I can, when I can.
Thank you for your help. That is not really that urgent, take your time.
I’ve been contacted by some Polish enthusiast, he sent me a link to his TI-74 floppy disk interface. Just to add to your links and docs collection, with Piotr’s firmware sources available that could be helpful.
It looks like the Paula is using a super, super, super dumb (as in, as few transistors as possible) technique for “sampling.” Internally, it must have a flip-flop whose Q is sampled at 500kbps. This flip-flop is reset to ‘1’ every 2us. However, the floppy’s RD signal appears to reset the flipflop to ‘0’ on the negative edge (e.g., it’s really a negative edge-triggered clock signal). This dumb design is effective, but quite crude, and would readily explain the erroneous first few bits when reading the stream, particularly if it’s using a DLL (versus a real PLL) to ensure sampling occurs in the middle of the bitcell.
Also, I’ve tried submitting this comment several times, and it keeps telling me EITHER I have entered a duplicate comment, OR that my captcha solution doesn’t match that displayed (when in fact it does — I’d post a screenshot to prove it if I could). You may want to review your captcha code. It seems very, very buggy.
Thanks for the comment. Comment s_p_a_m really sucks and I’ve just found a reasonable solution (akismet). I tried various captcha plug-ins for wordpress, but as you saw, they are pretty finicky and don’t work right. It’s honestly frustrating. I’ve disabled those plugins, because I think the s_p_a_m is under control.
Paula uses a DPLL with an up/down counter. I have a little more detail in this post
including a link to the patent for Paula.
If wikipedia is right, DLL’s were too new of an innovation to be used in Paula.