It is currently Mon Nov 20, 2017 9:43 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 22 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Sun Aug 20, 2017 9:25 am 
Offline
User avatar

Joined: Sun Aug 20, 2017 8:53 am
Posts: 4
Location: New York, NY
Hey all. Long time lurker on these forums, first time poster.

I'd like to let you all know about a new NES assembler that I just completed called Nessemble.

It functions very similarly to nesasm, but with a bunch of extra bells and whistles including:

  • `.incpng` pseudo instruction to include images without first converting to CHR data
  • Built-in disassembler to better analyze existing NES ROMs
  • Support for scripting to extend existing functionality

I'd love to know what everyone thinks. Regardless of its usefulness alongside existing assemblers, it was fun to create and might be useful to someone.

Please feel free to check out the website and contribute/raise issues on GitHub.


Top
 Profile  
 
PostPosted: Sun Aug 20, 2017 2:42 pm 
Offline

Joined: Wed Aug 16, 2017 12:15 am
Posts: 10
Location: Finland
Welcome.

Some quick comments on the documentation:
  • Operator precedence and associativity (left/right) are not defined.
  • NOP and SBC are listed under illegal/undocumented mnemonics.
  • The syntax seems to have been influenced by NESASM, which I'm not a fan of (especially the need to explicitly mark zero page operands with "<").
  • .org stands for "origin", not "organize".
  • The following pseudo-instructions would be useful: define 16-bit big-endian word, define 32-bit little-endian dword, define 32-bit big-endian dword.

Sorry if I sound too negative. Those were just details that caught my eye.


Top
 Profile  
 
PostPosted: Sun Aug 20, 2017 3:34 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10116
Location: Rio de Janeiro - Brazil
Not a big fan of the similarities to NESASM (LOW()/HIGH(), < for ZP, [] for indirection), but there are some cool additions. There are some errors in the documentation (I don't mind you calling .org "organize", it's your assembler after all), such as saying 2KB == 0x2000 and 4KB == 0x4000.

Also, it's not clear to me how the BANK() function works... In NESASM, banks are always 8KB, so if the mapper you're using works with 16 or 32KB banks you have to divide the value provide by NESASM by 2 or 4. Also, in NESASM, it doesn't look like BANK() is useful for referencing CHR banks, since the bank counter doesn't reset after the PRG-ROM and CHR banks can be as small as 1KB. Can your assembler get around these problems?

Can Nessemble generate NES 2.0 headers? Can you disable headers altogether, allowing it to be used for developing games for other 6502 platforms (such as the 2600)?

As I see it, the main drawback of NESASM is not its quirky syntax, but the annoying imposition of having to divide the whole program in 8KB chunks. The main drawback of ASM6, on the other hand, is not having any sort of built-in bank management (i.e. BANK() function), which makes inter-bank references that much harder to manage. If you can offer something that doesn't impose such arbitrary limitations and can make the management of multi-bank ROMs easier, Nessemble has the potential of becoming the go-to assembler for creating ROMs without hassle. That is, as long as it's featured in a newbie-friendly tutorial that we can recommend, otherwise I can only see Nerdy Nights producing more and more NESASM users.


Top
 Profile  
 
PostPosted: Mon Aug 21, 2017 3:36 am 
Offline
User avatar

Joined: Wed Jul 26, 2017 4:25 am
Posts: 9
[FR]
Bonjour,
vous avez un bugs à l'adresse: http://www.nessemble.com/documentation/
Le lien du texte : "Edit on GitHub " pointe vers la cible : https://github.com/kevinselwyn/nessembl ... s/index.md
Je pense que la cible devrai être: https://github.com/kevinselwyn/nessemble

[ENG]
Hello,
You have a bug at: http://www.nessemble.com/documentation/
The text link on the web page : "Edit on GitHub" target to : https://github.com/kevinselwyn/nessembl ... s/index.md
I think the target is: https://github.com/kevinselwyn/nessemble


Top
 Profile  
 
PostPosted: Mon Aug 21, 2017 7:22 am 
Offline
User avatar

Joined: Sun Aug 20, 2017 8:53 am
Posts: 4
Location: New York, NY
Thanks for the feedback so far!

qalle, great tips on the documentation. I'll note that `NOP` and `SBC` both have undocumented opcodes, which would probably make the undocumented versions unreachable because the assembler would use the documented ones. Also, the additional pseudo-instructions you mentioned could easily be added with a little bit of scripting. And tokumaru says I can define `.org` as "organize" ;) Although, I've looked at other assemblers, which ones define it as "origin", out of curiosity?

tokumaru, I'll look into some of the banking functionality. I'll admit that I haven't tried to make anything substantial with the assembler yet, but I'm sure pain points will emerge when I do. Also, I'll definitely add NES 2.0 support. If you use `--format RAW` when invoking the assembler, it will output a headerless ROM making 2600 development (theoretically) possible.

klr128, good catch. Merci.

Thanks, all!


Top
 Profile  
 
PostPosted: Mon Aug 21, 2017 7:42 am 
Offline

