Question on tile animation

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Question on tile animation
by on (#147702)
I'm trying to gather as much information as I can, on how the snes works, in preparation for the next updated release of bsnes-plus's debugger.

In my nes rom hacking days, I've never messed with chr animation within a chr-ram game. I've always converted my projects to chr-rom,so so I can swap the desired amount of tiles with other tiles, to give the appearance of animation. My question is, are there any snes games that utilize chr-rom, or is it universally chr-ram? And if it's the latter, how would one go about creating a chr animation routine within the snes?
Re: Question on tile animation
by on (#147704)
The NES and Neo-Geo are the only home video game machines with CHR-ROM, both because of their conceptual origins in arcades.

As you pointed out, CHR-ROM is simpler but less flexible, which is why most consoles use internal RAM. Additionally, putting this RAM inside the console reduces reproduction costs later on.

(I think a few random other non-arcade machines can draw tiles from physically-external ROM. The C64 is one, although I don't know if any cartridge-based games used it.)
Re: Question on tile animation
by on (#147707)
In case that wasn't clear, the SNES doesn't use anything resembling CHR-ROM or CHR-RAM on the NES. The PPU has no cartridge slot access, so if you want to display tile data, you have to put it in VRAM.
Re: Question on tile animation
by on (#147709)
Right, I had a feeling it was vram, and not dependant on a mapped to swap pages.

I've just never delt with vram with animation routines. Chr animation is one of my favorite things to do, and I want to make sure I do it correctly. I guess what I should do, is when bsnes-plus gets its update, is to load up super Mario world, and find that the asm routine that deals with tile swapping for the ? Blocks.

Is there a specific limit, to how many tiles you can load up that you want swapped, without slowdown or glitches occurring?
Re: Question on tile animation
by on (#147711)
infidelity wrote:
Is there a specific limit, to how many tiles you can load up that you want swapped, without slowdown or glitches occurring?

Unfortunately, yes. :( You can only upload 6 KB of data, which is equivalent to 3 64x64 sized sprites, but updating oam and other stuff also counts, so it's more of something like 2 and 1/2 64x64 sized sprites. That's easily the biggest problem with this setup. Also, if you try to update more, I think I've heard that the top of the screen gets clipped by a black bar, and the more you're updating, the further down the screen the bar will go. It only lasts for the frame after though.
Re: Question on tile animation
by on (#147712)
Oh wow. I'll definitely have to be careful to not go overboard in what id like swapped for animations. I appreciate all the info everyone thank you! Looking forward to starting my venture to snes rom hacking soon. :-)

Edit: Another question.

When writing a tile to the screen, how does the snes differentiate that the tile being drawn is 2bpp, 4bpp, 8bpp? And is the reasoning behind compresses gfx, due to size issues back in the 90's, cost, etc? Like, can I get away with a romhack, using uncompressed gfx?
Re: Question on tile animation
by on (#147713)
There isn't really a hard limit on tile animation. It depends on what you're trying to do, and how much else is going on.

You have 64 kB of VRAM to work with. Tilemaps are 2 kB (32x32) and can be doubled in the X and/or Y direction(s) for up to 8 kB per BG layer. Each tilemap can address up to 1024 tiles arranged linearly in VRAM, with each BG layer having a separate starting address. BG tiles can be either 8x8 or 16x16, selected separately for each layer. Sprite tiles are stored in 8 kB (16x16-tile) OBJ blocks similar to the NES, with two relocatable OBJ blocks in VRAM that can be accessed simultaneously; you can relocate these blocks (not the data, but where the PPU thinks the data is) not only between frames but also between scanlines (based on a simple experiment I did a bit ago).

The 6 kB limit Espozo is talking about is the approximate limit on DMA bandwidth per frame, so it only applies if the data you want to switch to is not already in VRAM. The SNES was designed to eliminate the overscan that wasted VBlank time on the NES, so unless you specifically set it to overscan mode, each frame is 224 scanlines, leaving you 38 blank ones at 165.5 bytes per line. (Mind you, this also generally includes OAM and CGRAM updates, so that's about a kilobyte gone if you need to fully update both.) You can also use force blank to turn the screen off early and/or turn it on late, allowing more time to transfer data. I'm trying to port a vertical shmup to the SNES, and my current design has only 206 active scanlines, leaving me roughly 9 kB of bandwidth per frame (I need it all...).

PAL systems have 312 scanlines per frame and no other relevant differences, so DMA bandwidth is huge; this dovetails nicely with the fact that the demoscene is bigger in Europe...

infidelity wrote:
When writing a tile to the screen, how does the snes differentiate that the tile being drawn is 2bpp, 4bpp, 8bpp?

It has to do with the PPU mode. The SNES has up to 4 separate BG planes, rather than just one as on the NES (and they can be independently scrolled, greatly attenuating a major source of tile animation requirements). Each plane has a separately designated tilemap and tile data range. The bit depth is fixed for a given BG layer in a given mode; for instance, in Mode 1, BG1 and BG2 are 4bpp, BG3 is 2bpp, and BG4 is unavailable.

The odd man out is Mode 7, which doesn't use bitplanes at all and is fixed to starting at $0000 and using the bottom half of VRAM. Each word is interpreted as an 8-bit tilemap entry followed by an 8-bit pixel. The result is a huge 128x128-tile map restricted to 256 tiles with no tile flipping, useful for allowing you to zoom out on a relatively expansive swath of terrain without eating all of VRAM. You can stick other data in the Mode 7 area as long as you can guarantee that the player will never see that part of the tilemap...

Sprites are locked to 4bpp.

Quote:
And is the reasoning behind compresses gfx, due to size issues back in the 90's, cost, etc? Like, can I get away with a romhack, using uncompressed gfx?

Compression was purely to save ROM space. If ROM space isn't an issue (and you don't have an S-DD1 or something like that), compression just wastes CPU time.
Re: Question on tile animation
by on (#147714)
infidelity wrote:
Oh wow. I'll definitely have to be careful to not go overboard in what id like swapped for animations. I appreciate all the info everyone thank you! Looking forward to starting my venture to snes rom hacking soon. :-)

Edit: Another question.

When writing a tile to the screen, how does the snes differentiate that the tile being drawn is 2bpp, 4bpp, 8bpp? And is the reasoning behind compresses gfx, due to size issues back in the 90's, cost, etc? Like, can I get away with a romhack, using uncompressed gfx?


This article can explains how to get around the DMA limit.

http://wiki.superfamicom.org/snes/show/ ... ffectively
Re: Question on tile animation
by on (#147716)
Oh awesome info 93143! Thank you very much for that!

And thank you for that link, psycopathicteen! I'll check it out now.
Re: Question on tile animation
by on (#147722)
I had originally explained the Mode 7 tile format backwards. I have corrected it. I figured you should be aware of this, since you seem to have been reading my post as I was editing it...
Re: Question on tile animation
by on (#147723)
Thanks for that heads up! I'll re-read that now.
Re: Question on tile animation
by on (#147754)
93143 wrote:
The SNES was designed to eliminate the overdraw that wasted VBlank time on the NES, so unless you specifically set it to overdraw mode, each frame is 224 scanlines, leaving you 38 blank ones at 165.5 bytes per line.

I think you mean overscan, not overdraw.
Re: Question on tile animation
by on (#147759)
I have a question on palette values.

I'm loading a 200 byte table, I have X & Y set as 16-bits. Anyway I was successful in loading 200 bytes into CGRAM. I wanted to perform a test, where I have a 200 byte table with each 2 bytes representing a color for each palette slot.

I have a table such as 00,00 01,00 02,00 03,00 etc etc.

When I reach the point of my table where I have 80,00 81,00, etc, it looks the same as the previous stored colors. So are palette colors only 00-7F?

Thanks everyone! :-)
Re: Question on tile animation
by on (#147776)
infidelity wrote:
I have a question on palette values.

I'm loading a 200 byte table, I have X & Y set as 16-bits. Anyway I was successful in loading 200 bytes into CGRAM. I wanted to perform a test, where I have a 200 byte table with each 2 bytes representing a color for each palette slot.

I have a table such as 00,00 01,00 02,00 03,00 etc etc.

When I reach the point of my table where I have 80,00 81,00, etc, it looks the same as the previous stored colors. So are palette colors only 00-7F?

Thanks everyone! :-)


SNES CGRAM entries are 15-bit: five bits of red, five bits of green and five bits of blue:

xBBBBBGG GGGRRRRR

However, when you write to CGRAM or read it back, the first read or write accesses the low 8 bits (the ones containing red) and the second one accesses the high 7 bits (the ones containing blue). In other words CGRAM access is little-endian, just like everything else on the SNES (and NES).

Don't think of CGRAM as an array of bytes, but as an array of 15-bit words. When you write a byte to $2122, it only gets stored in a temporary buffer. You have to write twice before the two bytes get combined into a word and actually written to CGRAM. The important things you have to remember are that the address you write to $2121 is the index of the first color you want to change, a word address (don't multiply it by 2 even though you're writing 2 bytes per color), and that you always have to transfer an even number of bytes.

The most significant bit in the high byte of a CGRAM word is like the top two bits of NES CGRAM: it simply doesn't exist; you can't even read back what you wrote to it.

One more thing: you can't write an entire word at once to CGRAM by using a 16-bit register. If you do rep #$20; sta $2122 then the low byte of A will be written to $2122 (which is what you want) but the high byte will be written to $2123, a completely different register (one of the clip window registers). I strongly recommend you learn how SNES DMA works and get used to using it for all data transfers to the PPU (OAM, VRAM, CGRAM); it's much more efficient and is what all commercial games do.
Re: Question on tile animation
by on (#147779)
Ahh thank you, that explains the left most bit not being recognized. That's why it's 00-7F I can only see.

I've been messing around all day with my asm. I've been able to load up a value and have it stored within the VRAM. It's not using DMA, but I will try to start reading up on it. I'm not trying to create anything now, I'm just trying to get my feet wet, in seeing if Im able to code in asm, to get things inserted. So far I'm able to adjust the snes screens brightness, I'm able to insert any color into any palette slot, and I've just been able to insert a value within the VRAM. :-) pretty good day for me. :-)

From my tests, it appears that for proper tile appearance of 2bpp, is to have the first byte filled, but the second byte blank, (since I know the vram uses 16-bits) so I was able to have a proper 8x8 tile appear correctly in vram that is meant for 2bpp.

I hope by tonight, to draw to one of the BG's.
Re: Question on tile animation
by on (#147782)
thefox wrote:
93143 wrote:
The SNES was designed to eliminate the overdraw that wasted VBlank time on the NES, so unless you specifically set it to overdraw mode, each frame is 224 scanlines, leaving you 38 blank ones at 165.5 bytes per line.

I think you mean overscan, not overdraw.

Yes I do. Fixed.

infidelity wrote:
From my tests, it appears that for proper tile appearance of 2bpp, is to have the first byte filled, but the second byte blank, (since I know the vram uses 16-bits) so I was able to have a proper 8x8 tile appear correctly in vram that is meant for 2bpp.

The 2bpp tile format is a list of 8 16-bit words. The low byte of each word is the low bit of each pixel in a sliver, and the high byte is the high bit of each pixel in the same sliver. There are no empty/ignored bytes.

4bpp is just two 2bpp tiles one after the other. 8bpp is just four 2bpp tiles one after another.

If you're trying to display a 2bpp tile in a layer with higher bit depth, you could get usable results by doing what you're describing - certainly it would look better than trying to use NES format...
Re: Question on tile animation
by on (#147783)
deleted post due to errors on my end.
Re: Question on tile animation
by on (#147785)
infidelity wrote:
Code:
8x8 in NES: 00,00,00,00,00,00,00,00,FF,FF,DB,FF,BD,C3,BD,FF

Unless I'm gravely mistaken, the SNES equivalent of that should be:
Code:
00FF,00FF,00DB,00FF,00BD,00C3,00BD,00FF

This has a decent explanation.
Re: Question on tile animation
by on (#147786)
Oh so that's how its done! Ok cause that format is definitely working, cause the 3 colors are appearing (even though they are all a form of gray within the bsnes-plus vram viewer) when the tile is manually drawn.

I will write this down in my vram notes for 2bpp. Thanks for that example!
Re: Question on tile animation
by on (#147787)
Wait, 3 colours? The data you posted should only have one non-transparent colour, since one of the bitplanes is zeroed. I assume you're talking about using different data...
Re: Question on tile animation
by on (#147788)
This is what I meant by the colors of the vram tile.

Image Image
Re: Question on tile animation
by on (#147791)
Okay, yeah. Different data. That makes sense, thanks.
Re: Question on tile animation
by on (#147797)
Np and thank you again! I was looking up DMA info, crazy info on that. I feel I'm still in the infancy with all of this, so i'll come back to that down the road, I know it was said this is a big deal to learn and utilize (paraphrasing) but I hope to get the jist of it someday.

edit

wow, after doing more reading on this DMA thing, it's really fast at transferring. I'm so used to the days of doing something like loading & storing 100 bytes worth of data...

Code:
(i know this wont work in an assembler, i code entirely in hex, this is just for people who hate reading opcodes and values)

LDY #$00
LDA $8000,Y
STA $9000,Y
INY
BNE TO LDA $8000,Y


So this DMA, does it perform a massive transfer instantaneously? like almost in a way how NES mapper chips can swap out a desired bank instantaneously?
Re: Question on tile animation
by on (#147802)
Not instantaneously. It's eight master cycles (ie: one slow CPU cycle) per byte. 2.68 MB per second. Plus 8 master cycles of overhead per channel and 12-24 for the whole transfer, plus whatever it took to set it up. For even modestly-sized transfers it's very worth it, though you have to be careful not to bork up HDMA if you're using both, since they use the same hardware and registers (in fact there's a bug on launch consoles where a specific type of DMA/HDMA conflict can stall the CPU).

Unfortunately it doesn't seem to be possible to move data from somewhere in WRAM to somewhere else in WRAM with DMA, not even with the WRAM gate on the B bus...

From the CPU's perspective, you could say DMA happens instantaneously, since the CPU is paused during it. So after you trigger a DMA transfer, you can write subsequent code under the assumption that the transfer is already finished.
Re: Question on tile animation
by on (#147815)
I don't think I quite got the grasp of this dma. I wanted to see if I could load my tile table at $80:9000, but it seems to load the entire bank from $8000-$FFFF. I cant pinpoint if the loading is starting at $9000 and is overlapping back to $8000, or, if it's really starting at $8000. Also when the tiles are written, they are not written to the very beginning of the vram. Here is sample code I copied from bsnes trace logger.

Code:
008115 lda #$80               A:000f X:0000 Y:0000 S:1fff D:0000 DB:00 nvMXdizC V:  2 H: 342
008117 sta $2115     [002115] A:0080 X:0000 Y:0000 S:1fff D:0000 DB:00 NvMXdizC V:  2 H: 366
00811a lda #$00               A:0080 X:0000 Y:0000 S:1fff D:0000 DB:00 NvMXdizC V:  2 H: 404
00811c sta $2116     [002116] A:0000 X:0000 Y:0000 S:1fff D:0000 DB:00 nvMXdiZC V:  2 H: 428
00811f lda #$00               A:0000 X:0000 Y:0000 S:1fff D:0000 DB:00 nvMXdiZC V:  2 H: 466
008121 sta $2117     [002117] A:0000 X:0000 Y:0000 S:1fff D:0000 DB:00 nvMXdiZC V:  2 H: 490
008124 rep #$18               A:0000 X:0000 Y:0000 S:1fff D:0000 DB:00 nvMXdiZC V:  2 H: 528
008126 ldx #$9000             A:0000 X:0000 Y:0000 S:1fff D:0000 DB:00 nvMxdiZC V:  2 H: 598
008129 stx $4302     [004302] A:0000 X:9000 Y:0000 S:1fff D:0000 DB:00 NvMxdizC V:  2 H: 630
00812c lda #$80               A:0000 X:9000 Y:0000 S:1fff D:0000 DB:00 NvMxdizC V:  2 H: 674
00812e sta $4304     [004304] A:0080 X:9000 Y:0000 S:1fff D:0000 DB:00 NvMxdizC V:  2 H: 698
008131 ldx #$0000             A:0080 X:9000 Y:0000 S:1fff D:0000 DB:00 NvMxdizC V:  2 H: 736
008134 stx $4305     [004305] A:0080 X:0000 Y:0000 S:1fff D:0000 DB:00 nvMxdiZC V:  2 H: 768
008137 lda #$18               A:0080 X:0000 Y:0000 S:1fff D:0000 DB:00 nvMxdiZC V:  2 H: 812
008139 sta $4301     [004301] A:0018 X:0000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:  2 H: 836
00813c lda #$01               A:0018 X:0000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:  2 H: 874
00813e sta $4300     [004300] A:0001 X:0000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:  2 H: 898
008141 lda #$01               A:0001 X:0000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:  2 H: 936
008143 sta $420b     [00420b] A:0001 X:0000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:  2 H: 960
008146 jmp $8146     [008146] A:0001 X:0000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:  2 H: 998


That jmp I have at the very end, is my endless loop.

I used the REP #$18 which I believe is X/Y set as 16 bit, again idk if I got this understood. Especially the setting of registers to either 8/16 bit, I know it's rep and sep, and I';ve seen different values used, and I jotted some down.
Re: Question on tile animation
by on (#147819)
infidelity wrote:
I don't think I quite got the grasp of this dma. I wanted to see if I could load my tile table at $80:9000, but it seems to load the entire bank from $8000-$FFFF. I cant pinpoint if the loading is starting at $9000 and is overlapping back to $8000, or, if it's really starting at $8000. Also when the tiles are written, they are not written to the very beginning of the vram. Here is sample code I copied from bsnes trace logger.

You have set $4305 (DAS0 - Transfer Size) to $0000. That causes DMA to transfer $10000 bytes to the destination (DMA also wraps around the Bank, Leaving it unchanged). You will need to set that register to the size of your block to transfer.


infidelity wrote:
I used the REP #$18 which I believe is X/Y set as 16 bit, again idk if I got this understood. Especially the setting of registers to either 8/16 bit, I know it's rep and sep, and I';ve seen different values used, and I jotted some down.

REP #$10 is all you need to change the Index register to 16 bits. REP #$20 changes the Accumulator to 16 bits and REP#$30 changes both.
Conversely SEP #$10 changes Index to 8 bits wide, SEP #$20 changes the Accumulator to 8 bits and SEP #$30 changes both.

The other bits used in REP/SEP change the other bits of the status register.


----
When debugging DMA, Geiger's Snes9x Debugger is your better option. It has a tickbox to turn on DMA tracing which detail all DMA transfers that occur in the trace.


For example:
Code:
DMA[0]: CPU->PPU Mode:0 0x00011B->0x2104 Bytes:220 (inc) V:225 OBJADDR: 0000
DMA[0]: CPU->PPU Mode:1 0x7E6B00->0x2118 Bytes:40 (inc) V:229 VRAM: 0406 (32,0) word
DMA[0]: CPU->PPU Mode:1 0x7E6B40->0x2118 Bytes:40 (inc) V:229 VRAM: 0407 (32,0) word
DMA[0]: CPU->PPU Mode:1 0x82843C->0x2118 Bytes:400 (inc) V:225 VRAM: 7A00 (1,0) word
Re: Question on tile animation
by on (#147891)
ok, I tried using the dma again, but I still cant get it to upload to vram for some reason. I thought I had it written correctly. I'm able to load 1000 bytes from $9000, I see it happen, but, it doesn't get transferred to vram's address $0000. Here is my code. Idk if im missing something, or have something incorrectly written. :-/

Code:
00810c lda #$80               A:00ff X:00ff Y:0000 S:1fff D:0000 DB:00 nvMXdizC V:  2 H: 272
00810e sta $2115     [002115] A:0080 X:00ff Y:0000 S:1fff D:0000 DB:00 NvMXdizC V:  2 H: 296
008111 rep #$10               A:0080 X:00ff Y:0000 S:1fff D:0000 DB:00 NvMXdizC V:  2 H: 334
008113 ldx #$0000             A:0080 X:00ff Y:0000 S:1fff D:0000 DB:00 NvMxdizC V:  2 H: 364
008116 stx $2116     [002116] A:0080 X:0000 Y:0000 S:1fff D:0000 DB:00 nvMxdiZC V:  2 H: 396
008119 lda #$01               A:0080 X:0000 Y:0000 S:1fff D:0000 DB:00 nvMxdiZC V:  2 H: 440
00811b sta $4300     [004300] A:0001 X:0000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:  2 H: 464
00811e lda #$18               A:0001 X:0000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:  2 H: 502
008120 sta $4301     [004301] A:0018 X:0000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:  2 H: 526
008123 ldx #$9000             A:0018 X:0000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:  2 H: 604
008126 stx $4302     [004302] A:0018 X:9000 Y:0000 S:1fff D:0000 DB:00 NvMxdizC V:  2 H: 636
008129 lda #$00               A:0018 X:9000 Y:0000 S:1fff D:0000 DB:00 NvMxdizC V:  2 H: 680
00812b sta $4304     [004304] A:0000 X:9000 Y:0000 S:1fff D:0000 DB:00 nvMxdiZC V:  2 H: 704
00812e ldx #$1000             A:0000 X:9000 Y:0000 S:1fff D:0000 DB:00 nvMxdiZC V:  2 H: 742
008131 stx $4305     [004305] A:0000 X:1000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:  2 H: 774
008134 lda #$01               A:0000 X:1000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:  2 H: 818
008136 sta $420b     [00420b] A:0001 X:1000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:  2 H: 842
008139 jmp $8139     [008139] A:0001 X:1000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:  2 H: 880


The jmp is just an infinite loop. Thanks everyone!

EDIT

This is strange, if I have my infinite jmp loop point to the beginning of this routine, then I see my tiles appear in the vram. So do I need to have this consistently loading? I thought you just needed to write to the vram one time, to have the registers altered, am I missing something?

Also, I'm guessing I do not know how to properly insert NES gfx, into an SNES rom. I first tried opening my .sfc rom with YY-CHR, I then used the 2bpp codec, I then pasted my NES tiles then saved the rom. When I see the tiles load up into the vram window of bsnes, they look horrificly squished in 2bpp mode?

So what I did was, I reopened the rom within YY-CHR, set the rom to 4bpp codec, I then inserted the regular 2bpp nes tiles, into the 4bpp codec, I then saved. When I booted the rom and tiles were written to the vram, they appeared correct in size! But, in 2bpp mode, the tiles are not side by side, there is an (every other gap) between them, when I switch the vram viewer to 4bpp, the 2bpp tiles then appear side by side.

I know I'm still learning, but can anyone skim through this reply to see if my code has any issues, and answer my latest questions as to why I need to have the vram setup code consisntantly running, and, my issue with inserting gfx properly into an snes rom?

Thank you so much again everyone!
Question om dma/vram. Please view latest post.
by on (#147923)
Any ideas? :-/
Re: Question on tile animation
by on (#147925)
A 4bpp tile is just two 2bpp tiles right after one another. So if you have a gap of a tile between each tile, it means you're pasting in 2bpp tiles in a 4bpp format (where the upper bitplanes (the second tile) are all zero).

I don't BELIEVE there is a difference between the NES and SNES 2bpp format (nevermind see post below). If the tiles are showing up "squished" when you try to transfer them over as 2bpp, it might help to know in what direction they're squished - horizontally, vertically or both?

I see nothing wrong with the code you posted:
Code:
00810c lda #$80
00810e sta $2115    ;increment destination address after a write to $2119 (word writes)
008111 rep #$10    ;16 bit X/Y
008113 ldx #$0000
008116 stx $2116    ;sets VRAM destination address to $0000
008119 lda #$01
00811b sta $4300    ;DMA Control:  Word writes, CPU --> VRAM
00811e lda #$18
008120 sta $4301    ;DMA Destination Register:  $2118
008123 ldx #$9000
008126 stx $4302
008129 lda #$00
00812b sta $4304    ;DMA Source Address:  $00/9000  (which is also $80/9000)
00812e ldx #$1000
008131 stx $4305    ;DMA Transfer Size:  $1000 (BYTES, not WORDS)
008134 lda #$01
008136 sta $420b    ;start DMA channel 0
008139 jmp $8139    ;infinite loop

... but you're right in that you should only need to DMA to VRAM once for it to work. So, I can only conclude the problem is somewhere else in your program. If your results are only working when you constantly repeat the DMA, then I can only think of a couple possible reasons why it might not work the first time. Are you trying to DMA to VRAM outside of vBlank?

A bit of context of where you have your DMA code might help a bit.
Re: Question on tile animation
by on (#147926)
infidelity wrote:
ok, I tried using the dma again, but I still cant get it to upload to vram for some reason. I thought I had it written correctly. I'm able to load 1000 bytes from $9000, I see it happen, but, it doesn't get transferred to vram's address $0000. Here is my code. Idk if im missing something, or have something incorrectly written. :-/

Code:
00810c lda #$80               A:00ff X:00ff Y:0000 S:1fff D:0000 DB:00 nvMXdizC V:  2 H: 272
00810e sta $2115     [002115] A:0080 X:00ff Y:0000 S:1fff D:0000 DB:00 NvMXdizC V:  2 H: 296
008111 rep #$10               A:0080 X:00ff Y:0000 S:1fff D:0000 DB:00 NvMXdizC V:  2 H: 334
008113 ldx #$0000             A:0080 X:00ff Y:0000 S:1fff D:0000 DB:00 NvMxdizC V:  2 H: 364
008116 stx $2116     [002116] A:0080 X:0000 Y:0000 S:1fff D:0000 DB:00 nvMxdiZC V:  2 H: 396
008119 lda #$01               A:0080 X:0000 Y:0000 S:1fff D:0000 DB:00 nvMxdiZC V:  2 H: 440
00811b sta $4300     [004300] A:0001 X:0000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:  2 H: 464
00811e lda #$18               A:0001 X:0000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:  2 H: 502
008120 sta $4301     [004301] A:0018 X:0000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:  2 H: 526
008123 ldx #$9000             A:0018 X:0000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:  2 H: 604
008126 stx $4302     [004302] A:0018 X:9000 Y:0000 S:1fff D:0000 DB:00 NvMxdizC V:  2 H: 636
008129 lda #$00               A:0018 X:9000 Y:0000 S:1fff D:0000 DB:00 NvMxdizC V:  2 H: 680
00812b sta $4304     [004304] A:0000 X:9000 Y:0000 S:1fff D:0000 DB:00 nvMxdiZC V:  2 H: 704
00812e ldx #$1000             A:0000 X:9000 Y:0000 S:1fff D:0000 DB:00 nvMxdiZC V:  2 H: 742
008131 stx $4305     [004305] A:0000 X:1000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:  2 H: 774
008134 lda #$01               A:0000 X:1000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:  2 H: 818
008136 sta $420b     [00420b] A:0001 X:1000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:  2 H: 842
008139 jmp $8139     [008139] A:0001 X:1000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:  2 H: 880


The jmp is just an infinite loop. Thanks everyone!

EDIT

This is strange, if I have my infinite jmp loop point to the beginning of this routine, then I see my tiles appear in the vram. So do I need to have this consistently loading? I thought you just needed to write to the vram one time, to have the registers altered, am I missing something?

Also, I'm guessing I do not know how to properly insert NES gfx, into an SNES rom. I first tried opening my .sfc rom with YY-CHR, I then used the 2bpp codec, I then pasted my NES tiles then saved the rom. When I see the tiles load up into the vram window of bsnes, they look horrificly squished in 2bpp mode?

So what I did was, I reopened the rom within YY-CHR, set the rom to 4bpp codec, I then inserted the regular 2bpp nes tiles, into the 4bpp codec, I then saved. When I booted the rom and tiles were written to the vram, they appeared correct in size! But, in 2bpp mode, the tiles are not side by side, there is an (every other gap) between them, when I switch the vram viewer to 4bpp, the 2bpp tiles then appear side by side.

I know I'm still learning, but can anyone skim through this reply to see if my code has any issues, and answer my latest questions as to why I need to have the vram setup code consisntantly running, and, my issue with inserting gfx properly into an snes rom?

Thank you so much again everyone!


Are you setting forced blank before attempting to transfer data? Just like the NES, VRAM on the SNES can only be accessed during VBlank or forced blank. On the SNES, you set forced blank by writing #$80 to $2100. Disabling all the BGs and sprites is not the same thing as forced blank on the SNES, unlike the NES.

The SNES 2bpp tile format is not the same as the NES 2bpp tile format. NES tiles consist of all 8 rows of the LSB plane, followed by all 8 rows of the MSB plane. SNES tiles have the two planes byte-interleaved. You can't "insert NES gfx into a SNES rom" without conversion. If YY-CHR doesn't have a "SNES 2bpp" option then look for a "Game Boy" option--GB tiles and 2bpp SNES tiles are in the same format.
Re: Question on tile animation
by on (#147942)
Thank You Khaz & AWJ!

The 2bpp gfx now appear correctly within the snes vram 2bpp viewer, due to changing to the GB codec within the snes rom! :-D

And thank you AWJ on that $2100 snes address! That did the trick! As soon as $420B was written to, I saw the vram fill up instantaneously, AND, I did not need to keep consistently jumping back to the start of dma/vram routine to keep it on!

I'd like to post what I have from my beginnings. I do NOT have anything written to any BG planes, nor any palettes, all I have is the initialization setup, turn on brightness to full, and my dma/vram test to upload 1000 bytes to vram.

Question, I'm not sure if I understood correctly on $2100. Does that act the same way as ppu rendering on/off for nes, like turning the screen to black? Just wondering if I need to come up with a new method, for writing to actual tiles from vram to the bg planes, once I get that far.

Anyway here is what I have for code, it's all within 00:0000.

Code:
;initialization setup
008000 sei                    A:0000 X:0000 Y:0000 S:01ff D:0000 DB:00 nv1BdIzc V:  0 H: 186
008001 clc                    A:0000 X:0000 Y:0000 S:01ff D:0000 DB:00 nv1BdIzc V:  0 H: 208
008002 xce                    A:0000 X:0000 Y:0000 S:01ff D:0000 DB:00 nv1BdIzc V:  0 H: 230
008003 rep #$18               A:0000 X:0000 Y:0000 S:01ff D:0000 DB:00 nvMXdIzC V:  0 H: 252
008005 ldx #$1fff             A:0000 X:0000 Y:0000 S:01ff D:0000 DB:00 nvMxdIzC V:  0 H: 282
008008 txs                    A:0000 X:1fff Y:0000 S:01ff D:0000 DB:00 nvMxdIzC V:  0 H: 314
008009 jsr $800f     [00800f] A:0000 X:1fff Y:0000 S:1fff D:0000 DB:00 nvMxdIzC V:  0 H: 336
00800f sep #$30               A:0000 X:1fff Y:0000 S:1ffd D:0000 DB:00 nvMxdIzC V:  0 H: 390
008011 lda #$8f               A:0000 X:00ff Y:0000 S:1ffd D:0000 DB:00 nvMXdIzC V:  0 H: 420
008013 sta $2100     [002100] A:008f X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  0 H: 444
008016 stz $2100     [002100] A:008f X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  0 H: 482
008019 stz $2101     [002101] A:008f X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  0 H: 520
00801c stz $2102     [002102] A:008f X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  0 H: 598
00801f stz $2103     [002103] A:008f X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  0 H: 636
008022 stz $2105     [002105] A:008f X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  0 H: 674
008025 stz $2106     [002106] A:008f X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  0 H: 712
008028 stz $2107     [002107] A:008f X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  0 H: 750
00802b stz $2108     [002108] A:008f X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  0 H: 788
00802e stz $2109     [002109] A:008f X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  0 H: 826
008031 stz $210a     [00210a] A:008f X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  0 H: 864
008034 stz $210b     [00210b] A:008f X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  0 H: 902
008037 stz $210c     [00210c] A:008f X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  0 H: 940
00803a stz $210d     [00210d] A:008f X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  0 H: 978
00803d stz $210d     [00210d] A:008f X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  0 H:1016
008040 lda #$ff               A:008f X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  0 H:1054
008042 sta $210e     [00210e] A:00ff X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  0 H:1078
008045 sta $2110     [002110] A:00ff X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  0 H:1116
008048 sta $2112     [002112] A:00ff X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  0 H:1154
00804b sta $2114     [002114] A:00ff X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  0 H:1192
00804e lda #$07               A:00ff X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  0 H:1230
008050 sta $210e     [00210e] A:0007 X:00ff Y:0000 S:1ffd D:0000 DB:00 nvMXdIzC V:  0 H:1254
008053 sta $2110     [002110] A:0007 X:00ff Y:0000 S:1ffd D:0000 DB:00 nvMXdIzC V:  0 H:1292
008056 sta $2112     [002112] A:0007 X:00ff Y:0000 S:1ffd D:0000 DB:00 nvMXdIzC V:  0 H:1330
008059 sta $2114     [002114] A:0007 X:00ff Y:0000 S:1ffd D:0000 DB:00 nvMXdIzC V:  1 H:   4
00805c stz $210f     [00210f] A:0007 X:00ff Y:0000 S:1ffd D:0000 DB:00 nvMXdIzC V:  1 H:  42
00805f stz $210f     [00210f] A:0007 X:00ff Y:0000 S:1ffd D:0000 DB:00 nvMXdIzC V:  1 H:  80
008062 stz $2111     [002111] A:0007 X:00ff Y:0000 S:1ffd D:0000 DB:00 nvMXdIzC V:  1 H: 118
008065 stz $2111     [002111] A:0007 X:00ff Y:0000 S:1ffd D:0000 DB:00 nvMXdIzC V:  1 H: 156
008068 stz $2113     [002113] A:0007 X:00ff Y:0000 S:1ffd D:0000 DB:00 nvMXdIzC V:  1 H: 194
00806b stz $2113     [002113] A:0007 X:00ff Y:0000 S:1ffd D:0000 DB:00 nvMXdIzC V:  1 H: 232
00806e lda #$80               A:0007 X:00ff Y:0000 S:1ffd D:0000 DB:00 nvMXdIzC V:  1 H: 270
008070 sta $2115     [002115] A:0080 X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  1 H: 294
008073 stz $2116     [002116] A:0080 X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  1 H: 332
008076 stz $2117     [002117] A:0080 X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  1 H: 370
008079 stz $211a     [00211a] A:0080 X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  1 H: 408
00807c stz $211b     [00211b] A:0080 X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  1 H: 446
00807f lda #$01               A:0080 X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  1 H: 484
008081 sta $211b     [00211b] A:0001 X:00ff Y:0000 S:1ffd D:0000 DB:00 nvMXdIzC V:  1 H: 508
008084 stz $211c     [00211c] A:0001 X:00ff Y:0000 S:1ffd D:0000 DB:00 nvMXdIzC V:  1 H: 586
008087 stz $211c     [00211c] A:0001 X:00ff Y:0000 S:1ffd D:0000 DB:00 nvMXdIzC V:  1 H: 624
00808a stz $211d     [00211d] A:0001 X:00ff Y:0000 S:1ffd D:0000 DB:00 nvMXdIzC V:  1 H: 662
00808d stz $211d     [00211d] A:0001 X:00ff Y:0000 S:1ffd D:0000 DB:00 nvMXdIzC V:  1 H: 700
008090 stz $211e     [00211e] A:0001 X:00ff Y:0000 S:1ffd D:0000 DB:00 nvMXdIzC V:  1 H: 738
008093 sta $211e     [00211e] A:0001 X:00ff Y:0000 S:1ffd D:0000 DB:00 nvMXdIzC V:  1 H: 776
008096 stz $211f     [00211f] A:0001 X:00ff Y:0000 S:1ffd D:0000 DB:00 nvMXdIzC V:  1 H: 814
008099 stz $211f     [00211f] A:0001 X:00ff Y:0000 S:1ffd D:0000 DB:00 nvMXdIzC V:  1 H: 852
00809c stz $2120     [002120] A:0001 X:00ff Y:0000 S:1ffd D:0000 DB:00 nvMXdIzC V:  1 H: 890
00809f stz $2120     [002120] A:0001 X:00ff Y:0000 S:1ffd D:0000 DB:00 nvMXdIzC V:  1 H: 928
0080a2 stz $2121     [002121] A:0001 X:00ff Y:0000 S:1ffd D:0000 DB:00 nvMXdIzC V:  1 H: 966
0080a5 stz $2123     [002123] A:0001 X:00ff Y:0000 S:1ffd D:0000 DB:00 nvMXdIzC V:  1 H:1004
0080a8 stz $2124     [002124] A:0001 X:00ff Y:0000 S:1ffd D:0000 DB:00 nvMXdIzC V:  1 H:1042
0080ab stz $2125     [002125] A:0001 X:00ff Y:0000 S:1ffd D:0000 DB:00 nvMXdIzC V:  1 H:1080
0080ae stz $2126     [002126] A:0001 X:00ff Y:0000 S:1ffd D:0000 DB:00 nvMXdIzC V:  1 H:1118
0080b1 stz $2127     [002127] A:0001 X:00ff Y:0000 S:1ffd D:0000 DB:00 nvMXdIzC V:  1 H:1156
0080b4 stz $2128     [002128] A:0001 X:00ff Y:0000 S:1ffd D:0000 DB:00 nvMXdIzC V:  1 H:1194
0080b7 stz $2129     [002129] A:0001 X:00ff Y:0000 S:1ffd D:0000 DB:00 nvMXdIzC V:  1 H:1232
0080ba stz $212a     [00212a] A:0001 X:00ff Y:0000 S:1ffd D:0000 DB:00 nvMXdIzC V:  1 H:1270
0080bd stz $212b     [00212b] A:0001 X:00ff Y:0000 S:1ffd D:0000 DB:00 nvMXdIzC V:  1 H:1308
0080c0 stz $212c     [00212c] A:0001 X:00ff Y:0000 S:1ffd D:0000 DB:00 nvMXdIzC V:  1 H:1346
0080c3 stz $212d     [00212d] A:0001 X:00ff Y:0000 S:1ffd D:0000 DB:00 nvMXdIzC V:  2 H:  20
0080c6 stz $212e     [00212e] A:0001 X:00ff Y:0000 S:1ffd D:0000 DB:00 nvMXdIzC V:  2 H:  58
0080c9 stz $212f     [00212f] A:0001 X:00ff Y:0000 S:1ffd D:0000 DB:00 nvMXdIzC V:  2 H:  96
0080cc lda #$30               A:0001 X:00ff Y:0000 S:1ffd D:0000 DB:00 nvMXdIzC V:  2 H: 134
0080ce sta $2130     [002130] A:0030 X:00ff Y:0000 S:1ffd D:0000 DB:00 nvMXdIzC V:  2 H: 158
0080d1 stz $2131     [002131] A:0030 X:00ff Y:0000 S:1ffd D:0000 DB:00 nvMXdIzC V:  2 H: 196
0080d4 lda #$e0               A:0030 X:00ff Y:0000 S:1ffd D:0000 DB:00 nvMXdIzC V:  2 H: 234
0080d6 sta $2132     [002132] A:00e0 X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  2 H: 258
0080d9 stz $2133     [002133] A:00e0 X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  2 H: 296
0080dc stz $4200     [004200] A:00e0 X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  2 H: 334
0080df lda #$ff               A:00e0 X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  2 H: 372
0080e1 sta $4201     [004201] A:00ff X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  2 H: 396
0080e4 stz $4202     [004202] A:00ff X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  2 H: 434
0080e7 stz $4203     [004203] A:00ff X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  2 H: 472
0080ea stz $4204     [004204] A:00ff X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  2 H: 510
0080ed stz $4205     [004205] A:00ff X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  2 H: 588
0080f0 stz $4206     [004206] A:00ff X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  2 H: 626
0080f3 stz $4207     [004207] A:00ff X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  2 H: 664
0080f6 stz $4208     [004208] A:00ff X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  2 H: 702
0080f9 stz $4209     [004209] A:00ff X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  2 H: 740
0080fc stz $420a     [00420a] A:00ff X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  2 H: 778
0080ff stz $420b     [00420b] A:00ff X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  2 H: 816
008102 stz $420c     [00420c] A:00ff X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  2 H: 854
008105 stz $420d     [00420d] A:00ff X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  2 H: 892
008108 cli                    A:00ff X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdIzC V:  2 H: 930
008109 rts                    A:00ff X:00ff Y:0000 S:1ffd D:0000 DB:00 NvMXdizC V:  2 H: 952

;jmp to dma/vram routine. the inc of $0f is for my own personal write breakpoint, so I don't have to step through the initialization setup
00800c jmp $810a     [00810a] A:00ff X:00ff Y:0000 S:1fff D:0000 DB:00 NvMXdizC V:  2 H:1002

;dma/vram test
00810a inc $0f       [00000f] A:00ff X:00ff Y:0000 S:1fff D:0000 DB:00 NvMXdizC V:  2 H:1034
00810c lda #$80               A:00ff X:00ff Y:0000 S:1fff D:0000 DB:00 nvMXdizC V:  2 H:1080
00810e sta $2115     [002115] A:0080 X:00ff Y:0000 S:1fff D:0000 DB:00 NvMXdizC V:  2 H:1104
008111 lda #$80               A:0080 X:00ff Y:0000 S:1fff D:0000 DB:00 NvMXdizC V:  2 H:1142
008113 sta $2100     [002100] A:0080 X:00ff Y:0000 S:1fff D:0000 DB:00 NvMXdizC V:  2 H:1166
008116 rep #$10               A:0080 X:00ff Y:0000 S:1fff D:0000 DB:00 NvMXdizC V:  2 H:1204
008118 ldx #$0000             A:0080 X:00ff Y:0000 S:1fff D:0000 DB:00 NvMxdizC V:  2 H:1234
00811b stx $2116     [002116] A:0080 X:0000 Y:0000 S:1fff D:0000 DB:00 nvMxdiZC V:  2 H:1266
00811e lda #$01               A:0080 X:0000 Y:0000 S:1fff D:0000 DB:00 nvMxdiZC V:  2 H:1310
008120 sta $4300     [004300] A:0001 X:0000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:  2 H:1334
008123 lda #$18               A:0001 X:0000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:  3 H:   8
008125 sta $4301     [004301] A:0018 X:0000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:  3 H:  32
008128 ldx #$9000             A:0018 X:0000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:  3 H:  70
00812b stx $4302     [004302] A:0018 X:9000 Y:0000 S:1fff D:0000 DB:00 NvMxdizC V:  3 H: 102
00812e lda #$00               A:0018 X:9000 Y:0000 S:1fff D:0000 DB:00 NvMxdizC V:  3 H: 146
008130 sta $4304     [004304] A:0000 X:9000 Y:0000 S:1fff D:0000 DB:00 nvMxdiZC V:  3 H: 170
008133 ldx #$2000             A:0000 X:9000 Y:0000 S:1fff D:0000 DB:00 nvMxdiZC V:  3 H: 208
008136 stx $4305     [004305] A:0000 X:2000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:  3 H: 240
008139 lda #$01               A:0000 X:2000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:  3 H: 284
00813b sta $420b     [00420b] A:0001 X:2000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:  3 H: 308
00813e jmp $813e     [00813e] A:0001 X:2000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:  3 H: 346
Re: Question on tile animation
by on (#147945)
Glad to hear you've got that fixed! I'd say the good news is it's very little work to get from where you are now to displaying a background on screen. You just have to set up a few registers to tell the PPU what video mode you're in and where to find the tiles and tilemap in VRAM, and then build a tilemap. Specifically you'll definitely need to set up $2105 (mode/tile sizes) and $2107-$210D (VRAM locations for each BG Tileset/map).

You'll also need to write a palette to CGRAM to make the tiles appear correctly. You can input your colours manually using $2121 and $2122, or you can DMA a palette to $2122 just like you DMA'd the tiles.

(And if you're looking for a quick reference for the SNES's registers, my copy of Yoshi's (err, Koitsu's) "Snes1.txt" document has been absolutely indispensible to me since day one... Long since forgotten where I found it.)

EDIT: Forgot:
Quote:
Question, I'm not sure if I understood correctly on $2100. Does that act the same way as ppu rendering on/off for nes, like turning the screen to black? Just wondering if I need to come up with a new method, for writing to actual tiles from vram to the bg planes, once I get that far.

If you turn the screen off with $2100 the PPU stops drawing, meaning the screen instantly turns black and you're able to access VRAM again. For most normal purposes, you'll turn the screen on once and leave it, and do all your VRAM-accessing during vBlank. If you need more time, you can use $2100 to keep the screen off until you're done and turn it on after, at the expense of vertical drawing room.
Re: Question on tile animation
by on (#147946)
would it be because I'm loading 1000/2000 bytes of data into the dma/vram, that I'm required to shut off $2100? Cause I'm thinking maybe that's why when I did a bare bones write to the vram with one tile without dma, there was no issue. I'll start begin working on upload an entire palette set using dma too, I already have just one color inserted into the transparent palette slot. :-)
Re: Question on tile animation
by on (#147949)
infidelity wrote:
would it be because I'm loading 1000/2000 bytes of data into the dma/vram, that I'm required to shut off $2100? Cause I'm thinking maybe that's why when I did a bare bones write to the vram with one tile without dma, there was no issue

Quite possibly, I forget offhand how much you can DMA in one vBlank. It's also very likely to do with your program (I assume) going straight from initialization to the DMA without timing it to a vBlank, so you were probably trying to start the DMA right in the middle of the screen to begin with.

And speaking of timing when you want to go beyond just making things appear on screen to actually animating backgrounds and such, you'll need to have an actual game-loop-structure in your code too, whereby you have a main loop that waits for a vBlank interrupt every time through (probably with a WAI instruction) and a vBlank interrupt routine that does all your interactions with VRAM. Which I should mention; to do that you need to enable the vBlank interrupt by writing $80 to $4200.
Re: Question on tile animation
by on (#147950)
Khaz wrote:
(And if you're looking for a quick reference for the SNES's registers, my copy of Yoshi's (err, Koitsu's) "Snes1.txt" document has been absolutely indispensible to me since day one... Long since forgotten where I found it.)

I use the collected information on superfamicom.org, a lot of which is transcribed from anomie's docs. Several of the pages have gotten a lot of use, but the Registers page is one of two that I keep going back to no matter what I'm doing, the other being the 65816 reference page (I was new to ASM when I started a year ago). For second opinions and to confirm the latest known data on a topic, I check the newer (but IMO harder to navigate) fullsnes by nocash.

infidelity wrote:
would it be because I'm loading 1000/2000 bytes of data into the dma/vram, that I'm required to shut off $2100? Cause I'm thinking maybe that's why when I did a bare bones write to the vram with one tile without dma, there was no issue.

Did the earlier attempt have the same code context, so that it would happen at the same time? It could be that you randomly hit VBlank. As far as I know it doesn't matter whether it's the CPU proper or the DMA unit that's putting the values on the bus; you can't change VRAM during active display. I'd suspect an emulator bug, but with bsnes that's pretty unlikely unless you're deliberately trying to exploit an edge case...

Khaz wrote:
I forget offhand how much you can DMA in one vBlank.

A regular VBlank is 38 lines at 165.5 bytes per line, minus handling time at the beginning. About 6 kB. I suspect the problem here is timing - trying to run VRAM loading code without a timed trigger is a recipe for general failure peppered with random successes...
Re: Question on tile animation
by on (#147951)
yeah everything im doing is based off of seeing if I can get things to work for the first time. I honestly don't have any kind of demo or project in mind lol, im just excited to be able to get stuff (somewhat) working and appearing on the snes.

I tried reusing the exact same method I did for my dmd/vram, and try a dma/palette setup, only chaning the low byte of $2118 to 22, so that it's storing the palette data to $2122. I tried loading 200 bytes, but only 100 of the 200 logged bytes are being stored within the CGRAM. This is what I have.

Code:
008155 lda #$22               A:0000 X:1000 Y:0000 S:1fff D:0000 DB:00 nvMxdiZC V: 27 H: 724
008157 sta $4301     [004301] A:0022 X:1000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V: 27 H: 748
00815a ldx #$a000             A:0022 X:1000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V: 27 H: 786
00815d stx $4302     [004302] A:0022 X:a000 Y:0000 S:1fff D:0000 DB:00 NvMxdizC V: 27 H: 818
008160 lda #$00               A:0022 X:a000 Y:0000 S:1fff D:0000 DB:00 NvMxdizC V: 27 H: 862
008162 sta $4304     [004304] A:0000 X:a000 Y:0000 S:1fff D:0000 DB:00 nvMxdiZC V: 27 H: 886
008165 ldx #$0200             A:0000 X:a000 Y:0000 S:1fff D:0000 DB:00 nvMxdiZC V: 27 H: 924
008168 stx $4305     [004305] A:0000 X:0200 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V: 27 H: 956
00816b lda #$01               A:0000 X:0200 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V: 27 H:1000
00816d sta $420b     [00420b] A:0001 X:0200 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V: 27 H:1024
008170 lda #$80               A:0001 X:0200 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V: 27 H:1062
008172 sta $2100     [002100] A:0080 X:0200 Y:0000 S:1fff D:0000 DB:00 NvMxdizC V: 30 H:1234
I'm still trying to figure it out, can thank you guys enough for all of your info and help!
Re: Question on tile animation
by on (#147958)
infidelity wrote:
yeah everything im doing is based off of seeing if I can get things to work for the first time. I honestly don't have any kind of demo or project in mind lol, im just excited to be able to get stuff (somewhat) working and appearing on the snes.

I tried reusing the exact same method I did for my dmd/vram, and try a dma/palette setup, only chaning the low byte of $2118 to 22, so that it's storing the palette data to $2122. I tried loading 200 bytes, but only 100 of the 200 logged bytes are being stored within the CGRAM. This is what I have.

Code:
008155 lda #$22               A:0000 X:1000 Y:0000 S:1fff D:0000 DB:00 nvMxdiZC V: 27 H: 724
008157 sta $4301     [004301] A:0022 X:1000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V: 27 H: 748
00815a ldx #$a000             A:0022 X:1000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V: 27 H: 786
00815d stx $4302     [004302] A:0022 X:a000 Y:0000 S:1fff D:0000 DB:00 NvMxdizC V: 27 H: 818
008160 lda #$00               A:0022 X:a000 Y:0000 S:1fff D:0000 DB:00 NvMxdizC V: 27 H: 862
008162 sta $4304     [004304] A:0000 X:a000 Y:0000 S:1fff D:0000 DB:00 nvMxdiZC V: 27 H: 886
008165 ldx #$0200             A:0000 X:a000 Y:0000 S:1fff D:0000 DB:00 nvMxdiZC V: 27 H: 924
008168 stx $4305     [004305] A:0000 X:0200 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V: 27 H: 956
00816b lda #$01               A:0000 X:0200 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V: 27 H:1000
00816d sta $420b     [00420b] A:0001 X:0200 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V: 27 H:1024
008170 lda #$80               A:0001 X:0200 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V: 27 H:1062
008172 sta $2100     [002100] A:0080 X:0200 Y:0000 S:1fff D:0000 DB:00 NvMxdizC V: 30 H:1234
I'm still trying to figure it out, can thank you guys enough for all of your info and help!


If you're transferring to CGRAM you have to use DMA transfer mode 0 or 2, rather than transfer mode 1 as with VRAM (in other words, write #$00 or #$02 to $43x0 rather than #$01). You want to write all the bytes to $2122, not alternate between $2122 and $2123.
Re: Question on tile animation
by on (#147988)
Thank you AWJ! That was the issue, plus, it seemed I needed to only use LDA #$00 STA $2121, to properly set the starting point for my CG-RAM. I was doing LDA #$0000 $8E2121, and it wasn't storing the palette hex values correctly. But when I did the LDA #$00, it stored them correctly. I know this because I copied/pasted the 200 bytes used in the bootup for Super Mario World. So this is the code I have for loading 200 bytes. :-)

Code:
;already have x/y set to 16-bit's

008141 lda #$00               A:0001 X:1000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V: 27 H: 692
008143 sta $4300     [004300] A:0000 X:1000 Y:0000 S:1fff D:0000 DB:00 nvMxdiZC V: 27 H: 716
008146 lda #$00               A:0000 X:1000 Y:0000 S:1fff D:0000 DB:00 nvMxdiZC V: 27 H: 754
008148 sta $2121     [002121] A:0000 X:1000 Y:0000 S:1fff D:0000 DB:00 nvMxdiZC V: 27 H: 778
00814b lda #$22               A:0000 X:1000 Y:0000 S:1fff D:0000 DB:00 nvMxdiZC V: 27 H: 816
00814d sta $4301     [004301] A:0022 X:1000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V: 27 H: 840
008150 ldx #$b000             A:0022 X:1000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V: 27 H: 878
008153 stx $4302     [004302] A:0022 X:b000 Y:0000 S:1fff D:0000 DB:00 NvMxdizC V: 27 H: 910
008156 lda #$00               A:0022 X:b000 Y:0000 S:1fff D:0000 DB:00 NvMxdizC V: 27 H: 954
008158 sta $4304     [004304] A:0000 X:b000 Y:0000 S:1fff D:0000 DB:00 nvMxdiZC V: 27 H: 978
00815b ldx #$0200             A:0000 X:b000 Y:0000 S:1fff D:0000 DB:00 nvMxdiZC V: 27 H:1016
00815e stx $4305     [004305] A:0000 X:0200 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V: 27 H:1048
008161 lda #$01               A:0000 X:0200 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V: 27 H:1092
008163 sta $420b     [00420b] A:0001 X:0200 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V: 27 H:1116
008166 lda #$0f               A:0001 X:0200 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V: 27 H:1154
008168 sta $2100     [002100] A:000f X:0200 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V: 30 H:1326
00816b jmp $816b     [00816b] A:000f X:0200 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V: 31 H:   0


So I hope at some point today to begin seeing if I can draw a tile to a BG plane.

EDIT

I'm doing a test to see if I can fill the entire vram with tiles. So far, I'm able to load 8000 bytes into the vram, but if I go any higher, the bytes from 8000-FFFF are not correct, I'm assuming this is because I cant reach the other bank.

I have my tiles stored at address (viewing in a hex editor) $10000-$1FFFF, so that's 16 full chr pages of tiles, and it should fill the entire vram when viewing in 2bpp mode.

My question is, is there a way for me to read the DMA address that deals with how many bytes are stored into it, and if im able to perform some sort of CMP, where I can adjust the DMA register that looks for the bank id to load the rest of the tiles from? I'm asking this, incase you are only allowed 8000 bytes, and then have to re-write the routine again, due to needing to change the bank id.

This is what I have for loading the entire vram from $0000-$FFFF.

Code:
;load 8000 bytes into vram, from $0000-$7FFF, in bank 02, while asm is running in bank 00
00810c lda #$80               A:00ff X:00ff Y:0000 S:1fff D:0000 DB:00 nvMXdizC V:  2 H: 264
00810e sta $2115     [002115] A:0080 X:00ff Y:0000 S:1fff D:0000 DB:00 NvMXdizC V:  2 H: 288
008111 lda #$80               A:0080 X:00ff Y:0000 S:1fff D:0000 DB:00 NvMXdizC V:  2 H: 326
008113 sta $2100     [002100] A:0080 X:00ff Y:0000 S:1fff D:0000 DB:00 NvMXdizC V:  2 H: 350
008116 rep #$10               A:0080 X:00ff Y:0000 S:1fff D:0000 DB:00 NvMXdizC V:  2 H: 388
008118 stz $2116     [002116] A:0080 X:00ff Y:0000 S:1fff D:0000 DB:00 NvMxdizC V:  2 H: 418
00811b lda #$01               A:0080 X:00ff Y:0000 S:1fff D:0000 DB:00 NvMxdizC V:  2 H: 456
00811d sta $4300     [004300] A:0001 X:00ff Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:  2 H: 480
008120 lda #$18               A:0001 X:00ff Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:  2 H: 518
008122 sta $4301     [004301] A:0018 X:00ff Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:  2 H: 582
008125 ldx #$8000             A:0018 X:00ff Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:  2 H: 620
008128 stx $4302     [004302] A:0018 X:8000 Y:0000 S:1fff D:0000 DB:00 NvMxdizC V:  2 H: 652
00812b lda #$02               A:0018 X:8000 Y:0000 S:1fff D:0000 DB:00 NvMxdizC V:  2 H: 696
00812d sta $4304     [004304] A:0002 X:8000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:  2 H: 720
008130 ldx #$8000             A:0002 X:8000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:  2 H: 758
008133 stx $4305     [004305] A:0002 X:8000 Y:0000 S:1fff D:0000 DB:00 NvMxdizC V:  2 H: 790
008136 lda #$01               A:0002 X:8000 Y:0000 S:1fff D:0000 DB:00 NvMxdizC V:  2 H: 834
008138 sta $420b     [00420b] A:0001 X:8000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:  2 H: 858

;load 8000 bytes into vram, from $8000-$FFFF, in bank 03, while asm is running in bank 00
;for some reason at 00:813E, I need to set the vram high byte as C0, to start at vram address $8000?
00813b stz $2116     [002116] A:0001 X:8000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:  2 H: 896
00813e lda #$c0               A:0001 X:8000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:200 H: 958
008140 sta $2117     [002117] A:00c0 X:8000 Y:0000 S:1fff D:0000 DB:00 NvMxdizC V:200 H: 982
008143 lda #$01               A:00c0 X:8000 Y:0000 S:1fff D:0000 DB:00 NvMxdizC V:200 H:1020
008145 sta $4300     [004300] A:0001 X:8000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:200 H:1044
008148 lda #$18               A:0001 X:8000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:200 H:1082
00814a sta $4301     [004301] A:0018 X:8000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:200 H:1106
00814d ldx #$8000             A:0018 X:8000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:200 H:1144
008150 stx $4302     [004302] A:0018 X:8000 Y:0000 S:1fff D:0000 DB:00 NvMxdizC V:200 H:1176
008153 lda #$03               A:0018 X:8000 Y:0000 S:1fff D:0000 DB:00 NvMxdizC V:200 H:1220
008155 sta $4304     [004304] A:0003 X:8000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:200 H:1244
008158 ldx #$8000             A:0003 X:8000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:200 H:1282
00815b stx $4305     [004305] A:0003 X:8000 Y:0000 S:1fff D:0000 DB:00 NvMxdizC V:200 H:1314
00815e lda #$01               A:0003 X:8000 Y:0000 S:1fff D:0000 DB:00 NvMxdizC V:200 H:1358
008160 sta $420b     [00420b] A:0001 X:8000 Y:0000 S:1fff D:0000 DB:00 nvMxdizC V:201 H:  18


Image

Thanks everyone! :-)
Re: Question on tile animation
by on (#148005)
infidelity wrote:
So far, I'm able to load 8000 bytes into the vram, but if I go any higher, the bytes from 8000-FFFF are not correct, I'm assuming this is because I cant reach the other bank.

I have my tiles stored at address (viewing in a hex editor) $10000-$1FFFF, so that's 16 full chr pages of tiles, and it should fill the entire vram when viewing in 2bpp mode.

Sounds like a memory mapping issue.

First off, please note that in order to determine how the location of data in a hex editor translates to its location in the system's memory map, it's necessary to know what memory model you're using. If you're hex-editing a ROM directly, I'm not sure I have the requisite understanding to instruct you - it's the cartridge, not the SNES, that determines the ROM mapping...

On a Super NES, banks $00-$3F and $80-$BF have registers and mirrored RAM in the bottom half of each bank; they're somewhat like the NES's memory map. This is very useful since you get fast access to all MMIO resources as well as the bottom 8 kB of internal WRAM, but it means you can only access 32 kB of ROM per bank. A type of ROM mapping called (by hackers) LoROM restricts ROM bank sizes to 32 kB so as to allow fast access to all data from within these bank ranges.

Banks $40-$7D and $C0-$FF are 100% ROM (the 128 kB of internal WRAM takes up banks $7E and $7F), so you can access a whole ROM bank there. A type of ROM mapping called HiROM allows 64 kB data banks, so you can read data in 64 kB chunks in these bank ranges, but this means you can only read the top half of a ROM bank in $00-$3F and $80-$BF.

For small to medium-sized games, normally the ROM is mirrored across bank ranges. If you're using HiROM, for instance, the 64 kB of ROM that you can't access all of in bank $01 (or $81) will be present in its entirety in banks $41 and $C1. Games over 2 MB (LoROM) or 4 MB (HiROM) have to use less mirroring; the 12 MB Star Ocean hack uses none (it's a mix of 32 kB and 64 kB ROM banks).

...

If I had to guess, I'd say you're probably using LoROM, which would explain why the data at $10000-$1FFFF is ending up in banks $02 and $03. You won't be able to DMA that in one chunk from there, because the data is no longer contiguous in the SNES memory map (shadow RAM and MMIO are in between the two halves). Even in the all-ROM regions it wouldn't work (assuming my LoROM conjecture is correct), because DMA wraps within a bank - not to mention that not all LoROM mappings bother to mirror $8000-$FFFF to $0000-$7FFF in those banks. To access 64 kB all at once you need to be using HiROM and access the data in $40-$7D or $C0-$FF.

...

Also note that addresses into VRAM are word, not byte.
Re: Question on tile animation
by on (#148020)
At the risk of being a little off topic, I have a "tile animation" question that's rather specific, and it's short so I didn't feel like starting a thread over it. Was watching a TAS of Demon's Crest and admiring the final boss's death animation at 35:10. I've seen similar animations in other games - Dragon View has one really nice teleport animation that's the same kinda concept (here at 28:43), with the sprite spreading out vertically one line at a time.

Does anyone know, in general terms, how that's done? The Demon's Crest version I could see deleting pixels from VRAM in some repeating pattern to do the fading effect, but spreading it out vertically like that seems like a royal pain. Is there maybe some easy trick to it I'm missing out on? Demon's Crest's one is a bit big for it but I could see giving each horizontal strip its own sprites in Dragon View, so you can move them more freely.

Just curious...
Re: Question on tile animation
by on (#148021)
For Demon's Crest, I think it's a combination of deleting pixels in VRAM and a per-scanline effect of modifying the BG scroll registers (for Dragon View, the sprite may have been transferred to a background layer, too... although it may also be rendering the effect, too on a per-line basis, although it's limited to the size of the sprite).
Re: Question on tile animation
by on (#148023)
KungFuFurby wrote:
For Demon's Crest, I think it's a combination of deleting pixels in VRAM and a per-scanline effect of modifying the BG scroll registers (for Dragon View, the sprite may have been transferred to a background layer, too... although it may also be rendering the effect, too on a per-line basis, although it's limited to the size of the sprite).

Ahaa, that makes perfect sense for Demon's Crest, especially considering the background is just a solid colour gradient. I should have realized there was a free layer there.

I'm not sure what Dragon View's doing though, I'm pretty sure there's no spare BG layer in that room. Seeing as how the effect stays within the original sprite area, I think it's probably actually editing the sprite tiles. I should have a closer look and actually see what's going on...

EDIT: Alright, I was wrong. The instant you touch the warp point, Dragon View copies that crouching position over to BG1. BG1 is apparently empty in that room. It SHOULD be used for the bit of foreground along the bottom with the doorway, but I guess they used sprites for that just in this room so they could abuse BG1.
Re: Question on tile animation
by on (#148037)
Khaz wrote:
EDIT: Alright, I was wrong. The instant you touch the warp point, Dragon View copies that crouching position over to BG1. BG1 is apparently empty in that room. It SHOULD be used for the bit of foreground along the bottom with the doorway, but I guess they used sprites for that just in this room so they could abuse BG1.

Color me surprised, I was also betting on a sprite based effect (either allocating plenty of sprites or blitting into just one or two). I'm surprised they didn't go further with the HDMA tables then, the effect does look kinda lame...
Re: Question on tile animation
by on (#148040)
Thank you 93143, for explaining the LoROM HiRom. That explains why I need to do 8000 bytes (hex) at a time for dma/vram transfer.

Ok I have another question on vram. The vram has address $0000-$FFFF. I currently have it entirely filled with tile data, as seen in my previous post with a pic. Where do the bg planes store the tile data? Is it within the vram I already have filled? Is there another (ram) section that I don't know about that holds these values? Thanks! :-)
Re: Question on tile animation
by on (#148042)
infidelity wrote:
Thank you 93143, for explaining the LoROM HiRom. That explains why I need to do 8000 bytes at a time for dma/vram transfer.


Better revise that to 32,768 bytes for the convenience for our readers (which is $8000 bytes in hexadecimal). Reduces confusion that way (I sometimes end up doing that myself). Also, that's only good if the data is at the start of the bank ($xx8000-$xxFFFF)... otherwise, you've got until the end of the bank, followed by any data on the next bank for the next transfer.
Re: Question on tile animation
by on (#148043)
Sorry about that, I added (hex) to my comment.
Re: Question on tile animation
by on (#148051)
Khaz wrote:
EDIT: Alright, I was wrong. The instant you touch the warp point, Dragon View copies that crouching position over to BG1. BG1 is apparently empty in that room. It SHOULD be used for the bit of foreground along the bottom with the doorway, but I guess they used sprites for that just in this room so they could abuse BG1.

I'll be blunt, that's pretty overkill for something that could have been managed in software honestly (it's literally just copying entire rows as-is and the sprite is rather tiny). Heck, just split each row into its own sprite and you don't even need to keep the CPU busy during the animation itself (overflow wouldn't be an issue since empty rows would be the ones removed anyway).

Each to their own way of doing it, I guess.
Re: Question on tile animation
by on (#148057)
Optiroc wrote:
the effect does look kinda lame...

Seems a bit judgmental for an animation effect they expected to get one use out of per playthrough. I think it looks wonderfully fancy without being ostentatious or a waste of effort.
Quote:
I'll be blunt, that's pretty overkill for something that could have been managed in software honestly

I would imagine the rationale was "It's just so much easier to use a BG layer and HDMA...". Like, that approach I bet you write one HDMA table and you're done. Doing it the other way is a lot of copying and moving things around manually....
Re: Question on tile animation
by on (#148059)
Oh right, I forgot about HDMA >.<; Still, the software option is there if you don't want to waste layers.
Re: Question on tile animation
by on (#148060)
Ok I have another question on vram. The vram has address $0000-$FFFF. I currently have it entirely filled with tile data, as seen in my previous post with a pic. Where do the bg planes store the tile data? Is it within the vram I already have filled? Is there another (ram) section that I don't know about that holds these values?

Also, how do you where the nmi is in a rom? The rom I have is megaman X, that I'm using to test all my stuff you have all seen in this thread. When I hacked the nes, I knew that the nmi had its own address at $FFFA, and that the reset vector had an infinite loop on itself waiting for an nmi to trigger.

So how do I know where to locate the snes nmi address, and does the snes have a reset vector. Cause so far it seems to me, that the reset vector always starts at 00:0000. Thanks again for the info! :-)
Re: Question on tile animation
by on (#148064)
infidelity wrote:
Ok I have another question on vram. The vram has address $0000-$FFFF. I currently have it entirely filled with tile data, as seen in my previous post with a pic. Where do the bg planes store the tile data? Is it within the vram I already have filled? Is there another (ram) section that I don't know about that holds these values?

Also, how do you where the nmi is in a rom? The rom I have is megaman X, that I'm using to test all my stuff you have all seen in this thread. When I hacked the nes, I knew that the nmi had its own address at $FFFA, and that the reset vector had an infinite loop on itself waiting for an nmi to trigger.

So how do I know where to locate the snes nmi address, and does the snes have a reset vector. Cause so far it seems to me, that the reset vector always starts at 00:0000. Thanks again for the info! :-)


BG nametables are in the same VRAM as tile patterns (so you can't completely fill VRAM with tiles if you want to display any BGs). There are PPU registers that control where the nametable for each BG is, and where the tile pattern data for each BG and for the sprites begins (i.e. the VRAM address corresponding to "tile number 0" for that layer)

The 65816 reset vector is at 00:fffc, the same as the 6502. The 65816 has a 24-bit address space, but the vectors are 16-bit and can only reside in, and only point to, the first 64KB of the address space. When the CPU is powered on or reset it is running in 6502 emulation mode, and fetches the NMI vector from 00:fffa and the IRQ and BRK vectors from 00:fffe, exactly like a 6502. When the CPU is running in native mode (i.e. after clc; xce) it fetches NMI from 00:ffea, IRQ from 00:ffee and BRK from 00:ffe6 (the 65816 has a bunch of other vectors as well but you never need to worry about them on the SNES)

Those addresses are CPU addresses; how they translate to ROM offsets depends on the cartridge type. For a mode 20 cartridge, subtract $8000 from the CPU address (this only works for addresses in the first 32KB of the ROM!) So for Megaman X the reset vector is at offset $7ffc in the ROM, and the value in it is $8000, which points to the very beginning of the ROM (as you've noticed). For a mode 21 cartridge don't subtract anything from the CPU address (again, this only applies to addresses in the first bank).

Note that if any of the vectors is less than $8000, then that vector is pointing into RAM rather than ROM, and you'll have to trace the game code to see what it puts in that RAM location to find the actual interrupt handler. Do not get confused by mode 21--a vector value of $1000 is pointing to offset $1000 in RAM, not ROM, regardless of whether it's mode 20 or mode 21 (I made this mistake myself when I started reverse engineering my first SNES game, many years ago. I got very confused because there was valid code at the ROM address the NMI vector appeared to be pointing to, but it wasn't the code that was executing at NMI)

The value of the reset vector will always be between $8000 and $FFFF--it has to point to ROM, because RAM is uninitialized when the SNES is powered on. This is one of the heuristics SNES emulators and flashcarts use to determine the correct mapping for a ROM image.
Re: Question on tile animation
by on (#148065)
infidelity wrote:
Ok I have another question on vram. The vram has address $0000-$FFFF.

VRAM addresses on the Super NES is word addressed. For example, $0000 is 16 bits, $0001 is 16 bits, $0002 is 16 bits, etc. This means the 65536 byte VRAM has addresses $0000-$7FFF.

Quote:
I currently have it entirely filled with tile data, as seen in my previous post with a pic. Where do the bg planes store the tile data? Is it within the vram I already have filled? Is there another (ram) section that I don't know about that holds these values?

Tile data goes in "pattern tables". Each background can address 1,024 different tiles (16 KiB for 4-color, 32 KiB for 16-color, or the whole 64 KiB for 256-color). The VRAM addresses of the pattern tables used by each background are specified in $210B.

Map data goes in "nametables", each 2048 bytes ($400 words) in size, which hold which tile goes at each position in a 32x32 tile grid. The VRAM addresses of the nametables are specified in the background screen base registers ($2107-$210A). A scrolling background usually has two nametables side by side, giving an effective 64x32 tile grid, so that columns of tiles can be uploaded to the nametable before they scroll into view.

One possible VRAM layout for mode 1 might look like this:

$0000-$3FFF: 16-color background tiles 0-1023, used by background 1 and 2
$4000-$5FFF: Sprite tiles 0-511 (sprites are always 16 colors)
$6000-$63FF: Background 1 left nametable
$6400-$67FF: Background 1 right nametable
$6800-$6BFF: Background 2 left nametable
$6C00-$6FFF: Background 2 right nametable
$7000-$73FF: Background 3 nametable (often used for a scoreboard, like the "fix" layer on Neo Geo)
$7400-$7FFF: 4-color background tiles 640-1023, used by background 3
Re: Question on tile animation
by on (#148067)
Thank you AWJ & tepples! All of that information is very helpful! I'll start tonight working on inserting a tile to a BG. And then try to have a functional nmi.

Oh with the nmi, in the nes I forget off the top of my head, of the nes needing a value of $80 sorted to it, in order for the nmi to kick on. Does the snes have a similar register that needs to be written to within the rest vector, for the nmi to be initiated? Thanks again for all of that info!
Re: Question on tile animation
by on (#148073)
http://wiki.superfamicom.org/snes/show/Registers

Scroll down to the detailed description of NMITIMEN, which is at $4200.