- Any idea about switching CHR banks for background rendering, then sprites rendering, in a less-intensive possible thing? -_-;;
Quote:
When in 8x16 sprite mode, both sets of registers are used. The 'A' set is used for sprite tiles, and the
'B' set is used for BG. This makes it so that sprites can have a full 8k of CHR available, without having
to share any of the tiles with the BG (since the BG uses it's own 4k of CHR, designated by the 'B' set). It
is unsure what you will get when reading CHR via $2007.
When in 8x8 sprite mode, only one set is used for both BG and sprites. Either 'A' or 'B', depending on which
set is written to last. If 'B' is used, $1000-1FFF always mirrors $0000-0FFF (making the 'B' set pretty
worthless with 8x8 sprites)
What do you mean? When you are drawing sprites, switch to set A, when you are doing the BG, switch to set B. How is this intensive? I don't think there is a magic trick to making it more simple.
Are you worried about true accuracy of when which CHR set should be mapped in, incase some game were to read CHRROM? I don't think any game does but if you are concerned about accuracy I imagine the switch would happen at certain PPU clocks.
In my emulator when emulating MMC5 and 8x16 sprites, I just swap the sets when drawing my sprites and swap them back afterwards or something like that. Nothing fancy and it works fine.
MottZilla wrote:
What do you mean? When you are drawing sprites, switch to set A, when you are doing the BG, switch to set B. How is this intensive? I don't think there is a magic trick to making it more simple
- Pixel by pixel rendering. So I would had to switch banks every pixel, or PPU clockcycles. This is intensive.
Quote:
In my emulator when emulating MMC5 and 8x16 sprites, I just swap the sets when drawing my sprites and swap them back afterwards or something like that. Nothing fancy and it works fine.
- How do you do exactly this timing? By every scanline, pixel...?
- Actually, I'm working in this thing. My bg/spr render fetches directly from mmc5 banks, instead of "normal" ppu chr fetching. Still writing it... let's see.
Based on my understanding of Brad Taylor's PPU doc, you switch in the sprite banks when the PPU is supposed to be reading sprite cel slivers into secondary OAM (dots 256-319) and BG banks at other times.
- I still can't understand how this is possible. I mean, about caching tiles to be rendered/used later. Does the NES use some tile caching? I only read "pre-fetch" tons of times, but the only real caching I know is the sprite OAM, buffering 8 per scanline AFAIK.
- So, perhaps buggy, but my emu renders frames in real time, fetching palettes, tiles and scroll values all in real time execution. If there's CHR data on PPU bus, it's fetched. I really have no clue about pre-fetches, or how this heck is "pre-stored" in the NES, anyway... -_-;;
- Well, regarding the MMC5 CHR thing, I created 2 arrays of 8 pointers for separated banks. The background rendering always fetch data from specific pointers; the sprites too, from another region. ^_^;; Yup, I didn't test yet, just finishing this mess... but an idea anyway.
The sprite patterns for the next scanline are fetched during hblank. You might remember this was one of the reasons I had so much trouble making that border at the top of the screen a while back.
As others have mentioned, your sprite rendering is Doing It Wrong if you're having issues with when the switch is supposed to be.
When fetching the 8 tiles for the sprites during hblank, you use the A regs for 8x16. Anything else, you use the B regs. The two get accessed at completely different times, so there's no particular issues.
As for how it is possible in reality, the MMC5 has a pretty solid grasp of what the PPU is doing at any particular time (it has to, for the EXRAM effects) so it just knows when to apply the remapping.
Quote:
When fetching the 8 tiles for the sprites during hblank, you use the A regs for 8x16. Anything else, you use the B regs. The two get accessed at completely different times, so there's no particular issues.
- I'm trying to ask
how does the ppu keep the gfx banks until the sprites are rendered during the next scanline, or cycles 0~255? I know it fetches the
tile index, since the rendering reads gfx data from pointers, and changing them will affect the rendering, no doubt.
- Hard?
When in hblank, it reads the tile index from OAM, and then reads the actual pattern table data into an internal 16 byte buffer (2 bytes of pattern data per sprite, 8 sprites). In the 2C02 Technical Reference, these are referred to as Memory Fetch Phase 129 through 160.
When rendering the visible portion of the line, it combines the data fetched during hblank for the sprites with the data fetched on the fly for the background. Given that layout, the MMC5 only has to switch the CHR banks twice: once at the beginning of hblank, over to the sprite banks, and once at the end of hblank, back to the BG banks.
ReaperSMS wrote:
When in hblank, it reads the tile index from OAM, and then reads the actual pattern table data into an internal 16 byte buffer (2 bytes of pattern data per sprite, 8 sprites). In the 2C02 Technical Reference, these are referred to as Memory Fetch Phase 129 through 160.
When rendering the visible portion of the line, it combines the data fetched during hblank for the sprites with the data fetched on the fly for the background. Given that layout, the MMC5 only has to switch the CHR banks twice: once at the beginning of hblank, over to the sprite banks, and once at the end of hblank, back to the BG banks.
Thanks Fx3 for asking the question...this thread cleared it up a great deal for me!
- As last question: the background chr data is always from mode_b registers, or does it follow the same "rule" of 8x8 or 8x16 sprites?
Quote:
When in 8x8 sprite mode, only one set is used for both BG and sprites. Either 'A' or 'B', depending on which set is written to last. If 'B' is used, $1000-1FFF always mirrors $0000-0FFF (making the 'B' set pretty worthless with 8x8 sprites)
Assuming the doc you quoted is correct, the BG uses the B set when in 8x16 mode, last set written in 8x8 mode
ReaperSMS wrote:
Assuming the doc you quoted is correct, the BG uses the B set when in 8x16 mode, last set written in 8x8 mode
- From Disch's mapper docs.
Docs:
Quote:
When in 8x16 sprite mode, both sets of registers are used. The 'A' set is used for sprite tiles, and the
'B' set is used for BG.
[snip]
When in 8x8 sprite mode, only one set is used for both BG and sprites. Either 'A' or 'B', depending on which
set is written to last.
No commercial games (that I know of) use 8x8 spritse with MMC5.
Disch wrote:
No commercial games (that I know of) use 8x8 spritse with MMC5.
- I don't know exactly what you mean, as I trapped writes to $2000:20h=0, setting 8x8 sprites, but probably I'm misunderstanding the things..? [CastleVania3]
As I understand it, CV3 doesn't really use much of the MMC5, treating it as essentially a VRC-6 with a different register layout.
Second Quest extra enemies and rising water area use MMC5 features which aren't implemented in PocketNES.
- OK, so CastleVania 3 and Laser Invasion seem to work fine.
- I'm unable to get Just Breed working. The first fading screen "Just Breed" is glitched; next, it hangs like a flash. Plus, Uncharted Waters is glitched during the intro.
- Are 2007h reads required for proper MMC5 working? Any hints?
Quote:
- I'm unable to get Just Breed working. The first fading screen "Just Breed" is glitched; next, it hangs like a flash
Did you implement the hardware multiplier ? JB relies heavily on it.
And it only uses ExRAM mode for tiles all the way along, you you'll only get glitched BG if you don't implement that (but the game should be "playable", and the sprites should show up correctly).
Bregalad wrote:
Quote:
- I'm unable to get Just Breed working. The first fading screen "Just Breed" is glitched; next, it hangs like a flash
Did you implement the hardware multiplier ? JB relies heavily on it.
And it only uses ExRAM mode for tiles all the way along, you you'll only get glitched BG if you don't implement that (but the game should be "playable", and the sprites should show up correctly).
- Yes, the multiplier-thing is okay, but the ExRAM is working as read/write and as nametable, when setup by mirroring type.
- I suspect it's a problem with IRQs. There's not much from open source emulators: I did a look in 3 different sources - they have completely different MMC5 mechanics. In other words: empirical knowledge.