A good Snes Disassembler?

Strictly for discussing ZSNES development and for submitting code. You can also join us on IRC at irc.libera.chat in #zsnes.
Please, no requests here.

Moderator: ZSNES Mods

Post Reply
Skeud
New Member
Posts: 4
Joined: Mon Dec 20, 2004 4:50 pm

A good Snes Disassembler?

Post by Skeud »

Hi everybody.
I've found a Nes disassembler which can create almost perfect ASM source, by using a special output file created by another emulator.
(see here and look for SMARTRENES).
In fact, his emulator create a file with informations about the layout of the rom :

Code: Select all

0000,82af,DATA,GLOBAL,
0000,827c,CODE,GLOBAL,
0000,817b,CODE,GLOBAL,
0000,81d3,CODE,GLOBAL,
0000,800a,CODE,GLOBAL,
0000,838a,CODE,GLOBAL,
First is the bank, then it is the offset.
Each time the emulator jump to a subroutine, it writes this information into this file, and each time it loads a data, it does the same.
I was wondering if it was possible to implement such function on a Snes emulator?
Of course, there will be still some 'unknown' area in the rom, but the more you play, the more you'll get :)
byuu

Post by byuu »

Yes, it's possible. The only things it would not be able to grab would be code executed in WRAM, or if someone was sadistic, code that executes differently depending upon p.m/p.x (e.g. lda #$0000 / lda #$00 : brk #$00), which I really doubt even exists.
Now you just need to find someone to implement it in an emulator for you.
FistOfFury
Hazed
Posts: 84
Joined: Wed Aug 25, 2004 1:25 pm

Re: A good Snes Disassembler?

Post by FistOfFury »

Skued, WLA DX is the newest, most actively updated and "best" 65816 assembler (and other cpus) I've found. I remember reading on their forums or the webpage that the creator of WLA DX was planning on working on a dissasembler. I asked him if 65816 support would be in it, and he said of course. But that was a while ago, so I haven't checked to see what's up with the project, if like he started on it, or if he's still planning on doing it. You might want to check their forums, and ask if he can include the stuff your asking about. This is your best bet, I doubt an snes dissasembler will make it into zsnes anytime soon, and any other snes disassembler that is out there is probably really outdated and prob has bad bugs.
http://www.hut.fi/~vhelin/wla.html
byuu

Post by byuu »

As far as assemblers, I have assemblers dedicated to the 65816 and spc700 as well. This makes a huge difference in terms of flexibility when compared to all-in-one table assemblers such as WLA-DX. As one example: being able to declare processor states (p, d, db, etc.) which allow one to generate optimized code automatically. Not possible with a table file.
However, WLA-DX has support for an amazing amount of processors, and if you learn to use the tool on one processor, you can use it for all of them.

As far as disassemblers, an SNES disassembler is not possible. Opcode lengths vary depending upon the status of the processor.
Take the following code: a9 00 a2 ea 1a
This code could be:
lda #$00
ldx #$ea
inc a
Or it could be:
lda #$a200
nop
inc a
Or it could be:
lda #$00
ldx #$1aea

How do you know? You don't. You can guess based on previous opcodes, but you can't guess what opcodes like plp will do to the processor status. Nor can you predict entry / exit points to subroutines.
Anyone writing a straight-up SNES disassembler is wasting their time.

The idea in the thread parent's post was correct, though. If you keep a log of the processor status at each and every opcode encountered, you could then use that log to disassemble the file. The downside is you can only reliably disassemble the parts of code that executed, and you'll probably never be able to execute all code paths no matter how much you play the game, but it's the best you can get for disassembly.
caitsith2
New Member
Posts: 8
Joined: Tue Aug 03, 2004 9:27 am

Post by caitsith2 »

Not only that, some of that data that is defined, will actually be code executed in wram, or the spc700, and there is no reliable way to tell, except to follow a disassembly by hand, and manually add in to the code/data map, and even then, for wram code, you have to specify region, then get the emulator to log the processor status on those bytes for you, spc700, get it to log that area, and find out what actually is spc700 code, and what is data. Straight out disassembly is downright impossible.

Worse, if this code is stored compressed, then you will not even be able to disassemble that block at all.
Skeud
New Member
Posts: 4
Joined: Mon Dec 20, 2004 4:50 pm

Post by Skeud »

caitsith2 wrote:Worse, if this code is stored compressed, then you will not even be able to disassemble that block at all.
But if you have well traced all the code, you can know the way the game decrypt this compressed code.
I know a perfect disassembled code cannot be generated, but it would create more accurate result than a 'dump' disassembler.
If you follow exactly the code, you can fetch the SEP REP sequences and know the size of each opcode.
OptiRoc
Rookie
Posts: 18
Joined: Mon Jan 10, 2005 12:31 am

Post by OptiRoc »

byuusan wrote:As far as assemblers, I have assemblers dedicated to the 65816 and spc700 as well. This makes a huge difference in terms of flexibility when compared to all-in-one table assemblers such as WLA-DX.
That sounded mildly interesting! Would you like to disclose the name(s) and author(s) of those assemblers? I have not been able to find anything to even remotely match WLA, and as happy I am with it I certainly wouldn't mind trying out a new one.
byuu

Post by byuu »

