EA logo VDP control port bug

For anything related to VDP (plane, color, sprite, tiles)

Moderators: BigEvilCorporation, Mask of Destiny

Post Reply
vext01
Interested
Posts: 24
Joined: Sat Sep 15, 2012 12:20 am

EA logo VDP control port bug

Post by vext01 » Sun Oct 21, 2012 8:56 pm

Hi,

In my last post I mentioned that the flipping EA logo (at the start of many genesis games), is corrupted in dgen/sdl.

Stef said:
The EA logo is just a problem with write to VDP CTRL port. I don't remember the detail but i know this has something to do with VDP internal command state (first or second command word about to be written).
I have been reading Charles' VDP notes and found some reference to what Stef may be referring to:
Since the 68000 treats 32-bit memory access as two 16-bit operations,
you can program two registers at once:

; Set split point bits for both window registers
move.w #$91809280, $00C00004
Looks like this is gnu syntax asm, that would be: mov #$91809280 -> $00C00004. So if you move a 32-bit data value into a memory address it writes twice. In the above case once at 00C00004 and again at 00C00006.

I found the following code, which seems to tally up:
extern "C" void m68k_write_memory_32(unsigned int address, unsigned int value)
{
md::md_musa->misc_writeword(address, ((value >> 16) & 0xffff));
md::md_musa->misc_writeword((address + 2), (value & 0xffff));
}
This seems correct. I have tried changing the order of the writes, with no joy.

So does anyone know anything about this EA logo bug?

Thanks

vext01
Interested
Posts: 24
Joined: Sat Sep 15, 2012 12:20 am

Post by vext01 » Sun Oct 21, 2012 9:01 pm

Ah:
In order for the VDP to know if the first or second 16-bit half of the
command word has been written to the control port, it maintains an internal
write-pending flag. This flag is updated when these conditions are met:

- It is set when the first half of the command word is written.
- It is cleared when the second half of the command word is written.
- It is cleared when the data port is written to or read from.
- It is cleared when the control port is read.
...
May have answered my own question.

Charles MacDonald
Very interested
Posts: 292
Joined: Sat Apr 21, 2007 1:14 am

Post by Charles MacDonald » Sun Oct 21, 2012 9:40 pm

May have answered my own question.
That's basically it; the first write sets the lower 14 bits of the VRAM address, the second write sets the upper 2 bits. Some games write all 32-bits first, then later write single words to the control port to change the lower 14 bits of the address. Batman & Robin is another one.

Once interesting side effect is that the upper 2 address bits are latched, such that if you set the address to, say, $8000, do enough I/O to make the address increment to $CA00, and then write a single word to the control port, the upper 2 bits are reloaded with the latched value and the address is back to $8xxx.

If you are getting other EA games to work, some of them set register $8C to $01 (not $81) which is an alias for the 320-pixel width display, and some of them use the invalid horizontal scroll mode (I forget the bit pattern) where the scroll table is indexed by "line & 7" such that the first 8 scroll words are applied to each line repeatedly going down the display.

Since the EA games were initially unlicensed they did a lot of weird stuff. :)

vext01
Interested
Posts: 24
Joined: Sat Sep 15, 2012 12:20 am

Post by vext01 » Sun Oct 21, 2012 9:54 pm

Hi Charles,

Hope all is well.

Well I see the code attempting to deal with two word vdp writes:
http://dgen.git.sourceforge.net/git/git ... =HEAD#l383

Note the use of coo_waiting. This looks mostly correct (maybe). Or atleast it seems to cache the first word until the second is received.

I'm going to have to think about it some more. It has not clicked yet.

Thanks for the reply.

vext01
Interested
Posts: 24
Joined: Sat Sep 15, 2012 12:20 am

Post by vext01 » Sun Oct 21, 2012 10:50 pm

OK, so a VRAM fill would be an operation that could cause "enough IO" right?

So it seems there are three potential issues:

* Writing 32 VRAM address bits, then later only the upper most.
* Latching
* Invalid scroll modes.

In the first, how can you write only the single word to change the lower address 14-bits? The VDP is waiting for the second word. Is this where we would read the VDP data port for example to reset the pending flag?

Attached are some screenshots of the EA logo at the start of Mutant Leauge Hockey (one of my favorite games). It starts looking almost right and then corrupts into these weird vertical bars.

Which of the three behaviors do you reckon it is that is causing this?

Image

Image

Thanks

Charles MacDonald
Very interested
Posts: 292
Joined: Sat Apr 21, 2007 1:14 am

Post by Charles MacDonald » Tue Oct 23, 2012 12:25 am

In the first, how can you write only the single word to change the lower address 14-bits? The VDP is waiting for the second word. Is this where we would read the VDP data port for example to reset the pending flag?
Yeah it's waiting for the second word, but the question is what does the VDP do with the first word? Where do those 16 bits go?

You could assume it has 16 bits of internal storage to hold data from the first write, which isn't used until the next 16 bits are written. That what DGen does now.

But what we found through testing was that the first write directly updates 14 of the 16 VRAM address bits. There is no internal storage, the new address bits written go into the current 16-bit VRAM address. And several games depend on that functionality by only writing one word to the control port to change the lower 14 bits of the VRAM address.

vext01
Interested
Posts: 24
Joined: Sat Sep 15, 2012 12:20 am

Post by vext01 » Wed Oct 24, 2012 11:39 am

Hi,

So myself and a friend implemented the following:
- Update address immediately after receiving half a command (first 16-bits)
- Reset the pending flag on register or data read.

This helps a lot, but is still not quite right. Notice that half of the text is missing:

Image
Image
Image

I *think* this is a different bug, but I can't be sure. What do you guys think?

Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Post by Stef » Wed Oct 24, 2012 3:06 pm

vext01 wrote:Hi,

So myself and a friend implemented the following:
- Update address immediately after receiving half a command (first 16-bits)
- Reset the pending flag on register or data read.

This helps a lot, but is still not quite right. Notice that half of the text is missing:
That is what i needed to fix the EA logo in Gens.
I guess you're close now, honestly I don't remember about the address update from half command... I think i never needed it in Gens.

Eke
Very interested
Posts: 885
Joined: Wed Feb 28, 2007 2:57 pm
Contact:

Post by Eke » Wed Oct 24, 2012 5:40 pm

Seems like a DMA that copy the bottom text data in VRAM is only partially (half) handled. Remember that for some operations, the DMA length set in registers $19,$20 represents a value in words and for some others it's in bytes, maybe it's the cause of the issue :?: :?:

vext01
Interested
Posts: 24
Joined: Sat Sep 15, 2012 12:20 am

Post by vext01 » Wed Oct 24, 2012 11:03 pm

Boom!

Image

I had missed a couple of flag clearing cases. Did a load of refactoring whilst I was there. It's in the 'ea_logo' branch of our git repo if anyone is interested.

Big thanks to everyone that helped. I think we plan to make a release fairly soon!

There are at least two other vdp bugs in dgen that I know of, so I will be back :D

Post Reply