Advice on SX application
Keith M
Posts: 102
I'm working on a hobby project that involves attaching an old amiga floppy disk drive to a PC's parallel port. Think PC-based parallel port external amiga floppy drive controller. The floppy drive interface is a very simple one, and spits out synchronous serial data, but does *not* have a clock lead. The clock is built into the data stream. The drive uses MFM encoding, and this data is not massaged in any way before leaving the drive. The serial data IS the actual flux transitions.
The data rate is 500kbps, and the bitcells that contain a transition, or do not contain a transition are 2us wide. The data lead is normally HIGH at 5v. I have used an external component to turn the transitions into square 0-bit's(of duration 1.5us) So I have this stream of data which is free-flowing(ie no flow control whatsoever) that is coming in serially that I'll need to sample, and then send out via parallel(8-bits at a time) to the PC. If you could imagine a 500kbps sync serial to parallel converter with no clock lead, you're on the right track.
Remember, MFM has a rigid structure that guarantees that a flux transition occurs at least every 3rd bit cell. See two high-bit's(no transition) in a row, you know a transition is next. See a transition occur, we know a high-bit is next. The data itself also has a sector header that has 16 known bits. There a bunch of cases where you can predict bits based on past bits. Other designs have created a PLL circuit where a transition has reset a 555 oscillating at 500kbps. Here's the point --- there isn't a case where a long string of 0's or 1's would cause a loss of sync.
I originally planned on using a PIC, but they(the smaller PICs that have affordable supported programmers) are simply too slow. Enter the 28AC at 50mhz.
Does anyone have any advice for how to approach this from a programming perspective on the SX? Should I be using timers or interrupts? What are some gotchas or problems to expect in advance? I'm a competent C programmer(on PCs, and palm pilots), C++/Java(windows, anyways), etc. My assembly experience is limited --- and I haven't dived into embedded assembly. I've written small/semi-working C programs for the PIC.
I have written some code already in SX/B (would prefer C if it is at least partially community-supported, it seems few and far between on the SX). It looks something like:
wait for a transition to 0v
fullbyte = 0; totalbits = 1
waitline: wait (2us - how long it took to do the last instructions)
sample the pin
(store function looks like this, below)
if PC acked the received byte, clear the "byte ready" pin to the PC
shift fullbyte to the left by 1 (fullbyte = fullbyte << 1)
fullbyte = fullbyte | samplepinbit (or the new bit with the shifted byte)
increase totalbits by 1
if totalbits > 7 then xferbytetothepc
goto waitline
xferbytetothepc: RB = fullbyte
RA.xxx (tell the PC a byte is ready)
goto waitline
Will this simple logic work? Is there a better way to attack this? I'm having a seriously hard time with timing issues on when to sample properly. Also, I have no idea how to troubleshoot this? Should I further modularize things? Test each module separately? My initial program was more complicated in that it would actually look wait for 0-transitions where they would be expected to better sync.· The code would just be free running but would be locked to each 0-transition, which is happnening very often.
Sorry about the long post, I'm trying to be concise but this is involved.
Thanks.
Keith
·
The data rate is 500kbps, and the bitcells that contain a transition, or do not contain a transition are 2us wide. The data lead is normally HIGH at 5v. I have used an external component to turn the transitions into square 0-bit's(of duration 1.5us) So I have this stream of data which is free-flowing(ie no flow control whatsoever) that is coming in serially that I'll need to sample, and then send out via parallel(8-bits at a time) to the PC. If you could imagine a 500kbps sync serial to parallel converter with no clock lead, you're on the right track.
Remember, MFM has a rigid structure that guarantees that a flux transition occurs at least every 3rd bit cell. See two high-bit's(no transition) in a row, you know a transition is next. See a transition occur, we know a high-bit is next. The data itself also has a sector header that has 16 known bits. There a bunch of cases where you can predict bits based on past bits. Other designs have created a PLL circuit where a transition has reset a 555 oscillating at 500kbps. Here's the point --- there isn't a case where a long string of 0's or 1's would cause a loss of sync.
I originally planned on using a PIC, but they(the smaller PICs that have affordable supported programmers) are simply too slow. Enter the 28AC at 50mhz.
Does anyone have any advice for how to approach this from a programming perspective on the SX? Should I be using timers or interrupts? What are some gotchas or problems to expect in advance? I'm a competent C programmer(on PCs, and palm pilots), C++/Java(windows, anyways), etc. My assembly experience is limited --- and I haven't dived into embedded assembly. I've written small/semi-working C programs for the PIC.
I have written some code already in SX/B (would prefer C if it is at least partially community-supported, it seems few and far between on the SX). It looks something like:
wait for a transition to 0v
fullbyte = 0; totalbits = 1
waitline: wait (2us - how long it took to do the last instructions)
sample the pin
(store function looks like this, below)
if PC acked the received byte, clear the "byte ready" pin to the PC
shift fullbyte to the left by 1 (fullbyte = fullbyte << 1)
fullbyte = fullbyte | samplepinbit (or the new bit with the shifted byte)
increase totalbits by 1
if totalbits > 7 then xferbytetothepc
goto waitline
xferbytetothepc: RB = fullbyte
RA.xxx (tell the PC a byte is ready)
goto waitline
Will this simple logic work? Is there a better way to attack this? I'm having a seriously hard time with timing issues on when to sample properly. Also, I have no idea how to troubleshoot this? Should I further modularize things? Test each module separately? My initial program was more complicated in that it would actually look wait for 0-transitions where they would be expected to better sync.· The code would just be free running but would be locked to each 0-transition, which is happnening very often.
Sorry about the long post, I'm trying to be concise but this is involved.
Thanks.
Keith
·
Comments
http://www.techtravels.org/amiga/amiga.html
Be sure to click the blog link at the bottom for current news, pictures, etc
You're going to LOVE your new SX for this project. It may have everything you need.
I didn't completely understand all of the details of your post, but I checked out your blog and looked at your scope pictures. If I understand the circuit you put together correctly, it looks like it is smoothing out the transition to 5V so that a processor would only have to deal with lows and highs. Good news and bad news... The good news is that it looks like it does a great job. The bad news is that you can probably throw it away. Did you get the SX-Key Development System manual? Look in the index for Schmitt-Trigger (page 91 in my copy). This is a state that an input pin can be put in that will have the processor interpret anything below 15% of the source voltage as a logic zero and anything above 85% as a logic one. Looking at your output vs. input on the scope, it looks like it lines up exactly the same.
Also, in your post or on your site, it said something about a pull-up resistor. I just wanted to point out that for most of the ports, you can have them also enable a pull-up resistor (in addition to the Schmitt-Trigger).
Again, I am sorry if I didn't get all of the details of your post right, but it looks like the bits are encoded in the duty cycle of the signal (getting this mostly from your scope pictures). It looks like the lows are of a fairly consistent period and it is the highs that vary. For the sake of the following description, lets assume that when it goes high for a short period, it represents a zero and when it goes high for a long period, it is a one. That being the case, my first stab at solving the problem would look something this:
Interrupt Routine
if INPUT_PORT is LOW
InputPeriod = InputCount // Move the current count into the InputPeriod used by the main program
InputCount = 0
InputReady = 1 // Let the main program know that the input is now ready
else
InputCount++ // You said you were a C programmer [noparse];)[/noparse]
// Add code here for sending the data on the parrallel port when data is available
End Interrupt Routine
Main Program
While True
If InputReady
// Reset the InputReady so that it starts counting the next high when the port state changes to high
InputReady = 0
// At this point, the InputPeriod contains the length of how long the input signal was high.
if InputPeriod < MIN_INPUT_THRESHOLD
<throw away the bit?>
else
InputValue = (InputPeriod < MIN_INPUT_LOGIC_ONE_PERIOD)
// Do whatever you want with your input value. Based on what you are doing, I doubt it will be a problem, but
// make sure this routine does not take so long to run that you start missing input values. Look at the SX site
// for UART_VP's for examples of how it serializes data out within the interrupt and do the same sort of thing
// for sending the parrallel data. The last thing you would want is to build in delays to the following routine
call ProcessInput(InputValue)
End IF // Throw in a little basic just for kicks
End If
Wend
End Main Program
You can vary the frequency of the interrupt routine with your resonator selection and the interrupt prescaler. I would recommend making the interrupt go between 150 and 200 times for a high. At this rate, you won't have to worry about catching transitions.
Lastly - you must be as old as me or be into antiques. I remember my Amiga as the my first truely multi-tasking machine that I could use for a BBS and still have other programs running!!
Man I wish I had a scope - sure would have made my project easier. I'm cheap, so I made one out of an SX that receives input, keeps timing and serialized the data to a Java scope app I made on the PC [noparse]:D[/noparse]
Good luck,
Jim
Use the "Code" formatting button to keep the indenting when you post a message.
Thanks, PeterM
Use the "URL" formatting button when you have an URL in a post. It makes it an actual link instead of just text.
BTW, I'm glad you posted the blog link. When you originally mentioned this project, I thought you were doing something that was technically interesting, but I couldn't understand the point of it. The blog cleared it up. I realize that that you want to be able to read (and write?) Amiga floppies on a PC, presumably to get data from them.
I love these kind of projects. In addition to programming, I also do machining and welding. My friend (who owns a business designing and building all sorts of interesting precision machines for different industries) often looks at metal projects I make and wonders why I don't just buy something off the shelf. He just doesn't understand that sometimes you want the exact thing, and not the functional substitute. Being able to read Amiga floppies on a PC is something of value to you (and others I'm sure) and should be a cool technical challenge.
Keep scratching that itch...
Thanks, PeterM
Post Edited (PJMonty) : 3/10/2005 6:04:16 AM GMT
Thanks for taking the time to reply.
Jim: Re: my circuit. Yeah, what it does is take any a signal that is negative going, and output a 1.5us negative pulse instead.· I need(ed) this because the signal transitions from 0v to 5v across the whole period and trying to have something sample early enough to catch the 0v is tough.· If I can get rid of this, I would be plenty happy.· Although I knew the SX supported Schmitt Trigger action on the input --- I really didn't grasp that this could have helped me.· I've looked at schmitt triggers before, and I thought they were only for positive-going signals -- at least it was on the shift register I looked at.
I've looked at your code and it makes sense.
I know some of my presentation of how this stuff works was a little unclear.· In MFM, you have two possible states, either you have a transition in the bitcell OR you have no-transition. So you sample the bitcell, if you see a transition(which sounds like it will be interpreted as a low with S.T. action) --- that is one state.· The other state is no transition, ie the signal stays high for the entire duration of the bitcell.
Look at the picture in this entry :
http://www.techtravels.org/amiga/amigablog/blogger.php?page=news_photo&id=1110341462
NT = No transition(HIGH, 5v), T = Transition(Low, 0v)
Now looking at the horizontal divs as you go from div #2 to div #10(ignore the first incomplete transition), you would read this as NT, T, NT, T, NT, T, NT, NT,·T.· This still has·to be decoded, and so those lows and highs, 0's, and 1's·don't·directly represent the data.· You have to take 16-bits of raw MFM to get 8-bits of actual data.
I properly adjusted the scope so that the beginning of the bitcell falls right on a div boundary, so that it can be read more easily.
Just so I fully understand this, you are suggesting I use an interrupt routine to do the actual sampling and the interrupt prescaler to change the timing of when it samples.· Is this right? Am I using INTERRUPT and OPTION in SX/B? I'm new to interrupts although I have a general idea of how they work.· Can you be more specific if I'm going to run at 50mhz with the external Murata, etc?
I'm 30.· I grew up on the Amiga and on BBS's.· Great time.· I'm a nostalgia junky as well.· I have this massive collection of amiga floppies which I want to get into the 21st century, in order to preserve them, for posterity's sake --- and also for the amiga emulators (UAE).· I *could* load them into one of the five amiga's I have at home, but there are several issues, like how to get the data to my PC.· The amiga serial port is only capable of about 33.6kbps, even with a fast(er) processor.· This is the only port you can effectively communicate with the real world.· Either PPP or dumb term/zmodem is just too slow to move all this data.· SO, I figure, why not make a controller for the PC?
There are commercial products available for under $200 --- I've already spent way over that on this project. It's not really about the END perse.· It's about the journey.· I've even bumped into ex-commodore engineers that wrote the assembly code for the amiga to read floppies. The amiga is an amazing machine.· The only other alternative to the commercial product is the hobby project designed 8 years ago by an Italian.· It has issues that I cover on my website.
Thanks guys for the support(both technical and on the idea!)
Keith
Keith - I looked up what MFM encoding is and it makes a little more sense now. Here's a link for those that are interested: www.storagereview.com/guide2000/ref/hdd/geom/dataMFM.html.
Yes, I would use an interrupt for your processing. I'm guessing that you will need it for being able to send the stream out of the parrellel port at the same time that you are receiving anyway. It looks like you should be able to decode the stream based on knowing the time between falling edges and histeresis (knowing what value came before), though, I have not worked it out through my head. As for the programming language, I like using the assembler based on the fact that I LOVE real-time debugging and I have to know what the assembly code means anyway.
So, is this the signal coming from the Drive? Or is this after you send it through the 74HC132? If it is the former, I am still suspecting that you could do with just the Schmitt Trigger and the pullup(if required) built into the SX. Just imaging, you may end up with a board with a couple resisters, an SX and an input/output header - pretty cool.
Jim
Yes, that link shows the actual output coming from the data lead off the drive.·You can tell because there is an actual transition and not a square wave like the output from the other IC.· ·I'm sniffing a connection between an amiga and the floppy drive via a daisy-chain port on the drive.
I think you are right on the money with the Schmitt Trigger.· I read the section of the manual you pointed me to, and it looks like it lined up perfectly.· This is what I'll plan on using.· The 85% of vdd mark should be roughly 3/4 the way through the 2us bitcell(based on how fast it transitions), which is perfect.· Almost exactly the same bit width I had before.
I plan on doing the MFM decode on the PC -- even if the SX could do it, I have a lot more control over it once it gets into the PC, plus history, lots more memory, etc.
Yeah very cool! That's why I wanted to re-do the design from several years ago.· The older design used several IC's, a harder-than-it-has-to-be PCB, lots of components.
Question: do you think I should simply sample once within the interrupt that is triggered every X us?· Or should I implement something more complicated, like say, oversampling, and manually checking for the edge to make sure I'm sampling at the right time?
Thanks.
Keith
·
Or something like that. I would have the Interrupt go off often enough to get a good clean delineation between when a transition is missing and when it isn't, but not so often that you end up having the 'InterruptCounter' run the risk of rolling over 255.
I realize the it still shows you outputting 0's and 1's, but in this example, a 0 would represent that no transitions were skipped and a one would indicate that one transition was skipped (or however one wants to wrap their head around MFM. It would then be up to the PC to decode it. That said, once you see how much fun it is programming the SX, you'll want to do the interpretation within the SX too There is certainly enough power, program space and speed to have the interface to the PC just be the actual data - but to each his/her own.
Jim
Thanks for the code.
I beginning to think that I'm reading MFM all wrong.· I thought I had a grasp it, but the lack of any meaningful data coming out of the SX to my PC has me rethinking it.· The routines to store and transfer to the PC are easy and solid.· They work reliably and I've tested them in a couple different configurations.
The output from the drive has a sync sector header in raw MFM, so I don't have to do the decode to tell if it's receiving properly.· If I'm receiving properly, I'll see it.· If not, I won't.· My "searching" routines don't just look for stuff that is byte-aligned. A header shifted across bytes would still be detectable.
I've read quite a bit on MFM but I'm just not reading the data correctly.· At this point, I'm making educated guesses as to what constitutes a 0 and 1 coming out of the drive.
Thanks for your help.
Keith
P.S. I've attached a new scope image that is at 5us per div so that you can see more data than what I showed earlier.
Post Edited (Keith M) : 3/11/2005 11:18:05 PM GMT
Post Edited (Keith M) : 3/11/2005 11:18:57 PM GMT
You used the preamble to synchronize to the bit cell centers, and could re sync on each bit once you were locked on, because there was a guaranteed transition at the center of each bit cell. The direction of the transition gave the state, or you could look at the line state just before or after the transition to figure out the bit value.
The point I want to make here is that it seems to me the disk data must have some kind of preamble that allows the data separator to synchronies to the bits. In MFM, if I figured it out correctly, that would be alternating ones and zeros, which should cause only transitions at the middle of the bit cells, where the ones are. So if you find a string of the wide bit cells in your data, you know they are one bits at the transition points, and can start decoding from there.
But you have to maintain sync, which means keeping track of the previous bit cell value and then looking for a transition a certain time after that to determine if you have a following one or zero.
I think the string of bits you have shown doesn't give enough information to determine the values, you have to have a sync pattern to do that.
If I was home, I'd dig out my copies of the Amiga hardware reference manuals and work it out in detail. Sounds like a fun project. I only just got the Amiga emulator from Cloanto at Christmas and have been playing some of the old games on my PC. I had a friend who worked for Discovery Software, the makers of Marauder disk copier, as well as Arkanoids and some other games for the Amiga.
I remember Rick Ross, who figured out the disk cracks, saying the Amiga didn't need a floppy controller because with a barrel shifter you could do MFM decoding in software very quickly.
That might be a clue how to do it [noparse]:)[/noparse] It seem to me the Amiga just sucked in all the bits from the disk and then in software found the preamble to signal the start of a track and worked out the data bytes from there. The barrel shifter comment suggests that there is some easy way to figure out the bits by shifting them one bit exclusive oring or something like that.
I think that is why it was considered to have a 'fast' floppy disk system. There was no need to synchronize to sector or start of track marks on the disk, and waiting for the disk to revolve around to the start of the track. I think it just sucked in a whole track, found the start, inserted whatever data it needed to and then blasted the whole track back out again, without regard to the rotational position of the disk. The PC and other systems have to wait for the start of track to rotate around before they can read or write sectors.
So, I think, you need to find the preamble, sync your ISR with it and check each transition and make adjustments to keep it in sync, and go from there. But the preamble is key.
One other point I have to make about detecting bit transitions. I got bitten by this and it took me a day to figure out. My prototype used the B transition registers, I tied two lines together and set up one up to trip on high to low, the other to trip on low to high. That way, once I was in sync, whichever one was tripped after the middle of the bit cell indicated the bit value. OK that worked real well. When I made my production hardware, which was also targeted at other things, I forgot all about the special B pin properties and used the whole B port for something else.
So I was then forced to do the transition detection in software. Which meant a now much higher speed interrupt. Not too big a deal, just sample the line each ISR, compare it to a saved previous value and if they are different, you had a transition. OK, the point I want to make here, is that you must only sample the line *once* per transition check.
My first cut at transition detection read the pin for the line, compared it to the old value, and then read it again and put that into the 'old value bit'. I had not thought about the point that the line could very well change in between those two readings, despite them being only 100 ns or so apart, and so I would miss transitions. In hindsight, well DUH!. But it took me a while to figure out that I had to read the pin once, save that value, compare it to the old one, and then save the new into the old for the next time.
Looking briefly at the code snippet above, the issue is that the data is held in the transitions, not whether the data is high or low, and it isn't the length of time between transisitons, transitions close together can indicate either a string of ones or zeros depending on what happened before. The only thing you can hang your hat on is that a bunch of wide transitions in a row must be ones, and the transitions represent the center of the bit cell.
Good luck with it, I'd be very interested in building one if you care to share what you come up with. I have a *lot* of old Amiga stuff I'd like to get back...... packrat that I am..[noparse]:)[/noparse]
If I did my example correctly, there should be three cases found in the data, transitions separated by the nominal bit period, 2 micro seconds, 1 and a half bit periods or 3 micro seconds, and 2 bit periods or 4 microseconds.
Suppose you sample at nominally twice the bit rate, and call any sample with a transition in it a 1, and any sample without a transition in it a 0.· Synchronizing is left as an exercise for the reader.
Assuming my attached diagram came through, the top line represents the original data, each long·bar underneath represents a transition.· Below are marks indicating the center and mid bit cell points.· The bottom line of data is what you get if you sample at twice the bit rate, with a one for·each sample that had a transition.
You can see that there is one case that gives a sampled 10001 pattern, which is a 1 0 1 pattern in the data.· If I'm correct and·did the MFM encoding properly, then all you have to do is sample at twice the bit rate, suck in bits until you see the 10001 pattern and you know the two 1s in that pattern are real 1s in the data, and the middle 0 is a real 0. Once you find that, you grab every other sample, and it will be the correct data.
To put it more in the time domain, if you don't see a transition for longer than 3 microseconds, the next transition is a 1 and represents the middle of the bit cell.· Once you have that it should not be difficult to maintain sync with the subsequent transitions and find the proper ones and zeros.
Using the SX B port and a 1 Mhz interrupt may be good enough.· Set the appropriate B port pin to be schmitt triggered, and detect rising edges.· You don't set the B port to interrupt the SX, you are going to use the RTCC to interrupt at twice the bit rate and test the B port to see if it saw an edge since the last RTCC interrupt.
Read the WKPND_B register in the interrupt to see if you had a transition in the last half bit time. If I remember correctly, the process of reading the WKPND_B register also clears it, which you want.
Set a 1 in a shift register if you had a transition, a 0 if you don't and look for the 10001 pattern to show you which half bit time bits are the real data, and start shifting those into another shift register to accumulate your bytes.· Probably want to keep looking for the 10001 pattern in the test shift register to keep sync.
I think you could probably feed the disk drive output right into a B port pin, (adding series resistor for current limit etc.)· So no other external active components.
The key point there is that once you found that sync point, you can keep sync and stuff appropriate bits into a data register. It may be necessary to sample at 4 or 8 times the bit cell rate, so you can slide the test point around to match the transitions.· If there is a mismatch between the bit clock coming out of the floppy drive and the RTCC rate, ( a certainty, because of the motor speed variation, drag etc.) you will have to keep an eye on the transitions and resync to them.·
If you were sampling at 8 times the bit rate, and saw a transition, you would expect another transition at either 8, 12 or 16 interrupts later.· If you see it a little early or late, say 6 or 10 interrupts, you reset the counter to 8, if you see one between 10 to 14 you reset the counter to 12, 14 to 18 you reset to 0 and call that a 1 bit.· Every 4 interrupts you shift the test shifter and check for the sync pattern.
Hmm. Lets do some numbers. First off, looking at your scope photos, if the first one on your blog is right, the scope was set for 2 microseconds per division, and the closest any two transitions are is 4 microseconds.·· There is one interval of 6 microseconds.· That suggests a bit cell time of 4 microseconds, or 250 KHz, not 500.· The second scope photo in this forum, at 5 microseconds a division seems consistent with that.· Is your scope set for a variable time per division?· I'm thinking the Amiga 3.5 inch floppies were 800K bytes?· If so then they would have been 250 Khz data rate, not 500 Khz.
If the true bit time is 4 microseconds, not two, then sampling at 8 times a bit cell with 25 cycles less 6 for 19 instructions per interrupt on a 50 Mhz SX might be feasible.· The ISR would have to test for the transition, adjust a sync counter, shift a data shifter and maybe set a couple of bits to tell the main routine that it should shift in a data bit and what it is.· The main routine would have to be responsible for looking for whatever data pattern tells you where bytes start and end, and then it would pass them to your PC via the parallel port.· Maybe with a software fifo on the SX side as well.· Unless you were just stuffing every 8 detected bits to the PC and letting the software on that side figure out where the start of real bytes were in the reconstructed bit stream.
Setting up the hardware properly might help the efficiency, like using port B.0 or B.7 as the test pin, so when you swap the W with the WKPND register you can just rotate the transition detected bit out of W into the carry and into another register.· This is definitely a case that requires·setting the option register so that W appears in the data memory as a register at WREG.
19 instructions sounds tight.· You might want to consider either a faster clock for the SX, like 75 Mhz or coding the MFM routines the old PIC way without using an interrupt.··Coding the main routine to test the bits, pass data to the PC etc. in such a way that it always takes the same amount of time to execute the loop between transition tests.
Gets messier the more I think about it, which is how it always goes before it gels.· What is the order of the bits off the disk?· Most significant bit first or least? How many bits per revolution of the disk?· What is the sync pattern to tell you the beginning of a track has been found?
Post Edited (Michael Chadwick) : 3/12/2005 9:24:03 AM GMT
Thanks for looking at this.
As far as a preamble goes, each sector has a sync pattern, this sync pattern is 0x0000 0xA1A1 uncoded or 0xAAAA 0xAAAA 0x4489 0x4489 in MFM.· The barrel shifter you must be talking about is called the "Blitter" Chip which is a custom IC designed for graphics.· The amiga uses the blitter chip to decode the MFM.· The blitter chip sync's off of this "sync pattern" and then starts to decode from there.· This is the only "hardware sync" per se, outside of the regular transitions to keep you in sync.
I definitely remember the Marauder software --- it was very popular back in the day.· That's exciting that you know someone involved with something like that.· I've been talking back and forth to old Commodore employees that actually wrote the disk code.· This is going on 15 years ago that they wrote it, so I wouldn't expect them to know the nitty-gritty details.· The sense of community back then(still now?)·was amazing on the Amiga platform.· Tell him hello from a fan!
This is designed specifically as a "community" project in that everything I do will be fully documented and shared with the public.· Certainly I need this functionality, but besides being a learning process for me, I want to benefit the entire community by giving them another option instead of buying commercial products that do the same thing.· I've spent more money (and I doubt Im done) and time than the commercial products cost.
The amiga floppies were 880k bytes per floppy.· All the documentation I have says 500kbps·and 2us per bitcell --- this wasn't something I guessed or assumed.· I'm always open to the fact that this stuff might be wrong, but I don't want to start with that assumption.
Although this is on my website, it's probably not clear, or easily accessible.· Look at the attached schematic, and I apologize in advance for the huge size.· You can't scale this sucker because its bmp, and the lines disappear......
This schematic shows the same type of circuit I'm trying to build with using the SX instead of the 555 and supporting chips.· I've done the hardware analysis as far as figuring out how the thing works, computing the RC numbers, etc. Look here :
http://www.techtravels.org/amiga/analysis.html
I don't think there is any funny business going on re: what you were talking about with the "transitions" having an independent meaning vs the actual highs and lows.· (btw: I'm somewhat familiar at a high level with Manchester encoding from 10mbps ethernet, my day job)· The reason why I don't think so is because the data lead comes directly out of the drive and into the shift register on the schematic.· The 555 is free running at an adjustable rate (via a pot, but just at 500kbps for the center), and then the 555 is kept in sync by the transitions.· The data gets moved to the PC and then the PC software reads the data in --- and the pc software inverts this data before shoving it into a byte array.· If what you were talking about were true, the data would have to be manipulated someplace, and I just don't see it.· It's not in the hardware (as far as I can tell), and its definitely not in the software....... There would have to be something that converts the "transition from 0 to 1 or 1 to 0" into real data, and I just don't see this.
Having extra sets of eyes on the schematic is invaluable, because I'm really weak regarding my hardware and electronics skills. This is a "big" project for me.· I don't mind investing the time trying to learn this stuff, though.· This is fun!
Thanks!
Keith
P.S. At the top of that link is a downloadable copy of the entire 555 project including source code, schematics, pcb layout, etc. This is what I'm attempting to duplicate using an SX.
Looking at the schematic, I have to agree with you, it appears that the 555 is being reset on the low going pulses, and then whatever time delay it is set for, it clocks the state of the data line at that point into the shift register. If it doesn't get reset, it clocks again after whatever time period it is set for.
I think the circuit works exactly as I suggested the SX version needed to work, and here's why:
I think you made a mistake in your calculations of the frequency range on the TLC555. According to the data sheet the period is Ct*(Ra + 2Rb) * .693 My reading of the schematic puts Ra at 6.8k fixed, and Rb at 6.8k minimum, up to 16.8K. That gives 1.44 / (( 6.8 +6.8 + 6.8) * .00025 ) for a maximum frequency of 282 Khz, down to a lowest frequency of 1.44/((6.8 + 16.8 + 16.8) * .00025) or 142 Khz.
Which while not centered on 250Khz, gives the possibility. I think the key here is the frequency and the time the output stays low. The low time can range from Ct * Rb * .693 or .25e-9 * 6.8e3 * .693 or 1.17 microseconds to .25e-9 * 16.8e3 * .693 or 2.9 microseconds. The high time goes 2.356 microseconds to 4.088 microseconds.
Here is a key point you missed:
The series of two inverters ahead of the reset line on the 555 form a one shot that reduces the length of the reset pulse compared to the input pulse. With the component values given into the LS14 which is a Schmitt trigger inverter, the reset is reduced to less than 300 nano seconds in round numbers.
When the input low going pulse comes in, it causes the 555 to discharge the RC. Because of the reset being less than the input pulse time, when it goes high, the output of the 555 will go high while the input from the disk is still low, and clock a 0 into the 164 shift register. The 555 will then start it's high timeout.
If the 555 is set to have a period of about 3 microseconds, after a transition it times out and clocks a 1 into the shift register. So for every transition, you get two bits out, a 0 and a 1. On the longer intervals it might clock 2 or 3 1s into the shift register. So every transition it sees, it will clock a 0 into the shift register, and it will then cycle and as long as it doesn't see a transition will clock a 1 into the shift register every 3 microseconds or so.
This is pretty close to what I was saying needs to be done with the SX. Clock a 1 into the data if there was a transiton, then wait a half bit time and if there was no transition, clock a 0 in. Only the data in Marcos' circuit is inverted, which is why he inverts it after he reads it into the PC.
Looking at the source, the ImportTrack code is where he reads pin 10 on the parallel port. That pin is the Attn pin, which sets bit 6 in the status port register of the parallel port. He is waiting for it to go high then low then high again before he reads the data register. That sets him up to only read after the 374 holding register has been clocked, and gives the data some time to settle.
Further in the source in DecodeLongword where he grabs the data, you can see that he is masking off every other bit and combining MFM data to get to unencoded data. Although it looks to me like the Amiga must have output the even bits of a 32 bit word followed by the odd bits, considering the way Marcos is combining stuff.
I think it should be pretty easy to do the function of the cirucit with the SX. I would use the B pins to interrupt in addition to having the RTCC interrupt enabled. This would emulate the function of the 555 pretty well. Set up the RTCC for the timeout function of just longer than half a bit interval. Something like 3 microseconds. When the B pins trip an interrupt, you shift a 0 into the output shift register. When the ISR trips due to the RTCC countdown, which you figure out by not finding a transition bit in WKPND, stuff a 1 into the shift register. Every 8 ISRs you transfer the shifter to another register and set a bit that allerts your main routine to signal the PC to grab the value. Should be functionally equivalent to the Marcos circuit, but only one chip plus a couple of support components.
Double check my timing calculations. 3 microseconds as a minimum time doesn't seem short enough, if it truly is MFM coming out of the drive. The other thing is, have you seen any intervals in the data of exactly twice the shortest? All the scope photos you have shown show 4 microsecond intervals and 6 microsecond intervals. It seems to me there should be 8 microsecond intervals as well, unless I goofed how I encoded my example MFM.
In my scheme of looking every half bit time, I would check every 2.5 microseconds or so. That would give me patterns of 101, 1001, and 10001, in the data, which in the enencoded data would correspond to 11 or 00, 100 or 001, and finally 101, which is unambiguous in its meaning.
3 microseconds on the 555 wouldn't ever manage to pick up the three 0s, or in the case of Marcos' circuit, 3 1s.
Since it appears that the Amiga did odd and even bits separately, most likely the easiest way to do the encode in software, maybe there is something other than straight MFM going on.
I looked at how you would generate MFM, and it comes down to spreading the bits in a byte apart by one so they end up in two bytes, call those the expanded bits, then duplicating the values so each two bits are one original bit. Call those the doubled bits. Make another copy of the doubled bits, shift it left one, OR it with the original doubled bits. Then XOR with a 0x5555 mask to invert every other bit. If you do it right you end up with a 1 every where there is supposed to be a transition in the MFM data.
I think you are right about the blitter being responsible for that. I checked and the 68000 doesn't have a barrel shifter, but the blitter did, as well as being able to combine multiple sources of data with various logical operations.
Yes, you are right there is an 8us interval.· I've seen 4, 6, and 8.
Can you explain how you are arriving at those patterns?
I think this may have something to do with the sample time, but I'm coming up with three possibilities.
If its a "4-interval", then you have 10.
If its a "6-interval", then you have 100.
If its a "8-interval", then you have 1000.
Are you including the next transition in the current data?
I'm guessing that after a transition, and three timeout periods, that I should reset to just waiting on a transition right?· There are fairly long periods of inactivity between data -- where the data lead stays HIGH for long periods.......·I don't want to keep adding 0's to the·data.
Also, how can I tell the difference between the last 4-interval, and the last 8-interval if there is a long period of HIGHs at the end of the transfer?· This would be the normal idle condition.· Unless there is a mandatory closing transition or something that I don't know about --- or perhaps because the length of the data is fixed, I can simply stop using the bits after I reach the length......
My transfer to PC routine is pretty good.· I basically have the PC wait for a data-ready-lead to come high, the PC immediately reads the byte, raises an ACK-lead, and then waits for the data-ready-lead to drop.· I have a small check inside the ISR to drop the data-ready-lead once it sees the ack-lead come high.· This gives the PC at least 8 bits of time (whatever we decide it is) to retrieve the byte before the SX changes it.
BTW: what are you considering the data rate and the bitcell width now? 250kbps and 4us?· If it helps, my scope triggers on 2us, but doesn't on 5us.· I'm guessing this is due to the fact that the 5us isn't an even multiple.....
Thanks.
Keith
I should know the make/model of it for as long as I have been staring at it lately.
I also have another scope, a much newer 2000's BK Precision one, which is only 30mhz, good enough for most of the stuff I do --- but it's not storage. The only feature I think I need besides what it has. The decent scopes that were storage were easily double to triple the price I paid for mine, so..... off to use the old model!
Keith
BTW: I looked at your code, and although it was quite daunting at first just due to its raw size, when I got down to it, the actual code code is only about 25 lines of real code. Besides the setup (which is important, of course) All the action happens in the ISR and in main. The only main difference between your code and mine, is that mine is missing the RTCC = 0 at the beginning of the ISR. I knew that had to go someplace, and I put it at the END of the ISR, after processing an edge, and obviously that is not going to do much good.
My SX/B code might be 2 pages or so printed, and that's with a heck of a lot less lines/page.
(I'm not knocking it, just noticing the difference. Then again my code doesn't work, yet. [noparse]:)[/noparse] )