Bitplanes 1 pixel off?

Discussion of hardware and software development for Super NES and Super Famicom. See the SNESdev wiki for more information.

Moderator: Moderators

Forum rules
  • For making cartridges of your Super NES games, see Reproduction.
Post Reply
Breadstick
Posts: 10
Joined: Wed Oct 19, 2022 1:14 pm

Bitplanes 1 pixel off?

Post by Breadstick »

Hey all, this feels like somewhat of a beginner question but I am at the end of my tether trying to figure out whats happening.
For a 4 bit sprite I'm DMAing into VRAM

Code: Select all

PlayerSprite:  ;Bitplanes 1 and 2 are interleaved, same as 3 and 4
                ;So the left column is plane 1, second is plane 2. Then this repeats for 3 and 4
    .db %00000000 %00000000
    .db %00000000 %00000000
    .db %00000000 %00000000
    .db %00000000 %00000000
    .db %11111111 %11111111
    .db %11111111 %11111111
    .db %11111111 %11111111
    .db %11111111 %11111111
    
    .db %00000000 %00000000
    .db %00000000 %00000000
    .db %00000000 %00000000
    .db %00000000 %00000000
    .db %00000000 %00000000
    .db %00000000 %00000000
    .db %00000000 %00000000
    .db %00000000 %00000000

    ;Start of the next one, we'll get there in a second
    .db %11111111 %11111111
    .db %11111111 %11111111	;Note we have 2 lines here
    .db %00000000 %00000000	;And the third is set to 0
With a colour palette of white, red, green, blue, I get the result
glitchA.png
And whats more, looking at the loaded tiles, even though I only have two rows set to ones on the next sprite, I get this
GlitchB.png
GlitchB.png (2.34 KiB) Viewed 1030 times
The top of sprite 1 isn't 0s, and sprite 2 has 3 rows with data in it. It looks like the second bitplane is off by 1, because if I change the sprite to be

Code: Select all

PlayerSprite:
    .db %00000000 %00000000
    .db %00000000 %00000000
    .db %00000000 %00000000
    .db %00000000 %11111111	;Note I've moved it up by 1
    .db %11111111 %11111111
    .db %11111111 %11111111
    .db %11111111 %11111111
    .db %11111111 %00000000
It draws properly
glitchC.png
I really don't get whats happening because from what I know of the SNES this shouldn't be how 4bpp graphics are stored?
My DMA code is the following, in the event I've got something wrong there

Code: Select all

DMAPlayerSprite:
    rep #$20
    
    lda.w #PlayerSprite
    sta $4302   ;Set the source

    sep #$20    ;8 bit A

    lda #64  ;Byte size
    sta $2115
    sta $4305
    lda #0
    sta $2116   ;Set the VRAM target
    sta $2117
    sta $4306   ;Upper byte of DMA transfer size

    lda #$18
    sta $4301   ;Target 2118 (VRAM gate)

    lda	#$0
    sta $4304   ;src is in Bank 0
    ;sta	$4300

    lda	#$01
    sta	$4300   ;Flag to send a word at a time   
    sta	$420b   ;start the DMA

    rts
A huge thank you to anyone who takes the time to help!
User avatar
jeffythedragonslayer
Posts: 344
Joined: Thu Dec 09, 2021 12:29 pm

Re: Bitplanes 1 pixel off?

Post by jeffythedragonslayer »

Could you show us the code with the raw memory addresses replaced with their fullsnes common names so they're easier to read?

Also, what tool did you use to create the glitch png screenshot?
Last edited by jeffythedragonslayer on Sun Feb 05, 2023 5:14 pm, edited 1 time in total.
Breadstick
Posts: 10
Joined: Wed Oct 19, 2022 1:14 pm

Re: Bitplanes 1 pixel off?

Post by Breadstick »

Well boy howdy I didn't know these existed
Here they are with some lovely lovely names!

