The AY-3-8910 and its variations were widely used in classical machines like for example the Sinclair ZX Spectrum, Amstrad CPC and Atari ST. It can produce up to three different squarewave sounds simoultaneously, and it also has one noise-generator and one envelope generator.
Allthough it has its limitations, there are tricks to get around a few of them:
1. Fast arpeggios to emulate chords on one chanel.
2. Software envelopes to get around the limitations of the single envelope generator.
3. Matching the hardware envelope to a played tone's frequency for a more sawtooth-like sound.
4. Software tone sweep
5. Using the volume controlls and certain settins to emulate a DAC for digital audio.
The fifth one is more of a hack, so the synth implements point 1-4. There is one software envelope and one tone-sweep parameter for every channel, and overall one noise-sweep parameter and one arpeggiator.
I'm still in the proccess of testing everything, but it should in theory work fine. I just hope that the 4MHz Z80 in my Tiki-100 computer is fast enough to handle 125 updates of the synth per second. Here is the documentation:
Code:
Next step will be to make a music player or real-time sequencer that uses this in some way or another.
Allthough it has its limitations, there are tricks to get around a few of them:
1. Fast arpeggios to emulate chords on one chanel.
2. Software envelopes to get around the limitations of the single envelope generator.
3. Matching the hardware envelope to a played tone's frequency for a more sawtooth-like sound.
4. Software tone sweep
5. Using the volume controlls and certain settins to emulate a DAC for digital audio.
The fifth one is more of a hack, so the synth implements point 1-4. There is one software envelope and one tone-sweep parameter for every channel, and overall one noise-sweep parameter and one arpeggiator.
I'm still in the proccess of testing everything, but it should in theory work fine. I just hope that the 4MHz Z80 in my Tiki-100 computer is fast enough to handle 125 updates of the synth per second. Here is the documentation:
Code:
; #######################################################
; # #
; # AY-3-8910 Synthesizer for Z80 #
; # #
; #######################################################
;
; Version 1.00
; by Frode van der Meeren
; November 2014
;
; Overview:
;
; This synthesizer is designed to take full use of the
; AY-3-8910's native features. It presents each of the
; three channels as their own instrument, and it also
; provides additional features like software-envelopes,
; frequency sweeps and an arpeggiator.
;
; There is two full chromatic scales implemented. A
; regular equal-tempered scale and the scale of its
; perfect fifths. Additional tones for harmonic chord
; progression is also present, but care must be taken
; when using these with the tones from the scales.
;
; The synth can be implemented in a lot of applications.
; It can be used as a music player, for realtime sequencing,
; with external music and MIDI equipment, music in games,
; or with anything at all that should need to use the AY
; soundchip.
;
; Instructions:
;
; To run the synth, first make sure to include the right
; interface for the AY chip under AYdrv below. The interface
; is generalized, and your driver must ensure that the
; data reaches correctly to the chip in your particular.
; system. See the documentation below for a description.
;
; When the AY interface is in place, make sure to set up
; code that calls synthcycle at a fixed interval. These
; intervals must be very well and evenly timed for best
; performance. The synthcycle routine will keep the
; software envelopes, frequency sweeps and the arpeggiator
; going.
;
; After that is done, call shutup and the synth is ready
; to use. Instruments are by default set to use the hardware
; envelope, so you might want to start by setting up the
; instruments and envelopes. Finally it's time to send music
; messages to play music.
;
; It's always a good idea to call shutup to reset everything
; when the performance is done.
;
;
; #######################################################
; # #
; # Control #
; # #
; #######################################################
; # #
; # synthcycle: #
; # n/a #
; # #
; # shutup: #
; # n/a #
; # #
; #######################################################
synthcycle:
ld a,$00
call updateinst ; Update instrument A
ld a,$01
call updateinst ; Update instrument B
ld a,$02
call updateinst ; Update instrument C
call updatenoise ; Update noise
jp updatearp ; Update arpeggio
shutup:
di
call endArpeggio ; Arpeggio
push ix
ld a,$00 ; Instrument A
call resetInstrument
ld a,$01 ; Instrument B
call resetInstrument
ld a,$02 ; Instrument C
call resetInstrument
ld ix,instrN ; Noise
ld (ix+0),$00
ld (ix+1),$00
ld a,$06
ld b,$02
ld c,$00
call AYdrv
ld (ix+2),$00
ld (ix+3),$00
pop ix
ei
ret
;
; The synth has three instruments, where each instrument
; corresponds to one hardware-channel of the AY chip. Each
; instrument has its own proper fully programmable ADSR
; amplitude envelope in software, but it's also possible to
; let an instrument use the hardware envelopes. All the
; instruments also has individual frequency sweep functions.
;
; When using the hardware envelope, you can choose to have it
; steady at a fixed speed, or you can have it match the
; frequency of the tones played. It can also be set to run at
; double frequency in both modes. Any instrument can be set
; to use the hardware synth regardless, but only a single
; instrument can physically perform with it at any time. If
; a new tone is played using the hardware envelope, any
; previous playing tones with hardware envelope it will be
; terminated.
;
; Software envelopes trigger on playTone, and if the previous
; tone was not complete, the volume will not jump down to
; start the attack of the next tone. The attack will rather
; begin from the curent volume when the playTone was received.
; playTone trigger attack>decay>sustain, and endTone will
; trigger release from sustain. Attack and sustain volume
; can be set to any of the 16 possible levels.
;
; Envelopes can be updated realtime, but updates will only
; take effect on the first tone after the update is performed.
; The parameters of setEnvelopes varies depending on the
; envelope type selected for the instrument as well. When
; an instrument is redefined with setInstrument, any tone
; payed by it will be automatically terminated immediately.
;
; Each instrument also has it's own individual frequency
; sweep. skip to the tone table towards the end of this file
; for an overview of the tone-byte format.
;
;
; #######################################################
; # #
; # Instrumental #
; # #
; #######################################################
; # #
; # setInstrument: #
; # a = inst (A=0, B=1, C=2) #
; # b = tone (Yes=0) #
; # c = noise (No=0) #
; # d = envelope type (SwE=0) #
; # #
; # setEnvelope: #
; # a = inst (A=0, B=1, C=2) #
; # b = volume (4-7 att, 0-3 sus)/HwE follow (No=0) #
; # c = attack duration in ticks/HwE double (No=0) #
; # d = decay duration in ticks/HwE freq high #
; # e = release duration in ticks/HwE freq low #
; # l = HwE mode (b0 hold, b1 alternate, b2 attack) #
; # #
; # playTone: #
; # a = inst (A=0, B=1, C=2) #
; # b = tone #
; # #
; # endTone: #
; # a = inst (A=0, B=1, C=2) #
; # #
; # sweepTone: #
; # a = inst (A=0, B=1, C=2) #
; # b = tone #
; # c = sweep duration in ticks #
; # #
; #######################################################
include synth\instruments.asm
;
; The hardware noise of the AY can be set and tuned totally
; independent from the rest of the synth, but it is the
; settings of the instruments that define how noise will
; be used.
;
;
; #######################################################
; # #
; # Noise Generator #
; # #
; #######################################################
; # #
; # setNoise: #
; # a = tune (0 = bright, 31 = dark) #
; # #
; # sweepNoise: #
; # a = tune (0 = bright, 31 = dark) #
; # b = sweep duration in ticks #
; # #
; #######################################################
include synth\noise.asm
;
; One arpeggio can be played at any time. The arpeggio
; will take completely over one or two channels of the
; AY chip. The only three events capable of interrupting
; an arpeggio is when one of the performing instruments
; are re-defined, a new arpeggio is started or when the
; entire synth is reset. In any other case, the only ways
; to stop an arpeggio is to let it run for the remaining
; of it's set duration or by stopping it manually.
;
;
; #######################################################
; # #
; # Arpeggiator #
; # #
; #######################################################
; # #
; # playArpeggio: #
; # a(0-3) = inst (0=A, 1=B, 2=C, 4=AB, 5=BC, 6=CA) #
; # a(4-7) = volume #
; # b/h/l = tones in arpeggio #
; # c = ticks per tone #
; # de = ticks of overall duration #
; # #
; # endArpeggio: #
; # n/a #
; # #
; #######################################################
include synth\arpeggio.asm
;
; The tone ranges from C1 to B8. It should be noted that
; the brighter resolution is rather weak, so you might
; not want to use the top octave (C8-B8).
;
; The 5ths scale is a perfect 5th up from the chromatic
; Equal-tempered scale. This is not the same as an equal-
; tempered fifth. These are used mainly for power-chords.
;
; The remaining tones are for harmonic chord progression.
; Major chords are progressed using the Pytagorean scale,
; and minor chords are based on the just-intonated thirds
; from these major chords. All minor chords using these
; tones are therefore very flat compared to the equal-
; tempered and perfect fifth scales! The major chords may
; be slightly detuned from the equal tempered scales, but
; not by much.
;
;
; #######################################################
; # #
; # Tone-table lookup #
; # #
; #######################################################
; # #
; # Tone Byte-Format #
; # oooTTTTT: o = octave tr. (0-7), T = tone (0-31) #
; # #
; # Tones #
; # 0-11 = Chromatic scale from C1 to B1 #
; # 20-31 = 5ths from G1 to F#1 (transposing at C) #
; # 12 = Bb1 (Bb) #
; # 13 = D1 (Bb Dm) #
; # 14 = F1 (Bb Dm F) #
; # 15 = A1 (Dm F Am) #
; # 0 = C1 (F Am C) #
; # 16 = E1 (Am C Em) #
; # 20 = G1 (C Em G) #
; # 17 = B1 (Em G Bm) #
; # 18 = D1 (G Bm) #
; # 19 = F#1 (Bm) #
; # #
; #######################################################
include synth\tuning.asm
; #######################################################
; # #
; # AY-3-8912 interface #
; # #
; #######################################################
; # #
; # AYdrv: #
; # a = AY-register #
; # b = Operation (1=IN, 2=OUT, 3=AND, 4=OR, 5=XOR) #
; # c = Data out #
; # ret d = Data in #
; # #
; # All other registers than D are preserved #
; # #
; #######################################################
AYdrv:
include synth\tiki100ay.asm
; #######################################################
; # #
; # Linear function plotter #
; # #
; #######################################################
include synth\linear.asm
Next step will be to make a music player or real-time sequencer that uses this in some way or another.