Language…
6 users online: Coockie1173, Gutawer, Hayashi Neru, LXXXInsane, Ringo, tactirunips - Guests: 67 - Bots: 101
Users: 57,945 (2,500 active)
Latest user: karls_Corinthia

Asar: Under new management

That is correct.


Now can we stop poking ancient threads and take the ASM questions to the ASM forum?
<blm> zsnes users are the flatearthers of emulation
no how come asar accepts both JML [$0000] and JMP [$0000]?
Originally posted by Ladida
no

ban

Quote
how come asar accepts both JML [$0000] and JMP [$0000]?

Oversight somewhere ~5 years ago (how time flies...), when stealing the xkas opcode tables. That should be JML only.

But it's no big deal; the [] makes the desired distance clear, so there's only one possible thing for that to assemble to.

And even JMP/JML is no big deal, it just wastes a byte (I think I had to enable it in xkas mode). JSR/JSL is the important one; it crashes if misunderstood, so I made sure that Asar refuses to emit that. Blocking JMP $123456 is more for symmetry than anything else.
<blm> zsnes users are the flatearthers of emulation
seeing as this is already bumped and I had the random idea recently.
Wouldn't it be nice if asar could detect a SA-1 ROM and set a label in for the ASM file to use?
Like

Code
if SA1_ROM == 1
 incsrc sa1version.asm
else
 incsrc normalversion.asm
endif

Anime statistic on MyAnimeList:
400 animes completed ✓
6000 episodes completed ✓
100 Days completed ✓
... what even am I doing with my life?
you could technically already do that

if read1($whatever the address in the rom header is for rom type) == $sa1rom value
etc
100% sure Alcaro will answer with read1($00ffd5) == $23
GitHub - Twitter - YouTube - SnesLab Discord
Well, if there already is a convenient way like this.
Anime statistic on MyAnimeList:
400 animes completed ✓
6000 episodes completed ✓
100 Days completed ✓
... what even am I doing with my life?
There seems to be a bug with elseif.

The following code doesn't work:
Code
!n = 0

if !n == 1
print "!","n == 1"
elseif !n == 0
print "!","n == 0"
else
print "!","n > 1 || ","!","n < 0"
endif

Code
test.asm:5: error: Invalid number. [elseif !n == 0]
!n > 1 || !n < 0


For the record, this doesn't work, either:
Code
!n = 0

if !n == 1
print "!","n == 1"
elseif !n
print "!","n > 1 || ","!","n < 0"
else
print "!","n == 0"
endif

Code
test.asm:5: error: Label n not found [elseif !n]
!n == 0


In both cases, the elseif seems to be ignored. Even when !n is 0.

