SNES Example 1

Finally, some real programming!

Let’s do the simplest possible thing, to make sure that ca65 is working and we can get something to assemble correctly. We are going to turn the screen red.



.include "defines.asm"
.include "macros.asm"
.include "init.asm"

.segment "CODE"

  ;enters here in forced blank
.a16 ;just a reminder of the setting from init code

  stz pal_addr ;set color address to 0
  lda #$1f     ;palette low byte gggrrrrr
  sta pal_data ;1f = all the red bits
  lda #$00     ;palette high byte -bbbbbgg
  sta pal_data ;store zero for high byte

  ;turn the screen on (end forced blank)
  lda #$0f
  sta $2100

  jmp InfiniteLoop

.include "header.asm"


Notice that every asm file is included into the main file. That is to keep our compile.bat as simple and error proof as possible. I have put the SNES_01 folder inside my cc65 folder, and so the path to the bin folder is ..\bin\


Let’s go over every line.

.p816 – puts the assembler in 65816 mode

.smart – tell the assembler to automatically adjust register size depending on REP / REP changes (handled through macros like A8, AXY16, etc)

.include – all of our constants, macros, init code, and header file.

.segment “CODE” – where will our main code end up, in the CODE segment

main: – our label, where the init code jumps to at startup

.a16 / .i16 – this is what the register size was when it left init. These are assembler directives to set A and XY assembly to 16 bit size.

phk / plb – not that important here, but sets the Data Bank Register to the same as the Program Bank (which is currently $80, a mirror of $00, and necessary for fastROM).

A8 – a macro to put the A register in 8 bit mode, I know it’s confusing since I just told the assembler to do A16 a second ago. If you like, you can delete the .a16 line since we change it right away, but I like to leave directives just to remind myself what the settings were just before we got here.

stz pal_addr ;$2121 – set the palette address register to zero

lda #$1f – load A register with the value $1f – the low byte of the color $001f = red.

sta pal_data ;$2122 – send the low byte to the palette (CGRAM)

lda #$00 – load A register with the value $00 – the upper byte of the color.

sta pal_data ;$2122 – send the high byte to the palette

lda #$0f – full brightness, no forced blank
sta fb_bright ;$2100 – effectively turns the screen ON

$2100 hardware register bits… x- – -bbbb
x = forced blank if set (turns off screen rendering)… $80
b = screen brightness, from 0 = black to $0f = full brightness

jmp InfiniteLoop – will jump repeatedly to this line

Now, we did NOT activate anything on the “main screen”, such as layers 1,2,3, or 4, or sprites (objects). With nothing on main, only the background color will show, which is the 0th palette entry.


Each color is 15 bits, BGR (the upper bit should be 0). Try changing the color and re-assembling. If you run it in MESEN-S, remember to reload from file/open and not click on the picture of the file (which only reloads the savestate, rather than reloading from file).

-bbbbbgg gggrrrrr
black = $0000
red = $001f
green = $03e0
blue = $7c00
white = $7fff

Here’s what it looks like. It’s not much, but we need to start somewhere.


And, if you look at the palette viewer, you can see our color at index 0.



Before we go, I just want to briefly mention the other files here.

Init.asm is the RESET code (and a few other bits). It zeroes all the registers and RAM and gets us to square one, before jumping long to main. Don’t feel like you need to understand every line in this file. Focus on the main code for now.

Macros.asm is a few macro definitions, like A8, AXY16, etc.

Defines.asm is a bunch of constants. I really hate the official names of each register, and I made my own list of names that I can read more easily. If you want to see the official list (and read about the hardware registers) go here…

And, lastly, the compiled ROM is the SNES_01.sfc file. This is what you should open in an emulator. I recommend the MESEN-S emulator. The usual file extension for SNES files are .sfc or .smc. SFC for Super Famicom and SMC for Super Magicom (a cartridge dumper / copier from the old days).


Now, I had written a library of code (EasySNES), but I did not use most of it here. I was discussing the matter with some friends, and I feel that SNESdev could be taught better with simpler examples, and the library will just obfuscate what is really going on.


(SNESdev SNES SFC Super Nintendo Super Famicom programming tutorial)


My apologies, since this first tutorial is essentially the same as this one…

I didn’t copy it. We just both coincidentally arrived at the same first step. Oh well. The next steps will be different.


SNES main page


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s