Here’s what I’ve been tinkering with for the past three months with the Wonderful toolchain.
New tools
The highlight of this project update is the introduction of three new tools - some long awaited by users, others long awaited by myself.
agbpack
There are two primary forms of GBA homebrew:
- Cartridge images, available via an attached ROM - the primary form of homebrew these days;
- Multiboot images, loaded directly to memory via link cable - used for multiplayer games, early homebrew development (think Xboo PC cables), and by the GBA Movie Player.
Modern libraries, like gba-link-connection, provide an user-friendly interface for developing multiplayer games. As a result, there has been a small resurgence of interest in creating multiboot GBA software. However, it is still a rather constrained form - you have to fit the entire game in 256 KiB of EWRAM, and the largest games can take as long as 30 seconds (!) to be transmitted over the cable.
agbpack
is a tool I developed which attempts to lessen both of these problems by taking advantage of in-place executable decompression:
- With a compression ratio of 55-80%, games can be transferred significantly faster;
- By allowing direct extraction into EWRAM, IWRAM and VRAM, uncompressed multiboot executables can use more than 256 KiB total space, making them a little less constrained.
Simply run:
$ agbpack original_mb.gba packed_mb.gba
using any multiboot .gba
file as input, and receive a compressed file back! (Note that supporting direct placement of data in IWRAM and VRAM requires adaptations to the toolchain.)
You can download the standalone tool here; it is also integrated by default into the Wonderful toolchain.
wf-…tool usage
I’ve long been a fan of bbbbbbr’s romusage tool for estimating the memory usage of cartridge images built using SDCC.
It doesn’t support ELF files, or the WonderSwan, so I decided to build my own variant of the tool: wf-wswantool usage
.
Section Range Size Used Used% Free Free%
--------------- -------------------- ------- ------- ------ ------- ------
Internal RAM 0x0000 -> 0xFFFF 65536 21670 33% 43866 67% |=#####.###=.................|
+- Mono area 0x0000 -> 0x3FFF 16384 13478 82% 2906 18% |##.-####################=...|
+- Color area 0x4000 -> 0xFFFF 49152 8192 16% 40960 84% |####=.......................|
Cartridge ROM 0xE0000 -> 0xFFFFF 131072 48573 37% 82499 63% |.................-##########|
+- Linear $FF 0xE0000 -> 0xFFFFF 131072 48573 37% 82499 63% |.................-##########|
+- Bank $FE 0xE0000 -> 0xEFFFF 65536 0 0% 65536 100% |............................|
+- Bank $FF 0xF0000 -> 0xFFFFF 65536 48573 74% 16963 26% |.......#####################|
In addition, it supports the toolchain’s other target platforms - the WonderWitch and the GBA:
Section Range Size Used Used% Free Free%
--------- ------------------ ------ ------ ------ ------ ------
Code 0x0000 -> 0xFFFF 65536 5552 8% 59984 92%
Data 0x0000 -> 0xFFFF 65536 42094 64% 23442 36%
Section Range Size Used Used% Free Free%
--------- -------------------- ------- ------- ------ ------- ------
IWRAM 0x0000 -> 0x7FFF 32768 12680 38% 20088 62%
EWRAM 0x00000 -> 0x3FFFF 262144 245708 93% 16436 7%
As I’ve only really added the small set of features I relied on myself when using GBDK, don’t hesitate to propose additional ones!
wf-env
One slightly annoying aspect of the Wonderful toolchain’s installation was having to manually configure environment variables, like WONDERFUL_TOOLCHAIN
,
and adding /opt/wonderful/bin
to PATH
. In line with many other toolchains, I have added a command to perform this step for you:
# bash, zsh, ...
$ . wf-env
# fish
~> . /opt/wonderful/bin/wf-env.fish
An useful additional feature is the -a
argument - it adds all the installed toolchains to PATH
. This allows you to use tools such as arm-none-eabi-nm
or ia16-elf-objdump
without having to manually type in or append their paths.
Toolchain improvements
WonderSwan target updates
- Added helper functions for configuring horizontal/vertical blank timers.
- Added startup files which allow creating “pin-strapped” (PCv2-compatible) cartridge images.
- Added
ia16_get_sp()
helper function. - Added
setjmp()
andlongjmp()
implementations. - Fixed
ws_bank_with_rom0()
typo. - Fixed
ws_cart_rtc_*
helper functions. - Initial work on stdio file/console I/O started.
- Updated
binutils-ia16
on Windows to 2.43.1. - Documentation improvements: additional comments, fixed Doxygen function output.
- Improved header support for the CLion IDE.
- Removed the legacy
wf-wswantool romlink
linker. It was deprecated really early in the toolchain’s history, so it shouldn’t affect any existing projects.
One notable feature is that wswan/small-sram
and wswan/medium-sram
subtargets now support defining variables in internal RAM as follows, without
having to explicitly specify an ELF section:
uint16_t ws_iram my_table_in_iram[32];
As a side note, wf-mednafen
received a minor update
fixing some CPU/APU emulation bugs and improving the debugger port layout slightly. (While Mesen 2 is the
recommended emulator for WonderSwan development these days, it does not yet cover more oddball usage scenarios.)
GBA target updates
Other than the integration of agbpack
, the GBA target has received two new headers:
<gba/bios.h>
, containing wrappers for BIOS SWI calls,<gba/mmio.h>
, containing macros for accessing (most of) the GBA’s memory-mapped I/O space.
A performance issue was identified where __muldi3
was built as Thumb in Thumb mode, which is both significantly larger and slower than always using the
ARM variant (even with the overhead of interwork!) - this has been fixed.
With regards to packages, the GCC ARM toolchain has been updated (binutils 2.44 -> 2.45, GCC 15.1.0 -> 15.2.0); the version of libtonc
packaged has also been updated.
I don’t think the target on its own is likely to leave the “experimental” stage soon, let alone become as friendly as something like Butano. Regardless, a bit of progress has been made this time around.
Miscellaneous changes
wf-fatfs
has been updated to R0.16p1.- In addition, a bug which broke removing directories when the
FF_WF_LIST_DOTDOT
configuration option was enabled has been fixed.
- In addition, a bug which broke removing directories when the
wf-process
has received LuaLS-compatible bindings for its API libraries.wf-sox
has been replaced with the sox_ng fork on Linux.- Added a minimal landing page to the toolchain’s website.
- Some
wf-tools
now emit ANSI color codes as part of text output. (If you’re not a fan of that, theNO_COLOR
environment variable is respected.)