Joined: Tue May 28, 2013 5:49 am
Posts: 872
Location: Sweden
I'm curious why indirection brackets () conflicts with mathematical brackets on some assemblers but not others? Or are they separate for clarity reasons? Personally I prefer () for indirection because [] are very tedious to type on many non-English keyboards (as we just discussed in another thread).

Also while I'm not totally against NESASM's zeropage addressing notation, I think CA65 is doing it the best way. It automatically chooses zeropage addressing when a zeropage address is used, which can be overridden by a prefix before the address if one needs to.
Non-automatic zeropage addressing could be annoying if one needs to move lots of variables from the zeropage.


Top
 Profile  
 
PostPosted: Mon Aug 21, 2017 8:05 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19237
Location: NE Indiana, USA (NTSC)
snarf2888 wrote:
And tokumaru says I can define `.org` as "organize" ;) Although, I've looked at other assemblers, which ones define it as "origin", out of curiosity?

Probably just about every single one of them, including emulators for architectures other than 6502. Google assembly org origin returns this page, for example.

I'm curious why indirection brackets () conflicts with mathematical brackets on some assemblers but not others? Or are they separate for clarity reasons?
I imagine it makes the parser simpler. Just matching lda (some_arbitrary_string),Y won't work; you have to match lda (some_full_expression),Y, which means it has to be applied after the stage of the parser that recognizes expressions. And the expression part of the parser has to be smart enough not to swallow the outermost parentheses.
Code:
; These should assemble the same way, using aaaa,Y addressing mode
lda 3*4+2*5,Y
lda (3*4)+(2*5),Y

; This should assemble differently, using (dd),Y addressing mode
lda (3*4+2*5),Y

Perhaps the author of the MagicKit assemblers (PCEAS and NESASM) thought brackets would simplify the parser and wasn't considering the francophone minority, as more developers were in Japanese- or English-speaking countries when the TG16 and NES were popular.

The other issue is that the 65816 uses brackets for "indirect long" addressing modes, which use the data bank in the pointer instead of the data bank from the data bank register.

Pokun wrote:
Non-automatic zeropage addressing could be annoying if one needs to move lots of variables from the zeropage.

This feature arises from MagicKit's early focus on the HuC6280, the CPU of the TG16. Its direct page is at $2000-$20FF instead of $0000-$00FF. The direct page of the SPC700 (Super NES audio CPU) is at $0000-$00FF or $0100-$01FF depending on P bit 5. The direct page of the LR35902 (Game Boy CPU) is at $FF00-$FFFF, though that one's based on an 8080 rather than a 6502. And the direct page of the 65816 can be moved to start at any location in bank 0 ($000000-$00FFFF), though if direct page doesn't start on a 256-byte boundary, each direct page instruction incurs an extra cycle of index addition penalty.

On the HuC6280, for example, which address should lda $02 read? Should it read $0002 in absolute mode? Or should it read $2002 in direct page mode?


Top
 Profile  
 
PostPosted: Mon Aug 21, 2017 8:26 am 
Offline
User avatar

Joined: Sun Aug 20, 2017 8:53 am
Posts: 4
Location: New York, NY
I had parsing problems with [] vs (). I _wanted_ to use () for indirect addressing et al., but it was simpler for the assembler to parse [].

Regarding the zeropage syntax, I also dislike having to use <, but automagically figuring out if an address is zeropage was difficult for my assembler, especially when it came to using labels (since label addresses are gathered during the first pass of the assembler). In the end, I wanted people to opt in to optimizing and using zeropage addressing instead of trying to think for the programmer.

Turns out, it's difficult to write parsers.


Top
 Profile  
 
PostPosted: Mon Aug 21, 2017 8:49 am 
Offline
User avatar

