_    _ _                       _____ __  __   _______          _
| |  | | |               /\    / ____|  \/  | |__   __|        | |
| |  | | |__   ___ _ __ /  \  | (___ | \  / |    | | ___   ___ | |
| |  | | '_ \ / _ \ '__/ /\ \  \___ \| |\/| |    | |/ _ \ / _ \| |
| |__| | |_) |  __/ | / ____ \ ____) | |  | |    | | (_) | (_) | |
 \____/|_.__/ \___|_|/_/    \_\_____/|_|  |_|    |_|\___/ \___/|_|
         Version 2.1                By Vitor Vilela & Fernap

Thank you for downloading UberASM Tool. We hope it helps you on your SMW hacking journey.

Overview/FAQ

Q. What is UberASM Tool?

A. UberASM Tool is a program that lets you manage various UberASM resources, applying them to different levels (usually levels, but sometimes overworld maps, or game modes) as you wish. UberASM Tool applies several hijacks in key places in an SMW ROM which allow it to run code for UberASM resources at specific times during the game, such as once per frame during levels. This approach offers a good compromise between flexibility and ease of managing resources; resources can be added, removed, or applied to different levels easily. You can generally do more things with a dedicated patch than with an UberASM resource, but removing a patch or having a patch be active only for certain levels is generally more difficult. There's also much less risk of two UberASM resources conflicting with each other than there is for two patches.

Q. What's new in 2.0, and what should I be aware of when upgrading to 2.0 from 1.x?

A. Version 2.0 of UberASM Tool is a signficant update to the program. If you try to run it out of the box with your existing list.txt file, you'll notice an error during list processing that the sprite: command is no longer supported. Simply change sprite: to freeram: in your list.txt, and remove the sprite-sa1: line. The way the global code file works has also changed. See Common Issues below for how to convert any any resources that that use this.

Other new features include:

Q. What's new in 2.1?

A. Version 2.1 of UberASM Tool is a modest update compared to the 2.0 update.

Q. Help! ___ doesn't work anymore!

A. That's not a question! See Common Issues for some potential hiccups, and see the incompatibilities.txt file for known incompatibilities and what to do about them.

Q. I've downloaded a patch/block/sprite that has some uberasm, but the instructions don't really make sense with the current version of UberASM Tool. What should I do?

A. You've probably got something meant for the global code file or even the original UberASM patch. See Common Issues below for steps to make them work.


Table of Contents:

  1. General Use
    1. Quick Start
    2. Running UberASM Tool
    3. The List File
    4. The Library
    5. Common Issues
  2. Technical Information
    1. Resources
    2. Labels
    3. The DBR
    4. Extra Bytes
    5. NMI
    6. The Library
    7. Shared Routines
    8. Other Code Files
    9. SA-1
    10. Dos and Don'ts
  3. Credits and Ackknowledgements

Part I: General Use

Quick Start

  1. Copy the contents of the UberASM Tool .zip file to a dedicated folder somewhere within your project. Right now, best practice is to keep a separate copy of UberASM Tool for each project that you're working on (although there are plans to add flexibility here in a future version).
  2. Place the .asm files for whatever UberASM resources you're using into the level/, gamemode/, or overworld/ folders as appropriate (most resources will be for levels, and resources may have additional instructions as well, so be sure to check for them).
  3. Edit your list file (usually list.txt in the UberASM Tool folder) and change the rom: command to point to the location of your ROM file. It can be given either relative to the UberASM Tool executable (like ../myrom.smc) or as an absolute path.
  4. If you're upgrading from 1.x and using an existing list file, remove the line with sprite-sa1: (if it's there), and on the line with sprite: ..., change sprite to freeram.
  5. Add the resources you want to use to the list file. For example, to use a resource named LRonoff.asm in the level/ folder for level 105, you'd add the line 105 LRonoff.asm under the level: section of the list file. See The List File for more detail.
  6. Run UberASMTool.exe (either double click on the icon, or run it from the command line). See below for command line options and more.

Running UberASM Tool

UberASM Tool has the command line syntax:

> UberASMTool [options...] [<list file> [<ROM file>]]

