It is currently Sat Nov 18, 2017 7:04 am

All times are UTC - 7 hours



Forum rules


Related:



Post new topic Reply to topic  [ 15 posts ] 
Author Message
 Post subject: SNES Beginner Questions
PostPosted: Mon Jan 04, 2016 6:04 pm 
Offline

Joined: Tue Dec 29, 2015 2:42 pm
Posts: 11
I am making a new year's resolution to learn programming for the SNES! I am a fairly experienced web dev who's also done a fair bit of spare-time hardware projects, so low-level stuff isn't completely foreign to me. However, I'm going to have many, many questions as I go, and it's considerably less clutter to ask all my questions in a single thread. So with that, I've been going through bazz's tutorials (very helpful) but there's a few things I don't yet understand.

Yoshi's doc describes $2118 as the video port data register, what is written to the location set in the address register $2116. However, what is the purpose of register $2119? Assuming these registers are word-size, does this simply allow me to write two words to VRAM?


Top
 Profile  
 
PostPosted: Mon Jan 04, 2016 6:13 pm 
Offline
User avatar

Joined: Thu Dec 25, 2014 10:26 pm
Posts: 309
Location: Canada
$2118 and $2119 are each one byte, together they make up the one "word" VRAM data port. One 16-bit STA to $2118 writes the lo byte to $2118 and the hi to $2119. Depending on how you have $2115 set up, this may or may not be what you want.

Happy to answer any random questions you may have!


Top
 Profile  
 
PostPosted: Mon Jan 04, 2016 6:27 pm 
Offline

Joined: Tue Dec 29, 2015 2:42 pm
Posts: 11
Khaz wrote:
$2118 and $2119 are each one byte, together they make up the one "word" VRAM data port. One 16-bit STA to $2118 writes the lo byte to $2118 and the hi to $2119. Depending on how you have $2115 set up, this may or may not be what you want.

Happy to answer any random questions you may have!


Ah, the registers are a byte each. I thought they were a word each; makes much more sense. I presume the same is for $2116 when setting the address register? Thanks!


Top
 Profile  
 
PostPosted: Mon Jan 04, 2016 9:14 pm 
Offline

Joined: Fri Jul 04, 2014 9:31 pm
Posts: 801
Yeah, the SNES is a funny kind of 16-bit system. The CPU data bus access is 8-bit (backward compatibility with 6502, you see), and as a result all addresses reference a byte, except in VRAM which goes by words. So setting $2116-17 to $3000 targets a byte offset of $6000 in VRAM, but setting $2181-83 to $003000 just targets an offset of $003000 in WRAM (also available at $7E3000 on the A bus).


Top
 Profile  
 
PostPosted: Tue Jan 05, 2016 8:38 pm 
Offline

Joined: Tue Dec 29, 2015 2:42 pm
Posts: 11
So, it appears I've run into another thing that looks off. I'm currently in the NMI-VBLANK portion of bazz's tutorials. I've used this code to set my tilemap to $0400:

Code:
    lda #$04
    sta $2107


This translates to 0000 0100, and according to the documentation for register $2107, this is word "1" of the Tile Map, beginning at $0400 in VRAM.

bsnes, however, appears to show a VRAM location of $0800 for my tilemap. To illustrate:

Image

Note the tilemap data located at $0800 according to the VRAM debugger. Yet, in my code, I consistently use $0400 as a VRAM write address, and it works just as if it was located at $0400 (the palette is swapped on the tile, as you can see the high byte in the debugger).

Am I missing some reason this is at $0800 in the debugger instead of the expected $0400?


Top
 Profile  
 
PostPosted: Tue Jan 05, 2016 8:56 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19222
Location: NE Indiana, USA (NTSC)
The word address is $0400. Writes to VMADD ($2116) set an address in 2-byte words.

The byte address is $0800. The memory viewer is presumably showing byte addresses. If it were instead showing word addresses for consistency with VMADD, the numbers down the left side would look like this:

Code:
0200
0208
0210
0218
...
03F8
0400
0408 (cut off)


You might want to contact support to learn the rationale behind showing byte addresses in the video memory viewer.


Top
 Profile  
 
PostPosted: Sat Jan 09, 2016 1:11 pm 
Offline

Joined: Tue Dec 29, 2015 2:42 pm
Posts: 11
Ah, makes sense. The memory map is even 16 bytes across which should've been a dead giveaway.

As far as writing to the tilemap goes, I've noticed a quirk. I'm testing a few subroutines that would write to the BG tilemap, and the tilemap doesn't seem to accept any writes when register $2100 is set to enable the screen. I assume all tilemap writes must be done when the screen is set to off? As far as games' technical design go, does this mean that normally you would write most of your tilemap "upfront", or is normal design to simply enable/disable the screen whenever a write is done and write your background in "segments" (e.g. scrolling past what would fit in the tilemap)? Does it normally go in vblank instead? I would imagine enabling/disabling causes flicker or other performance issues...just making sure before I get stuck in a bad practice.


Top
 Profile  
 
PostPosted: Sat Jan 09, 2016 1:52 pm 
Offline
User avatar

Joined: Thu Dec 25, 2014 10:26 pm
Posts: 309
Location: Canada
You can't interact with VRAM while the screen is being drawn. That leaves you two options:

1. Turn the screen off with $2100
2. Leave screen on and wait until vBlank

Depending on what you're trying to do you may need to do #1 for a moment, but generally speaking all your normal VRAM writing is done during vblank.


Top
 Profile  
 
PostPosted: Sat Jan 09, 2016 7:36 pm 
Offline
User avatar

Joined: Mon Sep 15, 2014 4:35 pm
Posts: 3107
Location: Nacogdoches, Texas
The time you'd want to turn off the screen is when you'd want to send more tile data than you can during vblank. You can only send enough tile data for about 3 64x64 sized sprites in one frame, so that's why you may need it.


