Disassemble & Reassemble?

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems.

Moderator: Moderators

Post Reply
User avatar
FARID
Posts: 484
Joined: Wed Apr 07, 2010 1:14 am
Location: Iran
Contact:

Disassemble & Reassemble?

Post by FARID » Mon Mar 06, 2017 11:39 am

I tested a few tools to disassemble and reassemble "Super Mario Bros. (W) [!].nes" but most of them give me strange errors.
Here is the only method which worked for me to some extent :

How to Disassemble :
Disassemble mario.nes with NESrevPlus
Select DASM format and Save "mario.asm"
Open "mario.asm" and find JMP $0006 and change it to JMP ($0006) [it seems to be a bug of disassembler]

How to Reassemble :
Use dasm to generate "mario.prg" : dasm mario.asm -f3 -omario.prg
Seperate "mario.chr" by using famiROM
Take out 16bytes header by using HxD and save it as "mario.hed"
Use cmd to generate "mario.nes" : copy /b mario.hed+mario.prg+mario.chr mario.nes

I would like to know how other people disassemble & reassemble a nes game.

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

Re: Disassemble & Reassemble?

Post by lidnariq » Mon Mar 06, 2017 11:58 am


User avatar
dougeff
Posts: 2617
Joined: Fri May 08, 2015 7:17 pm
Location: DIGDUG
Contact:

Re: Disassemble & Reassemble?

Post by dougeff » Mon Mar 06, 2017 1:16 pm

I have a disassembler half done, put it on the 'back burner' to work on some other things.

It separates the PRG and CHR ROMs and writes a file (with header) that can reassemble them. The ASM it generates is not great, lots of assembler errors of labels not found.

I've used frantiks tool and reassembled with asm6.
nesdoug.com -- blog/tutorial on programming for the NES

User avatar
FARID
Posts: 484
Joined: Wed Apr 07, 2010 1:14 am
Location: Iran
Contact:

Re: Disassemble & Reassemble?

Post by FARID » Mon Mar 06, 2017 1:50 pm

Thanks for the comments but please give more details

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

Re: Disassemble & Reassemble?

Post by tepples » Mon Mar 06, 2017 2:04 pm

About which step of the process would you like more detail?

Otherwise, it becomes more difficult to "explain more please" with "much detail".

User avatar
FARID
Posts: 484
Joined: Wed Apr 07, 2010 1:14 am
Location: Iran
Contact:

Re: Disassemble & Reassemble?

Post by FARID » Mon Mar 06, 2017 2:15 pm

tepples wrote:About which step of the process would you like more detail?

Otherwise, it becomes more difficult to "explain more please" with "much detail".
Just use the first post as a template

User avatar
rainwarrior
Posts: 7680
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Disassemble & Reassemble?

Post by rainwarrior » Mon Mar 06, 2017 2:53 pm

I use cc65's disassembler, code-data logs from FCEUX, and iteratively re-disassemble adding labels to an annotation file as I analyze the code.

Here's how I described this a previous time it was asked:
viewtopic.php?p=158176#p158176

User avatar
dougeff
Posts: 2617
Joined: Fri May 08, 2015 7:17 pm
Location: DIGDUG
Contact:

Re: Disassemble & Reassemble?

Post by dougeff » Mon Mar 06, 2017 4:18 pm

More details...

Frantiks DISASM6 tool...

http://www.romhacking.net/forum/index.p ... #msg178059

Sometimes with a CDL file from FCEUX (made by playing the game with CDL logger turned 'on')

Manually type header at top of file. Manually type .incbin "CHR.chr" at the bottom.

Cut and paste CHR ROM in hex editor to a new file (I use an old obsolete one).

Assemble with asm6.
nesdoug.com -- blog/tutorial on programming for the NES

Oziphantom
Posts: 774
Joined: Tue Feb 07, 2017 2:03 am

Re: Disassemble & Reassemble?

Post by Oziphantom » Tue Mar 07, 2017 6:25 am

