Skip to content

Instantly share code, notes, and snippets.

@up-n-atom
Last active May 17, 2023 04:28
Show Gist options
  • Select an option

  • Save up-n-atom/f89bbc2e20576b55c17f810d2d48e405 to your computer and use it in GitHub Desktop.

Select an option

Save up-n-atom/f89bbc2e20576b55c17f810d2d48e405 to your computer and use it in GitHub Desktop.
ImHex WonderSwan EEPROM pattern
#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