Uncompressing background, updating individual BG tiles.

Are you new to 6502, NES, or even programming in general? Post any of your questions here. Remember - the only dumb question is the question that remains unasked.

Moderator: Moderators

Post Reply
User avatar
Eisetley
Posts: 8
Joined: Fri Feb 02, 2018 4:45 am

Uncompressing background, updating individual BG tiles.

Post by Eisetley »

I'm working on a simple, non-scrolling, NROM game that will have just a few screens and I'm trying to figure out a decent way to load a background. I RLE'd the title screen using just notepad and now I'm trying to load it, but the whole screen is blue.
Screen data (left value is tile number, right is the amount):

Code: Select all

titlescrn:
	.db $24,$8c
        .db $c3,$01
        .db $c4,$01
        .db $c5,$01
        .db $c6,$01
        .db $c7,$01
        .db $c8,$01
        .db $c9,$01
        .db $ca,$01
        .db $cb,$01
        .db $24,$17
        .db $d3,$01
        .db $d4,$01
        .db $d5,$01
        .db $d6,$01
        .db $d7,$01
        .db $d8,$01
        .db $d9,$01
        .db $da,$01
        .db $db,$01
        .db $24,$14
        .db $e0,$01
        .db $e1,$01
        .db $e2,$01
        .db $e3,$01
        .db $e4,$01
        .db $e5,$01
        .db $e6,$01
        .db $e7,$01
        .db $e8,$01
        .db $e9,$01
        .db $ea,$01
        .db $eb,$01
        .db $ec,$01
        .db $ed,$01
        .db $ee,$01
        .db $ef,$01
        .db $24,$10
        .db $f0,$01
        .db $f1,$01
        .db $f2,$01
        .db $f3,$01
        .db $f4,$01
        .db $f5,$01
        .db $f6,$01
        .db $f7,$01
        .db $f8,$01
        .db $f9,$01
        .db $fa,$01
        .db $fb,$01
        .db $fc,$01
        .db $fd,$01
        .db $fe,$01
        .db $ff,$01
        .db $24,$d2
        .db $01,$01
        .db $19,$01
        .db $15,$01
        .db $0a,$01
        .db $22,$01
        .db $0e,$01
        .db $1b,$01
        .db $24,$19
        .db $02,$01
        .db $19,$01
        .db $15,$01
        .db $0a,$01
        .db $22,$01
        .db $0e,$01
        .db $1b,$01
        .db $1c,$01
        .db $24,$FF
        .db $24,$4E
        .db $0a,$01
        .db $15,$01
        .db $19,$01
        .db $11,$01
        .db $0a,$01
        .db $24,$01
        .db $18,$01
        .db $18,$01
        .db $24,$47
        ;;;attr
        .db $00,$0A
        .db $50,$01
        .db $55,$01
        .db $55,$01
        .db $51,$01
        .db $10,$01
        .db $00,$0B
        .db $40,$01
        .db $50,$02
        .db $00,$23
        .db $25 ;$25 = end of room

Code: Select all

backgrounds_lo: .dl titlescrn
backgrounds_hi: .dh titlescrn
Loading code:

Code: Select all

LoadBackground:
;Turn off NMI and rendering
   LDA #%00000000
   STA PPU_CtrlA
   STA PPU_CtrlB
   LDA PPU_CtrlB ;reading $2002 clears write pair for $2005/2006


   LDA #$20
   STA PPU_Addr
   LDA #$00
   STA PPU_Addr

   LDX BackgroundToLoad
   LDA backgrounds_lo, x
   STA BackgroundAddress
   LDA backgrounds_hi, x
   STA BackgroundAddress + 1
   LDY #$00
LoadBackgroundLoopA:
   LDA (BackgroundAddress), y
   CMP #$25
   BEQ LoadBackgroundLoopEnd
   INY
   LDX (BackgroundAddress), y
LoadBackgroundLoopB:
   STA PPU_Write
   DEX
   BNE LoadBackgroundLoopB
   INY
   JMP LoadBackgroundLoopA

