News:

11 March 2016 - Forum Rules

Main Menu

armips assembler (v0.7c released!)

Started by KC, June 18, 2009, 02:39:02 PM

Previous topic - Next topic

Steven Anthony


90s Retro Gamer

Quote from: KC on June 18, 2009, 02:39:02 PM
Update: PSX and GBA/NDS support is done now. You can download it here.

I've worked on this for quite a while now. After multiple rewrites and a longer break, I think it's almost ready to be released. I'm not sure when it will be done, but if everything goes as planned, it should be in the foreseeable future.
It is intended to be a very romhacking friendly assembler for PSX and also GBA/NDS. My main motivation to write this was the lack of virtually any decent assembler for PSX. You can insert and overwrite code into existing files, add cross-references between overlays and insert everything at once.

Currently implemented features:

  • full-fledged C-like infix expression parser
  • opening any file with any given memory offset. The content is not deleted and only the desired changes are applied. You can create/overwrite a file, too, though
  • you can also open multiple files in a row and cross-reference them. This was done in order to support overlays
  • local labels that are only valid until the next global label
  • table support
  • the complete MIPS r3000 instruction set for PSX
  • a couple of hard-coded MIPS macros to make writing code easier:
    • load immediate: li a0,0xDEADBEEF
    • load/write from/to offset: sw a0,0x80001000
    • unaligned load/store: ush a0,(a1)
    • branches: blt a0,0x100,Start
    • rotate: ror a0,a1,8
  • checks for load delay problems. As every load is delayed by 1 cycle, the loaded value is not immediately available. The following code would generate a warning:
       lw   v0,(v0)
       addiu   v0,1h
  • also an optional automatic fix for said problem. If enabled, the assembler will insert a nop whenever it encounters such a problem:
       lw   v0,(v0)
       nop
       addiu   v0,1h
  • optional output of all the labels to a given text file
  • optional output of all the generated code, complete with address in memory and origin, to a given text file
  • user defined macros
  • THUMB instruction set for GBA and NDS
  • complete ARM support for GBA and NDS

Planned features:
  • an area directive that takes amaximum size and generates an error if it's overflown
  • support for N64 and PS2

It would be nice to hear what you think about it, and also further feature requests. I can't guarantee that I will add anything, but I will consider every suggestion.

