It is currently Sun Sep 23, 2018 12:00 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: How do I set up MMC3?
PostPosted: Sun Dec 03, 2017 3:29 pm 
Offline
Formerly AlienX
User avatar

Joined: Fri Apr 18, 2014 7:41 am
Posts: 137
Location: Bulgaria
So far I've been writing programs with no mapper (UNROM). I wanted to try out something with MMC3, but it turns out that simply setting up the mapper is more confusing than I thought.
Now, I do realize there's already a thread like this, but there they simply focused on fixing the problem that the person, who tried to use the mapper had, so a lot of things remain unexplained to me.
What I ask is for someone to write a step-by-step guide, that details what to put into the header, how many PRG and CHR banks are correct to use, how does the number of banks affect where to write your initial code and any special code that might be necessary to set things up. If it's simple enough, you can also add bank-switching.
I ask this, not only to get a clear idea of how to do things, but for any user, who is just starting out with this mapper and would like to know how to work with it.

Thanks!

_________________
Greetings! I'm That Bio Mechanical Dude and I like creating various stuff like movies, games and of course chiptunes!
You can check out my YouTube Channel.
You can also follow me on Twitter.


Top
 Profile  
 
PostPosted: Sun Dec 03, 2017 4:29 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20565
Location: NE Indiana, USA (NTSC)
For one thing, "UNROM" isn't "no mapper". It's a mapper that switches PRG ROM A17-A14 based on the contents of a 74HC161, OR'd with CPU A14 to provide a fixed bank at $C000.

Asking "how many PRG and CHR banks are correct to use" is is like asking "how long is a piece of string?". I can provide the minimum and maximum sizes, but I'm not going to make an exhaustive list of 16-byte headers for every possible combination of PRG ROM size, CHR ROM size, CHR RAM size, WRAM size, and mirroring behavior. Cartesian products get really big really fast.

MMC3 PRG ROM can be 16 KiB to 512 KiB in powers of two.
MMC3 WRAM is either unpopulated, 8 KiB, or 8 KiB with battery.
MMC3 CHR ROM can be unpopulated, 8 KiB to 256 KiB, or 8 KiB to 64 KiB if CHR RAM is also used, in powers of two.
MMC3 CHR RAM is either unpopulated, 8 KiB, or 32 KiB. At least one of CHR ROM or CHR RAM must be populated. A battery is not available.
MMC3 nametable mirroring can be either normal (switchable H/V) or based on the bit 7 of the CHR ROM bank (which allows oddball things like 1-screen, diagonal, or L-shaped mirroring).
TQROM rule: If a board has both CHR ROM and CHR RAM, then CHR ROM is limited to 64 KiB, and the more flexible mirroring is not available. A board containing both CHR RAM and WRAM doesn't exist officially. If it did, it would probably be as expensive as Koei's SOROM boards, as it'd need four memories.

The iNES mapper for MMC3 depends on the chosen options.

  • CHR ROM and CHR RAM: mapper 119 (byte 6: $7x, byte 7: $7x)
  • Oddball mirroring: mapper 118 (byte 6: $6x, byte 7: $7x)
  • Neither: mapper 4 (byte 6: 4x, byte 7: $0x)

Choose one combination of the above, and I can give you the remainder of the correct header for this particular combination.

In all cases, startup code must be in the very last 8 KiB bank of PRG ROM, which is fixed to $E000-$FFFF.


Top
 Profile  
 
PostPosted: Sun Dec 03, 2017 5:23 pm 
Offline
User avatar

Joined: Wed Apr 02, 2008 2:09 pm
Posts: 1244
Your total PRG ROM size has to be less than or equal to 512KB. Valid values in the header for PRG banks are 1, 2, 4, 8, 16, 32. The mapper supports 512KB max for PRG, the ROM header specifies how many 16 KB banks there will be. 512/16=32. It should be a power of 2 because physical ROMs are.

