*** CPLD old project results #1 (sent on May 02 of 2009) ***
Hi Charles,
At about one year has passed since I wrote you an e-mail about my "Genesis asynchronous dram interface" project. It really took me a long time to employ the ideas I had based on the information you gave, as I was really busy with studies/job.
So, here are my results:
1) Enabling the $A11000 register:
I've noticed a periodic pulse on /CE_0, every ~14us and it is a pretty good 'refresh request signal' for most DRAMs working with CAS-before-RAS refresh.
The next step was trying to decode those refresh request pulses from all other pulses (ROM access) on /CE_0. I started wondering about it and thought something like: "If genesis is addressing ROM area AND /CE_0 is asserted, it is a NORMAL access cycle. Thus, if genesis is NOT addressing ROM area and /CE_0 is asserted, its a REFRESH request pulse".
So, relying on some genesis addresing pins (A22 and A23) and /CE_0 I wrote something for the DRAM interface's state machine like the HDL pseudo-code that follows:
if (A23 == '1' && A22 == '1' && /CE_0 == '0') -> Execute a CBR refresh cycle
else
if (A23 == '0' && A22 == '0' && /CE_0 == '0') -> Execute a NORMAL access cycle
It gave good results. I've tested a bunch of games and all of them worked except some games that later I found to be reseting the $A11000 register (Lotus II, Top Gear 2 and others).
Anyway, a rigorous test showed that many games freezes after several running hours. It took me to turning on my old Tektronix Type 453 Oscilloscope and analyzing when the CBR refresh cycles were happening. I've dedicated a pin from the interface's CPLD for getting a high level while a CBR refresh was being executed. That analysis made me notice that those refresh events were really crazy. It was possible to trigger the periodic ones (every ~14us) and to watch a lot of difused ones. I felt like I had to change the refresh decoding logic, relying on other signals like /AS, /DTACK, etc but I couldn't get any better result.
2) Enabling the $A11000 and getting the 'refresh request' from /CAS_2:
As I could read in the forums, /CAS_2 has the same ~14us periodic pulse as /CE_0, even if $A11000 is disabled.
Using the same hardware as I described above but using /CAS_2 as a refresh trigger, I got the SAME results.
3) Disabling the $A11000 and getting the 'refresh request' from /CAS_2:
The system behavior was very similar as the described above but many graphics were messed up (Sprites, background tiles were at most ok). I think that is something related to the graphics loaded by DMA. Probably, if $A11000 is disabled, genesis won't make the DMAs wait for the refresh cycles.
So it generates broken graphics but no broken code. Maybe it is the reason why games keep running.
4) Enabling the $A11000 and generating an INTERNAL refresh request:
Here is the funny part. I've made a timer internal to my interface's dram controller. It generates a refresh request every ~15us and it makes the state machine attaches a hidden-refresh cycle at the end of a normal access cycle.
This approach gave me the best results. Everything seems to be really fine: Games did not freeze after several running hours, refresh cycles are where they have to be, graphics are ok.
The Problems ?
- Refreshes happens as a function of normal access and nothing grants me that genesis will keep accesing ROM to conform the refresh specs.
- By DISABLING $A11000, graphics turns into a total mess like in the above approach. It makes me think that DMAs are total evil to those refresh methods.
--
If you have any idea, please tell me. If you have any clue on how the Super Magic Drive do it, please tell me so.
I am wondering if the SMD run its DRAM controller from a clock signal coming from the genesis (VCLK or EDCLK). It would be a great difference from my approach, as i've been running my controller from an external 32 MHz clock for all this time.
--
Best Regards,
Rafael.