This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

Modifying CHR RAM in place

Modifying CHR RAM in place
by on (#178308)
I'm working on some code that needs to draw data over what exists in a tile in CHR RAM, like adding a line with a pencil. I only care about one bit plane, so I need to read 8 bytes from the PPU, perform ORA, and write them back.

I don't have enough RAM to hold all of CHR RAM, so I need to read the data during VBLANK.

This is what I have right now:
It takes 159153 cycles (if I counted correctly).


Code:
lda #>TILEADDRESS
sta $2006
lda #<TILEADDRESS
sta $2006

bit $2007 ; clear read buffer

lda $2007 ; read 8 bytes, store on zero page
sta tmp0

lda $2007
sta tmp1

lda $2007
sta tmp2

lda $2007
sta tmp3

lda $2007
sta tmp4

lda $2007
sta tmp5

ldy $2007

ldx $2007

lda #<TILEADDRESS
sta $2005 ; keep high byte
sta $2006 ; go back to tile address

; write 8 bytes, ora'd with bytes read.
lda tmp0
ora #val0
sta $2007

lda tmp1
ora #val1
sta $2007

lda tmp2
ora #val2
sta $2007

lda tmp3
ora #val3
sta $2007

lda tmp4
ora #val4
sta $2007

lda tmp5
ora #val5
sta $2007

tya
ora #val6
sta $2007

txa
ora #val7
sta $2007


I feel like there should be a faster way to do it, but I'm not very knowledgeable about the PPU's internal state. Do I need to buffer the values, or is it possible to read, modify, then write to a value in the PPU?

EDIT: Saved some time using tokumaru's trick
Re: Modifying CHR RAM in place
by on (#178313)
Say you're doing a bunch of tiles at once, and you have no big WRAM to hold your frame buffer. (Canonical example: Videomation.) The easiest way to make this fast is to read up to 8 or so tiles out of CHR RAM during vblank, modify them during active picture, and write them back to CHR RAM during the next vblank.
Re: Modifying CHR RAM in place
by on (#178316)
I guess that could get me better average speeds at the cost of a one frame latency.