Adventures in NES ROM Expansion: Episode 03 (Dai Kaijuu Deburas)

Started by BlackPaladin, February 04, 2023, 02:04:58 AM

Previous topic - Next topic

BlackPaladin

I'm trying another attempt at NES ROM expanding... this time with Dai Kaijuu Deburas.  (MMC3 Mapper #4)  So far, I managed to physically increase the PRG ROM from 8 to 16.  (The extra space I inserted is from 0x10 to 0x20010 in the ROM.)

Information from the ROM (not expanded)
 PRG ROM: 8 x 16KiB = 128 KiB
 CHR ROM: 32 x  8KiB = 256 KiB

Information from the ROM (after physically expanded)
 PRG ROM: 16 x 16KiB = 256 KiB
 CHR ROM: 32 x  8KiB = 256 KiB

...and after running the physically expanded ROM on an emulator (My personal preference is using FCEUX), the game runs fine.  I assume that after this, there needs to be some NES ASM wizardry done so that the new banks can be recognized in the game.  This is where I'm at now.  Currently, I'm looking at this game's mapper (Again, it's MMC3 Mapper #4) and figuring out which location to use the debugger on to snap at to see what code needs to be altered.

For what it's worth, I saw a picture of the PCB board of the game in question, and the chip it shows is an MMC3B chip, made by Nintendo.  I don't know if that's relevant, but I'm typing it out here in case it is relevant.

By looking at the diagram on nesdev's article on MMC3, I assume I have to set a breakpoint somewhere between $8000-$9FFF and/or $C000-$DFFF, correct?  I apologize for sounding like an idiot, but I'm still a neophyte in this area of romhacking.

Cyneprepou4uk

That depends on what code exactly you want to alter.

If you're aiming at PRG bankswitching routines, set a write breakpoint to 8000 with condition
W == #06 || W == #07

BlackPaladin

Quote from: Cyneprepou4uk on February 04, 2023, 03:29:21 AMThat depends on what code exactly you want to alter.

If you're aiming at PRG bankswitching routines, set a write breakpoint to 8000 with condition
W == #06 || W == #07

In FCEUX's debugger, I set a CPU Write breakpoint to $8000 with the conditional you suggested... but I haven't received any response.  (Neither at the unexpanded nor the physically expanded ROM.)  I assume I have to try other locations with the same conditional (even numbers?) until I get a hit?

Cyneprepou4uk

Which emulator version are you using? If 2.2.3 or lower, update it.

If still no luck, does this breakpoint hit without this condition?

BlackPaladin

Quote from: Cyneprepou4uk on February 04, 2023, 01:56:38 PMWhich emulator version are you using? If 2.2.3 or lower, update it.

If still no luck, does this breakpoint hit without this condition?

I was using a prerelease version of FCEUX (2.6.5 Pre-Release).  With or without this conditional, there was no hit.  Just to be on the safe side, I booted up the most recent stable version (2.6.4) and tried both with and without the conditional.  Even when I used the condition you suggested, without the conditional, "W == #06", or "W == #07"... I didn't get a hit either.

Cyneprepou4uk

Ok, set a write breakpoint to 8000-9FFF then, without conditions.

BlackPaladin

Quote from: Cyneprepou4uk on February 04, 2023, 08:32:08 PMOk, set a write breakpoint to 8000-9FFF then, without conditions.

I followed your suggestion, and the debugger made a hit on this...

 
On the physically expanded ROM

  03FF52: 05 56     ORA $56 = #$80
  03FF54: 85 55     STA $55 = #$86
> 03FF56: 8D 00 80  STA $8000 = #$00
  03FF59: 8E 01 80  STX $8001 = #$00

On the unexpanded ROM

  01FF52: 05 56     ORA $56 = #$80
  01FF54: 85 55     STA $55 = #$86
> 01FF56: 8D 00 80  STA $8000 = #$00
  01FF59: 8E 01 80  STX $8001 = #$00