That sounded mildly interesting! Would you like to disclose the name(s) and author(s) of those assemblers?
...I was meaning that I wrote them.

The 65816 one is called xkas, the spc700 one is called spcas. Yes, I put a lot of time into naming them. If you read the documentation with them, you'll see what all they can do. Also, I wouldn't use xas on that page unless you like pain.
You can get both here: http://setsuna.the2d.com/?page=utils
OptiRoc
Rookie
Posts: 18
Joined: Mon Jan 10, 2005 12:31 am

Post by OptiRoc »

byuusan wrote:
That sounded mildly interesting! Would you like to disclose the name(s) and author(s) of those assemblers?
...I was meaning that I wrote them.

The 65816 one is called xkas, the spc700 one is called spcas. Yes, I put a lot of time into naming them. If you read the documentation with them, you'll see what all they can do. Also, I wouldn't use xas on that page unless you like pain.
You can get both here: http://setsuna.the2d.com/?page=utils
Ah, that's some nice work. I saw your work while looking for a better debugging environment some time ago, actually.

That's something of an ongoing project, by the way. Super Sleuth looks kinda nice, not quite what I'm really looking for (that's a ~two year old draft), but it's a nice start. What do you use for debugging?
byuu

Post by byuu »

What do you use for debugging?
This. By now you probably realize that I don't like using other peoples' stuff.
It's pretty lousy though, I've been more focused on accurate emulation than improving the debugger, and it shows.
When that doesn't work, I use ZSNES DOS.

Neat link, by the way. Your 65816 opcode disassembly idea is impossible due to the design of the SNES, though.
OptiRoc
Rookie
Posts: 18
Joined: Mon Jan 10, 2005 12:31 am

Post by OptiRoc »

byuusan wrote:This. By now you probably realize that I don't like using other peoples' stuff.
It's pretty lousy though, I've been more focused on accurate emulation than improving the debugger, and it shows.
When that doesn't work, I use ZSNES DOS.
Looks neat! Since you also rolled your own assembler, have you integrated the two in any way? Like exporting breakpoints from (for example) a special keyword anywhere in the code? That's something I've been missing with the WLA + ZSNES/DOS setup.
byuusan wrote:Neat link, by the way. Your 65816 opcode disassembly idea is impossible due to the design of the SNES, though.
Not quite. By just browsing randomly through memory it wouldn't display anything coherent. It's mainly meant to be used for breaking/stepping though, ie. once you hit a breakpoint you will be thrown to the current instruction. From there it should be no problem displaying succesive instructions, to get a clear view of what's going on while tracing. You have to redo the disassembly for each step, of course.
byuu

Post by byuu »

Looks neat! Since you also rolled your own assembler, have you integrated the two in any way? Like exporting breakpoints from (for example) a special keyword anywhere in the code? That's something I've been missing with the WLA + ZSNES/DOS setup.
No. Adding custom exports that the emulator recognizes would break my original goal of exact (as I can get) hardware emulation.
You can use 'print pc' in xkas to get the PC location, then add the breakpoint when the emulator starts.
I also plan to add import/export to the breakpoint list so you can save/load it. I suppose I could make xkas export a breakpoint list that's compatible with it, but I don't see the need.
From there it should be no problem displaying succesive instructions, to get a clear view of what's going on while tracing.
Not really. You'd have to emulate all the instructions ahead of you first, and there's no guarantee the code path is linear (what if you hit a jmp, and then immediately after that, the code assumes a different A/X size?)

Oh, also the tile viewer wouldn't work. You can't predict the palettes used for each tile. You could pull the ones that are displayed on-screen, but not all tiles are always onscreen, and palettes can change. You'd need a palette selection thing on there as well.
OAM view would need to take into account that for each OAM size, there are two different sizes.
If $2101 = %01100000, then there can be 16x16 or 32x32 sprites in the same space. If you're just showing one OAM sprite at a time, I don't see why there's the need to draw it 28 times.
Sorry to nitpick, I realize they're just mock-up pictures, at any rate :)
OptiRoc
Rookie
Posts: 18
Joined: Mon Jan 10, 2005 12:31 am

Post by OptiRoc »

byuusan wrote:No. Adding custom exports that the emulator recognizes would break my original goal of exact (as I can get) hardware emulation.
How is that? One obvious route is to let the assembler export a symbol table that also includes breakpoints, which the emulator then imports (including labels and breakpoints in applicable data structures).
byuusan wrote:
From there it should be no problem displaying succesive instructions, to get a clear view of what's going on while tracing.
Not really. You'd have to emulate all the instructions ahead of you first, and there's no guarantee the code path is linear (what if you hit a jmp, and then immediately after that, the code assumes a different A/X size?)
There would be garbage (temporarily interpreted as a "data" block) displayed after the "jmp", in case the disassembler can't decode any sensible instructions with the current register settings. What lies beneath an unconditional jump shouldn't be too interesting anyway, I reckon.
byuusan wrote:Oh, also the tile viewer wouldn't work. [. . .]
Sorry to nitpick, I realize they're just mock-up pictures, at any rate :)
That's alright, however all those details are actually taken care of in the mock-ups. So, anyway, I suppose I have to write my own emulator to get satisfied. :twisted:
Post Reply