Oct 4, 2026 · Updated Oct 11, 2026 · @Craig Taylor
The C64 had one SID. The MEGA65 has four, giving twelve voices, plus
four channels of digitised sound played by DMA. Everything passes
through a programmable cross-bar mixer before reaching the 3.5mm socket
and the digital video output. The core also contains a basic OPL2 FM
synthesiser, write-only at $FE00000-$FE000FF, feeding mixer
input $F in mono (mega65-core, slow_devices.vhdl,
audio_mixer.vhdl; mega65-core PR #879). The MEGA65 Book still
describes it as not functional (MEGA65 Book, p. V-24), and it is not
covered here.
The two working kinds of sound are very different. A SID synthesises its waveforms from a handful of register settings, so music costs almost no memory or CPU time. Digitised sound reproduces recorded audio, such as speech, real instruments or sound effects, at the cost of memory: each second of sound is thousands of bytes.
This chapter covers:
Register details in this chapter follow the MEGA65 Book, the official reference, in its June 2025 edition. Page references such as "p. P-18" refer to that edition.
BASIC 65 divides the SIDs between two jobs. PLAY uses SID 1 for voices 1-3 and SID 3 for voices 4-6; SOUND uses SID 2 for voices 1-3 and SID 4 for voices 4-6. Music and sound effects therefore never interrupt each other (MEGA65 Book, pp. B-190, B-243). Both commands return immediately and play in the background under interrupt control. The C128's PLAY, by contrast, stopped the program while it played.
| Command | Format | Purpose |
|---|---|---|
| SOUND | SOUND voice, freq, dur [, dir, min, sweep, wave, pulse] |
Sound effect on SID 2 or 4 |
| SOUND CLR | SOUND CLR |
Silence SOUND and PLAY and reset the sound system |
| PLAY | PLAY [string1, ..., string6] |
Music on SID 1 and 3 |
| TEMPO | TEMPO speed |
Music speed, 1-255 |
| ENVELOPE | ENVELOPE n [, attack, decay, sustain, release, waveform, pw] |
Redefine instrument slot 0-9 |
| FILTER | FILTER sid [, freq, lp, bp, hp, res] |
Set the filter for the right or left music SID |
| VOL | VOL right, left |
Volume 0-15 for SIDs 1-2 and SIDs 3-4 |
| RPLAY | RPLAY(voice) |
1 if music voice 1-6 is playing, otherwise 0 |
The voice is 1 to 6. The frequency is the raw 16-bit SID frequency value, 0 to 65535, not a value in hertz; the next section shows how to convert. The duration is in jiffies, 0 to 32767: 50 per second in PAL video mode and 60 in NTSC.
The optional parameters add a sweep and choose the tone. The direction is 0 up, 1 down or 2 oscillating; min is the lowest frequency of the sweep, and sweep is the step added to or taken from the frequency each jiffy, with the starting frequency as the top of the sweep (MEGA65 ROM source, SOUND). The waveform is 0 triangle, 1 sawtooth, 2 square (the default) or 3 noise, and pulse sets the square wave's width, 0 to 4095 (MEGA65 Book, p. B-243).
Because jiffies depend on the video standard, a program that wants a
sound of fixed length should check it first. Bit 7 of $D06F
is set in NTSC mode:
10 IF PEEK($D06F) AND $80 THEN J=60 : ELSE J=50
20 SOUND 1, 7382, J : REM SQUARE WAVE FOR ONE SECOND
30 SOUND 3, 4000, 120, 2, 2000, 400, 1 : REM SWEEPING SAWTOOTH
40 SLEEP 3 : REM LET THEM PLAY
50 SOUND CLR : REM SILENCE AND RESET
These lines follow the Book's own example (MEGA65 Book, p. B-243).
PLAY takes up to six strings, one per music voice. A note is a letter A to G, optionally preceded by modifiers. Directives are a letter followed by a digit, and stay in force until changed (MEGA65 Book, pp. B-190, B-191).
| Modifier | Effect |
|---|---|
# |
Sharp |
$ |
Flat |
. |
Dotted; it goes before the note, unlike sheet music |
W H Q I
S |
Whole, half, quarter, eighth or sixteenth note |
R |
Rest |
| Directive | Meaning | Range |
|---|---|---|
O |
Octave; 4 is the default, middle octave | 0-6 |
T |
Instrument envelope | 0-9 |
U |
Volume | 0-9 |
X |
Filter off or on | 0-1 |
M |
Modulation: vibrato depth, 0 off | 0-9 |
P |
Portamento: slide speed between notes, 0 off | 0-9 |
L |
Loop back to the start of the string | none |
The Book says that while portamento is on, notes are not gated off
between each other. In current ROMs the check that would do this is
disabled, so each note still ends normally (MEGA65 ROM source, PLAY).
Turn portamento off with P0.
10 ENVELOPE 9, 10, 5, 10, 5, 0, 300
20 VOL 8, 8
30 TEMPO 30
40 PLAY "O5T9HCIDCDEHCG IGAGFEFDEWCL", "O2T0QCGEGCGEG DBGB CGEGL"
This example is from the Book (MEGA65 Book, p. B-191). Spaces in PLAY strings are ignored, so they can separate bars.
Empty arguments leave a voice playing undisturbed, so
PLAY ,"O5CDE" changes only voice 2. PLAY with no arguments
silences all voices and resets the music system, including TEMPO. A PLAY
string is an ordinary BASIC string and limited to 255 characters; longer
pieces are played in sections, using RPLAY to wait for each to
finish.
TEMPO sets the length of a whole note to 24 divided by the speed, in seconds (MEGA65 Book, p. B-262): TEMPO 24 makes a whole note last one second.
ENVELOPE redefines one of the ten instrument slots used by PLAY's
T directive. Attack, decay, sustain and release are 0 to
15; the waveform is 0 triangle, 1 sawtooth, 2 pulse, 3 noise or 4 ring
modulation; pw is the pulse width (MEGA65 Book, p. B-99). The defaults
are:
| Slot | Instrument | A | D | S | R | Wave | Pulse |
|---|---|---|---|---|---|---|---|
| 0 | Piano | 0 | 9 | 0 | 0 | 2 | 1536 |
| 1 | Accordion | 12 | 0 | 12 | 0 | 1 | |
| 2 | Calliope | 0 | 0 | 15 | 0 | 0 | |
| 3 | Drum | 0 | 5 | 5 | 0 | 3 | |
| 4 | Flute | 9 | 4 | 4 | 0 | 0 | |
| 5 | Guitar | 0 | 9 | 2 | 1 | 1 | |
| 6 | Harpsichord | 0 | 9 | 0 | 0 | 2 | 512 |
| 7 | Organ | 0 | 9 | 9 | 0 | 2 | 2048 |
| 8 | Trumpet | 8 | 9 | 4 | 1 | 2 | 512 |
| 9 | Xylophone | 0 | 9 | 0 | 0 | 0 |
FILTER sets the SID filter for music: sid is 1 for the right music
SID and 2 for the left. The cutoff is 0 to 2047, the three mode switches
are 0 or 1, and resonance is 0 to 15. Combining modes produces
band-reject and notch effects. A voice uses the filter only while its
PLAY string has X1 in effect (MEGA65 Book, p. B-109).
VOL sets the volume, 0 to 15, of the right pair of SIDs, 1 and 2, and the left pair, 3 and 4. "Right" and "left" describe the default mix; the user's mixer settings decide where each pair is actually heard (MEGA65 Book, p. B-279).
The MEGA65's SIDs are implemented in the FPGA, and each behaves as a complete SID with three voices, a filter and its own envelope generators. They occupy four consecutive 32-byte register blocks, and the Book's I/O map names them by the side of the mix they feed:
| SID | Registers | Book name | Used by BASIC for |
|---|---|---|---|
| 1 | $D400-$D41F |
Right #1 | PLAY voices 1-3 |
| 2 | $D420-$D43F |
Right #2 | SOUND voices 1-3 |
| 3 | $D440-$D45F |
Left #1 | PLAY voices 4-6 |
| 4 | $D460-$D47F |
Left #2 | SOUND voices 4-6 |
The same four SIDs appear again at $D480-$D4FF (MEGA65
Book, p. J-9). Each block's registers are laid out exactly as on the
C64, so the reference in the next section applies to all four: add
$20, $40 or $60 to reach SIDs 2,
3 and 4.
The mixer treats the SIDs as two pairs: one mixer input carries the left SIDs and another the right SIDs (MEGA65 Book, p. V-24). By default each pair is panned only slightly towards its side, so a C64 tune played on SID 1 is still heard from both speakers. A program that wants a part to come from one side chooses a SID from the appropriate pair; the user's mixer settings decide how far apart the two pairs actually sound.
Each SID can also be panned on its own. Setting SIDEXENA, bit 4 of
$D63C, turns on two extra registers in every SID: offset
$1D sets that SID's left-channel volume and
$1E its right-channel volume, 0 to 255
($D41D and $D41E for SID 1). By default SIDs
1 and 2 ($D400, $D420) are set fully right and
SIDs 3 and 4 ($D440, $D460) fully left. With
SIDEXENA clear, the two registers are hidden and each SID keeps that
default panning
(mega65-core, sid_6581.vhdl, multisid.vhdl,
c65uart.vhdl; release 0.97).
Commodore built two versions of the SID. The original 6581 and the later 8580 differ in their filters and in how combined waveforms sound, and some C64 games relied on quirks of the 6581 that the 8580 fixed (MEGA65 Book, p. 4-7, for the quirks). Music written for one can sound noticeably different on the other, because composers tuned their filter settings to the chip they had.
The MEGA65 models either. The user chooses a default with the SID
generation setting in the configuration utility, and a program can
choose for itself with SIDMODE at $D63C: 0 selects 6581
behaviour and 1 selects 8580 (MEGA65 Book, p. R-3). There is one bit
per SID in the low four bits of $D63C, in an unexpected
order: bit 0 is SID 3 ($D440), bit 1 is SID 1
($D400), bit 2 is SID 4 ($D460) and bit 3 is
SID 2 ($D420) (mega65-core, September 2026). A program that changes SIDMODE should restore it before
exiting, since it overrides the user's setting.
C64 music players are usually called once per frame from a raster
interrupt, which ties their tempo to the video standard: 50 frames a
second in PAL, 60 in NTSC. The MEGA65 keeps both video modes and their
timings, so a tune written for PAL plays 20% faster in NTSC mode. A
player that must sound the same in both should be driven by a CIA timer
whose latch value it chooses from bit 7 of $D06F, or adjust
its tempo from that bit, as the SOUND example above does for durations.
A fixed latch is not enough, because the CIA clock itself differs: about
0.985 MHz in PAL and 1.023 MHz in NTSC. Release 0.97 cores run the NTSC
CIA clock at about 0.99 MHz instead; development cores correct it
(mega65-core PR #930).
Offsets are from the base of a SID, $D400 for SID 1.
Voices 1, 2 and 3 use the same seven-register layout at offsets
$00, $07 and $0E.
| Offset (voice 1) | Contents |
|---|---|
$00-$01 |
Frequency, 16 bits, low byte first |
$02-$03 |
Pulse width, 12 bits: low byte, then bits 11-8 in the low nybble |
$04 |
Control: waveform, gate and modulation bits, below |
$05 |
Attack (bits 7-4) and decay (bits 3-0) |
$06 |
Sustain level (bits 7-4) and release (bits 3-0) |
The control register:
| Bit | Name | Effect when set |
|---|---|---|
| 7 | Noise | Noise waveform |
| 6 | Pulse | Pulse waveform, width from registers 2-3 |
| 5 | Sawtooth | Sawtooth waveform |
| 4 | Triangle | Triangle waveform |
| 3 | Test | Holds the oscillator at zero |
| 2 | Ring | Ring-modulates triangle with the previous voice's oscillator |
| 1 | Sync | Synchronises this oscillator to the previous voice's |
| 0 | Gate | 1 starts attack, decay and sustain; 0 starts release |
For voice 1 the "previous" voice is voice 3.
| Offset | Contents |
|---|---|
$15 |
Filter cutoff, bits 2-0 |
$16 |
Filter cutoff, bits 10-3 |
$17 |
Resonance (bits 7-4); route voices 1-3 and external input through the filter (bits 0-3) |
$18 |
Bit 7 mutes voice 3; bits 6-4 select high-pass, band-pass and low-pass; bits 3-0 master volume |
$19-$1A |
Paddle inputs (read) |
$1B |
Voice 3 oscillator output (read) |
$1C |
Voice 3 envelope output (read) |
The frequency value is the output frequency multiplied by 16,777,216 and divided by the SID's clock rate, roughly 1 MHz. On a PAL C64 the clock is 985,248 Hz, so concert A at 440 Hz needs a value of about 7,493. The SID's own clock is what matters here, not the CPU speed, so the 45GS02 running at 40.5 MHz does not change the pitch.
This plays a note on SID 3, voice 1, which comes from the left of the default mix:
sid3 = $d440
lda #$0f
sta sid3+$18 ; volume 15, no filter
lda #$09
sta sid3+$05 ; attack 0, decay 9
lda #$00
sta sid3+$06 ; sustain 0, release 0
lda #<7493
sta sid3+$00
lda #>7493
sta sid3+$01 ; about 440 Hz
lda #$11
sta sid3+$04 ; triangle, gate on
; ... later ...
lda #$10
sta sid3+$04 ; triangle, gate off: release
The SID registers, apart from the four read-only ones, cannot be read
back at $D400. The MEGA65 does keep a readable copy of
what was written to all four SIDs at $FF65000-$FF6507F
(mega65-core, September 2026); the Book does not document it, so a program that needs a
register's current value, for example to change one control bit, is
safest keeping its own copy in RAM.
To play a recorded sound, a computer must send its samples to a digital-to-analogue converter at an exact, steady rate: 8,000 times a second for an 8 kHz sample. The MEGA65's DMA controller has four audio channels that do this in the background, much like the Amiga's. Unlike the Amiga's, they support 8- and 16-bit samples, rates up to about 1 MHz and 256 volume levels per channel, but no modulation between channels (MEGA65 Book, p. P-3).
The DMA controller is part of the CPU, and the MEGA65 has no bus slots reserved for audio. Audio DMA instead uses idle CPU cycles, which exist only at full speed, about 40.5 MHz: then every instruction that reads a byte from memory leaves a wait state that audio DMA can use. Two consequences follow (MEGA65 Book, p. P-18):
loop: JMP loop, starves audio DMA.
Add a read, such as LDA $1234, to any idle loop.Audio DMA also keeps running during ordinary DMA jobs, stealing cycles from them so that playback is not interrupted (MEGA65 Book, p. P-3).
$D711| Bit | Name | Effect |
|---|---|---|
| 7 | AUDEN | Enable audio DMA, and feed it to the mixer in place of the direct
digital registers at $D6F8-$D6FB |
| 4 | NOMIX | Bypass the mixer on the PWM outputs: audio DMA plays at full volume on the 3.5mm socket of R3 and earlier boards. HDMI audio and the audio DAC of R4 and later boards still carry the mixer output |
The other bits should normally be left clear, so write
$80 to $D711 to enable audio DMA (MEGA65 Book,
p. P-18).
Channels 0 to 3 have 16 registers each, at $D720,
$D730, $D740 and $D750. Offsets
are the same for every channel (MEGA65 Book, pp. P-21 to P-23):
| Offset | Name | Contents |
|---|---|---|
$0 |
control | Bit 7 enable, bit 6 loop, bit 5 sign, bit 4 sine mode, bit 3 stop flag, bits 1-0 sample format |
$1-$3 |
base address | 24-bit address where a looping sample restarts |
$4-$6 |
frequency | 24-bit rate value, added to a counter every CPU cycle |
$7-$8 |
top address | Low 16 bits of the last sample's address |
$9 |
volume | 0 (mute) to $FF (full), to this channel's own side |
$A-$C |
current address | 24-bit address of the next sample; set it to start playback |
$D-$F |
timing counter | The rate counter itself |
The control bits in detail:
| Bit | Name | Meaning |
|---|---|---|
| 7 | CHxEN | 1 plays the channel; clearing it stops playback |
| 6 | CHxLOOP | At the end, continue from the base address |
| 5 | CHxSGN | Sample sign: 0 signed, 1 unsigned |
| 4 | CHxSINE | Play a built-in 32-sample 16-bit sine wave instead of memory |
| 3 | CHxSTP | Set by the hardware when a sample finishes |
| 1-0 | CHxSBITS | %11 16-bit, %10 8-bit, %01
upper nybble, %00 lower nybble |
Three details trip people up. First, playback starts from the current
address at $A-$C, not the base address; the base address is
only the loop point, and for a whole-sample loop both are set to the
start. Second, only the low 16 bits of the end are compared, so one
sample can be at most 64KB and must lie in chip RAM. Third, the current
address registers are not latched and may change while being read; stop
the channel before reading them if an exact value matters (MEGA65 Book,
pp. P-18, P-19).
Getting the sign bit wrong makes the waveform jump wherever it crosses zero, which sounds like loud crackling. 4-bit samples use one half of each byte, so two different 4-bit sounds can share the same memory, one in each nybble.
The frequency value is added to a 24-bit counter every CPU cycle, and a new sample is fetched each time the counter overflows (MEGA65 Book, p. P-19). The value for a given rate is therefore:
value = rate * 16777216 / 40500000
| Sample rate | Value |
|---|---|
| 4 kHz | $000679 |
| 8 kHz | $000CF2 |
| 11.025 kHz | $0011D7 |
| 16 kHz | $0019E4 |
| 22.05 kHz | $0023AE |
| 32 kHz | $0033C8 |
These values assume the Book's 40.5 MHz clock; some published tables use 40 MHz and differ by about 1%, which is inaudible for most purposes. At rates up to about 16 kHz with 8-bit samples, the irregular spacing of idle cycles causes no audible distortion in normal programs; at much higher rates it can (MEGA65 Book, p. P-19). Frequency and volume can both be changed while a sample plays, so one recorded note can be played at different pitches or faded in and out.
Channels 0 and 1 feed the left digital audio input of the mixer and
channels 2 and 3 the right, at the volume in their own register
$9. Four more registers let each channel also feed the
opposite side: $D71C and $D71D send channels 0
and 1 to the right, and $D71E and $D71F send
channels 2 and 3 to the left. Setting both $D729 and
$D71C to $FF plays channel 0 at full volume on
both sides (MEGA65 Book, p. P-19).
Setting bit 4 of a channel's control register plays a built-in 32-sample, 16-bit sine wave instead of fetching from memory. Because no memory is read, the result is free of the distortion idle-cycle timing can cause, and clean tones well above 60 kHz are possible. The address registers must still be set as if the table sat in the bottom 64 bytes of memory (MEGA65 Book, pp. P-19, P-20).
When a non-looping sample ends, the hardware sets the channel's stop
flag, bit 3. The Book's text states that audio DMA cannot presently
generate interrupts, although its register table lists interrupt flag
and enable bits at $D713 and offset registers at
$D714-$D717 (MEGA65 Book, pp. P-20, P-21). Development
cores do raise these interrupts (mega65-core, September 2026), but until they are documented
and in a release, a program should poll the stop flag, for example once
a frame.
A 64KB region holds about eight seconds of 8-bit sound at 8 kHz. Longer sounds use the loop bit as a ring buffer: the channel loops over a region while the program copies the next part of the sound into the half the current address has just left, using DMA from attic RAM. Because audio DMA steals cycles from ordinary DMA jobs, the copies do not interrupt playback.
Everything the MEGA65 plays passes through a full cross-bar mixer. Each output, such as the left speaker or the right headphone, is built by multiplying every input by its own 16-bit coefficient and adding the results. Because each output has its own complete set of coefficients, every output can carry a completely different mix (MEGA65 Book, p. V-23).
The inputs relevant to the MEGA65 are listed below; the others exist only on the MEGAphone or development boards (MEGA65 Book, p. V-24).
| Input | Source |
|---|---|
$0 |
Left SIDs (3 and 4) |
$1 |
Right SIDs (1 and 2) |
$8 |
Digital audio left: audio DMA channels 0-1, or
$D6F8-$D6F9 |
$9 |
Digital audio right: audio DMA channels 2-3, or
$D6FA-$D6FB |
$E |
Coefficient also used for the OPL2 FM input, $F |
$F |
Its coefficient is the master volume for the output |
| Output | Destination |
|---|---|
$0 |
Left primary output |
$1 |
Right primary output |
$6 |
Left headphone output |
$7 |
Right headphone output |
The 128 coefficients are reached through a register-select port and a data port (MEGA65 Book, p. V-26):
| Register | Name | Purpose |
|---|---|---|
$D6F4 |
MIXREGSEL | Select a coefficient byte |
$D6F5 |
MIXREGDATA | Read or write the selected byte |
$D6F8-$D6F9 |
DIGILLSB/MSB | 16-bit sample for the left digital input |
$D6FA-$D6FB |
DIGIRLSB/MSB | 16-bit sample for the right digital input |
$D6FC-$D6FD |
READBACKLSB/MSB | Audio read-back, source selected by $D6F4, for
visualisers or effects |
The coefficient for input i on output o starts at byte
o × 32 + i × 2: the low byte there, the high byte at the
next number. For example, the right SIDs (input 1) on the left primary
output (output 0) are bytes 2 and 3. Changes take effect at once, so
ramp coefficients gradually to avoid clicks, and allow 32 cycles after
changing one coefficient before selecting another, or the change may be
lost (MEGA65 Book, pp. V-23, V-25).
This sets the right SIDs to full level on the left primary output:
lda #2 ; output 0, input 1, low byte
ldx #$ff
jsr setmix
lda #3 ; high byte
ldx #$ff
jsr setmix
rts
; setmix: write X to mixer byte A. Wait after
; selecting the byte and again after writing it
setmix sta $d6f4
ldy #8
sel lda $d6f5 ; let the selection settle
dey
bne sel
stx $d6f5
ldy #8
wait lda $d6f5 ; the read also gives audio
dey ; DMA its idle cycles
bne wait
rts
With AUDEN in $D711 clear, the digital inputs take their
samples straight from $D6F8-$D6FB, 16 bits per side. A
program writing these registers at a steady rate can play procedurally
generated sound, such as a software synthesiser, without audio DMA. For
recorded samples audio DMA is simpler, steadier and cheaper in CPU time
(MEGA65 Book, p. V-25).
The mixer settings belong to the user, who adjusts them with the audio mixer in the Freezer, and they persist with the machine. A program should normally control loudness and position through what it owns: each SID's volume register, the choice of SID pair, and the audio DMA volumes and cross-feed registers. Programs that genuinely need to manage the mix, such as music trackers, should read the coefficients they change and restore them before exiting.
Two practical habits help while developing:
On the R3 and earlier boards, the 3.5mm socket is driven by an
over-sampled 1-bit output, with a choice of pulse-width or pulse-density
modulation through the PWMPDM bit in $D711. R4 and later
boards use a dedicated DAC, and on older boards the Book recommends HDMI
audio for the best quality (MEGA65 Book, pp. V-25, V-26).
This example plays a recorded sound effect once, centred between the speakers, while the program carries on, and then detects when it has finished.
Audio DMA plays raw sample data with no file header, so a sound recorded or downloaded on a PC must first be converted. The free ffmpeg tool does it in one step; this converts any audio file to mono, 8 kHz, unsigned 8-bit samples (Dan Sanderson):
ffmpeg -i boom.wav -f u8 -ar 8000 -ac 1 boom.raw
The options are the sample format (u8 unsigned 8-bit,
s16le signed 16-bit), the sample rate in hertz, and the
number of channels. Copy the result to a disk image or the SD card with
the program.
From BASIC, reserve memory in bank 5 with MEM, as Chapter 6
described, then BLOAD the file to $50000:
10 MEM 0,3 : REM RESERVE $50000-$53FFF
20 BLOAD "BOOM.RAW",R,P($50000)
MEM 0,3 reserves the first two 8KB blocks of bank 5,
16KB in all, enough for the 12,000-byte sample used below: one and a
half seconds at 8 kHz. The load address follows Dan Sanderson's example
(Dan
Sanderson); the R flag loads the file raw, instead of treating its
first two bytes as a load address (MEGA65 Book, BLOAD).
This routine plays a 12,000-byte, unsigned 8-bit sample at 8 kHz on
channel 0. The sample starts at $050000 and its last byte
is at $052EDF, of which only the low 16 bits are written.
The CPU must be at full speed, its default in MEGA65 mode.
play lda #$00
sta $d720 ; stop channel 0 while setting it up
lda #$80
sta $d711 ; AUDEN: enable audio DMA
lda #$00 ; current address: start of sample
sta $d72a
sta $d72b
lda #$05
sta $d72c
lda #$00 ; base address: same, in case of looping
sta $d721
sta $d722
lda #$05
sta $d723
lda #$df ; top address: low 16 bits of $052EDF
sta $d727
lda #$2e
sta $d728
lda #$f2 ; rate: 8 kHz = $000CF2
sta $d724
lda #$0c
sta $d725
lda #$00
sta $d726
lda #$80 ; volume: left side
sta $d729
sta $d71c ; same to the right: centred
lda #$a2 ; enable, unsigned, 8-bit, no loop
sta $d720
rts
The final write starts playback. The routine returns at once, and the
sound plays while the program continues. Writing 0 to $D720
stops it early, and calling the routine again restarts the sound,
because it resets the current address.
The hardware sets the stop flag, bit 3 of $D720, when
the sample finishes (MEGA65 Book, p. P-20). A game can check it once a
frame:
lda $d720
and #%00001000 ; CH0STP
bne finished
| Change | How |
|---|---|
| Loop the sound | Control value $E2: bit 6 set |
| Signed 16-bit data | Control value $83: bit 5 clear, format
%11; the top address covers two bytes per sample |
| Left side only | Write 0 to $D71C |
| Right side | Use channel 2 at $D740, with $D71E for its
left-side level |
| Higher pitch | Increase the rate; doubling it plays an octave higher and twice as fast |
| Fade out | Lower the volume register a step each frame; it can change while playing |
| A clean test tone | Control value $90: sine mode, no memory needed |
| Several sounds at once | Use up to four channels, each with its own sample |
With four channels and the rate register acting as a pitch control, this is the basis of a MOD-style music player: short instrument samples, each played at different rates to make different notes. The MEGA65's intro disk includes such a player, Manche (Dan Sanderson).
$D400 and
$D420 (the right pair) and $D440 and
$D460 (the left pair), mirrored at
$D480-$D4FF. SIDMODE at $D63C selects 6581 or
8580 behaviour.$80 to
$D711, plays samples from chip RAM on four channels at
$D720-$D75F, using the CPU's idle cycles at full speed.
Playback starts at the current address, loops from the base address, and
sets a stop flag at the end. Rates are a 24-bit fraction of 40.5
MHz.$D71C-$D71F feeding each to the opposite
side.$D6F4 and
$D6F5; input 15's coefficient is each output's master
volume. The mix belongs to the user, so programs normally adjust their
own sources instead.Chapter 14 turns to mass storage on the SD card.