Friday 8 December 2023

Is your RAM OK?

Another very productive day!

I started out trying to get the code a bit further to display more on the screen. I was frustrated by the inefficient process of tracing execution via the waveforms in gtkwave. I had already written a crude "breakpoint" mechanism that simply halted the execution at that point, but it required re-compiling the simulation to change the address. So next task was to implement something more convenient.

After undergoing a baptism by fire with ImGui I ended up with some GUI elements allowing me to type in a breakpoint address, display the current address on the bus (PC), and the data bus values. I also added a button to go to the next address that was doing an instruction fetch (it was too complex for now to work out how to step to the next actual instruction - I was in a hurry).

CPU 'debugger' in the Verilog simulator

Now back to tracing the program and working out where it was spinning. Again, going back to my original MAME driver to look at the H8/3002 hacks, I implemented the very crude CUSKEY hack that ultimately allowed the RAM test to PASS. Then it was more RE in IDAPro trying to get it to jump to the full SELF TEST menu screen - to no avail. 1MB of code is a *lot* to search through!!!

Eventually I found it was spinning on a RAM address, waiting for the value to change. It appears that value is being changed in one of the ISR's. I had written the code to generate the VBLANK interrupt from the YGV608 and hook it up to the 68K core, but I hadn't seen it actually working. So I hooked it up again and all hell broke loose. I'm yet to confirm but it appears that as soon as interrupts are enabled in the core, it tries to service the pending VBLANK and fetches the INITIAL STACK POINTER vector and jumps there... have to look further into it as I'm no 68K hardware expert.

Changing tack for the day I decided to clean up the YGV608 Pattern Generator (tile display engine), re-writing it to support all 4 pattern plane modes and various page sizes. That required work on the register side that writes the pattern name table RAM, and the pattern generator itself. But as I knew it would, the logic shrinks down when you optimise it properly, though I have opted at this stage to tend to keep it readable. Finally I could see 'RAM OK' instead of a bunch of zeroes.

Last task was to account for the pipeline delays in the pattern generator and color bus to fix the clipping of characters. After hand-drawing a timing diagram in my 'retro project' notebook, it was obvious where I had to pipeline some counters, and only two compiles to get it right!

The first really clean display - simulation output

So a fairly clean display. I haven't accounted for the pipeline delays between the border and the pattern planes yet, hence the extra lines either side of the border. I should also note that I've only really just scraped the surface of the YGV608 functionality thus far, even where the pattern planes are concerned. There's the virtual screen made of (repeating) pages of planes, flipping, reversing, scrolling regions, transparency, mosaic displays, display priorities, name table mapping modes.... not to mention sprites and rotation! Having said that, I didn't even implement every function in the MAME driver either!

So next... I think I'll have to get interrupts working to get much further in executing the code. No point implementing YGV608 features that can't be tested!

No comments:

Post a Comment