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

Author Topic: Need Assembler Help to make 'Zelda - The Legend of Link' running on DS  (Read 2862 times)

dACE

  • Sr. Member
  • ****
  • Posts: 353
    • View Profile
Hi,

Hopefully you already downloaded and played the latest beta release of the ultimate NES hack: Zelda - The Legend of Link:
http://acmlm.kafuka.org/board/thread.php?id=7308&page=1

I have been looking into why 'Zelda - The Legend of Link' does NOT run properly on the DS emulator nesDS. It seems as if it fit the profile of what is described by the author:

"There is a fast way to learn if my rom will play perfectly on an emulator you use.
Watch the intro after the title screen fades away. I have a golden scroll moving up the screen.
If that scroll & text comes up garbage, then you should stop playing unfortunately.

This is because the emulator you are using, is not utilizing the MMC5 register $5130 correctly.

I perform chr swaps for 3 specific things, the intro, a mini game, and the Ganon fight.
If you continue to play the game with the garbaged gfx, it will obviously look bad, and it might even crash."


Since the emulator FCEUX does handle the register in question correctly, I did a comparison of the source-code between the two.


Here is a screen-shot of the file mmc5.cpp from the source of FCEUX (http://sourceforge.net/p/fceultra/code/HEAD/tree/fceu/trunk/src/boards/mmc5.cpp):



And here is the corresponding code of map5.s from the source of nesDS (http://sourceforge.net/p/nesds/code/ci/master/tree/arm9/source/mappers/map5.s):




So, if I understand it correctly, it is a matter of translating the C-code below into Assembler, in a way that fit the rest of the Assembler code for nesDS:

Code: [Select]
CHRBanksA[A & 7] = V | ((MMC50x5130 & 0x3) << 8);
Is anybody skilled enough in Assembler to 'fix' nesDS?

EDIT:

This is what I've tried - so far:

1. Adding another variable, called mmc50x5130:
Line 33:
mmc50x5130 = mapperdata+25

2. Storing the value of address x5130:
Line 293:
_30:
   and r0,r0,#0x03
   strb r0,mmc50x5130

3. Modifying the sprite section:
Line 159:
_20: @ For sprites.
_21:
_22:
_23:
_24:
_25:
_26:
_27:
   ldrb_ r1,mmc50x5130
   mov   r1,r1,lsl#8
   orr   r2,r2,r1

   mov r1,#0
   strb_ r1,chrbank
   adrl_ r1,chrpage0
   sub r2,r2,#0x20
   strb r0,[r1,r2]

4. Modifying the background section:
Line 229:
_28: @ For background.
_29:
_2a:
_2b:
   ldrb_ r1,mmc50x5130
   mov   r1,r1,lsl#8
   orr   r2,r2,r1

   mov r1,#1
   strb_ r1,chrbank
   adrl_ r1,chrpage0
   sub r2,r2,#0x20
   strb r0,[r1,r2]

Nedless to say - that didn't work...at all.
In fact - I made it worse, since now I get the 'red screen of death'.

At least another MMC5 game, Castlevania 3, seemed unaffected by my feeble attempts...

/dACE
« Last Edit: August 04, 2014, 12:59:48 pm by dACE »

snarfblam

  • Submission Reviewer
  • Hero Member
  • *****
  • Posts: 589
  • CANT HACK METROID
    • View Profile
    • snarfblam
Re: Need Assembler Help to make 'Zelda - The Legend of Link' running on DS
« Reply #1 on: August 04, 2014, 05:30:50 pm »
The problem here is that in the case of this register, FCEUX simply modifies a variable that is used elsewhere. The magic doesn't happen in the code you've posted. There is no trivial conversion here. The register in question is required to support a larger size CHR (graphic) ROM, which means that this feature needs to be programmed into other aspects of the emulator, and since FCEUX and nesDS don't necessarily do things the same way, you may have to do some digging and research before you even think about adding support in nesDS.

dACE

  • Sr. Member
  • ****
  • Posts: 353
    • View Profile
Re: Need Assembler Help to make 'Zelda - The Legend of Link' running on DS
« Reply #2 on: August 04, 2014, 06:08:36 pm »
You are probably right snarfblam - but what do you mean with
Quote
FCEUX simply modifies a variable that is used elsewhere

In the switch statement in FCEUX, the arrays CHRBanksA[A & 7] and CHRBanksB[A & 3] are assigned a value. A value that is adjusted, depending on the variable MMC50x5130 - that is also assigned in the very same switch statement.

So what variable is set and used elsewhere in the source of the mapper in FCEUX? What am I missing...?

Regarding the size of CHR used in the nesDS mapper - the following code appear in map5.s:

Code: [Select]
_01:
and r0,r0,#0x03
strb_ r0,chrsize
b mmc5chrb

I understod that as the size of the CHR was read from the actual ROM and placed in variable chrsize.

Is that also a misunderstanding of mine - knowing so very little Assembler?

/dACE
« Last Edit: August 04, 2014, 06:41:57 pm by dACE »

Nagato

  • Jr. Member
  • **
  • Posts: 41
    • View Profile
Re: Need Assembler Help to make 'Zelda - The Legend of Link' running on DS
« Reply #3 on: August 04, 2014, 07:00:28 pm »
Code: [Select]
ldrb_ r1,mmc50x5130
mov   r1,r1,lsl#8
orr   r2,r2,r1
...
strb r0,[r1,r2]

I might be misunderstanding something, but shouldn't that be:
Code: [Select]
ldrb_ r1,mmc50x5130
mov   r1,r1,lsl#8
orr   r0,r0,r1
...
strb r0,[r1,r2]
?

r2 would be the index, but in the FCEUX code it's ORing with the value being stored. Instead of ORing r1 and r2, it would probably need to be r1 and r0 because r0 is the byte being stored. I don't know if this will make it work or anything, though.

dACE

  • Sr. Member
  • ****
  • Posts: 353
    • View Profile
Re: Need Assembler Help to make 'Zelda - The Legend of Link' running on DS
« Reply #4 on: August 04, 2014, 08:06:34 pm »
Thanks for the tip Nagato, but the change you proposed alone didn't fix it.

Heck - propably none of the Assembler I have written is any good, I only know it passes through the syntax validation.

Snarfblam is probably right, there must be changes made to other parts of the code as well.

The next step should be to figure out how much storage is set aside for the PRG-ROM and the CHR-ROM in the source of nesDS (which by the way should be almost identical in that aspect to the source of PocketNES).

According to the specs of mapper MMC5 (http://wiki.nesdev.com/w/index.php/MMC5) it should be 1MB each.

EDIT:

So I searched the source of nesDS and found the following in rompatch.c
(https://sourceforge.net/p/nesds/code/ci/master/tree/arm9/source/rompatch.c):

Code: [Select]
void romcorrect(char *s)
{
unsigned char *rom = (unsigned char *)s;
[b]int prgsize = rom[4] * 16 * 1024;[/b]
[b]int chrsize = rom[5] * 8 * 1024;[/b]
int crcall = romcrc(rom + 16, prgsize + chrsize);
int crc = romcrc(rom + 16, prgsize);
...

Doesn't it at least appear to be large enough PRG-ROM and the CHR-ROM already defined in the source?


FYI:

Browsed through the source of Nestopia and the implementation of MMC5 (located in NstBoardMmc5.cpp).
I found the following regarding special treatment of register x5130:

Code: [Select]
...
NES_POKE_D(Mmc5,5130)
{
data = (data & Regs::CHR_HIGH) << 6;

if (banks.chrHigh != data)
{
ppu.Update();
banks.chrHigh = data;
}
}
...
for (uint i=0; i < 8; ++i)
banks.chrA[i] = data[7+i] | (data[19+(i/4)] & Regs::CHR_HIGH) << 8;

for (uint i=0; i < 4; ++i)
banks.chrB[i] = data[15+i] | (data[21+(i/4)] & Regs::CHR_HIGH) << 8;
...


/dACE
« Last Edit: August 05, 2014, 06:02:58 am by dACE »

snarfblam

  • Submission Reviewer
  • Hero Member
  • *****
  • Posts: 589
  • CANT HACK METROID
    • View Profile
    • snarfblam
Re: Need Assembler Help to make 'Zelda - The Legend of Link' running on DS
« Reply #5 on: August 04, 2014, 09:26:54 pm »
Sorry, guess I spaced a bit there. I didn't realize that the MMC50x5130 variable was used right above where it is assigned. Hard for me to follow what you were doing too, since my ASM skills are limited to 6502. Please disregard my nonsense.

dACE

  • Sr. Member
  • ****
  • Posts: 353
    • View Profile
Re: Need Assembler Help to make 'Zelda - The Legend of Link' running on DS
« Reply #6 on: August 06, 2014, 09:44:26 am »
Yeah - I'm giving up on this one...

Nobody except for Nagato extended me any help whatsoever and the current maintainer of nesDS, mr. huiminghao, does not know that 'his' own source-code for mapper 5 (MMC5) is a direct port from pocketNES!!

A couple of notes if anybody want's to pick this up in the future:

- The source of nesDS is available here:
http://sourceforge.net/p/nesds/code/ci/master/tree/

- The source of Fceux is available here:
http://sourceforge.net/p/fceultra/code/HEAD/tree/

- The complete environment for building the source of nesDS is availble here:
http://sourceforge.net/projects/devkitpro/files/Automated%20Installer/

- The latest by nesDS supported version of devKitARM is availble here:
http://sourceforge.net/projects/devkitpro/files/devkitARM/previous/devkitARM_r39-win32.exe/download

To recreate whats messed up with 'Zelda - The Legend of Link' in nesDS on windows emulators like Nestopia/Fceux you only have to change the 6th byte in the romheader from 80 (1024kb CHR-ROM) to 20 (256Kb CHR-ROM).

What bothers me the most is that it seems so solvable, if I only knew more Assembler maybe I could been able to solve it myself.

/dACE