It is currently Sun Sep 24, 2017 5:08 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 116 posts ]  Go to page Previous  1 ... 4, 5, 6, 7, 8
Author Message
PostPosted: Tue Dec 27, 2016 5:25 pm 
Offline

Joined: Mon Dec 26, 2016 8:58 am
Posts: 17
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


Top
 Profile  
 
PostPosted: Mon Jan 16, 2017 5:21 pm 
Offline

Joined: Mon Dec 26, 2016 8:58 am
Posts: 17
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


Top
 Profile  
 
PostPosted: Mon Jan 16, 2017 8:39 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 3192
Location: Mountain View, CA, USA
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?

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:

Code:
   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]

That means disasm6 -l filename not disasm6 -lfilename. 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. See my point? So going forward, comply with the usage syntax. This may or may not be your problem; let's assume it isn't and continue on.

Code:
$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;

Okay, so we can see here that $labelFile is probably getting set to the filename passed as an argument. So what uses this variable?

Code:
$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;

}

Okay, so from this we can see that readLabels() is what ideally does the parsing of the file. Let's look at that.

Code:
function readLabels($filename)
{

   $arr = readLabelText(file_get_contents($filename));
   
   return $arr;
   

}

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...

Code:
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;
}

Now we're into it. The first thing you can see is how there's absolutely no error checking or emission of errors -- if your label file doesn't match the preg_match_all(), then it silently says nothing. Very user-friendly!

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:
mylabel = $abc0
otherlabel = 12345

In this case, $matches[0][0] would contain mylabel, $matches[1][0] would contain $ (address base designation, hex in this case), and $matches[2][0] would contain abc0.

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:
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;

}

Looks to me like label = $address.

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...


Top
 Profile  
 
PostPosted: Tue Jan 17, 2017 5:38 am 
Offline

Joined: Mon Dec 26, 2016 8:58 am
Posts: 17
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


Top
 Profile  
 
PostPosted: Tue Jan 17, 2017 9:19 am 
Offline

Joined: Mon Dec 26, 2016 8:58 am
Posts: 17
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


Top
 Profile  
 
PostPosted: Tue Jan 17, 2017 10:05 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19004
Location: NE Indiana, USA (NTSC)
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.

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.

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?


Top
 Profile  
 
PostPosted: Tue Jan 17, 2017 4:08 pm 
Offline

Joined: Mon Dec 26, 2016 8:58 am
Posts: 17
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


Top
 Profile  
 
PostPosted: Tue Jan 17, 2017 4:24 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 3192
Location: Mountain View, CA, USA
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):
Code:
This is free software.  You may use, modify, and / or redistribute any part
of this software in any fashion.

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.


Top
 Profile  
 
PostPosted: Tue Jan 17, 2017 5:45 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19004
Location: NE Indiana, USA (NTSC)
charliee1151 wrote:
Is it worth moving to, say, C# or VB, and making a Win GUI app out of them?

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:

  1. Obtain a ROM somewhere, such as by dumping your authentic Game Pak using Kazzo.
  2. Disassemble.
  3. Patch the disassembly using the provided diff.
  4. Re-assemble the patched program.


Top
 Profile  
 
PostPosted: Wed Jan 18, 2017 6:03 am 
Offline

Joined: Mon Dec 26, 2016 8:58 am
Posts: 17
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


Top
 Profile  
 
PostPosted: Fri Feb 24, 2017 2:55 pm 
Offline

Joined: Mon May 25, 2009 2:20 pm
Posts: 27
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 ??


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 116 posts ]  Go to page Previous  1 ... 4, 5, 6, 7, 8

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 9 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group