It is currently Sun Dec 17, 2017 4:31 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 9 posts ] 
Author Message
PostPosted: Tue Jul 12, 2016 2:59 am 
Offline
User avatar

Joined: Sun Jun 05, 2016 1:41 pm
Posts: 74
Dizzy The Adenturer (CRC: DB99D0CB) runs on the Camerica mapper (mapper 71), which is a very basic mapper.

The game however seems to use some kind of interrupt, which I assume is the Vertical blank NMI, to split the screen close to the top so that the top strip contains the game's status panel, whilst the bottom second contains the game level. As with all Dizzy games (that I know of), the game doesn't use scrolling and instead flips the screen when Dizzy reaches an edge.

In my emulator I am experiencing what seems to be a 1 pixel vertical jitter in the game level, as if the code is alternating the Y scroll value by 1 pixel every other frame.

Does anyone have any idea why this is happening please? I am suspecting some kind of frame timing issue in my own code, but I can't seem to find a solution.

_________________
Tile IDE and tile engine for XNA: http://tide.codeplex.com/
Fancy Fish Mod - Minecraft Mod: http://fancyfishmod.weebly.com/


Top
 Profile  
 
PostPosted: Tue Jul 12, 2016 3:58 am 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 3192
Location: Mountain View, CA, USA
Camerica / mapper 71 games tend to be very anal about timing precision.

I loaded this game up (MD5: 7dc7d65ea289fbbb32cb76cffb2c31c7 *Dizzy The Adventurer (Camerica) (Aladdin) [!].nes) in NO$NES to see how it was doing the screen split -- looks like it might use sprite 0 to help with this (it's X/Y location is $92/$25, tile $00, and it has the priority bit set). I imagine this is compounded by very precise code.

You're correct that the game doesn't "scroll" in the sense that there's no real-time "panning" of the screen.

Take a look at the game in NO$NES (you'll find Window -> VRAM Viewer and Window -> I/O Map to be quite useful, especially since the registers update in real-time) and in Nintendulator (if you look very carefully in Nintendulator on either the first game screen or after finishing the first puzzle + moving to the next screen, you'll see some of sprite 0's pixels partially visible). Nintendulator tends to have extremely precise PPU emulation. Sadly I don't have this cart to try out on actual hardware to determine what it looks like there.

Is it at all possible to get an animated GIF (should be 2 frames? Maybe 3?) or video or something so we can see what's happening?


Top
 Profile  
 
PostPosted: Tue Jul 12, 2016 6:01 am 
Offline
User avatar

Joined: Fri Nov 19, 2004 7:35 pm
Posts: 3969
Double check your sprite 0 hit, and the timing on when T and V are assigned.
The game isn't timing from an interrupt, it's timing from the sprite 0 hit.

_________________
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!


Top
 Profile  
 
PostPosted: Tue Jul 12, 2016 6:30 am 
Offline
User avatar

Joined: Sun Jun 05, 2016 1:41 pm
Posts: 74
I ended up adding some GIF capture functionality for this. :)

Here's a capture of the gameplay:
Image

It looks like the level is scrolling up and down by 1 pixel, hence what I called "jitter".

_________________
Tile IDE and tile engine for XNA: http://tide.codeplex.com/
Fancy Fish Mod - Minecraft Mod: http://fancyfishmod.weebly.com/


Top
 Profile  
 
PostPosted: Tue Jul 12, 2016 7:13 am 
Offline
User avatar

Joined: Fri Nov 19, 2004 7:35 pm
Posts: 3969
Anyone who's ever worked on a NES emulator knows about scrolling jitter.

According to a quick run of Nintendulator:
First 2006 write happens on scanline 40, beginning at dot 233-243
then there are three more writes: 12 dots later, 321 dots after that, 12 dots after that.

Make sure your $2002 read is getting PPU status from the correct time, at the end of the read instruction, not the beginning of the instruction.
Likewise, make sure your 2006 writes are taking effect at the end of the STX/STY instruction, not the beginning of the instruction.

_________________
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!


Top
 Profile  
 
PostPosted: Tue Jul 12, 2016 7:27 am 
Offline
User avatar

Joined: Sun Jun 05, 2016 1:41 pm
Posts: 74
Thanks for the detailed info Dwedit.

In my emulator I essentially step one instruction at a time, determine the cycles consumed, multiply by 3 to get the corresponding PPU cycles and then step the PPU accordingly. This essentially means that PPU status is determined at the start of the instructions, not the end. I will have to find a way of going around this.

_________________
Tile IDE and tile engine for XNA: http://tide.codeplex.com/
Fancy Fish Mod - Minecraft Mod: http://fancyfishmod.weebly.com/


Top
 Profile  
 
PostPosted: Tue Jul 12, 2016 7:38 am 
Offline
User avatar

Joined: Sun Jun 05, 2016 1:41 pm
Posts: 74
Turned out I had a problem with the NMI delay triggered by the PPU. I set this to 21 PPU cycles (7 CPU cycles) and this solved the jitter.

For all I know it is working as a side effect of this, but I think I had the VBL - NMI timing a bit off anyway.

_________________
Tile IDE and tile engine for XNA: http://tide.codeplex.com/
Fancy Fish Mod - Minecraft Mod: http://fancyfishmod.weebly.com/


Top
 Profile  
 
PostPosted: Tue Jul 12, 2016 8:00 am 
Offline
User avatar

Joined: Fri Nov 19, 2004 7:35 pm
Posts: 3969
Games will almost always use 4-cycle instructions (LDx/STx absolute) to read/write from hardware registers, so you can get away with treating reads/writes as happening 12 dots later than the timestamp at the start of the instruction. Of course, this is not accurate if a game decides to use another addressing mode (like (nn,X) or (nn),Y), or uses a read-modify write instruction with dummy read triggering something else entirely.

_________________
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!


Top
 Profile  
 
PostPosted: Tue Jul 12, 2016 9:15 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19354
Location: NE Indiana, USA (NTSC)
Dwedit wrote:
Of course, this is not accurate if a game decides to use another addressing mode (like (nn,X) or (nn),Y), or uses a read-modify write instruction with dummy read triggering something else entirely.

The only practical use I can see for this is a test that uses open bus behavior to tell the difference between Famicom, US front-loading NES, US top-loading NES, and an NES with a PowerPak, or to detect attached controllers. Fill the nametable with known data like $00 and $FF, then read it back at $3F18,X (with X set to $FF) and see which bits ride the open bus from the read from $3F17 (mirror of $2007) to $4017 (controller 2).


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 9 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: Bavi_H, Bing [Bot] and 4 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