Also I have never used a message board before so sorry if my formatting is wack.
Perhaps a more skilled person will reply, but when I started out I remember two rows of random tiles along the top of my screen. It seems that those horrible rows vanished after I used the debugger to step through a frame of my code. As a result of those steps, I noticed that vblank would keep running for an entire frame, and then, vblank would interrupt itself and restart before it finished.
The fix involved using vblank entirely for (mostly) PPU operations (i.e. reads/writes to $2000, $2001, $2002, $2003, $2004, $2005, $2006, $2007). I had to move a lot of non PPU code out of vblank into my main loop. And, since vblank is pretty short, I implemented buffer use (i.e. fill an area of RAM, a buffer, with a bunch of appropriate values during main loop, and then, during vblank, use a simple loop to transfer that buffer’s values to the PPU); that massive game restructuring removed those two lines of random tiles at my screen’s top.
Maybe your game is perishing like mine was? Hope this helps.
edit: Ooh, just be sure to also never access the PPU outside of vblank. Otherwise, then the screen will also perish bc vblank is, normally, the only time that the PPU is dormant. When the PPU is active it hates being accessed; that’s surely evident by what appears on your screen.
- Make sure you are writing into the PPU address register correctly. For the top left corner of nametable 0, this should be #$20 and then #$00 into ($2006), followed by writes for your tile values into PPU data register ($2007).
- If this is correct, your Y scroll position could be corrupted. Writing two #$00's to the scroll register ($2005) after all ($2007) writes will reset your scroll position. Make sure you are still in vBlank (before scanline 0 begins).
Anyway, you can check the FCEUX nametable viewer. If your tiles are in the top left corner of that, the scroll register is incorrect. If they are not, then your PPU address is incorrect. If it is neither of these things, then post your code and let us know. We'll get you up and running!
Ok. It looks like your Y scroll value is somewhere between 240 - 255, and is showing pieces of the attribute table as tiles. My guess is that your scroll value update is coming after vBlank is over, which will corrupt the scroll position. You can test this in the step through debugger. Hit [Run Line] and [Step Into] as you follow your code and make sure that your ($2005) scroll values are both the last thing being set after ($2007) writes are done and before the scanline = -1
If you post your code, it would be much easier to help!
Ok, i recompiled your stuff and it doesn't seem like you were setting $2005 at all. I hastily threw in a scroll position set into your vBlank routine. Seems fine now.
Anyway, i noticed you were updating sprites after reading your controllers. You don't want to be doing that: it isn't sustainable. You only have 20 scanlines to do all of your graphics updates (in most cases), so, you have to structure your code in a way that that happens. It is okay to set the $200 region and wait until next frame to update your screen. Rule of Thumb: Do all graphics updates first, and then do everything else.
Code: Select all
VBLANK: ; Do all graphics related updates here LDA #$02 STA $4014 ; Reloads sprite stuff ; Set your scroll position after $2007 writes, etc. LDA #$00 STA $2005 STA $2005 ; Do everything else here... JSR ResetController JSR ReadUserInput JSR CheckRightPressed RTI
Anyway, this should get you going for now. I'm sure you'll have more questions as you go along. Don't be a stranger. Good luck!
Yep. The screen is 256x240. The Y position goes right from 239 to 0 when drawing the screen. If you set the Y position from 240 - 255, the NES gets very confused and draws the end of the attribute table as tiles.
So uh, don't do that
You can verify this by turning off sprite rendering by setting bit 4 of $2001 to 0 in vBlank. If it is a sprite, check your $200 page in the memory viewer to see which one it is. All sprite slots on a page copy with the $4014 DMA (in most cases).