Amazing! I assume it would be very difficult to make a Sega Saturn assembler (due to it's bizarre architecture)?

In any case, I'm sure this will open a new era of RHDN with more recent games being hacked/translated.

KC

I see no reason why SuperH assembly would be harder to implement than ARM or MIPS.

SC

#83
Quote from: KC on May 07, 2015, 01:48:15 PM
I see no reason why SuperH assembly would be harder to implement than ARM or MIPS.
I think what would be difficult is to write some useful or complex code on it, though. Unless one somehow managed to fully learn how the SS works.

Oh, I'll seize the moment to say: congratulations for creating this extremely useful assembler!!
It has been really useful for me in the past, and I hope it continues to do so in the future.

I used it with a still paused FF7 translation project when I got mad implementing many translation-related things and other new features in menus and battle layout.

And I tried using it with Suikoden II for an assembler-driven text reinsertion, though I later found a problem with text strings on armips and then gave up the project.

I created a dumper program that takes some address' parameters and dumps the text. All fine.
At least I managed to get something useful out of the messy and mixed Suikoden file structures.
Though still could not solve the text redundancy problem, since there's no way for me to know.
Later I tried using armips to reinsert the translated text. But, I could not make multi-line strings work.

Random Example (it's in Spanish):
.str "Bueno... ¿nos vamos a la cama?<\n>",7,1,"¿O quieres salir a tomar el aire?<\n>",7,0,"Hace una noche perfecta."
Nevermind of the values related to text pausing.
I would have loved to make something similar to this:
.str {
"Bueno... ¿nos vamos a la cama?<\n>
<Pause:1>¿O quieres salir a tomar el aire?<\n>
<Pause:0>Hace una noche perfecta." }
Though, maybe those curly braces would not really be needed.
Is there an obscure way to do this, or did I miss something? Maybe it's simply not possible now? Would it be possible in a future release?

I always thought of doing this translation text insertion through armips to save much time on reinsertion irknesses, but...

Also, now that I mention this Suikoden II project:
Do you know or know someone who knows how to change the font's width?
I searched high and low on all relevant files using all kind of searching methods imigining all kind of ways for that information to be stored... to no avail.
I even used debugger and tracing techniques.

While not mandatory for a translation it would still be nice to do it, since the original font is ugly and has some width errors.

By the way, I hope to see more from you in the Tales of Phantasia X and Narikiri Dungeon X for the PSP project soon.

Thank you for your work, sir! :thumbsup:

KC

I'm glad you find it useful! It wasn't actually meant to be a sophisticated text inserter, so the string commands are somewhat limited. I'm currently working on a new parser though, which would allow you to at least split the text over multiple lines in some way.

.str "Bueno... ¿nos vamos a la cama?<\n>",7,1,
"¿O quieres salir a tomar el aire?<\n>",7,0,
"Hace una noche perfecta."


It's still not really ideal, but at least a bit easier to read. Other additions are possible, though I can't say anything about that at this time. I can't help you with your game either, unfortunately.

x0_000

A useful feature for larger scale hacking would be some enum support. Basically something like
.beginenum
enum0
enum1
enum2
...
.endenum

would be equivalent to writing
enum0 equ 0x0
enum1 equ 0x1
enum2 equ 0x2
...

And you could change enum starting points by specify equs within the command, e.g.

.beginenum
enum0
enum1
enum2
enum3 equ 20
enum4
enum5
...
.endenum

would be the same as

enum0 equ 0
enum1 equ 1
enum2 equ 2
enum3 equ 20
enum4 equ 21
enum5 equ 22
...

The main reason for this is automatically allocating and reallocating indices, e.g. if I'm making events in an RPG and I need to track each one, normally I'd have to write

eventChest1 equ 1
eventChest2 equ 2
...
eventChest20 equ 20
eventSwitch1 equ 21
eventSwitch2 equ 22
...

So if I decide to add another chest event for whatever reason, I would have to either update all the eventSwitchX equs, or put the chest right after the eventSwitchXs (which is disorganized and not ideal.) You can also have the -sym output include what each enum gets mapped to.

MeganGrass

Good idea, x0_000.

@KC - May I ask if you plan to add support for generic c/c++ struct types?

Currently, I have to convert my structs/variables to something that armips can use, but I still have 4,493 lines of structures/variables to convert. Suffice to say that it would truly be a godsend!

granitor

Quote from: MarkGrass on May 14, 2015, 12:14:38 PM
Good idea, x0_000.

@KC - May I ask if you plan to add support for generic c/c++ struct types?

Currently, I have to convert my structs/variables to something that armips can use, but I still have 4,493 lines of structures/variables to convert. Suffice to say that it would truly be a godsend!

Those last too requests sound more like what a C or Cish compiler would do, not an assembler.

I like the concept of this assembler, a "patching assembler" is what I'd call it, maybe other have similar features but it seems very useful for modifying existing files. I think adding enums and structs is going too far though, that's really a compiler's work.

MeganGrass

Quote from: granitor on May 16, 2015, 09:17:07 PM
Those last too requests sound more like what a C or Cish compiler would do, not an assembler.

I like the concept of this assembler, a "patching assembler" is what I'd call it, maybe other have similar features but it seems very useful for modifying existing files. I think adding enums and structs is going too far though, that's really a compiler's work.

I absolutely agree.

...but just imagine having a 167Kb header file, full of every single structure, enumeration and variable that a certain PSone game uses, only to be be restricted to using it in a c/c++ compiler.

Granted, I could load a structure into a register and access various variables via indexing, but that would still require non-stop commenting just to know what the hell I'm working with.

It's a dumb question/request of KC, but most certainly worth asking for in my scenario.

KC

It's probably not terribly difficult to add. The new parser is a token based recursive descent parser, so you'd more or less just have to come up with some productions, turn them into a parsing function, and then add the retrieved enum/struct values as (qualified, preferably) labels. Not really one of my priorities, but everyone can contribute, and I'd be ready to answer questions in the RHDN IRC channel.

KC

Some updates from the last year:

  • N64 RSP support by sp1187
  • Expression functions added, builtin functions that can be called from inside expressions. For example, strlen, substr, fileExists, readByte, etc.
  • Partial parse time evaluation of expressions, if a block can be guaranteed to be inside of an unsatisfyable condition it will be omitted. This allows, for example, if/else blocks to have seperate equ definitions for the same symbol name. Equ is no longer allowed inside of blocks with conditions that can't be evaluated at parse time
  • Automatically determines and takes into account host endianness, and supports outputting data for both big end little endian platforms
  • Countless smaller changes, additions, and fixes