Skip to content
Game 0 Unit 15 of 16 1 hr learning time

The Machine Speaks Back

The 48K Spectrum has no sound chip. Sound is the CPU's own job: flip one bit of one port to push the speaker, wait, flip it back, wait — over and over. That square wave is the tone, and the CPU does nothing else while it plays. On this machine, you are the sound chip.

94% of Meet The Machine

Back in Unit 8 the machine learned to hear you, reading the keyboard through a port. This unit is the answer — and here the Spectrum stands apart from every other machine in this course.

The C64 has the SID. The NES has its APU. The Amiga has Paula. The 48K Spectrum has nothing — no sound chip at all. So how does it make a sound? The CPU does it by hand. There is one bit, bit 4 of port $FE, wired straight to the speaker. Write a 1 and the speaker cone pushes out; write a 0 and it pulls back. Do that fast enough, evenly enough, and the in-and-out becomes a tone.

That's the whole trick: flip the bit, wait, flip it back, wait, forever. The waiting sets the pitch — a longer wait is a lower note. And because the CPU is busy counting out those waits, it can do nothing else while the sound plays. On this machine, you aren't programming a sound chip. You are the sound chip.

What you'll hear by the end

ZX Spectrum 48K · beeper · port $FE bit 4
A beeper tone — the CPU toggling the speaker by hand

A plain, buzzy tone, held steady. It's a square wave — the speaker slammed between its two positions — and that thin, direct sound is the voice of a thousand Spectrum games. The waveform strip above is the real captured output: two flat halves, exactly as the bit goes high then low.

A flat cyan Spectrum screen and border, nothing drawn on it.
There's nothing to see — the work is in the speaker. The flat colour is just a sign the program is running.

Flip the bit, wait, repeat

; ============================================================================
; Meet the Machine - Unit 15: The Machine Speaks Back
; ============================================================================
; The 48K Spectrum has NO sound chip. Sound is the CPU's own job: flip bit 4 of
; port $FE to push the speaker, wait, flip it back, wait, over and over. That
; square wave IS the tone. The pitch is the length of the wait; the CPU does
; nothing else while it plays - it is the sound chip.
; ============================================================================

            org     32768

start:
            di                       ; no interrupts - they would jitter the tone

            ; --- clear the screen to a flat colour, so the shot is clean ---
            ld      hl, $4000
            ld      (hl), 0
            ld      de, $4001
            ld      bc, $17ff
            ldir                     ; blank every pixel
            ld      hl, $5800
            ld      (hl), $2d        ; paper cyan + ink cyan -> a flat field
            ld      de, $5801
            ld      bc, $02ff
            ldir

            ; ----------------------------------------------- YOUR CODE START
loop:
            ld      a, $15           ; speaker bit (4) HIGH, border cyan (bits 0-2)
            out     ($fe), a
            call    delay            ; hold...

            ld      a, $05           ; speaker bit LOW, border still cyan
            out     ($fe), a
            call    delay            ; ...hold

            jr      loop             ; forever - the toggling is the tone

delay:
            ld      bc, 200          ; the wait length - bigger is a lower note
.wait:      dec     bc
            ld      a, b
            or      c
            jr      nz, .wait
            ret
            ; ------------------------------------------------- YOUR CODE END

            end     start

After clearing the screen to a flat colour, the tone is one short loop:

loop:
        ld      a, $15           ; speaker bit (4) HIGH, border cyan (bits 0-2)
        out     ($fe), a
        call    delay            ; hold...

        ld      a, $05           ; speaker bit LOW, border still cyan
        out     ($fe), a
        call    delay            ; ...hold

        jr      loop             ; forever - the toggling is the tone

out ($fe), a writes a byte to port $FE. Bit 4 is the speaker: $15 has it set (high), $05 has it clear (low) — and both keep bits 0–2 at 5, so the border stays cyan the whole time. Between the two writes is a delay: a loop that counts a register down to zero and does nothing else. That pause is half of one wave. Flip high, wait; flip low, wait; round again — a square wave, built one instruction at a time.

The delay routine is the pitch:

delay:
        ld      bc, 200          ; the wait length - bigger is a lower note
.wait:  dec     bc
        ld      a, b
        or      c
        jr      nz, .wait
        ret

It loads a number and counts it down. A bigger number is a longer wait, a slower flip, a lower note. There is no frequency register to set — the time the CPU spends counting is the frequency. And note the di at the top of the program: with interrupts off, nothing else steals the CPU's attention, so the waits stay even and the tone stays pure.

Assemble and run

pasmonext --sna beeper.asm beeper.sna

A steady tone from the speaker; a flat cyan screen.

Try this: change the pitch

The wait length is ld bc, 200. Make it ld bc, 100 and the note jumps higher; ld bc, 400 and it drops lower. You're not setting a pitch — you're setting how long the CPU dawdles between flips, and that is the pitch.

Try this: a two-note tune

Wrap the loop in an outer counter so it flips a few hundred times, then change bc and flip a few hundred more. Two waits, two pitches — the start of a melody. This is exactly how Spectrum games played music: not by handing notes to a chip, but by the CPU counting out every single wave of every single note, itself.

If it doesn't work

  • Silence. Bit 4 isn't toggling — both out values must differ in bit 4 ($15 high, $05 low). If they're the same, the speaker never moves.
  • A faint or harsh click instead of a tone. The two delays aren't equal, or the loop isn't repeating — the wave needs an even high-then-low, over and over, to sound like a note.
  • The tone wavers in pitch. Interrupts are firing and stealing time. The di at the top keeps the CPU's count even; without it the 50-times-a-second interrupt jitters the note.

What you've learnt

The 48K Spectrum has no sound chip. Sound is made by the CPU itself: toggling bit 4 of port $FE to drive the speaker, with a counted delay between flips that sets the pitch. The CPU does nothing else while the tone plays — it is the oscillator. It's the opposite of a sound chip you set going and leave; here, the sound is the program.

What's next

That's the last of what the machine can do — its screen, its colour, its input, and now its sound, all of it driven straight by the CPU. One unit remains, and it isn't about a new instruction. Next — The Machine Trusts You — what it means to program a machine that does exactly what you wrote, even when you're wrong.