Skip navigation
NintendoAge
Welcome, Guest! Please Login or Join
Loading...

Nerdy Nights week 6 Backgrounds

May 17, 2008 at 4:08:29 PM
bunnyboy (81)
avatar
(Funktastic B) < Master Higgins >
Posts: 7704 - Joined: 02/28/2007
California
Profile
Previous Week - Multiple sprites, reading controllers

This Week:  Now that you have a basic understanding of the NES tile graphics, we learn how to display one static non scrolling background.  

Backgrounds
There are three components used to generate backgrounds on the NES.  First is the background color palette, used to select the colors that will be used on screen.  Next is the nametable that tells the layout of the graphics.  Finally is the attribute table that assigns the colors in the palette to areas on screen.

Background Palette
Like the sprites there are 16 colors in the background palette.  Our previous apps were already loading a background palette but it was not being used yet.  You can use the PPU Viewer in FCEUXD SP to see the color palettes.  

Nametables
Like the sprites, background images are made up from 8x8 pixel tiles.  The screen video resolution is 32x30 tiles, or 256x240 pixels.  PAL systems will show this full resolution but NTSC crops the top 8 and bottom 8 rows of pixels for a final resolution of 256x224.  Additionally TV's on either system can crop another few rows on the top or bottom.

One screen full of background tiles is called a nametable, and the NES has enough internal RAM connected to the PPU for two nametables.  Only one will be used here.  The nametable has one byte (0-255) for which 8x8 pixel graphics tile to draw on screen.  The nametable we will use starts at PPU address $2000 and takes up 960 bytes (32x30).  You can use the Nametable viewer in FCEUXD SP to see all the nametables.  

Attribute Tables
The attribute tables may be the most difficult thing to understand, and sets many of the graphics limitations.  Each nametable has an attribute table that sets which colors in the palette will be used in sections of the screen.  The attribute table is stored in the same internal RAM as the nametable, and we will use the one that starts at PPU address $23C0 ($2000+960).  

First the screen is divided into a 32x32 pixel grid, or 4x4 tiles.  Each byte in the attribute table sets the color group (0-3) in the background palette that will be used in that area.  That 4x4 tile area is divided again into 4 2x2 tile grids.  Two bits of the attribute table byte are assigned to each 2x2 area.  That is the size of one block in SMB.  This limitation means that only 4 colors (one color group) can be used in any 16x16 pixel background section.  A green SMB pipe section cannot use the color red because it already uses 4 colors.

When looking at a sample SMB screen, first the 4x4 tile grid is added and the palette is shown at the bottom:

You can see there are 8 grid squares horizontally, so there will be 8 attribute bytes horizontally.  Then each one of those grid squares is split up into 2x2 tile sections to generate the attribute byte:


No 16x16 area can use more than 4 colors, so the question mark and the block cannot use the greens from the palette.


Uploading the data
To set the background graphics your data has to be defined in your ROM using the .db directive, then copied to the PPU RAM.  Some graphics tools will generate this data but here it will just be done manually.  To keep it shorter only a few rows of graphics will be created.  The same CHR file from SMB will be used here too.  First the nametable data is defined, with each graphics row split into two 16 byte sections to keep lines shorter:

nametable:

  .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24  ;;row 1

  .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24  ;;all sky ($24 = sky)


  .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24  ;;row 2

  .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24  ;;all sky


  .db $24,$24,$24,$24,$45,$45,$24,$24,$45,$45,$45,$45,$45,$45,$24,$24  ;;row 3

  .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$53,$54,$24,$24  ;;some brick tops


  .db $24,$24,$24,$24,$47,$47,$24,$24,$47,$47,$47,$47,$47,$47,$24,$24  ;;row 4

  .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$55,$56,$24,$24  ;;brick bottoms


Then the attribute table data is defined.  Each byte covers 4x4 tiles, so only 8 bytes are needed here.  Binary is used so editing the 2 bits per 2x2 tile area is easier:

attribute:

  .db %00000000, %00010000, %0010000, %00010000, %00000000, %00000000, %00000000, %00110000


And finally the same color palette as SMB is used:

palette:

  .db $22,$29,$1A,$0F,  $22,$36,$17,$0F,  $22,$30,$21,$0F,  $22,$27,$17,$0F


