Sunsoft 5B audio: Difference between revisions
m (→Audio Register Write ($E000): rename register to reflect mirroring) |
(Move Disch's notes on sound emulation from iNES Mapper 069) |
||
Line 131: | Line 131: | ||
The tone channels each produce a 5-bit signal which is then converted to analog with a logarithmic DAC. (The AY-3-8190 is a 4-bit signal, but with a similar conversion.) | The tone channels each produce a 5-bit signal which is then converted to analog with a logarithmic DAC. (The AY-3-8190 is a 4-bit signal, but with a similar conversion.) | ||
== Disch's Notes == | |||
Sound: | |||
--------------------------- | |||
Sunsoft 5B appears to be identical to the AY 3-8910 (or a similar chip -- possibly a different AY 3-891x or a | |||
YM2149). The only game to use the sound, Gimmick!, does not use the envelope or noise functionality that | |||
exists on the AY 3-891x, however, through testing it has been shown that such functionality does in fact | |||
exist. | |||
The sound info below is a simplified version of the behavior. Envelope and Noise are not covered (aside from | |||
the noise shift formula), and registers relating to those areas are not mentioned. However the information | |||
below is enough to satisfy Gimmick! If you want further information and full register descriptions, consult | |||
an AY 3-8910 datasheet or doc. | |||
Sunsoft 5B has 3 Square channels (no configurable duty cycle -- always play at 50% duty). Each operate | |||
similarly to the native NES sound channels. They output sound at 1 octave lower than what may be expected, | |||
though (see below). | |||
Sound Regs: | |||
--------------------------- | |||
$C000: [.... AAAA] Address for use with $E000 | |||
$E000: [DDDD DDDD] Data port: | |||
R:0 -> [FFFF FFFF] Chan 0, Low 8 bits of Freq | |||
R:1 -> [.... FFFF] Chan 0, High 4 bits of Freq | |||
R:2 -> [FFFF FFFF] Chan 1, Low 8 bits of Freq | |||
R:3 -> [.... FFFF] Chan 1, High 4 bits of Freq | |||
R:4 -> [FFFF FFFF] Chan 2, Low 8 bits of Freq | |||
R:5 -> [.... FFFF] Chan 2, High 4 bits of Freq | |||
R:7 -> [.... .CBA] Channel disable flags (0=enabled, 1=disabled) | |||
C = Disable Chan 2 | |||
B = Disable Chan 1 | |||
A = Disable Chan 0 | |||
R:8 -> [.... VVVV] Chan 0, Volume | |||
R:9 -> [.... VVVV] Chan 1, Volume | |||
R:A -> [.... VVVV] Chan 2, Volume | |||
Operation: | |||
--------------------------- | |||
For tone generation, a counter is counted up each CPU cycle. When it reaches the given 'F' value, it resets | |||
to zero, and another step through the duty cycle is taken. These squares' duty cycles are fixed at 50% | |||
(AY 3-8910 docs say 8/16, but see below). | |||
Emulating in this fashion, with a 16-step duty, these channels play 1 octave higher than they should! | |||
Therefore, either channels are only clocked every other CPU cycle... or (what I find to be easiest to | |||
emulate) the duty is actually 16/32 instead of 8/16, or something else is going on. I do not know which is | |||
actually happening. | |||
The generated tone in Hz can be calculated with the following: | |||
CPU_CLOCK | |||
Hz = ------------- | |||
(F+1) * 32 | |||
When the duty cycle outputs high, 'V' is output, otherwise 0 is output. When the channel is disabled (see | |||
R:7), 0 is forced as output for the channel. | |||
Non-linear volume: | |||
--------------------------- | |||
Output volume is non-linear... increasing in steps of 3 dB. | |||
Output can be calculated with the following pseudo-code: | |||
vol = 1.0; | |||
for(i = 0; i < 0x10; ++i) | |||
{ | |||
sunsoft_out[i] = vol * base; | |||
vol *= step; | |||
} | |||
Where 'base' can be adjusted to match your native NES sound channel levels, and 'step' is "10^(dB/20)". | |||
For 3 dB, 'step' would be ~1.4125 | |||
Noise Formula: | |||
--------------------------- | |||
>> >> | |||
+-->[nnnn nnnn nnnn nnnn]->output | |||
| | | | |||
| | ++ | |||
| | | | |||
| v v | |||
+-------------------XOR | |||
- 16-bit right-shift reg | |||
- bits 0,3 (before shift) XOR to create new input bit | |||
- bit 0 is shifted to output | |||
- initial feed is 1 | |||
== References == | == References == | ||
* YM2149 datasheet: [http://pdf1.alldatasheet.com/datasheet-pdf/view/103366/ETC/YM2149.html http://pdf1.alldatasheet.com/datasheet-pdf/view/103366/ETC/YM2149.html] | * YM2149 datasheet: [http://pdf1.alldatasheet.com/datasheet-pdf/view/103366/ETC/YM2149.html http://pdf1.alldatasheet.com/datasheet-pdf/view/103366/ETC/YM2149.html] | ||
* GI AY-3-8910 datasheet: [http://www.speccy.org/hardware/datasheet/ay38910.pdf http://www.speccy.org/hardware/datasheet/ay38910.pdf] | * GI AY-3-8910 datasheet: [http://www.speccy.org/hardware/datasheet/ay38910.pdf http://www.speccy.org/hardware/datasheet/ay38910.pdf] |
Revision as of 05:54, 6 May 2013
The Sunsoft 5B is a superset of the Sunsoft FME-7. It is identical to the FME-7 except it contains extra audio hardware. This audio hardware was only used in one game, Gimmick! Because this game did not use many features of the chip (e.g. noise, envelope), its features are often only partially implemented by emulators.
Registers
The audio hardware is a type of Yamaha YM2149F, which is itself a variant of the General Instrument AY-3-8910 PSG.
Audio Register Select ($C000-$DFFF)
7......0 ----RRRR ++++- The 4-bit internal register to select for use with $E000
Audio Register Write ($E000-$FFFF)
7......0 VVVVVVVV ++++++++- The 8-bit value to write to the internal register selected with $C000
Internal audio registers
The YM2149F has 16 internal audio registers, selected with $C000 and written to with $E000.
Register | Bitfield | Description |
---|---|---|
$00 | LLLL LLLL | Channel A low period |
$01 | ---- HHHH | Channel A high period |
$02 | LLLL LLLL | Channel B low period |
$03 | ---- HHHH | Channel B high period |
$04 | LLLL LLLL | Channel C low period |
$05 | ---- HHHH | Channel C high period |
$06 | ---P PPPP | Noise period |
$07 | --CB Acba | Noise disable on channels C/B/A, Tone disable on channels c/b/a |
$08 | ---E VVVV | Channel A envelope enable (E), volume (V) |
$09 | ---E VVVV | Channel B envelope enable (E), volume (V) |
$0A | ---E VVVV | Channel C envelope enable (E), volume (V) |
$0B | LLLL LLLL | Envelope low period |
$0C | HHHH HHHH | Envelope high period |
$0D | ---- CAaH | Envelope reset and shape: continue (C), attack (A), alternate (a), hold (H) |
$0E | ---- ---- | I/O port A (unused) |
$0F | ---- ---- | I/O port B (unused) |
Sound
There are three channels that output a square wave tone. In addition there is one noise generator, and one envelope generator, both of which may be shared by any of the three channels.
The 5B's audio is driven by the CPU clock (1.78977267 MHz), but like the NES's APU, the YM2149F has an optional clock divider which halves the internal clock speed. By comparison of the produced pitches in Gimmick! with the register values used, it appears that the 5B is a YM2149F operating in this mode. To use an AY-3-8910 as a substitute, you would need an external divider to reduce the clock speed by half.
The frequency formulas given below assume the standard 1.78977267 MHz as the Clock value; note that each formula includes an additional divide by 2 to compensate for the YM2149F's internal divider.
Tone
The tone generators produce a square wave with a period controlled by the CPU clock and the 12-bit period value in registers $00-05.
- Frequency = Clock / (2 * 16 * Period)
- Period = Clock / (2 * 16 * Frequency)
Register $07 controls the mixing of tone and noise components of each channel. A bit of 0 enables the noise/tone on the specified channel, and a bit of 1 disables it. If both bits are 1, the channel outputs a constant signal at the specified volume. If both bits are 0, the result is the logical and of noise and tone.
If bit 4 of registers $08-$0A is set, the volume of the channel is controlled by the envelope generator. Otherwise, it is controlled by the 4-bit value in bits 3-0 of the same register.
Noise
The noise generator produces a 1-bit random wave with a period controlled by the CPU clock and the 5-bit period value in register $06.
- Frequency = Clock / (2 * 16 * Period)
- Period = Clock / (2 * 16 * Frequency)
Envelope
The envelope produces a ramp that can be directed up or down, or to oscillate by various shape parameters.
Period
The ramp has a frequency controlled by the CPU clock and the 16-bit period value in registers $0B-0C. Note this formula is the frequency of a single ramp, and not individual steps in it.
- Frequency = Clock / (2 * 256 * Period)
- Period = Clock / (2 * 256 * Frequency)
The YM2149F subdivides divides each ramp into 32 steps. Note that where alternating envelope shapes are used (triangle wave), the resulting pitch of the envelope is one octave down, since one wave cycle requires two ramps (up and down). Because the envelope is primarily intended for low (sub-audio) frequencies, its pitch control is not as accurate in audio frequency ranges as the tone channels.
The AY-3-8910 instead subdivides the ramp frequency by 16, and as a result has half the resolution for its envelopes. Because they both subdivide the same ramp frequency, the ramp's pitch will be the same as long as the clock speeds are equivalent.
Shape
Writing register $0D resets the envelope and chooses its shape. The shape has four parameters: continue, attack, alternate, and hold.
- Continue specifies whether the envelope continues to oscillate after the attack. If it is 0, the alternate and hold parameters have no effect.
- Attack specifies whether the attack goes from high to low (0) or low to high (1).
- Alternate specifies whether the signal continues to alternate up and down after the attack. If combined with hold it provides an immediate flip after the attack followed by the hold.
- Hold specifies that the value shall be held after the attack. If combined with alternate, the value at the end of the attack will be immediately flipped before holding.
Value | Continue | Attack | Alternate | Hold | Shape |
---|---|---|---|---|---|
$00 - $03 | 0 | 0 | x | x | \_______ |
$04 - $07 | 0 | 1 | x | x | /_______ |
$08 | 1 | 0 | 0 | 0 | \\\\\\\\ |
$09 | 1 | 0 | 0 | 1 | \_______ |
$0A | 1 | 0 | 1 | 0 | \/\/\/\/ |
$0B | 1 | 0 | 1 | 1 | \¯¯¯¯¯¯¯ |
$0C | 1 | 1 | 0 | 0 | //////// |
$0D | 1 | 1 | 0 | 1 | /¯¯¯¯¯¯¯ |
$0E | 1 | 1 | 1 | 0 | /\/\/\/\ |
$0F | 1 | 1 | 1 | 1 | /_______ |
Output
The tone channels each produce a 5-bit signal which is then converted to analog with a logarithmic DAC. (The AY-3-8190 is a 4-bit signal, but with a similar conversion.)
Disch's Notes
Sound: --------------------------- Sunsoft 5B appears to be identical to the AY 3-8910 (or a similar chip -- possibly a different AY 3-891x or a YM2149). The only game to use the sound, Gimmick!, does not use the envelope or noise functionality that exists on the AY 3-891x, however, through testing it has been shown that such functionality does in fact exist. The sound info below is a simplified version of the behavior. Envelope and Noise are not covered (aside from the noise shift formula), and registers relating to those areas are not mentioned. However the information below is enough to satisfy Gimmick! If you want further information and full register descriptions, consult an AY 3-8910 datasheet or doc. Sunsoft 5B has 3 Square channels (no configurable duty cycle -- always play at 50% duty). Each operate similarly to the native NES sound channels. They output sound at 1 octave lower than what may be expected, though (see below). Sound Regs: --------------------------- $C000: [.... AAAA] Address for use with $E000 $E000: [DDDD DDDD] Data port: R:0 -> [FFFF FFFF] Chan 0, Low 8 bits of Freq R:1 -> [.... FFFF] Chan 0, High 4 bits of Freq R:2 -> [FFFF FFFF] Chan 1, Low 8 bits of Freq R:3 -> [.... FFFF] Chan 1, High 4 bits of Freq R:4 -> [FFFF FFFF] Chan 2, Low 8 bits of Freq R:5 -> [.... FFFF] Chan 2, High 4 bits of Freq R:7 -> [.... .CBA] Channel disable flags (0=enabled, 1=disabled) C = Disable Chan 2 B = Disable Chan 1 A = Disable Chan 0 R:8 -> [.... VVVV] Chan 0, Volume R:9 -> [.... VVVV] Chan 1, Volume R:A -> [.... VVVV] Chan 2, Volume Operation: --------------------------- For tone generation, a counter is counted up each CPU cycle. When it reaches the given 'F' value, it resets to zero, and another step through the duty cycle is taken. These squares' duty cycles are fixed at 50% (AY 3-8910 docs say 8/16, but see below). Emulating in this fashion, with a 16-step duty, these channels play 1 octave higher than they should! Therefore, either channels are only clocked every other CPU cycle... or (what I find to be easiest to emulate) the duty is actually 16/32 instead of 8/16, or something else is going on. I do not know which is actually happening. The generated tone in Hz can be calculated with the following: CPU_CLOCK Hz = ------------- (F+1) * 32 When the duty cycle outputs high, 'V' is output, otherwise 0 is output. When the channel is disabled (see R:7), 0 is forced as output for the channel. Non-linear volume: --------------------------- Output volume is non-linear... increasing in steps of 3 dB. Output can be calculated with the following pseudo-code: vol = 1.0; for(i = 0; i < 0x10; ++i) { sunsoft_out[i] = vol * base; vol *= step; } Where 'base' can be adjusted to match your native NES sound channel levels, and 'step' is "10^(dB/20)". For 3 dB, 'step' would be ~1.4125 Noise Formula: --------------------------- >> >> +-->[nnnn nnnn nnnn nnnn]->output | | | | | ++ | | | | v v +-------------------XOR - 16-bit right-shift reg - bits 0,3 (before shift) XOR to create new input bit - bit 0 is shifted to output - initial feed is 1
References
- YM2149 datasheet: http://pdf1.alldatasheet.com/datasheet-pdf/view/103366/ETC/YM2149.html
- GI AY-3-8910 datasheet: http://www.speccy.org/hardware/datasheet/ay38910.pdf