User Tools

Site Tools


The Versatile Interface Adaptor (VIA) 6522

The AY-3-8912 Sound Chip

The Sound Chip inside the Oric is the AY-3-8912. This was a very popular sound chip back in the early 80's which was used in the Intellivision, Vectrex, MSX, Colour-Genie, Sinclair Spectrum 128/+2/+3, Amstrad CPC and Atari-ST.

The hardware consists of an 8 bit bus which is connected (on the Oric) to Port A of the VIA 6522 Chip. This appears at location $030F in the Oric memory map and for labeling conventions known as via_porta.

Port A also appears as the Printer Port which was also used for many Joystick Interfaces.

The 8-Bit bus may hold the AY Register number, AY Register Write, AY Register Read or Inactive/Disabled depending on the states of the two control lines. These control lines are known as CA2/CB2 in the VIA 6522 and BC1/BDIR on the AY-3-8912.

CA2CB2AY Data State
01Write AY Register Data
10Read AY Register Data
11Write AY Register Number

CA2/CB2 logic levels may be set in the Peripheral Control Register or via_pcr at location $030C.

The VIA 6522 Peripheral Control Register($030C)

0CA1 Control
1-3CA2 Control
4CB1 Control
5-7CB2 Control

CA2/CB2 Field Values

Bit PatternOperationEffective Output
000Input Negative Active Edge1
001Independant Interrupt Input Negative Active Edge1
010Input Positive Active Edge1
011Independant Interrupt Input Positive Active Edge1
100Handshake Output-
101Pulse Output(Pulse Mode)-
110Low Output0
111High Output1

For simple programming of these lines, only modes 110 and 111 will ever be used.

The AY expects the Register to be selected before any data is is sent to it. It remembers the last Register selected to know where to put the data.

So to write a Value to an AY register, we would use the following code.

        ;First place the register number onto VIA Port A
        LDA AYRegisterNumber
        STA via_porta
        ;Then set control lines to Register Number state
        LDA #ayc_Register
        STA via_pcr
        ;We have to set control lines to Inactive after
        LDA #ayc_Inactive
        STA via_pcr
        ;Before we place the Register data on the bus
        LDA AYRegisterValue
        STA via_porta
        ;The set control lines to Register Data State
        LDA #ayc_Write
        STA via_pcr
        ;And finally set control lines inactive again
        LDA #ayc_Inactive
        STA via_pcr

There are some ways we can optimise this code, both in the code itself and also through the way we access the control lines. See advanced_ay_access for the latter.

By using the X register we can reduce the lines by one row..

        ;First place the register number onto VIA Port A
        LDA AYRegisterNumber
        STA via_porta
        ;Then set control lines to Register Number state
        LDA #ayc_Register
        STA via_pcr
        ;We have to set control lines to Inactive after
        LDX #ayc_Inactive
        STX via_pcr
        ;Before we place the Register data on the bus
        LDA AYRegisterValue
        STA via_porta
        ;The set control lines to Register Data State
        LDA #ayc_Write
        STA via_pcr
        ;And finally set control lines inactive again
        STX via_pcr

The AY Sound Chip Registers

The AY-3-8912 Sound Chip contains 15 Registers which are usually numbered from 0 to E (Hexadecimal).

AY-3-8912 Register Array
0Channel A Tone Period LSBB7B6B5B4B3B2B1B0
1Channel A Tone Period MSB B11B10B9B8
2Channel B Tone Period LSBB7B6B5B4B3B2B1B0
3Channel B Tone Period MSB B11B10B9B8
4Channel C Tone Period LSBB7B6B5B4B3B2B1B0
5Channel C Tone Period MSB B11B10B9B8
6Noise Period B4B3B2B1B0
7Status Register IOANsCNsBNsATnCTnBTnA
8Channel A Amplitude EGB3B2B1B0
9Channel B Amplitude EGB3B2B1B0
AChannel C Amplitude EGB3B2B1B0
BEnvelope Period LSBB7B6B5B4B3B2B1B0
CEnvelope Period MSBB7B6B5B4B3B2B1B0
DEnvelope Cycle CntAttAltHld
EI/O Port A(Key Column)B7B6B5B4B3B2B1B0

Whilst the EG has limited use in monostable (single shot) mode when set to Bistable a limited range of very low Periods permit the EG to become a waveform generator to produce Sawtooth and Triangle waveforms. When mixed with a chip channel the EG can produce some interesting sounds best suited to Bass sounds.

The range of notes available when using the EG in this way is shown in the next diagram. Each Note corresponds to the BASIC MUSIC octave, however the actual frequency has also been provided for reference.