Just like our previous palette loading, a loop is used to copy a specific number of bytes from a memory location to the PPU.  First the PPU address is set to the beginning of the nametable at $2000.  Then our 128 bytes of background data are copied.  Next the PPU address is set to the beginning of the attribute table at $23C0 and 8 bytes are copied.

LoadBackground:

  LDA $2002             ; read PPU status to reset the high/low latch

  LDA #$20

  STA $2006             ; write the high byte of $2000 address

  LDA #$00

  STA $2006             ; write the low byte of $2000 address

  LDX #$00              ; start out at 0

LoadBackgroundLoop:

  LDA background, x     ; load data from address (background + the value in x)

  STA $2007             ; write to PPU

  INX                   ; X = X + 1

  CPX #$80              ; Compare X to hex $80, decimal 128 - copying 128 bytes

  BNE LoadBackgroundLoop  ; Branch to LoadBackgroundLoop if compare was Not Equal to zero

                        ; if compare was equal to 128, keep going down

              

LoadAttribute:

  LDA $2002             ; read PPU status to reset the high/low latch

  LDA #$23

  STA $2006             ; write the high byte of $23C0 address

  LDA #$C0

  STA $2006             ; write the low byte of $23C0 address

  LDX #$00              ; start out at 0

LoadAttributeLoop:

  LDA attribute, x      ; load data from address (attribute + the value in x)

  STA $2007             ; write to PPU

  INX                   ; X = X + 1

  CPX #$08              ; Compare X to hex $08, decimal 8 - copying 8 bytes

  BNE LoadAttributeLoop


The final changes are to tell the PPU to use the Pattern Table 0 graphics for sprites, and Pattern Table 1 for background:

  LDA #%10010000 ;enable NMI, sprites from Pattern 0, background from Pattern 1

  STA $2000


Enable the background rendering:

  LDA #%00011110 ; enable sprites, enable background

  STA $2001


And to tell the PPU that we are not doing any scrolling at the end of NMI:

  LDA #$00

  STA $2005

  STA $2005


Putting It All Together
Download and unzip the background2.zip sample files.  All the code above is in the background.asm file.  Make sure that file, mario.chr, and background.bat is in the same folder as NESASM, then double click on background.bat.  That will run NESASM and should produce background.nes.  Run that NES file in FCEUXD SP to see the background.  Set it to PAL Emulation so you get to see the whole screen.

Any background areas that you did not write to will still be using tile 0, which happens to be the number 0 in the SMB graphics.  Try adding more nametable and attribute data to the .db sections, then changing the loops so they copy more bytes to the PPU RAM.  You can also try changing the starting PPU address of the nametable and attribute table writes to move the rows further down.


NEXT WEEK:  Subroutines, game structure, states


Edited: 05/17/2008 at 04:13 PM by bunnyboy

May 17, 2008 at 6:48:09 PM
Jero (1)
avatar
(Jeroen ) < El Ripper >
Posts: 1106 - Joined: 03/02/2008
Netherlands
Profile
This makes me wanna work on pong again! I sent it to myself in an email, but hotmail wont open it cause "it might contain virusses" damn hotmail. I know theres no virus in my files

Jun 2, 2008 at 8:20:42 AM
Rachel (10)
avatar
(Player of Games, Killer of Threads) < Eggplant Wizard >
Posts: 335 - Joined: 05/24/2008
Texas
Profile
Excellent! That explanation actually made attribute tables seem... super easy! Thanks++. I'm looking forward to your lesson on game structure. That's the very thing that I'm struggling with right now.

-------------------------
Resident collector of and expert on vintage girly games and consoles--especially rare stuff! 

Currently playing: Miitomo (iOS), Yoshi's Woolly World (WiiU)

Jun 3, 2008 at 8:08:05 AM
-JoSeph- (2)
avatar
(Joseph Wak) < Crack Trooper >
Posts: 143 - Joined: 04/12/2008
Australia
Profile
Keep them coming. =]

Jul 4, 2008 at 1:54:59 PM
Kizul Emeraldfire (0)
avatar
(Kizul Emeraldfire) < Tourian Tourist >
Posts: 42 - Joined: 06/30/2008
United States
Profile
Geh, I'm stuck again. >.> I can't seem to figure out how to make more background. I just get blue sky on the two ready-made rows, and there're still a ton of zeroes all over the place. >.<'