Your total CHR ROM size has to be less than or equal to 256KB. Valid values in the header for PRG banks are 1, 2, 4, 8, 16, 32. The mapper supports 256KB max for PRG, the ROM header specifies how many 8KB banks there will be. 256/8=32. It should be a power of 2 because physical ROMs are.

Edit: 0 is valid too if you want CHR RAM.

Your reset label (and vectors) need to be in the last 8KB of your PRG data. MMC3 divides your PRG data into 8KB segments, but only the last 8KB segment (bank) is guaranteed a position on power on so reset code needs to be there. The last 8KB also needs to be mapped to $E000-$FFFF.

Disable IRQs by writing any value to $E000 after reset. (You can reenable them later when you learn about them.) To set vertical mirroring, write #$00 to $A000. To set horizontal mirroring, write #$01 to $A000. You can change this at any time, but definitely set it up to something known at the start.

Writing a value to $8000 affects how the CHR and PRG banks are arranged, as well as setting which bank a write to $8001 will change. The highest 2 bits written control how the CHR and PRG banks are arranged, the lowest 3 bits control which bank a write to $8001 will change.

For now, let's assume the highest bits are all zero. Writing #$06 to $8000 will say, "I want a write to $8001 to change which bank is at $8000-$9FFF now." Writing a 0 to $8001 will then map the first 8KB of your PRG data to $8000-$9FFF. Write a #$07 to $8000 will say, "I want a write to $8001 to change which bank is at $A000-$BFFF now." Write a 1 to $8001 will then map the second 8KB of your PRG data to $A000-$BFFF.

$8000 and $8001 are a bit like the $2006 and $2007 pair, except they can be written at any time and you write the even one once per value instead of twice. First you set what you want to change with the even register, then write the value to the odd register.

So say you're changing from a 32 KB NROM game with 8KB CHR and horizontal mirroring to MMC3.
Code:
.org $E000
reset:
sta $E000;Disable IRQs.
lda #$01
sta $A000;Horizontal mirroring

ldx #$00;Not specifically MMC3, but good to do early
stx $2000; Disable NMI
stx $2001; Disable Rendering

lda #$06;We want to change $8000-$9FFF to what it was when we were 32KB NROM
sta $8000;We'll now change $8000-$9FFF when we write to $8001
lda #0
sta $8001;Now the first 8KB segment of PRG is at $8000-$9FFF just like it was in the 32KB NROM version of the game.
;Now we need to make sure $A000-$BFFF is in the right place
lda #$07
sta $8000;We'll now change $A000-$BFFF when we write to $8001
lda #1
sta $8001;Now the second 8KB segment of PRG is at $A000-$BFFF just like it was in the 32KB NROM version of the game.

;$E000-$FFFF was already in the last 8KB of PRG, and that's guaranteed for MMC3.
;$C000-$DFFF is also fine. The high bits being clear when we last wrote to $8000 guarantee this.

;Done with PRG!
lda #0; Next write to $8001 will now change the 2KB at $0000-$07FF
sta $8000
lda #0
sta $8001;We want the first 2KB of our CHR there, so 0.

lda #1;Similar drill. Next write to $8001 will now change the 2KB at $0800-$0FFF
sta $8000
;This is the part that gets a bit confusing! We're selecting the start of a 1KB segment our CHR starts
;Odd numbers essentially become the even number below them.
;Since 0 is the first 1KB, and 1 is the second 1KB, and both were already mapped by changing a 2KB segment
;2 is the proper value for the next 2KB segment.
lda #2
sta $8001

lda #2
sta $8000;Next write to $8001 will now change 1KB at $1000-$13FF
lda #4;3 was the second part of the 2KB segment from the write above. So 4...
sta $8001

lda #3
sta $8000;Next write to $8001 will now change 1KB at $1400-$17FF
lda #5;Since we're writing 1KB segments now, odd numbers are valid.
sta $8001

lda #4
sta $8000;Next write to $8001 will now change 1KB at $1800-$1BFF
lda #6
sta $8001

lda #5
sta $8000;Next write to $8001 will now change 1KB at $1C00-$1FFF
lda #7
sta $8001

