Page 2 of 2
Posted: Wed Nov 29, 2006 11:32 pm
by Disch
oh yeah -- whoops ^^
Posted: Thu Nov 30, 2006 7:22 pm
by CartCollector
Here's the source with bug fixes and the compiled file. The only thing is, it delays for 2 seconds (I counted about 120 frames in Nintendulator' frame stepper), moves right one pixel, then starts scrolling left. What's causing that?
Oh, and I have some extra stuff in the source (like everything under "ScrewingWithScanlines"). I'ts unorganized stuff I might use once I get this working.
Posted: Sat Dec 02, 2006 4:12 pm
by CartCollector
So, has anyone tried it? How did it run for you?
Posted: Sat Dec 02, 2006 6:12 pm
by Celius
Well, I tried the demo, and it doesn't really scroll... At all... I tried it on both FCEUXD and Nintendulator, and it just scrolled 1 pixel. And I waited for a long time, like 20 seconds. Maybe I missed something, but it didn't work for me.
Posted: Sat Dec 02, 2006 7:06 pm
by Quietust
Looks like you're reusing variables without reinitializing them. When the first NMI hits, $00 is set to #$90 and $01 is set to #$94, which is causing the screen to be scrolled REALLY far to the right - once $00 overflows past zero and up to 4 (exactly 116 frames), THEN it sets horizontal scroll to 0, 1, 2, 3, etc.
Posted: Sat Dec 02, 2006 7:24 pm
by CartCollector
Oh yeah, I forgot I was using $00 and $01 for the name table loading. So, I just changed the locations of my variables, and it works! Thanks Quietust!
Okay, now there's other things I'd like to know.
1) How long is the time, in CPU cycles, between the end of rendering one scanline and the start of rendering the next (aka HBlank)?
2) I've read that the MMC3 interrupts can be triggered up to 7 CPU cycles before the scanline ends. How long should I delay before I start writing to the PPU?
3) I notice that in many demos, there's "shearing" between scanlines where mid-frame scroling takes place. What can be done to prevent ths? I read somewhere that you can't scroll more than 8 pixels without shearing, citing Chris Covell's CMCWavy demo. I was also thinking I could have certain scanlines where I do scrolling solid colors, but I don't know which scanline would shear (the one before or after the HBlank scroll).
Posted: Sat Dec 02, 2006 8:05 pm
by tepples
CartCollector wrote:1) How long is the time, in CPU cycles, between the end of rendering one scanline and the start of rendering the next (aka HBlank)?
Each scanline is 341 PPU cycles, consisting of 256 cycles of draw and 85 cycles of hblank, and there are 3.00 (NTSC) or 3.20 (PAL) PPU cycles in a CPU cycle. So hblank is a hair longer than 28 (NTSC) or 26 (PAL) CPU cycles; don't count on being able to run more than about 8 instructions.
2) I've read that the MMC3 interrupts can be triggered up to 7 CPU cycles before the scanline ends. How long should I delay before I start writing to the PPU?
If you're having trouble getting the whole screen to scroll, you might want to wait a while before tackling an MMC3 split. But if you feel ready to do an MMC3 scroll split, it's best to use a little less than one scanline (113.667 cycles on NTSC) to set up the registers first.
3) I notice that in many demos, there's "shearing" between scanlines where mid-frame scroling takes place. What can be done to prevent ths? I read somewhere that you can't scroll more than 8 pixels without shearing, citing Chris Covell's CMCWavy demo.
As I understand it, the problem here is that the high order bits (8's place) of the horizontal scroll take effect only at the end of the scanline, while the low order bits take effect immediately. This precise behavior of the PPU was not well understood back then.
Posted: Sat Dec 02, 2006 8:27 pm
by Disch
Tepples has a great post but there are a few points I want to touch on:
- The PPU is never really idle during rendering time. Even in 'HBlank' it's doing stuff. During cycles 320-340 of the scanline, the PPU is fetching tiles which will be displayed on the next scanline -- and up to cycle 251, the PPU is still using the VRAM address for rendering purposes. Therefore, if you want to be sure to avoid ALL forms of tearing/stray pixels/and other unwanted artifacts when splitting the screen, you'll want to keep your $2005/$2006 writes all between cycles 252-319... which gives you 67 PPU cycles of work time... which is about 22 CPU cycles (not quite 28) IF you manage to hit that first cycle at exactly the right time! Considering it's impossible to hit that cycle every time, you should give yourself a few cycles of "padding" -- maybe keep it down to 18 or 16 cycles if you want to be really safe.
Being off by a few cycles probably won't be that big of a deal... but it may cause unwanted rendering artifacts.
- I concur with tepples on the MMC3 deal. When I glanced at your demo it didn't look like you were even setting MMC3 up -- you just assigned your ROM to be mapper number 4. I would stick with mapper 0 until you get pretty comfortable. Mappers, while powerful, add more complication to the picture. MMC3 in paticular has a few funky rules you have to follow for the IRQs to work like you'd expect.
Posted: Sat Dec 02, 2006 9:05 pm
by tepples
Until you know exactly what you're doing, stick to splits using the sprite 0 overlap bit of the PPU status register. Commercial NES programmers made do just fine with sprite 0 in the two to three years between when Balloon Fight first split the screen and when the MMC3 was introduced.
Posted: Thu Mar 22, 2007 8:11 am
by albailey
I had a scrolling bug and this thread helped me fix it.
It turned out I was setting scroll and VRAM to zero in my resetHandler infiniteLoop when I was setting up my NMI statemachine to go to scrolling.
Now I am behaving myself and only playing with those during NMI.
Thanks,
Al