2021-05-02
I’ve finally turned my attention to porting the updated version of the Megadrive/Genesis core to the Turbo Chameleon 64. Since I last had any input into this core it’s come on in leaps and bounds, and adding the DeMiSTify module to make it run on controllerless boards would be next to trivial.
Or so I thought…
I generally start with the DE10-lite as a target platform since it has a nice large MAX10 FPGA of the same tech level as the Cyclone III and 10LP (i.e. counts logic elements the same way, uses RAM blocks of the same size.)
The ported core works nicely on DE10-lite.
I built it for Turbo Chameleon 64 V1 hardware and it works nicely there, too.
I built it for Turbo Chameleon 64 V2 hardware and…
Oh dear.
This is the second core where I’ve encountered a corruption problem on V2, and in both cases it’s resisted all the “simple” things that would be expected to solve it – adjusting RAM phase shift, checking resets, checking initialisation, mode register setting – I’ve even clocked both cores at 5/6 of their original speed (any slower than that and my monitor loses sync) and the problem remains. The Megadrive core meets timing even before I slow it down – so whatever the problem is, I don’t believe it’s a typical run-of-the-mill SDRAM issue – if it were, I would expect to see the errant behaviour changing from build-to-build, and especially in response to changing frequency or phase shift. I wondered if a multicycle constraint was masking a timing issue, but I think the symptom’s too deterministic to be caused by metastability issues.
My gut feeling is that there’s a problem with the SDRAM command sequencing, and the SDRAM chips on MiST, DE10-lite and Chameleon V1 are tolerating it but Chameleon V2 isn’t.
My first line of attack was to try and simplify the situation – remove as many variables as possible, and try and find the simplest possible access pattern that still fails. To do this, I was going to need to create some kind of custom Megadrive ROM, so that I can have full control of access patterns. That means going down the Megadrive homebrew development rabbit-hole!
So I started looking for Megadrive development toolkits and tutorials. I found a GCC-based toolkit which allows Megadrive software to be written in C, and I very quickly realised how spoiled I’ve become thanks to vbcc, vasm and vlink on the Amiga – I literally watched an entire movie while waiting for that Megadrive toolchain to build.
In the end I found some ASM tutorials here: https://blog.bigevilcorporation.co.uk/2012/02/28/sega-megadrive-1-getting-started/ – and used Vasm to assemble some examples (after search-and-replacing “0x” with “$” and “, ” with “,”) – and soon had a “Hello World” example up and running. Sadly such a simple example isn’t enough to make the problem manifest itself.
So the next line of attack is to get the SDRAM controller running under simulation, to make sure there aren’t any timing subtleties I’ve missed, and if it works OK in simulation, create an actual test core that I can run on each platform and compare the output… stay tuned!