Hopefully with the above, the chart on the wiki will make more sense. The way it describes CHR banks is pretty technical. But it's basically:
When writing a 1KB CHR bank (2, 3, 4, or 5 was last written to $8000), the value written to $8001 directly corresponds to 1KB in CHR. 0 is first 1KB of CHR, 1 is second 1KB of CHR, 2 is third KB of CHR etc.
When writing a 2KB CHR bank, (0 or 1 was last written to $8000) write the 1KB segment you want to start on. (But... one is subtracted from odd values. So you can only start at 0, 2, 4 etc.)

The value written to $8001 for PRG chooses which 8KB segment, the value written to $8001 for CHR chooses which 1KB segment, basically.

As for how else to setup, it would be helpful to know what assembler you used to build your previous ROMs.

Edit2: As far how does the number of banks affect where to write your code. Hmm...For CHR, so long as you only add banks after the banks that are there, nothing in your code really needs to change to add CHR banks.

PRG gets a little trickier because the very last PRG bank is the fixed bank (where your reset code and vectors need to be.) If you add PRG banks after the last one, you need to move that stuff too. If you add PRG banks before the first one, your writes to $8001 all need to be offset.

If your 8KB banks in order are A, B, C, and D. 0 refers to A, 1, refers to B, 2 refers to C, 3 refers to D. If you add E before A, 0 now refers to E... so any writes you had that wanted to swap in A will now swap in E.

So ideally you add banks before your last two banks (which are fixed at specific places), but after all the other banks.

If you find any of this confusing, by all means ask! This is a general answer, but feel free to ask for a specific one.

Edit3: Swapped mirroring whoops! Changed less than to less than or equal to while I'm here...

_________________
https://kasumi.itch.io/indivisible


Last edited by Kasumi on Mon Dec 04, 2017 3:48 am, edited 3 times in total.

Top
 Profile  
 
PostPosted: Mon Dec 04, 2017 2:36 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7518
Location: Chexbres, VD, Switzerland
tepples wrote:
MMC3 CHR RAM is either unpopulated, 8 KiB, or 32 KiB. At least one of CHR ROM or CHR RAM must be populated. A battery is not available.

Didn't know it could have 32kb of CHR-RAM. Well obviously it can, but I don't think it's Nintendo-standard to do this.
Same for battery, definitely not used on CHR-RAMs by Nintendo-standard carts, but technically nothing prevents one to do exactly that.


Top
 Profile  
 
PostPosted: Mon Dec 04, 2017 9:19 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20565
Location: NE Indiana, USA (NTSC)
Bregalad wrote:
tepples wrote:
MMC3 CHR RAM is either unpopulated, 8 KiB, or 32 KiB.

Didn't know it could have 32kb of CHR-RAM. Well obviously it can, but I don't think it's Nintendo-standard to do this.

One unlicensed game published by Retrotainment Games in 2016 uses (a clone of) MMC3 with 32 KiB of CHR RAM. I posted an explanation of how it lays out CHR RAM.


Top
 Profile  
 
PostPosted: Mon Dec 04, 2017 1:19 pm 
Offline
Formerly AlienX
User avatar

Joined: Fri Apr 18, 2014 7:41 am
Posts: 137
Location: Bulgaria
Wow, thanks for your replies! Kasumi's guide was especially detailed and it cleared up a lot of stuff for me. I still have a few questions, though.

I am using ASM6 to compile my programs, and this made me wonder... how do you define the different banks that aren't mapped to any particular address? Given that there are gonna be a lot of PRG banks that simply won't fit into the address range, how do I declare them? NESASM3 has a .bank command, but ASM6 doesn't. What do I do here?

Also, when bankswitching a certain area, where code is being run from, will the CPU continue reading from the address it was on, when the bankswitch happen? For example, let's say I'm running some code from a bank in $8000-$9FFF, I bankswitch that area and the instruction that causes the switch happens at $817F. After the switch, will the CPU continue reading from $8180 or will it somehow reset to $8000?

Thanks!

