IPS supposedly stands for "International Patching System" and is a patching format that was common with older ROMs back in the day.
The format is old and has limitations, so it's not often used today but I still wanted to keep the information alive as there are less sites documenting the format nowadays.
- IPS addresses offsets to the original file in a 24-bit value, therefore it is limited to
2^24meaning it can only patch up to the first 16 MiB of the file. - The patches themselves use 16-bit for the length and so it can only include patches up to
2^16or 64 KiB at a time.
| Section | Size (bytes) | Description |
|---|---|---|
| Header | 5 | Magic header identifying an IPS File, the header spells PATCH |
| Patches | 3 + 2 + Variable | Main patch records, see below |
| End of file marker | 3 | A marker showing that the end of file has been reached, it spells out EOF |
There are two types of patch records that can be found in the main section, normal patches just give some data to be patched in a specific offset, and Run Length Encoding (RLE) patches
| Section | Size (bytes) | Description |
|---|---|---|
| Offset | 3 | Offset in the original file where this patch should be applied |
| Length | 2 | Length of the patch that follows this section |
| Patch | Variable | The patch data itself is here, use the previous section to judge the size, if length is 0 this is where the RLE data lives, see below |
RLE Patches can be identified when length field is 0 if length is zero the patch section then becomes
| Section | Size (bytes) | Description |
|---|---|---|
| Run Length | 2 | The next value should be repeated this many bytes |
| Value | 1 | This is the value that needs to be repeated |
You can see an implementation of this in Python here: ravener/ips-patcher