Last active
May 17, 2023 04:28
-
-
Save up-n-atom/f89bbc2e20576b55c17f810d2d48e405 to your computer and use it in GitHub Desktop.
ImHex WonderSwan EEPROM pattern
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <std/io.pat> | |
| #include <std/mem.pat> | |
| #include <std/string.pat> | |
| #define SAVE_DATA_SIZE 96 | |
| #define NAME_LENGTH 16 | |
| namespace type { | |
| struct PackedBCD<auto Nibbles> { | |
| u8 bytes[Nibbles / 2]; | |
| } [[sealed, format_read("type::impl::format_packed_bcd")]]; | |
| namespace impl { | |
| fn format_packed_bcd(ref auto bcd) { | |
| str result; | |
| for (u32 i = 0, i < sizeof(bcd.bytes), i += 1) { | |
| u8 byte = bcd.bytes[i]; | |
| result += std::format("{}{}", byte >> 4, byte & 0xf); | |
| } | |
| return result; | |
| }; | |
| } | |
| } | |
| bitfield SystemFlags { | |
| volumeLevel : 2 [[format("format_volume")]]; | |
| padding : 4; | |
| constrast : 1 [[format("format_contrast")]]; | |
| customSplash : 1; | |
| }; | |
| enum Volume : u8 { | |
| MUTED, | |
| LOW, | |
| MEDIUM, | |
| HIGH | |
| }; | |
| fn format_volume(auto volume) { | |
| Volume result = volume; | |
| return result; | |
| }; | |
| enum Contrast : u8 { | |
| LOW, | |
| HIGH | |
| }; | |
| fn format_contrast(auto constrast) { | |
| Contrast result = constrast; | |
| return result; | |
| }; | |
| struct SystemInfo { | |
| padding[1]; | |
| u16 id [[comment("swan id")]];; | |
| u8 cartCount [[comment("cartridge swap count")]]; | |
| u8 saveCount [[comment("eeprom save count")]];; | |
| u16 bootCount; | |
| // WonderSwan is only 1024bit | |
| if (std::mem::eof()) | |
| break; | |
| padding[3]; | |
| SystemFlags systemFlags [[inline]]; | |
| }; | |
| enum Publisher : u8 { | |
| BAN = 1, // Bandai | |
| TAT, // Taito | |
| TMY, // Tomy | |
| KEX, // Koei | |
| DTE, // Data East | |
| AAE, // Asmik Ace | |
| MDE, // Media Entertainment | |
| NHB, // Nichibutsu | |
| CCJ = 10, // Coconuts Japan | |
| SUM, // Sammy | |
| SUN, // Sun Soft | |
| PAW, // Mebius | |
| BPR, // Banpresto | |
| JLC = 16, // Jaleco | |
| MGA, // Imagineer | |
| KNM, // Konami | |
| KBS = 22, // Kobunsha | |
| BTM, // Bottom Up | |
| KGT, // Kaga Tech | |
| SRV, // Sunrise | |
| CFT, // Cyber Front | |
| MGH, // Mega House | |
| BEC = 29, // Interbec | |
| NAP, // Nihon Application | |
| BVL, // Bandai Visual | |
| ATN, // Athena | |
| KDX, // KID | |
| HAL, // HAL Corporation | |
| YKE, // Yuki Enterprise | |
| OMN, // Omega Micott | |
| LAY, // Layup | |
| KDK, // Kadokawa Shoten | |
| SHL, // Shall Luck | |
| SQR, // Squaresoft | |
| SCC = 42, | |
| TMC, // Tom Create | |
| NMC = 45, // Namco | |
| SES, | |
| HTR, | |
| VGD = 49, // Vanguard | |
| MGT, // Megatron | |
| WIZ, // Wiz | |
| TAN = 53, // Tanita | |
| CPC = 54 // Capcom | |
| }; | |
| struct CartInfo { | |
| Publisher publisher; | |
| u8 color; | |
| u8 id; | |
| } [[format("format_cart")]]; | |
| fn format_cart(ref auto cart) { | |
| str publisher = std::string::substr(std::string::to_string(cart.publisher), 11, 3); | |
| if (std::string::ends_with(publisher, "?")) | |
| return ""; | |
| return std::format("SWJ-{}" + (cart.color ? "C{:02d}" : "{:03d}"), publisher, cart.id); | |
| }; | |
| enum BloodType : u8 { | |
| A = 1, | |
| B, | |
| O, | |
| AB | |
| }; | |
| enum Gender : u8 { | |
| MALE = 1, | |
| FEMALE | |
| }; | |
| struct BirthDate { | |
| type::PackedBCD<4> year; | |
| type::PackedBCD<2> month; | |
| type::PackedBCD<2> day; | |
| } [[single_color, format("format_date")]]; | |
| fn format_date(ref auto date) { | |
| return std::format("{}-{}-{}", date.year, date.month, date.day); | |
| }; | |
| struct Name { | |
| char value[NAME_LENGTH]; | |
| } [[static, sealed, format("format_name")]]; | |
| fn format_name_char(char c) { | |
| if (c >= 1 && c <= 10) | |
| return std::format("{:c}", c + 47); | |
| else if (c >= 11 && c <= 36) | |
| return std::format("{:c}", c + 54); | |
| else if (c == 37) | |
| return "❤"; // unicode support added in v1.28.0 | |
| else if (c == 38) | |
| return "♪"; // unicode support added in v1.28.0 | |
| else if (c >= 39 && c <= 42) { | |
| return std::string::at("+-?.", (c - 39) & 3); | |
| } | |
| return " "; | |
| }; | |
| fn format_name(ref auto name) { | |
| str result; | |
| for (u8 i = 0, i < NAME_LENGTH, i = i + 1) | |
| result += format_name_char(std::string::at(name.value, i)); | |
| return result; | |
| }; | |
| struct OwnerInfo { | |
| Name name; | |
| BirthDate birthday; | |
| Gender gender; | |
| BloodType bloodType; | |
| }; | |
| struct Eeprom { | |
| u8 saveData[SAVE_DATA_SIZE]; | |
| OwnerInfo ownerInfo; | |
| CartInfo cartInfo; | |
| SystemInfo sysInfo; | |
| }; | |
| Eeprom eeprom @ 0x00; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment