It is currently Tue Nov 13, 2018 8:36 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 4 posts ] 
Author Message
PostPosted: Thu Oct 18, 2018 12:00 pm 
Offline
User avatar

Joined: Wed Sep 05, 2018 11:13 am
Posts: 141
Location: Colorado
So I'm trying to create an asteroid out of background tiles and I'm running into issues where garbage is showing up in my background under certain conditions.

If I write 4 or 5 tiles to the background everything is fine. I am trying to copy over 4 entire rows of tiles starting with the top left corner of my large asteroid. (this isn't meant to be a long term solution, just a test)

Code:
    lda PPU_STATUS        ; PPU_STATUS = $2002
    lda #$21

    sta PPU_ADDR          ; PPU_ADDR = $2006
    lda #$08
    sta PPU_ADDR          ; PPU_ADDR = $2006

    @render_loop:
        lda asteroid_background,x ;#LARGE_ASTEROID_SPRITE_START
        sta PPU_DATA   

        inx
        cpx #40   ; I've been playing with this number
    bne @render_loop


If I tweak the cpx at the bottom to have #4 or #5 in it, the copy works fine. If I have #40 or #50 I get garbage all over the background.

I also tried something roughly like this (killed the code so this isn't exactly what I was testing).

Code:
    lda PPU_STATUS        ; PPU_STATUS = $2002
    lda #$21

    sta PPU_ADDR          ; PPU_ADDR = $2006
    lda #$08
    sta PPU_ADDR          ; PPU_ADDR = $2006

    @render_loop:
        lda asteroid_background,x ;#LARGE_ASTEROID_SPRITE_START
        sta PPU_DATA   

        inx
        cpx #4
    bne @render_loop


    lda PPU_STATUS        ; PPU_STATUS = $2002
    lda #$21

    sta PPU_ADDR          ; PPU_ADDR = $2006
    lda #$28
    sta PPU_ADDR          ; PPU_ADDR = $2006

    @render_loop_2:
        lda asteroid_background,x ;#LARGE_ASTEROID_SPRITE_START
        sta PPU_DATA   

        inx
        cpx #4 
    bne @render_loop_2




This also gives me garbage in my background.

Do I have too much code in my nmi? Or am I fundamentally doing this the wrong way?

Thanks

_________________
A few of my web games
https://www.embed.com
Or if you're bored at work
https://www.classicsolitaire.com


Top
 Profile  
 
PostPosted: Thu Oct 18, 2018 2:06 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 3676
Location: Mountain View, CA
Two immediate causes I can think of:

1. Exhausted available time in NMI -- Mesen makes figuring this out quite a bit easier than others; Lua scripts may be involved, otherwise breakpoints and staring at CPU cycle counters in the emulator
2. Nuances related to https://wiki.nesdev.com/w/index.php/PPU_scrolling -- this page will probably destroy your soul, but it matters tremendously WRT $2000 / $2002 / $2005 / $2006.

What I've said here probably does not help you at all, so I'm questioning even clicking Submit at this point.


Top
 Profile  
 
PostPosted: Thu Oct 18, 2018 2:35 pm 
Offline
User avatar

Joined: Wed Apr 02, 2008 2:09 pm
Posts: 1251
You have about 2270 cycles after the NMI happens to safely write things to $2007 (PPU_DATA ) (and $4014 for the sprite DMA).

I realize you've said this isn't your exact code. But I notice it doesn't initialize X. If X was already 40 before you started, one of the loops would run 256 times.

Another weird thing is you're saying you want to write four rows of tiles, but a row is only 32 tiles long, not 40 which might be part of the problem. (The screen is 256 pixels across. Divide that by 8 to get 32.)

Looking at the loop:
Code:
@render_loop:
        lda asteroid_background,x ;4 cycles
        sta PPU_DATA;4 cycles   

        inx;2 cycles
        cpx #40;2 cycles
        bne @render_loop;3 cycles (for all but one loop)

So 15 cycles for 39 of these loops, 14 cycles for one of them. That's only 599 cycles. But if you do it four times, that's 2396 cycles. You'd be over time. Also remember that sprite DMA takes 513ish cycles. So if you copied and pasted the above loop 4 times, and sprite DMA'd you'd be at 2909 cycles. Way over.

So
1. Make sure you're initializing X before each loop starts.
2. Rows are 32 tiles not 40.
3. Even with 32 tile rows, loops like this will be too slow to do 4 loops with a DMA.

You can unroll your loops. (You always know you'll be writing 32 tiles, so:
Code:
ldx #0
lda asteroid_background,x ;4 cycles
sta PPU_DATA ;1 write
inx
lda asteroid_background,x ;4 cycles
sta PPU_DATA ;2 writes
inx
lda asteroid_background,x ;4 cycles
sta PPU_DATA ;3 writes
;etc

Which is only 10 cycles per byte rather than 15. That's 320 cycles per row. 4 times is 1280 cycles. + 513 (sprite DMA) is 1793 cycles.

Doing 4 rows in a single NMI is usually pretty tight without doing some trickier things, though. Because writing rows/sprite DMA is not all the logic it will end up containing.

edit: Actually, it's worth noting you can't cpx the same number if you copy and paste multiple row loops.
If you have this:
Code:
@render_loop:
        lda asteroid_background,x ;#LARGE_ASTEROID_SPRITE_START
        sta PPU_DATA   

        inx
        cpx #4
    bne @render_loop

X is 4 at the bottom.
if you then do this (without changing X)
Code:
 @render_loop_2:
        lda asteroid_background,x ;#LARGE_ASTEROID_SPRITE_START
        sta PPU_DATA   

        inx
        cpx #4
    bne @render_loop_2

X starts at 4. So the loop with run 256 times. But if you do a ldx #0 beforehand, it will just load the same data.

But there's very little reason to have two loops if you're writing contiguous rows.

Just change the cpx to change the number of bytes.
Code:
        ldx #0
@render_loop:
        lda asteroid_background,x ;#LARGE_ASTEROID_SPRITE_START
        sta PPU_DATA   

        inx
        cpx #64;Just change this number
    bne @render_loop

Edit: Changed 256 tiles across to 256 pixels.

_________________
https://kasumi.itch.io/indivisible


Last edited by Kasumi on Fri Oct 19, 2018 10:29 am, edited 1 time in total.

Top
 Profile  
 
PostPosted: Fri Oct 19, 2018 7:32 am 
Offline
User avatar

Joined: Wed Sep 05, 2018 11:13 am
Posts: 141
Location: Colorado
Thanks guys. I broke it up so that it rendered a little bit at a time over several frames and it seems to be working(ish) now. Still having issues, but at least they are different issues.

Thanks again

_________________
A few of my web games
https://www.embed.com
Or if you're bored at work
https://www.classicsolitaire.com


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

All times are UTC - 7 hours


Who is online

Users browsing this forum: NOOPr 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