_________________
Greetings! I'm That Bio Mechanical Dude and I like creating various stuff like movies, games and of course chiptunes!
You can check out my YouTube Channel.
You can also follow me on Twitter.


Top
 Profile  
 
PostPosted: Mon Dec 04, 2017 8:42 pm 
Offline
User avatar

Joined: Wed Apr 02, 2008 2:09 pm
Posts: 1244
I guess the simplest answer to your address question is there are two types of address.

Even with NROM, the first byte after your header could go into $8000 in NES Memory, or it could go into $C000 in NES memory.

The NES doesn't really care where things are in your rom, only where they'll be mapped in NES' own memory.

What .org does is specify where things should be mapped in NES memory for that particular block of code. (I'll explain why I said should instead of will later.)

Code:
   .org $8000
main:;endless loop
   jmp main


gets assembled as $4C (jmp) $00 $80

Code:
   .org $A000
main:;endless loop
   jmp main


gets assembled as $4C (jmp) $00 $A0

Without the .org, jmp main couldn't work. There'd be no way for the assembler to know WHERE to put the jump. (Well, it could use some arbitrary starting location to assemble bytes at.)

Now, say you have the second example (.org $A000) in your first bank (bank 0).

And you did this:
Code:
   lda #$06;
   sta $8000;We'll now change $8000-$9FFF when we write to $8001
   lda #0
   sta $8001;Now the first 8KB segment of PRG is at $8000-$9FFF
   jmp main


You've just put code designed to be at $A000 at $8000. So that jmp main would jmp to $A000, but that's not where you just bank swapped in the infinite loop bank. So your program would probably crash. If you did this instead:
Code:
   lda #$06;
   sta $8000;We'll now change $8000-$9FFF when we write to $8001
   lda #0
   sta $8001;Now the first 8KB segment of PRG is at $8000-$9FFF
   jmp $8000

You would jmp to where you put the main loop in memory. But then immediately after, it would still jmp to $A000 and crash. ("main" is replaced with $A000 when assembled)

This is why I said "where things should be mapped" rather than "will be mapped." You can totally put blocks of code in memory where they're not designed to be, but you shouldn't.

I don't use much asm6, but as far as I can tell, you use .base and .pad

For example:
Code:
;bank 0
   .base $8000;Assemble the next byte to be mapped at $8000
   nop;Now the next byte will be mapped at $8001
   .pad $A000;Fills from $8001 to $9FFF. (Will assemble the next byte at $A000)
;bank 1
   .base $A000
   ;code here
   .pad $C000
   
;banks 2 and 3
   .base $8000
   ;code here
   .pad $C000
;bank 4
   .base $A000
   ;code here
   .pad $C000
;bank 5
   .base $A000
   ;code here
   .pad $C000
;bank 6
   .base $8000
   ;code here
   .pad $A000
;bank 7
   .base $8000
   ;code here
   .pad $A000

.org is usually equivalent to .pad in asm6. The above demonstrates a few things. That it's possible to have two $A000-$BFFF banks in a row. That it's possible to have two $8000-$9FFF banks in a row. That it's possible to define two 8KB banks together as one 16KB bank so long as their addresses would have been contiguous. ("banks 2 and 3") A lot of people treat MMC3 as if it has 16KB banking and just swap both 8KB banks every time.
Quote:
will the CPU continue reading from the address it was on, when the bankswitch happen?

The simplest answer is the bank switch is basically completely invisible to the CPU. So yes, it will totally still try to run the instruction at the address following the current instruction. The bank switch might change what's there, of course. ;) (It wouldn't specifically be one byte greater, though. Different instructions are different sizes.)

Don't do this, but what follows is a detailed example:

Say this is bank zero.
Code:
   .org $8000
   lda #$06;
   sta $8000;We'll now change $8000-$9FFF when we write to $8001
   lda #1
   sta $8001;Now the second 8KB segment of PRG is at $8000-$9FFF
   jmp $8000

