DISASM6 v1.5 Nes-oriented disassembler producing reassemblable asm6 code

Started by frantik, February 12, 2011, 12:50:14 AM

Previous topic - Next topic

frantik

DASM6 is a multi-pass NES-oriented disassembler which produces ASM6 code.


Features:
* produces instantly re-assemblable code (without any human modification)
* iNES header support
* Can export CHR-ROM
* can use optional NES registers
* can use custom defined labels
* can use FCEUDX code/data logs


The output can be reassembled using ASM6.  I've tested it with a handful of roms and so far every mapper 0 rom has assembled into a 1:1 copy of the original. For 16k games that have 2 copies in in the .nes file, it will tweak the iNes header from 2 prg banks to 1 unless you disable 16k checking

Download Dasm6 v1.5
Example output

Please let  me know about any bugs and any suggestions you have. 

Some future ideas:
* may add  support for mappers

Windows EXE and PHP source included


frantik

here's version 1.4

changes in this version include

* option for lowercase opcodes
* options for processing arbitrary portions of the rom, either by file location or code location. 
* all numeric parameters accept decimal, $hex, 0xhex and %binary forms
* Custom labels ending with "RTSTable" will be interpreted as RTS jump tables.  (For any jump table stuff to work you also have to be using a CDL)
* Improved handling of relative labels (eg SomeLabel+1)
* fixed bugs

I'm planning on adding support for TableLow/TableHigh stuff in the next version

oh yeah i changed the name to DISASM6 cause i thought DASM was a generic term for disassembler, but apparently its not. I googled and there is an assembler called DASM and one called ASM6 so this should make it more clear this is a DISassembler, not an assembler.

ThVortex

Hey, are you still maintaining your disasm6 written in PHP? I made a few minor improvements to v1.4 and I'm including them in here as a patch file. All the changes have to do with handling transitions between code and data in the .cdl file. The changes are:

1. If a location is marked as both code and data in the .cdl file, then it should be treated as code (right now it's treated as data). This can happen when writing PRG-ROM to setup the mappers. For example, the North American Tetris uses "INC $8000" to reset the MMC1 mapper, but location $8000 contains valid code as well.

2. When something is decoded as hex data, disasm6 automatically reads 4 bytes at a time without checking ahead in the cdl to see if any bytes are marked as code. Once again in Tetris there are cases where a "JSR" is immediately followed by two data bytes which are a pointer for the subroutine to read. The subroutine then returns two bytes after the pointer, so the raw bytes in the .cdl file are: code code data data code code ...". Right now, disasm6 will decode all four "data data code code" bytes as if they were data only. The logic I added to handle this is in the same loop that already checks for a label somewhere in the middle of those 4 bytes which would correctly cause us to read less than 4 bytes for this line of output.

3. When using one of the "JumpTable" or "RTSTable" labels, disasm6 starts to decode all data as table pointers until it encounters some user defined label. With my patch, the first byte marked as code will also end the decoding of the table. Otherwise, for each jump/RTS table you would need to manually add a dummy label to stop decoding any further.

Spoiler

--- a/disasm6.php
+++ b/disasm6.php
@@ -1238,7 +1238,7 @@ while ($pass <= $lastPass)


          // data byte
-         if (($cdlByte & bindec('00000010')) >> 1)
+         if (($cdlByte & bindec('00000011')) == bindec('00000010'))
          {

             $counter_pad = dechex_pad($counter);
@@ -1298,6 +1298,12 @@ while ($pass <= $lastPass)
             $isDataByte  = true;
             $dataStr = 'Data';
          }
+
+         // code byte ends table
+         else
+         {
+            $theOldLabel = '';
+         }
       }


@@ -1315,6 +1321,11 @@ while ($pass <= $lastPass)
       {
          if ($pass >= 1)
          {
+            if ($cdlFilename !== false)
+            {
+               $cdlPos = ftell($cdlFile);
+            }
+
             // check to see if a label exists in this opcode.. if so then usually it's data
             for ($i = 1; $i <= $readBytes; $i++)
             {
@@ -1334,6 +1345,27 @@ while ($pass <= $lastPass)
                   $addressingType = -1;
                   continue;
                }
+
+               // if this byte marked as data in cdl; check if next bytes are code
+               if ($cdlFilename !== false && $isDataByte)
+               {
+                  $newCdlByte = ord(fread($cdlFile, 1));
+
+                  if ($newCdlByte & bindec('00000001'))
+                  {
+                     $invalidCounter = 0;
+                     $readBytes =  $i - 1;
+                     $isInvalid = 1;
+                     $byteLen = $i;
+                     $addressingType = -1;
+                     continue;
+                  }
+               }
+            }
+
+            if ($cdlFilename !== false)
+            {
+               fseek($cdlFile, $cdlPos);
             }
          }
[close]

cret

go r2, use debug. .... White hand was fainted

ThVortex

You mean an instruction set reference for the 6502 processor that NES uses? I mostly use http://www.obelisk.demon.co.uk/6502/

cret

go r2, use debug. .... White hand was fainted

frantik

Blew the dust off this old code and decided to share it

Here is version 1.5

* incorporates the changes suggested by ThVortex
* corrects the uc bug pointed out by mkmr
* option to stop writes to PRG from creating labels
* option to enable (experimental) mapper 2 support
* disabled the code handling the "branch out of range" bug

Please let me know if you find any bugs

w7n


frantik


dougeff

It took me a while to figure out how to use disasm6, since there is no documentation. But I got it to work well, and here's how...

Run the .nes file in FCEUX, run the code/data logger as much as you can, save the .cdl file

In command prompt, open the folder, (have all files and disasm6 in folder), type...
>disasm6 file.nes -cdl file.cdl

Then open the .asm file in Wordpad, not Notepad (as I prefer to use). Save it.
Assembles great.

also, if you just type...
>disasm6
it gives you a list of options, that you type similar to how I did it earlier with -cdl.
nesdoug.com -- blog/tutorial on programming for the NES

tygerbug


ThVortex

You can still download it from the Wayback Machine:

https://web.archive.org/web/20160327230457/http://swiftlytilting.com/files/disasm6-1.5.zip

tygerbug

  I have downloaded it. It gives me a file not found error when I attempt to run the program.