This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

DISASM6 v1.5 - Nes oriented disassembler producing asm6 code

DISASM6 v1.5 - Nes oriented disassembler producing asm6 code
by on (#73719)
DISASM6 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

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

example output
Re: DASM6 - Nes oriented disassembler producing asm6 code
by on (#73721)
frantik wrote:
... it's a 2 pass 6502 disassemler written in PHP


Image

by on (#73723)
While a disassembler is cool, I too am bemused by the choice of PHP. I suppose if that is all that you know, then fine. I am reminded of a quote that I'm totally going to screw up: "If you only have a hammer, then every problem is a nail" (or something).

And I say the above half jokingly. You've produced working code, and decided to share it with everyone. That is far more than most people have done. I congratulate you on your accomplishment, even if I snicker at PHP itself. Just don't port it to COBOL, FORTRAN or JCL, ok? ;)

Side-note: The core engine for "cacti" is written in PHP (web page + batch processing scripts).

What would be really awesome is if you could identify, via static code analysis, code from data. I can think of several heuristics for this.

I once worked on a static code analyzer for intelligently disassembling NES roms. It would start with each of the three interrupt vectors and trace all possible code execution paths. I then realized that I had bitten off more than I wanted to when I needed to handle constructs like this:

Code:
tay
lda some_tbl_msb, y
pha
lda some_tbl_lsb, y
pha
php
rti


But if you could nail stuff like that, it would be TOTALLY AWESOME.

by on (#73728)
wow, who would expect people who program for an ancient and obsolete processor would make fun of someone else for their choice of programming languages. ... snip ...

by on (#73729)
frantik wrote:
wow, who would expect people who program for an ancient and obsolete processor would make fun of someone else for their choice of programming languages. fucking idiots



Lol, we might program for an ancient processor, but can YOU handle the challenge? NES compiler version, please!

by on (#73730)
3gengames wrote:
Lol, we might program for an ancient processor, but can YOU handle the challenge? NES compiler version, please!


yeah, i'll leave that up to you (though i do also write 6502 asm)

by on (#73731)
frantik wrote:
3gengames wrote:
Lol, we might program for an ancient processor, but can YOU handle the challenge? NES compiler version, please!


yeah, i'll leave that up to you (though i do also write 6502 asm)


As if PHP were more powerful then 6502? Hahaha!

by on (#73732)
anyways, on topic

clueless wrote:
What would be really awesome is if you could identify, via static code analysis, code from data. I can think of several heuristics for this.


yes that would be cool but i think beyond the scope of this disassembler

besides, i dont think it would be very effective at finding small bits of data in bit blocks of program code. finding big blocks of data isn't hard because there are lots of invalid opcodes

it might not hurt to make 2 kinds of labels though.. ones used by LDA/X/Y and ones used by JMP/JSR. then it would be even more obvious where data is and where program code is

the main thing i want to do right now is make sure all labels which are referenced actually exist in the program code so that the output can immediately be reassembled without any modification

by on (#73734)
I take it that one of your goals is that a re-assmbled NES file should be identical to the one disassembled? If so, you could stress test this by writing a small program to generate totally random NES roms (with valid ines header). Then automate the disassembly and reassembly of the image, and compare the MD5 checksums. If a test fails, set the original ROM aside for later analysis.

Would be even cooler if your randomly generated ROMs used a byte distribution that is typical of most NES games.

Do you have a fairly large corpus of ROM images to test with already?

And the FORTRAN thing.. I'm sorry if I touched a nerve. I was just teasing (just a little). I've had far worse. Sivak told me that my game sucked. Period. :( The guys at work make fun of me for using C, C++ and Perl. Yet my code can run circles around their fancy java frameworks. Doesn't stop them from being dicks about it though. I'm sorry if I was a dick to you. I didn't intend to be.

by on (#73735)
clueless wrote:
I'm sorry if I was a dick to you. I didn't intend to be.


it's all good.. i had literally just woken up lol so i was a lil bitchy.. it was more the combination of the facepalm and your post.. but it's all good :)


and yeah the object is to create an assembly file that generates identical output as the original file. i haven't gotten to that point yet though.. but asm6 doesn't generate any errors besides missing labels so thats good

by on (#73736)
I'm sometimes astounded by the negativity that is thrown about on these forums.

But anyhow your disassembler looks cool. I program in PHP quite often, and though it is a bit of a retarded beast, some cool stuff can be done with it. If you're a good programmer, that's all that matters.

by on (#73739)
clueless wrote:
What would be really awesome is if you could identify, via static code analysis, code from data. I can think of several heuristics for this.

Also maybe think about emulator assisted disassembly. FCEUX can make code/data logs already.

E: Wohoo 400th post...

E2: Also forgot to say: nice work OP.

by on (#73742)
thefox wrote:
clueless wrote:
What would be really awesome is if you could identify, via static code analysis, code from data. I can think of several heuristics for this.

Also maybe think about emulator assisted disassembly. FCEUX can make code/data logs already.


Yup, and that was instrumental in my reverse engineering of Crystalis back in 2001 or so. However, a complete disassembly requires playing the game such that you access every memory location, or create a TAS that does the same.

by on (#73743)
thefox wrote:
clueless wrote:
What would be really awesome is if you could identify, via static code analysis, code from data. I can think of several heuristics for this.

Also maybe think about emulator assisted disassembly. FCEUX can make code/data logs already.


hmm good point.. i will see if i can incorporate those somehow :)

by on (#73749)
frantik wrote:
thefox wrote:
clueless wrote:
What would be really awesome is if you could identify, via static code analysis, code from data. I can think of several heuristics for this.

Also maybe think about emulator assisted disassembly. FCEUX can make code/data logs already.


hmm good point.. i will see if i can incorporate those somehow :)


Yes...but....what about bankswitching? JSR to $c039 might mean "jump into this pile of data" if the disassembler doesn't know that the code it just disassembled prior to this caused the MMC1 to swap the high bank. ?

Now...disassembly aided by a code/data log file generated by a run of the ROM in an emulator like FCEUX or NESICIDE...that is not static, but accurate. In fact, isn't that what people most often use to rip NSFs?

by on (#73752)
What you folks are now talking about is already accomplished using IDA Pro. It does have 6502 support, and can deal with the situations as described in the latter part of the thread.

by on (#73758)
NESICIDE wrote:
Yes...but....what about bankswitching?


well right now mappers are supported at all anyways
How high can Fortran RICH?
by on (#73766)
clueless wrote:
And the FORTRAN thing.. I'm sorry if I touched a nerve. I was just teasing (just a little).

With the Fortran comment, I was almost expecting someone to pull out PUSH START TO RICH. Is Dian Shi Mali part of the corpus?

cartlemmy wrote:
I'm sometimes astounded by the negativity that is thrown about on these forums.

Don't be astounded; it's expected. Normal person + pseudonymity + audience = dick (NSFW language).

koitsu wrote:
IDA Pro

Who's buying? Linus Torvalds originally wrote Linux in part so that he wouldn't have to pay for Unix.

by on (#73770)
You know, I've had that Mario Lottery rom forever, and never had the "PUSH START TO RICH" event happen. I'm surprised that it spontaneously became a meme, just like Cheetahmen.

by on (#73822)
I got it to create all labels, but now i've run into a new problem.. it seems ASM6 forces ZP mode for things such as AND $0023,x .. in the original code it's 3D 23 00 but after using ASM6 it generates 35 23, basically the same thing as AND $23,x

is there a way to avoid using ZP mode in ASM6?

edit: heh looks like i'm not the 1st person to experience this

by on (#73831)
frantik wrote:
is there a way to avoid using ZP mode in ASM6?


This looks like a bug in asm6. Some people might argue it's a "funny way of doing auto-optimisation", but I disagree.

The parser appears to turn 16-bit absolute addresses with a high byte of zero ($00) into ZP. The assembler does use the correct opcode for the ZP mode, but that isn't what the user wants.

I also confirmed that tricks like "LDA $00ff+0" and "LDA 0+$00ff" do not work around the bug. Parens don't help either.

Loopy et al, can you comment on this?

by on (#73834)
i looked at the asm6 code but it wasn't immediately apparent where it selects between ZP vs Absolute

for now i treated it similarly to invalid opcodes and just spit out .hex 3D 23 00.. most of the time it's actually data that is causing it anyways

by on (#73836)
It (asm6) seems to do this with any absolute addressing mode (including indexed ones) where a 16-bit value is provided and the high byte is $00. So you'll need to use .DB workarounds for all the opcodes that have that addressing mode. I haven't checked things like JMP ($00FF) yet, but you can do so by writing the code and using "asm6 -l blah.asm", then looking at "blah.lst" to see what gets generated.

by on (#73837)
JMP ($00XX) does not seem to affected

finishing up some changes.. it's now a FOUR pass disassembler but it produces code which can be immediately re-assembled into an identical copy of the original, so i got that going for me

by on (#73839)
Here's how I understand it working in assemblers such as ASM6 and ca65: The values $23, $0023, and 35 all get turned into the same data type (integer). If the assembler can determine that the integer is smaller than $100 at compile time, it emits a zero page instruction; otherwise, it emits an absolute instruction. Why would you want to force absolute indexed over zero page indexed addressing, except A. to join the end of zero page with the beginning of the stack, or B. to program the Super NES (with its movable zero page) instead of the NES?

(Rereading) You mean C. to make NESASM-assembled code round-trippable, as NESASM treats all addresses as absolute unless forced with a zero page operator.

EDIT: For that you need whatever counterpart ASM6 has to ca65's a: address size modifier, which forces 16-bit addressing.

by on (#73842)
Maybe just create macros for the 16-bit instructions, and emit instances of them instead of the real instructions when you encounter a 16-bit instruction with an 8-bit value.

by on (#73843)
tepples wrote:
(Rereading) You mean C. to make NESASM-assembled code round-trippable, as NESASM treats all addresses as absolute unless forced with a zero page operator.


it's to make all code "round-trippable".. i just used .hex instead, though it would be nice if ASM6 allowed a way to force it to use the specific opcode that is implied by the code.

by on (#73844)
This is a bit ironic, as some Japanese recently released a hacked version of NESASM, that you can force it to have the same behaviour as ASM6 when the -autozp option is used.

I now think about it though, apart from the other problematic quirks of NESASM, due to its origin as PCEAS, the "non-auto zero page" aspect of it was actually mandatory, since ZP for the PCE is located at $2000, so if you somehow want to code for both systems, especially when you want to reuse portions of codes in projects for both platforms, it will always be a good practice to manually specify when ZP addressing has to be used.

by on (#73849)
And ZP for the 8080 derivative in the Game Boy is at $FF00. Both of these cases resemble the Super NES case.

by on (#73874)
i updated the disassembler to version 1.1.. updated the first post but here is the link:

Download Dasm6 v1.1

it's now a multi-pass disassembler, usually taking between 4-5 passes for the labels to "stabilize", with an add'l pass needed to generate the output. you can specify how many passes you want with -p or -passes, or just let it run its course.

i've not tested it with a ton of roms but 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

If you use the new -c or -chr option it will export the CHR data and include it from the assembly file so you can instantly check if the disassembly is valid. The -r or -registers option aliases the common nes registers with their text names instead of their memory addresses.

next i want to add support for custom external memory location/label names (should be easy) and also support the data/code mapping from fceudx.. the code mapping also tells you which bank the code was loaded in so that might be essential for automatic disassembly of more complex roms.

by on (#73875)
Tepples is right. Whether you enter 6, $6, $06, $0006, or $000000006, asm6 sees it as just a number. If it's <256, a ZP instruction is emitted. I'm open to the idea of having a forced absolute address. Any suggestions on syntax?

Until something is implemented, making a macro is an easy workaround (as Dwedit already suggested)

by on (#73876)
the most intuitive way would be if it's something like LDA $00FF it uses absolute but if it's LDA $FF then use ZP.

if it has to be some kind of special syntax, maybe quote marks? to say, "yes i really mean this!!"

LDA "$00FF"

but i think being able to leave them out would make more sense.. perhaps some kind of directive to enable/disable the mode?

it's not something the average programmer needs to worry about but for disassembling it would be nice to represent all valid lines of code without resorting to hex/db/etc

or maybe something like

LDA word($00FF)
LDA byte($00FF)

to force ZP or ABS


(btw for those who missed it at the bottom of page 2 i updated the code :))

by on (#73877)
frantik wrote:
the most intuitive way would be if it's something like LDA $00FF it uses absolute but if it's LDA $FF then use ZP.

Remember that unlike disassembled code, normal programs rarely (ideally, never) use explicit addresses, they use labels, so this is not an option.

I'm not sure what the best solution is... Some assemblers use something like "LDA.W Variable" for this, don't they? It looks weird though, since with the 6502 this is really the only case where you'd ever want to force an addressing mode or the other. I would like this feature, but I have no idea about the best syntax.

In my own programs I usually .db the opcode and then .dw the label (and put the actual instruction as a comment), or I add $800 to the address in order to use a mirror or ZP at $800-$8FF (this would definitely not be OK in a disassembly).

by on (#73879)
tokumaru wrote:
frantik wrote:
the most intuitive way would be if it's something like LDA $00FF it uses absolute but if it's LDA $FF then use ZP.

Remember that unlike disassembled code, normal programs rarely (ideally, never) use explicit addresses, they use labels, so this is not an option.


yeah it would only work with explicit values not labels.. some kind of way to force word/byte seems like the next best option.. either

LDA.W label
LDA word(label)

seem to make the most sense. i kinda like the 2nd one better myself

by on (#73880)
If you change behavior to treat $00ff to be read as ABS And $ff to be read as ZP, wouldn't that break existing compatibility with the assembler projects?

Why not a switch at the start of the source file, to tell the assembler how to treat addressing modes and labels/values. And there's already symbol mechanism for selecting high/low byte of a word or label, right?

by on (#73881)
Maybe an -optimizezp switch would help? or maybe something inside the assembler, assuming optimizing ZP instructions, and when it's not wanted/needed some thing like .nozpoptimize flag inside the assembler?


Just my ideas, nice to see this being added! :D

by on (#73884)
added initial support for fceudx data/code maps.. actually pretty cool :D.. working on other changes too and will release the new version later

by on (#73886)
loopy wrote:
Tepples is right. Whether you enter 6, $6, $06, $0006, or $000000006, asm6 sees it as just a number. If it's <256, a ZP instruction is emitted. I'm open to the idea of having a forced absolute address. Any suggestions on syntax?

Until something is implemented, making a macro is an easy workaround (as Dwedit already suggested)

asm6 is trying to do code optimisation without the programmer's consent. This is, for lack of better word, inappropriate.

Let me make it crystal clear so there's no misunderstandings:

* If someone types "LDA $00FF", the assembled result should be AD FF 00.
* If someone types "LDA $FF", the assembled result should be A5 FF.
* If someone types "label EQU $00FF" and "LDA label", the assembled result should be AD FF 00.
* If someone types "label EQU $FF" and "LDA label", the assembled result should be A5 FF.

This is how all classic Apple II assemblers (Merlin 8, Merlin 16, and ORCA/M) did it. The reason it was done that way: assembly code, when written by a person, by nature should be KISS -- that is to say, the assembler should not try to do "smart things" without the programmer's prior consent. Nobody is going to get me to bend on this one, period. Assembly is a different beast than higher level languages.

If you truly disagree with this, then there's a logical alternative: add a flag (proposals: -O (dash capital oh, a la cc/gcc), -fXXX (a la gcc), or -optimizezp (but please support -optimisezp for those of us who spell normally ;) )) which enables such optimisations. Without the flag, it should behave like I described above. And please be sure to explain in the README what the flag does/affects.

by on (#73893)
loopy wrote:
Tepples is right. Whether you enter 6, $6, $06, $0006, or $000000006, asm6 sees it as just a number. If it's <256, a ZP instruction is emitted. I'm open to the idea of having a forced absolute address. Any suggestions on syntax?

A 65816-inspired suggestion:
Code:
lda $00FF,d  ; generates zero page
lda $00FF,b  ; generates absolute

The reason for the names 'D' and 'B' becomes clear when you consider how these instructions operate on a 65816: address,d is an 8-bit offset from D (direct page base pointer, frozen at 0 on 6502; compare TAD instruction), and address,b is a 16-bit offset from B (data bank base pointer; compare PLB instruction). A directive would switch between ,d and ,b being the default for labels less than $100.

And if you extend this 65816 analogy, setting the CPU type to 65816 would unlock another syntax:
Code:
lda far $00FF  ; generates long absolute

Thus 'jmp far' and 'jsr far' would become synonyms for 'jml' and 'jsl'.

I don't like frantik's suggestion of .W, as it too closely resembles the syntax for data size, not address size, in 68K (MOVE.W) and ARM (LDRH, LDRB) assembly language.

koitsu wrote:
* If someone types "LDA $00FF", the assembled result should be AD FF 00.
* If someone types "LDA $FF", the assembled result should be A5 FF.
[...]
This is how all classic Apple II assemblers (Merlin 8, Merlin 16, and ORCA/M) did it.

As I understand it, the mini-assemblers in Integer BASIC, the enhanced IIe monitor, and the IIGS monitor acted this way, but only because they didn't support labels or decimal numbers. How would the assembler treat decimal labels (e.g. label EQU 120)?

Quote:
* If someone types "label EQU $00FF" and "LDA label", the assembled result should be AD FF 00.
* If someone types "label EQU $FF" and "LDA label", the assembled result should be A5 FF.

So you're choosing a data type for the label based on the length of the constant's literal value. That sort of resembles the distinction between near and far pointers on 8086. How would it treat computed labels (e.g. label EQU somebase + someoffset)?

by on (#73894)
koitsu wrote:
* If someone types "label EQU $00FF" and "LDA label", the assembled result should be AD FF 00.
* If someone types "label EQU $FF" and "LDA label", the assembled result should be A5 FF.

There are much better ways to declare variables than using EQU. I always use ENUM and DSB for that, so that rearranging them in the future doesn't require changing a shitload of EQUs. Also, I might want to access a certain variable using ZP addressing most of the time, but in a timed section of my code I might need to access it a bit slower. Your solution doesn't work for these cases.

IMO, the addressing mode shouldn't be decided based on the declaration at all. Using EQU to declare variables is not considered a good practice anymore, and there might be the need to access the same variable using different addressing modes. This selection should be made on an instruction-per-instruction basis, and it should be possible to select a default behavior.

by on (#73898)
tepples wrote:
I don't like frantik's suggestion of .W, as it too closely resembles the syntax for data size, not address size, in 68K (MOVE.W) and ARM (LDRH, LDRB) assembly language.


tokumaru mentioned it :-p

by on (#73900)
Regarding how older assemblers like Merlin 8/16 and ORCA/M did it: they both differ in methodology, and it turns out my memory has failed me once again. People aren't going to like the Merlin 8/16 method, believe me (and I don't approve of it either, but it's how it worked). I'll document both for everyone's sake.

Merlin 8/16 (quoting the manual):

Quote:
There is no difference in syntax for zero page and absolute modes. The assembler automatically uses zero page mode when appropriate. Merlin 8/16 provides the ability to force non-zero page addressing. The way to do this is to add anything except D in Merlin 8, or L in Merlin 16, to the end of the opcode. Example:

LDA $10 assembles as zero page (2 bytes: A5 10)

while,

LDA: $10 assembles as non-zero page (3 bytes: AD 10 00)


Also, in the indexed indirect modes, only a zero page expression is allowed, and the assembler will give an error message if the "expr" does not evaluate to a zero page address.

...

Merlin 8/16 will decide the legality of the addressing mode for any given opcode.


Be sure to note the colon in "LDA:" above. You could literally say "LDAX $10" and accomplish the same thing. When the manual says "add anything", they mean "add any character of your choice". Yup, you read that correctly. And please don't start aspie'ing over what the assembler would do with something like "LDA:" (is that a label or an opcode, etc...). The simple answer is: Don't Do That(tm).

I'll provide ORCA/M details later, I'll need to go down to the garage and dig through boxes to find the manual. Expect me to edit this post once I find it.

by on (#73901)
i generally agree with koitsu that if a label is defined as a word, it should be treated as a word...

Label_00FF = $00FF
enum $A0
Label_00A0 .word 0000
enum
Label_00C0 EQU $00C0

all of the above should be treated as non-ZP


if that's not possible, something like this makes sense to me, but it's not really asm friendly

LDA word(label)
LDA byte($00FF)

or maybe just

LDA .word label


btw i might make sense to split the topic since most of the discussion is about asm6, no dasm6 :D

by on (#73908)
Quote:
LDA word(label)
LDA byte($00FF)


Ouu :3 I like that

Reminds me of lda high(label or address or whatever) or lda low( same ) in PCEAS (NESASM too, right?). Looks more natural than appending .b or.w which is more 68k style of assembler syntax.

by on (#73909)
released v1.2 which adds support for FCEUDX code/data logs and user definable labels.

i guess now i have to start looking into how to handle mappers :\


to define labels use the format

label = $0000

comments starting with a semicolon and invalid lines are ignored. Decimal (no modifier), hex ($) and binary (%) supported

by on (#73915)
- My $0.02 if that matter... :) In my CPU emulator, I use a syntax that helps me to identify the opcode and its addressing mode. In short words, it's opcode string + addressing mode number. So, you have LDA1, STA1 or LDA6 etc..

by on (#73919)
a suggestion with this program, frantik:

add an NSF disassembler, as an option or as a seperate program with at least minimal-to-no bankswitching support!

see the NSF file format on the wiki for more info:
http://wiki.nesdev.com/w/index.php/NSF

but is a great tool otherwise, should be a good FREE alternative even if it isn't portable!

by on (#73920)
Hamtaro126 wrote:
even if it isn't portable!


it's "portable" in the sense that it can be used on any major OS.. though for mac/linux you will have to install PHP first. just think of it as a "dependency" ;)

the windows EXE in the zip file is mostly the PHP interpreter with the script packed inside of it.. it's possible to do the same thing with a unix executable, just no one has done it

actually.. it would be super trivial to make a web-based form for this so i might do that as well.. then it can even be used on CromeOS :D


btw, check out the output of excitebike.. i used a code/data log that was 94% complete as well as a couple dozen user defined labels. i think the disasm looks pretty nice :D when using the c/d logs, if an unknown area is encountered, it just assumes that it's probably the same type as the previous byte, unless the address is a known program code label created by a jump or branch. using this method, you don't have to have 100% complete logs to generate good output

this tool should really simplify the initial stages of creating completely documented disassemblies like doppleganger's SMB disassembly

by on (#73963)
Minor change (my OCD is kicking in):

Code:
;-------------------------------------------------------------------------------
; break vector
;-------------------------------------------------------------------------------
break:      .hex 83 00         ; $fff0: 83 00     Invalid Opcode - SAX ($00,x)
            .hex 04 14         ; $fff2: 04 14     Invalid Opcode - NOP JoyMirrorGame
            .hex 04 14         ; $fff4: 04 14     Invalid Opcode - NOP JoyMirrorGame
            .hex 04 14         ; $fff6: 04 14     Invalid Opcode - NOP JoyMirrorGame
            .hex 04 d4         ; $fff8: 04 d4     Invalid Opcode - NOP $d4

;-------------------------------------------------------------------------------
; Vector Table
;-------------------------------------------------------------------------------
vectors:    .dw nmi            ; $fffa: 3b c2     Vector table
            .dw reset          ; $fffc: 84 c1     Vector table
            .dw break          ; $fffe: f0 ff     Vector table


This is technically the IRQ/BRK vector. Most games would use this for hardware IRQs. Naming it "break" and "break vector" is a bit misleading. Possibly naming the label "irqbrk" and the comment as "IRQ/BRK vector" would be better?

by on (#73964)
ok, thanks, i'll change it :) any other "OCD" stuff like that is very welcome!

by on (#74289)
made some changes, mostly to do with how the output is displayed, but one cool thing is support for jump tables.. if a user defined label ends with "JumpTable" then all of the following pairs of bytes are assumed to be labels (until the next label is encountered)

Version 1.3

and again, the RAW output of excitebike from the program (using a code data log and fair amount of user defined memory and PRG labels, .. i've been disassembling excitebike for a bit now )

by on (#74291)
Nice idea. Would it be too hard to add support for labels starting with RTSTable, where the following two-byte values are assumed to be one less than a label?

by on (#74303)
tepples wrote:
Nice idea. Would it be too hard to add support for labels starting with RTSTable, where the following two-byte values are assumed to be one less than a label?


good suggestion :D.. i was already planning on adding support for pointer tables (where all the low bytes are listed first then the high bytes) but RTSTable sounds like a good idea too

btw can you name an example of a Mapper 0 game which uses RTS Tables?

by on (#74305)
Code:
            .hex b9 88 00                    ; $e45f: b9 88 00  Bad Addr Mode - LDA $0088,y


Why can't it specify LDA $0088,Y? The Zero Page,Y form of this instruction does not exist, so there's no conflict.

by on (#74306)
Dwedit wrote:
Code:
            .hex b9 88 00                    ; $e45f: b9 88 00  Bad Addr Mode - LDA $0088,y


Why can't it specify LDA $0088,Y? The Zero Page,Y form of this instruction does not exist, so there's no conflict.


thanks, i added a check for that addressing type in the next version.. now exicitebike is "bad addr mode" free.. i thought it was weird that the original code seemed to be waste a few bytes

by on (#74345)
working out some bugs... now it's faster and can produce valid output in only 2 passes with a complete CDL file.

tepples do you (or anybody) have an example of an NROM game which uses the RTS trick? from my searches so far i think i've just heard of final fantasy using it. i have the code implemented to disassemble it but i need a test case

by on (#74346)
frantik wrote:
tepples do you (or anybody) have an example of an NROM game which uses the RTS trick? from my searches so far i think i've just heard of final fantasy using it. i have the code implemented to disassemble it but i need a test case

Two of my NROM-128 games use it. LJ65 uses one RTS dispatcher for the playfield's state and calls it once for each player (I think the variable was called curTurn). Concentration Room uses three: one for the title screen menu, one for the game state, and one for the CPU opponents' state.

EDIT: Will explain further below

by on (#74347)
cool thanks.. and since i'm feeling lazy, could you tell me the location of one of the RTS tables in one of your games? :D

edit.. nm, i see the source for concentration room is included so i can just use that

by on (#74348)
In LJ65
src/t.s#game_cycle

In Concentration Room
src/litemain.s#titleDispatch is a really tricky one: it pushes the address of a handler for a title screen menu item, and then instead of RTSing directly into the handler, it JMPs to a routine that clocks the random number generator, and that RTSes into the handler. src/aidiocy.s#doAI and src/memorygame.s#stateDispatch are more straightforward. Notice that every time you build these in ca65, the addresses of these routines will change. By default, Concentration Room is preprocessed by a shuffler so that I can 1. more easily find buffer overflows and 2. trace leaks should I ever make an enhanced version of the game for selling copies on carts. You can disable this by changing shufflemode in the makefile.

by on (#74350)
the WORDs specified in my CDL turn to BYTEs.

And I think (I read) the next version should fix it,

EDIT: Sorry if I reminded you, but aren't you still going to add minimal NSF support?

You can use CDLs with the NSFs using FCEUX Code/Data Logger!

by on (#74351)
Hamtaro126 wrote:
the WORDs specified in my CDL turn to BYTEs.


what do you mean? CDL doesn't specify words anywhere, does it?

Quote:
EDIT: Sorry if I reminded you, but aren't you still going to add minimal NSF support?


you suggested it but i dont think i made a comment. it's not a big priority but i may add it. is it any different from a regular rom besides the header?

tepples wrote:
In LJ65
src/t.s#game_cycle


ok, got RTS tables working.. also got labels with +/- in them working properly as well

Code:
@das_skip:  LDA $30,x                ; $c469: b5 30     
            ASL                      ; $c46b: 0a       
            TAX                      ; $c46c: aa       
            LDA state_RTSTable+1,x   ; $c46d: bd 77 c4 
            PHA                      ; $c470: 48       
            LDA state_RTSTable,x     ; $c471: bd 76 c4 
            PHA                      ; $c474: 48       
straight_rts:
            RTS                      ; $c475: 60       

;-------------------------------------------------------------------------------
state_RTSTable:
            .word wait_for_join-1    ; $c476: 8b c4         
            .word __c4f9-1           ; $c478: f8 c4         
            .word __c627-1           ; $c47a: 26 c6         
            .word __c6a3-1           ; $c47c: a2 c6         
            .word __c7a8-1           ; $c47e: a7 c7         
            .word __c7a8-1           ; $c480: a7 c7         
            .word __cbb5-1           ; $c482: b4 cb         
            .word __ccc7-1           ; $c484: c6 cc         
            .word __cd0b-1           ; $c486: 0a cd         
            .word __cd73-1           ; $c488: 72 cd         
            .word __ca10-1           ; $c48a: 0f ca         

;-------------------------------------------------------------------------------
wait_for_join:
            LDA $ad                  ; $c48c: a5 ad     
            BNE straight_rts         ; $c48e: d0 e5     
 


custom label file:
Code:
@das_skip = $c469
straight_rts = $c475

state_RTSTable = $C476
state_RTSTable+1 = $C477

wait_for_join = $C48C

by on (#74359)
frantik wrote:
what do you mean? CDL doesn't specify words anywhere, does it?


I'm sure, It should say in the original specifications! Or maybe if there is none, a special build would do!

frantik wrote:
you suggested it but i dont think i made a comment. it's not a big priority but i may add it. is it any different from a regular rom besides the header?


Code:
;Please use Fixed-length Font before using!

;The NSF header is for the Wiki, What it is:

;It is 70 bytes for the header, Here is a short reference in my beta code:

;ASM6 Compatible Header Data

;----------------------------------------------------------------
; NSF header
;----------------------------------------------------------------

   .db "NESM",$1a ;identification of the NSF header
   .db $01,$7f,$01 ;NSF Format Version, # of tracks, Current Track #.
   .dw Load    ;Load Address
   .dw Init    ;Init Address
   .dw Play    ;Play Address
;       0000000000000000111111111111111
;       0123456789ABCDEF0123456789ABCDE
   .db "Yo! Wagyan by H126, (WIP Hack!)",$00 ;Title
   .db "1987-2010 Capcom,Bandai-Namco  ",$00 ;Copyright
   .db "Maajyan HigaShio,NOW Production",$00 ;Programmer

   .dw $411A  ;Used as Init Verification, Needed for NSF to work
   
   ;Bank Select:
   .db $00,  $00,  $00,  $00,  $00,  $00,  $00,  $00
   ;   with  with  with  with  with  with  with  with
   ;   $5ff8 $5ff9 $5ffa $5ffb $5ffc $5ffd $5ffe $5FFF
   ;   is    is    is    is    is    is    is    is
   ;   $8000 $9000 $A000 $B000 $C000 $D000 $E000 $F000

   .dw $0000           ;Pal Compatibility Crap (Shouldn't be touched)
   .db $00
   
   .db %00000000       ;Expansion bits:
                       ;00000000=NONE (Normal/No Extras)
                       ;00000001=VRC6 (Konami VRC6)
                       ;00000010=VRC7 (Konami VRC7)
                       ;00000100=NFDS (Nintendo Famicom Disk System)
                       ;00001000=MMC5 (Nintendo MMC5)
                       ;00010000=N106 (Namcot 106)
                       ;00100000=FME7 (Sunsoft FME7/5B)
                       ;01000000=UNUS (Unused)
                       ;10000000=UNUS (Unused)

   .db $00,$00,$00,$00 ;Unused Bytes

                .base $8000
                .org $8000

;Note: Modify where the NSF Interrupts are from before use, as the NSF interrupts are LOAD, INIT and PLAY,

Load: ; Insert Code Here
Init: ; Insert Code Here
Play: ; Insert Code Here


Sorry if I did it to push buttons, frantik, This contributation (NSF header) is my gift to you,

by on (#74361)
Hamtaro126 wrote:
frantik wrote:
what do you mean? CDL doesn't specify words anywhere, does it?


I'm sure, It should say in the original specifications!


yeah i don't think CDL says anything about words:
Code:
xPdcAADCC = Whether it was accessed as code.
D = Whether it was accessed as data.
AA = Into which ROM bank it was mapped when last accessed:
00 = $8000-$9FFF
01 = $A000-$BFFF
10 = $C000-$DFFF
11 = $E000-$FFFF
c = Whether indirectly accessed as code (e.g. as the destination of a JMP ($nnnn) instruction)
d = Whether indirectly accessed as data (e.g. as the destination of an LDA ($nn),Y instruction)
P = If logged as PCM audio data.
x = unused.


no words.. but you can make it recognize jump tables if you make a custom label that ends with "JumpTable" (as seen in my excitebike output), or RTSTable as seen above

Quote:
Sorry if I did it to push buttons, frantik, This contributation (NSF header) is my gift to you,


thanks.. so the rest of the file is just a regular rom though, right?

by on (#74409)
heh, koitsu i found your feature request list from... 7 years ago

Quote:
Most I've found suffer from the following idiocies:

* Expect specific binary sizes (i.e. 32K or 16K)
* Expect NES images (i.e. full game images with iNES header)
* Do not allow you to specify a src address offset (i.e. $E000 vs. the usual $8000 or $C000)
* Cannot disassemble to code that is easily re-assembled (i.e. without address labels / opcodes+operand bytes)
* Do not support lowercase mneumonics (i.e. all opcodes in uppercase)
* Do no form of proper code tracing (NESRev does this by implementing a small emulator-like pre-pass which generates pretty clean code)
* For those which insert inline comments for NES PPU registers / etc., do not allow you to disable this behaviour
* Do not include binaries for *IX platforms (or do not include source); I consider this a minor issue, though

If you look at all of the 6502 disassemblers out there, you won't find any which encompass all of the above -- or even HALF of the above.


i think i've got almost all of those things.. options to turn off the comments and allow for lowercase mnemonics have been on my mind, just not implemented.

i'm going to add options to specify where to start reading and how much to read.. you can already specify the origin and if there is no CHR, it should treat snippets of code correctly.

by on (#74590)
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.

i'll try to include a proper help file next time around too

by on (#74592)
How do I tell the disassembler that a memory range 8000-8A20 is data? (edit: figured it out, set the Code Start parameter)

by on (#74594)
Dwedit wrote:
How do I tell the disassembler that a memory range 8000-8A20 is data? (edit: figured it out, set the Code Start parameter)


the code start parameter allows you to set where to start disassembling from

to explicitly tell it what is code and what is data, right now you have to use a CDL file generated by FCEU* .. i may add a way to indicate if a label is code or data but right now that is the only way. even incomplete CDL files will generate decent results

also, if you make a custom label like

Code:
MyLabel = $8A21


then it will be sure to start processing the opcode at 8A21 even if the stuff above it is data

by on (#74596)
Mapper writes confuse the disassembler, for example, it thinks that A000 is data because there are writes pointing there. Also looks like FCEUX thought it was data too, because it was marked as both data and code in the CDL file. Maybe "code" should always trump "data".

Code:
            ROL                ; $9ffb: 2a       
            LDY $05f8,x        ; $9ffc: bc f8 05 
            .hex c0            ; $9fff: c0        Suspected data

;-------------------------------------------------------------------------------
__a000:     .hex 01            ; $a000: 01            Data
__a001:     .hex 2a bc 6e 06   ; $a001: 2a bc 6e 06   Data

;-------------------------------------------------------------------------------
            CPY #$01           ; $a005: c0 01     
            ROL                ; $a007: 2a       
            TAY                ; $a008: a8       


Anyway, I think that labels should not interrupt known code, instead emit a label like
_a000 = $ - 1
or something like that.

edit:
Code:
            .hex 90 7f         ; $c706: 90 7f     Illegal Branch - BCC #$7f

Since when are forward branches of 127 illegal?

by on (#74620)
Dwedit wrote:
Mapper writes confuse the disassembler, for example, it thinks that A000 is data because there are writes pointing there. Also looks like FCEUX thought it was data too, because it was marked as both data and code in the CDL file. Maybe "code" should always trump "data".


ok i will look into that... i dont think i realized a byte could be marked as either code or data. what rom were you testing btw?

Quote:
edit:
Code:
            .hex 90 7f         ; $c706: 90 7f     Illegal Branch - BCC #$7f

Since when are forward branches of 127 illegal?


i seem to recall asm6 not liking brances to $7f so i did that... ill have to double check again..
yeah... so is this a bug in asm6?
Code:
      90 7D                     BCC #$7F
*** Branch out of range.


edit.. nm, i think it only happens with you're using a constant instead of an addres.. the error message confused me

by on (#74621)
I was testing the program out on my Chu Chu Rocket game. Also, the quality of disassembly went way up when I made a Code-Data log before disassembling the game.

by on (#74623)
Dwedit wrote:
I was testing the program out on my Chu Chu Rocket game. Also, the quality of disassembly went way up when I made a Code-Data log before disassembling the game.


will this rom exhibit the problem? what are your command line options? (i'm trying to play the game to make an cdl but i can get it to consistently place the arrow tile down..? oh i see you have to hold the button then press the arrow key.... i was like wtf)

i've improved the output somewhat but i think i need to allow a way for users to specify memory locations that should not be interpreted as program code labels when using LDA/STA

Code:
            RTS                ; $9ffc: 60       

;-------------------------------------------------------------------------------
__9ffd:     LDA __8980,y       ; $9ffd: b9 80 89 

;-------------------------------------------------------------------------------
__a000:     .hex 85            ; $a000: 85        Suspected data
__a001:     PHP                ; $a001: 08       

;-------------------------------------------------------------------------------
            LDA __89c0,y       ; $a002: b9 c0 89 
            STA $09            ; $a005: 85 09     
            LDA __8600,y       ; $a007: b9 00 86 


and yeah, using a CDL gives you much much better results. with the CDL it will make educated guesses.. in the future I would like to make the disassembler a little "smarter" when handling roms without a CDL too.

by on (#74626)
frantik wrote:
Quote:
edit:
Code:
            .hex 90 7f         ; $c706: 90 7f     Illegal Branch - BCC #$7f

Since when are forward branches of 127 illegal?


i seem to recall asm6 not liking brances to $7f so i did that... ill have to double check again..
yeah... so is this a bug in asm6?
Code:
      90 7D                     BCC #$7F
*** Branch out of range.


edit.. nm, i think it only happens with you're using a constant instead of an addres.. the error message confused me


"BCC #$7F" is invalid syntax, and whatever asm6 did there (assembled it to $90 7D) is incorrect. It should have just thrown an error and not shown any assembled opcode and operand values at all. I have no idea where it got $7D from. The correct syntax in your code would have been "BCC $7F". There is no immediate addressing mode on branch instructions (such would make no sense).

Furthermore, terminology complaint: The $7F in "BCC $7F" *is not* an address, it's an offset (sometimes called a nearlabel).

And yes, $7F is a valid branch range. It's the equivalent of +127. Branch instructions range from +127 to -128. It's just a signed 8-bit number.

by on (#74629)
i thought it was strange.. regardless i've already removed the code for that from 1.5

edit... actually, i think it is an ASM6 bug.. it's treating it like an address

Code:
                                 .org $c000
0C000 90 7A                     BCC $7C
*** Branch out of range.
0C002 90 7A                     BCC $7E
*** Branch out of range.
0C004 90 79                     BCC $7F
*** Branch out of range.
0C006 EA                        NOP
0C007 EA                        NOP
0C008 EA                        NOP
0C009 EA                        NOP
...

0C07D EA                        NOP
0C07E EA                        NOP
0C07F EA                        NOP
0C080 EA                        NOP


vs

Code:
                                .org $00
00000 90 7A                     BCC $7C
00002 90 7A                     BCC $7E
00004 90 79                     BCC $7F
00006 EA                        NOP
00007 EA                        NOP
00008 EA                        NOP
00009 EA                        NOP
0000A EA                        NOP

by on (#74630)
It's treating #$7F as an absolute address. If you never specify an origin address, it will default to 0000. So it emits the instruction to jump to address 7F relative to the address after the jump (0002), and there's your 7D.

by on (#74631)
Dwedit wrote:
It's treating #$7F as an absolute address. If you never specify an origin address, it will default to 0000. So it emits the instruction to jump to address 7F relative to the address after the jump (0002), and there's your 7D.


yeah that is what it is doing..

it shouldn't matter now though as far as the disassembler is concerned since it generates labels for branches but it seems like BCC $7F shouldn't be treated the same way as BCC SomeLabel where SomeLabel is $7F

by on (#74632)
Do any assemblers allow you to manually specify the relative displacement after a branch instruction? To me, it seems just logical that "$XX" is interpreted like an address, as that is the case with any other instruction, so I don't think ASM6 is doing anything wrong here. "BCC #$7F" may look weird, but looks to me like a more logical way to explicitly represent the displacement...

I mean, if someone doesn't want to use labels for whatever reason they are allowed to use addresses as arguments to branch instructions, right? With every other instruction, if I use "$XX" that number is interpreted as an address, so why would it be any different with the Bxx instructions? IMO, "BCC $7F" should mean "branch to address $7F" and "BCC #$7F" should mean "branch to the location 127 bytes ahead".

by on (#74633)
tokumaru wrote:
IMO, "BCC $7F" should mean "branch to address $7F" and "BCC #$7F" should mean "branch to the location 127 bytes ahead".



i tend to agree, though BCC #$7F is treated just like BCC $7F in asm6.. i think BCC #$7F should throw a proper error message at least

by on (#74636)
tokumaru wrote:
Do any assemblers allow you to manually specify the relative displacement after a branch instruction?


Yes, I'm pretty certain Merlin 8/16 and ORCA/M both behave this way, and I know the Apple IIGS mini-assembler behaves this way as well. There's absolutely no reason an assembler should not honour what the programmer says when they type "BCC $7F". The result should be $90 7F. If the assembler prefers to treat $7F as an address instead of an offset, there should at least be a way to honour literal offsets (possibly something like "BCC =$7F".

As for disassemblers: some disassemblers show the displacement in a human-friendly form, e.g. "90 7F" disassembles into "BCC $7F ; +128" or if the disassembler supports labelling then "BCC <nearlabel>" with "<nearlabel> <some code>" further down in the disassembly. For negative offsets, it would show -XXX.

I've also seen disassemblers which would output "BCC $7F {+128}" or "BCC $7F {nearlabel}, which is basically the same as the above but with the label and human-friendly offset written in literal braces ({}).

by on (#74638)
asm6 is not supposed to be parsing BCC #$xx. It's a bug and I'll look into it.

On BCC $address, I am 100% in agreement with tokumaru. I started another post arguing with you, but realized I was repeating what he already wrote so I deleted it. You can reread his post instead :P

by on (#74639)
tokumaru wrote:
Do any assemblers allow you to manually specify the relative displacement after a branch instruction?


I allow that with xkas, although it's a 65816 assembler, it's compatible except for the 'illegal' opcodes with the 6502.

It's quite handy when you are writing hundreds of small inline patches and don't want to break it down into individual labeled lines.

org $8214; sta $2180; dex; bne $fa //easier to do the math in your head

by on (#74640)
koitsu wrote:
if the disassembler supports labelling then "BCC <nearlabel>" with "<nearlabel> <some code>" further down in the disassembly. For negative offsets, it would show -XXX.


I considered doing that but then there is the potential for up to 3 labels for 1 memory location. There isn't much difference between -_C010 and __C010 anyways, and if you use non-unique labels then you have to keep track of them to ensure it is ok to use it in that context.

you can however use relative labels in the user provided label list

by on (#74643)
koitsu wrote:
There's absolutely no reason an assembler should not honour what the programmer says when they type "BCC $7F".

What the programmer is saying is BCC $007F. Consider the case of code copied to zero page.

Quote:
The result should be $90 7F. If the assembler prefers to treat $7F as an address instead of an offset, there should at least be a way to honour literal offsets (possibly something like "BCC =$7F".

How about something close to BCC *+$7F, where * represents a program counter?

by on (#74647)
I think BCC #xx should be an error. If you want to specify the relative branch yourself, use BCC $+2+offset.

by on (#74657)
Dwedit wrote:
I think BCC #xx should be an error. If you want to specify the relative branch yourself, use BCC $+2+offset.


why? because it implies an addressing mode which doesn't exist?

from a readability standpoint, I much prefer BCC #offset vs BCC $+2+offset.. and regardless of addressing mode, it makes sense. i mean LDA #$7F will always put a 7F after the opcode, so BCC #$7F should as well

by on (#74658)
tepples wrote:
How about something close to BCC *+$7F, where * represents a program counter?


Works for me. Honestly anything works, as long as it's documented in the manual that comes with the assembler. Sub-par assembler documentation is unacceptable. :D

frantik wrote:
Dwedit wrote:
I think BCC #xx should be an error. If you want to specify the relative branch yourself, use BCC $+2+offset.


why? because it implies an addressing mode which doesn't exist?


Yes. # indicates immediate.

by on (#74660)
koitsu wrote:
Yes. # indicates
immediate.


then just put ut in the manual: "for branches, # acts similarly to immediate, but it's not technically the same thing." :D

conceptually, # means "a number which isn't a memory address" to me.

it's obviously up to loopy though.. and it's not even an issue really since i doubt many people will ever use the feature.. i'm not even quite sure why my code was generating BCC #$7F style output, and it's not now

by on (#74677)
Dwedit wrote:
Mapper writes confuse the disassembler, for example, it thinks that A000 is data because there are writes pointing there. Also looks like FCEUX thought it was data too, because it was marked as both data and code in the CDL file. Maybe "code" should always trump "data".


I added an option to disable creating labels in the PRG area (is that the right name? $8000 - $FFFF) when using STA/X/Y

working on a good way to be able to name them (right now when you make any label it will be placed into the program code unless it has a + or - in the text (but doesnt start with +/-))

by on (#74743)
koitsu wrote:
There's absolutely no reason an assembler should not honour what the programmer says when they type "BCC $7F". The result should be $90 7F.

But what if I don't want to use labels and still want the assembler to calculate the relative displacement for me? What do I do if I really want to branch to address $7F but don't want to have a label marking that position?

by on (#74768)
tokumaru wrote:
koitsu wrote:
There's absolutely no reason an assembler should not honour what the programmer says when they type "BCC $7F". The result should be $90 7F.

But what if I don't want to use labels and still want the assembler to calculate the relative displacement for me? What do I do if I really want to branch to address $7F but don't want to have a label marking that position?

I don't have an answer to this question. :-) I think overall the best approach is to implement both methods and document in the assembler documenation whichever one requires a quirk (e.g. BCC =$7F).

Tepple's example of using *+$7F is ideal, but to minimise support requests, I would recommend changing the branch-too-far error message to indicate the boundaries explicitly (-128 to +127 or -126 to +129, depending on if the author wants to take into consideration the branch being from the end of the instruction or the opcode, respectively. Let's not get too OCD about this one though; if I had to vote on which to output, it would be the former).

by on (#74775)
koitsu wrote:
I don't have an answer to this question. :-) I think overall the best approach is to implement both methods and document in the assembler documenation whichever one requires a quirk (e.g. BCC =$7F).

Tepple's example of using *+$7F is ideal, but to minimise support requests, I would recommend changing the branch-too-far error message to indicate the boundaries explicitly (-128 to +127 or -126 to +129, depending on if the author wants to take into consideration the branch being from the end of the instruction or the opcode, respectively. Let's not get too OCD about this one though; if I had to vote on which to output, it would be the former).


You just helped me understand why the Z80 programmer's manual specified -126 to +129 for its relative jump operand range. :-)
Glad to see this
by on (#75141)
Hey guys,

I am the guy that came up with FCEUXD's Code/Data logger, the specification for the CDL files, and all of that. That stuff was all my idea back in 2004. My other idea was this exact project - a smart disassembler that produces a reassemblable disassembly using the CDL files (and ALL files - more on that later) as input. I actually implemented the disassembler (calling it xdDasm), but the project was abandoned. I never got it functional enough to be happy releasing it.

One thing I also implemented was an Address Label Logger. Basically FCEUXd would log these *.ALL files that would have ASCII lines that tell which instruction in the rom accessed which address in the rom. It was very useful for making labels work correctly across banks since if you see a JMP $8097, you don't know which bank that references and hence don't know where to put a label. It would only log accesses that went across banks.

Anyway, I am very happy to see someone else has done the disassembler. I know of a few other people that attempted this. _hyde_ had special logs he outputted from his own emu, and made his own unreleased disassembler - he did a lot of games with it. I don't know what snowbro used to make disassemblies for metroid and King's Quest 5 - he may have implemented something like this for it. Disch wrote his own smart disassembler and used his own logs from his emulator to do one for Final Fantasy 1. It's a pretty solid idea, just no-one has made a generic disassembler to do it.

You can find most of the disassemblies here that were produced by the above mentioned people.
http://gilgalad.arc-nova.org/vgscr/nes.html
(megaman 3 is the only one there that is xdDasm output. It was the only game I really got xdDasm to working with before I abandoned it)

There are a few cases I know of where this kind of smart disassembly won't work. There are games like Zelda which copies much of it's code to RAM. It won't be logged as code if it's being copied to RAM. Also, Fester's Quest has an annoying random number generator that likes to read random data from the ROM causing lots of crap to be logged as data (you have to hack that random number generator to be *nicer* before logging that game)

bbitmaster

by on (#75209)
I couldnt get the address label logger to work in any version of FCEU* that i used

still got a few more features i want to add to this :)

by on (#75394)
Nice, but I split two files, a Chase HQ NES file and a pure program BIN....Why is the program full of "illegal opcode"s? That'd be a nice fix. And also, this tool is pretty nice, but truthfully still isn't good enough to use to me and probably others, since it runs into so many illegal opcodes in normal code. I cxan't even find intructions like a read from $4016 when I know there is one that I need to change. Hopefully this gets fixed in the next version. :)

by on (#75449)
the illegal opcodes are usually data. but the program assumes everything is code unless you specifically tell it what is code and what is data, using a code/data log (CDL)

A CDL can be generated using most branches of FCEUD. Even incomplete CDL logs will give much better results


oh.. btw Chase HQ uses a mapper, so you have to tell the disassembler where to start and end.. it probably didn't show the code you were looking for because it wasn't in the first 8k, which is what will get read if you don't tell it otherwise.

you have to manually do the mapper stuff because the disassembler is has no concept of mappers... just like the NES console itself doesn't have a concept of mappers.. it just reads the 8k of prg memory

by on (#75453)
Okay, I'll try that later. So this only reads 8K of data? Didn't realize that! -facepalm-
Re: DISASM6 v1.4 - Nes oriented disassembler producing asm6
by on (#108448)
Yeah that's right, resurrecting a thread from almost a year ago!

What's the status of this project? There seem to be bugs/etc. which are supposedly fixed in 1.5 (unreleased?) and so on, so I was hoping to get my hands on such, or at least find out how the project's coming along.

If it's one of those "I've lost interest" things, that's perfectly okay too! Just let us know.

Thanks!
Re: DISASM6 v1.4 - Nes oriented disassembler producing asm6
by on (#112061)
Run with the -lc option reduces the number of passes.
Just me?
Re: DISASM6 v1.4 - Nes oriented disassembler producing asm6
by on (#124666)
frantik, are you still maintaining disasm6? 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.
Re: DISASM6 v1.5 - Nes oriented disassembler producing asm6
by on (#139989)
Found this old thread and saw there was some interest in this disassembler

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
Re: DISASM6 v1.5 - Nes oriented disassembler producing asm6
by on (#140713)
Yeah, this is a great tool, frantik. I'd love to convert it into C (and I might just do that) sometime. I dunno, when I see good tools like this, I just feel inclined to help and make them better in some way. Might even be a worthwhile github.com project between a bunch of us. (I already have some of my own projects up there)

Anyway rambling aside, I did find a bug:

Code:
D:\Console\bin>disasm6

Warning: gzinflate(): data error in C:\__OldXP-80GB\WinBinder\binaries\phpack\exe_bootstrap.php on line 95

DISASM6 v1.5 - A NES-oriented 6502 disassembler - Created by Frantik 2015
-------------------------------------------------------------------------------
Usage:
...

I'm not sure what's going on there with the gzinflate() call. I see no such thing in the .php script, so I'm lead to believe the PHP-to-executable compiler being used may have an actual bug. I should also note that the C:\__OldXP-80GB etc... directory is nothing on my system -- this looks to be something on the author's system.

Finally: what license is this code released under? I don't see any copyrights or licenses in the source or binary, so...
Re: DISASM6 v1.5 - Nes oriented disassembler producing asm6
by on (#140835)
Hey koitsu

Thanks for pointing out that bug. It seems to be caused by the PHP "compiler" I used called "PHPack". The path mentioned does exist on my machine. I will look into it. The program still works though it seems?

Technically there is no license. Feel free to do anything you like with the code, though I'd appreciate at least some credit if anyone decides to release a new or ported version
Re: DISASM6 v1.5 - Nes oriented disassembler producing asm6
by on (#153970)
So I tried this against a CNROM game and it seems to run into trouble right away:

Code:
reset:      ; irq/brk vector
;-------------------------------------------------------------------------------
irq:        lda $2002          ; $b814: ad 02 20 
            bmi Array          ; $b817: 30 fb     
__b819:     lda $2002          ; $b819: ad 02 20 
            bpl __b819         ; $b81c: 10 fb     
            lda $15            ; $b81e: a5 15     
            pha                ; $b820: 48       
            jsr __e2f5         ; $b821: 20 f5 e2 
            pla                ; $b824: 68       
            .hex 85            ; $b825: 85        Suspected data
__b826:     ora $20,x          ; $b826: 15 20     
            inc $20eb,x        ; $b828: fe eb 20 


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"
Re: DISASM6 v1.5 - Nes oriented disassembler producing asm6
by on (#153971)
It's marked as "suspected data" because something's reading or writing to the $15 at $B826. (Hence why the __b826: label appeared)

This is kinda hard to address. For now, the easiest thing for you to do is change the code to treat the CDL parser's "was executed" as taking priority over "was read/written" (Search the source for "newCdlByte")
Re: DISASM6 v1.5 - Nes oriented disassembler producing asm6
by on (#185519)
Hi, newbie here.

In referenc to this post:

irq:        lda $2002          ; $b814: ad 02 20 
            bmi Array          ; $b817: 30 fb     
__b819:     lda $2002          ; $b819: ad 02 20 
            bpl __b819         ; $b81c: 10 fb     
            lda $15            ; $b81e: a5 15     
            pha                ; $b820: 48       
            jsr __e2f5         ; $b821: 20 f5 e2 
            pla                ; $b824: 68       
            .hex 85            ; $b825: 85        Suspected data
__b826:     ora $20,x          ; $b826: 15 20     
            inc $20eb,x        ; $b828: fe eb 20 

and this response:

"This is kinda hard to address...."

In the interest of a possible bug report, I notice this in my code: (2 examples)

This code
LSR ; $8c15: 4a
LSR ; $8c16: 4a
LSR ; $8c17: 4a
TAX ; $8c18: aa
LDY __8c20,x ; $8c19: bc 20 8c
.hex 4c e2 ; $8c1c: 4c e2 Suspected data
__8c1e: .hex 8c ; $8c1e: 8c Suspected data
__8c1f: RTS ; $8c1f: 60


SHOULD BE

LSR ; $8c15: 4a
LSR ; $8c16: 4a
LSR ; $8c17: 4a
TAX ; $8c18: aa
LDY __8c20,x ; $8c19: bc 20 8c
JMP __8ce2 ; $8c1c: 4c e2 8c
RTS ; $8c1f: 60


SIMILARILY
LDA ($26),y ; $8d96: b1 26
STA $3b ; $8d98: 85 3b
.hex 4c ; $8d9a: 4c Suspected data
__8d9b: EOR ($8d,x) ; $8d9b: 41 8d

SHOULD BE
LDA ($26),y ; $8d96: b1 26
STA $3b ; $8d98: 85 3b
JMP 8d41: ; $8d9a: 4c 41 8d

Not sure if this is the same issue. Like I said, newbie.

Thanks
Re: DISASM6 v1.5 - Nes oriented disassembler producing asm6
by on (#185538)
I don't believe frantik is maintaining this anymore... it's been almost 2 years.

What happens, is that some games use a base address for an indexed mode that actually is code (not data). The disassembler marks that point as the start of data, even though it is clear to a human that it is code.

It is a bug...BUT, it will technically reassemble correctly, if that counts for anything.

It's more annoying to me that illegal opcodes are assumed to be code, when that is rarely the case.
Re: DISASM6 v1.5 - Nes oriented disassembler producing asm6
by on (#185583)
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
Re: DISASM6 v1.5 - Nes oriented disassembler producing asm6
by on (#186874)
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
Re: DISASM6 v1.5 - Nes oriented disassembler producing asm6
by on (#186887)
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...
Re: DISASM6 v1.5 - Nes oriented disassembler producing asm6
by on (#186906)
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
Re: DISASM6 v1.5 - Nes oriented disassembler producing asm6
by on (#186916)
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
Re: DISASM6 v1.5 - Nes oriented disassembler producing asm6
by on (#186918)
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?
Re: DISASM6 v1.5 - Nes oriented disassembler producing asm6
by on (#186949)
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
Re: DISASM6 v1.5 - Nes oriented disassembler producing asm6
by on (#186953)
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.
Re: DISASM6 v1.5 - Nes oriented disassembler producing asm6
by on (#186959)
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.
Re: DISASM6 v1.5 - Nes oriented disassembler producing asm6
by on (#186985)
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
Re: DISASM6 v1.5 - Nes oriented disassembler producing asm6
by on (#189917)
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 ??
Re: DISASM6 v1.5 - Nes oriented disassembler producing asm6
by on (#228163)
FrankWDoom 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"


Well I doubt you'll see this but you should try running the option -iw or -ignorewrites which ignores writes to $8000 - $FFFF

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


the weird thing is readLabelText was added in 1.5.. in 1.4, readLabels did everything. I'm sure I had a good reason.

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