Ever since upgrading to Win7, I’ve been without VB.NET to mess around with. For one reason or another, the web deployment for VB.NET Express 2010 won’t begin the download on my PC. I finally did some digging around in my discs around here, and found my old 2003 edition from when I went to the community college. I went ahead and installed it. There seems to be some compatibility issue somewhere with the development environment executable, but I have yet to find anything. Anyway, I wanted to build something and see if things worked out alright.
I went ahead and remade my old console program makebin into a small windowed program. It’s not really much, and I only use it to make blank binary files for use in Tile Layer Pro (File -> New has never worked for me). But hey, it was nice to see I can still use an older VB.NET : ) Here is the windowed version of it: makebin2. If you like the program but prefer command line and also a Linux build: makebin.
Not much to this post, but I’ve got a ton I’m working on. Hopefully back to palettes next time!
Filed under: Tools by Roth
1 Comment »
Last time I talked about how to stick a palette routine in the NMI so it refreshes every frame automatically, giving us free reign to edit the virtual RAM palette for quick updates. Now I’d like to cover how to get some flashiness going in the program. This will add a bit of pizazz to things with little to no effort. For now we will work on the basics of the code, and at another time we’ll touch on portability.
Let’s first get some arbitrary numbers for our base palette laid down and decide what we would like to animate:
palette:
.byte $0f,$00,$c0,$30, $0f,$00,$10,$f0, $0f,$00,$10,$30, $0f,$00,$10,$30
.byte $0f,$00,$10,$30, $0f,$00,$10,$30, $0f,$00,$10,$30, $0f,$00,$10,$30
Let’s pick that $c0 in there. We know from last time that we can change something in the palette with a simple lda to sta. Since we want to animate, we’ll pick a few colors to use so we can do more than just a single update to the palette. Let’s refer to our diagram of colors and choose what we would like to change it to:

Let’s try something fluid, like making the color go from dark to light and light to dark. How about all the $cX values there? Alrighty, let’s put those into a table. Since we want to go from darker to lighter then back again, let’s set it up like so:
pal_animation1:
.byte $0c, $1c, $2c, $3c, $2c, $1c
So the way it will work is to read the bytes in, and when the last byte is reached, start over. So when we start over the $1c goes back to $0c, making a fluid wave of dark-light/light-dark. The problem is, we can’t just read them in and expect things to work out. If we just read them all in, they would just overwrite each other, accomplishing nothing! Yes, we are going to need a timer. Let’s use another one to help out the X register for now, too. Later on we will need more than this, but for now these are the only reserve bytes we will use.
anim_ticker: .res 1
anim_offset: .res 1
Let me go ahead and paste the code, then we’ll go over what it is doing.
; initialize
ldx #$00
stx anim_offset
lda #$0a
sta anim_ticker
jsr animate_that_smeg
; ------------------------------------
animate_that_smeg:
dec anim_ticker
bne :++
lda #$0a
sta anim_ticker
ldx anim_offset
cpx #$05
bne :+
ldx #$00
stx anim_offset
jmp @next
: inx
stx anim_offset
jmp @next
: ldx anim_offset
lda pal_animation1, x
sta pal_address+2
@next:
rts
Well, there it is! Like I said, portability later, for now, there it is. Let’s check out what it’s doing.
We have anim_ticker initialized to $0a. We decrement that number, and if it isn’t zero, jump to the portion where we load from our pal_animation1 table. This means that the same color is getting stored at pal_address+2 10 frames in a row. Once anim_ticker reaches #$00, we then push a #$0a back into it, test if anim_offset is #$05 (because we have six different colors in our table), and if not, increment that number, then jump to the end of the routine. However, if it IS at #$05, we store #$00 back into it and jump to the end of the routine and start the whole thing over. Not too shabby!
If you need to reread that last paragraph because you don’t understand the code, then do so! It’s not really all that complicated, and is something that will make your games/programs/demos look all uh… shiny! Anywhat, the next palette stuff we will deal with will be color manipulation. It will utilize this same code above as well, so, be ready!
Filed under: 6502 Code by Roth
No Comments »
The palette! This is one of my favorite parts of the NES, as it can be used to make your game look like more is going on than there really is.
Since I’ve gotten into NES development, I’ve found that one of the better ways to use NMI is for PPU updates, while saving game logic for the main loop. Considering that the palette is written to via $2006 (writes to the PPU), sticking it in the NMI makes sense. Not only because of that, but this allows you to update the palette in your main loop via RAM, which will update on the next firing of NMI. No switching the screen off and back on during the main loop, which is bad practice from my experiences!
Note: The syntax I use is for ca65. You may need to modify it according to what assembler you use.
The first thing that we have to do is figure out where we want to stick our virtual palette register in RAM. I like using the last 32 bytes in a page, so let’s go with $4e0:
pal_address = $4e0
Let’s stick some initial palette somewhere in our file. You can make a file and use include binary…
palette:
.incbin "our_palette.pal"
… or you can code it like this (except with the proper colors that you need):
palette:
.byte $0f,$00,$10,$30, $0f,$00,$10,$30, $0f,$00,$10,$30, $0f,$00,$10,$30
.byte $0f,$00,$10,$30, $0f,$00,$10,$30, $0f,$00,$10,$30, $0f,$00,$10,$30
Just for the halibut, here is a chart showing the colors available on an NES. I’m sure most devvers know this, but be sure to use the left number first, then the top number. So if we wanted to use the white in the bottom left corner, it would be $30, and NOT $03:

After establishing which colors you want to start out with, the next thing to do before the main loop of the game begins (and sometime after clearing RAM before switching NMIs back on), is fill pal_address with the initial data. The following code just copies everything from our label palette in ROM to the label pal_address in RAM. The X register is set to zero, and we load the first byte from palette (ROM) and save it as the first byte in pal_address (RAM). After that, we increase the X register by one, test to see if we have done this loop 32 times, and if not, go back to load the next byte from ROM to stick in the next byte of RAM:
ldx #$00
: lda palette,x
sta pal_address,x
inx
cpx #$20
bne :-
Next, taking that address and putting it to use, we stick this in our NMI*:
lda #$3f
sta $2006
ldx #$00
stx $2006
: lda pal_address,x
sta $2007
inx
cpx #$20
bne :-
What that does is set the PPU to $3f00, where the NES’ palette is stored. Notice that before we stored the low end of the address ($00) that we also set X to $00. Now we can use that as the offset like we did before, but this time we are storing the first byte of RAM (pal_address) into the first address where the NES’ palette is stored ($3f00) via the PPU address $2007. Once again, increase the X register by 1, then check to see if the loop has gone 32 times. If not, repeat the loop. Now, this gives us access to our palette in the main loop by simply writing to our virtual palette register in RAM (pal_address). Changing parts of the palette during our main loop is as easy as:
lda #$2c
sta pal_address+11
When the next NMI fires, this is what the palette from above would look like in the PPU:
0f 00 10 30 0f 00 10 30 0f 00 10 2c 0f 00 10 30
0f 00 10 30 0f 00 10 30 0f 00 10 30 0f 00 10 30
Notice where the 2c is? If you count over, it is 11 bytes from the starting point of the palette, and this is why we made it pal_address+11… to change that specific color!
You might not notice it right now, but this gives you a lot of power over the palette. Next time, we’ll go over animating the palette to add some life to the backgrounds and/or sprites in your games! Stay tuned!
*Side note: If you have bit 2 of $2000 set, this means you are incrementing the PPU by 32 for every write to it (for instance, laying down tiles vertically). If this is the case, keep in mind that ANY writes to the PPU will increase by 32, this includes the palette. This can be worked around by sticking these code snippets before and after the palette refresh in NMI (h/t to Quietust):
lda reg2000_save ; before palette refresh code in NMI
and #%11111011 ;
sta reg2000_save ;
sta $2000 ;
; ...
lda reg2000_save ; after palette refresh code in NMI
ora #%00000100 ;
sta reg2000_save ;
sta $2000 ;
Filed under: 6502 Code by Roth
No Comments »
|
|