[FE5] Volt Edge: A Library for FE5 ASM (And Events!)

This is an attempt at writing a kind of standard library for working with Fire Emblem: Thracia 776.

Get it here.

It has a few goals:


Consolidated RAM Maps

    aSRAM .block

      aSaveDataHeader  .dstruct structSaveDataHeader ; $700000
      aSaveSlot1       .dstruct structSaveDataEntry  ; $700008
      aSaveSlot2       .dstruct structSaveDataEntry  ; $702000
      aSaveSlot3       .dstruct structSaveDataEntry  ; $703FF8
      aSaveSlotSuspend .dstruct structSaveDataEntry  ; $705FF0
      .fill ($708000 - *), ?

    .bend

Volt Edge provides (as of version 0.01) a full SRAM map and a WIP WRAM map that documents the location and use of different variables and structures. The objective here is to avoid having to define these yourself and to keep names consistent throughout projects.

It’s much clearer to use these named memory locations within code:

...
lda aSRAM.aSaveDataHeader.CompletionFlag
and #$00FF
beq +

  ; Foo some bars if this isn't
  ; your first rodeo.

  lda aSRAM.aSaveDataHeader.CompletionCount
  and #$00FF
  sta wR0
  jsl rlYeeHaw

+
...

as opposed to

...
lda $700003
and #$00FF
beq +

  ; Foo some bars if this isn't
  ; your first rodeo.

  lda $700002
  and #$00FF
  sta $0B
  jsl rlYeeHaw

+
...

Labels are given a short prefix to make identifying their size easier:

  • a - Array - although really this is just some variable or stucture of a nonstandard size.
  • b - Byte - 8 bits
  • w - Word - 16 bits
  • l - Long - 24 bits

Vanilla Definitions

  Leif                  = $0001
  Finn                  = $0002
  Orsin                 = $0003
  Halvan                = $0004
  Eyvel                 = $0005
  ...

Similar to the EA Standard Library, Volt Edge defines vanilla character, class, and item definitions (along with a couple miscellaneous constants). These can be toggled off if not desired.

Volt Edge also defines many vanilla structures in order to make writing assembly, tables, etc. easier:

  ...
  lda structCharacterDataRAM.X,b,y
  and #$00FF
  sta wR0

  lda structCharacterDataRAM.Y,b,y
  and #$00FF
  sta wR1
  ...

Hardware and I/O Register Definitions

As above but with things common to the SNES.

  lda #INIDISP_Setting(false, 15)
  sta bBufferINIDISP
  sta INIDISP,b

  ...

  lda bBufferINIDISP
  and #INIDISP_Brightness
  cmp #15
  bne +
  ...


Misc. Helpers

I don’t like having to figure out where in the memory map some address is. I don’t like having to write format strings to print the current offset. Volt Edge includes a set of macros, definitions, and functions that make things easier, clearer, and with less repetition.

* := $012345
.logical mapped($012345)

  rlFrobulator

    .autsiz
    .databank ?

    asl a
    tax

    lda aFooTable,x
    sta wR0

    jsl rlFoo

    rtl

    .databank 0

  aFooTable

    .word pack([1, 2])
    .word pack([3, 4])

  .warnhere

.here

I guess that’s enough rambling for now.


Bonus

Why is this called “Volt Edge”?

I was originally going to call it the FE5 Standard Library, but I felt like that’s a bit arrogant. After that, I figured “Reinhardt” would’ve been a fun name, trying to follow Stan’s name things after characters shtick, but I can only copy Stan so much.

So, instead I chose the most contentious thing included in my menu translation. Anyone using this is now forced to .include "VoltEdge.h" in their project. I love it.

22 Likes

An update for all 9 people who’ve clicked the GitHub link:

Volt Edge has been updated to include definitions for writing events. Eventually I’ll have to write up some doc on making your own events, but this is a good start. So far, definitions for condition codes and main codes have been added, along with a few helpers and macros.

Another huge part of what’s been added is a list of vanilla assembly routines that are called in events to provide specialized functionality (these’re called ASMCs). FE5 eventing relies heavily on these ASMCs, as the normal event codes are very basic in functionality.

Up next will most likely be macros that focus on these ASMCs, as setting up their inputs can be quite the pain. See:

PLAY_SOUND_WORD $00F7 ; TODO: sound definitions
DIALOGUE dialogueYourDialoguePointerHere
YIELD

STORE_WORD wEventEngineParameter1, TurnStatusActing
CALL_ASM_LOOP rlASMCActiveUnitSetTurnStatus

STORE_WORD wEventEngineParameter1, yourItemHere
PAUSE_SKIPPABLE 10
YIELD

CALL_ASM_LOOP rlASMCGiveActiveUnitItem
YIELD_UNK

CALL_ASM_LOOP rlASMCSetupGiveItemPopup
CALL_ASM_LOOP rlASMCWaitWhileGiveItemPopup
CALL_ASM_LOOP rlASMCSetupGiveToConvoyIfInventoryFull
CALL_ASM_LOOP rlASMCWaitWhileGiveToConvoyIfInventoryFull

STORE_WORD wEventEngineParameter1, TurnStatusActing
CALL_ASM_LOOP rlASMCActiveUnitUnsetTurnStatus

STORE_WORD wEventEngineXCoordinate, yourXCoordinate
STORE_WORD wEventEngineYCoordinate, yourYCoordinate
STORE_WORD wEventEngineParameter1, yourTileID
CALL_ASM_LOOP rlASMCSingleTileChangeByCoords
YIELD_UNK

That’s all of the setup just for a house to give an item when visited. The ASMCs with parameters can be macro’d, larger blocks that accomplish one task can be macro’d,and then even this entire thing can be macro’d. Lots of work to do on my end, but being able to type out a single line instead of all of this will be great.

7 Likes

A bunch of event macros have now been added. Most of them are just to make using ASMCs easier, but a few are for blocks of commonly-used codes.

That block in the previous post gets condensed down into a macro that looks like

    macroItemHouse .macro DialoguePointer, Item, Coordinates, TileID
      PLAY_SOUND_WORD $00F7 ; TODO: sound definitions

      DIALOGUE \DialoguePointer
      YIELD

      macroASMCActiveUnitSetUnitState UnitStateActing

      macroGiveActiveUnitItem \Item

      macroASMCActiveUnitUnsetUnitState UnitStateActing

      macroASMCSingleTileChangeByCoords \Coordinates, \TileID
    .endm

and when writing your events you’d just type

macroItemHouse yourDialogue, yourItem, [x, y], yourTile

Nice, huh? Check out VOLTEDGE/EVENTS/Macros.h for more.

A guide for writing events with these coming sometime in the unforeseeable future.

3 Likes

I’d recommend putting it at the top of the thread. There’s quite a bit to scroll through before you see the link.

This is cool stuff and I am excited to see what comes of this work.

1 Like