It is currently Thu Dec 14, 2017 8:19 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 89 posts ]  Go to page 1, 2, 3, 4, 5, 6  Next
Author Message
 Post subject: Micro Machines glitches
PostPosted: Tue Feb 24, 2015 9:22 am 
Offline
User avatar

Joined: Mon Dec 29, 2014 1:46 pm
Posts: 750
Location: New York, NY
Shaky horizontal lines appear on the right-side of some of the screens of Micro Machines in my emulator. The game itself seems to play okay though.

Image

Image

The Tricky-to-emulate games lists mentions, "Micro Machines requires correct values when reading PPU $2004 (OAMDATA) during rendering." What does this refer to exactly?


Top
 Profile  
 
PostPosted: Tue Feb 24, 2015 10:32 am 
Offline
User avatar

Joined: Sat Jan 22, 2005 8:51 am
Posts: 427
Location: Chicago, IL
It's referring to the behavior of $2004 reads during visible scanlines described here: http://wiki.nesdev.com/w/index.php/PPU_ ... evaluation

_________________
get nemulator
http://nemulator.com


Top
 Profile  
 
PostPosted: Tue Feb 24, 2015 11:29 am 
Offline
User avatar

Joined: Mon Dec 29, 2014 1:46 pm
Posts: 750
Location: New York, NY
James wrote:
It's referring to the behavior of $2004 reads during visible scanlines described here: http://wiki.nesdev.com/w/index.php/PPU_ ... evaluation


I carefully implemented that logic (see here), but I'm still getting the Micro Machines glitches. Did I miss something on that page?


Top
 Profile  
 
PostPosted: Tue Feb 24, 2015 12:05 pm 
Offline
User avatar

Joined: Mon Dec 29, 2014 1:46 pm
Posts: 750
Location: New York, NY
Wait a second. I downloaded a different ROM and this one wants to use mapper 71 instead of mapper 2. WTF?

I'll implement that mapper and see what happens...

Edit: Unfortunately, implementing mapper 71 did not help. The graphical glitches still look the same.


Top
 Profile  
 
PostPosted: Tue Feb 24, 2015 12:58 pm 
Offline
User avatar

Joined: Sat Jan 22, 2005 8:51 am
Posts: 427
Location: Chicago, IL
re: mapper 2 vs. 71: http://wiki.nesdev.com/w/index.php/INES_Mapper_071

As far as $2004 reads go, this (hack) should be enough to make Micro Machines work:

Code:
if (rendering)
{
   if (current_cycle < 64)
      return_value = 0xFF;
   else if (current_cycle < 256)
      return_value = 0x00;
   else if (current_cycle < 320)
      return_value = 0xFF;
   else
      return_value = sprite_buffer[0];
}


I don't completely understand what the game is doing here, but it seems that the whole purpose of these reads is to adjust timing:

Code:
...
FD6E:   BIT $2004
FD71:   BMI $FD73
FD73:   PHA
...


The only impact that BMI can have is on the number of clock cycles consumed, so make sure that you're accounting for the extra clock cycle on a taken branch.

_________________
get nemulator
http://nemulator.com


Top
 Profile  
 
PostPosted: Tue Feb 24, 2015 1:29 pm 
Offline
User avatar

Joined: Mon Dec 29, 2014 1:46 pm
Posts: 750
Location: New York, NY
Thanks. That did not solve the problem, but it did have a noticeable effect. It reduced the amount of glitching.

What's the concept behind the hack? Is there an accurate way to do this?


Top
 Profile  
 
PostPosted: Tue Feb 24, 2015 3:03 pm 
Offline
User avatar

Joined: Sat Jan 22, 2005 8:51 am
Posts: 427
Location: Chicago, IL
zeroone wrote:
What's the concept behind the hack?

Micro Machines reads $2004 around dot 320. If the read occurs before dot 320, it needs to see a value with the high bit set (implemented properly, the read would return $FF because it would take place while the PPU is fetching from an empty sprite slot). If the read occurs >= dot 320, it needs to see a value without the high bit set (which it does, because the first byte in secondary OAM is < 0x80).

Quote:
Is there an accurate way to do this?

Yep. Implement it as described on the wiki.

_________________
get nemulator
http://nemulator.com


Top
 Profile  
 
PostPosted: Tue Feb 24, 2015 3:41 pm 
Offline
User avatar

Joined: Mon Dec 29, 2014 1:46 pm
Posts: 750
Location: New York, NY
James, thanks for the reply.

James wrote:
Yep. Implement it as described on the wiki.


I implemented as close to the wiki description as I could, but I must be misinterpreting something.

James wrote:
implemented properly, the read would return $FF because it would take place while the PPU is fetching from an empty sprite slot


I see the wiki says:

Quote:
Cycles 1-64: Secondary OAM (32-byte buffer for current sprites on scanline) is initialized to $FF - attempting to read $2004 will return $FF.


Does that mean that $2004 returns the contents of secondary OAM?

James wrote:
If the read occurs >= dot 320, it needs to see a value without the high bit set (which it does, because the first byte in secondary OAM is < 0x80).


