DPCM samples
Playing recorded sound on the NES through its delta modulation channel, a 1-bit delta stream read from cartridge ROM.
On this page
The delta modulation channel (DMC) plays 1-bit delta-encoded samples from cartridge ROM at one of 16 rates1. A sample starts at and runs bytes, so a game stores each one as an address byte, a length byte, and a rate1.
- Sound effectsThe Legend of Zelda (1986). 7 samples for boss roars, a boss hit, and a hurt sound.2,3
- Music trackSuper Mario Bros. 3 (1988). Samples play as a track in the music.4,5
#Parameters
Both games store a rate byte per sample, and both use only rates $0F, $0E, $0D5, the three fastest of the 162,1. Super Mario Bros. 3 reuses recordings at slower rates or shorter lengths to get more sounds from 9 recordings5. Zelda’s two roars play at different rates, the Aquamentus roar at $0E and the Dodongo roar at $0F3,2.
#Quirks
- Super Mario Bros. plays no samples, but during its overworld and underwater songs it raises the DMC’s output level by writing
$4011directly6.
Games
| Game | Year | How | Note |
|---|---|---|---|
| The Legend of Zelda | 1986 | Sound effects | 7 samples for boss roars, a boss hit, and a hurt sound |
| Super Mario Bros. 3 | 1988 | Music track | samples play as a track in the music |
Every claim about this mechanic, by game (6)
References
- ^ abcThe delta modulation channel (DMC) plays 1-bit delta-encoded samples from , bytes long, at one of 16 rates; a program can also load its 7-bit output level directly through
$4011.WikiNESdev Wiki, “APU DMC”How we know
The NES APU's delta modulation channel (DMC) can output 1-bit delta-encoded samples or can have its 7-bit counter directly loaded, allowing flexible manual sample playback.
lead · archived copy ↗ Sample address = %11AAAAAA.AA000000 = $C000 + (A * 64) … Sample length = %LLLL.LLLL0001 = (L * 16) + 1 bytes
Overview · archived copy ↗ For example, on NTSC (1.789773 MHz), a rate of 428 gives a frequency of 1789773/428 Hz = 4181.71 Hz.
Pitch table · archived copy ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^ abcThe game keeps 7 DMC samples in three tables of address, length, and rate bytes, and a request byte picks the entry by its lowest set bit.Codealdonunez/zelda1-disassembly
How we know
554 TXA 555 LDY #$00 ⋮ 557 INY 558 LSR 559 BCC :- 560 LDA SampleRates-1, Y 561 STA DmcFreq_4010 562 LDA SampleAddrs-1, Y 563 STA DmcAddress_4012 564 LDA SampleLengths-1, Y 565 STA DmcLength_4013 ⋮ 574SampleAddrs: ⋮
src/Z_00.asm lines 553–582 at 50a1c86 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^ abThe samples are sound effects; boss code requests
$10for the Aquamentus, Gleeok, and Ganon roar (entry 4, rate$0E),$20for the Dodongo and Gohma roar (entry 5), and$02for a boss hit (entry 1), andDeleteSlotrequests$08, which the disassembly labels the "hurt" sound (entry 3).Codealdonunez/zelda1-disassemblyHow we know
4846 LDA #$10 ; Play Aquamentus/Gleeok/Ganon roar. 4847 STA SampleRequest
src/Z_04.asm lines 4846–4847 at 50a1c86 · upstream ↗ 4900 LDA #$20 ; Play Dodongo/Gohma roar. 4901 STA SampleRequest
src/Z_04.asm lines 4900–4901 at 50a1c86 · upstream ↗ 8493 LDA #$02 ; Boss hit sound effect 8494 STA SampleRequest
src/Z_04.asm lines 8493–8494 at 50a1c86 · upstream ↗ 1770DeleteSlot: 1771 LDA #$08 ; "Hurt" sound effect 1772 STA SampleRequest
src/Z_02.asm lines 1770–1772 at 50a1c86 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^The music data has a sample track beside the other channels' tracks; each note byte on it queues a sample, and
Music_PlayDMCloads that sample's rate, address, and length from three 16-entry tables and restarts the DMC.CodeSouthbird's SMB3 disassemblyHow we know
927 LDA Music_PCMTrkPos 928 BEQ PRG031_E738 ; If Music_PCMTrkPos = 0 (disabled), jump to PRG031_E738 ⋮ 936 LDA [Music_Base_L],Y ; Get next byte in music segment track
PRG/prg031.asm lines 926–936 at 09b1bd8 · upstream ↗ 950 STA DMC_Queue ; Store note into DMC queuePRG/prg031.asm line 950 at 09b1bd8 · upstream ↗ 94 LDA DMC_MODCTL_LUT-1,Y ; Subtract 1 from LUT address since $00 is disabled and $01 is first DMC sound 95 STA PAPU_MODCTL ; Update PAPU_MODCTL ⋮ 98 LDA DMC_MODADDR_LUT-1,Y ; Subtract 1 from LUT address since $00 is disabled and $01 is first DMC sound 99 STA PAPU_MODADDR ; Set PAPU_MODADDR (address of sound) ⋮ 107 LDA #$0f 108 STA PAPU_EN ; Disable DMC 109 LDA #$1f 110 STA PAPU_EN ; Enable DMC
PRG/prg031.asm lines 91–110 at 09b1bd8 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^ abcThe 16 sample entries play 9 recordings, some reused at a lower rate or cut short; their rate bytes are
$0F(33,144 Hz) for most, and$0E(24,858 Hz) or$0D(21,307 Hz) for some of the reused copies.CodeSouthbird's SMB3 disassembly · NESdev Wiki, “APU DMC”revisedHow we know
163DMC_MODCTL_LUT: 164 .byte $0F ; Sample 0 (DMC01) ⋮ 170 .byte $0E ; Sample 6 (DMC05 3/4 length) ⋮ 172 .byte $0E ; Sample 8 (DMC06 slower) ⋮ 179 .byte $0D ; Sample 15 (DMC09 even slower)
PRG/prg031.asm lines 163–179 at 09b1bd8 · upstream ↗ 113 ; The address are $C000 | (value << 6) 114MADR .func ((\1 & $3FFF) >> 6) ⋮ 117MLEN .func ((\2 - \1) >> 4)
PRG/prg031.asm lines 113–117 at 09b1bd8 · upstream ↗ For example, on NTSC (1.789773 MHz), a rate of 428 gives a frequency of 1789773/428 Hz = 4181.71 Hz.
Pitch table · archived copy ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Revised after a check by a second AI model, 2026-10-21.
- ^During the overworld and underwater songs the sound engine raises a counter by 1 a frame up to
$30and writes it to the DMC's output level at$4011; other songs count it back down to 0, and the game plays no samples.CodeXkeeper0/smb1How we know
79 LDY DAC_Counter ; load some sort of counter 80 LDA AreaMusicBuffer 81 AND #%00000011 ; check for specific music 82 BEQ NoIncDAC 83 INC DAC_Counter ; increment and check counter 84 CPY #$30 85 BCC StrWave ; if not there yet, just store it 86NoIncDAC: 87 TYA 88 BEQ StrWave ; if we are at zero, do not decrement 89 DEC DAC_Counter ; decrement counter 90StrWave: ⋮
src/music-engine.asm lines 79–91 at 1cc3c92 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
Sources
Code
- Southbird. 2025. “smb3: Super Mario Bros. 3 disassembly for NESASM (captainsouthbird/smb3).” Commit 09b1bd8. captainsouthbird/smb3 @ 09b1bd8 · licence, all uses
- Núñez, Aldo. 2021. “zelda1-disassembly: A complete disassembly of The Legend of Zelda.” Commit 50a1c86. aldonunez/zelda1-disassembly @ 50a1c86 · licence, all uses
- doppelganger and Xkeeper. 2022. “smb1: Super Mario Bros. disassembly for asm6f (Xkeeper0/smb1).” Commit 1cc3c92. Xkeeper0/smb1 @ 1cc3c92 · licence, all uses
Secondary
- NESdev Wiki contributors. n.d. “APU DMC.” NESdev Wiki. Version oldid 23783. original · archived · licence, all uses