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

Bankswitch when image > 256 tiles, possible issues?

Bankswitch when image > 256 tiles, possible issues?
by on (#225983)
I didn't test it yet so the goal it to get information about an hypothetical continuous image that has more than 256 tiles. And I don't want to hear about "keep it less than 255", I just want to know the possible issues, if any ;)

Let say this image is used in a non interactive section, where there is no game play. It could be a cut scene, or anything that doesn't require any input from the user. This image, being complex, requires more 256 tiles. Let say this time the target picture doesn't have a black space where the bankswitch will occur (my 2 split I did before had such thing, which helped a lot). If this image is continuous and you have to change the bank mid-screen to see the rest of the image properly, is there is no sprite on the scanline where you switch, is there any possibility of artifact or any possible issue doing so?

Was is common during the nes era too? I just hope I won't really need to use that often but I may have one case when I won't be able to avoid it.
Re: Bankswitch when image > 256 tiles, possible issues?
by on (#225984)
There is no possible issue.
Banshaku wrote:
Was is common during the nes era too?

No, it was common to keep the tiles on screen less than 257. Mid-frame CHR bankswitching was used mainly for status bars. And it was more common to change the tileset with $2000.4 and use sprites tiles as BG.
Re: Bankswitch when image > 256 tiles, possible issues?
by on (#225985)
It causes a glitch on GTROM I think, but not most other mappers.

Instead of changing the bank, you can also change PPUCTRL to point to the other pattern table. You get 512 tiles that way.
Re: Bankswitch when image > 256 tiles, possible issues?
by on (#225987)
@Bregalad / @pubby

Switching bg/sprite is the most common, interesting one. Will keep that in mind.

For mapper, it would be with an mmc3.

Let's say that even though you really wanted to use the bg/sprite switch but for some reason, you still needed some sprites for some highlights that cannot be done with bg. If we use the trick mentioned above, the only way I would see is keeps the lower part of the pt for tiles and keep upper one (1k) for sprite and duplicate into the other pt then. This one seems the simplest to do.

Still, what if you try to switch bank with mmc3, what could be the possible issue to do so for such image?
Re: Bankswitch when image > 256 tiles, possible issues?
by on (#225988)
I remember pirate ports of Genesis and SNES games doing this for title screens and such, but can't think of any examples in official games at the moment.

Since pattern tables are in a separate chip from the PPU and switching them doesn't directly interfere with any of the PPU's work (i.e. the rendering pipeline isn't disturbed in any way), this operation shouldn't suffer from a ton of "gotchas" like other raster effects do.

Looking at the good old PPU timing diagram, you can see that the PPU starts processing the background for the next scanline at cycle 321, and keeps fetching background data (including pattern bytes) all throughout the scanline. Then, when hblank starts, the PPU starts fetching sprite patterns, and does this until cycle 320, and the whole thing repeats. This means that the PPU is constantly reading pattern data, so you should switch background tiles when the PPU is fetching sprite tiles (between PPU cycles 257 and 320, or the first ~21 CPU cycles of hblank) and vice versa, in order to avoid inconsistent tile usage.

Banshaku wrote:
Switching bg/sprite is the most common, interesting one. Will keep that in mind.

That will affect how MMC3 IRQs work though, so for that specific mapper, this might not be a good idea (if you plan on using IRQs after swapping the pattern tables via $2000).

Quote:
Let's say that even though you really wanted to use the bg/sprite switch but for some reason, you still needed some sprites for some highlights that cannot be done with bg. If we use the trick mentioned above, the only way I would see is keeps the lower part of the pt for tiles and keep upper one (1k) for sprite and duplicate into the other pt then. This one seems the simplest to do.

$2000 switching will give you 512 tiles to distribute between sprites and background. If the frame starts with the background using tiles from $0000 and sprites from $1000, then at the spit you tell the background to use tiles from $1000, sprites will keep using tiles from $1000. This will totally screw up the MMC3's scanline counter though.

Quote:
Still, what if you try to switch bank with mmc3, what could be the possible issue to do so for such image?

I don't see why not. If you're using 2KB windows for the background, you only need to switch 2 banks: do the first $8000 write in advance, then use A, X and Y to buffer the remaining $8001, $8000 and $8001 values so you can make those writes as fast as possible when hblank starts. If you're using 1KB windows for the background though it may be hard to fit all those writes into the tiny hblank window, so you may want to try and design the graphics in a way that tiles from the 1KB windows that are switched last aren't used near the beginning of the scanline.
Re: Bankswitch when image > 256 tiles, possible issues?
by on (#225989)
You know, I had a nice concise write-up composed for this, but then I accidentally clicked on [X] for a tab in Chrome instead of switching a tab, so now I get to try and re-write the entire thing. (Yeah, I'm pissed off right now, and this is backed by a 16 hour work day)

I can't tell precise from the initial post, but are we simply talking about doing CHR page swapping during HBlank, to achieve more graphics than the "classic" pattern table contains? And if so, was it common?

If I understand the subject correctly: no, it wasn't common. There are a handful of games which do this, but the one that gets brought up all the time is Jurassic Park -- it does pretty much non-stop MMC3 page swapping of some sort all the time, best I can tell (Mesen's Event Viewer is incredible for this sort of thing), but I'm not sure how much it actual CHR + palette swapping. Jurassic Park's an MMC3 / NES-TSROM game.

There's this post/thread from almost 10 years ago talking about this general subject. And let's not forget about Bregalad's write-up.

You don't have very much time in HBlank, though, which is why doing it for status bars or split-screen stuff is easier -- those extra scanlines give you more time (cycles) to do what you need. You only have something like ~110 CPU cycles in HBlank, IIRC.

Off-topic: I used to try and keep a list of these type of games in my head, mainly as "test subjects" for emulator authors who wanted to really test their general mapper and PPU emulation out heavily, but I've since forgotten many of them. It might be worth putting a list somewhere on the Wiki, just as sorts of general FYI games, especially considering this page talks about the advantages of HBlank CHR-ROM swapping (see "Advantages" bullet list). This page might make a good place to put such things, maybe?
Re: Bankswitch when image > 256 tiles, possible issues?
by on (#225990)
@Tokumaru

It seems quite achievable if done properly in hblank while sprites are done. thank you for confirming!

@koitsu,
Sorry to hear that you lost you post, I know how infuriating it is ^^;;; Lost a long post for beta testing on another forum because I didn't know how the bbs soft worked yet.

This is not for realtime use (I need to check Jurasic park now, I'm curious!) but for showing some content during either an intro or cutscene so not much processing input, just showing an image. Yes, it means having more tile than the pt can show by switching mid-frame and restarting tiles from 0 (or any arbitrary one in upper bg bank) to show more content when necessary. I guess it is less intensive than the mid-screen scanline scroll split then.
Re: Bankswitch when image > 256 tiles, possible issues?
by on (#225991)
koitsu wrote:
You only have something like ~110 CPU cycles in HBlank, IIRC.

In NTSC, an ENTIRE SCANLINE is about 114 CPU cycles (341 PPU cycles / 3 = 113,66666...), hblank is just the small portion when a picture is not being rendered (341 - 256 = 85 PPU cycles, or about 28 CPU cycles), but even during hblank the PPU is still doing stuff - most of it is used to fetch sprite patterns, and the rest is used to kick off the background rendering for the next scanline, so you still have to tiptoe around those things when making use of hblank.
Re: Bankswitch when image > 256 tiles, possible issues?
by on (#225992)
Quote:
If the frame starts with the background using tiles from $0000 and sprites from $1000, then at the spit you tell the background to use tiles from $1000, sprites will keep using tiles from $1000. This will totally screw up the MMC3's scanline counter though.

This is absolutely not a problem if the part where BG and sprites uses the same side of the pattern table is after the split. What you describe is also exactly what Final Fantasy III does for its battle scenes.

Quote:
There's this post/thread from almost 10 years ago talking about this general subject. And let's not forget about Bregalad's write-up.

@Banshaku : No problem but it looked like you opened many threads about things that were discussed over and over in the past 15 years, so some further searching in the forums before asking something wouldn't be completely pointless...
Also, instead of ressorting to obscure archives of old versions of the document from my no-longer-existing-former-personal-website, you can get the last version officially from RHDN.
Re: Bankswitch when image > 256 tiles, possible issues?
by on (#225993)
@Bregalad

It is true that I didn't search in detail about that specific case (phbb search is not that accurate though) but one of your post, forgot in which thread, that mentioned to do things in the limit of the hardware instead made me want to post on the subject since it seemed that maybe it was not common somehow.

It is possible that many questions refer to content that have been posted 10~15 years ago but I'm not aware of all of them and sometime it is not easy to find them if you don't know how to search them. I'm not aware of a easy list to search on that subject too and I'm been inactive for quite sometime. In that case I will be more than glad if you refer me in the right direction and I will gladly look at that post then.
Re: Bankswitch when image > 256 tiles, possible issues?
by on (#226000)
Heosphoros' Embered Recollections album ROM used MMC3 CHR splits. The ROM itself is just music over static images, and instead of having to manage background tiles they split each image into 4 parts, if I recall:
https://chipmusic.org/forums/topic/201/heosphoros-embered-recollections-2a03nes-rom-nsf-andor-mp3/
(I'm pretty sure miau programmed this one.)

Was it common to do CHR splits for more background tiles? Sure. Especially common for status bars. Metal Slader Glory does it to swap in its font set. More generically for splitting a background was a lot less common though. (I can't even think of an example offhand, but I'm sure there's some title screens that do it. Edit: Gimmick! does on its title screen at the same time as a scroll split.)

Swapping within hblank was always possible, but I don't know of any commercial era games that did so. (Lot easier now with the hindsight of decades of reverse engineering and emulators.) Edit: I think there's a few that did use hblank, but it was uncommon.
Re: Bankswitch when image > 256 tiles, possible issues?
by on (#226002)
Smash TV is another game that does it. Its title screen, but maybe elsewhere as well.
Re: Bankswitch when image > 256 tiles, possible issues?
by on (#226003)
pubby wrote:
It causes a glitch on GTROM I think, but not most other mappers.

GTROM has a problem with CHR banking?

I remember Memblers mentioning some problems during prototyping, but is there a problem in the finished board?
Re: Bankswitch when image > 256 tiles, possible issues?
by on (#226017)
@ rainwarrior

Yes! That album does seems to use multiple banks to display a dithered like image so some people did it with not much artifact too. So I should ask Miau then? ;)

@Kasumi

Smash TV then? understood, will check that too.

So what I want to do is not futile and may have been done before, I'm happy to hear that. Time to work then.

Yes, I know, next time I should search more. Hopefully the next time I ask a question will be when I have more sleep in me :lol: if not, my memory blurs and I'm quite trigger happy to ask questions since I love talking about these things ;)

edit:

yep, Jurasick Park changes bank mid-scanline to show more details in the t-rex mouth. Smash TV does something but I'm not sure what. When you put the scanline in the middle, color is different so I'm not sure what it does. I guess I should sleep ^^;;
Re: Bankswitch when image > 256 tiles, possible issues?
by on (#226019)
Since it's easy to check a few title screens by opening a nametable viewer and cycling through a few games. There's probably a lot of examples of this, but here's a few more:

Gauntlet II: 3 CHR splits for its title screen. (Much like that Heosphoros album above.)
RoboCop 2 and RoboCop 3: CHR split for background.
Gremlins 2: CHR split for text.
Gun Nac: Also CHR switches for text throughout its intro and title.

Also, there was the MMC2 made for Punch Out to do exactly this in an automated way by having the mapper switch CHR whenever a particular tile is fetched.
Re: Bankswitch when image > 256 tiles, possible issues?
by on (#226022)
rainwarrior wrote:
Swapping within hblank was always possible, but I don't know of any commercial era games that did so. (Lot easier now with the hindsight of decades of reverse engineering and emulators.)

Maniac Mansion Marble Madness (*) does this with $2000 while Mother (J) does this with MMC3 bankswitching registers. Long ago I released a demo showing a theoretical Fire Emblem doing this with MMC1 bankswitching registers (the actual Fire Emblem had the MMC4 doing this automatically using hardware only).

(*)Sorry I just originally typed the wrong "MM" game.
Re: Bankswitch when image > 256 tiles, possible issues?
by on (#226024)
tokumaru wrote:
even during hblank the PPU [...] kick off the background rendering for the next scanline, so you still have to tiptoe around those things when making use of hblank.
Specifically, the raster timing means that the fetch for the last possibly-displayed background tile happens on cycle 248, and the bankswitch needs to happen before prefetch for the following scaline starts on cycle 320. (ulfalizer's diagram). This is a little more tolerant (8 extra cycles at the beginning) than the timing for disabling rendering without artifacts.
Re: Bankswitch when image > 256 tiles, possible issues?
by on (#226208)
edit: skip ahead to my later post, as it turns out there is no GTROM glitch.

rainwarrior wrote:
pubby wrote:
It causes a glitch on GTROM I think, but not most other mappers.

GTROM has a problem with CHR banking?

I remember Memblers mentioning some problems during prototyping, but is there a problem in the finished board?


Yeah, that was an "interesting" time. I'd highly recommend to anyone, if they're going to order 1000 assembled boards that you first obtain an oscilloscope. I was so perplexed by the OAM issues (which turned out to be nothing, a bad register setting in the Game Genie) that I kinda glossed over the problem that is in there. I should put it in the main GTROM docs, probably isn't due to a combination of laziness, embarrassment, and that it has a software work-around (for the most common uses at least). Or maybe it's part of a conspiracy to make my boards harder to emulate. :wink: haha

What happens is when you write to the mapper, the latch briefly outputs the high byte of the mapper address, and then the actual data written. For one of the pattern and nametable banks this has no effect, it's just 100% normal. But if using the other bank though, it will screw up the PPU fetch for any cycle you write to the mapper. It doesn't affect CPU banks at all, or the LEDs (theoretically it should dim them very slightly if you wrote to the register a lot, I doubt it's perceptible though).

The work-arounds are only somewhat obnoxious:
1) pattern tables - if you're displaying more than 256 BG tiles it's usually either A) a status bar on top of the screen, or B) a static screen or cutscene. Usually this means for the top portion of the screen, the CPU is waiting for sprite zero and/or running cycle-timed code. During this time you would display the "bad" page, avoid doing any CPU bankswitching (shouldn't be too hard at that point). Then write to the register during hblank. Writing during hblank means that glitch will corrupt sprites on the next line, so can't have sprites on the split point. After you've switched to the "good" page, your program can run as normal.
2) name tables - same as above, or alternately you can use the different $5xxx $7xxx mapper addresses matched up with your nametable bit, and you will always have the "good" page. Glitch is based on the high byte of the address, and the nametable bits happen to line up with those.

It was never supposed to happen, but the nametable glitch actually looks kinda cool sometimes. Would be funny to use it as an effect.
Re: Bankswitch when image > 256 tiles, possible issues?
by on (#226209)
Memblers wrote:
What happens is when you write to the mapper, the latch briefly outputs the high byte of the mapper address, and then the actual data written. For one of the pattern and nametable banks this has no effect, it's just 100% normal. But if using the other bank though, it will screw up the PPU fetch for any cycle you write to the mapper. It doesn't affect CPU banks at all, or the LEDs (theoretically it should dim them very slightly if you wrote to the register a lot, I doubt it's perceptible though).
But ... the 74'377 is a register, not a transparent latch? How do both values make it through?
Re: Bankswitch when image > 256 tiles, possible issues?
by on (#226210)
So, what does "briefly" mean? Does this affect all 8 output bits? Presumably it's fast enough that the CPU's next instruction read is never affected? (Or is the low nybble unaffected?)

Shouldn't the glitch be limited to one sliver of one tile, then?

Why would writing during hblank corrupt the sprites?

Memblers wrote:
Or maybe it's part of a conspiracy to make my boards harder to emulate. :wink: haha

Well, my dump of The Incident appears to (accidentally?) rely on some specific timing of the EEPROM recovery after erase during saving, so even the one game I implemented the emulator to try it didn't completely work for without modification. ;)
Re: Bankswitch when image > 256 tiles, possible issues?
by on (#226211)
Memblers wrote:
you can use the different $5xxx $7xxx mapper addresses matched up with your nametable bit, and you will always have the "good" page. Glitch is based on the high byte of the address, and the nametable bits happen to line up with those.
Thinking a little more, shouldn't you be able to used indexed stores to get around this for CHR banks? e.g. sta $4FFF,X as long as X is nonzero?

(Or does the logic react to reads as well as writes? I never did ask if you'd be willing to share what the specific schematic is...)
Re: Bankswitch when image > 256 tiles, possible issues?
by on (#226281)
rainwarrior wrote:
So, what does "briefly" mean? Does this affect all 8 output bits? Presumably it's fast enough that the CPU's next instruction read is never affected? (Or is the low nybble unaffected?)

Something like 20-30 nanoseconds, and I'm sure it does affect all 8 bits. The CPU address bits will be fine, it's something like 550ns until the next read cycle begins.

rainwarrior wrote:
Shouldn't the glitch be limited to one sliver of one tile, then?

Yeah, the glitches are mostly 8x1 sized, and some look 16x1 (that seems a little fast for consecutive register writes though?).

rainwarrior wrote:
Why would writing during hblank corrupt the sprites?

During hblank the PPU is fetching sprite pattern data for the next line. So to be more precise, it would corrupt the next line's sprite pattern data fetching (only if any are present on the next line).

rainwarrior wrote:
Memblers wrote:
Or maybe it's part of a conspiracy to make my boards harder to emulate. :wink: haha

Well, my dump of The Incident appears to (accidentally?) rely on some specific timing of the EEPROM recovery after erase during saving, so even the one game I implemented the emulator to try it didn't completely work for without modification. ;)

It's funny too because I think bunnyboy had given that code to Kevin, I modified for GTROM mapping, and you've modified it. It's a lot of fingerprints on one subroutine. The SST39SF chips specifies the time it takes, so that should be "within spec", though my usual code polls the chip. I had used some AM29F chips in the past, and those had huge variations in erase time (like some chips took >10 times longer than others).

lidnariq wrote:
Memblers wrote:
you can use the different $5xxx $7xxx mapper addresses matched up with your nametable bit, and you will always have the "good" page. Glitch is based on the high byte of the address, and the nametable bits happen to line up with those.

Thinking a little more, shouldn't you be able to used indexed stores to get around this for CHR banks? e.g. sta $4FFF,X as long as X is nonzero?

(Or does the logic react to reads as well as writes? I never did ask if you'd be willing to share what the specific schematic is...)

That's great! The indexing does work. And $4x,$5x,$6x,$7x is enough to cover both CHR bits.

Yeah, it is sensitive to reads as well, but I haven't tried to do it. Reading would always be the same as the glitch value, that's interesting. I can share the schematic. I'll get some screencaps from the scope and make up a post for it in the GTROM thread tonight or tomorrow.


---
edit
---
I was wrong about the timing, the glitch does last for a full CPU cycle.
Re: Bankswitch when image > 256 tiles, possible issues?
by on (#226282)
Memblers wrote:
rainwarrior wrote:
Memblers wrote:
Or maybe it's part of a conspiracy to make my boards harder to emulate. :wink: haha

Well, my dump of The Incident appears to (accidentally?) rely on some specific timing of the EEPROM recovery after erase during saving, so even the one game I implemented the emulator to try it didn't completely work for without modification. ;)

It's funny too because I think bunnyboy had given that code to Kevin, I modified for GTROM mapping, and you've modified it. It's a lot of fingerprints on one subroutine. The SST39SF chips specifies the time it takes, so that should be "within spec", though my usual code polls the chip. I had used some AM29F chips in the past, and those had huge variations in erase time (like some chips took >10 times longer than others).

I didn't mean it was relying on the delay deliberately. It seemed to be a bug (NMI / thread synchronization) that would occur if the sector clear happened "immediately" which coincidentally caused some bad timing for the bug, not actually to do with the save itself just about how/when NMI was re-enabled after doing the save.
Re: Bankswitch when image > 256 tiles, possible issues?
by on (#226359)
Update on the GTROM glitch, it's caused by using indexing while writing to the register. Just normal STA $5000 works fine every time. So essentially, there is no glitch. The 6502 does a read before the write for absolute indexed write, the mapper is sensitive to reads, thus the open bus result. The failure was in my test methodology (hacking UNROM games' register address, while not changing the opcode). Mystery solved. Will post further info in the Membler Industries section of the forum.

Just wanted to clarify that GTROM works fine, despite what I was saying.
Re: Bankswitch when image > 256 tiles, possible issues?
by on (#226360)
Ah, and that makes the value stick on the output of the latch for a full instruction cycle, long enough for 2 PPU fetches.