Garhoogin @garhoogin.com · 13/08/2025Though most changes introduced with each revision to the DS firmware had minimal visible difference, the 2005-02-28 version does introduce a bug fix for the initial setup language selection GUI. Before, you could input the Back button before the animation completes, cutting off the selection sound. 030
Garhoogin @garhoogin.com · 24/07/2025The BNFR font file format used by the firmware does not have support for kerning pairs, so the spacing between the L and T in "HEALTH" would appear too wide. The BNLL file splits the text at this point and moves the letters 1 pixel closer together. This is only done for English. [2/2] 030
Garhoogin @garhoogin.com · 24/07/2025In the DS firmware boot menu, the health and safety heading text is split into two separate text elements to adjust for kerning in the word HEALTH. This is controlled by a BNLL file, which defines text and where it goes on the screen. [1/2] 151
Garhoogin @garhoogin.com · 26/02/2025By the version 2006-03-08, the firmware is no longer applying the patch on the basis of game title ID, but by scanning for the applicable code sequences in the game's code. I'd like to write a full comprehensive list of all changes between versions some time, but that will take a while. [6/6] 010
Garhoogin @garhoogin.com · 26/02/2025The patches affect game title IDs ADMx (Animal Crossing: Wild World, all versions), ASCx (Sonic Rush v0), AYAJ (Big Brain Academy v0, v1), ATGJ (Daredemo Asobi Taizen v0), ABLJ (The Blade of Fate v0), and AM9J (Lost Magic v0). These patches are not applied in the IS-NITRO versions. [5/6] 110
Garhoogin @garhoogin.com · 26/02/2025The DS wireless patches were introduced in firmware version 2006-02-05 following discussion of games having wireless errors on the DS Lite's updated MAC. They patch the WaitLoop_ClrAid function to check for MAC states of MP response and pre-response. [4/6] 110
Garhoogin @garhoogin.com · 26/02/2025One notable thing I found is that the code for download play patching for Super Mario 64 DS was only added in the version 2005-02-28. This version also replaces their slow ASH decompressor written in C to one written in assembly. [3/6] 110
Garhoogin @garhoogin.com · 26/02/2025The two IS-NITRO-EMULATOR firmware versions dated 2006-02-20 (original controller and USG controller) are actually identical in code and data, only differing in the IPL2 type field in the header, where the USG controller version sets the USG bit (which allows configuring the backlight level). [2/6] 110
Garhoogin @garhoogin.com · 26/02/2025I've been examining the differences between different DS firmware versions, I'm surprised that there isn't much information about what's different between them. [1/6] 130
Garhoogin @garhoogin.com · 09/02/2025Took some time this week to write up a quick and dirty program for operating on DS firmware images. Can clean/replace user data, extract/replace modules, fix errors and more. Find it at github.com/Garhoogin/fw.... :)github.comGitHub - Garhoogin/fwutil: Operate on DS firmware.Operate on DS firmware. Contribute to Garhoogin/fwutil development by creating an account on GitHub. 020
Garhoogin @garhoogin.com · 25/01/2025Given the final result, it's clear that there's nothing specific to 24-bit RGB values here, nor does the color channel order have any effect. This can be adjusted to other channel widths by changing the OR bitmap. For 15-bit RGB, for example, use 0x4210. [9/9] 020
Garhoogin @garhoogin.com · 25/01/2025It becomes clear that all we're doing after right shifting the color one place is separating and re-combining parts of the color. It can finally be simplified: [8/9] 110
Garhoogin @garhoogin.com · 25/01/2025It becomes apparent now that since we're going to be setting the most significant bit of each channel with the final OR with 0x808080, we don't need to worry about clearing the upper bit of each channel. We'll rearrange some shifts: [7/9] 110
Garhoogin @garhoogin.com · 25/01/2025We can pull out the right shifts on each of the channels next by combining some shifts: [6/9] 110
Garhoogin @garhoogin.com · 25/01/2025We can pull some operations out. First, we can eliminate some of the OR operations: [5/9] 110
Garhoogin @garhoogin.com · 25/01/2025Given y is 8 bits, right shifting it one place gives a 7-bit value. Because the addition will not produce any carries, it can be written with a bitwise OR operation. Applying this to all channels gives the following code: [4/9] 110
Garhoogin @garhoogin.com · 25/01/2025I want this to round half up to the next whole number, so I will add 1 before dividing by 2. This gives y'=(y+256)/2. In bitwise terms, this last equation can be written y'=(y+0x100)>>1. The addition can be pulled out, giving y'=(y>>1)+0x80. [3/9] 110
Garhoogin @garhoogin.com · 25/01/2025Here, I define colors as a 24-bit value where the least significant 8 bits are the level of red, then the next 8 bits are the green level, then the blue level. The formula I use to average a color with white is to apply an averaging on each channel with 255. This looks like y'=(y+255)/2. [2/9] 110
Garhoogin @garhoogin.com · 25/01/2025A cool bit trick I've picked up is a really quick way to average an RGB color with white. In the end, the whole process is reduced to just two operations. Over the course of this thread I'll walk through my process of coming to this conclusion, and hope that you might find it interesting. [1/9] 130
Garhoogin @garhoogin.com · 31/12/2024Guessing this is a resource saving mechanism? Mario Kart DS does something similar for Download Play, to reduce memory and download time. Perhaps it was considered a minor detail and worth cutting corners on? 100
Garhoogin @garhoogin.com · 18/12/2024Overall, you get a 3 bits-per-pixel texture data (2 bits per pixel in texel data plus 1 bit per pixel, on average, in index data), plus the size of the palette. Using good techniques in the encoder, you can achieve a really strong quality of compression. [7/7] 010
Garhoogin @garhoogin.com · 18/12/2024There's other opportunities for optimization too. You may choose to use transparent mode on an interpolated tile even when it has no transparent colors if the interpolated color is better fitting the colors in that tile than the 2 you'd get without it. [6/7] 110
Garhoogin @garhoogin.com · 18/12/2024This makes encoding difficult, since it allows not only for palettes to be shared, it allows them to be overlapped. Two 4-color palettes may share 2 of their colors, for example. Or even more confusingly, a 2-color interpolated palette can have its colors used as part of a 4-color palette. [5/7] 110
Garhoogin @garhoogin.com · 18/12/2024There's one final flag stored in the index data, which indicates the tile uses a transparent color mode. For the interpolated color mode, this gives only one interpolated color, and color index 3 becomes transparent. For full 4-color mode, you lose the third color for transparent. [4/7] 110
Garhoogin @garhoogin.com · 18/12/2024In addition to this, the index data includes a flag to select a 4-color mode instead of 2 colors and 2 interpolated colors. This opens up a lot of opportunity to extract more texture quality out of the format. The palette index is still in terms of 2-color palettes, however. [3/7] 110
Garhoogin @garhoogin.com · 18/12/2024For one, rather than storing 2 colors with the 4x4 block of pixels, the colors are stored in a palette separate from the texture data, and a 16-bit unit of data (index) associated with each 4x4 block gives the palette index for that tile. This allows multiple tiles to share a single palette. [2/7] 110
Garhoogin @garhoogin.com · 18/12/2024Texture compression on the DS is such a tricky thing. In a way, it's structurally similar to common DXT texture compression. It's just different enough to make it a huge pain to encode. [1/7] 110
Garhoogin @garhoogin.com · 16/12/2024That would make sense, there's definitely not enough hanzi in this glyph set to represent much meaningful Chinese. This image I just rendered from font 0 (main font) in my IS-NITRO's firmware, so I'm sure a JNFR from a Chinese firmware would be a good bit larger. 020
Garhoogin @garhoogin.com · 16/12/2024In a way that makes sense, given that the font the banner text renders with has the following glyphs to use, none of which appear Cyrillic that I can tell: 120
Garhoogin @garhoogin.com · 15/12/2024For other languages, the search order is English, German, French, Spanish, Italian, than Japanese. If no banner text is available in any language, then the firmware uses the user's current language (i.e. shows no text). [3/3] 040
Garhoogin @garhoogin.com · 15/12/2024For English, if no English banner text exists, then it searches in order of French, Spanish, German, Italian, then Japanese. For Japanese, it searches in order of English, German, French, Spanish, then Italian. [2/3] 130
Garhoogin @garhoogin.com · 15/12/2024Something cool the DS firmware does is that it tries to display banner text in the boot menu even when banner text for the user's language is not present. What's also interesting is that the way it searches for the banner text depends on the selected language. [1/3] 230
Garhoogin @garhoogin.com · 11/12/2024The receiving system performs some checks on the sequence, like ensuring the time delay is between 1 and 100 frames. The chime sequences for the L+Up, L+Left and L+Right combinations all have invalid time delays, which results in no sound. I've restored the sounds playable here attached. [9/9] 010
Garhoogin @garhoogin.com · 11/12/2024In that 5th byte, the lowest bit indicates the sequence should have a random pitch variation. Bit 1 adds a slight random time fluctuation between each note. And lastly bit 2 enables a sound modulation, creating a warbly effect on the sound. [8/9] 120
Garhoogin @garhoogin.com · 11/12/2024Some fields in the first 6 bytes control attributes of the chime sequence. The first byte, when set to 1, makes the receiving system override the chime sequence with its default sequence. The second byte controls the number of frames each note lasts. The 5th byte is a set of flags. [7/9] 120
Garhoogin @garhoogin.com · 11/12/2024The code 0x19 functions as a no-op code, which can be used to sustain or rest. The 0x1A code stops the note, serving as a staccato. The 0x1B is the terminating code, which ends the chime sequence. On receipt, the receiving systems verify the chime sequence to ensure there is an ending code. [6/9] 120
Garhoogin @garhoogin.com · 11/12/2024The chimes themselves are described in a 23-byte header preceding the picture. Up to 17 of these bytes descibe the chime sequence, which consists of an array of notes that may take values between 0x00 and 0x18 inclusive. There are a couple other codes that are used as well. [5/9] 120
Garhoogin @garhoogin.com · 11/12/2024The L+Down key combination on an original DS sets a field in the header that tells the receiving system to override the chime with its own default, which is why it sounds normal when received on original DS, and sounds extended on a DSi. The extended chime is the default chime on the DSi. [4/9] 120
Garhoogin @garhoogin.com · 11/12/2024Of note is that the chime sound that plays is a part of the PictoChat protocol, so the sound of the chime is determined by the system that sends the picture. Notably, when you send a picture on a DSi, it uses an extended chime sound by default. [3/9] 120
Garhoogin @garhoogin.com · 11/12/2024Holding the L and either left, right, or up keys together results in a silenced chime. Holding the L and down keys together has no effect on an original DS, but when received on a DSi it plays a longer extended chime. [2/9] 120
Garhoogin @garhoogin.com · 11/12/2024A really cool detail on the DS that I think seems to be often overlooked is that PictoChat has a feature that allows you to change up the message chime by holding certain keys while sending a message. [1/9] 120
Garhoogin @garhoogin.com · 10/12/2024When no valid game card is detected, then the firmware starts up as normal. This is the state that it starts in when first powered on, giving access to the user configuration menu, and to test PictoChat and Download Play. [7/7] 020
Garhoogin @garhoogin.com · 10/12/2024When a valid card is detected that has no debug program, the firmware skips the health and safety screen and displays the boot menu. The game banner is displayed, but booting the game card is disabled. This is used to preview the game banner from within the debugger. [6/7] 120
Garhoogin @garhoogin.com · 10/12/2024The debugger first transfers the user ROM into emulation memory, then the debug monitor program is written over it toward the end. This enables the firmware to load and run the debug initialization code before the user code is run; the debugger then restores the ROM to its original state. [5/7] 120
Garhoogin @garhoogin.com · 10/12/2024When the firmware boots the game card, it checks (redundantly) that it is running on a debugger. When it sees this, it boots into the debug program rather than the user card program. Under normal circumstances, the debug program is inserted by the debugger just before booting. [4/7] 120
Garhoogin @garhoogin.com · 10/12/2024The firmware behaves differently under some conditions at startup. For one, when a valid card is detected with a debug program attached, the firmware skips the boot UI and loads right into the debug program entrypoints. This is how programs are normally booted during debugging. [3/7] 120
Garhoogin @garhoogin.com · 10/12/2024The firmware programs are different, however. The debugger firmware has checks in place to ensure that it is running on a debugger. If a debugger is not detected, it hangs on startup before the health and safety screen. [2/7] 120
Garhoogin @garhoogin.com · 10/12/2024The IS-NITRO-EMULATOR follows an interesting boot process when compared to that of a normal retail DS unit. The debugger's BIOS is identical to a retail unit's. Both contain code to detect the debugger on startup. The isDebugger field in shared memory is then set to 1 when detected. [1/7] 120
Garhoogin @garhoogin.com · 07/12/2024Given that games on Iris were run from the GBA cartridge slot, having a footer structure allows game code at runtime to simply ignore the footer data and use it as a raw data blob. The new DS card slot, where games are not mapped to memory, may have been why this was changed. [7/7] 030
Garhoogin @garhoogin.com · 07/12/2024The main differences in the file format are where newer hardware features are supported, such as extended palettes and affine extended backgrounds. The file version signature strings were also updated, and some fields rearranged. An example ISC file is attached here: [6/7] 120