And this is bank one
Code:
   .org $8000
   nop;a byte for lda
   nop;a byte for #$06
   
   nop;a byte for sta
   nop;a byte for $00
   nop;a byte for $80
   
   nop;a byte for lda
   nop;a byte for #1
   
   nop;a byte for sta
   nop;a byte for $01
   nop;a byte for $80
   ;We are now at the same address
   ;as jmp $8000 in bank zero
   lda #$00;disable rendering
   sta $2000
   sta $2001

If the code was running at $8000 in bank zero:
Mapped at $800A is jmp $8000. But at $8007 is sta $8001 that changes what's mapped at $800A. (Really, what's mapped in the whole region from $8000-$9FFF)
So it continues from $800A in bank 1 rather than bank 0. In other words, rendering will get disabled, rather than looping by jumping back to $8000.

I've attached a test ROM that demonstrates this. (Note that it doesn't do a lot of initialization it probably should, but it's good enough to show the concept in the current version of FCEUX.)

Put a breakpoint for execution at $8000, reset or power on, then step through it. You can see the next instruction change.
Attachment:
mmc3bankswaptest.nes [32.02 KiB]
Downloaded 63 times


I'd recommend never swapping the bank you're currently in, though. (At least not with MMC3) A good practice is having your main loop in $E000-$FFF9. You can swap in a data bank into $8000-$9FFF from there. You can swap in a bank with subroutines to read that data in $A000-$BFFF. You jsr to the subroutine, when it returns you can swap both banks again from the safety of the fixed bank.

Even if some of this goes over your head, so long as you understand the recommendation, how to "make banks" in asm6, and the "two types of address" you're fine to continue. The bank switching the bank you're in question is more theoretical than practical. At least with MMC3. AxROM swaps all of $8000-$FFFF at once. Even then, I'd probably opt for code in RAM that does the swap and jmps to the right location in the new bank.

_________________
https://kasumi.itch.io/indivisible


Top
 Profile  
 
PostPosted: Tue Dec 05, 2017 4:02 pm 
Offline
Formerly AlienX
User avatar

Joined: Fri Apr 18, 2014 7:41 am
Posts: 137
Location: Bulgaria
Thank you very much! That really cleared up a lot. I will now try to compile a program, using MMC3. I'll ask, if I encounter any issues.

_________________
Greetings! I'm That Bio Mechanical Dude and I like creating various stuff like movies, games and of course chiptunes!
You can check out my YouTube Channel.
You can also follow me on Twitter.


Top
 Profile  
 
PostPosted: Sun Sep 16, 2018 2:12 am 
Offline

Joined: Tue Apr 11, 2006 4:08 am
Posts: 275
Location: Poland
I do not want to write about MMC3 in the topic about MMC1.
viewtopic.php?f=10&t=12030&start=15

That is why I continue my previous questions about MMC3 here:

I am trying to initialize the MMC3 code, but I think I got lost in everything.


I try to write an MMC3 code with 256KB PRG and CHR RAM:


Code:

   .inesprg 16      ;256kb prg
   .ineschr 0      ;chr ram
   .inesmap 4
   .inesmir 0



Reset Code moved to E000:

Code:

RESET:
   sta $e000

   sei
   cld
 
   lda #$40
   sta $4017
 
   ldx #$FF
   TXS
 
   ldx #$07
mmc3initloop:
   stx $8000
   lda mmc3tbl,x
   sta $8001
   dex
   bpl mmc3initloop
   sta $A000

   stx $2000
   stx $2001

VBlankWait1:
   BIT $2002
   BPL VBlankWait1

VBlankWait2:
   BIT $2002
   BPL VBlankWait2

   TXA
ClearMemory:
   STA $0000, x
   STA $0100, x
   STA $0200, x
   STA $0300, x
   STA $0400, x
   STA $0500, x
   STA $0600, x
   STA $0700, x

   INX
   BNE ClearMemory

   JSR CopyCHR         ;copy chr data to CHR ROM

   ;loadscreen, loadsprite etc

Forever:

   JSR VBWait

   JMP Forever

mmc3tbl:
   .db $0,$2,$4,$5,$6,$7,$0,$1



