Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision Next revision Both sides next revision | ||
8bit_chiptune:sn76489 [2019/11/19 15:34] admin |
8bit_chiptune:sn76489 [2019/11/19 15:58] admin [5. How the SN76489 makes sound] |
||
---|---|---|---|
Line 1: | Line 1: | ||
===== SN76489 notes ===== | ===== SN76489 notes ===== | ||
- | [[https:// | + | taken from [[https:// |
This is a document to clear up a few inaccuracies regarding this chip | This is a document to clear up a few inaccuracies regarding this chip | ||
- | (existing inaccuracies are mentioned in particular, usually marked | + | (existing inaccuracies are mentioned in particular, usually marked), and also to document everything there is to know about |
- | > like this <), and also to document everything there is to know about | + | |
it. | it. | ||
Line 11: | Line 10: | ||
I won't know about it - unless you can run tests for me. | I won't know about it - unless you can run tests for me. | ||
- | + | ---- | |
- | ==== Contents ==== | + | ==== 1. conventions |
- | + | ||
- | 1. Conventions | + | |
- | 2. SN76489 signings | + | |
- | 3. Accessing the SN76489 from software | + | |
- | 4. SN76489 registers | + | |
- | 4.1 SN76489 register writes | + | |
- | 5. How the SN76489 makes sound | + | |
- | 5.1 Tone channels | + | |
- | 5.2 Noise channel | + | |
- | 5.2.1 The Linear Feedback Shift Register | + | |
- | 5.2.2 The 15-bit shift register | + | |
- | 5.2.3 An implementation of the noise shift register | + | |
- | 5.3 Volume/ | + | |
- | 6. The imperfect SN76489 | + | |
- | 6.1 Noise volume | + | |
- | 7. Playing samples on the SN76489 | + | |
- | 8. Game Gear stereo extension | + | |
- | + | ||
- | + | ||
- | ==== 1. Conventions | + | |
Binary numbers are denoted by a leading " | Binary numbers are denoted by a leading " | ||
Line 67: | Line 46: | ||
- | 3. Accessing the SN76489 from software | + | ==== 3. Accessing the SN76489 from software ==== |
- | ====================================== | + | |
The SN76489 has an 8-bit write-only data bus, so it is controlled in | The SN76489 has an 8-bit write-only data bus, so it is controlled in | ||
software by writing bytes to it. How this is done depends on the system. | software by writing bytes to it. How this is done depends on the system. | ||
- | Sega Game 1000 (SG-1000) | + | - Sega Game 1000 (SG-1000)\\ |
- | Sega Computer 3000 (SC-3000) | + | - Sega Computer 3000 (SC-3000)\\ |
- | Sega Master System (SMS) | + | - Sega Master System (SMS)\\ |
- | Sega Game Gear (GG) | + | - Sega Game Gear (GG)\\ |
- | Sega Mega Drive/ | + | - Sega Mega Drive/ |
- | The SN76489 can be accessed by writing to any I/O port between 0x40 | + | The SN76489 can be accessed by writing to any I/O port between 0x40 and 0x7f, although officially only 0x7f was recommended. A few games write to 0x7e. |
- | | + | - Sega Mega Drive/ |
- | | + | The SN76489is memory-mapped to the 68000 CPU at location 0xc00011, and the Z80 CPU at 0x7f11.\\ |
- | + | - ColecoVision\\ | |
- | Sega Mega Drive/ | + | - Coleco Adam?\\ |
- | The SN76489is memory-mapped to the 68000 CPU at location 0xc00011, and | + | The SN76489 is mapped to I/O port $ff.\\ |
- | | + | |
- | + | ||
- | ColecoVision | + | |
- | Coleco Adam? | + | |
- | The SN76489 is mapped to I/O port $ff. | + | |
- | + | ||
- | Other systems | + | |
- | Let me know :) | + | |
- | 4. SN76489 registers | + | ==== 4. SN76489 registers ==== |
- | ==================== | + | |
The SN76489 has 8 " | The SN76489 has 8 " | ||
Line 102: | Line 71: | ||
- | Channel | + | Channel |
- | 0 (%00) Vol0 | + | 0 (%00) -------- |
- | 1 (%01) Vol1 | + | 1 (%01) -------- |
- | 2 (%10) Vol2 | + | 2 (%10) -------- |
- | 3 (%11) Vol3 | + | 3 (%11) -------- |
- | Volume registers: | + | Volume registers:\\ |
- | The value represents the attenuation of the output. Hence, %0000 is | + | The value represents the attenuation of the output. Hence, %0000 is full volume and %1111 is silence. |
- | | + | |
- | Tone registers: | + | Tone registers:\\ |
- | These give a counter reset value for the tone generators. Hence, low | + | These give a counter reset value for the tone generators. Hence, low values give high frequencies and vice versa. |
- | | + | |
- | Noise register: | + | Noise register:\\ |
- | One bit selects the mode (" | + | One bit selects the mode (" |
- | | + | |
- | It appears the initial state of these registers depends on the hardware: | + | It appears the initial state of these registers depends on the hardware:\\ |
- | - Discrete chips seem to start with random values (an SC-3000 is | + | - Discrete chips seem to start with random values (an SC-3000 is reported to start with a tone before the chip is written to by the software).\\ |
- | | + | - The Sega integrated versions seem to start initialised with zeroes in the tone/noise registers and ones in the volume registers (silence).\\ |
- | | + | |
- | - The Sega integrated versions seem to start initialised with zeroes in | + | |
- | | + | |
- | 4.1 SN76489 register writes | + | ==== 4.1 SN76489 register writes ==== |
- | =========================== | + | |
- | When a byte is written to the SN76489, it processes it as follows: | + | When a byte is written to the SN76489, it processes it as follows:\\ |
- | If bit 7 is 1 then the byte is a LATCH/DATA byte. | + | If bit 7 is 1 then the byte is a LATCH/DATA byte.\\ |
%1cctdddd | %1cctdddd | ||
Line 142: | Line 104: | ||
``------- Channel | ``------- Channel | ||
- | | + | Bits 6 and 5 (" |
- | | + | |
- | | + | |
- | | + | The remaining 4 bits (" |
- | | + | ** The latched register is NEVER cleared by a data byte.** |
- | | + | |
- | + | ||
- | > The latched register is NEVER cleared by a data byte. < | + | |
If bit 7 is 0 then the byte is a DATA byte. | If bit 7 is 0 then the byte is a DATA byte. | ||
Line 158: | Line 115: | ||
`-------- Unused | `-------- Unused | ||
- | | + | If the currently latched register is a tone register then the low 6 bits of the byte are placed into the high 6 bits of the latched register. If the latched register is less than 6 bits wide, high bits are discarded.\\ |
- | | + | |
- | | + | |
- | | + | |
The data have the following meanings (described more fully later): | The data have the following meanings (described more fully later): | ||
- | Tone registers: | + | Tone registers: |
- | ddddDDDDDD gives the 10-bit half-wave counter reset value. | + | ddddDDDDDD gives the 10-bit half-wave counter reset value.\\ |
- | + | ||
- | Volume registers: | + | |
- | dddd gives the 4-bit volume value. | + | |
- | If a data byte is written, the low 4 bits of DDDDDD update the 4-bit | + | |
- | volume value. However, this is unnecessary. | + | |
- | Noise register: dddd(DDDDDD) = -trr(---trr) | + | Volume registers: dddd(DDDDDD) = vvvv(--vvvv)\\ |
- | The low 2 bits of dddd select | + | dddd gives the 4-bit volume value.\\ |
- | (bit 2) selects the mode (white (1) or " | + | If a data byte is written, |
- | If a data byte is written, | + | |
- | mode in the same way. | + | |
+ | Noise register: | ||
+ | The low 2 bits of dddd select the shift rate and the next highest bit (bit 2) selects the mode (white (1) or " | ||
This means that the following data will have the following effect | This means that the following data will have the following effect | ||
- | (spacing added for clarity, hopefully): | + | (spacing added for clarity, hopefully):\\ |
- | 1. %1 00 0 1110 Latch, channel 0, tone, data %1110 | + | **1.** %1 00 0 1110 Latch, channel 0, tone, data %1110\\ |
- | | + | %0 0 001111 |
- | | + | Set channel 0 tone to %0011111110 = 0xfe (440Hz @ 35976545Hz clock)\\ |
- | 2. %1 01 1 1111 Latch, channel 1, volume, data %1111 | + | **2.** %1 01 1 1111 Latch, channel 1, volume, data %1111\\ |
- | | + | Set channel 1 volume to %1111 = 0xf (silent)\\ |
- | 3. %1 10 1 1111 Latch, channel 2, volume, data %1111 | + | **3.** %1 10 1 1111 Latch, channel 2, volume, data %1111\\ |
- | | + | %0 0 000000 |
- | | + | Set channel 2 volume to %1111 = 0xf (silent)\\ |
- | | + | THEN update it to %0000 = 0x0 (full)\\ |
- | > The data byte is NOT ignored. | + | **The data byte is NOT ignored.**\\ |
- | 4. %1 11 0 0101 Latch, channel 3, noise, data %0101 | + | **4.** %1 11 0 0101 Latch, channel 3, noise, data %0101\\ |
- | | + | Set noise register to %101 (white noise, medium shift rate)\\ |
- | 5. %1 11 0 0101 Latch, channel 3, noise, data %0101 | + | **5.** %1 11 0 0101 Latch, channel 3, noise, data %0101\\ |
- | | + | %0 0 000100 |
- | | + | Set noise register to %101 (white noise, medium shift rate)\\ |
- | | + | THEN update it to %100 (white noise, high shift rate)\\ |
- | > The data byte is NOT ignored. | + | ** The data byte is NOT ignored.** |
- | Numbers 1, 2 and 4 above are the same as is described in the various | + | Numbers 1, 2 and 4 above are the same as is described in the various existing docs. |
- | existing docs. | + | |
Number 3 IS USED - when pausing between text boxes in SMS Alex Kidd in | Number 3 IS USED - when pausing between text boxes in SMS Alex Kidd in | ||
Line 222: | Line 170: | ||
Many games also produce the above two unusual behaviours but not | Many games also produce the above two unusual behaviours but not | ||
repeatedly (often when a SFX is first played, for example). | repeatedly (often when a SFX is first played, for example). | ||
- | |||
Also of note is that the tone registers update immediately when a byte | Also of note is that the tone registers update immediately when a byte | ||
Line 233: | Line 180: | ||
%0 0 111111 | %0 0 111111 | ||
- | There were a couple of ways to handle SN76489 writes before: | + | There were a couple of ways to handle SN76489 writes before:\\ |
- | + | **1.** Latch only the tone registers, as above, and leave them latched when other types of data (volume, noise) are written. This gives a " | |
- | 1. Latch only the tone registers, as above, and leave them latched when | + | |
- | other types of data (volume, noise) are written. This gives a | + | |
- | " | + | |
- | the " | + | |
- | + | ||
- | 2. Latch tone registers as above, and " | + | |
- | data are written. When a data byte is written with it unlatched, the | + | |
- | data is discarded. This fixes the " | + | |
+ | **2.** Latch tone registers as above, and " | ||
- | 5. How the SN76489 makes sound | + | ---- |
- | ============================== | + | ==== 5. How the SN76489 makes sound ==== |
This is already well documented, but I'll repeat it again with | This is already well documented, but I'll repeat it again with | ||
Line 265: | Line 205: | ||
decremented, | decremented, | ||
- | 5.1 Tone channels | + | === 5.1 Tone channels === |
- | ================= | + | |
The counter is reset to the value currently in the corresponding | The counter is reset to the value currently in the corresponding | ||
Line 288: | Line 227: | ||
This is often used for sample playback on the SN76489. | This is often used for sample playback on the SN76489. | ||
- | 5.2 Noise channel | + | === 5.2 Noise channel === |
- | ================= | + | |
The counter is reset according to the low 2 bits of the noise register | The counter is reset according to the low 2 bits of the noise register | ||
Line 305: | Line 243: | ||
shift register" | shift register" | ||
- | 5.2.1 The Linear Feedback Shift Register | + | === 5.2.1 The Linear Feedback Shift Register === |
- | ======================================== | + | |
The LFSR is an array of either 15 or 16 bits, depending on the chip | The LFSR is an array of either 15 or 16 bits, depending on the chip | ||
Line 333: | Line 270: | ||
For white noise (Noise register bit 2 = 1): | For white noise (Noise register bit 2 = 1): | ||
- | | + | - For the SMS (1 and 2), Genesis and Game Gear, the tapped bits are bits 0 and 3. For the SC-3000H, the tapped bits are bits 1 and 2. For the BBC Micro, using John Kortink' |
- | | + | |
- | | + | |
- | | + | |
- | | + | - I would like to confirm the bit pattern for other systems, please contact me if you can help by running/ |
- | | + | |
- | | + | |
- | | + | - Example (SMS/GG): |
| | ||
Line 358: | Line 290: | ||
For " | For " | ||
- | | + | - For the SMS, GG and Genesis, only bit 0 is tapped, ie. the output bit is also the input bit. The effect of this is to output the contents of the shift register in a 16-bit long loop. |
- | | + | |
- | | + | |
- | | + | - For the BBC Micro, bit 1 is tapped, giving a 15-bit long loop. |
- | | + | - Other systems need investigation. |
| | ||
Line 372: | Line 302: | ||
| | ||
- | Note that this " | + | Note that this " |
- | chip's documentation, | + | |
- | defined elsewhere (white noise with a configurable periodicity); | + | |
- | is a duty cycle modifier. For this reason, throughout this document | + | |
- | it is always referred to with quotes. | + | |
When the noise register is written to, the shift register is reset, | When the noise register is written to, the shift register is reset, | ||
Line 383: | Line 309: | ||
important as it affects the sound of white noise. | important as it affects the sound of white noise. | ||
- | 5.2.2 The 15-bit shift register | + | === 5.2.2 The 15-bit shift register === |
- | =============================== | + | |
The values given above are for using a 16-bit shift register. However, | The values given above are for using a 16-bit shift register. However, | ||
Line 400: | Line 325: | ||
- | 5.2.3 An implementation of the noise shift register | + | === 5.2.3 An implementation of the noise shift register === |
- | =================================================== | + | |
The method of generating white noise is the most fundamentally incorrect | The method of generating white noise is the most fundamentally incorrect | ||
Line 407: | Line 331: | ||
most common method is to do something like: | most common method is to do something like: | ||
- | #define WHITE_NOISE_FEEDBACK 0xf037 | + | #define WHITE_NOISE_FEEDBACK 0xf037 |
- | #define PERIODIC_NOISE_FEEDBACK 0x8000 | + | |
- | ... | + | |
- | ShiftRegister>> | + | |
- | ShiftRegister^=(WhiteNoise? | + | ShiftRegister>> |
- | Output=ShiftRegister& | + | |
+ | | ||
With the correct choice of periodic feedback parameter (depending on | With the correct choice of periodic feedback parameter (depending on | ||
Line 437: | Line 362: | ||
parity(): | parity(): | ||
- | int parity(int val) { | + | int parity(int val) { |
val^=val>> | val^=val>> | ||
val^=val>> | val^=val>> | ||
Line 443: | Line 368: | ||
val^=val>> | val^=val>> | ||
return val&1; | return val&1; | ||
- | }; | + | }; |
Thanks go to Dave (finaldave) for coming up with this. You may get | Thanks go to Dave (finaldave) for coming up with this. You may get | ||
Line 450: | Line 375: | ||
built-in parity checking instructions/ | built-in parity checking instructions/ | ||
- | 5.3 Volume/ | + | === 5.3 Volume/ |
- | ====================== | + | |
The mixer then multiplies each channel' | The mixer then multiplies each channel' | ||
Line 465: | Line 389: | ||
is defined as | is defined as | ||
- | | + | power 1 |
- | log ------- | + | |
- | power 2 | + | |
Whether it's positive or negative depends on which way around you put | Whether it's positive or negative depends on which way around you put | ||
Line 494: | Line 418: | ||
(voltage 2) | (voltage 2) | ||
- | Rearranging, | + | Rearranging, |
voltage 1 | voltage 1 | ||
Line 504: | Line 428: | ||
build an output table, for example: | build an output table, for example: | ||
- | int volume_table[16]={ | + | int volume_table[16]={ |
- | 32767, 26028, 20675, 16422, 13045, 10362, | + | 32767, 26028, 20675, 16422, 13045, 10362, |
- | | + | 5193, 4125, 3277, 2603, 2067, 1642, 1304, 0 |
- | }; | + | |
These correspond to volume register values 0x0 to 0xf, in that order. | These correspond to volume register values 0x0 to 0xf, in that order. | ||
Line 519: | Line 443: | ||
example. | example. | ||
- | + | ---- | |
- | 6. The imperfect SN76489 | + | ==== 6. The imperfect SN76489 ==== |
- | ======================== | + | |
Real components aren't perfect. The output of the SN76489 in its | Real components aren't perfect. The output of the SN76489 in its |