If you want to see the whole routine in which the hit resides, here it is.  (I'll use the spoiler tag for this as it's kinda long.

Spoiler
  03FF28: A9 80     LDA #$80
  03FF2A: 85 56     STA $56 = #$80
  03FF2C: A2 32     LDX #$32
  03FF2E: 20 3E FF  JSR $FF3E
  03FF31: A2 33     LDX #$33
  03FF33: 20 57 FF  JSR $FF57
  03FF36: A9 40     LDA #$40
  03FF38: 8D 01 A0  STA $A001 = #$00
  03FF3B: A9 00     LDA #$00
  03FF3D: 8D 00 A0  STA $A000 = #$00
  03FF40: A9 06     LDA #$06
  03FF42: A0 00     LDY #$00
  03FF44: A2 00     LDX #$00
  03FF46: 20 B5 FF  JSR $FFB5
  03FF49: A0 00     LDY #$00
  03FF4B: 4C 66 FF  JMP $FF66
  03FF4E: 86 57     STX $57 = #$32
  03FF50: A9 06     LDA #$06
  03FF52: 05 56     ORA $56 = #$80
  03FF54: 85 55     STA $55 = #$86
> 03FF56: 8D 00 80  STA $8000 = #$00
  03FF59: 8E 01 80  STX $8001 = #$00
  03FF5C: 60        RTS
[close]



Cyneprepou4uk

So it's really 8000, but is written with bit7 = 1 (86/87 instead of 06/07). Doesn't explain this though

QuoteEven when I used the condition you suggested, without the conditional, "W == #06", or "W == #07"... I didn't get a hit either.

Anyway, here's your PRG bankswitching routine, or at least one of them.

BlackPaladin

Quote from: Cyneprepou4uk on February 04, 2023, 09:21:25 PMSo it's really 8000, but is written with bit7 = 1 (86/87 instead of 06/07). Doesn't explain this though

Anyway, here's your PRG bankswitching routine, or at least one of them.


 Chances are, it was something I got wrong.  Sorry about that.

I guess I have to edit that area of the ROM so that it can read the newly added banks I had physically added.

Cyneprepou4uk

03FF2C: A2 32     LDX #$32
03FF2E: 20 3E FF  JSR $FF3E

This is an example of how to swap 8000-9FFF area. X is a bank ID.

03FF31: A2 33     LDX #$33
03FF33: 20 57 FF  JSR $FF57

And this is probably for A000-BFFF.

BlackPaladin

Quote from: Cyneprepou4uk on February 04, 2023, 09:33:19 PM03FF2C: A2 32     LDX #$32
03FF2E: 20 3E FF  JSR $FF3E

This is an example of how to swap 8000-9FFF area. X is a bank ID.

03FF31: A2 33     LDX #$33
03FF33: 20 57 FF  JSR $FF57

And this is probably for A000-BFFF.

So does this mean that where "X" is, that needs to be edited so that it can recognize the newly added banks, right?  If so, does those numbers have to be halved?  Doubled?  Something else?

Cyneprepou4uk

If you want to select 0x00010-0x0200F, use X = 00. For 0x02010-0x0400F use X = 01. For 0x04010-0x0600F use X = 02. And so on.

I can't tell if you should edit original code, or add a new one. That depends on the code, your tasks and your approaches.

BlackPaladin

I don't know if this is relevant or not, but I copied from the FCEUX debugger a lot of the areas where the debugger itself snapped at $8000.  (Again, I'm using the spoiler tag here.  The code itself is long.

Spoiler
  03FF28: A9 80    LDA #$80
  03FF2A: 85 56    STA $56 = #$80
  03FF2C: A2 32    LDX #$32
  03FF2E: 20 3E FF  JSR $FF3E
  03FF31: A2 33    LDX #$33
  03FF33: 20 57 FF  JSR $FF57
  03FF36: A9 40    LDA #$40
  03FF38: 8D 01 A0  STA $A001 = #$24
  03FF3B: A9 00    LDA #$00
  03FF3D: 8D 00 A0  STA $A000 = #$10
  03FF40: A9 06    LDA #$06
  03FF42: A0 00    LDY #$00
  03FF44: A2 00    LDX #$00
  03FF46: 20 B5 FF  JSR $FFB5
  03FF49: A0 00    LDY #$00
  03FF4B: 4C 66 FF  JMP $FF66
  03FF4E: 86 57    STX $57 = #$34
  03FF50: A9 06    LDA #$06
  03FF52: 05 56    ORA $56 = #$80
  03FF54: 85 55    STA $55 = #$86
> 03FF56: 8D 00 80  STA $8000 = #$79
  03FF59: 8E 01 80  STX $8001 = #$48
  03FF5C: 60        RTS
  03FF5D: 20 40 FF  JSR $FF40
  03FF60: E8        INX
  03FF61: D0 06    BNE $FF59
  03FF63: 20 3E FF  JSR $FF3E
  03FF66: E8        INX
  03FF67: 86 58    STX $58 = #$35
  03FF69: A9 07    LDA #$07
  03FF6B: 05 56    ORA $56 = #$80
  03FF6D: 85 55    STA $55 = #$87
> 03FF6F: 8D 00 80  STA $8000 = #$BC
  03FF72: 8E 01 80  STX $8001 = #$A4
  03FF75: 60        RTS
  03FF76: A9 00    LDA #$00
  03FF78: 05 56    ORA $56 = #$80
> 03FF7A: 8D 00 80  STA $8000 = #$00
  03FF7D: B9 59 00  LDA $0059,Y @ $0059 = #$14
  03FF80: 8D 01 80  STA $8001 = #$00
  03FF83: A9 01    LDA #$01
  03FF85: 05 56    ORA $56 = #$80
  03FF87: 8D 00 80  STA $8000 = #$00
  03FF8A: B9 5A 00  LDA $005A,Y @ $005A = #$1E
  03FF8D: 8D 01 80  STA $8001 = #$00
  03FF90: A9 02    LDA #$02
  03FF92: 05 56    ORA $56 = #$80
  03FF94: 8D 00 80  STA $8000 = #$00
  03FF97: B9 5B 00  LDA $005B,Y @ $005B = #$C3
  03FF9A: 8D 01 80  STA $8001 = #$00
  03FF9D: A9 03    LDA #$03
  03FF9F: 05 56    ORA $56 = #$80
  03FFA1: 8D 00 80  STA $8000 = #$00
  03FFA4: B9 5C 00  LDA $005C,Y @ $005C = #$AF
  03FFA7: 8D 01 80  STA $8001 = #$00
  03FFAA: A9 04    LDA #$04
  03FFAC: 05 56    ORA $56 = #$80
  03FFAE: 8D 00 80  STA $8000 = #$00
  03FFB1: B9 5D 00  LDA $005D,Y @ $005D = #$AF
  03FFB4: 8D 01 80  STA $8001 = #$00
  03FFB7: A9 05    LDA #$05
  03FFB9: 05 56    ORA $56 = #$80
  03FFBB: 8D 00 80  STA $8000 = #$00
  03FFBE: B9 5E 00  LDA $005E,Y @ $005E = #$AF
  03FFC1: 8D 01 80  STA $8001 = #$00
  03FFC4: 60        RTS
[close]

Also, what you described as "X", does this mean that when X is pointing at 32 & 33, does this mean the existing code is pointing toward 0x60010-0x6200F and 0x62010-0x6400F respectively? 

I'm just confused as in the physically expanded ROM, this text starts at 0x281CC.  (Unexpanded, the text would start at 0x081CC.)  If that's the case, shouldn't X be pointing somewhere around 15 and 16 respectively?  (Or am I confusing that with something else... and judging from my track record, I probably am.)

Cyneprepou4uk

03FF76 is CHR bankswitching.

Higher bits are ignored if there's no actual PRG there, so 32 = 12.

BlackPaladin

Quote from: Cyneprepou4uk on February 04, 2023, 10:43:30 PM03FF76 is CHR bankswitching.

Higher bits are ignored if there's no actual PRG there, so 32 = 12.

So does this mean that this code here...  (Again, using spoiler tags)

Spoiler
  03FF76: A9 00     LDA #$00
  03FF78: 05 56     ORA $56 = #$80
  03FF7A: 8D 00 80  STA $8000 = #$00
  03FF7D: B9 59 00  LDA $0059,Y @ $0059 = #$14
  03FF80: 8D 01 80  STA $8001 = #$00
  03FF83: A9 01     LDA #$01
  03FF85: 05 56     ORA $56 = #$80
  03FF87: 8D 00 80  STA $8000 = #$00
  03FF8A: B9 5A 00  LDA $005A,Y @ $005A = #$1E
  03FF8D: 8D 01 80  STA $8001 = #$00
  03FF90: A9 02     LDA #$02
  03FF92: 05 56     ORA $56 = #$80
  03FF94: 8D 00 80  STA $8000 = #$00
  03FF97: B9 5B 00  LDA $005B,Y @ $005B = #$C3
  03FF9A: 8D 01 80  STA $8001 = #$00
  03FF9D: A9 03     LDA #$03
  03FF9F: 05 56     ORA $56 = #$80
  03FFA1: 8D 00 80  STA $8000 = #$00
  03FFA4: B9 5C 00  LDA $005C,Y @ $005C = #$AF
  03FFA7: 8D 01 80  STA $8001 = #$00
  03FFAA: A9 04     LDA #$04
  03FFAC: 05 56     ORA $56 = #$80
  03FFAE: 8D 00 80  STA $8000 = #$00
  03FFB1: B9 5D 00  LDA $005D,Y @ $005D = #$AF
  03FFB4: 8D 01 80  STA $8001 = #$00
  03FFB7: A9 05     LDA #$05
  03FFB9: 05 56     ORA $56 = #$80
  03FFBB: 8D 00 80  STA $8000 = #$00
  03FFBE: B9 5E 00  LDA $005E,Y @ $005E = #$AF
  03FFC1: 8D 01 80  STA $8001 = #$00
  03FFC4: 60        RTS
[close]

Is the code that needs to be edited so that the physically added banks are recognized in the ROM itself?

Also, I want to thank you for being patient with me on this subject.  I'm sure all these questions may be grating, but this is something I'm alien to me.  I guess everyone has to start somewhere.

Cyneprepou4uk

No, as I said this routine is CHR bankswitching, not PRG.

Let's take this example
03FF2C: A2 32     LDX #$32
03FF2E: 20 3E FF  JSR $FF3E

32 = 12
12 * 0x2000 + 0x10 = 0x24010
0x24010-0x2600F

Copy from there and paste to 0x00010-0x0200F. Then replace 32 with 00. And boom - your bank 00 is working the same way as original.

BlackPaladin

Quote from: Cyneprepou4uk on February 05, 2023, 02:56:23 AMNo, as I said this routine is CHR bankswitching, not PRG.

Let's take this example
03FF2C: A2 32     LDX #$32
03FF2E: 20 3E FF  JSR $FF3E

32 = 12
12 * 0x2000 + 0x10 = 0x24010
0x24010-0x2600F

Copy from there and paste to 0x00010-0x0200F. Then replace 32 with 00. And boom - your bank 00 is working the same way as original.

Oh, I see... I apologize for that mix-up.

So just copying and pasting from 0x3FF2C "A2 32 20 3E FF" and changing the "32" to a "00" in that area is what it takes to get new banks to be recognized? 

In any case, I typed up a test line at 0x000060 to see that it can be shown in-game.  Right now, I'm trying to get the pointers to work on that test line.   The text location is in 0x281CC and the game uses standard pointers though the two bytes are split into two separate pointer tables.  So the first line's high-byte, "BC", is located in 0x28010 whereas the low-byte, "81", is located in 0x280EE.

With this hack, does this mean I change the high-byte to "50" and the low-byte to "00", and the game will display the text?  Or my calculations are way off?

Cyneprepou4uk

No, copy from 0x24010-0x2600F.

BC + 81 = 81BC. It's a CPU address, not file address. If you load bank 00 into 8000-9FFF CPU area, 0x00060 will be 8050, so pointer should be 50 + 80.

BTW, in 81BC example high byte is 81, not BC.

BlackPaladin

Quote from: Cyneprepou4uk on February 05, 2023, 03:31:23 AMNo, copy from 0x24010-0x2600F.

BC + 81 = 81BC. It's a CPU address, not file address. If you load bank 00 into 8000-9FFF CPU area, 0x00060 will be 8050, so pointer should be 50 + 80.

BTW, in 81BC example high byte is 81, not BC.

I copied everything from 0x24010-2600F and pasted it all to 0x10 so that it covers from there to 0x200F.  I also changed the "32" in "03FF2C: A2 32     LDX #$32" to a "00".  With those changes made, does this mean that the new banks will be recognized in the ROM?

As of now, I'm trying to do another test line, this time in 0x2040.  No luck yet.

I don't know what I'm doing wrong... or if I'm missing something.

Cyneprepou4uk

#19
It's just an example of how bank 00 can be used. It's not some kind of magic trick so that all new banks at once somehow become available at will.

If you want to read text from bank 00, first you need to load it instead of whatever bank was loaded.

For example, the text at 0x281CC can be read because bank 14/34 was loaded into 8000-9FFF.