-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSuper Mario Bros 3 Music Format.txt
677 lines (582 loc) · 38.3 KB
/
Super Mario Bros 3 Music Format.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
SUPER MARIO BROS. 3 MUSIC FORMAT
v1.1
By Justin Olbrantz (Quantam)
The permanent home of this specification and others, with the latest updates, is https://github.com/TheRealQuantam/RetroDocs.
This specification describes the music engine used by Super Mario Bros. 3, the last game released on the Nintendo Entertainment System by Nintendo's Research and Development 4, the group famous for legendary game designer Shigeru Miyamoto and composer Koji Kondo and responsible for the Super Mario and Legend of Zelda franchises. From the perspective of a music hacker, the R&D4 group is also famous for its distinctive music engines. While there is some variation in encoding between games, all of R&D4's NES engines share some common features which combine to make them outright hostile to romhackers seeking to insert their own music into the games and tool makers who might try to make this process easier.
First, R&D4 engines are EXTREMELY basic. While engines by other companies typically have robust, flexible engines designed to give maximum flexibility to the composer and allow the engine to be used with little to no modification in many games with many types of music, R&D4 engines are typically hybrid systems that combine basic note data with hard-coded hardware settings that provide the special sauce for each game's distinctive sound. These engines typically only have 3 event types: notes, rests, and set note length commands; if you're lucky there might be a set timbre or portamento command, as in SMB3, or timbre might be hard-coded in the engine, as in earlier R&D4 games.
Second, R&D4 uses a track format unlike anything I've seen from other companies or groups - a format which seems to have anachronistic origins tracing back to Nintendo's very first NES game. While it is standard practice to separate track data into hardware channels to allow for compression structures such as loops to take full advantage, the primary division of data in R&D4 engines is time. In a structure reminiscent of trackers such as FamiTracker, data for all channels is bundled together into blocks of varying duration, and these blocks are then strung together into a complete track by a global block playlist; segments of music data are repeated not by any kind of loop structure, but simply by putting the block in the playlist multiple times. This rigid structure places many constraints on romhackers that are absent in non-R&D4 formats.
Basic Features:
- Single byte notes and rests, though current note length must be previously defined with an additional byte
+ Hybrid tempo system that mimics staff notation style divisive rhythm
- 5-octave chromatic scale from A#1 (58.27 Hz) to D7 (2349 Hz) for square wave (triangle is 1 octave lower).
- 13 note lengths from whole notes through 16th notes with dots and triplets for some lengths for all tempos, plus several tempo-specific lengths
- 10 tempos ranging from 112.5 to 450 BPM
- 5 channels - square 1, square 2, triangle, noise, and DMC - each with separate event sequences
+ Multi-timbre support
- 8 square timbres with non-looping duty cycle/volume envelopes, plus 1 hard-coded timbre using pitch slide
- 3 percussion noise presets
- 16 DMC percussion presets on 9 instruments
- Rising portamento for the square channels
+ Tracker-like block structure
- Track data divided first by time, then channel
- Variable-duration blocks of fixed maximum physical size
- Tracks constructed of a playlist of blocks
- Single tempo per block
Some general notes in interpreting this specification:
- All word (16-bit) values in the format are little-endian, with the least-significant byte preceding the most-significant.
- All values are unsigned unless noted otherwise.
- All numbers preceded by $ are hex, and in general unless they represent byte strings or addresses most numbers without $ are in decimal.
- Byte values are generally shown as hex "ab" where "a" is the high nibble and "b" is the low nibble (standard mathematical digit ordering). When it is necessary to show bit fields, bytes are shown in binary as "abcd efgh" (again mathematical order); in bit fields "-" means that the value of the bit does not matter in the given context.
- Many command lists (e.g. channel data commands) are encoded ambiguously, where 1 value could be interpreted as multiple different commands (e.g. 00 could also match 0n). These lists are ordered such that the first matching command is the correct interpretation.
- A wave's "period" is inversely proportionate to its frequency; in the NES the square wave channel's period = 1789773/16 / frequency (triangle channel is 1 octave lower for the same period), and the value actually written to the hardware is 1 less than this. Here "pitch" is used as proportionate to key number, is what humans perceive, and frequency doubles (period halves) with each pitch increase of 1 octave. As such "linear period", "linear frequency", and "linear pitch" are all very different things, and linear pitch is what sounds linear to the ear.
Track Format
Tracks are formatted in a 4-level hierarchical structure - 5 if you include the individual channels:
1. Track table
2. Block header offset table
3. Block header blocks
4. Music blocks
5. Channel data
At the highest level is the track table. Each track entry consists of 3 values (though in fact it's actually 3 parallel arrays of values): first block index, last block index, and loop block index, which define which blocks belong to the track and how to loop at the end of the track. However, as block headers (to be described shortly) are ALSO packed into 256-byte blocks, there are in fact 2 track tables needed to hold all the tracks for the game, which are here referred to as bank 1 (or the "low" bank) and bank 2 (the "high" bank); note that this use of "bank" is distinct from the ROM bank, and the 2 meanings generally do not coincide.
The track block indices index into the second level of structure: the block header offset table. This table is an array of bytes which specify the location of each block header within the block of block headers (*cough*); it is because these are byte-sized offsets within the block that there can only be so many block headers in said block, requiring 2 different track tables and likewise 2 different block offset tables. This table also doubles as the playlist of blocks: a track begins at the specified first block and proceeds sequentially through this table until it finishes playing the specified last block, at which point the track either ends or loops back to the specified loop block.
The first 8 entries in the bank 1 block offset table are fanfares, though #8 is in fact an empty track used to stop music playback. Fanfares are short, non-looping, single-block tracks that interrupt side-scrolling background music to play in events such as death or level completion and the prior track is usually resumed afterwards (though the restart mechanism only supports bank 2 tracks and bank 1 tracks 9 and $a). Fanfares 1-8 are mapped directly to block offset entries 1-8 in bank 1, and have no separate track table. Fanfare 7 is the "time is running out" fanfare, and is hard-coded in the engine to increase the tempo of the track it resumes to by 1 level (see the list of tempos) until the end of that track.
The third layer of structure, then, are the block headers. These headers specify 3 key pieces of information: the address of the block, the tempo of the block (R&D4 engines have no explicit commands to set the tempo, only the value in the block header), and the starting locations of the square 1, triangle, noise, and DMC channel data within the block; square 2 is the master channel and is always located at the very beginning of the block.
This leaves a small window for shenanigans. It might occasionally be useful to share data from specific channels between blocks; this is done in 1 track from SMB3, for instance. This is possible in a very limited way: it is possible for 2 block headers to refer to the same block data by address, but provide different tempo or channel data offsets. This requires careful layout of data as all data used by a block header must be in a 256-byte window (we'll call it a virtual block). This is especially tricky since the block address also specifies the square 2 data location, requiring the square 2 data to always precede the data for the other channels for all virtual blocks and the offsets to the other channels to be relative to the start of the square 2 channel.
However, the reason the square 2 channel is called the master channel goes beyond its location within the block: the square 2 channel is the only channel whose block data is explicitly terminated and thus determines the duration of the block as a whole; when the end of the square 2 channel data for a block is reached, all channels advance to the next block (if any) together. The effect of shorter durations between channels varies by channel. The square 1 and triangle channels MUST be the same duration as the square 2 channel. But for the noise and DMC channels, given how common it is to compose tracks with short, repetitive drum loops underneath more lengthy melodies, the noise and DMC channel data will be looped infinitely until the end of the square 2 block data is reached.
To summarize, a virtual block:
- Is defined by a block header
- Has a single specified tempo
- Defines the locations of each channel's data within the virtual block
- May be of any length of time, but...
- May be at most 256 bytes for all channel data combined and begins with the square 2 data
- Will repeat its noise and DMC channel data if said data is shorter than the square 2 data, allowing short drum loops to be used under longer melodies
- May overlap with other virtual blocks if you're evil
- Is a true "block" if it does not overlap any other blocks
The following additional constraints also exist to make romhacking harder:
- 2 banks of tracks
- 15 tracks in bank 1, 12 tracks in bank 2 (though track 12 is unused)
- First 8 entries in the block header offset table for bank 1 are fanfares
- Bank 1 has space for $2c entries in its block header offset table (i.e. the playlist size) and $24 block headers (though 2 headers partially overlap), bank 2 has space for $2d entries in its block header offset table and $25 block headers.
- Theoretical maximum of $ff block header offset entries and $25 block headers per bank if structures are relocated
All music code and data is stored in ROM banks $1c/$1d at $a000-dfff and bank $1f at $e000-$ffff. To convert addresses to file offsets:
For addresses $a000-$dfff: file offset = addr + $2e010
For addresses $e000-$ffff: file offset = addr + $30010
IMPORTANT NOTE: The SMB3 engine is very unusual in that it uses 1-based indices for its arrays such as the track list, and it is documented likewise here. This means all array addresses given, unless noted otherwise, are actually 1 element BEFORE the first element in the list, and numbers such as track numbers begin with 1.
Block Header Structure:
+0 byte: tttt 0000: Tempo index t. Tempos (in BPM): 0: 112.5, 1: 120, 2: 128.6, 3: 150, 4: 180, 5: 200, 6: 225, 7: 257.1, 8: 300, 9: 450
+1 word: Block start address: square 2 channel address
+3 byte: Triangle block offset or 0 if none
+4 byte: Square 1 block offset
+5 byte: Noise block offset or 0 if none
+6 byte: DMC block offset or 0 if none
Example block header: 30 B1 AB 26 11 00 38
30:
t = 3: Tempo 3 (150 BPM)
B1 AB: Block (and square 2 channel data) start address $abb1
26: Triangle data block offset $26
11: Square 1 data block offset $11
00: No noise channel data for this block
38: DMC channel data offset $38
Bank 1:
1C:a73f byte[$2c]: Block header offset table
1C:a76c structs ($101 bytes): Block headers block. Note that this is NOT an array, and block headers are not necessarily aligned.
1C:a86c byte[$f]: 0-based first track block index
1C:a87b byte[$f]: 0-based last track block index
1C:a88a byte[$f]: 0-based loop track block index, or 0 if no loop
Bank 2:
1C:b3ff byte[$2d]: Block header offset table
1C:b42d structs ($103 bytes): Block headers block. Same caveats.
1C:b52f byte[$c]: 0-based first track block index
1C:b53b byte[$c]: 0-based last track block index
1C:b547 byte[$c]: 0-based loop track block index, or 0 if no loop
NOTE: The track block indices given in the above arrays are 0-based, while the block header offset tables (as well as the track block index tables themselves) are accessed with 1-based indices. E.g. for bank 1's first track, 1C:b530 (index 1 of the first track block index table) = 8; this block's header offset can then be found at 1C:a748 (index 9 of the block header offset table). This means it is impossible for a track to loop to block 1, as that would be a loop block index of 0, which means no loop.
See the Additional Tables section for information on relocating these structures.
Time and Tempo
As already stated, SMB3 supports the following tempos in BPM: 0: 112.5, 1: 120, 2: 128.6, 3: 150, 4: 180, 5: 200, 6: 225, 7: 257.1, 8: 300, 9: 450.
The SMB3 engine uses a hybrid of tempo and frame counting. Note lengths are converted at note start to frames the note should play at that tempo. This produces lengths of fractional frames at some length/tempo combinations, which the engine cannot directly deal with. This is handled by the primary/secondary system, in which the relevant lengths are assigned 2 length codes, a primary and a secondary, and a complete tuplet using these codes will produce the correct number of frames the tuplet should play combined. A triplet is made of 2 primary and 1 secondary length notes. A doublet of 16ths has 1 primary and 1 secondary length note, though at tempos where the primary and secondary lengths are the same, Kondo often does not distinguish between the 2. At some tempos this can be exploited for a very slight swing rhythm; for more information see the full note length table in Additional Tables.
Note Length Codes (pairs are primary/secondary):
Whole Half 4th 8th 16th
Normal: c a 8 4 0/1
Dotted: b 9 5
Triplet: 6/7 2/3
Triangle channel notes may auto-release (be silenced) prior to the beginning of the next event. When a note begins, after the length of the note in frames is calculated, the triangle's linear counter is set based on the note length as follows:
Note duration is 1-9 frames: linear counter set to $18 quarter-frames (~6 frames)
$a-$12: $20 (~8 frames)
$13-$24: $50 (~$14 frames)
$25+: $ff (no auto-release)
See the Additional Tables section for information on changing these lengths.
Notes and Keys
SMB3 uses 3 different key sets: 1 for the melodic channels, 1 for the noise channel, and 1 for the DMC channel. The melodic channels all use the same key set save that the triangle channel is 1 octave lower than the square channels for the same key code.
The melodic key table, giving octave numbers for the square channels:
Oct C C# D D# E F F# G G# A A# B Max Detune at Bx
1: 7d* 7e* 7f* 0.96 cents
2: 0* 1 2 3 4 5 6 7 8 9 a b 1.91 cents
3: c d e f 10 11 12 13 14 15 16 17 3.83 cents
4: 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 7.66 cents
5: 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 15.4 cents
6: 30 31 32 33 34 35 36 37 38 39 3a 3b 30.8 cents
7: 3c 3d 3e 36.7 cents at D7
Notes:
- C2 is 65.41 Hz
- Detune figures are for the actual octaves listed. As such for the triangle channel the appropriate detune value is in the row above the corresponding row of key values, e.g. the detune value for $17 (B2) on triangle would actually be 1.91 cents.
- Keys with * are an exploit that requires that the note event either IMMEDIATELY follow an attributes command or be the target key of a portamento. Additionally, key 0 is ONLY possible on square 2 channel.
The noise channel has 3 presets. It is not readily apparent what they are supposed to be, so only their basic characteristics will be given. Note that pitch is the value written to the NES' registers, and that number of frames refers to the maximum length of the sound and it will be cut short if the note duration is shorter:
# Vol Pitch # Frames
1 $e 3 2
2 $f $a 2
3 $f 2 $a
The preset list for the DMC channel is as follows:
1: Bass/kick drum
2: Snare drum short
3: Snare rim
4: Snare drum long (appears to be buggy and can play garbage data on longer notes)
5: Wood block
6: Bongo high
7: Bongo mid
8: Timbales high
9: Timbales low
a: Synth pad high
b: Synth pad low
c: Bongo low
d: Clap
e: Timpani high
f; Timpani mid
10: Timpani low
Channel Data Format
Compared to other engines, and even compared to the track structure, channel data is extremely simple. The format differs slightly between channels, but the basic 3 commands are the same: play note, rest, and set note attributes, which sets the length for subsequent notes/rests and for the square channels the timbre. The square channels additionally have the ability to perform portamento between 2 notes, but this has limitations.
Square Channel Data Format:
00: Channel-specific:
Square 2: End of block
Square 1: Set ctrl 2 to $94 for the rest of the block. This is used in fanfare 1 (death).
7e: Rest for the current note duration. Sets the envelope to sustain: the envelope position is set to its last entry - which is silence for most envelopes - which is continued until the next note command.
ff 0KKK KKK0: Portamento target:
IMMEDIATELY following a note: Modifies the previous note (only a single note duration occurs for the whole thing) to play linear period portamento from previous key k to K (K > k). The pitch rises (period decreases) at a rate of 3/4 period units per frame. Portamento will NOT work properly (if at all) if the target key is lower than the base key or if the portamento crosses a $100-period boundary above B1, below D2, ~F2, below A2, below D3, below A3, or below A4.
After anything else: Does nothing and should not be used
1ttt LLLL: Note attributes. Sets timbre number to t (0-7) and note length code to L for subsequent notes. MUST NOT be immediately followed by another attributes command.
0kkk kkk0: Play key k for the current note duration
Triangle Channel Data Format:
00: Pseudo-rest for the current note duration. Silences channel after 1/4 frame. Probably a bug rather than a feature.
7e: Rest for the current note duration. Silences channel.
8L (1--- LLLL): Set note length code to L for subsequent notes, subject to auto-release. MUST NOT be immediately followed by another length command.
0kkk kkk0: Play key k for the current note duration
Noise Channel Data Format:
00: Loop. Restart noise events for this block.
01: Rest for the current note duration. Silences channel. This actually plays noise preset 0, which sets the noise channel volume to 0.
8L (1--- LLLL): Set note length code to L for subsequent notes. MUST NOT be immediately followed by another length command.
0000 0kk-: Play noise preset k (1-3) for the current note duration.
DMC Channel Data Format:
00: Loop. Restart DMC events for this block.
7e: Rest for the current note duration. Silences channel.
8L (1--- LLLL): Set note length code to L for subsequent notes. MUST NOT be immediately followed by another length command.
000k kkkk: Note. Play DMC sound k (1-$10) for the current note duration.
Examples
Square 2 Channel (the tempo for this block is 3: 150 BPM):
94 (1001 0100): Set attributes
t = 1: Timbre 1
L = 4: 8th note. 12 frames at this tempo resulting in the short envelope (explained in the Timbre section).
54: Note
k = $2a: Key F#5
5C FF 5E: Portamento
k = $2e: Initial key A#5
K = $2f: Final key B5
00: End of block
Square 1 Channel (the tempo for this block is 0: 112.5 BPM):
90 (1001 0000): Set attributes
t = 1: Timbre 1
L = 0: 16th note primary, 8 frames at this tempo (at this tempo 16th primary and secondary are the same length). Short envelope will be used.
60: Note
k = $30: C6
62: Note
k = $31: C#6
94 (1001 0100): Set attributes
t = 1: Timbre 1
L = 4: 8th note, 16 frames at this tempo. Short envelope will be used.
7e: Rest
98 (1001 1000): Set attributes
t = 1: Timbre 1
L = 8: Quarter note, 32 frames at this tempo. Long envelope will be used.
Triangle Channel (the tempo for this block is 3: 150 BPM:
88: Set length
L = 8: Quarter note, 24 frames at this tempo. Linear counter will be set to $50: ~20 frames until auto-release.
26: Note
k = $13: Key G2 (triangle is 1 octave lower)
8C: Set length
L = $c: Whole note, 96 frames at this tempo. Linear counter will be set to $ff: no auto-release.
3C: Note
k = $1e: Key F#3
9B: Not actually part of this channel because the square 2 channel data ends the block at the end of the previous note.
Noise Channel (the tempo for this block is 4: 180 BPM):
94: Set length
L = 4: 8th note, 10 frames at this tempo
02 x 2: Notes
k = 1: Noise preset 1
06: Note
k = 3: Noise preset 3
02: Note
k = 1: Noise preset 1
00: Loop. The full block is in fact 320 frames, so this 40-frame loop will play 8 times.
DMC Channel (the tempo for this block is 0: 112.5 BPM):
98: Set length
L = 8: Quarter note, 32 frames at this tempo
05: Note
k = 5: Wood block
00: Loop. The full block is 256 frames, so this 32-frame loop will play 8 times.
As can be seen, square 1 and triangle channels are never explicitly terminated, while noise and DMC channels need only be explicitly terminated when they loop before square 2 data ends.
Square Wave Timbres
Square wave timbres in SMB3 consist of a simple non-looping envelope of ctrl 1 ($4000, $4004) values including both duty cycle and volume; each value in the envelope table is played for 1 frame, and the final value is sustained indefinitely (it is also used when a rest is encountered). There are long and short variants for each timbre: a short $17-entry envelope for notes shorter than $13 frames and a long $40-entry envelope for longer notes; which length is used is selected when each note begins and the length in frames is calculated. Notably, SMB3 envelope values are stored in reverse order, where entry 0 is the last entry. Interestingly, unlike most such envelopes in other engines, some SMB3 timbres actually vary their duty cycles during their early decay phase.
Each byte value in the envelope has the format ddLV vvvv:
d: Duty cycle. 0: 12.5%, 1: 25%, 2: 50%, 3: 75%
L: Disable length counter and play note forever. Oddly, this is never set in SMB3, giving all notes a maximum duration of 127 frames. For SMB3 this generally has minimal impact, as only whole notes at the slowest tempo exceed this (128 frames), but this effect can be seen when a sustaining envelope note is followed by 1 or more rests.
V: Specifies that v is the volume and not decay rate. Always set.
v: The volume
Example
Short timbre 0 envelope:
90 92 94 95 95 95 95 95 95 95 95 95 95 95 95 95 95 96 96 15 17 58 1A
1A (0001 1010):
d = 0: Duty cycle of 12.5%
v = $a: Volume of 10
58 (0101 1000):
d = 1: Duty cycle of 25%
v = 8: Volume of 8
17 (0001 0111):
d = 0: Duty cycle of 12.5%
v = 7: Volume of 7
...
90 (1001 0000):
d = 2: Duty cycle of 50%
v = 0: Silence, making this a non-sustaining envelope
ADDITIONAL TABLES
Master Note Length Table
TDiv BPM 0 1 2 3 4 5 6 7 8 9 $a $b $c $d $e $f
16P 16S 8TP 8TS 8 8D 4TP 4TS 4 4D 2 2D 1
0 (16): 112.5: 8 8 b a 10 18 15 16 20 30 40 60 80 1 1f 0
1 (15): 120: 7 8 a a f 16 14 14 1e 2d 3c 5a 78 5 0 0
2 (14): 128.6: 7 7 9 a e 15 13 12 1c 2a 38 54 70 1 4 0
3 (12): 150: 6 6 8 8 c 12 10 10 18 24 30 48 60 4 2 16
4 (10): 180: 5 5 7 6 a f d e 14 1e 28 3c 50 3 1 13
5 (9): 200: 4 5 6 6 9 d c c 12 1b 24 36 48 1e 3 0
6 (8): 225: 4 4 5 6 8 c b a 10 18 20 30 40 0 0 0
7 (7): 257.1: 3 4 5 4 7 a 9 a e 15 1c 2a 38 b 0 0
8 (6): 300: 3 3 4 4 6 9 8 8 c 12 18 24 30 2 0 0
9 (4): 450: 2 2 3 2 4 6 5 6 8 c 10 18 20 ff ff ff
Legend:
TDiv: Tempo divider. BPM = 1800/TDiv.
1, 2, 4, etc.: Whole, half, quarter, etc. notes
D: Dotted
T: Triplet
P: Primary (2 in a triplet)
S: Secondary (1 in a triplet)
Only entries 0-$c of each tempo are standardized while $d-$f are odd values, most of which aren't used and whose meaning, when any, varies by tempo. The following are the meanings of those that could be identified:
TDiv BPM $d $e $f
0 (16): 112.5: 128 ?
1 (15): 120: 16T*
2 (14): 128.6: ? ?
3 (12): 150: 16T* 32T* ?
4 (10): 180: ? ? ?
5 (9): 200: 5*8T* 16T
6 (8): 225:
7 (7): 257.1: ?
8 (6): 300: 16T
9 (4): 450: ? ? ?
* indicates that these tempo/length combinations are actually used in game. Length $d for tempo 5 is only ever used on the DMC channel, and occurs in pairs with length 2 (8T) to form a combined half-note.
Code to read the note length from the table (bank $1f):
E345 LDA $E874,Y
Code to assign the triangle linear counter value based on the note length in frames:
E696 CMP #$0A
E698 BCC $E6A6
E69A CMP #$13
E69C BCC $E6AA
E69E CMP #$25
E6A0 BCS $E6AE
E6A2 LDA #$50
E6A4 BNE $E6B4
E6A6 LDA #$18
E6A8 BNE $E6B4
E6AA LDA #$20
E6AC BNE $E6B4
E6AE LDA #$FF
E6B0 BNE $E6B4
E6B2 LDA #$80
E6B4 STA TrgLinear_4008
Square Channel Timbre Envelopes
Each timbre has long and short variants. The short variant is used for notes shorter than $13 frames, and the long variant is used for longer notes. In most cases the long variant just has slower decay than the short variant, but timbres 2 and 3 have significant differences in their volume envelopes.
1f:e765 word[8]: Long envelope address table
1f:e775 word[8]: Short envelope address table
To make it easier to read, the duty cycle envelope is separated from the volume envelope. Also, to make the envelopes more intuitive the order of entries is REVERSED to make time go from left to right; in the actual game, entry 0 in an envelope is the LAST entry.
Short Timbre Envelopes:
Timbre 0 @b1d6 (391e6):
Duty cycle: 01002222222222222222222
Volume: a8756655555555555555420
Timbre 1 @b22d (3923d):
Duty cycle: 01111111111111111111111
Volume: a9765432211100000000000
Timbre 2 @b284 (39294):
Duty cycle: 22222222222222222222222
Volume: 89aa9875311100000000000
Timbre 3 @b2dc (392ec):
Duty cycle: 22222222222222222222222
Volume: 88877000000000000000000
Timbre 4 @b2f3 (39303):
Duty cycle: 11111111111111111111111
Volume: 33455666777765443332211
Timbre 5 @b34a (3935a):
Duty cycle: 11111111111111111111111
Volume: a9876543211000000000000
Timbre 6 @b22d (3923d):
Duty cycle: 01111111111111111111111
Volume: a9765432211100000000000
Timbre 7 @b3e1 (393f1):
Duty cycle: 23011111111111111111111
Volume: ba987654321111111111110
Long Timbre Envelopes:
Timbre 0 @b196 (391a6):
Duty cycle: 0100222222222222222222222222222222222222222222222222222222222222
Volume: a875665555555555555555555555555555555555555555555555555555555420
Timbre 1 @b1ed (391fd):
Duty cycle: 0111111111111111111111111111111111111111111111111111111111111111
Volume: a987665544333222111111000000000000000000000000000000000000000000
Timbre 2 @b244 (39254):
Duty cycle: 2222222222222222222222222222222222222222222222222222222222222222
Volume: 789aa99988888888888888888888888888888777777766655554444332221110
Timbre 3 @b29c (392ac):
Duty cycle: 2222222222222222222222222222222222222222222222222222222222222222
Volume: 8887776666666666666666666666666666666666666666666666666666555554
Timbre 4 @b30a (3931a):
Duty cycle: 1111111111111111111111111111111111111111111111111111111111111111
Volume: 3345566677777777776666555555555544444433333222222222222222111111
Timbre 5 @b361 (39371):
Duty cycle: 1111111111111111111111111111111111111111111111111111111111111111
Volume: a987665544332221766554433322211054433322221111003222111111111000
Timbre 6 @b1ed (391fd):
Duty cycle: 0111111111111111111111111111111111111111111111111111111111111111
Volume: a987665544333222111111000000000000000000000000000000000000000000
Timbre 7 @b3a1 (393b1):
Duty cycle: 2301111111111111111111111111111111111111111111111111111111111111
Volume: ba98765432111111111111111111111111111111111111110000000000000000
Code to set the initial index in an envelope (i.e. the envelope length):
E756 CMP #$13
E758 BCC $E75E
E75A LDA #$3F
E75C BNE $E760
E75E LDA #$16
Code to read an envelope address:
E78E CMP #$13
E790 BCC $E79E
E792 LDA $E765,X
E795 STA $71
E797 LDA $E766,X
E79A STA $72
E79C BNE $E7A8
E79E LDA $E775,X
E7A1 STA $71
E7A3 LDA $E776,X
E7A6 STA $72
Track, Fanfare, and Block Tables
To briefly explain the format of the tables:
Bank 1 @ 1c:a76c (3877c) a73f (3874f) a86c (3887c) a87b (3888b) a88a (3889a):
- Block header block address: $a76c in bank $1c (file offset $3877c)
- Block offset table address: $a73f
- Track first block table address: $a86c
- Track last block table address: $a87b
- Track loop block table address: $a88a
Block 1 (1) @+8d: 3 abb1 (38bc1) +26 +11 +0 +38
- Block header offset in the block header block: $8d
- Tempo index: 3 (150 BPM) (the actual value of this byte is $30)
- Block base address: $abb1 (this is also the address of the square 2 channel data)
- Triangle channel data offset: $26
- Square 1 channel data offset: $11
- Noise channel data offset: 0 (no noise channel for this block)
- DMC channel data offset: $38
Note: Duplicate (repeated) block headers within the same track are abbreviated to make it more obvious that they are duplicates.
Bank 1 @ 1c:a76c (3877c) a73f (3874f) a86c (3887c) a87b (3888b) a88a (3889a):
Fanfare 1: Death
Block 1 (1) @+8d: 3 abb1 (38bc1) +26 +11 +0 +38
Fanfare 2: Game Over
Block 2 (2) @+a6: 3 ab35 (38b45) +20 +12 +0 +0
Fanfare 3: Recovered Scepter
Block 3 (3) @+94: 3 aae7 (38af7) +21 +11 +0 +31
Fanfare 4: Rescued Kings
Block 4 (4) @+ad: 4 abff (38c0f) +4d +27 +0 +73
Fanfare 5: Bowser's Fall
Block 5 (5) @+fa: 3 a8d0 (388e0) +6f +4c +0 +ba
Fanfare 6: Stage Clear
Block 6 (6) @+9b: 3 a9f7 (38a07) +1f +10 +2e +3c
Fanfare 7: Hurry Up
Block 7 (7) @+86: 8 ab65 (38b75) +35 +18 +0 +0
Fanfare 8: Silence
Block 8 (8) @+a2: 6 a8ad (388bd) +0 +30 +35 +ab
Track 1 (1): Grass Land (World 1)
Block 9 (9) @+3f: 5 af3b (38f4b) +7f +31 +b5 +ce (loop point)
Block 10 (a) @+54: 5 b024 (39034) +40 +1c +5b +84
Track 2 (2): Desert Land (WOrld 2)
Block 11 (b) @+31: 0 ad02 (38d12) +1b +e +2f +33 (loop point)
Track 3 (3): Water Land (WOrld 3)
Block 12 (c) @+46: 3 adce (38dde) +40 +37 +60 +72 (loop point)
Block 13 (d) @+4d: 3 ae54 (38e64) +40 +37 +60 +85
Track 4 (4): Giant Land (World 4)
Block 14 (e) @+23: 3 ac99 (38ca9) +20 +a +61 +65 (loop point)
Track 5 (5): Sky Land Ground (World 5)
Block 15 (f) @+38: 3 adc0 (38dd0) +0 +0 +0 +7
Block 16 (10) @+2a: 3 ad3b (38d4b) +56 +2d +7a +81 (loop point)
Track 6 (6): Ice Land (World 6)
Block 17 (11) @+6a: 3 b0c9 (390d9) +25 +12 +2a +35 (loop point)
Track 7 (7): Pipe Land (World 7)
Block 18 (12) @+71: 1 b10a (3911a) +56 +17 +64 +7d (loop point)
Block 19 (13) @+78: 1 b137 (39147) +29 +15 +37 +50
Track 8 (8): Dark Land (World 8)
Block 20 (14) @+62: 0 af15 (38f25) +13 +a +0 +1c (loop point)
Track 9 (9): Sky Land Sky (World 5)
Block 21 (15) @+1c: 0 aa3f (38a4f) +2e +19 +0 +0 (loop point)
Track 10 (a): Star Power
Block 22 (16) @+7f: 8 aa8e (38a9e) +37 +1a +49 +4f (loop point)
Track 11 (b): Warp Zone
Block 23 (17) @+15: 0 a990 (389a0) +0 +b +0 +0
Block 24 (18) @+1c: 0 aa3f (38a4f) +2e +19 +0 +0 (loop point)
Track 12 (c): Music Box
Block 25 (19) @ +0: 0 a9a7 (389b7) +0 +13 +0 +0 (loop point)
Block 26 (1a) @ +7: 0 a9c6 (389d6) +0 +f +0 +0
Block 27 (1b) @ +0
Block 28 (1c) @ +e: 0 a9e2 (389f2) +0 +a +0 +0
Track 13 (d): Cursed Kings
Block 29 (1d) @+b4: 3 a89a (388aa) +29 +14 +0 +0 (loop point)
Track 14 (e): Spade House
Block 30 (1e) @+5b: 5 aefe (38f0e) +7 +4 +10 +0 (loop point)
Track 15 (f): Ending
Block 31 (1f) @+bb: 0 c27a (3a28a) +0 +1b +0 +0
Block 32 (20) @+bb
Block 33 (21) @+c2: 0 c2a6 (3a2b6) +0 +21 +0 +0
Block 34 (22) @+bb
Block 35 (23) @+c9: 3 c2d8 (3a2e8) +23 +12 +33 +40
Block 36 (24) @+d0: 3 c333 (3a343) +45 +23 +65 +72 (loop point)
Block 37 (25) @+d0
Block 38 (26) @+d7: 3 c3b2 (3a3c2) +1f +10 +32 +3f
Block 39 (27) @+d7
Block 40 (28) @+de: 3 c3fe (3a40e) +39 +1d +5e +6b
Block 41 (29) @+e5: 3 c476 (3a486) +6d +24 +a4 +b1
Block 42 (2a) @+ec: 3 c534 (3a544) +24 +c +37 +44
Block 43 (2b) @+e5
Block 44 (2c) @+f3: 3 c585 (3a595) +23 +f +3d +4a
Bank 2 @ 1c:b42d (3943d) b3ff (3940f) b52f (3953f) b53b (3954b) b547 (39557):
Track 1 (1): Overworld Theme 1
Block 1 (1) @+69: 3 b554 (39564) +29 +18 +41 +45
Block 2 (2) @+70: 3 b5a9 (395b9) +54 +2c +af +be (loop point)
Block 3 (3) @+77: 3 b5c3 (395d3) +50 +2b +95 +a4
Block 4 (4) @+70
Block 5 (5) @+7e: 3 b629 (39639) +21 +12 +2f +48
Block 6 (6) @+85: 3 b68a (3969a) +69 +35 +7a +89
Block 7 (7) @+8c: 3 b71d (3972d) +5f +30 +72 +81
Track 2 (2): Underworld Theme
Block 8 (8) @+bd: 5 c073 (3a083) +4b +0 +ae +95 (loop point)
Track 3 (3): Underwater Theme
Block 9 (9) @+54: 0 bbe7 (39bf7) +19 +d +0 +0
Block 10 (a) @+5b: 0 bc07 (39c17) +37 +1c +b2 +b8 (loop point)
Block 11 (b) @+5b
Block 12 (c) @+62: 0 bc5f (39c6f) +39 +1d +5a +60
Track 4 (4): Fortress Theme
Block 13 (d) @+38: 0 c218 (3a228) +1f +10 +0 +2e (loop point)
Block 14 (e) @+38
Block 15 (f) @+3f: 0 c251 (3a261) +15 +a +0 +1e
Track 5 (5): Koopa Kids
Block 16 (10) @+c4: 4 bcc5 (39cd5) +31 +19 +3c +59
Block 17 (11) @+cb: 4 bd3f (39d4f) +45 +23 +5c +62 (loop point)
Block 18 (12) @+cb
Block 19 (13) @+d2: 4 bda7 (39db7) +45 +23 +64 +6a
Track 6 (6): Airship Theme
Block 20 (14) @+46: 0 c124 (3a134) +19 +d +0 +29 (loop point)
Block 21 (15) @+4d: 0 c167 (3a177) +51 +29 +7d +88
Track 7 (7): Hammer Bros.
Block 22 (16) @+a1: 3 b87a (3988a) +d +7 +0 +13
Block 23 (17) @+a8: 3 b8a5 (398b5) +2b +0 +3c +42
Block 24 (18) @+a8
Block 25 (19) @+af: 3 b8a8 (398b8) +28 +16 +39 +3f (loop point)
Block 26 (1a) @+af
Block 27 (1b) @+b6: 3 b8ed (398fd) +43 +22 +64 +85
Track 8 (8): Toad's House
Block 28 (1c) @+93: 0 c000 (3a010) +27 +14 +0 +70 (loop point)
Block 29 (1d) @+93
Block 30 (1e) @+9a: 0 c038 (3a048) +27 +14 +0 +38
Track 9 (9): Overworld Theme 2
Block 31 (1f) @ +0: 3 b999 (399a9) +21 +11 +0 +0
Block 32 (20) @ +7: 3 b9c1 (399d1) +32 +15 +73 +83 (loop point)
Block 33 (21) @ +e: 3 ba02 (39a12) +23 +12 +32 +42
Block 34 (22) @+15: 3 b9c1 (399d1) +32 +29 +73 +83
Block 35 (23) @+1c: 3 ba53 (39a63) +52 +29 +7b +8b
Block 36 (24) @+23: 3 bb04 (39b14) +26 +15 +68 +6e
Block 37 (25) @+2a: 3 bb3a (39b4a) +23 +13 +32 +38
Block 38 (26) @+23
Block 39 (27) @+31: 3 bb79 (39b89) +36 +1c +46 +59
Track 10 (a): Toad's House
Block 28 (1c) @+93: 0 c000 (3a010) +27 +14 +0 +70 (loop point)
Block 29 (1d) @+93
Block 30 (1e) @+9a: 0 c038 (3a048) +27 +14 +0 +38
Track 11 (b): Bowser Battle
Block 40 (28) @+d9: 7 b7c3 (397d3) +1b +e +28 +0
Block 41 (29) @+e0: 7 b7f8 (39808) +43 +22 +6e +78 (loop point)
Block 42 (2a) @+e7: 7 b7f8 (39808) +48 +22 +6e +78
Block 43 (2b) @+ee: 7 b7f8 (39808) +53 +22 +6e +78
Block 44 (2c) @+f5: 7 b7f8 (39808) +65 +22 +6e +78
Track 12 (c): Unused
Block 45 (2d) @+fc: 4 bcc5 (39cd5) +31 +19 +0 +0 (loop point)
Bank 1 Track Structures
Code to load the block indices for a track (bank $1f):
E417 LDA $A86C,Y
E41A STA $7AE0
E41D LDA $A87B,Y
E420 CLC
E421 ADC #$02
E423 STA $7AE1
E426 LDA $A88A,Y
E429 STA $7AE2
Code to load the block header offset and then load the parameters from the header:
E45A LDA $A73F,Y
E45D TAY
E45E LDA $A76C,Y
E461 STA $04FD
E464 LDA $A76D,Y
E467 STA $6B
E469 LDA $A76E,Y
E46C STA $6C
E46E LDA $A76F,Y
E471 STA $04D0
E474 LDA $A770,Y
E477 STA $04FF
E47A LDA $A771,Y
E47D STA $04D1
E480 STA $07F3
E483 LDA $A772,Y
E486 STA $04D2
E489 STA $04DE
Bank 2 Track Structures
Code to load the block indices for a track:
E388 LDA $B52F,Y
E38B STA $7AE0
E38E LDA $B53B,Y
E391 CLC
E392 ADC #$02
E394 STA $7AE1
E397 LDA $B547,Y
E39A STA $7AE2
Code to load the block header offset and then load the parameters from the header:
E3B6 LDA $B3FF,Y
E3B9 TAY
E3BA LDA $B42D,Y
E3BD STA $04FD
E3C0 LDA $B42E,Y
E3C3 STA $6B
E3C5 LDA $B42F,Y
E3C8 STA $6C
E3CA LDA $B430,Y
E3CD STA $04D0
E3D0 LDA $B431,Y
E3D3 STA $04FF
E3D6 LDA $B432,Y
E3D9 STA $04D1
E3DC STA $07F3
E3DF LDA $B433,Y
E3E2 STA $04D2
E3E5 STA $04DE
Revisions
v1.1:
- As it turns out, the way SMB3 mixes 0-based and 1-based indexing is so confusing I got confused writing the spec. This revision fixes that error and attempts to clarify the subject so as to prevent any further mishaps.
- Add table of noise preset characteristics
- Unhid the unused track that was previously hidden because it's junk
- Various other small changes meant to increase clarity