NoteTriangle Envelope PeriodSawtooth Envelope PeriodFrequency (Herz)
D#1 2577.71
F#1 2192.41
G#1 19103.7
A-19 18109.9
A#1 17116.4
B-18 16123.3
C-2 15130.7
C#27 14138.4
D-2 13146.7
D#2 155.4
E-26 12164.6
F-2 11174.4
F#2 184.8
G-25 10195.8
G#2 207.4
A-2 9219.8
A#2 232.8
B-24 8246.7
C-3 261.4
C#3 7 276.9
D-3 293.4
D#3 310.8
E-33 6329.3
F-3 348.9
F#3 369.6
G-3 5 391.6
G#3 414.9
A-3 439.6
A#3 465.7
B-32 4493.4
C-4 522.8
C#4 553.8
D-4 586.8
D#4 621.7
E-4 3 658.6
F-4 697.8
F#4 739.3
G-4 783.3
G#4 829.8
A-4 879.2
A#4 931.5
B-41 2986.9
C-5 1045
C#5 1107
D-5 1173
D#5 1243
E-5 1317
F-5 1395
F#5 1478
G-5 1566
G#5 1659
A-5 1758
A#5 1863
B-5 11973

Pitch Registers 0-5

These registers provide 3 channels of Tone.

Each channel has a 12 bit Counter which provides enough resolution to produce smooth pitch bend between notes.

The lower the counter value the higher the frequency.

There are two methods to convert a musical note to pitch.

Lookup Table

The first is to create a 12bit lookup table whose length corresponds to the number of notes required. This has the distinct advantage of consuming the least number of cycles to translate.

However altering the base frequency for tuning purposes is more difficult since any adjustment to the whole table will not be as accurate at higher frequencies.

For 96 notes (8 Octaves) a 192 byte table is required.

Note that this technique was used in Sonix 3.2

The code is included below and is based on 96 notes.

        LDX note
        LDA Pitch_lo,X
        STA ay_Pitch_A_Low
        LDA Pitch_hi,X
        STA ay_Pitch_A_High

Base Table

The other method is to create a 12bit 12 entry table whose length corresponds to the 12 notes within a single octave(Octave Zero). The other octaves can be located by shifting the table down through code.

This has the advantage of using less bytes(and the same number of bytes regardless the number of notes) but uses more cpu cycles.

Altering the base frequency for tuning purposes is also easier since we adjust just the 12 values.

Note this technique was used in Sonix version 3.42 and 4.00

The code is included below

        LDA note
        ;Convert Large Note to Octave(X) and 12 value Note(A) (Divide by 12)
        LDX #255
  loop1 INX
        SBC #12
        BCS loop1
        ADC #12
        ;Fetch 12 Bit Base Note
        LDA base_pitch_lo,Y
        STA ay_Pitch_A_Low
        LDA base_pitch_hi,Y
        ;Finish if Octave Zero
        CPX #00
        BEQ finish
        ;Shift up for Octave
  loop2 LSR
        ROR ay_Pitch_A_Low
        BNE loop2
        STA ay_Pitch_A_High
   .byt $ee,$16,$4c,$8e,$d8,$2e,$8e,$f6,$66,$e0,$60,$e8
   .byt $0e,$0e,$0d,$0c,$0b,$0b,$0a,$09,$09,$08,$08,$07

Noise Register 6

The AY-3-8912 contains a single Noise Generator whose pulsewidth may be adjusted from 0(Tinny) to 31(Bassy).

Status Register 7

The Status Register holds a number of flags that control the link between Tone and Noise Generators to the A/D converters (Volume Registers). The Status Register also has a Data Direction Flag in Bit 6 (IOA) which should be kept set to set the Key Column register to output.

TnA,TnB and TnC correspond to Tone Channels A,B and C. When each bit is reset the corresponding Tone Period Generator is fed to the Volume Register.

NsA,NsB and NsC correspond to Channels A,B and C. When each bit is reset the Noise Generators output is attached to the corresponding Volume Register.

Amplitude(Volume) Control Registers 8,9,A

The Volume registers provide a control over the volume of the corresponding tone generators and Noise Generator.

The Volume may be controlled through software using the 4 lower bits of each register (Resetting Bit 4). Alternatively volume control may be passed to the Envelope generator by setting Bit 4 of the corresponding Volume Register.

Volume on the AY-3-8912 follows a Logarithmic scale. This means the difference in volume levels between 1 and 2 will sound very different to 14 and 15.

Note, Some Music on other machines such as the Spectrum 128K limited the volume to below 8 in order to achieve greater suttlety with volume levels.

Envelope Generator (EG) Period and Control Registers B,C,D

There is just one Envelope Generator. So it has limited use when used in a melody. The Period Registers form a 16 bit value that defines the time between each successive volume step of the chosen waveform cycle.

The Envelope Cycle Register Sets the shape of the Volume Envelope. Each bit defines a particular attribute of the envelope which uses a very simplified ADSR formation. The table below illustrates only the values that correspond to unique envelope shapes.

Cycle BitsValue(Decimal)CycleEnvelope ShapeWaveform name
10008BistableHigh Slope Low Repeating)Sawtooth
10019MonostableHigh Slope Low
101010BistableHigh Slope Low Slope High RepeatingTriangle
101111MonostableHigh Slope Low then High
110012BistableLow Slope High RepeatingSawtooth
110113MonostableLow Slope High
111014BistableLow Slope High Slope Low RepeatingTriangle
111115MonostableLow Slope High then Low

I/O Port A (Key Column Register)

oric/hardware/the_via_and_ay-3-8912.txt · Last modified: 2008/03/28 23:41 by twilighte