Page 1 of 1

Fun with CHR-ROM

Posted: Sat Nov 18, 2006 5:58 pm
by CartCollector
I've got this pattern table, and it looks like this in YY-Chr. Now, I put in in my NESASM program using

.bank 2
.org $0000
.incbin "parallax.chr"

Once I compile it, though, the palette dump I get from RockNES looks like this. Notice the squiggly line thingies at the top. Where are they coming from?

Also, I'm having problems with the name\attribute table. It seems as if the name and attribute tables are filled with $00. However, when I look at the dump from RockNES, the file seems intact! I write %10001000 to $2000, and the file is included in NESASM's bank 2 at $2000.

Posted: Sat Nov 18, 2006 6:03 pm
by Quietust
Nametables and attribute tables cannot be in CHR ROM unless you are using a specialized mapper - you must store it in your PRG ROM (i.e. banks 0/1) and then copy it into PPU memory.

I'm not sure what's going on with your tile corruption, though - are you using a special mapper?

Posted: Sat Nov 18, 2006 6:15 pm
by CartCollector
Thanks for the info on the name and attribute tables. I'm using Mapper 0, so that can't be the problem. NESASM maybe?

Posted: Sat Nov 18, 2006 6:49 pm
by Celius
So you can't read exactly what data is in the tiles unless you're using CHR RAM?

Posted: Sat Nov 18, 2006 6:58 pm
by Quietust
Celius wrote:So you can't read exactly what data is in the tiles unless you're using CHR RAM?
Umm, yes you can...
Just because the tiles are in CHR-ROM doesn't mean you can't read them - set the VRAM address (via $2006) to point at tile data (PPU $0000-$1FFF) and read the data out of $2007.

Posted: Sat Nov 18, 2006 9:45 pm
by Celius
But how would you do that if $2007 is one register, and there are 16 bytes to make up a tile?

Posted: Sat Nov 18, 2006 10:14 pm
by tepples
Celius wrote:But how would you do that if $2007 is one register, and there are 16 bytes to make up a tile?
One byte at a time.

First set the starting address:

Code: Select all

  lda #addrhi
  sta PPUADDR
  lda #addrlo
  sta PPUADDR
  lda PPUDATA  ; load the PPU's read buffer
Then copy a 256-byte chunk from PPUDATA into increasing locations in RAM, and copy it back out to VRAM.

Posted: Sun Nov 19, 2006 1:45 am
by Bregalad
CHRROM is just readable, and CHRAM is both readable and writable. That remains true, even if CHROM is supposed to be read by the PPU it's still possible for the CPU to read it in VBlank (just remember that $2007 reads are buffered, exept for palette area !). Some games with limited PRGROM does this including Super Mairo Bros. 1 and several others (my game does that too, but I did it rather for fun because I'm not totally out of PRGROM).

Also, CHRRAM is supposed to be written to by the CPU and read by the PPU, but it's also possible to read it from the CPU. (Final Fantasy II does that to animate the water. However, Hanjuku Hero and Final Fantasy III animates the water in a similar way, but this time they improved the code to keep a copy of the water tiles in RAM, so that they have more VBlank time to do other things, on the other side of wasing a portion of RAM).

Posted: Tue Nov 21, 2006 8:03 pm
by CartCollector
I'm getting glitched data in the name tables. Here's my code:

Code: Select all

	lda #$20	;Set $2007 to name tables
	ldx #$00
	sta $2006
	stx $2006

	lda #$90	;start address at $9090
	sta $01
	sta $00	
	ldx #$04
	ldy #$FF

LoadNameTable:

	lda [00],y
	sta $2007
	dey
	bne LoadNameTable

VWait3:	
	lda $2002
	bpl VWait3
	
	dex
	beq PalletteStart	;load pallette data
	inc $01
	ldy #$FF
	jmp LoadNameTable	

Posted: Wed Nov 22, 2006 10:38 am
by Bregalad
- Your code is somewhat confusing and not very well ordered, wich isn't a very good way to go
- Did you make sure to write #$00 to $2001 before doing all this ?
- It's a bad idea to "hardcore" your adress at $9090 in the code. You'd rather use a labed, and do something like the following :

Code: Select all

lda #<Label
sta PointerL
lda #>Label
sta PointerH

lda [Pointer],Y

Posted: Wed Nov 22, 2006 11:40 am
by CartCollector
The code in the above box was copied incorrectly, so I fixed it up. Also, $2001 is zeroed out, as well as $2000. It still does not work. Anything else?

Posted: Wed Nov 22, 2006 11:48 am
by Bregalad
What your code does is copy data from $918f to $9090 BACKWARDS to $2007, then copy $928f to $9190 BACKWARDS, etc...
What you probably want is to do it forward.
You'd want to do something like that :

Code: Select all

  ldx #$04
LoadLoop2
  ldy #$00
LoadLoop
  lda [Pointer], Y
  sta $2007
  iny
  bne LoadLoop
  dex
  bne LoadLoop2

Posted: Wed Nov 22, 2006 12:47 pm
by Disch
your example copies the first 256 bytes over 4 times instead of the whole 1k.

Here's a quick fixup:

Code: Select all

  ldx #$04
  ldy #$00   ; no need to put this in a LoadLoop2
                  ; as Y will be 0 when you DEX, and thus will be 0
                  ; everytime LoadLoop iterates
LoadLoop
  lda [Pointer], Y
  sta $2007
  iny
  bne LoadLoop
  inc PointerH    ; need this to advance forward 256 bytes in the source
  dex  
  bne LoadLoop

Also -- make sure you set the PPU address to increment by 1 after $2007 writes and not by 32, in addition to shutting the PPU off and all the other things mentioned.

Posted: Wed Nov 22, 2006 7:14 pm
by CartCollector
Thanks Disch, your loop worked.