diff --git a/README.md b/README.md index ac59acc..e594611 100644 --- a/README.md +++ b/README.md @@ -116,6 +116,7 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi | QOI | `image/qoi` | [`patterns/qoi.hexpat`](patterns/qoi.hexpat) | QOI image files | | RAS | `image/x-sun-raster` | [`patterns/ras.hexpat`](patterns/ras.hexpat) | RAS image files | | ReFS | | [`patterns/refs.hexpat`](patterns/refs.hexpat) | Microsoft Resilient File System | +| RGBDS | | [`patterns/rgbds.hexpat`](patterns/rgbds.hexpat) | [RGBDS](https://rgbds.gbdev.io) object file format | | Shell Link | `application/x-ms-shortcut` | [`patterns/lnk.hexpat`](patterns/lnk.hexpat) | Windows Shell Link file format | | shp | | [`patterns/shp.hexpat`](patterns/shp.hexpat) | ESRI shape file | | shx | | [`patterns/shx.hexpat`](patterns/shx.hexpat) | ESRI index file | diff --git a/patterns/rgbds.hexpat b/patterns/rgbds.hexpat new file mode 100644 index 0000000..5752824 --- /dev/null +++ b/patterns/rgbds.hexpat @@ -0,0 +1,132 @@ +#pragma author ISSOtm +#pragma description Object files for the RGBDS Game Boy assembly toolchain +// Documentation: https://rgbds.gbdev.io/docs/rgbds.5 + +#pragma magic [ 52 47 42 39 ] @ 0x00 +#pragma endian little + +#include + +using LONG = u32; +using BYTE = u8; +using STRING = std::string::NullString; + +char magic[4] @ 0; +LONG revNum @ $; +LONG nbSym @ $; +LONG nbSect @ $; + +namespace fstack { + enum Type : BYTE { + REPT, + File, + Macro, + }; + struct Node { + LONG parentID; + LONG parentLineNo; + Type type; + if (type != Type::REPT) { + STRING name; + } else { + LONG depth; + LONG iters[depth]; + } + }; + + LONG nbNodes @ $; + Node nodes[nbNodes] @ $; +} + +namespace sym { + enum Type : BYTE { + Local, + Import, + Exported, + }; + struct Symbol { + STRING name; + Type type; + if (type != Type::Import) { + LONG nodeID; + LONG lineNo; + LONG sectionID; + LONG value; + } + }; + + Symbol symbols[nbSym] @ $; +} + +namespace sect { + enum PatchType : BYTE { + DB, + DW, + DL, + JR, + }; + struct Patch { + LONG nodeID; + LONG lineNo; + LONG ofs; + LONG pcSectID; + LONG pcOfs; + PatchType type; + LONG rpnSize; + BYTE rpn[rpnSize]; + }; + + enum Type : BYTE { + WRAM0, + VRAM, + ROMX, + ROM0, + HRAM, + WRAMX, + SRAM, + OAM, + }; + bitfield Attrs { + Type type : 6; + bool isFragment : 1; + bool isUnion : 1; + }; + struct Section { + STRING name; + LONG size; + Attrs attrs; + LONG address; + LONG bank; + BYTE alignment; + LONG alignOfs; + if (attrs.type == Type::ROMX || attrs.type == Type::ROM0) { + BYTE data[size]; + LONG nbPatches; + Patch patches[nbPatches]; + } + }; + + Section sections[nbSect] @ $; +} + +namespace assert { + enum Type : BYTE { + Warn, + Err, + Fatal, + }; + struct Assertion { + LONG nodeID; + LONG lineNo; + LONG ofs; + LONG pcSectID; + LONG pcOfs; + Type type; + LONG rpnSize; + BYTE rpn[rpnSize]; + STRING msg; + }; + + LONG nbAsserts @ $; + Assertion assertions[nbAsserts] @ $; +} diff --git a/tests/patterns/test_data/rgbds.hexpat.o b/tests/patterns/test_data/rgbds.hexpat.o new file mode 100644 index 0000000..5a067b5 Binary files /dev/null and b/tests/patterns/test_data/rgbds.hexpat.o differ