I've been tinkering with trying to recreate an LC PDS card that I'm pretty sure existed inside of Apple at some point: a ROM Flash SIMM programmer supported by Apple's Flasher app, at least for the Quadra 605 and LC 475. I wrote a blog post about it a while back where I described getting it working with a protoboard. Basically it's just a PDS connector, ROM SIMM socket, and a 22V10. It's a pretty simple concept. It forwards 32-bit read and write cycles to a flash SIMM, and Apple's Flasher app does the rest. I replicated the Lobos board from this thread and tested it with AMD and Intel 28F020 chips, both of which are supported by the app. I've been testing it in my LC 475.
Long story short, @Jockelill turned it into a PCB, much cleaner than my rat's nest. We've been doing some tinkering with it off and on. I've come to the realization that it doesn't quite work correctly though. Maybe it's not so simple after all. It wasn't working with the Intel 28F020 chips (verification errors early on during programming) until I accidentally realized that probing my generated /WE signal with my oscilloscope fixed the problem, which led me to try delaying its falling edge through a register. That also fixed the problem. However, I don't really understand why it fixed it because I didn't have any setup time issues with the address and /WE.
I've been really buckling down and studying the 68020 user manual's timing diagrams on pages 282 and 286, and the write cycle description starting on page 80. I was wondering if some of the amazing smart folks here would be willing to double check my understanding of what's going on. I'm having a hard time figuring out how I can meet all of the timings.
What I'm lost about here is, how do I meet these specs by only looking at CLK, /AS, and /DS?
My first naive approach was just to use AS to generate the /WE and /OE pulses. As long as my card is selected, /AS being asserted also means /WE or /OE is asserted (depending on RW). This actually worked okay on the AMD chips, but failed with the Intel chips. I did realize from the amazing knowledge in this post that I need to drive DSACK0/1 high afterward briefly because otherwise it goes back up noticeably slowly, so my first tweak to the logic used a register to drive it high for a clock cycle afterward. I did that and it looked much better on the scope, but it didn't fix the compatibility with the Intel chips.
Thinking about this simple approach in terms of setup and hold time:
The chips don't need any address setup time, but there is more than enough anyway (15 ns + 7.5 ns 22V10 propagation delay). Since /WE stays asserted the entire time /AS is asserted, it also has more than enough address hold time.
Data setup time is where it gets a little trickier. The /WE rising edge will be when /AS is deasserted, which gives it tons of setup time, but only 15 ns of hold time before the data becomes invalid. But when you take into account the 22V10's propagation delay (3 to 7.5 ns) before /WE goes high, the hold time is really somewhere in the ballpark of 7.5 to 12 ns. This doesn't necessarily meet the requirement for 10 ns of hold time.
Does my datasheet interpretation (and math) check out here? Based on this, I don't understand why delaying the /WE falling edge through a register actually fixed compatibility with Intel chips. It added more setup time that I didn't need anyway. Maybe the real problem is that I'm not meeting the data hold time requirement, and tinkering with other timings made it unexplainably start working? Maybe Apple's ASIC that pretends to be a 68020 bus for the expansion slot doesn't quite behave exactly the same as a real 68020? Can anyone think of any other explanation?
How can I move things around to obtain more data hold time after my /WE rising pulse? I assume it means I need to figure out how to make /WE go high earlier, but I don't know what I can use for that other than maybe looking at when /DS goes low. If I delay the /DS falling edge through a register and use it to generate the /WE rising edge, it seems like that would leave me with /WE falling somewhere in the middle of S1, and rising at the S3->S4 transition. Theoretically that would give me over 60 ns of /WE pulse width, but I'm not convinced that it leaves me with enough data setup time since the data only becomes valid sometime in the middle of S2.
Do I need to insert a wait state to give myself more time to work with? Am I misunderstanding something about how these bus cycles work? My head is spinning in circles and I'm crying uncle. If someone out there wouldn't mind checking my work or at least talking it out with me, I would greatly appreciate it! Thank you!
Long story short, @Jockelill turned it into a PCB, much cleaner than my rat's nest. We've been doing some tinkering with it off and on. I've come to the realization that it doesn't quite work correctly though. Maybe it's not so simple after all. It wasn't working with the Intel 28F020 chips (verification errors early on during programming) until I accidentally realized that probing my generated /WE signal with my oscilloscope fixed the problem, which led me to try delaying its falling edge through a register. That also fixed the problem. However, I don't really understand why it fixed it because I didn't have any setup time issues with the address and /WE.
I've been really buckling down and studying the 68020 user manual's timing diagrams on pages 282 and 286, and the write cycle description starting on page 80. I was wondering if some of the amazing smart folks here would be willing to double check my understanding of what's going on. I'm having a hard time figuring out how I can meet all of the timings.
- ATF22V10C-7:
- Propagation delay: min = 3 ns, max = 7.5 ns
- Intel N28F020-120:
- /WE falling edge address min setup time: 0 ns
- /WE falling edge address min hold time: 40 ns
- /WE rising edge data min setup time: 40 ns
- /WE rising edge data min hold time: 10 ns
- /WE min pulse time = 60 ns
- Am28F020-120:
- /WE falling edge address min setup time: 0 ns
- /WE falling edge address min hold time: 50 ns
- /WE rising edge data min setup time: 50 ns
- /WE rising edge data min hold time: 10 ns
- /WE min pulse time = 50 ns
- Am28F020 seems to need more setup/hold time, so I'm shooting for its specs for setup/hold, and Intel's for minimum /WE pulse width.
What I'm lost about here is, how do I meet these specs by only looking at CLK, /AS, and /DS?
My first naive approach was just to use AS to generate the /WE and /OE pulses. As long as my card is selected, /AS being asserted also means /WE or /OE is asserted (depending on RW). This actually worked okay on the AMD chips, but failed with the Intel chips. I did realize from the amazing knowledge in this post that I need to drive DSACK0/1 high afterward briefly because otherwise it goes back up noticeably slowly, so my first tweak to the logic used a register to drive it high for a clock cycle afterward. I did that and it looked much better on the scope, but it didn't fix the compatibility with the Intel chips.
Thinking about this simple approach in terms of setup and hold time:
The chips don't need any address setup time, but there is more than enough anyway (15 ns + 7.5 ns 22V10 propagation delay). Since /WE stays asserted the entire time /AS is asserted, it also has more than enough address hold time.
Data setup time is where it gets a little trickier. The /WE rising edge will be when /AS is deasserted, which gives it tons of setup time, but only 15 ns of hold time before the data becomes invalid. But when you take into account the 22V10's propagation delay (3 to 7.5 ns) before /WE goes high, the hold time is really somewhere in the ballpark of 7.5 to 12 ns. This doesn't necessarily meet the requirement for 10 ns of hold time.
Does my datasheet interpretation (and math) check out here? Based on this, I don't understand why delaying the /WE falling edge through a register actually fixed compatibility with Intel chips. It added more setup time that I didn't need anyway. Maybe the real problem is that I'm not meeting the data hold time requirement, and tinkering with other timings made it unexplainably start working? Maybe Apple's ASIC that pretends to be a 68020 bus for the expansion slot doesn't quite behave exactly the same as a real 68020? Can anyone think of any other explanation?
How can I move things around to obtain more data hold time after my /WE rising pulse? I assume it means I need to figure out how to make /WE go high earlier, but I don't know what I can use for that other than maybe looking at when /DS goes low. If I delay the /DS falling edge through a register and use it to generate the /WE rising edge, it seems like that would leave me with /WE falling somewhere in the middle of S1, and rising at the S3->S4 transition. Theoretically that would give me over 60 ns of /WE pulse width, but I'm not convinced that it leaves me with enough data setup time since the data only becomes valid sometime in the middle of S2.
Do I need to insert a wait state to give myself more time to work with? Am I misunderstanding something about how these bus cycles work? My head is spinning in circles and I'm crying uncle. If someone out there wouldn't mind checking my work or at least talking it out with me, I would greatly appreciate it! Thank you!