Question on tile animation

Discussion of hardware and software development for Super NES and Super Famicom.

Moderator: Moderators

Forum rules
  • For making cartridges of your Super NES games, see Reproduction.
93143
Posts: 1371
Joined: Fri Jul 04, 2014 9:31 pm

Re: Question on tile animation

Post by 93143 »

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...
infidelity
Posts: 486
Joined: Fri Mar 01, 2013 4:46 am

Re: Question on tile animation

Post by infidelity »

deleted post due to errors on my end.
Last edited by infidelity on Tue May 19, 2015 2:07 pm, edited 1 time in total.
93143
Posts: 1371
Joined: Fri Jul 04, 2014 9:31 pm

Re: Question on tile animation

Post by 93143 »

infidelity wrote:

Code: Select all

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: Select all

00FF,00FF,00DB,00FF,00BD,00C3,00BD,00FF
This has a decent explanation.
infidelity
Posts: 486
Joined: Fri Mar 01, 2013 4:46 am

Re: Question on tile animation

Post by infidelity »

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!
93143
Posts: 1371
Joined: Fri Jul 04, 2014 9:31 pm

Re: Question on tile animation

Post by 93143 »

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...
infidelity
Posts: 486
Joined: Fri Mar 01, 2013 4:46 am

Re: Question on tile animation

Post by infidelity »

This is what I meant by the colors of the vram tile.

Image Image
93143
Posts: 1371
Joined: Fri Jul 04, 2014 9:31 pm

Re: Question on tile animation

Post by 93143 »

Okay, yeah. Different data. That makes sense, thanks.
infidelity
Posts: 486
Joined: Fri Mar 01, 2013 4:46 am

Re: Question on tile animation

Post by infidelity »

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: Select all

(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?
93143
Posts: 1371
Joined: Fri Jul 04, 2014 9:31 pm

Re: Question on tile animation

Post by 93143 »

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.
infidelity
Posts: 486
Joined: Fri Mar 01, 2013 4:46 am

Re: Question on tile animation

Post by infidelity »

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: Select all

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.
UnDisbeliever
Posts: 77
Joined: Mon Mar 02, 2015 1:11 am
Location: Australia (PAL)
Contact:

Re: Question on tile animation

Post by UnDisbeliever »

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: Select all

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
infidelity
Posts: 486
Joined: Fri Mar 01, 2013 4:46 am

Re: Question on tile animation

Post by infidelity »

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: Select all

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!
infidelity
Posts: 486
Joined: Fri Mar 01, 2013 4:46 am

Question om dma/vram. Please view latest post.

Post by infidelity »

Any ideas? :-/
User avatar
Khaz
Posts: 314
Joined: Thu Dec 25, 2014 10:26 pm
Location: Canada

Re: Question on tile animation

Post by Khaz »

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: Select all

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.
Last edited by Khaz on Thu May 21, 2015 2:41 pm, edited 2 times in total.
AWJ
Posts: 433
Joined: Mon Nov 10, 2008 3:09 pm

Re: Question on tile animation

Post by AWJ »

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: Select all

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.
Post Reply