At the beginning, switching the bank $ 8000- $ 9FFF to the new one (0E) in which the graphics data are located (8kb chr).

Code:
CopyCHR:                                 ;in e000

   LDA %00000110      ;6: Select 8 KB PRG ROM bank at $8000-$9FFF (or $C000-$DFFF)
   STA $8000
   LDA #$0E      ;switch to bank 0E
   STA $8001

   ;copychr data to cart chrram code

   LDA %00000110
   STA $8000
   LDA #$00      ;back to bank 00
   STA $8001

   RTS


Top
 Profile  
 
PostPosted: Sun Sep 16, 2018 5:49 am 
Offline
User avatar

Joined: Sun Sep 19, 2004 10:59 pm
Posts: 1430
sdm wrote:
Code:
   ldx #$07
mmc3initloop:
   stx $8000
   lda mmc3tbl,x
   sta $8001
   dex
   bpl mmc3initloop
   sta $A000

   stx $2000
   stx $2001

...
mmc3tbl:
   .db $0,$2,$4,$5,$6,$7,$0,$1



Remark: that code is writing #$FF to $2000 and $2001, which is not what you want it to do - you should change those to STA and insert an "LDA #$00" above the "sta $A000" just to make it absolutely clear what you're writing (even though it's already getting that value from the beginning of mmc3tbl, it's unclear and confusing and you will forget about that little detail at some point).

_________________
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.


Top
 Profile  
 
PostPosted: Mon Sep 17, 2018 3:03 am 
Offline

Joined: Tue Apr 11, 2006 4:08 am
Posts: 275
Location: Poland
ok, everything seems to work, the problem was a small trifle - before LDA% 00000110, there was no "#" character (of course, nesasm3 did not display an error and I missed the problem).

I changed the reset code. Works, but is it correct?

Code:
RESET:

   sta $E000;Disable IRQs.
   lda #$01
   sta $A000;Horizontal mirroring

   sei
   cld
 
   lda #$40
   sta $4017
 
   ldx #$FF
   TXS
 
   inx
   stx $2000
   stx $2001

   lda #$06
   sta $8000
   lda #0
   sta $8001
   lda #$07
   sta $8000
   lda #1
   sta $8001

VBlankWait1:
   BIT $2002
   BPL VBlankWait1

VBlankWait2:
   BIT $2002
   BPL VBlankWait2

   TXA
