The POKEY module has a random number generator, six scan lines, eight potentiometer ports, three timers, a serial port and four audio channels.[2#1]
Hardware
The POKEY chip (C012294 (original), C012294-02 (dual-core) and C012294-04 (quad-core))[1§2] have 40 lines. These are:
- Pin 1: Vss: Ground[1§3] at 0V.
- Pins 2 - 6: D3, D4, D5, D6, D7: Data Bus I/O.[1§3]
- Pin 7: Ø2: Phase 2 Clock Input.[1§3]
- Pin 8 - 15: P6, P7, P4, P5, P2, P3, P0, P1: Potentiometer Scan.[1§3]
- Pin 16: KR2: Keyboard Row strobe Input.[1§3]
- Pin 17: Vcc: Power at 5V.[1§3]
- Pin 18 - 23: K5, K4, K3, K2, K1, K0: Keyboard Scan Output
- Pin 24: SID: Serial Input Data.[1§3]
- Pin 25: KR1: Keyboard Row strobe Input.[1§3]
- Pin 26: BCLK: Bi-directional Clock I/O.[1§3]
- Pin 27: ACLK: Serial Clock Output.[1§3]
- Pin 28: SOD: Serial Output Data.[1§3]
- Pin 29: IRQ: Interrupt Request Output.[1§3]
- Pin 30 - 31: CS0, CS1: Chip Select.[1§3]
- Pin 32: R/W: Read / Write I/O Control.[1§3]
- Pin 33 - 36: A3, A2, A1, A0: Memory Address Input.[1§3]
- Pin 37: AUD: Audio Output.[1§3]
- Pin 38 - 40: D0, D1, D2: Data Bus I/O.[1§3]
Software
Registers
The POKEY chip was accessible as a memory-mapped device. On Atari 8-bit computers it is mapped to the D2xx
page,[1§4] and on the Atari 5200 it is mapped to the E8xx
page.[1§4]. There are 29 registers,[1§4] each with a different function depending on whether it was read from or written to.[1§4] These are:
- Read
00
- 07
: POT0 - POT7:[1§4]
The "POT" (potentiometer) registers map to analog-to-digital converter ports.[1§6]
- Write
00
- 07
: (AUDF1, AUDC1) - (AUDF4, AUDC4):[1§4]
The AUDFx registers are for controlling audio frequency, containing the interval (in clock cycles) between successive cycles as an 8-bit integer from 1 to 256.[1§5.1]
The AUDCx registers are for controlling distortion and volume, or for playing PCM audio streams.[1§5.2] The bit-field is interpreted as follows:
- Bits
0
- 3
: Volume:
A four bit integer representing the volume of the channel,[1§5.2], presumably used as a multiplicative factor from 0 to 15. TODO: Test volume behaviour precisely.
- Bit
4
: Volume only?:
A boolean flag that determines the use of the Volume value.[1§5.2] If this flag is 0
, the Volume value will be used to modify the amplitude of the channel's waveform. If this flag is 1
, the Volume value will be used as the channel output,[1§5.2] which can be used to play PCM audio[1§5.2] at a sample rate limited by the speed at which the register is updated.TODO: Can this be tested?
- Bit
5
- 8
: Noise:
Settings for noise and distortion. According to Wikipedia, the settings are interpreted as follows:TODO: Is this correct? Test +> A0 & E0
| Noise Value | Bits Value | Description |
| ----------- | ---------- | ----------------------------- |
| 0 0 0 | $00 | 5-bit then 17-bit polynomials |
| 0 0 1 | $20 | 5-bit poly only |
| 0 1 0 | $40 | 5-bit then 4-bit polys |
| 0 1 1 | $60 | 5-bit poly only |
| 1 0 0 | $80 | 17-bit poly only |
| 1 0 1 | $A0 | no poly (pure tone) |
| 1 1 0 | $C0 | 4-bit poly only |
| 1 1 1 | $E0 | no poly (pure tone) |
- Read
08
: ALLPOT:[1§4]
A bit-field containing one bit per port. On POTGO, all bits are set to 1
; they are individually set to 0
when scanning is complete and their registers are ready to be read.[1§6.9]
- Write
08
: AUDCTL:[1§4]
A bit-field containing flags corresponding to the behaviour of the audio channels. The bit-field is interpreted as followed:
0
: Clock Base rate[2#2.2] / Frequency Divider rate:[1§5.3]
Determines the base clock speed for the audio channels. A value of 0
means 64kHz,[2#2.2][1§5.3] and a value of 1
means 15kHz.[2#2.2][1§5.3]
1
: High pass filter, channels 2 and 4?:[2#2.2][1§5.3]
If 1
, filters channel 2 based on base frequency of channel 4,[2#2.2] only allowing through frequencies higher than specified.[1§5.3] As explained by the Atari Pokey Data Sheet:
The high-pass filter consists of a D-type flip-flop and an exclusive-OR gate. The noise control circuit output is sampled by this flip flop at a rate set by the "high-pass" clock. The input and output of the flip-flop pass through the exclusive-OR gate. However, if it is lower than the clock rate, the flip-flop output will tend to follow the input and the two exclusive-OR gate inputs will mostly be identical (11 or 00) giving very little output. This gives the effect of a crude high-pass filter, passing only noise whose minimum frequency is set by the high-pass clock rate. Only channels 1 and 2 have such a high-pass filter. The high-pass clock for channel 1 comes from the channel 3 divider. The high-pass clock for channel 2 comes from the channel 4 divider.
2
: High pass filter, channels 1 and 3?:[2#2.2][1§5.3]
If 1
, filters channel 1 based on base frequency of channel 3,[2#2.2] only allowing through frequencies higher than specified.[1§5.3] See above for a detailed description of the behaviour.
3
: Connect channels 3 & 4?:[1§5.3]
If 1
, use channel 3 as channel 4's clock;[2#2.2] creates 16-bit channel.[1§5.3] TODO: The base of channel 3 or the signal?
4
: Connect channels 1 & 2?:[1§5.3]
If 1
, use channel 1 as channel 2's clock;[2#2.2] creates 16-bit channel.[1§5.3]
5
: Channel 3 clock[2#2.2] frequency:[1§5.3]
TODO: 1§5.3 & 2#2.2 contradict; test.
6
: Channel 3 clock[2#2.2] frequency:[1§5.3]
TODO: Ditto
7
: 17-bit / 9-bit poly?:[2#2.2][1§5.3]
Determines whether the internal 17-bit polynomial register is read as 9-bit.[2#2.2] If this flag is 0
, the register is read as 17-bit; if it is 1
the register is read as 9-bit.[1§5.3]
Interrupts
There are eight interrupts,[1§8] numbered 0
to 7
.[2#8] These are:
Interrupts are managed using the IRQEN register and read using IRQST.[2#8] To enable an interrupt, set the relevant bit of IRQEN to 1
; to disable it set the bit to 0
.[2#8] This register isn't initialised by default; this must be done before enabling processor IRQ to avoid undesired behaviour.[2#8] The IRQST register is initially full of 1
bits, and goes to 0
when the relevant interrupt is fired.[2#8] In order to reset a given bit of IRQST, the relevant bit of IRQEN must be (temporarily) set to 0
.[2#8] Note that this does not apply to bit 3
(XD); this bit of IRQST will be 0
when serial output is empty and 1
when it is not regardless of whether bit 3
of IRQEN is reset.