Strange sprite 0 hit behaviour on Nintendulator

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

User avatar
rainwarrior
Posts: 8062
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Strange sprite 0 hit behaviour on Nintendulator

Post by rainwarrior »

I'm having a really strange thing happen with my attempt to use sprite 0 hit to cause a scroll split at a variable screen position. My code runs fine in every emulator I've tried except Nintendulator, and also appears to run correctly on my NTSC NES. The ROM also autodetects and compensates for PAL but I do not have a PAL NES to run a hardware test on.

In the attached ROM, a two-pixel wide sprite is placed on pixels 253/254 to trigger a sprite 0 hit. $2002 is polled for the hit, and once detected the scroll split is timed to be written during hblank on the following scanline. To demonstrate the variable position, the sprite will be moved from Y=41 to Y=239, one pixel per frame.

For some reason in Nintendulator the $2002 test appears to fail randomly (maybe on 3% of frames?), causing the scroll split to be missed in overlay_test_1.nes. I can't figure out why.

Does Nintendulator emulate something unusual about sprite 0 hits that other emulators do not? Since it's not happening on my hardware test, I'm wondering if it is a bug in Nintendulator, but I'm worried that it's emulating some rare case that I should really be looking out for.


This is the code that waits for the sprite 0 hit and sets the scroll, you can find it at $801F in memory when the last 32k bank is selected (this uses an oversized 256k BNROM mapper).

Code: Select all

render_overlay:
	lda #1
	sta nmi_lock ; disables NMI temporarily in case sprite 0 hit fails
	:
		; sprite 0 hit doesn't clear until the end of vblank, make sure that's happened
		bit $2002
		bvs :-
	:
		bit $2002         ; will hit after dot 253
		bmi @overlay_fail ; if vblank is detected, we completely missed the sprite 0 hit
		bvc :-
	; [ 4 cycles elapsed since sprite 0 hit ]
	; wait for hblank alignment
	; add 3 dots to get from 254 sprite hit to 257 hblank (1 cycle)
	; a line is 341 dots long (113.6 cycles NTSC, 106.6 cycles PAL)
	; thus, this wait needs: NTSC 84 cycles, PAL 77 cycles (+6 cycles above, +27 cycles below)
	lda player_pal          ; [ 3 ]
	bne :+                  ; [ +2 if NTSC, +3 if PAL ]
		nop
		nop
		nop
		nop
	:                       ; [ 13 NTSC, 6 PAL ]
	; 71 cycles to go
	lda player_pal          ; [ +3 ]
	.repeat 34
		nop
	.endrepeat              ; [ +68 ]
	; [ NTSC 84, PAL 77 cycles waited ]
	; wait finished
	lda #%00001010
	sta $2001            ; disable sprite rendering
	lda #%00000100
	sta $2006            ; 2006.1 > nametable %01
	lda overlay_scroll_y
	sta $2005            ; 2005.2 > Y scroll
	and #%00111000
	asl
	asl
	ldx #0
	; [27 cycles elapsed since wait finished]
	; the last two write should fall in hblank (after dot 256, before dot 320)
	stx $2005            ; 2005.1 > X scroll = 0
	sta $2006            ; 2006.2 > Y scroll bits 3-5, X scroll low bits = 0
	lda #0
	sta nmi_lock
	rts
@overlay_fail:
	lda #0
	sta nmi_lock
	rts
If you need the NMI routine, or other source, I can post it.

In overlay_test_2.nes, the fail-safe line bmi @overlay_fail is commented out, which doesn't make a difference, except in Nintendulator. In Nintendulator the overlay position appears to freeze on frames where the test fails, which I don't quite understand. If it's catching the sprite on the next frame, the scroll should not have been executed. Very puzzling...


I apologize that this isn't a simple test program with full source. I made an attempt to produce a "simpler" test ROM, but so far I have been unable to do so. This is excerpted from a larger program I'm working on.
Attachments
overlay_test_2.nes
(256.02 KiB) Downloaded 139 times
overlay_test_1.nes
(256.02 KiB) Downloaded 155 times
User avatar
Quietust
Posts: 1786
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Re: Strange sprite 0 hit behaviour on Nintendulator

Post by Quietust »

What version are you running? I just tried both ROMs in the latest development build (from April 21, 2013) for several minutes, and I didn't see any glitches.

If you're running an old version, it was probably a bug in the way it emulated OAM overwrite - originally, the sprite fetch logic was using the last value written to $2003 to fetch the first 8 bytes of OAM, but now it overwrites the first 8 bytes of OAM with whatever page the sprite address was pointing at (to more closely match what the real PPU appears to do).
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
User avatar
rainwarrior
Posts: 8062
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Strange sprite 0 hit behaviour on Nintendulator

Post by rainwarrior »

This is happening for me with the 0.975 beta binaries from here, both ANSI and unicode versions, and also with the 0.970 release binaries as well.