Top
 Profile  
 
PostPosted: Sun Jan 10, 2016 9:25 am 
Offline

Joined: Tue Dec 29, 2015 2:42 pm
Posts: 11
Espozo wrote:
The time you'd want to turn off the screen is when you'd want to send more tile data than you can during vblank. You can only send enough tile data for about 3 64x64 sized sprites in one frame, so that's why you may need it.


I have the handy-dandy chart from the SNES wiki showing me how many cycles each instruction uses; generally, how many cycles do I have on an NTSC console during Vblank?


Top
 Profile  
 
PostPosted: Sun Jan 10, 2016 9:55 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19222
Location: NE Indiana, USA (NTSC)
I haven't tested how long "post-render" is on the Super NES. (On the NES, it's time between the end of picture and the vblank NMI. But "pre-render" appears to be one line given the way scrolling works (where the top line is hidden). Assuming that pre-render and post-render are both 1 line, this means that in 224-line mode on an NTSC system, vblank is 262 - 1 (pre-render) - 224 (picture) - 1 (post-render) = 36 scanlines long. Each scanline is 341 dots long, minus ten for DRAM refresh, and DMA copy takes two dots per byte. So (341 - 10) * 36 / 2 = 5958 bytes. Compare this to a 128x16 pixel strip of sprite cels, which is 1024 bytes, and you'll end up being able to send about five such strips plus the 544 bytes of OAM.


Top
 Profile  
 
PostPosted: Sat Jan 16, 2016 2:37 pm 
Offline

Joined: Tue Dec 29, 2015 2:42 pm
Posts: 11
Looks like I'm having an issue writing to the tilemap...

I noticed this issue after observing screen corruption while trying to create a font routine. To setup, I use PPU screenmode 2 and scroll the layer down enough to display the entirety of the tile. As a test, I have a vblank manually triggered, and then I write to BG1 tilemap address to display tiles onscreen. Prior to writing to the tilemap address, I set the address register to $0400 and begin writing tilemap indicies required to display text. When I display, say, three tiles...it works perfectly:

Image

I modified this simple routine to print ten of the same tile to the tilemap. Nothing else changes except the amount of tiles. I get this:

Image

Tilemap entry #4 is scrolled up by itself, and the tenth one is way off into the distance. Testing it with my font character set gave even stranger results: the third, fourth, and fifth entries would end up way down at the bottom, while the rest display normally. The memory in the tilemap looks fine:

Image

I reasoned there is some timing issue I'm missing...I placed this whole routine in the NMI vblank handler, but I get identical results. So not sure what I'm doing wrong or where my understanding of how the tilemap works is breaking down (I reasoned that the X,Y coordinates of a tile in a BG could be computed based on a presumption that the tilemap is a continuous array of word-size entries).

If you want to see the code responsible, you can check here.


Top
 Profile  
 
PostPosted: Sat Jan 16, 2016 3:14 pm 
Offline

Joined: Mon Nov 10, 2008 3:09 pm
Posts: 431
ashterix wrote:
Looks like I'm having an issue writing to the tilemap...

I noticed this issue after observing screen corruption while trying to create a font routine. To setup, I use PPU screenmode 2 and scroll the layer down enough to display the entirety of the tile. As a test, I have a vblank manually triggered, and then I write to BG1 tilemap address to display tiles onscreen. Prior to writing to the tilemap address, I set the address register to $0400 and begin writing tilemap indicies required to display text. When I display, say, three tiles...it works perfectly:

Image

I modified this simple routine to print ten of the same tile to the tilemap. Nothing else changes except the amount of tiles. I get this:

Image

Tilemap entry #4 is scrolled up by itself, and the tenth one is way off into the distance. Testing it with my font character set gave even stranger results: the third, fourth, and fifth entries would end up way down at the bottom, while the rest display normally. The memory in the tilemap looks fine:

Image

I reasoned there is some timing issue I'm missing...I placed this whole routine in the NMI vblank handler, but I get identical results. So not sure what I'm doing wrong or where my understanding of how the tilemap works is breaking down (I reasoned that the X,Y coordinates of a tile in a BG could be computed based on a presumption that the tilemap is a continuous array of word-size entries).

If you want to see the code responsible, you can check here.


Why are you using mode 2? Mode 2 is an offset-per-tile mode, meaning each column of the screen has its own scroll values, fetched from a table in VRAM. This scroll offset table is controlled by BG3's registers. It looks like you've set BG3 to use the same RAM as BG1, meaning the same data is being interpreted as both the tilemap and the scroll offset table. If you just want to display a simple 4bpp tilemap, use mode 1.


Top
 Profile  
 
PostPosted: Sat Jan 16, 2016 10:05 pm 
Offline

Joined: Tue Dec 29, 2015 2:42 pm
Posts: 11
Looks like I misunderstood the screen modes in that case. Working good now!

Image


Top
 Profile  
 
PostPosted: Mon Mar 28, 2016 6:44 pm 
Offline
User avatar

Joined: Fri Sep 02, 2011 8:34 pm
Posts: 476
ashterix wrote:
... I've been going through bazz's tutorials (very helpful) but there's a few things I don't yet understand.


Thanks for using my tutorials! I'm glad you found them very helpful, but I would like to add that they are on a public wiki, so if you realized anything that could be better, please feel free to make your own contribution by modifying the content!

_________________
SNES Tutorials (WLA DX)
SNES Memory Mapping Tutorial (Universal / LoROM) -- By Universal I introduce how memory mapping works, rather than just provide a LoROM map.
SNES Tracker (WIP) - Music/SFX composition tool / SPC Debugger


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

All times are UTC - 7 hours


Who is online

Users browsing this forum: fred and 9 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