More MMC1 CHR bankswitching woes (On real hardware)

Are you new to 6502, NES, or even programming in general? Post any of your questions here. Remember - the only dumb question is the question that remains unasked.

Moderator: Moderators

User avatar
Bregalad
Posts: 7988
Joined: Fri Nov 12, 2004 2:49 pm
Location: Chexbres, VD, Switzerland

Re: More MMC1 CHR bankswitching woes (On real hardware)

Post by Bregalad » Sun Nov 23, 2014 11:14 am

Oui :beer: :D

User avatar
MottZilla
Posts: 2832
Joined: Wed Dec 06, 2006 8:18 pm

Re: More MMC1 CHR bankswitching woes (On real hardware)

Post by MottZilla » Wed Nov 26, 2014 4:29 pm

Vectrex2809 wrote:
I used FCEUX and NEStopia. I'm gonna give Nintendulator a go, thanks for the advice. I also heard about puNes being accurate, is that the case?
Accurate is a general term. Most emulators are alot more accurate than the used to be for the NES. This is thanks to more detailed information becoming available. The author of puNES could tell you some things about how it emulates. In the past, emulator programmers had to guess, assume, and just try things out to get games working. Some information was available but it was incomplete and sometimes not entirely correct. But now we know most of the important details to emulate it with a high degree of accuracy.

It's important to note that most software isn't going to require extremely accurate emulation. Only a small percentage of games are programmed in a way that requires precise simulation.

tepples
Posts: 22143
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: More MMC1 CHR bankswitching woes (On real hardware)

Post by tepples » Wed Nov 26, 2014 6:34 pm

MottZilla wrote:Only a small percentage of games are programmed in a way that requires precise simulation.
Including your game that ends up inadvertently depending on an emulator bug. Emulators for developers need to be a lot more accurate to be useful for testing things that push the NES harder. For game logic and simple graphics updates, FCEUX plus testing on an NES about once a day is fine. But if you're trying raster effects or pushing a lot of data to the PPU each frame, you might want to be able to test without having to go to the NES (which lacks a step debugger and RAM viewer) every single time.

On this Thanksgiving day, I'm thankful that we're not stuck with NESticle anymore.

sdm
Posts: 306
Joined: Tue Apr 11, 2006 4:08 am
Location: Poland

Re: More MMC1 CHR bankswitching woes (On real hardware)

Post by sdm » Tue Sep 11, 2018 12:13 pm

I have a question about switching MMC1 banks when the PRG ROM has 512KB (SUROM). At Nesdev wiki, he writes:

https://wiki.nesdev.com/w/index.php/Programming_MMC1
Then to switch PRG ROM banks, load the bank number (0-15) into A and call this subroutine:

mmc1_load_prg_bank:
sta $E000
lsr a
sta $E000
lsr a
sta $E000
lsr a
sta $E000
lsr a
sta $E000
rts
0-15 means the maximum number of banks 16 x 16kb - 256KB PRG. Is it not clear whether by loading a value greater than 15 the code will automatically switch banks 16-31?

lidnariq
Posts: 9843
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: More MMC1 CHR bankswitching woes (On real hardware)

Post by lidnariq » Tue Sep 11, 2018 12:28 pm

No, it will not.

You must write the MSbit into the register at $A000: (nesdevwiki)

sdm
Posts: 306
Joined: Tue Apr 11, 2006 4:08 am
Location: Poland

Re: More MMC1 CHR bankswitching woes (On real hardware)

Post by sdm » Wed Sep 12, 2018 1:47 am

Thanks.


Can anyone explain this to me:

"The 256 KB PRG bank selection applies to all the PRG area, including the supposedly "fixed" bank."

I guess that if I set the second 256KB of banks, the last bank will also be replaced with a new one? So I need to make a copy of a fixed bank?

LDA #%00000000 ;banks 0-15 (15fixed)
STA $A000
;switch banks

LDA #%00001000 ;banks 16-31 (31 fixed - copy)
STA $A000
;switch banks

?

User avatar
Bregalad
Posts: 7988
Joined: Fri Nov 12, 2004 2:49 pm
Location: Chexbres, VD, Switzerland

Re: More MMC1 CHR bankswitching woes (On real hardware)

Post by Bregalad » Wed Sep 12, 2018 2:55 am

Either banks 0-15 are used in the first slot and bank 15 in the second slot, or banks 16-31 are used in the first slot and bank 31 in the second slot. You can have bank 31 being an exact copy of bank 15 or not, depending on what you want to do. The advantage of it being an exact copy is that it's easier to use, and you can bankswitch banks 0-30 in the first slot without worrying about anything, but you have less PRG-ROM as you effectively loose 16kb.

If you have different banks, you have to keep track of everything with bankswitching, just like how you keep track of what is swapped in the swappable bank. You can also have part of the fixed bank being an exact copy, and part of it being different. I think that's what Dragon Warrior III and IV does, if I'm not mistaken.

Or you could just use 32k bankswitching and have 16 banks of 32k.

User avatar
tokumaru
Posts: 11907
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: More MMC1 CHR bankswitching woes (On real hardware)

Post by tokumaru » Wed Sep 12, 2018 3:24 am

That's weird indeed, but keep in mind that SUROM is basically a hack. Someone went "hey, we've got this CHR address line we're not using, how about we use it to select which half of a 512KB PRG chip will be used as a regular 256KB MMC1 PRG chip". SUROM is basically 2 independent 256KB MMC1 ROMs, but you get to switch between them.

sdm
Posts: 306
Joined: Tue Apr 11, 2006 4:08 am
Location: Poland

Re: More MMC1 CHR bankswitching woes (On real hardware)

