====== 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. {{:vs_register.png}} ===== 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 [[hardware:i o ports|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 ===== {{:audio_generator.png}} ---- [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 [[#modulation|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]