Music Processor

The music processor can be thought of as an independent CPU (MUZCPU) handling all output to the music/noise ports. Within each programmer-defined musical “score,” the programmer may use a series of instructions unique to the music processor (see below).

The MUZCPU has 4 registers:

  • MPC: Like all program counters, points to the next data byte to fetch.
  • MSP: Like a stack pointer, points to return addresses on the music stack.
  • DURATION: Loaded at the start of a note, then decremented every 60th of a second.
  • VOICES: A status register that tells which voices (tones) to load with what data.

The VOICES status register is shown below. Execution proceeds right-to-left. Make sure that you always have at least one MPC incrementing bit or load on.

MUZCPU Instruction Set

# of Bytes Instruction Argument(s) Comment
2 VOICES/VOICEM M Load VOICES status register with mask data (M)
2 MASTER F Sets master oscillator (TONMO) frequency (F)
3 CALL A Music CALL subroutine: (SP) = (PC+3); PC = address
1 RET Music RETurn: PC = (SP++)
3 JP A Music JumP: PC = address
2 NOTE1 D,D1 Duration, note or data (D1)
3 NOTE2 D,D1,D2 Duration, D1,D2
4 NOTE3 Duration, D1,D2,D3
5 NOTE4 Duration, D1,D2,D3,D4
6 NOTE5 Duration, D1,D2,D3,D4,D5
2 REST n Pauses silently for n 60ths of a second (except in LEGATO mode)
1 QUIET Stops music and sets volume = 0
2 OUTPUT p,d Port #(0–7), Data
9 OUTPUT SNDBX,D10,D11,D12,D13,D14,D15,D16,D17 Sound block transfer for all 8 output ports via SNDBX ($18)
3 VOLUME VOLAB, VOLC Sets volume Tones A–C
1 PUSHN Push # between 1-16 onto the stack
1 CREL Call relative to next instruction
3 DSJNZ A Decrement stack top and jump to address (a) if not 0, else pop stack
1 LEGSTA Flips between STACATO (notes clipped 1/60th of a second before end) and LEGATO (notes flow smoothly from one to the next) modes

Note: All note durations are limited to a maximum of 127 (i.e., 2.1 seconds)

The port numbers (0–7) passed to OUTPUT assume that output port $10 (VOLMO) is the “base” port (i.e., port $0). Port numbers are offset from that base. For example, to set Tone B's frequency to $82, one would call OUTPUT $02,$82. This would store the value $82 in output port $12 (TONEB).

Testing:
* PUSHN creates a loop index that DSJNZ decrements until zero (for looping music sections)?
* What does CREL do?
* Why NOTE4 and NOTE5? (Dogpatch uses NOTE4)

Master Oscillator

The frequency of the master oscillator is determined by the contents of several output ports. Port $10 (TONMO) sets the master frequency according to the following formula:

Fm = 1789 / (Port $10 + 1) kHz

Modulation

If bit 4 of output port $15 (VOLC) is set to 1, the master oscillator frequency will be modulated by noise. The amount of modulation will be set by the 8-bit noise volume register, output port $17 (VOLN).

If bit 4 of output port $15 is set to 0, the frequency of the master oscillator will be modulated by a constant value to give a vibrato effect. The amount of modulation will be set by the vibrato depth register (the first 6 bits of output port $14, VIBRA). The speed of modulation is set by the vibrato speed register (upper 2 bits of output port $14): 00 for fastest and 11 for slowest.

Frequency modulation is accomplished by adding a modulation value to the contents of port $10 (TONMO) and sending the result to the master oscillator frequency generator. In noise modulation, the modulation value is an 8-bit word from the noise generator. If a bit in the noise volume register is set to 0, the corresponding bit in the modulation value word will be set to 0. In vibrato modulation, the modulation value alternates between 0 and the contents of the vibrato volume register.

Modulation can be completely disabled by setting noise volume (VOLN) to 0 if noise modulation is being used, or by setting the vibrato depth (VIBRA) to 0 when vibrato is used.

Tones

The system contains three tone generators, each clocked by the same master oscillator. The frequency of Tone A is set by output port $11 (TONEA), Tone B by output port $12 (TONEB), and Tone C by output port $13 (TONEC). The frequency is given by the following formula:

Ft = Fm / (2 * (Tone port + 1)) = 894 / [(Port $10 + 1)(Tone port + 1)] kHz