LoadBackgroundLoopEnd:

 ;Reset Scroll
   LDA #$00
   STA PPU_Scroll
   STA PPU_Scroll
   INC BackgroundLoadingStatus
RTS
Another thing is updating a certain part of the background. Should I just decompress all the background data into ram first instead of running the code above, and then load a whole background every time a change is made?
User avatar
dougeff
Posts: 3079
Joined: Fri May 08, 2015 7:17 pm

Re: Uncompressing background, updating individual BG tiles.

Post by dougeff »

LDX (BackgroundAddress), y

This isn't a valid indirect mode (only LDA can do indirect modes). This should give an error when trying to assemble...

What assembler are you using?
nesdoug.com -- blog/tutorial on programming for the NES
User avatar
Eisetley
Posts: 8
Joined: Fri Feb 02, 2018 4:45 am

Re: Uncompressing background, updating individual BG tiles.

Post by Eisetley »

ASM6
Should I use LDA (BackgroundAddress), y->TAX?
User avatar
dougeff
Posts: 3079
Joined: Fri May 08, 2015 7:17 pm

Re: Uncompressing background, updating individual BG tiles.

Post by dougeff »

Probably yes.

If that doesn't work, open the file in an emulator with a debugger. Make sure the correct values are loading to the PPU.
nesdoug.com -- blog/tutorial on programming for the NES
User avatar
Sumez
Posts: 919
Joined: Thu Sep 15, 2016 6:29 am
Location: Denmark (PAL)

Re: Uncompressing background, updating individual BG tiles.

Post by Sumez »

Eisetley wrote:ASM6
Should I use LDA (BackgroundAddress), y->TAX?
Just remember to move it up before your "actual" LDA, to preserve the A register :)
User avatar
Eisetley
Posts: 8
Joined: Fri Feb 02, 2018 4:45 am

Re: Uncompressing background, updating individual BG tiles.

Post by Eisetley »

Sure, it works now. Turns out LDA (address) + something doesn't work either, so I had to manipulate Y.

Code: Select all

LoadBackgroundLoopA:
   INY
   LDA (BackgroundAddress), y
   TAX
   DEY
   LDA (BackgroundAddress), y
   CMP #$25
   BEQ LoadBackgroundLoopEnd
LoadBackgroundLoopB:
   STA PPU_Write
   DEX
   BNE LoadBackgroundLoopB
   INY
   INY
   JMP LoadBackgroundLoopA
Still, I don't know how to do updates on a chosen tile, first decompress whole screen somewhere in ram and load whole 1024 bytes of background + attributes every time I want to change something (even if it's only a single tile)?
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Uncompressing background, updating individual BG tiles.

Post by tokumaru »

Eisetley wrote:Turns out LDA (address) + something doesn't work either, so I had to manipulate Y.
Yup. LDA Absolute+Offset works because the address is calculated at assembly time, but with indirect addressing the address is calculated at run time, so you're limited by what the CPU can do.
Still, I don't know how to do updates on a chosen tile, first decompress whole screen somewhere in ram and load whole 1024 bytes of background + attributes every time I want to change something (even if it's only a single tile)?
It's definitely possible to update any number of bytes you want, just not from an RLE stream, since those don't typically allow for random access. If you want to read partial chunks off of an RLE stream, you'll need to break the stream in smaller pieces and create a list of pointers to the individual pieces.

Anyway, once you do know where to read the data from, you can calculate the target name table address using the following formula: Base OR (Y * 32) OR X.

Something like this should work for calculating the Target address dynamically at run time:

Code: Select all

  lda TileY
  asl
  asl
  asl
  asl
  rol TargetAddress+1
  asl
  rol TargetAddress+1
  ora TileX
  sta TargetAddress+0
  lda TargetAddress+1
  and #%00000011
  ora Base
  sta TargetAddress+1
TileX and TileY are 5-bit values (0 to 31) and Base is one of $20, $24, $28 or $2C, depending on which name table you're targeting. Then you can just write TargetAddress to register $2006 and set its value as the starting point for the transfer, instead of always starting from $2000.
Post Reply