News: 11 March 2016 - Forum Rules
Current Moderators - DarkSol, KingMike, MathOnNapkins, Azkadellia, Danke

Author Topic: Converting MMC1 to Other Mappers  (Read 2378 times)

Dracula X

  • Jr. Member
  • **
  • Posts: 89
    • View Profile
    • My YouTube Page for ROM hacking
Converting MMC1 to Other Mappers
« on: September 24, 2019, 10:41:40 am »
Is it easy to convert mapper 1 to other mappers?

I'm almost finished converting Dragon Warrior to MMC5 but the game keeps on crashing for some reason. I have the PPU and CHR working but I'm not sure what's making the game crashing.
I do not do other games that have already been done.

Bregalad

  • Hero Member
  • *****
  • Posts: 2644
    • View Profile
Re: Converting MMC1 to Other Mappers
« Reply #1 on: September 24, 2019, 10:47:40 am »
Is it easy to convert mapper 1 to other mappers?
Most of the time, very easy. But unless there's a particular purpose there's no point in doing that, except perhaps exerce yourself to do it.

Quote
I'm almost finished converting Dragon Warrior to MMC5 but the game keeps on crashing for some reason. I have the PPU and CHR working but I'm not sure what's making the game crashing.
Without further information it's impossible to help. Could be many things, in particular :
  • Do you use RAM or ROM that is already used by something else ?
  • If you used subroutines, do you leak stuff on the stack ?
  • Did you disable MMC5 IRQs correctly at startup ?
  • Are you sure your PRG banking routines are banking the right banks, including PRG-RAM ?

Dragon Quest (J) uses a lot of weird features such as APU-Frame IRQs and CHR-ROM reading back. I'm fairly certain Dragon Warrior (U) is clear of those, but it uses battery backed SRAM which is in itself tricky.

Dracula X

  • Jr. Member
  • **
  • Posts: 89
    • View Profile
    • My YouTube Page for ROM hacking
Re: Converting MMC1 to Other Mappers
« Reply #2 on: September 24, 2019, 11:32:21 am »
1. I think so
2. I'm not sure
3. No! And I am looking into that.
4. Yes!


Control (internal, $8000-$9FFF)
Is located at $FE0C

CHR bank 0 (internal, $A000-$BFFF)
Located at $FFAC

CHR bank 1 (internal, $C000-$DFFF)
Located at $FFC2

PRG bank (internal, $E000-$FFFF)
Located at $FF96

The game crashes when I try to talk to the king and go into battle on the field.
I do not do other games that have already been done.

Disch

  • Hero Member
  • *****
  • Posts: 2743
  • NES Junkie
    • View Profile
Re: Converting MMC1 to Other Mappers
« Reply #3 on: September 24, 2019, 01:52:06 pm »
The general rule of thumb when initializing a mapper (or, anything, really) is you should put everything in a known state.  Taken very loosely this means you should write to every writable register once at startup.

... and MMC5 has a LOT of writable registers...

However not all of them NEED to be written to.  For example, you don't need to configure how split screen works if it's disabled, but you SHOULD explicitly disable it.  And writing to the multiplication regs likewise isn't necessary because those don't really have any function if you aren't using them to multiply.

Here's a breakdown of MMC5 regs you SHOULD write to at startup and the value you should write to mimic MMC1 behavior.
(format:  00->5010 means you should write $00 to the $5010 register)

