DISASM6 v1.5 - Nes oriented disassembler producing asm6 code
Moderator: Moderators
-
- Posts: 22
- Joined: Mon Dec 26, 2016 8:58 am
Re: DISASM6 v1.5 - Nes oriented disassembler producing asm6
Thanks, I'll assume that is the case and RE the code accordingly.
If I was a bit more knowledgeable, I could change the code myself; I'd like to see the JMP shown properly, with the "Suspected Data" comment as, well , as comment, referencing the suspect address.
But thanks to frantik for the original, anyway, I'm having fun with it!
C
If I was a bit more knowledgeable, I could change the code myself; I'd like to see the JMP shown properly, with the "Suspected Data" comment as, well , as comment, referencing the suspect address.
But thanks to frantik for the original, anyway, I'm having fun with it!
C
-
- Posts: 22
- Joined: Mon Dec 26, 2016 8:58 am
Re: DISASM6 v1.5 - Nes oriented disassembler producing asm6
Hi again all,
Still playing with Disasm6, but having a bit of trouble getting the custom label thingy to work. This last piece of help would be appreciated.
Here is my command line, using the "l" (labels) command:
disasm6 code7.nes -lcode7.lbl -c -r
Here is my one-line custom label file, made with Notepad:
VBlank = $c014
Yet, the asm output is still:
__c014: lda PPUSTATUS ; $c014: ad 02 20
What do I need to do to get the label to work? [I took the format of the label file from a post here on the board (sorry, don't recall where), in which someone had a similar label question and posted an image file showing his label file, so I used that format.]
I've tried numerous label file formats, with and without "$", using "0x", using "h", including and excluding the "__". What am I missing? I've even tried decimal 49172.
Thanks
Charlie
Still playing with Disasm6, but having a bit of trouble getting the custom label thingy to work. This last piece of help would be appreciated.
Here is my command line, using the "l" (labels) command:
disasm6 code7.nes -lcode7.lbl -c -r
Here is my one-line custom label file, made with Notepad:
VBlank = $c014
Yet, the asm output is still:
__c014: lda PPUSTATUS ; $c014: ad 02 20
What do I need to do to get the label to work? [I took the format of the label file from a post here on the board (sorry, don't recall where), in which someone had a similar label question and posted an image file showing his label file, so I used that format.]
I've tried numerous label file formats, with and without "$", using "0x", using "h", including and excluding the "__". What am I missing? I've even tried decimal 49172.
Thanks
Charlie
Re: DISASM6 v1.5 - Nes oriented disassembler producing asm6
The source code to disasm6 is provided (it's in PHP). So let's look at it, shall we? Sadly this source code is not on GitHub or anywhere I can find other than nesdev, so I have to copy-paste it here directly. First, we find that the usage syntax is:charliee1151 wrote:...
Here is my command line, using the "l" (labels) command:
disasm6 code7.nes -lcode7.lbl -c -r
Here is my one-line custom label file, made with Notepad:
VBlank = $c014
Yet, the asm output is still:
__c014: lda PPUSTATUS ; $c014: ad 02 20
What do I need to do to get the label to work?
Code: Select all
echo <<<ENDOFSTRING
Usage:
disasm6 <file> [-t <file>] [-o #] [-l <file>] [-cdl <file>] [-cdlo #] [-d] [-i]
[-h] [-c] [-p #] [-r] [-lc] [-uc] [-fs #] [-cs #] [-fe #] [-ce <#>]
[-len #] [-iw] [-m2]
Code: Select all
$labelFile = false;
...
// check command line params
for ($i = 2; $i < $argc; $i++)
{
$nextParam = false;
if (isset($argv[$i + 1]) && substr($argv[$i + 1],0,1) != '-')
{ $nextParam = $argv[$i + 1];
}
switch (strtolower($argv[$i]))
{
...
case '-l':
case '-labels':
if (!$nextParam || !file_exists($nextParam))
{ outputHelp("You must specify a valid file");
}
$labelFile = $argv[++$i];
break;
Code: Select all
$labelLen = 0;
if ($labelFile !== false)
{
$fileLabels = readLabels($labelFile);
//$mapperArr = $fileLabels['mapperArr'];
//unset($fileLabels['mapperArr']);
$labelLen = $fileLabels['maxLength'] - 10;
$labelLen = $labelLen < 0 ? 0: $labelLen;
unset ($fileLabels['maxLength']);
$initLabels += $fileLabels;
}
Code: Select all
function readLabels($filename)
{
$arr = readLabelText(file_get_contents($filename));
return $arr;
}
Code: Select all
function readLabelText($str)
{
$arr = array();
$len = 0;
$str = preg_replace('%;.*$%m', '', $str);
if (preg_match_all('%^\s*([a-zA-Z0-9_\-\+\@]*)\s*\=\s*([\$\%]*)([a-fA-F0-9]*)%m', $str, $matches))
{
foreach($matches[0] as $n => $v)
{ $matches[1][$n] = trim($matches[1][$n]);
$thislen = strlen($matches[1][$n]);
if ($thislen > $len)
{
$len = $thislen;
}
if (strlen($matches[1][$n]) > 0)
{
if ($matches[2][$n] == '')
{ $matches[3][$n] = dechex_pad($matches[3][$n]);
}
if ($matches[2][$n] == '%')
{
$matches[3][$n] = dechex_pad(bindec($matches[3][$n]));
}
$arr[strtolower($matches[3][$n])] = $matches[1][$n];
}
}
}
$arr['maxLength'] = $len;
return $arr;
}
The $str = preg_replace('%;.*$%m', '', $str); essentially deletes/ignore any lines that start with ; (i.e. comments). The author chose to use % as the delimiter instead of /.
The if (preg_match_all('%^\s*([a-zA-Z0-9_\-\+\@]*)\s*\=\s*([\$\%]*)([a-fA-F0-9]*)%m', $str, $matches)) is what does the "line matching". It's a very long regex, so let's try to turn it into an English sentence:
* ^ -- anchor at beginning of the line
* \s* -- zero or more spaces
* ([a-zA-Z0-9_\-\+\@]*) -- zero or more characters in the ranges a-z, A-Z, 0-9, underscore, hyphen, plus, or at-symbol -- and if matched, save the contents into array (not string!) $matches[0]
* \s* -- zero or more spaces
* = -- an equals sign
* \s* -- zero or more spaces
* ([\$\%]*) -- zero or more characters of dollar-sign or percentage -- and if matched, save the contents into array $matches[1]
* ([a-fA-F0-9]*) -- zero or more characters in the ranges a-f, A-F, or 0-9 (i.e. valid hexadecimal values in upper or lowercase) -- and if matched, save the contents into array $matches[2]
So based on this, the following label assignments should be 100% valid:
Code: Select all
mylabel = $abc0
otherlabel = 12345
I have no idea why there's a special case for % (percentange) as a unit. Maybe binary? I don't know as of right now.
The code then iterates over all the entries in $matches[0], assigning the key to $n and the value to $v.
It then issues trim() on each correlating entry in $matches[1][$n] (trims off newlines, carriage returns, and spaces from start and end of the address base designation) and stores it back into $matches[1][$n]
It then checks the length of the string of $matches[1][$n] and if it's greater than $len (which starts at 0), then it assigns $len to the length of the string. I guess this is some kind of "max string length" test scenario, though I'm not sure why (it looks like it all gets used later on in some magic key called maxLength in the $arr array. Anyway...)
It then explicitly checks for the length of the string $matches[1][$n] to be greater than 0 (probably as a safety net due to crappy parsing ;-) ). If true:
It then compares $matches[2][$n] to '' (an empty string). If it's true, it uses dechex_pad() to turn -- I'm guessing here -- a decimal value in $matches[3][$n] into something. I haven't looked at dechex_pad() yet. It stores the result back in $matches[3][$n]. This is a new key/array entry in $matches.
It then compares $matches[2][$n] to '$' (dollar sign). If it's true, it uses dechex_pad(bindec()) to turn -- again, guessing -- a hexadecimal value in $matches[3][$n] into something. It stores the result back in $matches[3][$n]. This is a new key/array entry in $matches.
Finally, it populates the array $arr, using a key of the lowercased string version of $matches[3][$n], with a value of $matches[1][$n].
It then, before returning the array itself, populates $arr['maxLength'] with $len from earlier.
How all this works past this point is beyond me -- it would require a lot more RE'ing than I'm willing to put in. It looks like this tool can also **generate** label files, and the syntax it uses it kind of obvious:
Code: Select all
function outputLabels($arr, $text)
{
global $origin;
$ret = commentHeader($text);
foreach ($arr as $n => $v)
{
if ($n == 'maxLength')
{
continue;
}
if (hexdec($n) < $origin)
{
$ret .= str_pad($v , 20) . ' = $' . $n . "\n";
}
}
return $ret;
}
I hope this helps. But odds are if you want to troubleshoot/debug this yourself, you're going to need a full PHP install on the system and start running the .php script directly through the interpreter (i.e. not using disasm6.exe) and add some debugging echo/print statements, etc...
-
- Posts: 22
- Joined: Mon Dec 26, 2016 8:58 am
Re: DISASM6 v1.5 - Nes oriented disassembler producing asm6
Thanks for the explanation. Believe it or not, I actually did almost exactly what you did in your response (I promise, swear, and affirm that I did it), using an on-line "run php scripts" website.
After some 4 days or so, I was able to determine what the syntax was supposed to be (label = $xxxx) by copying selected parts of the php source (the same functions you did, for obvious reasons) and get all the way through to the same point where you did:
==>It then, before returning the array itself, populates $arr['maxLength'] with $len from earlier.<==.
At that point I ran into two problems:
1. I could not get the label array (matches[]) to give me more that a single output, even with multiple label assignments in the label file, and
2. I could not get ANY response out of disasm6.
I assumed both of these problems were because of improper formatting of the label file, which I why I tried so many different combinations and got rather frustrated. Imagine how much more frustrated I became when I found the previous post I mentioned, in which a screen shot of a (presumably) correct label file is included, and it MATCHED my file (as best as I can tell)!
At that point, I began to investigate exactly what you suggested...installing PHP on Win10 and debugging it. But the PHP install seems very complicated, and I realized that before I dug into all that, I should probably ask for help here...so I took the chance.
Well, I'm gratified to learn that my 4-day "learn minimum php by total immersion"(!?!?) project was not all in vain, and at least you have provided evidence of my sanity in my attempted analysis of the code!
Thanks very much for your help, your confirmation of my thought processes is certainly a step forward in that it verifies my studies so far.
I shall continue my research, going onward and upward, never ceasing, always moving forward...etc, etc. blah,blah,blah.
If I have any success, I'll certainly report it.
Seriously, thanks for what you did. At least I know I'm on the right track!
Charlie
After some 4 days or so, I was able to determine what the syntax was supposed to be (label = $xxxx) by copying selected parts of the php source (the same functions you did, for obvious reasons) and get all the way through to the same point where you did:
==>It then, before returning the array itself, populates $arr['maxLength'] with $len from earlier.<==.
At that point I ran into two problems:
1. I could not get the label array (matches[]) to give me more that a single output, even with multiple label assignments in the label file, and
2. I could not get ANY response out of disasm6.
I assumed both of these problems were because of improper formatting of the label file, which I why I tried so many different combinations and got rather frustrated. Imagine how much more frustrated I became when I found the previous post I mentioned, in which a screen shot of a (presumably) correct label file is included, and it MATCHED my file (as best as I can tell)!
At that point, I began to investigate exactly what you suggested...installing PHP on Win10 and debugging it. But the PHP install seems very complicated, and I realized that before I dug into all that, I should probably ask for help here...so I took the chance.
Well, I'm gratified to learn that my 4-day "learn minimum php by total immersion"(!?!?) project was not all in vain, and at least you have provided evidence of my sanity in my attempted analysis of the code!
Thanks very much for your help, your confirmation of my thought processes is certainly a step forward in that it verifies my studies so far.
I shall continue my research, going onward and upward, never ceasing, always moving forward...etc, etc. blah,blah,blah.
If I have any success, I'll certainly report it.
Seriously, thanks for what you did. At least I know I'm on the right track!
Charlie
-
- Posts: 22
- Joined: Mon Dec 26, 2016 8:58 am
Re: DISASM6 v1.5 - Nes oriented disassembler producing asm6
Umm, GOT IT!
I had to re-read your post twice before I caught what I had been overlooking (being so concentrated on the code and all).
Exactly as you had indicated, I was using the wrong command syntax for user-define labels. You said:
=>>That means disasm6 -l filename not disasm6 -lfilename<==
It never occurred to me that the usage was "space" specific!
Thanks for forcing me to re-re-re-review!
Charlie
I had to re-read your post twice before I caught what I had been overlooking (being so concentrated on the code and all).
Exactly as you had indicated, I was using the wrong command syntax for user-define labels. You said:
=>>That means disasm6 -l filename not disasm6 -lfilename<==
It never occurred to me that the usage was "space" specific!
Thanks for forcing me to re-re-re-review!
Charlie
Re: DISASM6 v1.5 - Nes oriented disassembler producing asm6
Then the program's command line syntax is nonstandard. It's the convention in POSIX (apart from grandfathered tar, find, and dd) that an option either always takes an argument or never takes one. For example, if -l and -f never take an argument, -l -f -i means the same as -lfi. Or if -l always takes an argument, -lfi means -l fi.koitsu wrote:You choosing to exclude the space is a bad habit. Not all argv parsers are going to be able to handle that properly; maybe you wanted -l -f -i shorthand as -lfi for example.
Another way to look at it: If -l something means one thing and -l -f means something else, then how do you pass the name -f as the value of the -l argument?
My first instinct would be to file an issue on the basis of least astonishment. But is there a public bug tracker? Is there even a maintainer?
-
- Posts: 22
- Joined: Mon Dec 26, 2016 8:58 am
Re: DISASM6 v1.5 - Nes oriented disassembler producing asm6
Yup, that's my background also, which is of course why I did it that way. Things like "-x -y -z" operating the same as "-x-y-z", operating the same as "-xyz" were all normal to me.
Anyway, it works great. Thanks to all who have helped me so far.
But, now I am curious. Obviously, NES is a rather (ahem!) legacy system. So maybe progs like DisAsm6 and Asm6 are not so useful anymore, at least not for the general mainstream. But, with there still being available retro consoles, which can take a homebrew cart, and the plethora of emulators across numerous platforms...is there not any interest in updating and expanding progs like these at all? Is it worth moving to, say, C# or VB, and making a Win GUI app out of them? Or maybe something more up-to-date on the graphics/tile/background image generator side? Or is the "dying breed" just further dying?
(Uh, uh, apparently I've been bitten by the Nintendo mini bug!!)
Thanks
Charlie
Anyway, it works great. Thanks to all who have helped me so far.
But, now I am curious. Obviously, NES is a rather (ahem!) legacy system. So maybe progs like DisAsm6 and Asm6 are not so useful anymore, at least not for the general mainstream. But, with there still being available retro consoles, which can take a homebrew cart, and the plethora of emulators across numerous platforms...is there not any interest in updating and expanding progs like these at all? Is it worth moving to, say, C# or VB, and making a Win GUI app out of them? Or maybe something more up-to-date on the graphics/tile/background image generator side? Or is the "dying breed" just further dying?
(Uh, uh, apparently I've been bitten by the Nintendo mini bug!!)
Thanks
Charlie
Re: DISASM6 v1.5 - Nes oriented disassembler producing asm6
Both asm6 and disasm6 are open-source. So when you say "updating or expanding progs like these", you are welcome to do so yourself. Licenses for each:
asm6 (from README.txt):
disasm6: there is none; author says do whatever you want with it as long as he gets credit for the original/base (reference).
asm6 is still heavily used. There are other threads on this board/forum discussing popularity of 65xx assembler suites. Sticking a GUI on front of asm6 would gain you literally nothing. GUIs are not not inherently better-suited for things of this nature -- a debugger is a different situation than an assembler. This is all *horribly* off-topic.
The Wiki maintains a common list of tools; feel free to use whatever works best for you and your needs/situation.
asm6 (from README.txt):
Code: Select all
This is free software. You may use, modify, and / or redistribute any part
of this software in any fashion.
asm6 is still heavily used. There are other threads on this board/forum discussing popularity of 65xx assembler suites. Sticking a GUI on front of asm6 would gain you literally nothing. GUIs are not not inherently better-suited for things of this nature -- a debugger is a different situation than an assembler. This is all *horribly* off-topic.
The Wiki maintains a common list of tools; feel free to use whatever works best for you and your needs/situation.
Re: DISASM6 v1.5 - Nes oriented disassembler producing asm6
I'd recommend making a GUI app that wraps a command-line disassembler. Not everybody uses Windows; at least calima and I use GNU/Linux. And not everybody prefers using a GUI every time, especially people who want to use disasm6 as a step in a build process. If you make the GUI and the actual disassembler separate processes, you can have the GUI display an equivalent command line that the user can copy and paste into a batch file/shell script, a makefile, etc. Then someone can make a ROM hack that is distributed as a difference file and a batch file/shell script that performs steps 2-4 of the following process:charliee1151 wrote:Is it worth moving to, say, C# or VB, and making a Win GUI app out of them?
- Obtain a ROM somewhere, such as by dumping your authentic Game Pak using Kazzo.
- Disassemble.
- Patch the disassembly using the provided diff.
- Re-assemble the patched program.
-
- Posts: 22
- Joined: Mon Dec 26, 2016 8:58 am
Re: DISASM6 v1.5 - Nes oriented disassembler producing asm6
Agree it's off-topic, and I DON'T want to start a discussion here, just get a quick answer. My interest is simply caused by the situation that I don't know PHP (very much evidenced by my previous posts). Had the progs been in VB or C#, I could debugged them much more easily.
Again, just curious.
Thanks, and yes, let's end this topic here.
Charlie
Again, just curious.
Thanks, and yes, let's end this topic here.
Charlie
-
- Posts: 130
- Joined: Mon May 25, 2009 2:20 pm
Re: DISASM6 v1.5 - Nes oriented disassembler producing asm6
Has this program been abandoned permenately ??
I've been using this with megaman 3 alot recently in the past few days to dissassemble and comment the C000-FFFF (fixed bank), and ran into a glitch involving branches that go 7F bytes forward or 80 bytes backward.
In this screenshot i took, the disasm6 did not do this 1 specific branch in megaman 3 correctly:
http://s31.postimg.org/5pk0v34ij/zcsdffd.png - This BEQ #7F which should go to $F0F1 just like the FCEUX debugger shows, however the disasm6 went in the wrong direction to EFF1
So i have to constantly keep changing that to point to a label name 7F bytes forward. But next time i run disasm6 to add more labels to locations, or RAM addresses, it reverts back to that eff1 again which is wrong.
so this was a glitch obviously with disasm6 ..is the author not ever updating this anymore ??
I've been using this with megaman 3 alot recently in the past few days to dissassemble and comment the C000-FFFF (fixed bank), and ran into a glitch involving branches that go 7F bytes forward or 80 bytes backward.
In this screenshot i took, the disasm6 did not do this 1 specific branch in megaman 3 correctly:
http://s31.postimg.org/5pk0v34ij/zcsdffd.png - This BEQ #7F which should go to $F0F1 just like the FCEUX debugger shows, however the disasm6 went in the wrong direction to EFF1
So i have to constantly keep changing that to point to a label name 7F bytes forward. But next time i run disasm6 to add more labels to locations, or RAM addresses, it reverts back to that eff1 again which is wrong.
so this was a glitch obviously with disasm6 ..is the author not ever updating this anymore ??
Re: DISASM6 v1.5 - Nes oriented disassembler producing asm6
Well I doubt you'll see this but you should try running the option -iw or -ignorewrites which ignores writes to $8000 - $FFFFFrankWDoom wrote:So I tried this against a CNROM game and it seems to run into trouble right away:
...
that .hex 85 business is obviously not data- should be STA $15
I tried feeding a CDL from fceux in but that doesn't seem to have any affect.
Is there something else I should be doing? I've also never used the CDL thing so maybe I'm doing that wrong?
I've been running like so: disasm6 "elfland (unl).nes" -cdl "elfland (unl).cdl"
the weird thing is readLabelText was added in 1.5.. in 1.4, readLabels did everything. I'm sure I had a good reason.koitsu wrote: Deeper into the rabbit hole we go, and more abstraction for no justified reason, hooray! The only thing that uses readLabelText() is readLabels(). It's also fantastically super awesomely amazing that the way this works is by passing the ENTIRE FILE CONTENTS as an argument, rather than just handing it a file handle or reference! *cough* So, let's look at that function...
I haven't worked on this in a while but I guess people still use it?! There's even a good bug report up there. I can't promise I'll work on this again but let me know your wish lists now..