Post by sdm » Wed Sep 12, 2018 11:36 am

It's hard for me to understand this, because earlier I used only UNROM, which is very simple.

For example. So if I have a code in the last SUROM fixed bank 31:

Code: Select all

SomeCode:                               ;code in fixed bank 31

	LDA #%00001000		;select PRG slot 2
	STA $A000                        ;(***)

	LDA #$20		                ;switch to bank 20 (example)
	STA MMC1_BankNumber
	JSR MMC1_PRGBankWrite

	JSR SomeCodeInBank20

	LDA #%00000000		;select PRG Slot 1
	STA $A000

	LDA #$00	                	;back to bank 00
	STA MMC1_BankNumber
	JSR MMC1_PRGBankWrite

	RTS

(***) - At the moment the code in bank 31 (fixed) will disappear (the code will hang) because the entire 256KB PRG has been "changed" to another one?? (Of course, such code in UNROM-512 will work without any problems.)

Sory, for stupid questions, but I'm stubborn and I often find it difficult to understand many things: /

lidnariq
Posts: 9843
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: More MMC1 CHR bankswitching woes (On real hardware)

Post by lidnariq » Wed Sep 12, 2018 11:46 am

The register at $A000 works just like any other register in the MMC1: you still have to write to it serially.

Because with SUROM there's only two useful values, you may wish to have functions like:

Code: Select all

SUROM_select_high_256k:
  ldx #1
  stx $A000
  stx $A000
  stx $A000
  stx $A000
  stx $A000
  rts

SUROM_select_low_256k:
  ldx #0
  stx $A000
  stx $A000
  stx $A000
  stx $A000
  stx $A000
  rts
You may wish to instead have a function that takes a number between 0 and 31 and automatically does both writes:

Code: Select all

SUROM_unified_bankswitch:
  sta $E000
  lsr
  sta $E000
  lsr
  sta $E000
  lsr
  sta $E000
  ldx PRG_RAM_DISABLED
  stx $E000
  stx $A000 ; these writes must still happen despite having no other effect
  stx $A000
  stx $A000
  stx $A000
  lsr
  sta $A000
  rts

User avatar
Bregalad
Posts: 7988
Joined: Fri Nov 12, 2004 2:49 pm
Location: Chexbres, VD, Switzerland

Re: More MMC1 CHR bankswitching woes (On real hardware)

Post by Bregalad » Thu Sep 13, 2018 12:27 am

Warning: In your example the comment says you're swapping bank 20, but you're actually swapping bank $20 which does not exist so bank 0 will be swapped instead. Also, I'm pretty sure none of us used SUROM-style banking either in our projects - we just know the theoretical whereabouts of it.
Personally I've never used much PRG bankswitching other than just testing (my only large project so far uses 32kb PRG), so I can't comment on what good practices are. However I'd go for two approaches if I were to make a large MMC1 games:
  • Approach A: Just say "screw it", and make bank 15 and bank 31 (the fixed banks) exact twins of eachother. You can now freely swap banks 0-14 and 16-30 in the first slot without worrying about anything. This is definitely what you should be doing if you're used to UNROM-style bankswitching. You "loose" 16k because one bank is duplicated
  • Approach B : Use 32kb bankswitching so that the problem does not even appears. You use 16 banks of 32kb. You need to make your own "fixed bank" trampoline code replicated in each of the 16 banks, where the bare minimum for IRQ, NMI and RESET handling should be done as well as bankswitching code. This should take about 1k, so you effectively "loose" 15k.
  • Approach C : I don't recommend this, but you go crazy and fully use the bankswitching sheme: You have two sets of 16 banks, and 2 fixed banks, and you make full usage of this. For example if you're making an RPG, you can have one set of banks dedicated to battle and overworld, and the other set of banks dedicated to towns and dungeons and script. It sounds like it wouldn't be that practical to use, but at least you don't loose anything because nothing is duplicated.

tepples
Posts: 22143
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: More MMC1 CHR bankswitching woes (On real hardware)

Post by tepples » Thu Sep 13, 2018 5:41 am

Approach C.2, inspired by how storage ended up split in larger projects that I've been involved in:
Use all of the first 256K for CHR and map storage, with CHR and map decompression in the first fixed bank. This frees up all of the second fixed bank for your game logic.

sdm
Posts: 306
Joined: Tue Apr 11, 2006 4:08 am
Location: Poland

Re: More MMC1 CHR bankswitching woes (On real hardware)

Post by sdm » Thu Sep 13, 2018 10:47 am

It's probably that I will skip using SUROM. In general, UNROM only lacks WRAM and controls mirroring from the level of the code / program. Apparently it will be better to try MMC3. Is there probably all PRG space available without any problems?

User avatar
tokumaru
Posts: 11907
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: More MMC1 CHR bankswitching woes (On real hardware)

Post by tokumaru » Thu Sep 13, 2018 7:59 pm

Yes, the MMC3 is a much nicer mapper, both in capabilities and programming friendliness. Lots of people assume that the MMC1 is the next logical step up from discrete logic mappers, but the truth is it's extremely awkward to use, and doesn't really offer much in terms of features.

User avatar
Banshaku
Posts: 2393
Joined: Tue Jun 24, 2008 8:38 pm
Location: Japan
Contact:

Re: More MMC1 CHR bankswitching woes (On real hardware)

Post by Banshaku » Thu Sep 13, 2018 9:26 pm

Unless for academic reasons (wants to know more about MMC1) it would be a lot easier to use MMC3. There is no serial bit thing and you just write 1 byte to select action then 1 byte for bank and it's done. A lot more easier to manage. And the bank format is easier too.

Post Reply