You also seem to be implying that $2004 returns the contents of secondary OAM. What address/offset into secondary OAM is accessed (if it is accessed)?

Why will $2004 return 0 between PPU cycles 64 and 256?


Top
 Profile  
 
PostPosted: Tue Feb 24, 2015 4:14 pm 
Offline
User avatar

Joined: Sat Jan 22, 2005 8:51 am
Posts: 427
Location: Chicago, IL
zeroone wrote:
Does that mean that $2004 returns the contents of secondary OAM?...You also seem to be implying that $2004 returns the contents of secondary OAM. What address/offset into secondary OAM is accessed (if it is accessed)?

$2004 reads return the contents of secondary OAM during these phases:
wiki wrote:
Cycles 257-320: Sprite fetches (8 sprites total, 8 cycles per sprite)
1-4: Read the Y-coordinate, tile number, attributes, and X-coordinate of the selected sprite from secondary OAM
5-8: Read the X-coordinate of the selected sprite from secondary OAM 4 times (while the PPU fetches the sprite tile data)
For the first empty sprite slot, this will consist of sprite #63's Y-coordinate followed by 3 $FF bytes; for subsequent empty sprite slots, this will be four $FF bytes

Cycles 321-340+0: Background render pipeline initialization
Read the first byte in secondary OAM (while the PPU fetches the first two background tiles for the next scanline)

zeroone wrote:
Why will $2004 return 0 between PPU cycles 64 and 256?

$2004 reads at that time will expose what's happening during sprite eval. If you're referring to my code, it's not accurate behavior.

Somebody who has implemented proper sprite eval logic can probably explain it better.

Oh, one more thing: I'm using the "old" PPU cycle terminology: e.g., idle cycle = 340, not 0, so adjust accordingly if you're not.

_________________
get nemulator
http://nemulator.com


Top
 Profile  
 
PostPosted: Tue Feb 24, 2015 4:40 pm 
Offline
User avatar

Joined: Mon Dec 29, 2014 1:46 pm
Posts: 750
Location: New York, NY
James wrote:
$2004 reads return the contents of secondary OAM during these phases


What address of secondary OAM does it return?

James wrote:
$2004 reads at that time will expose what's happening during sprite eval.


By returning what exactly?


Top
 Profile  
 
PostPosted: Wed Feb 25, 2015 10:53 am 
Offline
User avatar

Joined: Mon Dec 29, 2014 1:46 pm
Posts: 750
Location: New York, NY
Here is the $2004 read according to Nintendulator:

Code:
int   __fastcall   Read4 (void)
{
   if (IsRendering)
      readLatch = Sprite[SpritePtr];
   else   readLatch = Sprite[SprAddr];
   return readLatch;
}


The Sprite array appears to represent both primary and secondary OAM.

According to the wiki:

Quote:
Reading OAMDATA while the PPU is rendering will expose internal OAM accesses during sprite evaluation and loading; Micro Machines does this. It used to be thought that reading from this register wasn't reliable, however more recent evidence seems to suggest that this is solely due to corruption by OAMADDR writes. In the oldest instantiations of the PPU, as found on earlier Famicoms, this register is not readable. It's not known exactly which revision of the 2C02 added the readability—it is certainly absent in the RP2C02C, and present by the RP2C02G.


Can someone please provide more information? The wiki seems incomplete.

Edit: On a side note, FCEUX 2.2.1 looks more screwed up than my emulator:

Image

Image


Top
 Profile  
 
PostPosted: Wed Feb 25, 2015 2:31 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10164
Location: Rio de Janeiro - Brazil
FCEUX is pretty bad at emulating these kinds of obscure quirks.


Top
 Profile  
 
PostPosted: Wed Feb 25, 2015 2:35 pm 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3076
Location: Brazil
If the rendering is disabled and the PPU address is between $3F00-$3F1F, that's the color it outputs.


Top
 Profile  
 
PostPosted: Wed Feb 25, 2015 3:23 pm 
Offline
User avatar

Joined: Mon Dec 29, 2014 1:46 pm
Posts: 750
Location: New York, NY
Quote:
If the rendering is disabled and the PPU address is between $3F00-$3F1F, that's the color it outputs.


Can you elaborate on this?


Top
 Profile  
 
PostPosted: Wed Feb 25, 2015 3:48 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19343
Location: NE Indiana, USA (NTSC)
  • If rendering is disabled, and the current VRAM address is $0000-$3EFF, the PPU will output the color at $3F00.
  • If rendering is disabled, and the current VRAM address is $3F00, the PPU will output the color at $3F00.
  • If rendering is disabled, and the current VRAM address is $3F01, the PPU will output the color at $3F01.
  • If rendering is disabled, and the current VRAM address is $3F02, the PPU will output the color at $3F02.
  • If rendering is disabled, and the current VRAM address is $3F03, the PPU will output the color at $3F03.

It stores a table of colors at $3F00-$3F1F and expects to be able to switch to the next color by reading one byte from or writing one byte to the VRAM data port, which advances the VRAM address by 1.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 89 posts ]  Go to page 1, 2, 3, 4, 5, 6  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 6 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group