If no <list file> is given, UberASM Tool will use the file list.txt. If no <ROM file> is given, UberASM Tool will use the ROM file given by the rom: command in the list file. For example:

rom: MyHack.smc         ; ROM file to use.

All files may be given either as absolute paths or as paths relative to the UberASM Tool executable file. Alternatively, you can simply double click the executable and it will run as if no command line arguments were given.

The following options are supported (and strictly speaking may be placed in any order in the whole command line):

-d <directory>
Sets UberASM Tool's current working directory to directory, which can itself be either an absolute path, or relative to the executable. Any further relative paths will be relative to this, rather than the default of the executable.
-p
Disables the Press any key to continue... prompt when finished.
-q
Enables quiet mode (the same as setting verbose: quiet in the list file). This supresses a couple messages that can get displayed before the list file is actually processed.
-v
Prints the version number of the program and exits.

The List File

The list file (list.txt by default) contains configuration information for UberASM Tool, including what resources to use for what level/game mode/overworld map, along with some other information. For commands that take file names, you can either give absolute paths, or you can give relative paths, in which case UberASM Tool will look relative the directory of the UberASM Tool executable.

You may add comments to the list file. A ; or a # begins a comment, and the rest of the line is ignored.

The following commands are available:

verbose: <on/off/quiet/debug>
Sets the verbosity level for UAT. This command is optional and defaults to "off" if not specified.
quiet
Only error messages are displayed
off
Basic information about progress is also displayed
on
Extra information is displayed, such as individual library/ resource file progress, and a more detailed breakdown of total insert size
debug
Even more detailed information is displayed for debugging purposes. Also prevents UAT from deleting temporary files in asm/work/
deprecations: <on/off>
When set to "off", deprecation warnings from asar are not displayed. This command is optional and defaults to "off" if not specified. It's recommended to turn "on" deprecation warnings when developing new resources, but they're otherwise not usually relevant.
rom: <ROM file>
This specifies the ROM file that UberASM Tool will use. A ROM file may also be given on the command line, which will override the list file command (and the command may be omitted altogether in this case).
global: <asm file>
statusbar: <asm file>
macrolib: <asm file>
These specify the .asm files for the global code file, the status bar code file, and the macro library file. These are all required, but there are defaults in place initially. It's unlikely that you'll ever change these, but you can if you need to. See below for more information about how these are used.
freeram: <RAM address>
Specifies 2 bytes of free RAM used to keep track of the previous game mode. It must be given as as a full address in the $7E0000-7FFFFF range ($400000-41FFFF is okay too if using SA-1). This command is required, but the default value in place initially will likely be fine. More may be required in the future, but previous versions required 38 (68 on SA-1) bytes, rather than the current amount.
level:
overworld:
gamemode:
These commands indicate whether subseqent resources are for a level, an overworld map, or a game mode, respectively. Resources must occur somewhere after one of these, but you can switch between them freely.

Finally, anything else is interpreted as assigning resources to levels/gamemodes/overworlds, which has the form:

<number|*> <asm file> [: <extra byte 1> <extra byte 2> ...] [, ...]