ClearMemory:
   STA $0000, x
   STA $0100, x
   STA $0200, x
   STA $0300, x
   STA $0400, x
   STA $0500, x
   STA $0600, x
   STA $0700, x

   INX
   BNE ClearMemory

   JSR CopyCHR         ;copy chr data to cart (

(...)


Code:
CopyCHR:

   LDA #%00000110      ;6 / 8000-9fff
   STA $8000
   LDA #2         ;switch 0 to bank 2
   STA $8001

   LDA #$00
   STA $2006
   LDA #$00
   STA $2006

   LDX #$20      ;32x 256 bytes / 8kb

   LDA #low(TileSet)
   STA <NTloadLO
   LDA #high(TileSet)
   STA <NTloadHI

   LDY #$00
CopyCHRLoop:
   LDA [NTloadLO], y
   STA $2007
   INY
   BNE CopyCHRLoop
   INC <NTloadHI
   DEX
   BNE CopyCHRLoop

   LDA #%00000110
   sta $8000
   LDA #0         ;back to bank 0
   STA $8001

   RTS


Code:
   .bank 2         ;mmc3 bank 2
   .org $8000

TileSet:

   .incbin "demo.spr"
   .incbin "demo.chr"


Test code, 16 banks prg (256kb), chr ram, chr data in bank 2 (switched bank 8000), sound at START BUTTON in bank 17 (switched bank 8000),
a/b also switch mirroring (h/v).

I only want to switch bank 0 (address 8000-9FFF). Banks A000, C000 and E000 will not be changed. It seems that everything works, but not tested on hardware.


Attachments:
demo_mmc3_d2.nes [256.02 KiB]
Downloaded 1 time


Last edited by sdm on Tue Sep 18, 2018 5:45 am, edited 2 times in total.
Top
 Profile  
 
PostPosted: Mon Sep 17, 2018 11:43 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7518
Location: Chexbres, VD, Switzerland
Quietust wrote:
Remark: [...] you should change those to STA and insert an "LDA #$00" above the "sta $A000" just to make it absolutely clear what you're writing (even though it's already getting that value from the beginning of mmc3tbl, it's unclear and confusing and you will forget about that little detail at some point).

A good practice when doing this kind of optimisation is to leave the instruction here, but comment it. That way you won't waste the 2 bytes of an useless "LDA #$00" instruction where you know A is already always $00, but the intent of loading #$00 into A is still here, and if you ever modify the code you can uncomment it to make it activate again.


Top
 Profile  
 
PostPosted: Tue Sep 18, 2018 5:23 am 
Offline

Joined: Tue Apr 11, 2006 4:08 am
Posts: 275
Location: Poland
In the previous reset code I inserted the MMC3 init code, which I was thinking is some standard init code for this mapper. Maybe I did something wrong, I do not know.

viewtopic.php?f=10&t=12030&start=30#p225789

But I see, you do not need any special mmc3 initialization? Because the code I did works. As I wrote above, I only care about switching the 8000-9FFF bank without using advanced MMC3 functions (IRQ etc).


Top
 Profile  
 
PostPosted: Tue Sep 18, 2018 6:24 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20565
Location: NE Indiana, USA (NTSC)
If you don't initialize CHR windows 0-5, you'll display wrong CHR banks. This is true even if you use CHR RAM because the MMC3 can bankswitch CHR RAM.


Top
 Profile  
 
PostPosted: Thu Sep 20, 2018 11:57 am 
Offline

Joined: Tue Apr 11, 2006 4:08 am
Posts: 275
Location: Poland
Ok, but if I do not initiate mmc3 CHR banks at the beginning, but I will use chr banks in the standard order for NROM, then the code will work and mmc3 will read everything in the standard order? ($ 0000 4kb spr $ 1000 4kb bgr, 8kb all for one bank).

I did the test code 256KB PRG + 16KB CHR. It works, but I did not test it on the console and card with mmc3.

Code:

   .bank 32
   .org $0000

TileSet0:

   .incbin "demo.spr0"      ;lda 0 sta 8000, lda 0 sta 8001 = spr bank 0
   .incbin "demo.spr1"      ;lda 0 sta 8000, lda 3 sta 8001 = spr bank 1
   .incbin "demo.chr0"      ;lda 2 sta 8000, lda 4 sta 8001 = bgr bank 0
   .incbin "demo.chr1"      ;lda 2 sta 8000, lda 5 sta 8001 = bgr bank 1
   .incbin "demo.chr2"      ;lda 2 sta 8000, lda 6 sta 8001 = bgr bank 2
   .incbin "demo.chr3"      ;lda 2 sta 8000, lda 7 sta 8001 = bgr bank 3

   .bank 33
   .org $0000

TileSet1:

   .incbin "demo.spr2"      ;lda 0 sta 8000, lda  8 sta 8001 = spr bank 2
   .incbin "demo.spr3"      ;lda 0 sta 8000, lda 10 sta 8001 = spr bank 3
   .incbin "demo.chr4"      ;lda 2 sta 8000, lda 12 sta 8001 = bgr bank 4
   .incbin "demo.chr5"      ;lda 2 sta 8000, lda 13 sta 8001 = bgr bank 5
   .incbin "demo.chr6"      ;lda 2 sta 8000, lda 14 sta 8001 = bgr bank 6
   .incbin "demo.chr7"      ;lda 2 sta 8000, lda 15 sta 8001 = bgr bank 7

;etc



Attachments:
test_mmc3_e_chrom.nes [272.02 KiB]
Downloaded 1 time


Last edited by sdm on Fri Sep 21, 2018 3:02 am, edited 6 times in total.
Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 6 guests


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

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group