Say you have a mapper with 32K bank switching, and you have code running in RAM retrieving a whole bunch of data from one of the banks. This bank with the data has no NMI handler. So you'd want to disable NMI while accessing this bank.

When the $2000 register has bit 7 set, it fires a NMI at VBlank. If it is not, it does not fire an IRQ, so your program will do whatever it does 100% uninterrupted.

Ah, thanks 3gengames, that clears it up for me!

Kasumi wrote:

unregistered: Seems about right. If I already have rendering disabled and am updating the PPU outside the NMI, having the NMI interrupt this task is kind of useless. Is that more clear? Well... maybe not totally useless. If you have a total playtime counter and use the NMI to time it, you'd still want them enabled.

Yes I'm understanding this much better now; thanks Kasumi very much!

Kasumi wrote:

3gengames wrote:

it's automatically fire an NMI regardless of if it's in VBlank or not, which would mean your vblank would then writes to Palette, VRam, PPUCtrl, PPUMask, etc all during rendering, and that's bad!

Wow. I didn't know that. Good to know.

Yes, that's good to know for me too.

tepples wrote:

Say you have a mapper with 32K bank switching, and you have code running in RAM retrieving a whole bunch of data from one of the banks. This bank with the data has no NMI handler. So you'd want to disable NMI while accessing this bank.

Thank you tepples! This is the last quote but it helped me learn that disabling NMIs could be good to do sometimes. ---All these helpful bits of knowledge are so cool! They've made the message so clear; thank you so much yall!

1. Game logic in the main loop, video and audio updates in the NMI:The whole game logic (i.e. movement, collisions, etc.) is in the main loop, and once it finishes the program waits for the NMI to fire. When it fires, it performs all the necessary video and audio updates, and then control is returned to the main loop, where the next frame will be processed.

........ just want to write what I've learned.This was going to be a question about how to know when to write to VRAM... but this appeared:

tepples, on the previous page, wrote:

Correct. Because the NES PPU lacks the write FIFO of the SMS VDP and TG16 VDC, writes to the nametables must happen during vertical blanking or forced blanking. Prepare the writes in a RAM buffer during draw time and then copy them to VRAM during vblank.

And I remembered something about force blank( my brain is getting better! ) I had read:

If both the background and sprites are hidden, the PPU enters "forced blank" state, where it stops rendering and releases control of the address and data bus.

And so it doesn't matter whether or not it is vblank or forced blank, when the background and sprites are hidden by writing #$00 to PPUMASK $2001,... those are the only times VRAM (Video RAM maybe I think) can be written to!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

If you can optimize the VRAM transfers, that's a much better alternative than resorting to forced blanking. Unroll some loops, alternate different kinds of updates (e.g. you don't need to update the palette every frame), things like that.

If you can optimize the VRAM transfers, that's a much better alternative than resorting to forced blanking. Unroll some loops, alternate different kinds of updates (e.g. you don't need to update the palette every frame), things like that.

Thanks tokumaru!

VRAM transfers... that's what I'm trying to learn about now. VRAM holds more than the nametables? The wiki reads, "Valid addresses are $0000-$3FFF;..." That's quite large 16kb... why?

$2000 is where your nametable data begins, all 2KB of it in the 4KB space (Which is why we have to mirror. Also, dunno what the top 4KB is. The 3F00 page is palette, but the $3000+ data is possibly another mirror of the nametable data? Whatever it is, we don't have to worry about it.) but the ROM for the graphics is at $0000 and $1000 pages, (4KB each) and so if you use RAM and want to write to it to put different graphics data there for a reason, that's where the data is.

$0000-$0FFF=Lower graphics page.$1000-$1FFF=Higher graphics page.$2000-$2FFF=Nametables location. (2KB of space mirrored to 4KB so how you write to the different nametables depends on mirroring)$3000-$3EFF=I don't know, but I'm guessing just the $2000 page data in that space.$3F00-$3FFF=Palette data, 32 bytes mirrored through the whole space.

$2000 is where your nametable data begins, all 2KB of it in the 4KB space (Which is why we have to mirror. Also, dunno what the top 4KB is. The 3F00 page is palette, but the $3000+ data is possibly another mirror of the nametable data? Whatever it is, we don't have to worry about it.) but the ROM for the graphics is at $0000 and $1000 pages, (4KB each) and so if you use RAM and want to write to it to put different graphics data there for a reason, that's where the data is.

$0000-$0FFF=Lower graphics page.$1000-$1FFF=Higher graphics page.$2000-$2FFF=Nametables location. (2KB of space mirrored to 4KB so how you write to the different nametables depends on mirroring)$3000-$3EFF=I don't know, but I'm guessing just the $2000 page data in that space.$3F00-$3FFF=Palette data, 32 bytes mirrored through the whole space.

When writing tiles vertically is it like the graphic where a 16x16 metatile is written... and then the one below that... and then the one below that... or is it just a 8bit wide column of tiles? I'm trying to get the logic of how it works down right now.

You can do it either way. IMO, have a buffer, and just write what you can squeeze in. If you think you can upload a palette+2 columns, no harm in trying so. I don't know what the exact limit of how many tiles you can throw to the PPU, But I think 64+Palette is fine. Although, you really only have to ever update (scrollspeed/8) rows, so if your camera only ever moves 8 pixels maximum, then you only need to upload one column ever.

The practical limit without crazy stuff like self-modifying code is probably five rows or columns plus the OAM table, where an entire palette takes up one row.

^"is probably five rows or columns"? ...The PPU is set to increment by 32 each time... so I dont understand how both of my suggestions are possible. Is it possible to write a tile, PPU increments by 1, write another tile, PPU increments by 30, then write two more tiles below those? In my head the PPU increments by 32 after each write... so thats one collum of tiles at a time... right?

edit: I feel like I missed something that both of you understand. I'm sorry 3gengames and tepples.

It can also be set to to increment 1. This can be changed at any time. You write can write X columns of bytes, then change the bit and write a row of bytes. It's not picky. You could even write half a row, half a column, then the other half of the row, the other half of the column. It's not a good idea, just saying it because things aren't so rigid as you seem to be imagining.

It can also be set to to increment 1. This can be changed at any time. You write can write X columns of bytes, then change the bit and write a row of bytes. It's not picky. You could even write half a row, half a column, then the other half of the row, the other half of the column. It's not a good idea, just saying it because things aren't so rigid as you seem to be imagining.

YES!!!!!!!!!! Thank you for this help Kasumi!! (thank you for your help 3gengames and tepples! ) I didn't ever decide to invert the bit... thought that wouldn't be good cause it might take a while.

Who is online

Users browsing this forum: No registered users and 5 guests

You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot post attachments in this forum