It is currently Thu Jul 19, 2018 8:24 pm

All times are UTC - 7 hours



Forum rules


Related:



Post new topic Reply to topic  [ 9 posts ] 
Author Message
PostPosted: Wed Mar 21, 2018 9:39 pm 
Offline

Joined: Tue Oct 24, 2017 11:07 pm
Posts: 13
I have a mirror of the contents of one of my backgrounds in WRAM so I can change it and not have to worry about only writing to it in vblank. However, I'm running into strange timing errors where I'm not able to DMA my OAM mirror and my tilemap mirror in the vblank period (I'm assuming it's a timing error anyway, the amount of data that actually gets transferred seems to change depending on the number of nops I add to the vblank routine). If that's the case, and there's not enough time to transfer the whole mirror, how am I supposed to DMA it over in vblank? You don't have random access to VRAM so you can't just DMA using multiple channels with offsets, and interleaving the tilemap mirror seems like a huge pain. Any help would be appreciated.

In case I'm doing something wrong, here's my WRAM-VRAM macro:
Code:
.macro WRAMToVRAM source, destination, size
   lda #$80
   sta $2115 ;word-access,increment by one
   ldx #destination
   stx $2116
   ldx #source
   stx $4312 ;dma source address
   lda #$7e
   sta $4314 ;bank
   ldx #size
   stx $4315
   lda #$18 ;dest = $2118, vram write register
   sta $4311
   lda #$1 ;word increment on dest, src increment
   sta $4310
.endmacro


Top
 Profile  
 
PostPosted: Wed Mar 21, 2018 10:46 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 3434
Location: Mountain View, CA
Edit: ignore what I've written in this paragraph -- it's for NES, not SNES. VBlank on NTSC lasts somewhere between 2273 and 2387 CPU cycles. Reference: viewtopic.php?t=7878 -- this thread may interest you in other ways, such as how to visually display on-screen how much time something is taking through some cute/quirky methodologies (the NES can do this a bit easier, but there are ways on the SNES as well, such as, say, by changing the background colour palette entry to an alternate colour at the start of a routine, then back to what it originally was at the end of the routine. The thread I reference has some other methodologies though)

Anomie's timing doc outlines how long DMA takes per byte, however the cycle counts you see in that doc are not equivalent to CPU cycles.

nocash's SNES document probably has the answer as well, but may still require bits of math be done.

I can't remember how to do the whole "master cycle" to "CPU cycle" conversion ordeal. Someone else should be able to do the math for that (right now I am too lazy to go read + figure it out). Maybe nocash or someone else can provide that. (I should add: this is a very common question when doing NES or SNESdev -- "how much time is available in VBlank" + "how much time does X/Y/Z" take (esp. DMA), so it should be answered in such a way that is very friendly/easy for the software programmer to understand)

The macro you pasted is "general purpose", so how much time it takes is ultimately going to depend on the size argument.

Speaking generally: the bottom line is, with classic consoles, you cannot update an *entire screen* worth of data (including CHR, if applicable) in a single frame. I don't know if you're doing that, your post is simply too vague. The SNES is not designed for this (full layout + CHR data is the equivalent of full-motion video playback); it's designed so that you update only what needs to be changed. A lot of games that need large amounts of transfers do so across multiple frames (multiple NMIs), as long as visually it won't impact what you're trying to achieve; for example, if you're trying to update some tile map data for animating trees, maybe do some updates in one NMI, then the next do some more, essentially making the animation rate for the trees ~30fps. You get the idea. In general, you have to track/maintain all of this in software. Welcome to game development. :-)


Top
 Profile  
 
PostPosted: Wed Mar 21, 2018 10:59 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20273
Location: NE Indiana, USA (NTSC)
Here are the numbers.

On Super NES, a scanline (minus DRAM refresh time) is 1324 master clocks.
A fast cycle is 6 master clocks. There are 220.7 fast cycles per line.
A slow cycle is 8 master clocks. There are 165.5 slow cycles per line.
DMA copies one byte per slow cycle.
On NTSC with overscan mode turned off, there are 262 - 224 = 38 scanlines in vblank. Subtract one scanline for prerender time, and you may end up with 165.5 * 37 = a smidge under 6 KiB per vblank.
This means you can replace one-third of the 16 KiB sprite tile area per vblank.

