Day 4 - Making And Loading A Pallete
WHAT!?!
That's right, today we create and load a pallete. To create the pallete, we'll
use the program PAL.exe which I gave you in that zip file in Day 1. Run it, you will
see a window with 32 gray boxes which you can fill in by drawing colors from the colored
boxes on the bottom. Make sure when you make your pallete that you make the first color
on each row black or you'll get some funky results when we make backgrounds and sprites.
Save the pallete as our.pal, to save click the only menu and click the option with
the word save in it. Good. If you didn't do all that and got pissed that I made you run
a program that wasn't the assembler itself, click here to download
my pallete that I made for you. :) .
*New paragraph: what a pallete is, plain and simple*
*If I say something contradictory to this paragraph later in
this file, ignore it. *
A pallete is basically a bunch of colors to pick from. Our pallete is 32 colors
/bytes (1 color = 1 byte) long. 16 colors for the sprite pallete, 16 colors for the BG
pallete. Even though you can pick from 16 you can only use 4 per sprite or 4 per 16x16
piece of BG. Doing this is a little more complicated that what we've done so far, so I
won't cover it yet. OK, actually I just haven't done it yet, so how am I supposed to teach
you how to do it?
* end of new paragraph *
How We Load The Pallete?
To load the pallete, we write to 2 memory registers, $2006 twice to give it
the full address ($3F00) that we are going to load the pallete to. And then we just
keep giving $2007 byte after byte of our pallete until we've given it all of the pallete.
However, before we load the pallete, we need to learn a few other things.
Indexed Addressing
Maybe you remember in Day 1 or 2, when I said that X and Y registers can be
involved in Indexed Addressing. So this is how it works, k? :
;Assume X is 6.
lda $2002, x ; loads A with value at memory location ($2002+6) so
; memory location read is $2008.
;Assume Y is 9;
lda $2000, y ; loads A with value at memory location ($2000+9) so
; memory location read is $2009.
Note that you can load any register and use indexed addressing, not just A.
The Other Thing.
The other thing you need to know (and should have figured out already) is that
load (and maybe store) instructions can take a label as the base address.
here's some code to illustrate:
somelabel: .incbin "our.pal" ; include a pal file and label it's location.
lda somelabel, x ; load A with value from location (somelabel's address+X register's
; value).
Please remember that unless I say otherwise, examples that just load A with something
are just as applicable to loading X or Y. You should already know how label's work, if you
don't you shouldn't be reading this. Go read my Intel ASM Tutor or
other basic assembly book/article. Like I said before, you should already know some kind
of assembly language and label's are basic to ALL of them. So there.
Loading The Pallete
Instead of me blabing my keyboard off, how 'bout we let the code
explain it? :
lda #$3F ; these 4 lines tell $2006 that we
sta $2006 ; want the stuff we load $2007 with
lda #$00 ; to start at memory location $3F00
sta $2006 ; . Note that since we can only store a byte at a time we store twice
; to get the whole address in there.
ldx #$00 ; load X with 0.
loadpal: ; note that labels are followed by a ':' and aren't tabbed in.
lda ourpal, x ; load A with pallete value at location ourpal + x.
sta $2007 ; store the next pallete value into $2007 which will put it in
; the right place for us.
inx ; you've never seen this instruction before but it stands for INcrement X.
; it adds 1 to X.
cpx #32 ; ComPare X with 32 which is how many pallete values we need to load.
bne loadpal ; bne stands for Branch on Not Equal, so this will branch to loadpal
; if X wasn't equal to 32. If X is 32, then the loop will stop and were done
; loading the pallete.
Assume ourpal is a label that is defined later in the source file that looks something
like this:
ourpal: .incbin "our.pal" ; label our pallete for use in the loading code.
We will put together a complete code file when we get a sprite displayed tomorrow.
Here's that again without the comments:
lda #$3F
sta $2006
lda #$00
sta $2006
ldx #$00
loadpal:
lda ourpal, x
sta $2007
inx
cpx #32
bne loadpal
The New Instructions
You may have noticed the 3 new instructions in the loading code. They are
INX - Adds 1 to X. There is also INY which adds 1 to Y. There is NO INA
I heard that the designers of the 6502 just forgot it. There is a INA on
the next version of the 6502 (the 65c02) that is used on the SNES.
CPX - Compares a value with X. There is also CPY and CPA which compare things
with Y and A respectively. You can only use immediate values here. NO MEMORY
ADDRESSES ALLOWED.
BNE - Jumps to a label if the result of the last CPk (k is A or X or Y)
instruction was Not Equal. There is also BEQ which jumps if the result was
EQual. There are a few more that I'll explain when they come up.
This Day In Review
Loading the pallete is EXTREMELY important as a background or a sprite is
NOTHING without it's pallete. Loading a pallete is basically all you need to do to
it as once it's there, it does it's job without any help from you. Tomorrow a sprite.
All hail the NES! Good-night,
-Mike H a.k.a GbaGuy
Intro - Day 5