For me overlay_test_1.nes the scroll split disappears/flickers noticeably for at least a few frames per loop, usually for several frames at a time when it happens. It's very strange because it is not a consistent pattern; if I restart Nintendulator it will flicker at different times.

The sprite itself still renders in the correct position when the sprite 0 hit fails. Also, the NMI routine writes 0 to $2003 before doing the sprite DMA, so I think that should be okay.
User avatar
rainwarrior
Posts: 8062
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Strange sprite 0 hit behaviour on Nintendulator

Post by rainwarrior »

Hmm, tried it on a different computer and the problem is still there but less frequent. Also seemed to become stable a few seconds after starting execution.

Something really weird, though, if I turn off "auto" frameskip and set frameskip to 1 the scroll flickers on and off at a slow and regular rate, something like 30 frames on, 30 frames off. This is happening on both of my PCs consistently.
User avatar
rainwarrior
Posts: 8062
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Strange sprite 0 hit behaviour on Nintendulator

Post by rainwarrior »

With a frameskip of 0, the problem appears to be gone. (The default setting for frameskip is "auto", I hadn't tried adjusting it before.)
User avatar
Quietust
Posts: 1786
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Re: Strange sprite 0 hit behaviour on Nintendulator

Post by Quietust »

Okay, now I can confirm that it's a bug in the frameskip logic - when it knows nothing's going to make it to the screen, it skips whatever extra logic it can without affecting behavior, but it's clearly skipping too much.

[edit] Fixed - when I switched over to the detailed sprite evaluation logic, I missed a spot in the frameskip code for determining which sprite scanline to fetch (originally, it got a value from 0-15, but now it gets an absolute scanline number). A new build will be available shortly.
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Strange sprite 0 hit behaviour on Nintendulator

Post by tepples »

Sometime in 2011, I remember having seen similar misbehavior with mid-screen pattern table bankswitching when frameskip is enabled. Should I make a test ROM?
User avatar
rainwarrior
Posts: 8062
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Strange sprite 0 hit behaviour on Nintendulator

Post by rainwarrior »

I'm curious why frameskipping is on by default. Since Nintendulator seems oriented toward debugging (esp. how the user is required to manually start execution), I was kind of surprised that this was going on. When developing I'd rather see every frame go by than have the speed be kept even by skipping.

A personal preference, of course. Obviously it's easy to make the setting once you know the feature is there, but I would guess more people would want it off.
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Strange sprite 0 hit behaviour on Nintendulator

Post by tokumaru »

rainwarrior wrote:I would guess more people would want it off.
I certainly do. Whenever I run a new copy of Nintendulator (or any other emulator, for that matter) one of the first things I do is turn frame skipping off (as soon as I notice it's on). I find it annoying enough when playing (if my computer can't run it at full frame rate, I'd rather not play it), and completely unacceptable for debugging.
User avatar
thefox
Posts: 3139
Joined: Mon Jan 03, 2005 10:36 am
Location: Tampere, Finland
Contact:

Re: Strange sprite 0 hit behaviour on Nintendulator

Post by thefox »

I have actually completely forgotten that there even was a frame skipping option in Nintendulator, because I always have it turned off. But I do remember seeing in the sources that there were two separate, almost identical routines (mostly copy&paste) for running the PPU in the skip/non-skip modes (RunSkip() and, RunNoSkip()), and wondering that that must be a hell of a job to maintain. :)
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: fo.aspekt.fi
Ti_
Posts: 42
Joined: Sat Aug 03, 2013 3:08 pm
Location: Russia
Contact:

Re: Strange sprite 0 hit behaviour on Nintendulator

Post by Ti_ »

Nintendulator ,975 (build from 29 April) still have bug with frameskip. (game: ducktales2)
User avatar
Quietust
Posts: 1786
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Re: Strange sprite 0 hit behaviour on Nintendulator

Post by Quietust »

Ti_ wrote:Nintendulator ,975 (build from 29 April) still have bug with frameskip. (game: ducktales2)
Could you be more specific?
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
Ti_
Posts: 42
Joined: Sat Aug 03, 2013 3:08 pm
Location: Russia
Contact:

Re: Strange sprite 0 hit behaviour on Nintendulator

Post by Ti_ »

Quietust wrote:
Ti_ wrote:Nintendulator ,975 (build from 29 April) still have bug with frameskip. (game: ducktales2)
Could you be more specific?
if set to frameskip not 0.
Attachments
nintedulator.PNG
User avatar
Quietust
Posts: 1786
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Re: Strange sprite 0 hit behaviour on Nintendulator

Post by Quietust »

Found it - on sprite 0 hit during frameskip, it was neglecting to clear the "found sprite 0 in this scanline" flag, causing the first sprite on EVERY subsequent scanline to possibly trigger a hit. Should be fixed now.
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
Ti_
Posts: 42
Joined: Sat Aug 03, 2013 3:08 pm
Location: Russia
Contact:

Re: Strange sprite 0 hit behaviour on Nintendulator

Post by Ti_ »

Quietust wrote:Should be fixed now.
Same problem. Have you tested rom?
Post Reply