Day 19 - Easy Large Loads
Today, we will use a new loading loop that utilizes indirect addressing
to load a lot of data at a time. The data we will load will be the Zelda title
screen, and yes, today will include all of the code. I've included the 3 necessary
data files in nesasm.zip. Please redownload it, I could
have sworn that I already had them in there... sorry for any inconveniece.
Patater GBAGuy Mirror
Yep, indirect addressing (which is hard for me to type for some reason...)
is simply getting an address from the contents of another address, so say we wanted
to get a value from an address contained at $0010-$0011 (16-bit address, remember
But first a little review (I hope), vocab lesson #whatever:
Take the address $8000, $00 is the high byte and $80 is the low byte, got it?
(I might have that backwards, I have bronchitis at the moment...)
The low byte would be in $10 and the high byte in $11 (note that I use two
digits only, because the first 2 in the address are zero). So assuming the address
that we really want to load from is $82C5 which is at $10-$11, to load the byte
at $82C5 into the A register, we would do:
this can also be indexed, like so:
lda [$10], y
what this would do is take the address $82C5, add the contents of Y to that address
(the address not the contents), and get byte at the resulting address.
I hope you understood all that, because it's just going to get more confusing.
And just a short joke before we continue:
Surgeon General's Warning:
Attempting to understand the ASM Code in the
following sections of this document may cause
the reader to either increase their ASM skills
or drive them to suicidal frustration.
I think, therefore I am? no. I think therefore I'll give the complete
loop and explain it in pieces. Assume backg is the label of where a bunch of
name table data is included, also assume $2006 is pointing to $2000:
The first piece:
low() and high() are builtin instructions for NESASM.exe that take the high and low
bytes of an address, in this case, backg.
Note that $10 and $11 memory addresses are consecutive, it has to be that way, but
they could be any consecutive addresses.
X controls how many chunks of 256 bytes to load in this case, 4. Y must be 0 (zero).
This part loads 256 bytes to $2007 using indirect addressing indexed by Y.
Note that the registers (A,X,Y) wrap around so adding 1 to #$FF will make
the register contain #$00. And that's how this works, because when Y is incremented
to #$00, the loop will be done loading the 256 byte chunk.
This part increments the high byte of the address of the data to the next 256 byte
chunk. It also counts down 1 in the X register which contains the amount of chunks
left, if X is zero, it won't loop and we're done loading everything.
That went better than I expected...
The Full Code File
Before I give you the full code file (fully commented, of course), make sure
you have those 3 files in your code folder.
;--- CODE START ---;
.inesmap 0 ; INES header $H!7.
.org $FFFA ; vector table
addrLO: .db 0 ; make "variable"s for our indirect addressing
addrHI: .db 0
lda #$20 ; set the destination address in PPU memory
sta $2006 ; should be $2000
lda #low(backg) ; put the high and low bytes of the address "backg"
sta addrLO ; into the variables so we can use indirect addressing.
ldx #4 ; number of 256-byte chunks to load
sta $2007 ; load 256 bytes
inc addrHI ; increment high byte of address backg to next 256 byte chunk
dex ; one chunk done so X = X - 1.
bne loop ; if X isn't zero, do again
lda #$00 ; point $2006 to the pallete
lda tilepal, X ; use a simple load of 32 bytes.
jsr turn_screen_on ; call subroutine to turn on / setup the PPU.
infin: ; our infinite loop
; Setup the PPU
tilepal: .incbin "zelda.pal" ; include the pallete
backg: .incbin "zelda.nam" ; include the name table data
.incbin "zelda.chr" ; include the picture data in the background part
;of the CHR-BANK (#2)
;;--- CODE END/ END OF FILE ---;;
I hope you got all that and that it works (I did some modifications from my
This Day In Review
I thought that was fun. Day 20 could be anything, maybe Attributes,
maybe a lesson on the conditional branches.
Intro - Day 20