libnds:
- Split
systemShutDown()to createsystemReboot(). - Clean power management definitions.
- Un-deprecate
glTranslate3f32()because it’s used in several projects. - Stop writing the NAND CID to arbitrary RAM addresses used by the official SDK but not by BlocksDS. @edo9300
- Stop writing to
REG_VCOUNTduring initialization of the ROM. Thanks to @TuxSH for finding the original bug. - Add global timer definitions so that other libraries know which timer they can use.
- Ensure that file descriptors passed to
truncate()are valid FAT descriptors.
DSWiFi:
- Drop lwIP packets if there isn’t enough RAM to allocate a buffer for them (instead of crashing in an
assert()). - Add a workaround to prevent IPC buffer overflows.
SDK:
- Use the new libnds timer defi…
libnds:
- Split
systemShutDown()to createsystemReboot(). - Clean power management definitions.
- Un-deprecate
glTranslate3f32()because it’s used in several projects. - Stop writing the NAND CID to arbitrary RAM addresses used by the official SDK but not by BlocksDS. @edo9300
- Stop writing to
REG_VCOUNTduring initialization of the ROM. Thanks to @TuxSH for finding the original bug. - Add global timer definitions so that other libraries know which timer they can use.
- Ensure that file descriptors passed to
truncate()are valid FAT descriptors.
DSWiFi:
- Drop lwIP packets if there isn’t enough RAM to allocate a buffer for them (instead of crashing in an
assert()). - Add a workaround to prevent IPC buffer overflows.
SDK:
-
Use the new libnds timer defines in ARM7 templates and examples, as well as in DSWiFI, Maxmod and LibXM7.
-
Fixed the orientation of normals for planes in the volumetric shadow example. @Mori-TM
-
Improve exit-to-loader test.
libnds:
glTranslate3f32()has been converted from a define to astatic inlinefunction. The define could cause issues if someone was creating a C++ wrapper with the same name, for example.
DSWiFi:
- Don’t crash on an
assert()when sending fragmented lwIP packets.
SDK:
-
Support unusual
main()prototypes with 3 arguments instead of two. The third argument is set toNULL.
DSWiFi:
- IPv6 support has been added. The
ASSOCSTATUS_DHCPstate now waits for an IPv4 or an IPv6 address to be available (normally IPv4 is available first). FunctionWifi_GetIPv6()has been added, which lets the caller check if there is an available IPv6 address for the DS. - In DS mode, only send data packets to the ARM9 by default. Previously all management packets were being sent.
- In DS mode, send multicast packets to lwIP. Previously only packets addressed to the console or to the broadcast address (FF:FF:FF:FF:FF:FF) were sent to lwIP, which prevented DHCPv6 from working, for example.
- TX packets generated by lwIP and passed to DSWiFi weren’t handled correctly if they were in a fragmented
pbuf. This has been fixed. - Fix implementations of
ioctl()andfcntl(), as well as the definesO_RDONLY,O_WRONLY,O_RDWRandO_NONBLOCK.
SDK:
-
Added a new package with libcurl named
blocksds-libcurl. -
Added a new example of how to use libcurl with BlocksDS.
-
Improve documentation of exception handler example.
-
Add a bloom example based on the original demo by Bluescrn.
-
Mention the multiple ARM7 cores in the migration guide.
-
Support edge-triggered rumble cartridges in the Slot-2 example.
libnds:
- Fix mounting filesystems in SD cards with multiple partitions. This affected DeSmuME, for example. @edo9300
DSWiFi:
- A potential buffer overflow has been fixed in the DSi RX/TX queues.
- The DS RX/TX queues that transfer packets between the ARM9 and ARM7 have been rewritten to behave like in DSi mode. Now packets are written to the circular buffer one after the other, but they are never cut into two parts when the end of the buffer is reached. This guarantees that packets are always stored in one piece, which means that the ARM9 can avoid doing an extra copy to concatenate both parts, making communications faster.
- In DS mode packets are now read from/written to MAC RAM using DMA for extra speed and simplify the code.
- Now that packets are always stored in one piece, it isn’t needed to use
Wifi_RxRawReadPacketPointer()to copy them to a user-allocated buffer. FunctionWifi_RxRawReadPacketPointer()has been implemented as an alternative. It returns an uncached pointer to the packet in RAM. Please, check the documentation for advice on how to use them. - Improve random number generation. Previously, in DS mode,
W_RANDOMwas used for WEP seeds, a bad handmade RNG was used for WPA2 handshakes, andrand()was used in Mbed TLS instead of hardware entropy collection. A new system has replaced all of them. It constantly collects randomness from different events and updates a seed that is used to seed a xorshift32 generator. It isn’t super secure because there is no real source of randomness on the DS, but it’s better than the previous systems. - The
Wifi_TxHeaderandWifi_RxHeaderstructs are now private. They are never required by user code, and there is no equivalent in DSi mode, so it’s better to hide them.
SDK:
-
Fix linker warning about the implementation of
__sync_synchronize. Thanks to @asiekierka for the workaround. -
In a DSWiFi example some missing instructions have been added to the console output.
-
The SSL DSWiFi example has been updated with more test websites.
DSWiFi:
-
In the ARM7, Mbed TLS has been moved to twl sections. This code is only required to connect to WPA2 networks.
-
Transfer of data between DSWiFi and lwIP in the ARM9 has been fixed. The way
pbufstructs were managed was incorrect, and caused frequent assertion panic screens. -
Some missing defines have been added to public DSWiFI headers.
-
Some settings have been changed in lwIP (for example, to increase the number of available simultaneous sockets).
libnds:
- Fix reading console ID with
SCFG_ROMregisters disabled. @edo9300 - Ensure crypto has been initialized when a NAND read/write command is received in the ARM7. @edo9300
- Support using
write()to send text to the console with file descriptorsSTDOUT_FILENOandSTDERR_FILENO. - Fix potential cache corruption caused by
DC_InvalidateRange()inreadFirmware(). It has been replaced byDC_FlushRange(), and all calls toDC_InvalidateRange()have been removed. For more details, check Cearn’s articles here and here. - Add some missing SCFG and NDMA register definitions.
- Add no$gba debug register definitions (also used in melonDS).
- Simplify no$gba message print on the ARM9 (melonDS doesn’t support the simplified system on the ARM7).
DSWiFi:
- Add new DSi mode driver with support for Open, WEP and WPA2 networks. @ShinyQuagsire23 is the original author of the driver. It has been extracted from dsiwifi and modified to integrate it with the previous DSWiFi code.
- This driver can be enabled by passing
WIFI_ATTEMPT_DSI_MODEas one of the flags toWifi_InitDefault(). It’s also possible to useWIFI_DS_MODE_ONLYto force DS mode even on DSi consoles (this is the default setting). - The new DSi driver doesn’t support NiFi mode, it’s only available in backwards-compatible DS mode.
- The library now reads all Access Points configured in the WFC settings of DSi consoles. It uses them even in backwards-compatible DS mode (but it ignores access points that use WPA).
Wifi_ConnectAP()has been deprecated,Wifi_ConnectSecureAP()supersedes it. It’s more convenient because it takes as input a key and key length instead of a key and hardware definitions. It supports WPA, WEP and open networks.- The code on the ARM7 side is now divided into two parts. One of them is for DS mode, which is always loaded. The other one is for the DSi driver, which is only loaded to RAM in DSi mode. Some code can be shared between both modes, but not much.
- The code has been refactored a lot. The
WIFI_MODE,WIFI_AUTHLEVELandWIFI_CONNECT_STATEstate machines are now decoupled and they can’t directly change the state of other state machines, making it easier to understand the execution flow. - The internal IPC code of the library has been simplified. Several status flags have been removed as they are no longer needed.
Wifi_FindMatchingAP()has been simplified. It now only checks the BSSID and SSID of the reference AP we’re looking for.- Some new fields related to the security of the AP have been added to struct
Wifi_AccessPoint. Also, fieldrssiis now signed instead of unsigned. - Mbed TLS 3.4.6 has been added to the repository. This is required by the WPA2 handshake code. The license has been added to the repository, and the SDK documentation has been update to mention the new requirements.
- Flag
WFLAG_APDATA_ADHOCno longer works as ad hoc mode support has been removed (this is different from multiplayer mode, that’s still supported). Fieldmacaddrhas been removed from structWifi_AccessPoint. - Unused define
WFLAG_APDATA_SHORTPREAMBLEhas been removed. - The strings of
ASSOCSTATUS_STRINGShave been modified to make them useful. - The network interface (netif) used by lwIP is now set down when the WiFi connection is lost and set up when the console connects to an access point. This helps lwIP do some things better, like DHCP.
- Scan mode is now a bit faster in DS mode, the library stays for a shorter period of time in each channel.
- A few definitions and structs have been added to the public headers, as well as
freeaddrinfo()andgetaddrinfo().
SDK:
Improve SDK version string generation. The makefiles of all tools (except for dldipatch) have been modified to use the value of VERSION_STRING provided by the user. If the string is not provided, it tries to generate a version string in 2 different ways. If that fails, it defaults to “DEV”.
Added a prototype Mbed TLS 3.6.4 package to the pacman repository. Note that the entropy generation isn’t correct, so don’t use this for any application that requires security for now!
All tools (except for dldipatch) now accept a -V flag. When the tools are run with -V they print the version string and exit right away. This flag has been selected because some tools were already using -v for other purposes (like verbose output).
The file $BLOCKSDS/version.txt will now contain the value of VERSION_STRING generated when building BlocksDS instead of the commit ID.
Update license information about DSWiFi.
To reduce the size of NDS ROMs the default ARM9-only Makefile now uses the default ARM7 core with maxmod but without DSWiFi. Programs that require DSWiFi need to select the right core by adding this line to the Makefile: ARM7ELF := $(BLOCKSDS)/sys/arm7/main_core/arm7_dswifi_maxmod.elf
Examples:
-
New example that lets you display the photos stored in the NAND of a DSi console. @edo9300
-
The DSWiFi examples have been updated to use DSi mode and connect to WPA2 networks whenever possible.
-
There’s a new example to show how to use the new version check helpers.
libnds:
- Improve error checking in
nitroFSInit()when using official card commands to access NitroFS.nitroFSInit()now reads the new magic string stored by ndstool in the NDS ROM to check that the cartridge data can be read. The previous system was incorrect because the ROM header can’t be read after the initial load of the ROM. - Prevent changing the filesystem label of DSi NAND partitions with
fatSetVolumeLabel(). @edo9300 - Add support for the photo partition of the DSi NAND. @edo9300
- Save some RAM related to FatFs structs by moving them to TWL RAM. @edo9300
- Some minor code cleanup.
DSWiFi:
- Implemented
inet_aton(),inet_addr(),inet_ntop()andinet_pton(). - DSWiFi now prevents lwIP from updating its state before being connected to an access point.
- Some minor code cleanup.
ndstool:
- Add a magic string after the FAT filesystem table. This string can be used by libnds to check that card commands can read the cartridge data correctly.
- The unit code and title ID of the DSi ROM header can now be set by the user independently.
- The default title ID for DSi ROMs is now the DSiware code rather than the DSi gamecard code. This is a compatibility break with older versions. To get the same result as previous invocations of ndstool you need to use the argument
-u 00030000. If you were using a different title ID already now you will need to specify the unit code. For example,-u 00030004now becomes-u 00030004 -uc 3, and you can skip the-u 00030004because that’s the new default value.
SDK:
-
NitroFS now works when ROMs are loaded from Unlaunch (with some limitations, paths can only be up to 0x40 characters long, and file/folder names are in 8.3 name format). Thanks to @edo9300 for his device list support additions and his suggestions for ndstool.
-
The example that accessess all filesystems has been improved to check the
nand2filesystem as well.
libnds:
- NitroFS now detects failures during initialization.
nitroFSInit()has been cleaned and documented. Normally,nitroFSInit()tries to open the NDS ROM as a file, then it tries to read NitroFS from Slot-2 cartridge memory, and then it falls back to cartridge commands. There were no checks to verify that cartridge commands worked. - The exit-to-loader system has been slightly modified to increase compatibility with loaders that don’t determine the size of DSi RAM correctly. The compatibility break happened in Version 0.13.0.
keysCurrent()has been marked as deprecated.keyboardUpdate()has been modified to usekeysHeld()instead. This isn’t a new break, this just adds a warning for users of BlocksDS. The break happened in Version 0.13.0.- Function
dlopen_FILE()has been introduced. It works likedlopen(), but it takes aFILEhandle as input instead of a path. This is useful to load dynamic libraries that are already in RAM instead of in the filesystem. - The check that verifies that the IPC transfer region fits in memory has been fixed to not overlap the following memory regions.
- Card functions now use the right
CARD_defines. @lifehackerhansol
DSWiFi:
- Some minor improvements to the intergration with lwIP.
- Enable and fix some compiler warnings.
LibXM7:
- Enable and fix some compiler warnings.
grit:
- Fix
dib_pixel_replace()for 32-bit values. - Added some missing
breakstatements. - Enable and fix some compiler warnings.
mmutil:
- Enable and fix some compiler warnings.
SDK:
-
Document more of the behaviour of the exit-to-loader process of the NDS Homebrew Menu and the bootstub struct.
-
Enable and fix some compiler warnings in dsltool, teaktool and mkfatimg.
libnds:
- Added a new driver to read the NAND filesystem using standard filesystem functions (like
fopen()andfread()). The NAND filesystem is normally mounted in read-only mode, but developers can enable writing to it if required. This is done so that the contents of NAND are protected by default. @edo9300 - Fix regression causing
keysDownRepeat()not report keys on their first press. @edo9300 - Improve accuracy of
dotf32()andcrossf32(). In ARM mode their performance has increased.crossf32()is now always built as ARM. @Kuratius - Fix a bug that caused
rmdir()to be unable to remove empty directories (because they still contained entries"."and".."). Thanks to @edo9300 for the report and @asiekierka for the fix. - Added
fatGetVolumeLabel()andfatSetVolumeLabel(). @asiekierka - Added
SDMMC_getCidRaw(). @edo9300 - Add basic counting semaphore helpers for the cothread module.
- Implement
cothread_yield_signal()andcothread_send_signal()to allow threads to sleep until a user-defined event is sent to the scheduler. If all threads are waiting for signals or interrupts the CPU will enter low-power mode. - Mutexes and semaphores now use signals to yield and to notify other threads of changes to their state.
- Add a function to create an
argvstruct if the program is running on DSi, the loader hasn’t provided a validargvstruct, but there is a valid device list. @edo9300 - Replaced old FIFO IRQ defines by the new ones.
- Some warnings have been fixed.
DSWiFi:
- Migrate from sgIP to lwIP. lwIP is being maintained, and it is used by lots of other projects, which means it has been tested properly. It also supports more features than sgIP.
- This migration makes the size of NDS ROMs increse, so the build system of DSWiFi now creates new releases of the library without lwIP. They are useful for developers that only want to use the local multiplayer (NiFi) features of DSWiFi. The new library archives are called
libdswifi9_noip.aandlibdswifi9d_noip.a. - One big difference is that programs using DSWiFi will need to use threads. Instead of using
swiWaitForVBlank()they will need to usecothread_yield_irq(IRQ_VBLANK), for example. If they have a loop where they callrecv()they will also need to callcothread_yield()at some point in the loop. - Functions
write(),read()andclose()now work with socket file descriptors. - Functions
readv(),writev(),recvmsg()andsendmsg()have been implemented. - Some warnings have been fixed on ARM9 code.
Maxmod:
mmPlayModule()has been deprecated because its name is misleading and it expects you to pass the address of the MAS file with an offset. The new functionmmPlayMAS()replaces it. It doesn’t require the offset, and it has a name more descriptive.mmPlayMAS()is also available in the ARM9, not just the ARM7.- Fix mode C mixer. Sounds didn’t end until they were stopped manually, not when they reached the end of their sample.
- Some small optimizations. @GValiente
- Document some parts of the code.
mmutil:
- Make the output less verbose by default.
- In module files, if a pattern uses an invalid instrument (with a sample of length zero), the instrument is now removed from the pattern before being exported. This prevents crashes on GBA when playing songs with invalid instruments. A warning is printed for each instance of invalid instruments being used.
- In module files with instrument note maps (supported by IT and XM) mmutil now checks that the samples used in all note map entries are valid. If not, a warning is printed and it is set to 0. The warning is only printed once per sample per instrument.
- Prevent mmutil from exporting more than 200 pattern orders for modules. The MAS format is hardcoded to 200 pattern orders, so any module that has more entries than that will be clamped and mmutil will print a warning.
SDK:
-
In the crt0 of the ARM9, generate an
argvstruct if the application is running on a DSi, there is no validargvprovided by the loader, but there is a valid device list. @edo9300 -
Add example of how to play MAS files with Maxmod manually without a soundbank.
-
Improve example
nitrofs_and_fatto also display the contents of the NAND filesystem. It has been renamed toall_filesystems. -
Update DSWiFi examples to work with the new version of DSWiFi.
-
Add example of how to wait for signals in multithreading applications.
-
Add test of setting and getting filesystem labels.
-
Allow building all examples and tests in parallel. @steveschnepp
libnds:
- The detection of the official Slot-2 rumble pak (NTR-008) has been fixed. It used to be detected as a SuperCard. Also, the rumble API of libnds is now more flexible when detecting the type of activation of rumble. @asiekierka
- The enum of IPC commands used by DSWiFi has been moved from libnds to DSWiFi and made private.
- The system monitor of DS debugger units is now preserved during the startup process of libnds. The last 512KB of RAM are reserved so that the heap can’t grow too much and overwrite them (they can be used again if the developer manually calls
reduceHeapSize(0)). Additionally, libnds won’t setup an exception handler if it detects a debugger unit. The developer has to do it manually by callingdefaultExceptionHandler(). Thanks @Gericom for the bug report.
Maxmod:
- Fix instruments with panning and pitch envelope enabled at the same time. Previously, the panning envelope was used for the pitch envelope by mistake.
- On GBA now
mmInit()andmmInitDefault()return error if the number of requested channels is bigger than 32. This wasn’t supported anyway, and it would have silently failed if allowed. - The memory used by the panning slide VCMD on XM modules was using the volume slide memory when panning to the right (it used the right memory when panning to the left).
- The memory entries used by effects and volume effects has been documented.
- The IPC command for the ARM9
mmReverbConfigure()function has been simplified. It will now send all parameters in all cases, but this is what users will be using in most cases. In exchange for this, the function becomes a lot smaller and easier to maintain. - Check a few TODO notes and fix them (or remove them if they didn’t need any work).
- In the GBA port, move a function outside of IWRAM. This brings down IWRAM usage to a size lower than the ASM version of Maxmod, and it doesn’t affect performance in a noticeable way. @aronson
- Remove
always_inlineattribute from some functions to fix a build error with clang. @GalaxyShard - In DS mode, using Maxmod commands before initializing it will now show a crash error. This is more informative than simply ignoring commands.
- A critical bug has been fixed on the ARM7. In some cases, it was possible for the ARM7 message handler to be interrupted while editing the state of the circular buffer. This would leave the buffer in an inconsistent state and make the ARM7 treat uninitialized values in memory as legitimate ARM9 commands, causing crashes. Thanks to @pyramidensurfer for a test that managed to reproduce the error reliably.
- The ARM7 communications code is now built as Thumb instead of ARM to save space.
- The GBA version of Maxmod is now built with a format of debug symbols that no$gba can understand.
DSWiFi:
- The enum of IPC commands used by DSWiFi has been moved from libnds to DSWiFi and made private. Some commands weren’t used and they have been removed.
Wifi_InitDefault()now takes an int as argument instead of a bool. This lets the function get more flags in the future if they are implemented. Old C code using true or false will still work.- Lots of functions have been made private: Everything that has to do with manual initialization and synchronization between CPUs. Making this code private gives DSWiFi more flexibility to refactor the code.
- The initialization code of the library has been cleaned up and simplified.
- It is now possible to deinitialize DSWiFi with
Wifi_Deinit(). This will keep the sgIP memory pool still in the heap, but it will free all other resources. sgIP can’t be reinitialized safely at the moment. Wifi_InitDefault()now accepts flagsWIFI_DISABLE_LEDandWIFI_ENABLE_LEDto let DSWiFi know if it can control the LED blinking or not. By default, the LED is controlled by DSWiFi.Wifi_InitDefault()now accepts flagsWIFI_INTERNET_AND_LOCALandWIFI_LOCAL_ONLY. It makes it possible to initialize DSWiFi without sgIP if the game isn’t going to connect to the Internet. This saves over a 100 KBs of RAM in games that only want to setup a local multiplayer game. DSWiFi can be de-initialized and re-initialized in “local only” or “internet and local” modes whenver your application requires it. The documentation has been updated to reflect the new improvements.- Some static arrays used by sgIP are now allocated dynamically when the library is initialized. They are also freed when it is de-initialized.
mmutil:
- Change version number. Now it’s set from the environment instead of a hardcoded variable in the Makefile.
- Fix pattern flags when notes have non-empty volume. This bug was introduced in version 1.12.0. Thanks @GValiente for the bug report and @asiekierka for the help.
SDK:
-
The local multiplayer example of DSWiFi now initializes DSWiFi without sgIP so to save RAM.
-
Use C23 and C++23 to build all the ARM libraries.
-
GCC has been patched to always build
__aeabi_lmulin ARM mode, even for Thumb targets. This always leads to smaller and faster 64-bit multiply operations. @asiekierka -
picolibc has been updated with minor fixes to the
printffunction family.
libnds:
- A new function to control the LCD backlight level has been implemented,
systemSetBacklightLevel(). It works on DS, DS Lite and DSi. - Add a helper to set the master sound volume from the ARM9 called
soundSetMasterVolume(). - videoGL functions now copy textures and palettes to VRAM using
memcpy()instead of DMA copies. This will allow interrupts to happen while the copy is taking place instead of blocking the interrupts. - FatFs has been updated to R0.16. Also,
stat()now returns the actual creation timestamp of the file instead of using the time of the last access or modification. @asiekierka - libnds now checks that TLS isn’t used from IRQ handlers. This is only checked in debug builds of libnds because it would affect performance of some applications.
- Add support for compile-time evaluation of the
math.hfunctions. @Kuratius errnohandling has been fixed inscandir(). @shinyquagsire23- Fix memory leak in
open()when a file is failed to be opened. @shinyquagsire23 - Return 0 as modification and access dates of NitroFS files instead of leaving the fields uninitialized.
- Don’t clear
errnoinreaddir(). @asiekierka - Add new ARM7 audio defines that are less confusing than the previous ones. They are based on the names used by GBATEK. The audio helpers of libnds now use the new defines.
- The FatFs submodule link has been changed. If you want to update your current clone of BlocksDS you will need to manually edit
.git/modules/libs/libnds/modules/fatfs/configand change the URL to “blocksds” instead of “WonderfulToolchain”. You can also do a fresh clone. - Some Doxygen comments with missing information have been completed.
- The internal function
vramGetBank()has been improved with error checking. - Some videoGL code has been documented.
Maxmod
- The port to C has been completed. The only code left in assembly is the one that does software audio mixing on the GBA and the ARM7 of the DS. All of the definitions to access structures from assembly code have been deleted (except for the ones needed for the software mixing code).
- Some functions now return error codes instead of
void:mmInit(),mmInitDefault(),mmInitDefaultMem(),mmLoad(),mmUnload(),mmLoadEffect()andmmUnloadEffect(). - In the GBA port Maxmod can now be deinitialized with
mmEnd(). This isn’t possible on DS yet. - Helpers
mmGetModuleCount()andmmGetSampleCount()have been added to get the number of modules and samples available in the loaded sound bank. They are available from both CPUs. Previously, it was only possible on the ARM9, and only by accessing internal variables of Maxmod. - The following functions now check if the provided ID is out of bounds:
mmEffect(),mmEffectEx(),mmStart(),mmJingle(),mmLoad(),mmUnload(),mmLoadEffect()andmmUnloadEffect(). - All arrays have been marked as
const. Some functions have been moved back from IWRAM to ROM. This has no effect in the DS port, but it helps the GBA port reduce IWRAM usage. - Several comments have been added to the code.
- The code now uses the struct definitions of the headers instead of using magic numbers and assembly defines. Several variables have been modified to use the right types (for example, instead of using a
voidpointer, they use now pointers to the right type of struct). - A small bug when handling module channel bflags has been fixed.
- Fix the way in which the code that handles DCT accesses the instrument note map. This is a bug carried on from the assembly code.
mmSetPosition()is now available on the DS, not just the GBA.mmJingleStart()andmmJingleStop()have been implemented. They behave likemmStart()andmmStop(), so now jingles can also be played in a loop and they can be stopped at any point.mmJinglePause()andmmJingleResume()have been implemented.mmJingleActive()has been implemented.mmPosition(),mmJingle()andmmActiveSub()have been deprecated. UsemmSetPosition(),mmJingleStart()andmmJingleActive()instead.mmGetPosition()andmmGetPositionRow()have been implemented on the ARM9. The ARM7 refreshes the position once per frame, so the tick counter can easily skip values from the point of view of the ARM9. For that reason,mmGetPositionTick()hasn’t been implemented.- Sound effect handling has been heavily refactored. The ARM7 code that creates and reuses handles is now cleaner. The code that synchronizes the state of the sound effects from the ARM7 to the ARM9 has been removed. Now, the ARM9 sends messages to the ARM7 and it waits for the ARM7 to send the resulting handle to the ARM9. The previous system generated handles on the ARM9, which could cause channels to become permanently marked as “busy” on the ARM9 even if they were free on the ARM7.
mmEffectCancel()andmmEffectCancelAll()now work properly on DS.mmEffectCancelAll()can now stop released sound effects.mmEffectRelease()now has a big warning in the documentation mentioning that any effect that has been released can only be stopped by itself, by another effect or module, or bymmEffectCancelAll(). It can’t be stopped bymmEffectCancel().- A bug has been fixed where there could be memory corruption if a new active channel was requested but no more channels were available.
- In the documentation, create individual section for functions related to jingles. Keeping them in a different page than the functions for the main module means it’s easier to see the limitations of jingles.
- Events of type
MMCB_SONGMESSAGEnow include the layer (MM_MAINorMM_JINGLE) as part of the data passed to the callback. This is a compatibility break, but it’s very unlikely that anyone is getting events from a jingle, so it’s very unlikely to break any project. Events are rarely used, so the probability of ever finding a compatibility issue is almost 0. - Fix a crash that would happen when playing modules or jingles with more channels than allocated by Maxmod. Now, when Maxmod detects that the module (or jingle) tries to use a channel that is outside of the limits, it will just stop the song.
mmSetPatternEx()has been implemented, which lets the caller specify the new pattern order and row, not just the order like withmmSetPattern().- Build library with
-Osinstead of-O2in the ARM7 of the NDS to save memory.
mmutil:
- Some error checks have been added to prevent crashes if files can’t be opened or an output path isn’t provided. The application will now exit gracefully.
- Some magic numbers have been replaced by defines extracted from Maxmod. The code has been documented a bit.
- Some warnings have been fixed.
- The code has been reorganized. Variables now have reduced scopes instead of having whole functions as their scope.
- The command to build NDS test ROMs has been fixed in the documentation.
- The names of the temporary files created by the tool is no longer hardcoded. This makes it possible to execute mmutil multiple times from the same folder without conflicts.
DSWifi:
- Update instructions of how to enable debug output.
- Build library with
-Osinstead of-O2to save memory.
LibXM7:
- Use new libnds ARM7 audio defines.
SDK:
-
GCC has been updated to version 15.2.0 and binutils has been updated to version 2.45. @asiekierka
-
The default makefiles now print the mmutil command in verbose mode (
V=). -
The documentation now has a note about symlinks not working with MinGW.
-
Some Maxmod examples have been improved.
-
An example has been added to show how to set the LCD brightness level on different DS models.
libnds:
Rename symbols of FatFs inside libnds so that users can have their own copy of FatFs. @asiekierka
Improve normalizef32(): Fix normalization of large and small vectors and optimize its performance. @Kuratius, @19tracks
Fix base address of the bootstub struct.
Clarify documentation about how keysDownRepeat() works.
Move some key state handling to critical sections to prevent race conditions.
Fix implementation of swiIntrWait() on both CPUs. It has been rewritten in C and moved to the common folder so that both CPUs use the same implementation.
Two defines have been added for swiIntrWait(): INTRWAIT_KEEP_FLAGS and INTRWAIT_CLEAR_FLAGS.
Improve FIFO communications code:
- In FIFO wait loops, don’t discard current interrupts flags when calling
swiIntrWait(). If a FIFO interrupt has happened, exit the wait loop right away. - In
fifoWait*(), checkREG_IMEbefore callingswiIntrWait(). If interrupts are disabled, skip the wait.swiIntrWait()enables interrupts internally, and this may be an issue for code that relies on interrupts being disabled. The only side-effect of not callingswiIntrWait()is that the CPU won’t be able to enter low-power mode. - Fix some race conditions by moving some code and checks to critical sections.
- Add some new definitions related to FIFO interrupts that are clearer than the previous ones.
- Prevent deadlocks in some situations. For example, if the software RX queue was almost full, the hardware RX queue is half emptied in the IRQ handler, but it can’t be completely emptied, the FIFO code would never check the hardware RX queue again. There were similar situations with the TX queue. The new code adds checks for the RX and TX hardware queues in some other places (like
fifoCheck*()orfifoInternalSend()) that are likely to be executed in any potential user wait loop. - The FIFO buffer has been renamed to global FIFO pool. The send and receive queues have been renamed to RX and TX queues.
- Fix global pool corruption when the pool got filled with packets that hadn’t been handled. The code that allocates and frees blocks from the pool can’t handle the situation in which zero blocks are left, so the new code makes sure that there is always at least one free block in the pool.
- The code has been documented, and things like the global pool of blocks have been refactored to be much clearer.
- Unknown system FIFO commands will now crash the application instead of being ignored.
Improve cothread system:
- Show a crash message when trying to remove a nonexistent cothread context.
- Optimize
cothread_yield_irq(). - Prevent
cothread_yield(),cothread_yield_irq()andcothread_yield_irq_aux()from inside interrupt handlers. Instead of yielding,cothread_yield()returns right away, and the others callswiIntrWait()instead. swiIntrWait()is now only called ifREG_IME=1. If not, it is skipped.
Refactor global IRQ handler:
- Remove the
irqDummy()function, useNULLpointers instead. - Use fewer cycles to exit the handler when there isn’t an user interrupt handler assigned to the interrupt.
- Optimize code that wakes up threads waiting for an interrupt, preventing racen conditions.
Compile getHeap*() functions on the ARM7 too. @asiekierka
Maxmod:
- Fix Portamento + Volume Slide effect.
Grit:
- Crash if mode append is selected but it’s not allowed due to other settings. In the past, grit would just overwrite the invalid setting without warning the user.
- Add note to the documentation about how it is better to reduce quality of graphics before passing them to grit than to let grit reduce the quality.
SDK:
Documentation:
- Add a section to the “Usage notes” page about how to move the DTCM user variables to the end of DTCM using the
__dtcm_data_sizesymbol.
Examples:
- Fix example of streaming audio with Maxmod. Instead of reading the file from the Maxmod callback handler (which is inside an interrupt handler) the example now keeps a circular buffer. The main loop writes new data read from the file and the interrupt handler reads the data and sends it to Maxmod.
- Add example of displaying a 4 BPP tiled background. Rename the previous
bg_regularexample tobg_regular_8bitto clarify that it loads a 8 BPP tiled background. - Add example of creating an FPS counter.
- Add example of how to use the VBL interrupt.
- Improve C++ example to also run on the ARM7.
- Add example of how to use DMA to do HBLANK scroll effects.
- Add example of how to save and load data from the filesystem.
- Improve
key_inputexample to show the values returned bykeysDownRepeat(). - Fix build of the example that prints no$gba debug messages from both CPUs. Floating point support has been removed from
printf()on the ARM7 to save space.
Tests:
- The exit to loader test has been fixed (even though the exit code doesn’t work properly yet).
- Add a test to see how to exit CPU halt state with IRQs.
- Add a test to see the effect of deleting threads in different ways.
- Add a test to check that CPU contexts are preserved after returning from a cothread yield.
- Add a test to check the behaviour of the FIFO handling code when the FIFO hardware and software queues are full.
- Some test folders have been moved around for clarity.
- Add test of using the
__dtcm_data_sizesymbol.
Other:
-
Modify the default makefiles to allow the user to specify additional
LDFLAGSwhen including them.
libnds:
- Fix a bug that would crash the application if
__aeabi_atexit()was called when a dynamic library isn’t being loaded.
SDK:
-
Fix linker scripts to include the picolibc hook that calls all functions registered with the
atexit()family of functions. This also affected global destructors, which weren’t called at exit. @asiekierka -
Improve C++ example to test global destructors in addition to global constructors.
libnds:
- Improve performance of camera driver significantly.
- Support using TLS symbols from the main binary in dynamic libraries.
- Support
R_ARM_JUMP24relocation in dynamic libraries, which tends to be used for tail function calls in ARM mode. - Support global constructors and destructors in dynamic libraries. They are called when libraries are loaded and unloaded.
- Add
dlmembase()function to get the base address of a loaded dynamic library, which can be used to load the ELF file at the right address when debugging the program with GDB. - Add defines to manually place variables in ITCM.
- The two variables placed in DTCM by the cothreads code have been moved to ITCM to help the stack grow (they were being placed at the start of DTCM, which stopped the stack from growing into main RAM).
- Fix
grfLoadMemEx()andgrfLoadFileEx()when passingNULLinheader. - A few improvements to
hw_sqrtf(). @Kuratius - Minor documentation fixes. @Kuratius
- Reintroduce list of copyright holders to the license file. @asiekierka
- Uniformize license headers and update the list of copyright holders in the license file.
Maxmod:
- Fix some size definitions in the GBA public headers.
- Fix memory leaks when unloading modules. @ds-sloth
- A lot of assembly code has been converted to C, particularly code related to the module player and effects handling.
- Fix bug when stopping the playback of a module. This caused noise to be generated in the GBA port when a song was stopped.
- The DS programming guide has been fixed.
mmutil:
- Add readme to repository.
SDK:
dsltool:
- Support using TLS symbols from the main binary in dynamic libraries.
- Support
R_ARM_JUMP24relocations. - Support loading ELF files with more than 256 symbols. @jonko0493
- Add link to documentation about relocations.
- Support global constructors and destructors.
- Provide
__dso_handlein all dynamic libraries.
Examples:
- Add C constructor to basic dynamic library example and improve it in general.
- Add example of using C++ dynamic libraries.
- Let user stop song in audio modes Maxmod example.
Other:
-
Document limitations of dynamic libraries and how to debug them.
-
Enable default exception handler in the default debug ARM7 cores.
-
Clarify hack used in the crt0 to reference some symbols and prevent the garbage collector of the linker from removing it.
SDK:
Other:
-
Global initializers have been fixed for picolibc 1.8.10.
-
Fix conflicting types when including
math.hinstead ofcmathfrom C++ files.
Maxmod:
- Most of the files of the library have been converted from assembly to C to help people understand, maintain and improve the code. The remaining assembly code is the software mixing code of the ARM7 (on both DS and GBA modes) and the song player code (which is too big to convert in one go and it will require more work in the future). Both the GBA and DS ports have been tested. Thanks to @Lorenzooone for all his work!
- Some error checks have been added to code that didn’t have it (like all code using
fopen(),fread()ormalloc(). - Code that allocates memory now uses
calloc()instead ofmalloc()to clear the buffer before using it. - The unused Value32 FIFO handler code in the ARM7 has been removed.
- Cache management has been fixed. The cache handling functions of Maxmod were incorrect, and they have been removed. Now Maxmod uses the functions of libnds.
- IPC code that synchronized streaming between ARM7 and ARM9 has been improved. Instead of using shared memory to synchronize CPUs, new FIFO messages have been implemented. The old code required dangerous cache management that could corrupt variables surounding the “ready” flag used by the library.
SDK:
Other:
- GCC has been updated to version 15.1.0 in Wonderful Toolchain. You can check the release notes here. An important addition is the support for
#embed. - picolibc has been updated to version 1.8.10 in Wonderful Toolchain. Check the release notes here.
Examples:
-
A new example of how to use sound effects with Maxmod has been added.
-
The Maxmod streaming example has been fixed to not hang in DSi consoles or DS consoles with DLDI running on the ARM7.
-
The reverb Maxmod example has bee improved with a new song that makes the effect more evident.
-
The “sprites” example has been renamed to “sprites_regular” for clarity. Also, 128 KB sprite mapping mode is now used in this example, as this is what most developers would want in their own code.
-
Some comments have been added to the libnds sound example.
-
A missing example description has been added.
libnds:
- A new function has been added to reduce the heap space from the end of RAM:
reduceHeapSize(). - The sprite mapping enums have been simplified by removing a part of the value that wasn’t used by anything.
- A few documentation improvements in backgrounds, sprites and FIFO definitions.
SDK:
Documentation:
- The memory map documentation has been updated.
Examples:
- The images used in 2D sprites and backgrounds examples have been improved.
- A new example has been added to show how to use main engine video mode 6.
- A new example has been added to show how to use extended affine backgrounds. There was only an example of how to use regular affine backgrounds.
- The example of sprites that use extended palettes has been updated to use multiple palettes per engine instead of just one.
Tests:
- A new test has been added to check the bounds of the heap compared to the bounds of DTCM. It also checks if
reduceHeapSize(),malloc()andfree()interact the right way.
crts:
- A very old bug has been fixed where the heap end in DSi mode would allow malloc() to allocate memory inside DTCM (which is used by the stack, and would corrupt it). Thanks to @ds-sloth for the initial report that resulted in finding the bug.
Other:
-
A new tutorial for BlocksDS has been started. It’s available here, and the source code is available here.
libnds:
- Add initial helpers to load dynamic libraries with
dlfcn.hfunctions. Note that this is still experimental.dlopen(),dlsym(),dlerror()anddlclose()are supported. - Fixed global C++ constructors that require libnds and the cothread scheduler to be initialized. Some functions previously called from the crt0 have been moved to
cothread_main(), which runs after there is a valid multithreading environment. - Deallocate memory reserved for the FAT file system cache if
fatInit()fails. - Extend
statvfs()to return theST_RDONLYflag for read-only media. - File system operations should now return
EROFSfor read-only DLDI drivers. - Made
libndsCrash()public. - Fix potential issues involving FAT file system cache initialization.
- Add some checks to libc system call functions like
open().
DSWifi:
- Fix
ioctl(FIONREAD, x), which used to returnEINVALeven when it succeeded. - Remove Access Points from the list of availabled APs after enough time has passed without receiving any beacon packet from them.
Wifi_GetData()andWifi_GetAPData()have been updated to work with the changed system. - The array that specifies the order in which channels are scanned has been modified so that each channel is scanned the same number of times. This makes it easier to determine which APs to remove from the list of APs because we aren’t prioritizing APs from any channel. Also, scan mode now always start with channel 1.
- Old RSSI values of APs are now discarded instead of being used to average the value of the RSSI. This doesn’t really affect how the values behave in real life that much, so this change saves memory with no noticeable change in the behaviour of the library.
- Return error on timeouts when writing to baseband chip.
- Add error checks when initializing RF chip.
- Print debug message if the ARM7 TX queue is full when the library tries to add a new packet to it.
- Some documentation improvements.
dsltool:
- Introduced tool to the repository. This tool is used to convert dynamic libraries in ELF format to DSL format, which is similar to ELF, but simplified. This DSL format can be loaded by libnds with
dlopen().
teaktool:
- Ensure that ELF files are loaded correctly instead of crashing if they aren’t loaded and the pointer is NULL.
- Fix format in a printf.
SDK:
Documentation:
- The new dynamic library system has been documented in the main documentation of BlocksDS.
Examples:
- Three new examples have been added to show how to use the new dynamic library system.
crts:
- Some initialization has been moved away from the crt0 of the ARM9 to libnds to fix global C++ constructors that require libnds and the cothread scheduler to be initialized.
- A new linkerscript to build dynamic libraries has been added.
Other:
-
Libraries are now built with debug symbols (
-g) to help debug applications made with them.
libnds:
- Add a helper to convert UTF-16LE text (like the firmware player name and message) to UTF-8.
- Modify
assert()on the ARM7 to send the information to the ARM9 instead of displaying it on the no$gba console. - Added
swiIntrWaitAUX()for the ARM7. - The Doxygen documentation of interrupt functions has been fixed.
- The documentation of the firmware personal data has been improved with a warning saying that the struct may not be initialized right af the beginning of
main()on the ARM9. - Always use
fake_heap_startandfake_heap_endinsbrk(). - Some assertions in the timer functions were missing checks for values lower than zero, this has been fixed.
- All instances of
sassert()in common ARM7 and ARM9 code have been replaced byassert().
DSWifi:
- Add player name information to beacon packets, and add it to the
Wifi_AccessPointstruct so that clients can see it. This name can be replaced by any string defined by the developer if required. - Add way to get the RSSI of the AP we’re connected to. It can be done by calling
Wifi_GetData(WIFIGETDATA_RSSI). @Snowshoe - Always include
ASSOCSTATUS_STRINGSarray in builds. It used to be removed in builds without sgIP. - Some minor documentation fixes.
grit:
- Update documentation (command line interface and changelog).
- Let the build system define the version string compiled in the binary.
SDK:
Examples:
- In DSWifi examples, print multiplayer access points in color red when they aren’t accepting new connections. Also, display the player name provided by the beacon frames.
- There’s a new test to verify that
sbrk()works correctly in both the ARM7 and ARM9. - Update the asserts example to show that asserts that happen in the ARM7 are sent to the ARM9 and displayed on the screen.
Documentation:
- Document flag used for “twl” sections in ndstool and the linkerscripts.
Other:
-
Remove duplicated
__end__entries in ARM7 linkerscript files. -
The fake heap pointers are now setup on the ARM7, not only the ARM9.
-
The fake heap limit setup has been documented.
-
The R4RF DLDI driver included in the SDK has been updated.
-
Update CMake build system to link the debug version of libnds in debug builds.
libnds:
- videoGL now tracks the number of textures using a palettes correctly. Previously, palettes would be deleted even when there were textures using them. @sillysagiri
scanf()has been fixed so that it doesn’t record modifier keys on the output string.- Fix
readFirmware()andwriteFirmware()on the ARM9. They would silently fa