Instrument definitions The first byte tell the type of the instrument: 0x00 Sample 0x01 Square 1 0x02 Square 2 0x03 Programmable waveform (channel 3) 0x04 Noise 0x05-0x07 Makes the game crash 0x08 Sample that isn't resampled (always playing at the engine's pitch, probably faster) 0x09-0x0C Same as 0x01-0x04 as far as I can tell 0x40 Key split instrument (points to different sub-instruments depending on MIDI key) 0x80 Every Key split instrument / percussion (each MIDI key points to its own sub-instrument) Sampled Instrument (0x00) format: 00 kk 00 pp xxxxxxxx aa dd ss rr | | | | | | |_} Release value (8-bit), lower = fastest release | | | | | | Disabled with 0x00 | | | | | |____} Sustain level (8-bit) | | | | | Disabled with 0xFF | | | | |_______} Decay value (8-bit), lower = faster decay | | | | Disabled with 0x00 | | | |__________} Attack value (8-bit), lower = slower attack | | | Disabled with 0xFF | | |___________________} Pointer to sample data | |______________________} Panning (only used as percussion sub-instrument) |____________________________} MIDI key (only used as percussion sub-instrument) (usually 0x3C, mid-C in MIDI standard) PSG Instrument (0x01-0x04) format: cc kk tt ss | | | |_} Sweep control (only channel 1) | | | Disabled with 0x08 | | |____} Hardware time length control | | Disabled with 0x00 | |_______} MIDI key (usually 0x3C or 0x00, apparently have no effect) |__________} Channel If Square channel: dd 000000 |_} Duty cycle 0=12,5%, 1=25%, 2=50%, 3=75% If Noise channel: pp 000000 |_} Control of the noise's period (0 = 32767 samples, 1 = 127 samples) If Programmable Waveform channel: xxxxxxxx |_} Pointer to 16-byte waveform data aa dd ss rr | | | |_} Attack value (3-bit), higher = slower attack | | | Disabled with 0x00 | | |____} Decay value (3-bit), higher = slower decay | | Disabled with 0x00 | |_______} Sustain level (4-bit) | Disabled with 0x0F |__________} Release value (3-bit), lower = fastest release Disabled with 0x00 Dummy instruments are: 01 3C 00 00 02 000000 00 00 0F 00 See: Instrument definitions.txt $08002000 subroutine: ::03004450:: (r0 parameter) 03004474: Pointer to ROM ::030055B0:: (r1 parameter) 030055C4: Pointer to ROM Instrument = 3004450ROM * 12 + 30055C4ROM 03004484 = Instrument type (byte0) If instrument type == 80h: 03004450 |= 80h 03004490 = Pointer (word4) If instrument type == 40h: 03004450 |= 40h 03004490 = Pointer0 (word4) 03004494 = Pointer1 (word8) If instrument <= 3Fh: 03004450 &= 0Fh 03004486 = PSG Hardware time length control (byte2) With r1 = 03004484 & 07h If r1 == 01h/02h: If Sweep control (byte3) hasn't 80h and has 70h: 03004487 = Sweep control Else: 03004487 = 08h (disable) 03004488 = Duty cycle (word4) << 6 If r1 == 03h: With r0 = [Waveform data pointer (word04)] 04000070 (SOUND3CNT_L) = 40h (Wave RAM Bank = 1) 04000090 (WAVE_RAM) = r0[0..10h] 04000070 (SOUND3CNT_L) = 00h (1 Bank, RAM Bank = 0, Channel = off) If r1 == 04h: 03004488 = Noise period (word04) << 3 If r1 == 00h: 03004488 = Sample data pointer (word04) 0300448C = ADSR (word08) ++03004474 $0800481C subroutine: For instrument 80h ::03004180:: (r0 parameter) r1 = Pointer + [[030041C4]+[03004181]]*12 r2 = [03004181] r3 = [[030041C4]+[03004181]]*12 r4 = 0Ch If 03004180 hasn't 70h: Pointer + 03004181*12 030041B5 = byte01 If byte03 == 0: 03004186 = 40h Elseif byte03 >= 80h: 03004186 = byte03 - 80h Else: Pointer + [030041C4+03004181]*12