Turned out, it doesn't use DMA. The routine which fills CRAM before the wrong display is at 000078f0. It's not the same routine which fills CRAM at other places. Now trying to find out, why these instructions don't trigger a data upload in the VDP.MasterOfGizmo wrote:
Are we sure DMA to CRAM works at all? Do other games use that?
Also i read here and there that DMA to CRAM happens with an auto increment of 0.
Upd: I think I found it. It uses MOVE w. D0, $4(A6), which writes one word to the control port. So it start to set up the transfer. However it doesn't write another word, so the transfer address and code's second half is just what was left there. At the end, the CODE field ends in 13h. But the VDP doesn't trigger a CRAM write only for "00011" (which is documented in the VDP Wiki). So have to find out, how to handle these undocumented codes.
Upd2: the code seems to be broken in more aspects, too, e.g. without the second write, it won't set up the address. Also strange if the CODE is not correct, and no DMA FILL in progress, it just asserts FF_DTACK_N? Why? And if DMA FILL is in progress, shouldn't it just ignore CODE, and use the value for FILL?