<number> is the level number (0-1FF), game mode number (0-FF), or overworld map number (0-6, 0 = Main map; 1 = Yoshi's Island; 2 = Vanilla Dome; 3 = Forest of Illusion; 4 = Valley of Bowser; 5 = Special World; and 6 = Star World). Numbers here must be in hexadecimal. You can also specify * instead of a number, which is a special value that indicates that this resource is to run on all levels (or game modes, or overworld maps).

<asm file> is the name of the resource file to use. For levels, UAT looks relative to the level/ folder, for game modes, the gamemode/ folder, and for overworlds, the overworld/ folder. You may give paths relative to these, or you may also give an absolute path.

If a resource uses extra bytes (see below for more information), you must specify them after the resource file name with a : followed by the actual bytes to use. For more than one byte, separate them by spaces. Bytes are given in hexadecimal by default (or explicitly by prefixing with $ or 0x), but you can also give them in decimal by prefixing with an @, or in binary by prefixing with a %. You may also specify negative numbers here. So for example, -10, F0, $f0, -@16, @240, and %11110000 all refer to the same value. As of version 2.1, you can also speciy 2- and 3-byte values as a single number. For 2-byte values (words), enclose them in parentheses, e.g. (@1000), and for 3-byte values (longs), enclose them in brackets, e.g. [12AB00]. This is especially useful for supplying large decimal values to resources without having to convert to little-endian hex (see below for more info).

You may also assign more than one resource to each level/game mode/overworld map, including *. Simply add them in order, separated by commas. You may split resources over separate lines if you wish, but the comma must go on the same line as the preceding resource. Note that if multiple resources are given for a single level (or game mode or overworld map), UAT executes them in the order they are given, and resources under * are called first. This usually doesn't matter, but it can sometimes be something to keep in mind.

As of version 2.1, you can now skip a resource that was used on level/overworld/gamemode * by adding a - in front of the file name. Note that for this to work, the resource must actually be used in *, and * must be placed before where it's actually being skipped. A potential, nonobvious application of this feature is that you can skip a resource on * that uses extra bytes, and then re-add it with a different set of extra bytes to use a different set just for that level/overworld/gamemode. See the example list file below for an example use.

An example (just the resources are given; the other commands are omitted for clarity:

; Example list file...this line is a comment.
# so is this

level:
   105 incio.asm
   106 incio.asm,                 ; comment here too
       waves.asm, gradient.asm

overworld:
* music.asm, yoshi.asm : 00
0 -music.asm
1 -yoshi.asm, yoshi.asm:FF

level:
107 special.asm:@100, ../overworld/music.asm

The Library

Some resources may come with external library files. These should be placed in UberASM Tool's library/ folder. Any files in here are automatically included in your ROM and made available to UberASM resources. See below for more technical detail on UberASM's library system.

Common Issues

UberASM Tool 1.x allowed resource labels to be upper case (Main: or MAIN: instead of main:, for example). This was undocumented and no longer works in 2.0 (mainly for technical reasons). If a resource doesn't seem to be working (and especially if it did in 1.x), check to make sure the main resource labels (init:, main:, load:, and nmi:) are lower case. Note that this doesn't apply to other labels or to labels in a library file, since those are called explicitly by the resource itself.

There's also one change in how library labels are exported that can affect existing resources. In 1.x, if a library file named Foo.asm also containd the label Foo:, UAT would simply export the label Foo: instead of Foo_Foo: as the documentation suggested. This has been standardized for 2.0. Simply change any references like this if you get an error when trying to insert such a resource. For example, if you see jsl Foo, change it to jsl Foo_Foo.

You may run into resources (patches, uberasm, etc) that want you to copy and paste some code into UberASM Tool's global code file. If that code was destined for the init: label, it should work the same, but previous versions (1.x) also had support for main:, load:, and nmi: labels, which are no longer used. For code that goes under load:, make a new file and place the code under a load: label, but ending with RTL instead of RTS as the instructions might suggest. So,

load:
    <code to paste>
    RTL

Then put the new file in UAT's level/ folder and add it as a resource for level * in your list file.

Similarly, for code that goes under main:, make a new file and place the code under both main: and init:. So,

init:
main:
    <code to paste>
    RTL

Then put the new file in UAT's gamemode/ folder and add it as a resource for game mode * in your list file. For global code for the nmi: label, do the same, but just place it under nmi: in a new file.

As of the 2.0 release of UberASM Tool, there are a couple incompatible patches: lx5's NSMB star coins patch, and HammerBrother's SMA2 Slide Kill Chain patch. Assuming they haven't been updated by the time you read this, see the incompatibilities.txt file for instructions on making them work with the new version.

Some even older resources may talk about pasting code under level###: or something similar. If you run into this situation, you'll want to make a new .asm file (for level, overworld, or game mode, as appropriate) and paste the given code under a label called main:, but ending with RTL instead of RTS. Similarly, do the same for code for level###init:, place it under the init: instead. Then add the new file to your list.txt wherever you want to use it.

As of version 2.0, UberASM Tool will refuse to run on a ROM that has had a newer version of UberASM Tool used on it. It's recommended that you simply upgrade to the current version in this case. If for some reason you can't do that, you can force it to run by editing the asm/base/clean.asm file, and changing the !OldVersionOverride define to 1. But do so at your own risk; future versions may introduce breaking changes that will prevent older versions from cleaning up correctly. Also note that versions 1.x make no such check and will attempt to run anyway. As of 2.0, it should still work properly, but again, this may change in the future.

Resources wanting to access the sprite load table (unlikely, but possible) need to know if it's been remapped by Pixi. UberASM Tool looks to see if Pixi has marked it so and sets some defines appropriately. However, if Pixi has not been run yet, then UberASM Tool will assume the remap hasn't happened, when in fact it might be done later. To work around this, you can either rerun UberASM Tool after Pixi, or add the line %Force255SpritesPerLevel() to the your macro library file (other/macro_library.asm by default). Note that the sprite load table defines in versions of UberASM Tool prior to 2.0 simply didn't account for the remap possibility, and any resources relying on them would have likely failed in this case anyway.


Part II: Technical Information

The following sections describe the technical aspects of UAT in more detail. This is mainly intended for programmers and resource creators. If you're making a hack without getting into the details of ASM programming, you can probably skip this part, although there may still be some useful information here.

Resources

Resources are the main entities that UberASM Tool uses to achieve effects in the game. They can be used for levels, for particular game modes, or for particular overworld maps. However, there's no fundamental difference between the types, and a level resource can also be used as an overworld resource, for example. To make a resource for UberASM Tool, you simply need an .asm file that contains one or more special labels that UAT calls. These labels are main:, init:, nmi:, load: (for levels only), and end: (new to v2.0). See below for more specific information on each label. For example, here's a level resource that drains one coin from Mario every 4 frames:

main:
    LDA $9D
    BEQ .Return      ; don't run if sprites are locked
    LDA $0DBF|!addr
    BEQ .Return      ; don't run if already at 0 coins
    LDA $14
    AND #$03
    BNE .Return      ; only run every 4th frame
    DEC $0DBF|!addr  ; decrement coin count
.Return:
    RTL

As of v2.0, resources can also specify that they take extra bytes, similar to extra bytes for custom sprites. For example, suppose you have an UberASM resource for a wind effect that pushes on Mario. Previously, such a resource might have needed to use a define to set the wind speed. So if someone wanted to use the same effect in different levels with different wind speeds, they'd have to make separate copies of the resource with a different define value for each one. This wastes ROM space and makes organization difficult for the hack creator. Instead, now you can simply have your resource take an extra byte that gives the wind speed, and the same resource can be used in multiple levels with different wind speed values. See Extra Bytes for more information on how to write resources that use this feature, and see The List File for how users can specify extra bytes for resources in the list file.

Labels

The labels main:, init:, end:, and nmi: are available for all resource types, and level resources additionally have the load: label.

For levels, the load: label is called once, early in the level loading process. The primary purpose of this is to set up Lunar Magic's conditional direct map16 flags. See the Lunar Magic documentation for more information about this. The init: label is also called once, after the level is done loading and before fade-in. The main: label is called once at the beginning of each frame during normal level operation (in game mode $14), and end: is likewise called at the end of each frame (but before the OAM table information at $0420 is copied to $0400).

Overworld resource labels are similar, but run in game mode $0E (and have no load: label).

Game mode code's init: and main: labels will run at the start of the main game loop. On the first frame the mode is active, init: is run, and on all subsequent frames, main: is run. The end: label is run after the entire rest of the game loop, including the $0420 -> $0400 conversion routine. You may have noticed that UberASM Tool supports game modes $00-FF, even though SMW only uses game modes $00-29. Any game mode $2A or higher is a custom mode, and thus there will be no base SMW routine to run for that frame (except for the standard NMI routine).

For all resource types, the nmi: label runs early during SMW's NMI routine. Level resources have their NMI label called during game modes $13 and $14, and overworld resources during game modes $0D and $0E. In both cases, actual game mode code under "nmi:" will run first. See NMI for more information. As of version 2.1, level NMI routines also run in game modes $05-07 in order to be active on the title screen, but this can be disabled by editing asm/base/uber_defines.asm and changing the !DisableTitleScreenLevelNMI define to 1.

The DBR

By default, UAT sets the DBR (data bank register) to the appropriate bank when calling resource code for labels other than nmi:. This behavior is often not needed, and can be turned off for a resource if its .asm file contains the exact line (starting at column 1) ;>dbr off somewhere in the source file. Note that if you do need to set it manually, you don't need to worry about restoring it (unless set to a bank without RAM mirrors); UAT will do so after all resources have been called.

Extra Bytes

To tell UberASM Tool that a resource takes a fixed number of extra bytes, it must contain a line of the exact form (starting at column 1) ;>bytes <number> somewhere in the resource's .asm file. Only the first such line is read, and <number> must be a decimal number in the range 0-255 that says how many extra bytes this resource uses.

As of version 2.1, UAT also allows resources to take a variable number of extra bytes; to indicate this, use the line ;>bytes any instead. This will cause UAT to accept any number of bytes (including none, max still 255) to be specified each time a resource is invoked in the list file. In this case, the first byte passed to the resource will be a count of the number of bytes that were supplied in the list file (which may be 0 if none were specified), and the extra bytes themselves will start from the second byte.

Also as of version 2.1, users can specify word and long values as extra bytes in the list file (see above for how). UAT will store these in little-endian order, so for example, if a user specifies a 2-byte value as (@300), this will be stored in order as 2C 01, since 300 decimal = 12C hex.

Generally UAT passes a 16-bit pointer to the extra bytes for the current level/gamemode/overworld in $00-01. So for example, to load the third extra byte, you can use the code:

main:
    LDY #$02              ; load the offset into Y, first byte at offset $00, etc.
    LDA ($00),y           ; load the accumulator with the extra byte whose offset is in Y
    ; do something
    ; ...
    RTL

Note that this relies on the DBR being set prior to running this code. UAT sets it by default, but that behavior can be disabled (see The DBR for more info), so you'd either need to set it yourself, or just not disable it in the first place.

However, there's one case where it's different – namely in the nmi: label on SA-1 roms. Here, the pointer is placed on the stack, 4 bytes from the top. So for example again, to access the third byte, you can use the code:

nmi:
    PHK : PLB             ; the DBR must be set to the current bank
    LDY #$02              ; load the offset into Y -- first byte at offset $00, etc.
    LDA ($04,s),y         ; load the accumulator with the extra byte whose offset is in Y
    ; do something
    ; ...
    RTL

Note that you must be careful that if anything is pushed onto the stack before reading the extra byte data (which can happen if this code is in a subroutine that has been JSRed to, for example), you must take this into account when loading extra byte data.

To write hybrid lorom/sa-1 nmi: code as above, you might have something like:

nmi:
    PHK : PLB
    LDY #$02
    if !sa1
        LDA ($04,s),y
    else
        LDA ($00),y
    endif
    ; do something
    ; ...
    RTL

Note that if you write a resource that uses extra bytes, but someone attempts to insert it with an older (1.x) version of UberASM Tool, it will still appear to insert, but it won't work correctly. You can use the %require_uber_ver() macro to cause it to fail to insert in older versions; see Other Code Files for more information.

NMI

There are some special considerations that should be taken into account for UberASM code that runs under the nmi: label. If a resource uses extra bytes, the way these are accessed here is different on SA-1; see Extra Bytes for more detail.

If the game's NMI routine (which includes UberASM Tool's calling of resources' nmi: labels) takes too long, there can be noticeable graphical glitches, generally black bars at the top of the screen. To help avoid this, NMI code should be optimized for speed. To this end, UAT does not set the DBR for resources when calling the nmi: label. You're free to do so if you need, and if so, it does not need to be restored before returning (as long as it's set to a bank with RAM mirrors). See The DBR for more detail.

Finally, the main game code may not have finished running by the time that NMI code is run (i.e., the game is lagging, or experiencing slowdown). If this is the case, the value in memory location $10 will be nonzero, and you may not want to run your NMI code at all. If you do, special care needs to be taken on SA-1 (including hybrid resources that might run on either), since the SA-1 CPU does not get halted during NMI, but continues to run alongside the regular SNES CPU. In this case, normal scratch memory ($00-0F) is not safe to use. Instead, you can use absolute addressing, $0000-000F, which is scratch WRAM that the SA-1 CPU has no access to. Any scratch memory that you use during lag must be preserved, with the exception of $00-01 ($0000-0001 on SA-1); UberASM Tool uses this itself and restores it after all resources have been called.

The Library

UberASM Tool supports a system for shared library code that different resources can access. Files for the shared library should be placed in the library/ directory. You can have source (.asm) files, or binary (anything else) files.

Binary files simply get included (via an incbin) verbatim, with a single label exposed with name the same as the file's name without the extension. For example, if there's a file called library/PlayerGfx.bin, then all resources will have the label PlayerGfx: available at the start of the file's contents. Each binary file will have its own freedata area in the ROM. Likewise, source files get included into their own freecode region. Any labels in a source file will be available to resources with the file name prefixed. So for example, if the file library/math.asm contains the labels sqrt: and atan2:, then you can call these as routines with JSL math_sqrt and JSL math_atan2, respectively. Be aware that the DBR is not set automatically.

Since the filenames are used as label prefixes, library file names must be valid Asar labels. They must start with a letter and contain only letters, numbers, and underscores. However, they can also contain spaces, which UberASM Tool will convert to underscores. Furthermore, you may place library files into subdirectories. Label prefixes for files in subdirectories will have slashes converted to underscores. For example, the file library/stuff/My routine.asm will have its labels prefixed with stuff_My_routine_.

There a couple main disadvantages of the library system. First, library files are included in the ROM whether or not they're actually used. So you may wind up with wasted ROM space. Second, library files cannot call other library files. However, as of version 2.0, UberASM Tool has support for a shared routine system similar to that of Pixi and GPS which overcomes these limitations.

Shared Routines

UberASM Tool 2.0 adds support for shared routines. These are similar to those of Pixi and GPS, but are implemented a little differently. Shared routines are simply .asm files that have common code that different resources can call (one routine per file). To call a shared routine called name, add the line %UberRoutine(name) to your resource code. (This differs from Pixi and GPS, where you'd simply call %name() instead). Routine files must be located in the routines/ directory; see there for what's already included and available to use. Note that unlike libraries, routines are added to the ROM on-demand. If nothing uses a routine, it won't take up any space in the ROM. Also unlike libraries, shared routines may call other shared routines freely. And note that libraries may call shared routines. On the other hand, whether or not a shared routine can call a library will depend on where the routine is first used – if it's first used from a resource, it will work, but if it's first used from a library, it won't (because libraries can't call other libraries). It's probably best to just avoid this case altogether.

To make your own shared routine, simply create a new .asm file with the name of the routine in the routines/ directory (directly, not in a subdirectory). Execution starts at the beginning of the file; no label is needed there. The routine is JSLed to, so the DBR is not set automatically, and your routine should end with an RTL.

IMPORTANT: Due to the way shared routines are implemented, any labels in the routine MUST be macro-local. That is, they must start with a question mark.

So, for example, a shared routine that returns the first open sprite slot in X (or $FF if there are none) might look like the following:

    LDX #!sprite_slots-1
?-
    LDA !sprite_status,x
    BEQ ?Return
    DEX
    BPL ?-
?Return:
    RTL

If you place this as the file routines/FindFreeSpriteSlot.asm, then you can then call this from any library, resource, or other shared routine file by using %UberRoutine(FindFreeSpriteSlot).

Other Code Files

The macro library file (given by macrolib: in the list file) is included in every file assembled by UberASM Tool – resources, libraries, routines. If you wish, you can place common defines and macros here. Previous versions also put standard defines and macros here, but those have now been split out into asm/base/uber_defines.asm. Some pre-existing macros of note:

%require_uber_ver(major, minor)
Fails if the current version of UberASM Tool is less than major.minor. This will also cause a resource to fail on 1.x versions as well since this macro is new to 2.0. This is particularly useful for files with extra bytes since they'll appear to insert with older versions, but not work correctly due to the extra bytes not being passed.
%invoke_sa1(label)
Useful if you want to run some code on the SA-1 CPU; see SA-1 for more detail.
%prot_file(file, label)
%prot_source(file, label)
These include binary and source files respectively at the given label, but puts them in their own freedata/freecode blocks, especially useful for large binary files.

The global code file (given by global: in the list file) has an init: label that you can place code directly under. It's called by UberASM Tool fairly early in SMW's overall initailization, and code here should end with RTS instead of RTL. In most cases though, you can equiavlently just use game mode 0's init: instead, since very few things happen between the two.

Versions 1.x of UberASM Tool also had labels for main:, nmi:, and load: in the global code file, but these are no longer supported. See Common Issues for how to use code intended for these labels. Note, though, that there's one small difference here. Previously, global main: code would run before the global frame counter (at $13) was incremented, while code converted to run for UberASM Tool 2.0+ runs after the frame counter is incremented. This is unlikely to matter, but is worth being aware of, just in case.

The status bar code file (given by statusbar in the list file) has only one label used, main:, which is run during levels, a little later than normal main: code, right before the status bar is updated. Any code here should also end in RTS instead of RTL.

Note that unlike regular resources, code for the status bar and global code files is included with the main UberASM patch, rather than getting their own freecode blocks. Due to how the main patch is built, you can't use the %prot macros or shared routines that haven't already been called at least once in the global code or status bar code files.

SA-1

If using UberASM Tool on an SA-1 ROM, note that all resources still run on the SNES CPU side by default. If you want to take advantage of the speed boost that the SA-1 CPU offers, you can use the %invoke_sa1(label) macro to run the routine at label: on the SA-1 CPU. The called routine should end in an RTL, and the DBR is not set automatically, so you will have to do so if needed. To use this in a hybrid resource, then, some example code might look like:

; ... main resource code
if !sa1
    %invoke_sa1(MyRoutine)
else
    JSL MyRoutine
endif
; ... main code continues

...

MyRoutine:
    if !sa1
        PHB : PHK : PLB    ; save/set the DBR (if needed)
    endif

    ; ... routine body

    if !sa1
        PLB     ; restore the DBR (if it was set above)
    endif

    RTL

There are some extra things to consider when running NMI code on an SA-1 ROM. See NMI for more detail, and Extra Bytes if making a resource that needs to access extra bytes during NMI.

As of version 2.0, you can now also specify that UberASM Tool should run resource labels on the SA-1 CPU if it's available (i.e., it's safe to use this option on all ROMs – it simply does nothing on non-SA-1 ROMs). This works for any resource labels except nmi: – it will always be called on the SNES side. To do so, have a line in the resource .asm file exactly of the form ;>sa1 <comma separated list of labels>, with no extra spaces. For example, if a resource file contains the line ;>sa1 main,end, then SA-1 ROMs will have main: and end: run on SA-1, while init: and load: (if present) will run on the SNES side. Since older versions of UberASM Tool don't support this feature, consider using %require_uber_version(2, 0) here, especially if you have code that won't work properly without the SA-1 CPU being invoked as expected (such as when using the multiplication and division registers). Also keep in mind that there's some overhead in invoking the SA-1 CPU, so it may not be worth it for very short routines. The DBR will still be set by default, unless the resource file also contains ;>dbr off. See The DBR for more information.

Dos and Don'ts

Just a few random reminders for good practice when making resources:


Credits and Acknowledgements

UberASM Tool was inspired by GPS, Sprite Tool, edit1754's levelASM tool, levelASM+NMI version and 33953YoShI's japanese levelASM tool.

Asar 1.91, currently maintained by RPGHacker

Pidgin 3.2.0 by Benjamin Hodgson

Vitor would like to thank:

Fernap would also like to thank:

Contact

You can contact Vitor though the following links:

You can contact Fernap at