The tone volumes are controlled by output ports $15 (VOLC) and $16 (VOLAB). The lower 4 bits of port $16 set Tone A volume, the upper 4 bits set Tone B volume. The lower 4 bits of port $15 set Tone C volume. Noise can be mixed with the tones by setting bit 5 of port $15 to 1. In this case, the noise volume is given by the upper 4 bits of port $17 (VOLN). In all cases, a volume of 0 is silence and a volume of all 1's is loudest.

Music Processor Port Summary

               7    6    5    4    3    2    1    0
$10  TONMO   [ f ][ f ][ f ][ f ][ f ][ f ][ f ][ f ]   f = Master oscillator frequency
$11  TONEA   [ f ][ f ][ f ][ f ][ f ][ f ][ f ][ f ]   f = Tone A frequency
$12  TONEB   [ f ][ f ][ f ][ f ][ f ][ f ][ f ][ f ]   f = Tone B frequency
$13  TONEC   [ f ][ f ][ f ][ f ][ f ][ f ][ f ][ f ]   f = Tone C frequency
$14  VIBRA   [ s ][ s ][ v ][ v ][ v ][ v ][ v ][ v ]   s = Vibrato speed, v = Vibrato depth
$15  VOLC    [   ][   ][   ][ t ][ c ][ c ][ c ][ c ]   t = Vibrato(0)/Noise(1), c = Tone C volume
$16  VOLAB   [ b ][ b ][ b ][ b ][ a ][ a ][ a ][ a ]   b = Tone B volume, a = Tone A volume
$17  VOLN    [ n ][ n ][ n ][ n ][ n ][ n ][ n ][ n ]   n = Noise volume

Sound Block Transfer

All 8 bytes of sound control can be sent to the audio circuit with one OTIR instruction. Register C should be sent to $18 (SNDBX), register B to $8, and HL pointing to the 8 bytes of data. The data pointed to by HL goes to port $17 and the next 7 bytes of data goes to ports $16–$10.

Memory Location Data-to-port
X $17
X+1 $16
X+2 $15
X+3 $14
X+4 $13
X+5 $12
X+6 $11
X+7 $10

Audio Generator Block Diagram


[NM:103–5]

Technical Detail

The music processor can be divided into two sections. The first section generates the Master Oscillator Frequency, and the second section uses the Master Oscillator Frequency to generate ton frequencies and the analog audio output. The contents of all registers in the Music Processor are set by output instructions from the Z80.

Master Oscillator Frequency is a square wave whose frequency is determined by the 8 binary inputs to the Master Oscillator. This 8-bit word is the sum of the contents of the Master Oscillator Register and the output of the MUX. The MUX is controlled by MUX REG.

If MUX REG contains 0, then data from the Vibrato System will be fed through the MUX. The two bits from the Vibrato Frequency Register determine the frequency of the square wave output of the Low Frequency Oscillator. The 6-bit word at the output of the AND gates oscillates between 0 and the contents of the Vibrato Register. The frequency of oscillation is determined by the contents of the Vibrato Frequency Register. The 6-bit word, along with two ground bits, is fed through the MUX to the Adder. This causes the Master Oscillator Frequency to be modulated between two values, producing a vibrato effect.

If MUX REG contains 1, then data from the Noise System will be fed through the MUX. The 8-bit word from the Noise Volume Register determines which bits from the Noise Generator will be present at the output of the AND gates.

If a bit in the Noise Volume Register is 0, then the corresponding bit at the output of the AND gates will be 0. If a bit in the Noise Volume Register is 1, then the corresponding bit at the output of the AND gates will be noise from the Noise Generator. This 8-bit word is sent through the MUX to the Adder. The Master Oscillator Frequency is modulated by noise.

In the second part of the Music Processor, the square wave from the Master Oscillator is fed to three Tone Generator circuits that produce square waves at their outputs. The frequency of their outputs is determined by the contents of their Tone Generator Register and Master Oscillator Frequency. The 4-bit words at the output of the AND gates oscillate between 0 and the contents of the Tone Volume Register. These 4-bit words are sent to D-A Converters whose outputs oscillate between GND and a positive analog voltage determined by the contents of the Tone Volume Register.

One Noise bit and four Noise Volume bits from the first section of the Music Processor are fed to a set of AND gates. This set of AND gates operates the same way as the AND gates for the tones, except that the Noise AM Register must contain a 1 for the outputs of the AND gates to oscillate. The analog outputs of the four D-A Converters are summed to produce the single audio output.