You can replace more if you force blanking in the top and bottom of the screen by changing the master rendering enable bit in $2100. Let's say you add 24 lines of letterbox on the top and bottom making the middle 176 pixels tall, which covers the entirety of a widescreen TV when zoomed in. In that case, you might be able to push (262-176-1)*165.5 = over 13.5 KiB.


Top
 Profile  
 
PostPosted: Thu Mar 22, 2018 2:56 am 
Offline

Joined: Wed May 19, 2010 6:12 pm
Posts: 2713
I had too write a lot of code just to get sprites to animate automatically without black bars. My game incorporates an animation frame delay feature if not all animated sprites can be updated on time. It even checks for duplicates, so if there are 4 animation frames of explosions but 20 explosion sprites onscreen, it would just use the duplicates.


Top
 Profile  
 
PostPosted: Thu Mar 22, 2018 3:14 am 
Offline

Joined: Mon Mar 30, 2015 10:14 am
Posts: 275
psycopathicteen wrote:
I had too write a lot of code just to get sprites to animate automatically without black bars. My game incorporates an animation frame delay feature if not all animated sprites can be updated on time. It even checks for duplicates, so if there are 4 animation frames of explosions but 20 explosion sprites onscreen, it would just use the duplicates.


I think this is the big mistake nintendo did,thinking a 8/16 kbytes of VRAM for sprites was enough :?
With all the VRAM available for sprites, everything (or at least most things) could have been easier .


Top
 Profile  
 
PostPosted: Thu Mar 22, 2018 10:25 am 
Offline

Joined: Tue Oct 24, 2017 11:07 pm
Posts: 13
koitsu wrote:
Speaking generally: the bottom line is, with classic consoles, you cannot update an *entire screen* worth of data (including CHR, if applicable) in a single frame. I don't know if you're doing that, your post is simply too vague. The SNES is not designed for this (full layout + CHR data is the equivalent of full-motion video playback); it's designed so that you update only what needs to be changed. A lot of games that need large amounts of transfers do so across multiple frames (multiple NMIs), as long as visually it won't impact what you're trying to achieve; for example, if you're trying to update some tile map data for animating trees, maybe do some updates in one NMI, then the next do some more, essentially making the animation rate for the trees ~30fps. You get the idea. In general, you have to track/maintain all of this in software. Welcome to game development. :-)


I figured that I would keep my scope small for my "first project" and make a game where you jump on randomly placed platforms and get powerups to increase your speed, that sorta thing. However, so far I've only done development on consoles where either the CPU is fast enough to DMA an entire tilemap over in one vblank or you can just access vram during draw without screwing stuff up, so this is kinda new for me. I guess that because I'd not be adding a new platform to more than one "screen" at once (I keep track of locations in the 64x64 tilemap as "screens" because of the strange way they're stored in memory), I can just make my DMA code only send over the screen where the last added platform was.


Top
 Profile  
 
PostPosted: Thu Mar 22, 2018 10:27 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20273
Location: NE Indiana, USA (NTSC)
You can certainly DMA a whole non-scrolling tile map. That's only 32*28*2 = 1792 bytes. You can also DMA in new columns or rows as the scrolling window reaches them. It's just DMAing in new tiles that might cause delay.


Top
 Profile  
 
PostPosted: Thu Mar 22, 2018 3:35 pm 
Offline

Joined: Fri Jul 04, 2014 9:31 pm
Posts: 931
Do you mean you're using a maximum-sized 8 KB quad tilemap, and trying to DMA that into VRAM in one shot? Yeah, that's not going to fly without letterboxing.

Like tepples says, what most games did was update rows and columns as they scrolled into view. Since the screen is only 224 lines high, you don't actually need more than two "screens" worth of tilemap in VRAM for seamless scrolling if you do it right. Look into what $2115 does, and maybe take a second look at $2107-210A if you don't already know how to make the map smaller.


Last edited by 93143 on Thu Mar 22, 2018 9:53 pm, edited 1 time in total.

Top
 Profile  
 
PostPosted: Thu Mar 22, 2018 3:50 pm 
Offline

Joined: Wed May 19, 2010 6:12 pm
Posts: 2713
You can turn off rendering between levels.


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: Markfrizb 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