I use Regenerator http://csdb.dk/release/?id=149429, I have to pull the ROMs out of the NES first though . It now has a NES mode and outputs in TASS64 format. Its an interactive dissasmbler similar to FCEX et al, but with a lot more features to handle words, lo/hi hi/lo address tables, rts format etc. I did start making a Super Regenerator which might handle NES better, but its SNES LOROM only at the moment, which might or might not work depending upon your Mapper.
Then if I wanted to put it all back together, I would use a batch file to assemble the ROMs then use a asm file to pack them altogether again. Could easily be automated I would think for volume.

User avatar
FARID
Posts: 484
Joined: Wed Apr 07, 2010 1:14 am
Location: Iran
Contact:

Re: Disassemble & Reassemble?

Post by FARID » Tue Mar 07, 2017 10:33 am

Ok here is another method by using NESrevPlus and ASM6 :

How to Disassemble :
Disassemble mario.nes with NESrevPlus
Select X816 format and Save "mario.asm"

How to Reassemble :
Take out 16bytes header by using HxD and save it as "mario.hed"
Seperate "mario.chr" by using famiROM
Open "mario.asm" with Notepad++
Add to the first line of the file : .incbin "mario.hed"
Remove : .MEM 8
Remove : .INDEX 8
Add to the last line of the file : .incbin "mario.chr"
Find JMP $0006 and change it to JMP ($0006) [it seems to be a bug of disassembler]
Use ASM6 to generate "mario.nes" : asm6 mario.asm mario.nes

joshuarpl
Posts: 3
Joined: Sat Jul 06, 2019 8:59 am

Re: Disassemble & Reassemble?

Post by joshuarpl » Thu Jul 11, 2019 3:20 pm

Thanks! I followed your steps and it runs perfectly!

pwnskar
Posts: 104
Joined: Tue Oct 16, 2018 5:46 am
Location: Gothenburg, Sweden

Re: Disassemble & Reassemble?

Post by pwnskar » Fri Jul 12, 2019 10:53 am

dougeff wrote:Sometimes with a CDL file from FCEUX (made by playing the game with CDL logger turned 'on')
I've recently tried disassembling an MMC1 game (Maniac Mansion) this way and found the only way I could get the CDL to be of use throughout the whole rom was if I split up the NES and CDL file into 32kb chunks that I ran through disasm6 one pair at a time. Using a CDL file from a complete playthrough this way gave me much better results than not using any CDL at all or just the whole CDL and NES file in one go.
I wrote some python scripts and BAT files to help with the splitting of the NES and CDL files, as well as one script that turns all registers within $0000-$7FFF into constants at the top of any ASM file passed to it.

disasm.bat

Code: Select all

cd "REPLACE THIS WITH THE PATH TO ALL THE FILES"


python split_file.py "Maniac Mansion (Sweden).nes"
python split_file.py "Maniac Mansion (Sweden).cdl"


disasm6.exe "Maniac Mansion (Sweden)_0.nes" -t maniac0.asm -cdl "Maniac Mansion (Sweden)_0.cdl" -r
disasm6.exe "Maniac Mansion (Sweden)_1.nes" -t maniac1.asm -cdl "Maniac Mansion (Sweden)_1.cdl" -r
disasm6.exe "Maniac Mansion (Sweden)_2.nes" -t maniac2.asm -cdl "Maniac Mansion (Sweden)_2.cdl" -r
disasm6.exe "Maniac Mansion (Sweden)_3.nes" -t maniac3.asm -cdl "Maniac Mansion (Sweden)_3.cdl" -r
disasm6.exe "Maniac Mansion (Sweden)_4.nes" -t maniac4.asm -cdl "Maniac Mansion (Sweden)_4.cdl" -r
disasm6.exe "Maniac Mansion (Sweden)_5.nes" -t maniac5.asm -cdl "Maniac Mansion (Sweden)_5.cdl" -r
disasm6.exe "Maniac Mansion (Sweden)_6.nes" -t maniac6.asm -cdl "Maniac Mansion (Sweden)_6.cdl" -r
disasm6.exe "Maniac Mansion (Sweden)_7.nes" -t maniac7.asm -cdl "Maniac Mansion (Sweden)_7.cdl" -r


python maniac.py maniac0.asm
python maniac.py maniac1.asm
python maniac.py maniac2.asm
python maniac.py maniac3.asm
python maniac.py maniac4.asm
python maniac.py maniac5.asm
python maniac.py maniac6.asm
python maniac.py maniac7.asm


