hex()now take an optional width argument that allows padding the number with zeroes. (randomdude999)
objectsize()functions don't need quotes around the struct name anymore. For backwards compatibilty, quotes are still allowed. (p4plus2)
optimize address. (p4plus2)
ceil()functions have been added. (randomdude999)
<:function and math operator have been added (p4plus2)
datasize()function has been added. (p4plus2)
undefcommand inside an unexecuted
ifstatement would still get executed. This is now fixed. (randomdude999)
assertcommand would give strange errors when the condition to test contained a comma. This is now fixed. (randomdude999)
warnings enablecommand no longer prints the error message three times. (randomdude999)
!assembler_ver) are now always present. Previously they were missing when the DLL was called without specifying a standard defines file. (randomdude999)
LSR #4don't accept labels in their argument anymore. (randomdude999)
arch spc700. Now
adc.w a, $0properly assembles to
85 00 00instead of
84 00. (randomdude999)
arch superfxignoring all commands with more than 2 words (randomdude999)
canread()functions returned true for the first byte after the end of the ROM. That has been fixed.
check bankcross offnow should mess with the PC less (i.e. no forced fastrom addressing).
errorcommand now doesn't print the line of code that caused the error. All warnings except for the one from the
warncommand should now print the line of code that caused the warning. (note that not all warnings or errors are associated with a specific line of code.)
fullsa1rommapper now supports automatic freespace searching. (randomdude999)
incbinranges can now use math as an alternative to unprefixed hex. To use this, surround the math with parentheses. For example,
incbin file:(4+2)-($F+$10). Note that in math statements, unprefixed numbers are decimal, not hex! (randomdude999)
ddshould work better (randomdude999)
prot(randomdude999, found by WhiteYoshiEgg)
if !conditionwas removed without a proper deprecation process. It has been re-added with a deprecation warning, because a few patches still managed to use it.
defined()function (randomdude999) and
:now for consistency. (RPG Hacker)
?. (RPG Hacker)
macro my_macro() ?MacroLabel = $008000 dl ?MacroLabel ; Valid endmacro %my_macro() dl ?MacroLabel ; Error!
#will create that label without modifying existing label hierarchies. This is mainly intended for hacky incsrc/routine macros as used by GPS, which can break existing label hierarchies when used. (RPG Hacker)
Note that while it's technically possible to use this feature on sub labels, macro labels and macro sub labels, I don't think there's any reasonable use case for this. In most cases, regular macro labels and regular macro sub labels are recommended for usage inside macros.
macro my_new_routine() jsl MyNewRoutine !macro_routine_defined ?= 0 if !macro_routine_defined == 0 pushpc freecode cleaned #MyNewRoutine: incsrc routines/mynewroutine.asm pullpc !macro_routine_defined = 1 endif endmacro Main: %my_new_routine() .Sub ; Both of these are found dl MyNewRoutine dl Main_Sub
\!(useful for preventing Asar to replace defines in certain places). (randomdude999)
\\. (RPG Hacker)
pullbase. (randomdude999, RPG Hacker)
check titlecommand which makes Asar verify the title of the output ROM (to assure a patch is applied to the correct ROM). (randomdude999)
namespace nested on
check bankcross offwhich disables checking for bank crossing. Use with caution; might not work with certain features or outright break some stuff. (randomdude999, RPG Hacker)
filesize()function and a
stddefines.txt- see manual for details. (RPG Hacker, randomdude999)
includeoncecommand for shared files which may be included multiple times, but should only be assembled once. (RPG Hacker)
.l) are now also supported for the SPC700 architecture. (KungFuFurby)
stringsequalnocase()functions. (RPG Hacker)
!assembler_verare supported. Trying to modify those defines will throw an error. (RPG Hacker)
;@works. This command was really meant for backwards-compatibility with xkas and is supposed to assemble everything following it, which it now does again. (RPG Hacker)
When Asar finds an unknown command on a line starting with
;@asar 1.60 @asar 1.60 asar 1.60
@, it only throws a warning instead of an error. You can make use of this fact by using optional features from newer Asar versions and still have your patch assemble in old Asar versions, where those features are ignored (don't know how practicable and useful this really is, but in theory, it should be possible). And of course it can be used for patches that are compatible with both xkas and Asar, not that that's particularly useful anymore in this day and age.
$7Dcan be used correctly. (randomdude999)
freedata align. (TheBiob)
padcommand that made it not update the pc correctly and also made it trigger a bank cross error before actually writing any data into a new bank. (RPG Hacker)
canreadfile()crashing when reading from more than 16 different files in the same patch. (randomdude999)
math round onmaking the values negative sometimes. (randomdude999)
print double()not working when any of their arguments contain commas or parentheses. (randomdude999)
readfile1()via user-defined functions. Previously, this failed as Asar expected all parameters in user-defined functions to be numbers. (KevinCathcart)
aband a paramater
abc, Asar occasionally returned the parameter
abcwhen referencing the paramter
autoclear, which is an alias of
autoclean. Please use only
autocleanfrom now on.
freespace fixed, which is an alias of
freespace static. Please use only
freespace staticfrom now on.
if !condition. This feature was planned for deprecation as it bites with Asar's define syntax, but it was removed earlier than planned because, after inspecting the code, it was determined that it didn't work properly and probably wasn't even usable in versions prior to 1.60 at all. The only way to use it in Asar 1.60 was by using the new escape sequence for !, which didn't exist in earlier Asar versions. Thus it can be assumed that the feature wasn't used in previous Asar versions and can be removed safely. To negate conditions in Asar 1.60, either use the built-in logic functions (
if !(a == 0 && b == 0)becomes
if not(and(equal(a, 0),equal(b, 0)))) or directly negate the condition (
if !(a == 0 && b == 0)becomes
if a != 0 || b != 0).
freedata, for example), but I can't verify this.
pulltablecommands, which let you back-up or restore the current character table to the/from the stack.
ext\notepad-plus-plus\syntax-highlighting.xml. This file can be imported into Notepad++ as a user-defined language to add syntax highlighting for Asar patches, featuring all commands currently supported by Asar. By default, this syntax highlighting is enabled on all files with an extension of
.asr, but this can be customized via Notepad++.
;@that don't map to a recognized special command now only throw warnings at best and no errors.
readfile4(filename, offset)- similiar to
read1()etc. functions, except data is read from another file instead of from the ROM (note that offset is a PC offset, not a SNES offset). You can pass an optional third value which is returned if the read fails. These functions are primarily intended for reading bytes from another file and then doing math with them. For example: reading bytes from a Lunar Magic .pal file, converting them into a different format and then writing them to the ROM as a table that can directly be DMA'd to CGRAM without further conversions (all conversions happen at compile-time). As an additional bonus, all of those functions cache any file passed to them (up to 16 simultanous files), which means that multiple readfile() calls on the same file will keep the file open rather than repeatedly opening and closing the file.
canreadfile(filename, offset, length)- basically the
pctosnes(address)functions: for manually converting addresses (note that those functions are dependent on the ROM's current mapping mode, so use them with caution - chances are you will never need them at all).
clamp(value, min, max)functions:
min()return the maximum/minimum of two values, whereas
clamp()makes sure that that value is
safediv(dividend, divisor, exception)function: divides
divisoris 0, in which case
select(statement, true, false)function: if
falseis returned, in any other case,
trueis returned. Basically, a mathematical version of "if/else". Please note that unlike if/else blocks, function arguments in Asar are always evaluated before a function returns. In other words: if you do
select(1, 1/1, 1/0), Asar will throw a "division by zero" error, even though the function would return 1/1. In this particular case, it's recommended to simply use the
safediv()function in place of a regular division.
not(value)function: returns 1 if
valueis 0 and 0 in any other case.
greaterequal(a, b)- rather self-explanatory, return 1 if the respective comparison is true and 0 otherwise. Primarily intended to be passed as statement to
xor(a, b)- also self-explanatory, return 1 if the respective logical operation is true and 0 otherwise. Primarily intended to be passed as statement to
whileloops: Added compile-time
whileloops to Asar. Those work similar to if conditionals, with the difference that their blocks are assembled repeatedly until their condition becomes false. For easier implementation and higher compatibility, while loops are terminated with
endif, just like
ifconditionals. When using while loops, be careful not to cause an infinite loop. Asar won't make any effort to detect those.
\at the end of any line of source code and Asar will append the next line to it. This is similar to putting a
,at the end of a line, with the difference, that the
\itself does not appear in the concatenated string, whereas the
,would. This is useful to split long function definitions into multiplie lines, for example. Note that all whitespace following the
\is ignored, whereas whitespace preceeding the
for example, whereas
db \ $FF
double(num)print function: Can be passed to print to print a double variable with its fractional part. Has a default precision of 5 decimal places, but can be passed an optional second argument to override the precision.
round(num, precision)function: Rounds the double variable
precisiondecimal places. Pass 0 as precision to round to the nearest integer.
read4(), but always threw "Wrong number of parameters to function" errors when actually using those overloaded versions.
canread()when passing 2 arguments to it, because it actually treated it as
canread1()due to an internal error in string comparison.
would assemble to
00 00 00 80(
$80000000) in Asar 1.37, it now assembles to
FF FF FF FF
elseifconditionals now get properly resolved.
#=define operator now doesn't truncate its value when using
math round off, making it possible to do double-precision math with it.
@xkas : @asar 1.37on the first line would previously lead to an error, whereas putting
@asar 1.37 : @xkasthere would not. Both variations lead to an error message now, since it really doesn't make much sense to use them together in any combination.
@includecould previously be used on the first line only and needed to be chained with a
:inbetween. They can now be used on any line as long as no other command comes before or inbetween them.
src/test/arch-superfx.asmwas never edited to acknowledge this fix, so the test always failed
?=) to manual.txt. Those have been in Asar for quite a while, but were never documented yet, although they can be quite useful.
freespaceargument added; a
$xxbyte that will search the ROM for contiguous sections of that byte. Before it was hardcoded to only search for
$00. Default is still
$00if not supplied, so past patches should not be broken.
autocleanwas hardcoded to clean using
$00. This was fixed also to clean with the byte supplied by freecode, or
$00if not supplied.
lms r0,($00D4)used to output
3D A0 D4, which is actually incorrect because short addressing doubles the byte supplied by the instruction to give a range from
$01FEwith just one byte (since Super FX reads words). This now outputs
3D A0 6Awhich is correct. Also, asar now throws an error for anything outside
$01FEas well as all odd-numbered addresses for both
lmsinstructions. (Odd-numbered addresses cannot be accessed using short addressing due to the multiplying by 2.)
0xFFFFFFbecause freespace addresses use a high byte to indicate that they're freespace.