Question about SNES palette writes

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
zombero
Posts: 6
Joined: Mon May 01, 2017 8:45 am

Question about SNES palette writes

Post by zombero »

I'm using the following macro call and macro to make changes to palettes. The issue I'm having is that a significant portion of the time, rather than writing to the CGRAM destination that is given, it writes to CGRAM destination $01 instead. Does anyone with DMA transfer experience know what could cause this discrepancy? Thanks.

%SetPalette(#$B0, #$8000, #$e0, #$0020)

macro SetPalette(bank, source, dest, size)

;---header
php
rep #$30
pha
phx
phy
sep #$20
rep #$10

;---main

ldx <source>
stx $4372

lda <bank>
sta $4374

ldy <size>
sty $4375

lda <dest>
sta $2121

ldx #$2202
stx $4370

lda #$80
sta $420b

;---footer
rep #$30
ply
plx
pla
plp
endmacro
User avatar
dougeff
Posts: 3079
Joined: Fri May 08, 2015 7:17 pm

Re: Question about SNES palette writes

Post by dougeff »

I do know that in the last few lines...

rep #$30

Then

Plp

, the rep #$30 is meaningless, since plp restores the original processor state.
Last edited by dougeff on Tue May 16, 2017 7:15 am, edited 1 time in total.
nesdoug.com -- blog/tutorial on programming for the NES
zombero
Posts: 6
Joined: Mon May 01, 2017 8:45 am

Re: Question about SNES palette writes

Post by zombero »

dougeff wrote:the rep #$30 is meaningless, since plp restores the original processor state.
The rep #$30 is for the ply, plx, pla. These are pushed in 16-bit mode, so I need to pull them in 16-bit mode, too.
User avatar
dougeff
Posts: 3079
Joined: Fri May 08, 2015 7:17 pm

Re: Question about SNES palette writes

Post by dougeff »

I see. That makes sense.
nesdoug.com -- blog/tutorial on programming for the NES
adam_smasher
Posts: 271
Joined: Sun Mar 27, 2011 10:49 am
Location: Victoria, BC

Re: Question about SNES palette writes

Post by adam_smasher »

What assembler are you using? Have you checked to see that this is getting assembled correctly?
zombero
Posts: 6
Joined: Mon May 01, 2017 8:45 am

Re: Question about SNES palette writes

Post by zombero »

adam_smasher wrote:What assembler are you using? Have you checked to see that this is getting assembled correctly?
Asar. Yeah, I've stepped through the disassembly and everything checks out, as far as I can tell. Here's the disassembly:

$B8/C99E 08 PHP A:0002 X:0000 Y:0C70 P:envMxdizc
$B8/C99F C2 30 REP #$30 A:0002 X:0000 Y:0C70 P:envMxdizc
$B8/C9A1 48 PHA A:0002 X:0000 Y:0C70 P:envmxdizc
$B8/C9A2 DA PHX A:0002 X:0000 Y:0C70 P:envmxdizc
$B8/C9A3 5A PHY A:0002 X:0000 Y:0C70 P:envmxdizc
$B8/C9A4 E2 20 SEP #$20 A:0002 X:0000 Y:0C70 P:envmxdizc
$B8/C9A6 C2 10 REP #$10 A:0002 X:0000 Y:0C70 P:envMxdizc
$B8/C9A8 A2 00 80 LDX #$8000 A:0002 X:0000 Y:0C70 P:envMxdizc
$B8/C9AB 8E 72 43 STX $4372 [$05:4372] A:0002 X:8000 Y:0C70 P:eNvMxdizc
$B8/C9AE A9 B0 LDA #$B0 A:0002 X:8000 Y:0C70 P:eNvMxdizc
$B8/C9B0 8D 74 43 STA $4374 [$05:4374] A:00B0 X:8000 Y:0C70 P:eNvMxdizc
$B8/C9B3 A0 20 00 LDY #$0020 A:00B0 X:8000 Y:0C70 P:eNvMxdizc
$B8/C9B6 8C 75 43 STY $4375 [$05:4375] A:00B0 X:8000 Y:0020 P:envMxdizc
$B8/C9B9 A9 E0 LDA #$E0 A:00B0 X:8000 Y:0020 P:envMxdizc
$B8/C9BB 8D 21 21 STA $2121 [$05:2121] A:00E0 X:8000 Y:0020 P:eNvMxdizc
$B8/C9BE A2 02 22 LDX #$2202 A:00E0 X:8000 Y:0020 P:eNvMxdizc
$B8/C9C1 8E 70 43 STX $4370 [$05:4370] A:00E0 X:2202 Y:0020 P:envMxdizc
$B8/C9C4 A9 80 LDA #$80 A:00E0 X:2202 Y:0020 P:envMxdizc
$B8/C9C6 8D 0B 42 STA $420B [$05:420B] A:0080 X:2202 Y:0020 P:eNvMxdizc
$B8/C9C9 C2 30 REP #$30 A:0080 X:2202 Y:0020 P:eNvMxdizc
$B8/C9CB 7A PLY A:0080 X:2202 Y:0020 P:eNvmxdizc
$B8/C9CC FA PLX A:0080 X:2202 Y:0C70 P:envmxdizc
$B8/C9CD 68 PLA A:0080 X:0000 Y:0C70 P:envmxdiZc
$B8/C9CE 28 PLP A:0002 X:0000 Y:0C70 P:envmxdizc
User avatar
HihiDanni
Posts: 186
Joined: Tue Apr 05, 2016 5:25 pm

Re: Question about SNES palette writes

Post by HihiDanni »

I'm assuming this code is run in the NMI handler or a setup routine during force-blank? Is there any other part of your program that accesses the same registers? And is this debugger stepthru from a successful run?
SNES NTSC 2/1/3 1CHIP | serial number UN318588627
zombero
Posts: 6
Joined: Mon May 01, 2017 8:45 am

Re: Question about SNES palette writes

Post by zombero »

Successful and unsuccessful runs look identical. It's not run in the NMI handler, and I'm not really sure what that is, but upon some brief reading: it sounds like that's probably what I'm missing! Thanks for the info.
User avatar
HihiDanni
Posts: 186
Joined: Tue Apr 05, 2016 5:25 pm

Re: Question about SNES palette writes

Post by HihiDanni »

Well are you trying to call this during initialization or during gameplay? For gameplay it belongs in the NMI handler, if it's initialization you should enable force-blank (it's a bit in the INIDISP register at $2100) to turn off the display so you have free access to the PPU registers without needing to wait for NMI.