make.bat
split_file.py

Code: Select all

import re

import sys

file = sys.argv[1]

file_suffix_pattern = r"(\.[a-zA-Z0-9]*)"
file_suffix = re.findall(file_suffix_pattern, file)

CHUNK_SIZE = 32768


arg_len = len(sys.argv)
if arg_len > 2:
	CHUNK_SIZE = sys.argv[2]

file_index = 0
with open(file, "rb") as f:
	
	
	# is there a header?
	header = f.read(16)
	if not header.decode('ascii').startswith("NES"):
		f.seek(0)
		header = None
		print("No header found")
	
	chunk = f.read(CHUNK_SIZE)
	
	while chunk:
		new_file = re.sub(file_suffix_pattern, "_" + str(file_index) + r"\1", file)
		print(new_file)
		with open(new_file, "wb") as chunk_file:
			if file_index == 0:
				if not header == None:
					chunk_file.write(header)
				
			chunk_file.write(chunk)
			#print(chunk)
		
		file_index += 1
		chunk = f.read(CHUNK_SIZE)
maniac.py (replaces all register reads/writes within $0000-$7FFF with constants)

Code: Select all

import re
import sys


file = sys.argv[1]

constant_prefix = "__"

pattern = re.compile("([a-z]{3} \({0,1})\$([0-9|a-z]{2,4})")
replace_pattern = r"\1" + constant_prefix + r"\2"
variables = []

output_lines = []

f = open(file, "r")
for line in f:
	
	matches = re.findall(pattern, line)
	for match in matches:
		if match[1] not in variables:
			variables.append(match[1])
	
	# replace match in line with future constant name
	line = re.sub(pattern, replace_pattern, line)
	
	output_lines.append(line)
	
variables = sorted(variables)
	
temp1 = []
for match in variables:
	if len(match) == 2:
		temp1.append(match)
		
for match in variables:
	if len(match) == 4:
		temp1.append(match)

constants = []		
for match in temp1:
	constants.append(constant_prefix + match + " = $" + match)
	
for c in constants:
	print(c)
	
print("Unique variables found: " + str(len(temp1)))




with open(file, "w") as f:
	f.write(";-------------------------------------------------------------------------------\n")
	f.write("; Constants\n")
	f.write(";-------------------------------------------------------------------------------\n")
	
	for x in constants:
		f.write(x + "\n")
		
	f.write("\n")
		
	for item in output_lines:
		f.write(item)
make.bat

Code: Select all

cd ""REPLACE THIS WITH THE PATH TO ALL THE FILES"

asm6.exe maniac0.asm temp0.bin
asm6.exe maniac1.asm temp1.bin
asm6.exe maniac2.asm temp2.bin
asm6.exe maniac3.asm temp3.bin
asm6.exe maniac4.asm temp4.bin
asm6.exe maniac5.asm temp5.bin
asm6.exe maniac6.asm temp6.bin
asm6.exe maniac7.asm temp7.bin

copy /b temp0.bin+temp1.bin+temp2.bin+temp3.bin+temp4.bin+temp5.bin+temp6.bin+temp7.bin final.nes

fceux.exe final.nes
So far I've only tried this with the swedish version of maniac mansion and apart from the last asm file needing some manual touch up it seems to output assembly that's been categorized by code/data by the CDL throughout the whole NES file. I could not find any info online as to how to make disasm6 use anything past the first 32kb of a CDL so I thought this technique might be good to share.

If you try this technique with the swedish version (might work with others) of maniac mansion and the CDL file i've attached, it will not recompile completely on it's own due to some data being disassembled as code in bank 14 (i think), but with a more complete CDL or some manual fixup it should reassemble into a carbon copy.

This turned out to be a long reply. Basically what I'm trying to get across is that when disassembling with disasm6, CDL files are invaluable. And if you want to use them to disassemble a game with PRG rom larger than 32kb you have to do it in chunks.
Attachments
Maniac Mansion (Sweden)_CDL_FILE.zip
(7.08 KiB) Downloaded 154 times

Post Reply