00->5010   disable MMC5 PCM
00->5015   disable MMC5 pulse audio
01->5100   set PRG swapping to 16K mode (pretty sure DW uses 16K mode but I didn't double check)
00 or 01->5101   set CHR swapping to 8K or 4K mode (whatever dragon warrior uses, this is configurable on MMC1)
02->5102   enable PRG RAM
01->5103   enable PRG RAM
02->5104   Put ExRAM in CPU mode
50 or 44->5105   Set horizontal or vertical mirroring (whatever DW uses, it's configurable)
00->5113   Set PRG RAM page
00->5130   Set CHR block
00->5200   Disable split screen
00->5204   Disable scanline IRQs
read 5209   Disable Timer IRQs


I assume you should be able to figure out PRG/CHR swapping on your own.  If you do all the above on reset, then replace the game's PRG/CHR swapping with MMC5 equivalents, there's no reason why it wouldn't work.

KingMike

  • Forum Moderator
  • Hero Member
  • *****
  • Posts: 6923
  • *sigh* A changed avatar. Big deal.
    • View Profile
Re: Converting MMC1 to Other Mappers
« Reply #4 on: September 24, 2019, 02:30:44 pm »
Dragon Quest (J) uses a lot of weird features such as APU-Frame IRQs and CHR-ROM reading back. I'm fairly certain Dragon Warrior (U) is clear of those, but it uses battery backed SRAM which is in itself tricky.

Dragon Quest uses a different mapper entirely. It's a pretty early game so it uses a comparatively simple mapper.
So old I'm not even sure MMC1 existed when it was released.
According to NES Dev, no. The first game with it "appeared" (manufactured? released?) in April 1987, nearly a year after Dragon Quest was released. (in fact, that's even after Dragon Quest II's release.)
"My watch says 30 chickens" Google, 2018

Dracula X

  • Jr. Member
  • **
  • Posts: 89
    • View Profile
    • My YouTube Page for ROM hacking
Re: Converting MMC1 to Other Mappers
« Reply #5 on: September 24, 2019, 03:28:10 pm »
The general rule of thumb when initializing a mapper (or, anything, really) is you should put everything in a known state.  Taken very loosely this means you should write to every writable register once at startup.

... and MMC5 has a LOT of writable registers...

However not all of them NEED to be written to.  For example, you don't need to configure how split screen works if it's disabled, but you SHOULD explicitly disable it.  And writing to the multiplication regs likewise isn't necessary because those don't really have any function if you aren't using them to multiply.

Here's a breakdown of MMC5 regs you SHOULD write to at startup and the value you should write to mimic MMC1 behavior.
(format:  00->5010 means you should write $00 to the $5010 register)

00->5010   disable MMC5 PCM
00->5015   disable MMC5 pulse audio
01->5100   set PRG swapping to 16K mode (pretty sure DW uses 16K mode but I didn't double check)
00 or 01->5101   set CHR swapping to 8K or 4K mode (whatever dragon warrior uses, this is configurable on MMC1)
02->5102   enable PRG RAM
01->5103   enable PRG RAM
02->5104   Put ExRAM in CPU mode
50 or 44->5105   Set horizontal or vertical mirroring (whatever DW uses, it's configurable)
00->5113   Set PRG RAM page
00->5130   Set CHR block
00->5200   Disable split screen
00->5204   Disable scanline IRQs
read 5209   Disable Timer IRQs


I assume you should be able to figure out PRG/CHR swapping on your own.  If you do all the above on reset, then replace the game's PRG/CHR swapping with MMC5 equivalents, there's no reason why it wouldn't work.

Thanks for the startup code. It works without no problems.

But I'm still getting this error and the same thing happens. It started to happen when I talk to the king, try to talk to when no one is there and go into battle mode on the field. Everything else works.

A video clip about it here: https://youtu.be/2Svn9B5Z6gA
I do not do other games that have already been done.

Disch

  • Hero Member
  • *****
  • Posts: 2743
  • NES Junkie
    • View Profile
Re: Converting MMC1 to Other Mappers
« Reply #6 on: September 24, 2019, 04:57:09 pm »
I don't know if there's much more to tell you.  This will just take some good old debugging.

It seems to be CPU related so either you're jumping to bad code (likely wrong bank swapped in) or an unwanted IRQ is firing.

Can't really be of much more help without playing with the ROM myself.

Dracula X

  • Jr. Member
  • **
  • Posts: 89
    • View Profile
    • My YouTube Page for ROM hacking
Re: Converting MMC1 to Other Mappers
« Reply #7 on: September 24, 2019, 04:59:59 pm »
Can I give you the ROM patch to test it out?
I do not do other games that have already been done.

Disch

  • Hero Member
  • *****
  • Posts: 2743
  • NES Junkie
    • View Profile
Re: Converting MMC1 to Other Mappers
« Reply #8 on: September 24, 2019, 05:01:13 pm »
Sure.  I'll take a poke at it.

September 24, 2019, 06:07:34 pm - (Auto Merged - Double Posts are not allowed before 7 days.)
I was able to reproduce the crash.

Looks like an NMI is firing when you talk to the king, and the NMI code is scrambling the stack which causes it to jump back to the wrong place when it RTIs, which causes the crash.

The culprit code is here:

Code: [Select]
$FEF7:BD 06 01  LDA $0106,X @ $01EF = #$FF                   A:82 X:E9 Y:00 S:E9 P:NVUBdIzc
$FEFA:85 36     STA $0036 = #$B5                             A:FF X:E9 Y:00 S:E9 P:NVUBdIzc
$FEFC:C9 FF     CMP #$FF                                     A:FF X:E9 Y:00 S:E9 P:NVUBdIzc
$FEFE:D0 10     BNE $FF10                                    A:FF X:E9 Y:00 S:E9 P:nVUBdIZC
$FF00:BD 05 01  LDA $0105,X @ $01EE = #$98                   A:FF X:E9 Y:00 S:E9 P:nVUBdIZC
$FF03:C9 96     CMP #$96                                     A:98 X:E9 Y:00 S:E9 P:NVUBdIzC
$FF05:90 09     BCC $FF10                                    A:98 X:E9 Y:00 S:E9 P:nVUBdIzC
$FF07:C9 D6     CMP #$D6                                     A:98 X:E9 Y:00 S:E9 P:nVUBdIzC
$FF09:B0 05     BCS $FF10                                    A:98 X:E9 Y:00 S:E9 P:NVUBdIzc
$FF0B:A9 D6     LDA #$D6                                     A:98 X:E9 Y:00 S:E9 P:NVUBdIzc
$FF0D:9D 05 01  STA $0105,X @ $01EE = #$98                   A:D6 X:E9 Y:00 S:E9 P:NVUBdIzc

This code seems to be examining the interrupt return address, and if it's within the $FF96-FFD6 range, it will change the return address to $FFD6.  This matches my crash reproduction, as my NMI occurred when the PC was at $FF98 and the RTI took me back to $FFD6.

Looking at the original ROM, the $FF98-FFD6 range appears to be the PRG swap code.  After seeing that, it all clicked.

On MMC1, PRG swaps are serial -- you have to do 5 writes to do a swap.  So what happens if an interrupt happens after only 2 of the writes?  The swap would get butchered.  So the interrupt handler is checking to see if it was in the middle of a swap, and if it was, just skip over the rest of it (presumably it would have performed the desired swap first).

Since MMC5 swaps are not serial, you don't have to worry about this and can probably remove all this code.  That should fix the crash.
« Last Edit: September 24, 2019, 06:07:55 pm by Disch »

Dracula X

  • Jr. Member
  • **
  • Posts: 89
    • View Profile
    • My YouTube Page for ROM hacking
Re: Converting MMC1 to Other Mappers
« Reply #9 on: September 26, 2019, 06:59:46 pm »
Thank you for all the help that you have been giving me! Now I know how to do other ones now.

October 02, 2019, 10:36:54 pm - (Auto Merged - Double Posts are not allowed before 7 days.)
Quote
But I'm still getting this error and the same thing happens. It started to happen when I talk to the king, try to talk to when no one is there and go into battle mode on the field. Everything else works.

Sorry about the bump but I finally fixed the problem for Dragon Warrior 1. I had to move the bankswitch code to somewhere else. Thanks to Bregalad for that info!
« Last Edit: October 02, 2019, 10:36:54 pm by Dracula X »
I do not do other games that have already been done.