Music Score Example

          VOICES     11010100B     ; ABC = Data 1
          MASTER     0A1H          ; ABC = 1/2 [???]
          VOLUME     88H,08H       ; Tones ABC set to volume 8
          NOTE1      12,A1         ; Duration, Tone A
          NOTE1      12,C2
          NOTE1      24,E2
          NOTE1      12,C2
          NOTE1      12,E2
          REST       6             ; Pause 1/10th of a second
          VOICES     11110110B     ; Suck in Vibrato, AB and C bytes
          NOTE3      12,14,A2,E2   ; Duration, Tone A, B, C
          QUIET

Example seems wrong (or at least unclear)?

Make audio clip


Example: Football National Anthem & Cheer

; Music stack in RAM
MUSICWRK  EQU   $4E7F     ; BLOCK 2
; [...]
 
; call Begin Music system routine
         SYSSUK BMUSIC           ; START THE NATIONAL ANTHEM
         DW     MUSICWRK         ; MUSIC STACK
         DB     11111100B        ; 3-VOICE (A,B,C)
         DW     ANTHEM           ; SCORE
 
; [...]
 
ANTHEM:  MASTER 32
         VOLUME $CC,$0F          ; A,B=12, C=15
         NOTE3  12,G1,0,0        ; G1, 0, 0
         NOTE3  12,G1,0,0        ; G1, 0, 0
         NOTE3  36,C2,G1,E1      ; C2, G1, E1
         NOTE3  12,D2,B1,G1      ; D2, B1, G1
         NOTE3  14,E2,C2,G1      ; E2, C2, G1
         NOTE3  16,F2,D2,G1      ; F2, D2, G1
         NOTE3  72,G2,E2,C2      ; G2, E2, C2
;
         NOTE3  14,C2,F1,A1      ; C2, F1, A1
         NOTE3  16,D2,F1,A1      ; D2, F1, A1
         NOTE3  54,E2,C2,A1      ; E2, C2, A1
         NOTE3  18,F2,D2,G1
         NOTE3  36,D2,B1,G1      ; D2, B1, G1
         NOTE3  72,C2,E1,G1      ; C2, E1, G1
;
CHEERS:  LEGSTA                  ; Cheers
         MASTER  24
         VOICEM  11111101B       ; A,B,C & Noise
         VOLUME  $FF,$1F         ; Max. Volume
;
         PUSHN  5
L2FE8:   DB     30               ; Noise
         NOTE3  25,G6,60,80
         DSJNZ  L2FE8
         LEGSTA
         QUIET

Example: Astro Battle Base Explosion

MUSSTK  EQU   $4F12     ; Music Stack Pointer
 
; [...]
 
; Begin Music system routine
        SYSSUK  BMUSIC          ; UPI Begin playing MUSIC
        DW      MUSSTK          ; ... Music Stack = $4F12
        DB      $FC             ; Setup Voices, Use Tones A, B, and C
        DW      L28A9           ; Score Address of "Base Exploding"
 
; [...]
 
; Sound Effect of "Base Exploding"
L28A9:  MASTER  255             ; Set Tone of Master Oscillator to $FF
        VOLUME  $FF,$1F         ; Sets Volumes Tone A = 15, Tone B = 15, Tone C = 15, [and NM = 1]
        LEGSTA                  ; Flip to LEGato from STAccato
        OUTPUT  $07,$F0         ; Noise Volume = 15 
        NOTE3   50,$88,$D4,$F8  ; Duration = 50/60'th of a sec, TC= TB= TA=
        VOLUME  $CA,$1C         ; Sets Volumes Tone A = 10, Tone B = 12, Tone C = 12, [and NM = 1]
        OUTPUT  $07,$B8         ; Noise Volume = 184
        NOTE3   30,$88,$D2,$FA  ; Duration = 30/60'th of a Sec, TC= TB= TA=
        VOLUME  $BA,$1B         ; Sets Volumes Tone A = 10, Tone B = 11, Tone C = 11, [and NM = 1]
        OUTPUT  $07,$80         ; Noise Volume = 8
        NOTE3   30,$8E,$DD,$FF  ; Duration = 30/60'th of a Sec, TC= TB= TA=
        VOLUME  $86,$16         ; Sets Volumes Tone A = 6, Tone B = 8, Tone C = 6, [and NM = 0]
        OUTPUT  $07,$00         ; Noise Volume = 0
        NOTE3   25,$90,$E0,$FF  ; Duration = 25/60'th of a Sec, TC= TB= TA=
        QUIET

[NM:56–8, 119–20]