NMI nametable data updater (for scrolling)

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems.

Moderator: Moderators

Post Reply
Wave
Posts: 110
Joined: Mon Nov 16, 2009 5:59 am

NMI nametable data updater (for scrolling)

Post by Wave »

I'm thinking about a generic nametable updatter for scrolling on my "framework" for neshla, that will take commands in NMI and update accordingly.

My structure right now would be like:

1 byte Command
2 bytes Data SRC

Command would be like this:
TTCNNNNN
TT: Nametable numer (0-3)
C: Column mode (set ppu to inc32)
NNNNN: Column/Row number to update

Well, that's for nametables I have to do another one for the attributes.

Any idea about it? Am I forgetting something?
User avatar
Dwedit
Posts: 4470
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Post by Dwedit »

How about a generic Spit out PPU bytes function:
MM AA AA LL DD.... and TT

MM = 'mode' (exactly what gets written to 2000)
AA AA = PPU address (big endian)
LL = length
DD... = data
TT = terminator (maybe use 80+, so negative flag will indicate the end)

So your NMI code doesn't need to do any thinking, just read bytes off the stream, set the mode, set the address, send some data.

An unpacker would be something like

loop1:
lda PACKET,y
bmi exit
sta $2000 ;mode
iny
lda PACKET,y
iny
sta $2006
lda PACKET,y
iny
sta $2006
ldx PACKET,y
iny
loop:
lda PACKET,y
sta $2007
iny
dex
bne loop
jmp loop1
exit:
rts

There's better ways to do it. This is about 7.5 bytes per scanline (inside the loop), which isn't enough to spit out 256 bytes.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
Wave
Posts: 110
Joined: Mon Nov 16, 2009 5:59 am

Post by Wave »

The mode byte it's a good idea but I will only use it's 3 last bits.
The PPU address could be calculated outside NMI, that's true.
The data would be a pointer, it will be a litte slower but mi command queue will hold only few a bytes per command (it's a multipurpose queue)

So I would leave it like:

MM: Mode, to be or'ed with the current $2000 value (and masked first)
AAAA: PPU address
DDDD: data src
LL: length

like:

lda _curr2000
and MODE_MASK
ora PACKET, y
sta _curr2000
sta $2000
lda PACKET+1, y
sta $2006
lda PACKET+2, y
sta $2006

//Load src address
lda PACKET+3, y
sta _memSrc
lda PACKET+4, y
sta _memSrc+1

ldx PACKET+5, y
ldy #0
loop:
lda (_memSrc), y
sta $2007
iny
dex
bne loop
Post Reply