Help? ^^;

-------------------------
 

Jul 4, 2008 at 2:05:20 PM
albailey (55)
avatar
(Al Bailey) < Lolo Lord >
Posts: 1523 - Joined: 04/10/2007
Ontario
Profile
Originally posted by: Kizul Emeraldfire

Geh, I'm stuck again. >.> I can't seem to figure out how to make more background. I just get blue sky on the two ready-made rows, and there're still a ton of zeroes all over the place. >.<'

Help? ^^;




Did you update this part:
CPX #$80              ; Compare X to hex $80, decimal 128 - copying 128 bytes

If you are adding more bytes to the background to be copied, you need to increment that to be bigger than 128

Al


-------------------------

My Gameboy collection  97% complete.          My N64 collection   88% complete



 My Gamecube collection  99% complete        My NES collection   97% complete


Jul 6, 2008 at 1:56:17 AM
Kizul Emeraldfire (0)
avatar
(Kizul Emeraldfire) < Tourian Tourist >
Posts: 42 - Joined: 06/30/2008
United States
Profile
Ahhh, yeah, that was it -- forgot to update that. ^^;

Now it works; I doubled its value to $FF. Now there's two rows of sky above the blocks, and one below them. The weird thing is, now the blocks are green. o.O I also changed the CPX value in LoadAttribute (doubled it from $08 to $10), but that didn't seem to do anything. >.> (also quadrupled the LoadAttribute CPX value -- now the zeroes below the bottom sky-row have mixed-up colors! ) I happened to double (actually, duplicate) the 'attribute' data, so I dunno what's going wrong with the colors. o.o'

