It is currently Sat Sep 22, 2018 10:12 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 9 posts ] 
Author Message
PostPosted: Mon Sep 10, 2018 8:44 am 
Offline

Joined: Fri Oct 28, 2016 12:37 pm
Posts: 32
Hi all,

Since I'm using DMA transfer during NMI my sprite data is technically already buffered, so is there any harm in updating sprite ram data (position, attributes, etc), in my main loop instead of within NMI?

The only possible risk I can think of is I may be making changes while the DMA process is active but I don't know if that is a bad thing on the NES?

I tried searching for a definitive answer on this but could not find it.


Top
 Profile  
 
PostPosted: Mon Sep 10, 2018 8:56 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20565
Location: NE Indiana, USA (NTSC)
Mostly your main loop needs to set a flag in RAM that tells your NMI handler that the sprite list is filled and ready to push to OAM, and then have the NMI handler clear that flag. If the flag is not set, the NMI handler would skip pushing the list to OAM. Otherwise, during lag frames, your NMI handler could end up pushing a half-built list, causing visible artifacts.


Top
 Profile  
 
PostPosted: Mon Sep 10, 2018 9:58 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10814
Location: Rio de Janeiro - Brazil
casprog wrote:
Since I'm using DMA transfer during NMI my sprite data is technically already buffered, so is there any harm in updating sprite ram data (position, attributes, etc), in my main loop instead of within NMI?

Not at all. That's actually the preferred way to do things: main thread handles game logic and buffers PPU updates (which includes the OAM buffer), and then the NMI handler flushes the buffers to VRAM/OAM. You just need to use a flag to indicate to the NMI handler when the buffered data is valid - you don't want to send half-ready data to VRAM.

Quote:
The only possible risk I can think of is I may be making changes while the DMA process is active but I don't know if that is a bad thing on the NES?

That won't happen, because the CPU stays busy while the DMA transfer takes place, execution only continues when the transfer is done.


Top
 Profile  
 
PostPosted: Mon Sep 10, 2018 12:08 pm 
Offline

Joined: Fri Oct 28, 2016 12:37 pm
Posts: 32
A-ha! thanks guys : )

Perfect, currently my NMI works with a PPU buffer and main thread updates sprite ram, so I just need to add the ready flag.


Top
 Profile  
 
PostPosted: Mon Sep 10, 2018 12:28 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 3606
Location: Mountain View, CA
Not sure if it will matter to the OP, but doesn't doing this cause problems with PAL consoles? (That 3rd paragraph required me to read it about 6 times...)


Top
 Profile  
 
PostPosted: Mon Sep 10, 2018 12:42 pm 
Online

Joined: Sun Apr 13, 2008 11:12 am
Posts: 7541
Location: Seattle
(I just edited that paragraph and moved it to the end of the section; hopefully it's clearer now. The entire rest of the section is only about the 2C02, so I thought it made sense to move this bit about the 2C07 to the end)


Top
 Profile  
 
PostPosted: Mon Sep 10, 2018 1:37 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 3606
Location: Mountain View, CA
lidnariq wrote:
(I just edited that paragraph and moved it to the end of the section; hopefully it's clearer now. The entire rest of the section is only about the 2C02, so I thought it made sense to move this bit about the 2C07 to the end)

Yes, this is much clearer -- thank you!


Top
 Profile  
 
PostPosted: Mon Sep 10, 2018 3:56 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 6817
Location: Canada
koitsu wrote:
Not sure if it will matter to the OP, but doesn't doing this cause problems with PAL consoles? (That 3rd paragraph required me to read it about 6 times...)

The OP wasn't asking about doing the DMA during the main thread, so it's not really related to that problem, no.

Yes, please give that paragraph a copyedit/rewrite. I think I wrote it, but it was more of a first pass attempt to have the wiki describe the PAL situation at all.


Top
 Profile  
 
PostPosted: Mon Sep 10, 2018 8:45 pm 
Offline

Joined: Fri Oct 28, 2016 12:37 pm
Posts: 32
I noticed a nice chunk of cycles saved adding the flag in, hovering around 1100 now under close to full load while processing my ppu buffer and redrawing sprites, and on average nmi is sitting around 99!

I added this at the end of my main thread, after my game logic runs:

Code:
   
   ; check if we should update dma
   LDA spriteram_updated   
   BEQ dma_check_done       
   LDA #$01
   STA perform_sprite_dma
   ; reset spriteram update flag
   LDA #$00
   STA spriteram_updated
dma_check_done:   



Then during nmi:

Code:
   LDA perform_sprite_dma
   BEQ sprite_dma_done
   LDA #$00
   STA $2003
   LDA #$02
   STA $4014
   ; reset dma flag
   LDA #$00
   STA perform_sprite_dma
sprite_dma_done:   


The NMI routine is the only place which resets the dma flag and my main thread is the only place that turns it on. My sprite updates appear to be working correctly, does this solution seem OK?


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: No registered users and 6 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