Code: Select all

 DMAPlayerSprite:
    rep #$20
    
    lda.w #PlayerSprite
    sta $4302   ;Set the source

    sep #$20    ;8 bit A

    lda #64  ;Byte size
    sta VMAIN
    sta DAS0L
    lda #0
    sta VMADDL   ;Set the VRAM target
    sta VMADDH
    sta DAS0H   ;Upper byte of DMA transfer size

    lda #$18
    sta BBAD0   ;Target 2118 (VRAM gate)

    lda	#$0
    sta A1B0   ;src is in Bank 0

    lda	#$01
    sta	DMAP0   ;Flag to send a word at a time   
    sta	MDMAEN   ;start the DMA

    rts
User avatar
jeffythedragonslayer
Posts: 344
Joined: Thu Dec 09, 2021 12:29 pm

Re: Bitplanes 1 pixel off?

Post by jeffythedragonslayer »

I do not know off the top of my head while reading this on my smartphone on the couch, but I suggest you try poking around in the excellent Mesen debugging emulator. I scribbled over VRAM with it a lot and in bsnes+ at runtime to experiment this past year - that's how I created the tile stride table:

viewtopic.php?p=280631&hilit=tile+stride+table#p280631
Breadstick
Posts: 10
Joined: Wed Oct 19, 2022 1:14 pm

Re: Bitplanes 1 pixel off?

Post by Breadstick »

Thanks for the link!
Breadstick
Posts: 10
Joined: Wed Oct 19, 2022 1:14 pm

Re: Bitplanes 1 pixel off?

Post by Breadstick »

Ok I've fixed it, and in case someone has this issue I'll explain what happened here
There is a tutorial linked on the wiki, https://en.wikibooks.org/wiki/Super_NES ... A_tutorial
and at some point it has the line
ldy #$80 ; we will try to write 128 ($80) bytes in one row ...
sty $2115 ; ... and we will let the PPU let this know.
And it seems to be this write to 2115 that bungles it

As soon as I removed the line where I was writing the expected size to 2115, it behaved as normal
Hope this helps anyone who gets the same issue!
User avatar
jeffythedragonslayer
Posts: 344
Joined: Thu Dec 09, 2021 12:29 pm

Re: Bitplanes 1 pixel off?

Post by jeffythedragonslayer »

Does anyone rely on this? If the tutorial is broken, we should fix it. It's on a wiki, after all.
UnDisbeliever
Posts: 124
Joined: Mon Mar 02, 2015 1:11 am
Location: Australia (PAL)
Contact:

Re: Bitplanes 1 pixel off?

Post by UnDisbeliever »

Breadstick wrote: Sun Feb 05, 2023 6:16 pm and at some point it has the line
ldy #$80 ; we will try to write 128 ($80) bytes in one row ...
sty $2115 ; ... and we will let the PPU let this know.
And it seems to be this write to 2115 that bungles it
That comment makes no sense at all.

VMAIN ($2115) (wiki link) controls how the internal VRAM address is incremented. (It also allows for VRAM address-remapping, but let's ignore that for now.)

You should always set VMAIN before DMAing to VRAM to ensure the data is copied in the correct manner.

To write word data to VRAM (required for 2/4/8bpp tile data), you need to set VMAIN to $80.

In DMAPlayerSprite, you are writing 64 to VMAIN. Bit 6 of VMAIN doesn't map to anything and puts the PPU into a "low-byte increment, increment by 1" mode. This mode is intended for writing data to only the low-VRAM chip (VMDATAL byte register). Writing word data to VRAM in this mode is not recommended as it can cause an off-by-one error (The first byte is transferred correctly, all other bytes are transferred to `intended word address + 1`).
Oziphantom
Posts: 1565
Joined: Tue Feb 07, 2017 2:03 am

Re: Bitplanes 1 pixel off?

Post by Oziphantom »

Code: Select all

    lda #64  ;Byte size
    sta $2115
that looks wrong.

Code: Select all

ldy #$80 ; we will try to write 128 ($80) bytes in one row ...
sty $2115 ; ... and we will let the PPU let this know.
And it seems to be this write to 2115 that bungles it
My guess is at this point your Y is 16bits and hence you trash 2116 as well.

If you've not seen it, try my tutorials here viewtopic.php?t=24387
Post Reply