This page has information on when you can reliably access the different registers (during force-blank, v-blank (NMI), h-blank, or any time).

Edit: While in your initialization routine you might also want to disable the v-blank interrupt (or otherwise prevent your NMI routine from doing anything). If NMI fires while you're writing to the registers and then does its own writes to the registers you might get some strange results. So you should check for that as well.

Edit 2: Another observation: If SetPalette will be used in performance critical code you may want to cut down on the register-to-stack operations. At the very least, you can optimize this by replacing the ldy/sty instructions with ldx/stx and then removing the phy/ply instructions surrounding the operation.
SNES NTSC 2/1/3 1CHIP | serial number UN318588627
zombero
Posts: 6
Joined: Mon May 01, 2017 8:45 am

Re: Question about SNES palette writes

Post by zombero »

HihiDanni wrote:Well are you trying to call this during initialization or during gameplay? For gameplay it belongs in the NMI handler
It's during gameplay, so I'll look into the NMI route.
HihiDanni wrote:Edit 2: Another observation: If SetPalette will be used in performance critical code you may want to cut down on the register-to-stack operations. At the very least, you can optimize this by replacing the ldy/sty instructions with ldx/stx and then removing the phy/ply instructions surrounding the operation.
I don't believe it is during critical code, but I'll go ahead and at least make that optimization.
zombero
Posts: 6
Joined: Mon May 01, 2017 8:45 am

Re: Question about SNES palette writes

Post by zombero »

Update: after doing some reading about NMI, I was able to locate the game's v-blank routine and altered my macro to write to the game's queue of graphics changes to make during NMI, rather than having the macro perform a DMA transfer on its own. Looks like this has resolved the issue.

Thanks for the help!
Post Reply