Joined: Mon Feb 07, 2011 12:46 pm
Posts: 932
I do have a suggestion about the extending. If a JavaScript code returns a ArrayBuffer, Uint8Array, or DataView, it should accept that too rather than only a string. (Similar things can be supported in Scheme and Lua if they have similar features, but I don't know if they do.)

The = syntax for defining constants within the assembly code does not seem to be documented, although that is what seems to be the case by looking at the source codes; apparently also a label name by itself with no colon or anything else defines a constant 1, which should also be documented if that is in fact the case.

Also, I do happen to like the MagicKit-style addressing modes, even if some people do not.

Adding additional functions for use with JavaScript-based extensions can also be helpful, such as (could be added into a "Nessemble" global object; you could use a code such as const N=Nessemble; if you wanted an abbreviation):
  • include(filename) for including another JavaScript code from another file.
  • loadText(filename) for reading another file as text.
  • loadBinary(filename) for reading another file as a ArrayBuffer.
  • save(filename,data) for writing data (either a string or a ArrayBuffer or typed array or DataView) to another file.
  • addSymbol(name,value,type) to add a symbol.
  • pass() to determine which pass of the assembler it is.
  • address() to tell you the current address.
  • romArray() to retrieve a Uint8Array for the ROM.
(and so on; possibly not all of them will be implemented at once, but some versions might implement sone.)

Another suggestion can be ability to omit the word .macro when calling a macro in cases where it is unambiguous, like other assemblers will do too.

_________________
.


Top
 Profile  
 
PostPosted: Mon Aug 21, 2017 10:30 am 
Offline

Joined: Wed Aug 16, 2017 12:15 am
Posts: 10
Location: Finland
snarf2888 wrote:
I had parsing problems with [] vs (). I _wanted_ to use () for indirect addressing et al., but it was simpler for the assembler to parse [].


Ophis uses [] as mathematical brackets and () for indirect addressing modes: lda ([1+1]*3),y (which I like).

snarf2888 wrote:
...automagically figuring out if an address is zeropage was difficult for my assembler, especially when it came to using labels...

The reason why I abandoned my assembler project.


Top
 Profile  
 
PostPosted: Mon Aug 21, 2017 11:48 am 
Offline

Joined: Tue May 28, 2013 5:49 am
Posts: 872
Location: Sweden
tepples wrote:
Pokun wrote:
Non-automatic zeropage addressing could be annoying if one needs to move lots of variables from the zeropage.

This feature arises from MagicKit's early focus on the HuC6280, the CPU of the TG16. Its direct page is at $2000-$20FF instead of $0000-$00FF. The direct page of the SPC700 (Super NES audio CPU) is at $0000-$00FF or $0100-$01FF depending on P bit 5. The direct page of the LR35902 (Game Boy CPU) is at $FF00-$FFFF, though that one's based on an 8080 rather than a 6502. And the direct page of the 65816 can be moved to start at any location in bank 0 ($000000-$00FFFF), though if direct page doesn't start on a 256-byte boundary, each direct page instruction incurs an extra cycle of index addition penalty.

On the HuC6280, for example, which address should lda $02 read? Should it read $0002 in absolute mode? Or should it read $2002 in direct page mode?

Wouldn't LDA $02 simply read $2002 in zero page mode and $0002 in absolute mode since only in direct page mode the upper byte is implied? But I guess that there might not just be one right answer. The relocatable direct page of 65816 and SPC700 would require an assembler directive where the programmer tells the assembler where the DP is for automatic direct page addressing I guess.

I'm not sure how Gameboy assemblers normally handle the LDH instruction though. But on the Gameboy the "direct page" is used for a relocated OAM-DMA subroutine, stack, hardware registers and as a fast direct page-like RAM, so there's not a lot of direct page variables to move around in the first place. I think RGBASM uses LDH as forced direct page addressing no matter if the upper byte ($FF) is used or not, but I haven't tested it.


Top
 Profile  
 
PostPosted: Tue Aug 22, 2017 10:11 am 
Offline

Joined: Mon May 25, 2009 2:20 pm
Posts: 38
what about copying the "auto zero page" thing from the nesasm 2.51 so people dont have to type the < thing for zero page stuff ??

http://www.2a03.jp/~minachun/nesasm/nesasm_x86.html

I personally only use this type of NESASM for my megaman odyssey. Cause i hate the whole idea of typing those annoying < things in front of zero page addresses and label names.

This autozp version does not make you do that. so i only use that.

Why was it "never" added to the version 3 anyway ??


Top
 Profile  
 
PostPosted: Tue Aug 22, 2017 3:53 pm 
Offline
User avatar

Joined: Sun Aug 20, 2017 8:53 am
Posts: 4
Location: New York, NY
snarf2888 wrote:
I wanted people to opt in to optimizing and using zeropage addressing instead of trying to think for the programmer.


Programmers should be accountable for writing code optimized to their liking, even at such a low level.

I can't speak to `.autozp`, but nesasm is an entirely different assembler than Nessemble. Feel free to check out the code and submit a pull request for new features.


Top
 Profile  
 
PostPosted: Tue Aug 22, 2017 4:29 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10116
Location: Rio de Janeiro - Brazil
The problem is that 99.9% of the time you DO want ZP addressing (who doesn't want faster code?), and having to type "<" for every freaking ZP variable is incredibly annoying, considering that, at least for me, the bulk of the variables are there, while arrays and things that are referenced less often occupy the other pages. The only time you intentionally need to slow down the access to ZP variables is in timed code, which doesn't have much use on the NES outside of raster effects (and even then there are often other choices to waste 1 extra cycle). On the 2600 it's more common for me to need to access variables using 4 cycles (all of the RAM is in ZP on the 2600!), but it's still the exception.


Top
 Profile  
 
PostPosted: Tue Aug 22, 2017 9:46 pm 
Offline

Joined: Mon May 25, 2009 2:20 pm
Posts: 38
tokumaru wrote:
and having to type "<" for every freaking ZP variable is incredibly annoying, .


yea exactly my point earlier. there's some bugs apparently with this 2.51 that were fixed in the version 3.whatever .. but i'll stay with this older one, cause of the autozp, sole reason only.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 22 posts ]  Go to page 1, 2  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: Google [Bot] and 10 guests


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

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