Also, (I'm guessing due to the fact that $FF is only 255, not 256,) for some reason the bottom-right corner in the last block on the bottom row of sky has a 0 in it, instead of being blank blue. o.O

-------------------------
Hark, the newbie hath spoken!

-------------------------
 

Jul 6, 2008 at 2:05:03 AM
Zzap (47)
avatar
(James ) < King Solomon >
Posts: 3301 - Joined: 05/01/2007
Australia
Profile
Did you increase the attribute's in this section so you had more? There were only enough attribute entries for the number of background tiles copied before, so you'll need to add more into this section to make it correct

attribute:
.db %00000000, %00010000, %0010000, %00010000, %00000000, %00000000, %00000000, %00110000

Compare to #$00 instead of #$FF, this will do a complete 256 tiles. To do more tiles than this, you'll need to use both the X and Y registers in the loop.

-------------------------

Chunkout for iPhone, iPad and iTouch out now!
Chunkout Games: FaceBook | Web

Jul 7, 2008 at 4:57:33 PM
Kizul Emeraldfire (0)
avatar
(Kizul Emeraldfire) < Tourian Tourist >
Posts: 42 - Joined: 06/30/2008
United States
Profile
Okay, this is currently what I'm having a problem with right now. As far as I can tell, it SHOULD be fine! \o.o/ At least, I think it should. >.>

LoadBackground:
LDA $2002 ; read PPU status to reset the high/low latch
LDA #$20
STA $2006 ; write the high byte of $2000 address
LDA #$00
STA $2006 ; write the low byte of $2000 address
LDX #$00 ; start out at 0
LoadBackgroundLoop:
LDA background, x ; load data from address (background + the value in x)
STA $2007 ; write to PPU
INX ; X = X + 1
CPX #$00 ; Compare X to hex $80, decimal 128 - copying 128 bytes
BNE LoadBackgroundLoop ; Branch to LoadBackgroundLoop if compare was Not Equal to zero
; if compare was equal to 128, keep going down


LoadAttribute:
LDA $2002 ; read PPU status to reset the high/low latch
LDA #$23
STA $2006 ; write the high byte of $23C0 address
LDA #$C0
STA $2006 ; write the low byte of $23C0 address
LDX #$00 ; start out at 0
LoadAttributeLoop:
LDA attribute, x ; load data from address (attribute + the value in x)
STA $2007 ; write to PPU
INX ; X = X + 1
CPX #$10 ; Compare X to hex $08, decimal 8 - copying 8 bytes
BNE LoadAttributeLoop ; Branch to LoadAttributeLoop if compare was Not Equal to zero
; if compare was equal to 128, keep going down

background:
.db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;;row 1
.db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;;all sky

.db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;;row 2
.db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;;all sky

.db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;;row 1
.db $24,$24,$24,$24,$24,$24,$24,$24,$36,$37,$24,$24,$24,$24,$24,$24 ;;all sky

.db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;;row 2
.db $24,$24,$24,$24,$24,$24,$24,$35,$25,$25,$38,$24,$24,$24,$24,$24 ;;all sky

.db $24,$24,$24,$24,$45,$45,$24,$24,$45,$45,$45,$45,$45,$45,$24,$24 ;;row 3
.db $24,$24,$24,$24,$24,$24,$24,$39,$3A,$3B,$3C,$24,$53,$54,$24,$24 ;;some brick tops

.db $24,$24,$24,$24,$47,$47,$24,$24,$47,$47,$47,$47,$47,$47,$24,$24 ;;row 4
.db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$55,$56,$24,$24 ;;brick bottoms

.db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;;row 1
.db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;;all sky

.db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;;row 2
.db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;;all sky

attribute:
.db %00000000, %00000000, %00000000, %00000000, %00000000, %00000010, %00001010, %00000000
.db %00000000, %01000000, %01010000, %01000000, %00000000, %00000000, %00000000, %11000000

What am I doing wrong? \o.o/ Oh, and a screenshot of how it looks when I kick it up in NESTopia (Mario's colors may differ from ROM-to-ROM):

P.S.: sorry for the ridiculously-long post -- I dunno how to create 'Spoiler' sections with this software. <.<

-------------------------
 


Edited: 07/07/2008 at 04:58 PM by Kizul Emeraldfire

Jul 7, 2008 at 7:28:38 PM
Zzap (47)
avatar
(James ) < King Solomon >
Posts: 3301 - Joined: 05/01/2007
Australia
Profile
Ummm, what *should* it be looking like? One big thing there is you don't appear to be loading any palettes, did you just not paste the code or is that missing?

-------------------------

Chunkout for iPhone, iPad and iTouch out now!
Chunkout Games: FaceBook | Web

Jul 7, 2008 at 7:54:11 PM
Kizul Emeraldfire (0)
avatar
(Kizul Emeraldfire) < Tourian Tourist >
Posts: 42 - Joined: 06/30/2008
United States
Profile
Sorry, I just didn't paste that in. >.> LoadPalettes and LoadPalettesLoop are currently unmodified from the example ASM file.

-------------------------
 

Jul 8, 2008 at 5:12:59 AM
Zzap (47)
avatar
(James ) < King Solomon >
Posts: 3301 - Joined: 05/01/2007
Australia
Profile
Not 100% sure what you're after, but to use the palettes appropriately you'll need to shuffle around your attribute values a bit:

attribute:
.db %00000000, %00000000, %00000000, %00000000, %00000000, %10000000, %10100000, %00000000
.db %00000000, %0000001, %00000101, %00000001, %00000000, %00001000, %00001010, %00000011

-------------------------

Chunkout for iPhone, iPad and iTouch out now!
Chunkout Games: FaceBook | Web

Jul 8, 2008 at 5:20:22 AM
Kizul Emeraldfire (0)
avatar
(Kizul Emeraldfire) < Tourian Tourist >
Posts: 42 - Joined: 06/30/2008
United States
Profile
Huh. Bizzare. It's like I had the attribute bytes backwards. o.O

Looking at the example pic, I thought SURE that they were right-to-left, bottom-to-top -- ah well. Thanks, Zzap -- that worked perfectly.

Now to figure out how to fill the whole screen with graphics... ^^

-------------------------
 

Jul 8, 2008 at 12:26:53 PM
albailey (55)
avatar
(Al Bailey) < Lolo Lord >
Posts: 1523 - Joined: 04/10/2007
Ontario
Profile
The thing about loading the entire nametable (1024 bytes = 32x30 for the tiles, plus 64 for the entire OAM attributes) is that the X counter you are using can only go up to 256. So how do you load in the 257th byte?
The answer is to use a slightly more complicated syntax for the addressing mode. I suspect bunnyboy has covered this (or is planning to) in one of his tutorials.

If he hasnt, or you dont want to wait, you need to clone the LoadBackground method and give it different starting points, and make additional data tables (backgroundX and load each of those in 256 (or less) sized chunks.

You should be able to leave the attribute stuff alone since its 64 bytes max.


Al

Al

-------------------------

My Gameboy collection  97% complete.          My N64 collection   88% complete



 My Gamecube collection  99% complete        My NES collection   97% complete


Jul 8, 2008 at 4:06:43 PM
Kizul Emeraldfire (0)
avatar
(Kizul Emeraldfire) < Tourian Tourist >
Posts: 42 - Joined: 06/30/2008
United States
Profile
Sweet! Thanks, Al!

-------------------------
 

Jul 18, 2008 at 5:25:04 AM
Kizul Emeraldfire (0)
avatar
(Kizul Emeraldfire) < Tourian Tourist >
Posts: 42 - Joined: 06/30/2008
United States
Profile
Hmmmmmmm... I still can't figure out how to create more than half a screen's-worth of background. >.<

Here is my entire background.asm file: http://nintendoage.pastebin.com/m...

I'd include a screenshot, but it's basically the same as the one I posted before, just with proper colors, and with four 16×16-pixel rows of plain blue sky above what's already in my former screenshot. >.>

So -- anyway. What do I do to load a FULL background, instead of just half of it? \o_O/ Anyone? >.>?

-------------------------
 

Jul 19, 2008 at 3:55:35 AM
Zzap (47)
avatar
(James ) < King Solomon >
Posts: 3301 - Joined: 05/01/2007
Australia
Profile
Here's a version that loads a full background, using simple addressing, and note that I haven't really bothered setting the attributes up so that it looks pretty or anything (it just repeats the rows you had previously) I also reset the scroll values after writing to the PPU so that it wasn't having issues there.

http://nintendoage.pastebin.com/f...

Also, here's a simpler version where I use both the X and Y registers to load the full nametable and attribute table in 1 loop:

http://nintendoage.pastebin.com/f...

-------------------------

Chunkout for iPhone, iPad and iTouch out now!
Chunkout Games: FaceBook | Web

Jul 19, 2008 at 4:13:37 AM
Kizul Emeraldfire (0)
avatar
(Kizul Emeraldfire) < Tourian Tourist >
Posts: 42 - Joined: 06/30/2008
United States
Profile
Sweet! Thanks, Zzap -- they work great!

As for the first one you linked to, for some reason I could SWEAR I did something like that already. o.O I guess maybe it was 'cause I was using both the X and the Y registers when I should've just been using X or something. Ah well -- thanks again!

-------------------------
 

Aug 22, 2009 at 8:40:10 AM
KennyB (14)
avatar
(No Go ogle result) < Eggplant Wizard >
Posts: 466 - Joined: 09/06/2006
Belgium
Profile
I'm having some problems with my background.


I made my background with the 2's from the background pallette. As you can see I have black and green two's. The green 2's are the one's that I want. 
I checked my attributes and they are all set to %00000000 which should result in the green 2's.
For some reason, the black 2's uses a different pallete. 

Here is my code:


I first used %00000000 for all my attributes. Then I changed them all to %11111111 to see if anything happens (it should change to all black 2's), but the result is the same. 

My guess is that my attributes aren't getting loaded or somehting. 
Anyone knows what I'm doing wrong ? 

-------------------------
 


Edited: 08/22/2009 at 08:42 AM by KennyB

Aug 22, 2009 at 8:49:26 AM
bunnyboy (81)
avatar
(Funktastic B) < Master Higgins >
Posts: 7704 - Joined: 02/28/2007
California
Profile
You are loading too much background, which is extending into the attribute memory area. You have 4 loops of 256 bytes which is 1024 bytes, but there's only 960 bytes of background tiles. Need to change one of the loops to copy fewer bytes.

Aug 22, 2009 at 9:14:38 AM
KennyB (14)
avatar
(No Go ogle result) < Eggplant Wizard >
Posts: 466 - Joined: 09/06/2006
Belgium
Profile
Originally posted by: bunnyboy

You are loading too much background, which is extending into the attribute memory area. You have 4 loops of 256 bytes which is 1024 bytes, but there's only 960 bytes of background tiles. Need to change one of the loops to copy fewer bytes.


Also got this working right....so again: Thx alot 

-------------------------
 

Oct 27, 2009 at 5:41:49 PM
resynthesize (0)

(brandon t) < Cherub >
Posts: 7 - Joined: 10/19/2009
United States
Profile
Originally posted by: Zzap

Here's a version that loads a full background, using simple addressing, and note that I haven't really bothered setting the attributes up so that it looks pretty or anything (it just repeats the rows you had previously) I also reset the scroll values after writing to the PPU so that it wasn't having issues there.

http://nintendoage.pastebin.com/f21f5696c

Also, here's a simpler version where I use both the X and Y registers to load the full nametable and attribute table in 1 loop:

http://nintendoage.pastebin.com/f12cef2c1


Hi Zzap,

Would you mind explaining the following block of code?

===============================
  LDA #low(background)
  STA AddrLow
  LDA #high(background)
  STA AddrHigh

  LDX #$04              ; Loop X 4 times
  LDY #$00              ; Loop Y 256 times
LoadBackgroundsLoop:
  LDA [AddrLow],y
  STA $2007
  INY
  BNE LoadBackgroundsLoop
; Outer loop
  INC AddrHigh           ; increment high byte of address backg to next 256 byte chunk
  DEX                    ; one chunk done so X = X - 1.
  BNE LoadBackgroundsLoop   ; if X isn't zero, do again
===============================

I've worked out the general idea of it but I'm confused on the details.  I don't understand the purpose of incrementing AddrHigh since that isn't referenced anywhere else. 

Thanks!
Brandon


-------------------------
 

Oct 27, 2009 at 7:49:07 PM
Mario's Right Nut (352)
avatar
(Cunt Punch) < Bowser >
Posts: 6636 - Joined: 11/21/2008
Texas
Profile
You have to incriment AddrHigh cause:
$2000 + $00 = $2100
So on the second outer loop you want to start writing from $2100 not $2000. If you didn't do this, you would just overwrite the top 1/4 of the screen 4 times.

-------------------------

This is my shiny thing, and if you try to take it off me, I may have to eat you.

Check out my dev blog.


Oct 27, 2009 at 8:10:48 PM
resynthesize (0)

(brandon t) < Cherub >
Posts: 7 - Joined: 10/19/2009
United States
Profile
Originally posted by: Mario's Right Nut

You have to incriment AddrHigh cause:
$2000 + $00 = $2100
So on the second outer loop you want to start writing from $2100 not $2000. If you didn't do this, you would just overwrite the top 1/4 of the screen 4 times.


I understand that AddrHigh is incremented to start processing the next chunk.  What I am confused about is how incrementing it is automatically updating the loop to look at the correct address. 

Here is my understanding of the loop:

* AddrHigh and AddrLow are both set to the high and low bytes of the background address
* X and Y registered are set with 4 and 0 respectively
* Loop starts
* The first byte of the background is loaded into the accumulator and stored in $2007.  This is where I am confused.  If the background tiles started at $3F00 for example, AddrHigh should contain $3F and AddrLow $00, right?  The LDA is reading from AddrLow ($00) + Y, which is 0 the first time around the loop.  Wouldn't that load whatever was in $00 the first time around?  I think there is some magic with the brackets where LDA [AddrLow], y is automatically calculating the correct offset from AddrHigh and AddrLow, but I don't see how that is done, and that is what I'm confused about

 


-------------------------
 

Oct 27, 2009 at 8:53:52 PM
udisi (88)
avatar
< King Solomon >
Posts: 3270 - Joined: 11/15/2006
United States
Profile
I think I see what you're saying
AddrHigh and AddrLow are just variables

AddrHigh .rs and AddrLow .rs.....They're not defined anywhere, so they are set to default $00

I think the magic you're looking for has to do with the code snippet right before the loop

LDA $2002
LDA #$20
STA $2006 ; write the high byte of $2000 address
LDA #$00
STA $2006 ; write the low byte of $2000 address

I don't understand it completely myself, but I'm pretty sure this is setting the the the address for the variables.