irixxxx/picodrive

handle the direct color / "fantom bitmap" "mode"

Closed this issue · 13 comments

notaz commented

It's basically DMAing to CRAM while VDP only shows the background color. Never got around to emulating it, but it shouldn't be too hard to detect and handle.

Description: https://gendev.spritesmind.net/forum/viewtopic.php?f=8&t=1203
Introductory video: https://www.youtube.com/watch?v=eYYeGy47UJE
Compiled ISO from the video, so you don't have to: https://notaz.gp2x.de/md/mirror/people/matteusbeus/

Since RaycastDemo is sort of playable (and not just a single image like many other demos) it would be nice to have it work.

Actually I didn't dare trying to implement it since it's extremely timing sensitive and PicoDrive internal timing just isn't that accurate. I'll put it on my list, but don't hold your breath...

notaz commented

I think it should be possible to fake it with reasonable accuracy without touching the current VDP code. Basically when drawing a line, if 16bpp renderer is on and dma to cram is active without autoincrement, just take the DMA data and copy it to appropriate columns. Wouldn't that work? 68k is stalled so nothing should be interfering with this.

It depends. If the regular case is that the DMA-transferred data is aligned with the start of the display area that's perfectly OK. If however there's some fill data added for alignment purposes it won't work correctly.
It's also usually the background color the DMA is overwriting. Is there a technical reason for this, or would every other color work the same? (scrap that. It can't be right.)

notaz commented

IIRC the DMA start code sequence is quite sensitive to get it all stable, so there shouldn't too many variations of it and just hardcoding some constant to skip the padding might work.

Here's an ugly POC hack I did last night for checking the basics:

y.txt

It assumes always having color DMA mode if destination is CRAM and increment is 0. No further checking done, and no idea if this is (unintentionally?) done somewhere in any real world game. No proper checking for edge conditions etc.

Comments welcome.

notaz commented

Looks and works good enough I think.

It's not working for the dmabmp1 and 2 versions from the thread you linked to.
A lot of the others have a shift of 2 pixels to the left or right.
There's a problem with h32 images which have heavy shifts left or right.

I can't get it right though. The vdp timing is just not good enough for this. IMO the main problem is that on 68k (and z80 FWIW) memory access the exact cycle of that access is not known since fame/cyclone instruction billing is only done at the end of the instruction, but the instructions have very different execution times, so the cycle count for the memory access isn't good enough. That leads to some inaccuracy in the vdp cycle timing.

notaz commented

It's weird that dmabmp1 and 2 are misaligned while dmabmp4 and dmacolor7 are ok even though their dma code seems to be the same?

notaz commented

You forgot to add source when calculating colbase.

A lot of the others have a shift of 2 pixels to the left or right.
There's a problem with h32 images which have heavy shifts left or right.

Even with that I think it's much better than not supporting it at all.

You forgot to add source when calculating colbase.

Tsk tsk. Sorry for that, late night programming.

Even with that I think it's much better than not supporting it at all.

Here's a slightly more elaborate version which IMHO fares noticeably better, also some cleanup and some testing for DMA really going to the BG color:

y.txt

notaz commented

LGTM

Leftover work to do: softscaling for h32, and some ARM assembly in FinalizeLine.

added with 724db45