Skip to content

Sound Beep

Generate a simple beep or tone by toggling the speaker bit. Rising or falling pitch for feedback sounds.

Taught in Game 1, Unit 2 soundbeeperaudiospeaker

Overview

The Spectrum has no dedicated sound chip - just a 1-bit speaker controlled through port $FE. Toggle bit 4 on and off at different speeds to create tones. Vary the delay between toggles for pitch, and loop duration for length. Simple but effective for game feedback.

Code

; =============================================================================
; SOUND BEEP - ZX SPECTRUM
; Generate tones via speaker bit toggling
; Taught: Game 1 (Ink War), Unit 2
; CPU: Variable (blocks during playback) | Memory: ~40 bytes
; =============================================================================

KEY_PORT    equ     $fe
SPEAKER_BIT equ     $10         ; Bit 4 of port $FE

; Rising tone (success sound)
; Good for: claiming cells, collecting items, positive feedback
sound_success:
    ld      hl, 400             ; Starting pitch (higher = lower frequency)
    ld      b, 20               ; Duration (number of cycles)

.loop:
    push    bc
    push    hl

    ; Generate one cycle of tone
    ld      b, h
    ld      c, l                ; BC = delay count
.tone_loop:
    ld      a, SPEAKER_BIT      ; Speaker on
    out     (KEY_PORT), a
    call    .delay
    xor     a                   ; Speaker off
    out     (KEY_PORT), a
    call    .delay
    dec     bc
    ld      a, b
    or      c
    jr      nz, .tone_loop

    pop     hl
    pop     bc

    ; Decrease delay (increase pitch)
    ld      de, 20
    or      a
    sbc     hl, de

    djnz    .loop
    ret

.delay:
    push    bc
    ld      b, 5
.delay_loop:
    djnz    .delay_loop
    pop     bc
    ret

; Falling tone (error/failure sound)
; Good for: invalid moves, damage, negative feedback
sound_error:
    ld      hl, 100             ; Start high pitched
    ld      b, 15               ; Duration

.error_loop:
    push    bc
    push    hl

    ld      b, h
    ld      c, l
.error_tone:
    ld      a, SPEAKER_BIT
    out     (KEY_PORT), a
    call    .delay
    xor     a
    out     (KEY_PORT), a
    call    .delay
    dec     bc
    ld      a, b
    or      c
    jr      nz, .error_tone

    pop     hl
    pop     bc

    ; Increase delay (decrease pitch)
    ld      de, 15
    add     hl, de

    djnz    .error_loop
    ret

Simple single beep:

; Quick beep (for button press feedback)
sound_click:
    ld      hl, 200             ; Pitch
    ld      b, 5                ; Short duration

.click_loop:
    push    bc
    push    hl

    ld      b, h
    ld      c, l
.click_tone:
    ld      a, SPEAKER_BIT
    out     (KEY_PORT), a
    call    short_delay
    xor     a
    out     (KEY_PORT), a
    call    short_delay
    dec     bc
    ld      a, b
    or      c
    jr      nz, .click_tone

    pop     hl
    pop     bc
    djnz    .click_loop
    ret

short_delay:
    push    bc
    ld      b, 3
.sd_loop:
    djnz    .sd_loop
    pop     bc
    ret

Trade-offs

AspectCost
CPUBlocks execution during playback
Memory~40 bytes per sound routine
LimitationNo background playback, mono only

When to use: Short feedback sounds (clicks, beeps, success/error tones).

When to avoid: Background music or sounds during gameplay - CPU is blocked.

How It Works

  1. The speaker is controlled by bit 4 of port $FE
  2. Set bit 4 high ($10) to push the speaker cone out
  3. Set bit 4 low ($00) to let it return
  4. The speed of toggling determines the pitch
  5. Smaller delay = higher frequency = higher pitch

Pitch Reference

Delay ValueApproximate Note
50-100High beep
100-200Medium tone
200-400Low tone
400+Very low rumble

Patterns: Game Loop (HALT)

Vault: ZX Spectrum