Skip to content

Instantly share code, notes, and snippets.

@applecuckoo
Last active October 4, 2024 22:45
Show Gist options
  • Save applecuckoo/b6472465a8fb84b3e7488448a4a217e3 to your computer and use it in GitHub Desktop.
Save applecuckoo/b6472465a8fb84b3e7488448a4a217e3 to your computer and use it in GitHub Desktop.
A draft ImHex pattern for the VGM chiptune file format
#pragma author applecuckoo
#pragma description VGM chiptune files (WIP)
#pragma endian little
#pragma MIME audio/x-vgm
import type.magic;
import type.byte;
import std.core;
import std.string;
import std.ptr;
import std.fxpt;
import std.io;
import std.math;
struct PackedBCD<auto Digits> {
type::Nibbles bytes[Digits];
} [[/*sealed,*/ format("format_packed_bcd")]];
fn format_packed_bcd(auto bcd) {
str result;
for (u32 i = 3, i < sizeof(bcd.bytes), i -= 1) {
u8 highbyte = bcd.bytes[i].high;
if (highbyte >= 10)
return "Invalid";
result += std::format("{}", highbyte);
u8 lowbyte = bcd.bytes[i].low;
if (lowbyte >= 10)
return "Invalid";
result += std::format("{}", lowbyte);
}
std::fxpt::fixed result_fmt;
result_fmt = std::string::parse_int(result, 10);
return result_fmt;
};
bitfield SN76489Flags {
frequency : 1;
negateOutput : 1;
GameGearStereo : 1;
clockDiv : 1;
XNORNoiseMode : 1;
padding : 3;
};
bitfield AY8910Flags {
legacyOutput : 1;
singleOutput : 1;
discreteOutput : 1;
RAWOutput : 1;
YMclockDivLow : 1;
padding : 3;
};
bitfield OKIM6258Flags {
clockDiv : 2;
ADPCMsel : 1;
outputBitDepth : 1;
padding : 4;
};
bitfield K054539Flags {
reverseStereo : 1;
disableReverb : 1;
KeyOnUpdate : 1;
padding : 5;
};
enum AY8190Type : u8 {
AY8910,
AY8912,
AY8913,
AY8914,
YM2149 = 0x10,
YM3439,
YMZ284,
YMZ294,
};
enum C140Type : u8 {
C140_NamcoSystem2,
C140_NamcoSystem21,
ASIC219_NamcoNA,
};
struct Gd3 {
type::Magic<"Gd3 "> ident;
u8 version[4];
u32 Gd3Length;
std::string::NullString16 trackNameEng;
std::string::NullString16 trackNameOriginal;
std::string::NullString16 gameNameEng;
std::string::NullString16 gameNameOriginal;
std::string::NullString16 sysNameEng;
std::string::NullString16 sysNameOriginal;
std::string::NullString16 trackAuthorEnglish;
std::string::NullString16 trackAuthorOriginal;
std::string::NullString16 gameReleaseDate;
std::string::NullString16 VGMConverter;
std::string::NullString16 Notes;
};
struct Header {
type::Magic<"Vgm "> ident;
u32 eofOffset;
PackedBCD<4> version; // TODO: decode this 'properly'? this is 4-bit BCD
u32 SN76489_clk; // TODO: bit 31 and the dual chip bit indicates if a T6W28 is in play
u32 YM2413_clk;
Gd3 *Gd3Offset : u32 [[pointer_base("std::ptr::relative_to_parent")]];
u32 sampleCount;
u32 loopOffset;
u32 loopSamples;
// VGM 1.01 onwards
u32 rate;
// VGM 1.10 onwards
u16 SN76489_feedback;
u8 SN76489_shift_width;
// VGM 1.51 onwards
SN76489Flags snflags;
// VGM 1.10 onwards
u32 YM2612_clk;
u32 YM2151_clk;
// VGM 1.50 onwards
u32 VGMOffset;
// VGM 1.51 onwards
u32 SegaPCM_clk;
u32 SegaPCM_reg;
u32 RF5C68_clk;
u32 YM2203_clk;
u32 YM2608_clk;
u32 YM2610_clk; // TODO: bit 31 indicates if this is a YM2610B or not
u32 YM3812_clk;
u32 YM3526_clk;
u32 Y8950_clk;
u32 YMF262_clk;
u32 YMF278B_clk;
u32 YMF271_clk;
u32 YMZ280B_clk;
u32 RF5C164_clk;
u32 PWM_clk;
u32 AY8910_clk;
AY8190Type AY8910_type;
AY8910Flags AY8910_flags;
u8 YM2203_flags;
u8 YM2608_flags;
// VGM 1.60 onwards
u8 volumeMod;
padding[1];
u8 loopBase;
// VGM 1.51 onwards
u8 loopMod;
// VGM 1.61 onwards
u32 DMG_clk;
u32 APU_clk; // TODO: bit 31 enables the FDS sound addon
u32 MultiPCM_clk;
u32 uPD7759_clk;
u32 OKIM6258_clk;
OKIM6258Flags OKIM6258_flags;
K054539Flags K054539_flags;
C140Type C140_type;
padding[1];
u32 OKIM6295_clk;
u32 K051649_clk;
u32 K054539_clk;
u32 HuC6280_clk;
u32 C140_clk;
u32 K053260_clk;
u32 Pokey_clk;
u32 QSound_clk;
// VGM 1.71 onwards
u32 SCSP_clk;
// VGM 1.70 onwards
u32 extraHeaderOffset;
// VGM 1.71 onwards
u32 WonderSwan_clk;
u32 VSU_clk;
u32 SAA1099_clk;
u32 ES5503_clk;
u32 ES5005_clk;
u8 ES5503_ch;
u8 ES5505_ch; // TODO: bit 31 indicates if this chip is an ES5505 or a ES5506
u8 C352_clockDiv;
u32 X1_010_clk;
u32 C352_clk;
u32 GA20_clk;
// VGM 1.72 onwards
u32 Mikey_clk;
};
struct VGM {
Header header;
};
VGM vgm @ 0x00;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment