What Tepples said is correct; root cause of your issue is unrelated to the "failed checksum" message, and fixing that is up to a utility that runs either post-assembly or has to be handled properly by the assembler itself.
I'm of the same opinion as bazz at this point, but will expand:
1. $2121 not being set immediately prior to tinkering with $2122 is probably not wise.
2. You're not doing
anything with $2115 (VRAM access mode/model), $2116/2117 (VRAM address) nor $2118/2119 (VRAM data) -- meaning, you aren't writing anything to VRAM. You're making a blind (and very bad!) assumption that the content of VRAM is is pre-zeroed/empty. This would vary from emulator to emulator. If higan/bsnes sticks "random crap" there on power-on, then good, because there's no guarantee what VRAM contains on power-on or reset on the actual console! It's your responsibility to zero this out (commonly done via DMA) as you see fit.
3. Likewise/related to 2, you're not doing anything with $2105 (selecting BG mode/size), $2107 through $210a (BG-SC size/base address), nor $210b/210c (name base address for CHR data). You've probably got $2105 as $00 (mode 0, tile size of 8x8), and $2107 (BG1) is probably pointing to $0000 in VRAM, and $210b (BG1 and BG2) is probably also pointing to $0000 in VRAM, which is probably not what you want (CHR data at the same location as the layout data? Heh ;-) Well I guess for a "blank/zero everything" you might!).
See SNES developers manual Chapter 3 (page 2-3-2 onward) for what you should be doing before turning on the screen in this case.
4. You probably aren't initialising the 65816 correctly but since you aren't providing full source code I can't tell. The
very first thing you should be doing (meaning this is the code that should get pointed to by the RESET vector) is this:
Code:
.org $xx8000 ; Or however this is done with WLA DX -- see below for why I say $xx, but $xx8000 is important!
RESET: ; Point RESET vector here
sei
clc
xce
jml RESETNEXT
RESETNEXT:
jsl SNES_Init
My guess is that (2) and (3) are the cause of your problem.
(4) is also immensely important. There are multiple things going on there, so I'll itemise them:
4a) You need to make sure the assembler is operating with the knowledge that it's in either bank $c0 (normal speed mode 21 (hirom) -- probably what you want), or $80 (fast speed mode 21 but be aware of the memory layout) -- see SNES developers manual page 2-21-4 for the memory layout and see the notes at the bottom of that page -- and this also relates to (4d) below,
4b) Disabling interrupts ASAP is important, you don't want a spurious NMI or hardware IRQ happening at this point. This is just common practise as well, even on the 6502/65c02,
4c) You absolutely need to clear emulation mode on startup. The 65816 starts up in 65c02 emulation mode (e.g. e=1),
4d) The
jml {next line} looks pointless but isn't. This is a "65816 quirk" per se; what's being ensured here is that the K register (sometimes called "PBR" -- "Program Bank Register") gets set to where your code should actually be running out of and not bank $00. All the 65816 vectors are bankless, i.e. 16-bit values, and bank $00 is assumed. But also remember that this same quirk/issue needs to apply to other vectors (ex. NMI).
Reworded: K is $00 on power-on, so your startup code is actually going to be executed in bank $00. If you look at a memory map for mode 21, look at what's in bank $00 -- specifically how $8000 to $ffff are mirrored from bank $c08000 to $c0ffff. Same goes for $808000 to $80ffff. This is one of the reasons why that mirroring is important, and likewise, why that
jml is important -- to get out of bank $00 and into $c0 or $80 (depends on what you want). But you also need to keep the routines within the $xx8000 to $xxffff range (well $ffe3 I guess), meaning don't go doing something like
.org $800000 for your RESET vector to be at $0000 (look at what's in bank $00 at $0000 ;-) ).
See SNES developers manual pages 2-24-3 and 2-24-4 for details on (4b) through (4d); they're discussed fully there. Otherwise please read (do not skim) the
Western Design Center's 65816 Programmer's Manual, page 55 ("Interrupts").
You may also want or need to do a
phk/plb once you've switched over to a different bank; this sets the B register to whatever K is at the time. Again you need to know what you're doing, have familiarity with your assembler, and understand the memory map fully to know what's "safe". Example: you don't want to be in bank $00 and do something like a jmp $2100, you'd want to be in bank $c0 (not $00 or $80). ;-)
Also, your SNES init routine should be this (if it isn't already) -- this is intended to be used via
jsl SNES_Init (not
jsr, but you can change over to
jsr/rts if you want), and not as a macro. When I say "SNES init routine" I'm referring to the memory mapped registers themselves, not part of the stuff discussed above in (4).
Code:
SNES_Init:
sep #$20
lda #$80
sta $2100
stz $2101
stz $2102
stz $2103
stz $2104
stz $2105
stz $2106
stz $2107
stz $2108
stz $2109
stz $210a
stz $210b
stz $210c
stz $210d
stz $210d
stz $210e
stz $210e
stz $210f
stz $210f
stz $2110
stz $2110
stz $2111
stz $2111
stz $2112
stz $2112
stz $2113
stz $2113
stz $2114
stz $2114
lda #$80
sta $2115
stz $2116
stz $2117
stz $211a
stz $211b
lda #$01
sta $211b
stz $211c
stz $211c
stz $211d
stz $211d
stz $211e
lda #$01
sta $211e
stz $211f
stz $211f
stz $2120
stz $2120
stz $2121
stz $2123
stz $2124
stz $2125
stz $2126
stz $2127
stz $2128
stz $2129
stz $212a
stz $212b
stz $212c
stz $212d
stz $212e
stz $212f
stz $4200
lda #$ff
sta $4201
stz $4202
stz $4203
stz $4204
stz $4205
stz $4206
stz $4207
stz $4208
stz $4209
stz $420a
stz $420b
stz $420c
stz $420d
rtl
This is covered in the official SNES developers manual, section 2-26-1. And yes, there is some redundant code in there (such as the unnecessary second
lda #$80 and the secondary
lda #$01), but that's irrelevant to your issue as well. Stay focused. :D
It would really help if you would provide the full source to everything and not just hobbled together bits. This is incredibly important when starting out.
P.S. -- Where should I send a bill for my time? ;-) Just kidding...