(Also, is there a reason why defines are substituted within strings? Or is this just a side-effect of how they're processed? Is there a more elegant way to escape defines within strings?)

EDIT: elseif 0 works, as does elseif 0 == 0. This seems to be a problem with defines when used in elseif conditions.
EDIT 2: functions work with elseif, but only if they don't contain defines.
GradientToolLevelMusic UtilitySM64 Clean ROM verifierHQX VirtualDub FilterImoSPC2 (Alpha)Music Section SPC PlayerEmbeddable SPC Player for SMWCYouTube EmbedderJSRomcleanJS Address ConverterLazyHDMA
The problem is that resolvedefines doesn't get called for elseif, it's because numif==numtrue is not true, not entirely sure how those 2 variables work atm but will follow up some other night.
apparently you can only use one elseif? adding more gives an "invalid number" error

aka

Code
if a
elseif b
elseif c ;invalid number
elseif d ;invalid number
else
endif



you can work around it by doing this at least:

Code
if a
elseif b
else
	if c
	elseif d
	else
	endif
endif
Never really understood why some coding languages implement their own elseif syntax. I always thought of it as a simple nested if, since in C (and many others), one liners and blocks (such as if and loops) don't need brackets. And since C is also fine with writing multiple lines of code in one line, it would be just a normal nested else-if, if you add a line break between the words.
Anime statistic on MyAnimeList:
400 animes completed ✓
6000 episodes completed ✓
100 Days completed ✓
... what even am I doing with my life?
I don't recommend using elseif at all, it has rather undefined behavior. I already had big troubles with it on Touhou Mario 2 and the SA-1 GPS before. use a chain of if/else instead.
GitHub - Twitter - YouTube - SnesLab Discord
Originally posted by JackTheSpades
Never really understood why some coding languages implement their own elseif syntax. I always thought of it as a simple nested if, since in C (and many others), one liners and blocks (such as if and loops) don't need brackets. And since C is also fine with writing multiple lines of code in one line, it would be just a normal nested else-if, if you add a line break between the words.

That method only works if you can use a single statement as a block of code.

In particular, it requires that the linebreak is not significant other than as a kind of whitespace.

Which excludes Asar. And Python and a few others.
<blm> zsnes users are the flatearthers of emulation
So I just went ahead and made an Asar 1.40, mostly just to implement a single function I needed for my own means, but while I was at it, I also fixed a load of bugs and added a lot of other nice-to-have features (many of which can already be implemented via Asar macros or functions, but having them built directly into Asar is more reliable and also a lot faster). Most notable changes include:
  • readfile functions: Allows you to read bytes from a different file rather than from ROM. Main motivation here was make a patch that reads bytes from a Lunar Magic .pal file and write them into a table in a format that can be DMA'd to CGRAM directly, all at compile-time.
  • select functions: Similar to if/else conditionals, but can be used in all places where math is allowed (such as in function definitions).
  • You can put \ at the end of a line to append the next line to it (similar to , at the end of line, except the \ doesn't appear in the concatenated line).
  • while loops: Work just like if conditionals, but assemble a block of code repeatedly. Useful for generating huge data tables without having to rely on macro recursion (which of course means they're not bound by the 256 depth recursion limit). It is possible to create infinite loops, though, so be careful.
  • print command can now print double variables when passed double() (that is, it can print a number with its fractional part).
  • Fixed (among many other things) the notorious "elseif" bug that failed to resolve defines in elseif statements.


For all other new features and bug fixes, check either the changelog or the comments on the upload itself. Please let me know of any bugs you find in this version of Asar, especially regarding patch compatibility.

Link:
https://www.smwcentral.net/?p=section&a=details&id=14560
Feel free to visit my website/blog - it's updated rarely, but it looks pretty cool!
Wow, that's actually really cool! I had no idea you were working on stuff like this. The changes you made don't actually affect me, but this is definitely the version I'll be using from now on.

And while I'm at it, @Alcaro: you once mentioned you had discontinued Asar and dislike the way you coded it back then. Just out of curiosity, would you mind explaining what you'd do differently today?


 
Originally posted by WhiteYoshiEgg
Wow, that's actually really cool! I had no idea you were working on stuff like this.


Haha, yeah, that's because I love surprising people! :P

As already mentioned, I mainly did it because there was that one missing feature I didn't know how to work around without leaving the bounds of Asar, namely the readfile functions. I could have used an external script to generate the tables I need, but that didn't feel like a pleasing solution to me (mainly because it requires you to install some kind of interpreter on the system, unless you use bat files, which I have no experience with). Anyways, while I was already at it, I thought "well, why not implement those other features I wanted to have in the past and also fix a few of the bugs that annoyed me".

Ironically, I encountered a lot of the bugs I fixed just from working on Asar. I didn't know about them beforehand and only stumbled across them while verifying certain features or adding in my own stuff. This mainly goes for most of the bugs related to functions. I didn't know about those until trying to add in my own functions and noticing they were never executed correctly.

Originally posted by WhiteYoshiEgg
And while I'm at it, @Alcaro: you once mentioned you had discontinued Asar and dislike the way you coded it back then. Just out of curiosity, would you mind explaining what you'd do differently today?


After having worked on this, I can kinda see what he means. The source code of Asar isn't in the best shape. This means: in some places it's hard to understand and therefore hard to maintain (and even harder to extend). A lot of things are hard-coded, there is a lot of macro abuse and many problems are solved "in-place" with little structure on a higher level. Basically, when you write a compiler for a programming language and want to have it clean and extensible, you'll probably want to generate an AST. Asar doesn't do that, but instead basically just reads line by line from the source file, then splits that line into words and does some stuff, depending on what words it found in that line. This works fair enough, but has its limitis and is bound to get confusing sooner or later. It's also difficult to extend. Asar's main code generator, for example, is basically just a giant if/elseif block with all functionality hardcoded there, so if you want to add functionality to Asar, you basically have to hijack this enormous construct (which I had to do for adding while loops). Some code is also "all over the place", making it a bit difficult to find what you're looking for.

As much as object orientation is overused nowadays and used in a lot of wrong places, I think a parser & compiler is actually one of the things that could actually benefit from it when used correctly and could make your code a lot more maintainable and extensible (although technically, that doesn't even necessarily require objects per se, what reallys matters is just having a clear and structures hierarchy of things that's easy to extend).

Those are basically the impressions I've got so far, but then again, I may just not be used to this kind of code, since the code I encounter at work is usually very different, which makes sense, considering I enqounter game code most of the time and only rarely code for tools.
Feel free to visit my website/blog - it's updated rarely, but it looks pretty cool!
Does this build also include the struct keyword that p4plus2 was working on? If no, it would be great if you could add it, you can find it on his git account.
Anime statistic on MyAnimeList:
400 animes completed ✓
6000 episodes completed ✓
100 Days completed ✓
... what even am I doing with my life?
It doesn't yet and I wasn't aware that he was working on a version of his own (or, well, I was aware that he had some custom Asar build, but I thought it was just for personal needs that diverge a bit from the needs of Asar in terms of SMW hacking). Can you give me a link to the repository? If so, I can take a look and see what I can do.
Feel free to visit my website/blog - it's updated rarely, but it looks pretty cool!
link to repo
here's an example of what it looks like in practice:

Code
struct dma $4300
	.control: skip 1
	.destination: skip 1
	.source
		.source_word:
			.source_word_low: skip 1
			.source_word_high: skip 1
		.source_bank: skip 1
	.size:
		.size_low: skip 1
		.size_high: skip 1
endstruct align $10

	LDA #$2202
	STA dma[1].control
	LDA #.palette
	STA dma[1].source
	LDA #$012E
	STA dma[1].size
	SEP #$20
	LDA #.palette>>16
	STA dma[1].source_bank
	LDA #$02
	STA $420B

Anime statistic on MyAnimeList:
400 animes completed ✓
6000 episodes completed ✓
100 Days completed ✓
... what even am I doing with my life?
Oh. That does look useful enough to belong in there, and all changes required for that feature seem to be contained in just a single commit, so it should be rather easy to copy (well, that commit also contains a bunch of other changes which I won't copy, such as changing long double into an int64_t - I think this would actually break some of my new features - but I don't think these changes affect the struct functionality at all). I'll take a stab it at later and then probably bump the version to 1.41.
Feel free to visit my website/blog - it's updated rarely, but it looks pretty cool!