DOSBox-X
|
00001 // license:BSD-3-Clause 00002 // copyright-holders:Nicola Salmoria 00003 /*************************************************************************** 00004 00005 sn76496.c 00006 by Nicola Salmoria 00007 with contributions by others 00008 00009 Routines to emulate the: 00010 Texas Instruments SN76489, SN76489A, SN76494/SN76496 00011 ( Also known as, or at least compatible with, the TMS9919 and SN94624.) 00012 and the Sega 'PSG' used on the Master System, Game Gear, and Megadrive/Genesis 00013 This chip is known as the Programmable Sound Generator, or PSG, and is a 4 00014 channel sound generator, with three squarewave channels and a noise/arbitrary 00015 duty cycle channel. 00016 00017 Noise emulation for all verified chips should be accurate: 00018 00019 ** SN76489 uses a 15-bit shift register with taps on bits D and E, output on E, 00020 XOR function. 00021 It uses a 15-bit ring buffer for periodic noise/arbitrary duty cycle. 00022 Its output is inverted. 00023 ** SN94624 is the same as SN76489 but lacks the /8 divider on its clock input. 00024 ** SN76489A uses a 15-bit shift register with taps on bits D and E, output on F, 00025 XOR function. 00026 It uses a 15-bit ring buffer for periodic noise/arbitrary duty cycle. 00027 Its output is not inverted. 00028 ** SN76494 is the same as SN76489A but lacks the /8 divider on its clock input. 00029 ** SN76496 is identical in operation to the SN76489A, but the audio input on pin 9 is 00030 documented. 00031 All the TI-made PSG chips have an audio input line which is mixed with the 4 channels 00032 of output. (It is undocumented and may not function properly on the sn76489, 76489a 00033 and 76494; the sn76489a input is mentioned in datasheets for the tms5200) 00034 All the TI-made PSG chips act as if the frequency was set to 0x400 if 0 is 00035 written to the frequency register. 00036 ** Sega Master System III/MD/Genesis PSG uses a 16-bit shift register with taps 00037 on bits C and F, output on F 00038 It uses a 16-bit ring buffer for periodic noise/arbitrary duty cycle. 00039 (whether it uses an XOR or XNOR needs to be verified, assumed XOR) 00040 (whether output is inverted or not needs to be verified, assumed to be inverted) 00041 ** Sega Game Gear PSG is identical to the SMS3/MD/Genesis one except it has an 00042 extra register for mapping which channels go to which speaker. 00043 The register, connected to a z80 port, means: 00044 for bits 7 6 5 4 3 2 1 0 00045 L3 L2 L1 L0 R3 R2 R1 R0 00046 Noise is an XOR function, and audio output is negated before being output. 00047 All the Sega-made PSG chips act as if the frequency was set to 0 if 0 is written 00048 to the frequency register. 00049 ** NCR8496 (as used on the Tandy 1000) is similar to the SN76489 but with a 00050 different noise LFSR pattern: taps on bits A and E, output on E, XNOR function 00051 It uses a 15-bit ring buffer for periodic noise/arbitrary duty cycle. 00052 Its output is inverted. 00053 ** PSSJ-3 (as used on the later Tandy 1000 series computers) is the same as the 00054 NCR8496 with the exception that its output is not inverted. 00055 00056 28/03/2005 : Sebastien Chevalier 00057 Update th SN76496Write func, according to SN76489 doc found on SMSPower. 00058 - On write with 0x80 set to 0, when LastRegister is other then TONE, 00059 the function is similar than update with 0x80 set to 1 00060 00061 23/04/2007 : Lord Nightmare 00062 Major update, implement all three different noise generation algorithms and a 00063 set_variant call to discern among them. 00064 00065 28/04/2009 : Lord Nightmare 00066 Add READY line readback; cleaned up struct a bit. Cleaned up comments. 00067 Add more TODOs. Fixed some unsaved savestate related stuff. 00068 00069 04/11/2009 : Lord Nightmare 00070 Changed the way that the invert works (it now selects between XOR and XNOR 00071 for the taps), and added R->OldNoise to simulate the extra 0 that is always 00072 output before the noise LFSR contents are after an LFSR reset. 00073 This fixes SN76489/A to match chips. Added SN94624. 00074 00075 14/11/2009 : Lord Nightmare 00076 Removed STEP mess, vastly simplifying the code. Made output bipolar rather 00077 than always above the 0 line, but disabled that code due to pending issues. 00078 00079 16/11/2009 : Lord Nightmare 00080 Fix screeching in regulus: When summing together four equal channels, the 00081 size of the max amplitude per channel should be 1/4 of the max range, not 00082 1/3. Added NCR8496. 00083 00084 18/11/2009 : Lord Nightmare 00085 Modify Init functions to support negating the audio output. The gamegear 00086 psg does this. Change gamegear and sega psgs to use XOR rather than XNOR 00087 based on testing. Got rid of R->OldNoise and fixed taps accordingly. 00088 Added stereo support for game gear. 00089 00090 15/01/2010 : Lord Nightmare 00091 Fix an issue with SN76489 and SN76489A having the wrong periodic noise periods. 00092 Note that properly emulating the noise cycle bit timing accurately may require 00093 extensive rewriting. 00094 00095 24/01/2010: Lord Nightmare 00096 Implement periodic noise as forcing one of the XNOR or XOR taps to 1 or 0 respectively. 00097 Thanks to PlgDavid for providing samples which helped immensely here. 00098 Added true clock divider emulation, so sn94624 and sn76494 run 8x faster than 00099 the others, as in real life. 00100 00101 15/02/2010: Lord Nightmare & Michael Zapf (additional testing by PlgDavid) 00102 Fix noise period when set to mirror channel 3 and channel 3 period is set to 0 (tested on hardware for noise, wave needs tests) - MZ 00103 Fix phase of noise on sn94624 and sn76489; all chips use a standard XOR, the only inversion is the output itself - LN, Plgdavid 00104 Thanks to PlgDavid and Michael Zapf for providing samples which helped immensely here. 00105 00106 23/02/2011: Lord Nightmare & Enik 00107 Made it so the Sega PSG chips have a frequency of 0 if 0 is written to the 00108 frequency register, while the others have 0x400 as before. Should fix a bug 00109 or two on sega games, particularly Vigilante on Sega Master System. Verified 00110 on SMS hardware. 00111 00112 27/06/2012: Michael Zapf 00113 Converted to modern device, legacy devices were gradually removed afterwards. 00114 00115 16/09/2015: Lord Nightmare 00116 Fix PSG chips to have volume reg inited on reset to 0x0 based on tests by 00117 ValleyBell. Made Sega PSG chips start up with register 0x3 selected (volume 00118 for channel 2) based on hardware tests by Nemesis. 00119 00120 26/08/2018: Lord Nightmare, Qbix, ValleyBell, NewRisingSun 00121 * renamed the NCR8496 to its correct name, based on chip pictures on VGMPF 00122 * fixed NCR8496 behavior on write to mirrored registers; unlike any of the 00123 other variants, the NCR8496 seems to ignore writes to regs 1,3,5,6,7 if 0x80 00124 is not set. 00125 ***TODO: the above is NOT verified yet!*** 00126 * fixed NCR8496's noise lfsr behavior so it is only reset if the mode bit in 00127 register 6 is changed. 00128 * NCR8496's LFSR feedback function is an XNOR, which is now supported 00129 * NCR8496's output is inverted (though PSSJ-3's output is not) 00130 * add PSSJ-3 support for the later Tandy computers. 00131 00132 TODO: * Implement the TMS9919 - any difference to sn94624? 00133 * Implement the T6W28; has registers in a weird order, needs writes 00134 to be 'sanitized' first. Also is stereo, similar to game gear. 00135 * Factor out common code so that the SAA1099 can share some code. 00136 00137 ***************************************************************************/ 00138 00139 #include "emu.h" 00140 #include "sn76496.h" 00141 00142 #define MAX_OUTPUT 0x7fff 00143 //When you go over this create sample 00144 #define RATE_MAX ( 1 << 30) 00145 00146 sn76496_base_device::sn76496_base_device( 00147 const machine_config &mconfig, 00148 device_type type, 00149 const char *tag, 00150 int feedbackmask, 00151 int noisetap1, 00152 int noisetap2, 00153 bool negate, 00154 bool stereo, 00155 int clockdivider, 00156 bool ncr, 00157 bool sega, 00158 device_t *owner, 00159 uint32_t clock) 00160 : device_t(mconfig, type, tag, owner, clock) 00161 , device_sound_interface(mconfig, *this) 00162 // , m_ready_handler(*this) 00163 , m_feedback_mask(feedbackmask) 00164 , m_whitenoise_tap1(noisetap1) 00165 , m_whitenoise_tap2(noisetap2) 00166 , m_negate(negate) 00167 , m_stereo(stereo) 00168 , m_clock_divider(clockdivider) 00169 , m_ncr_style_psg(ncr) 00170 , m_sega_style_psg(sega) 00171 { 00172 } 00173 00174 00175 sn76496_device::sn76496_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) 00176 : sn76496_base_device(mconfig, SN76496, tag, 0x10000, 0x04, 0x08, false, false, 8, false, true, owner, clock) 00177 { 00178 } 00179 00180 u8106_device::u8106_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) 00181 : sn76496_base_device(mconfig, U8106, tag, 0x4000, 0x01, 0x02, true, false, 8, false, true, owner, clock) 00182 { 00183 } 00184 00185 y2404_device::y2404_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) 00186 : sn76496_base_device(mconfig, Y2404, tag, 0x10000, 0x04, 0x08, false, false, 8, false, true, owner, clock) 00187 { 00188 } 00189 00190 sn76489_device::sn76489_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) 00191 : sn76496_base_device(mconfig, SN76489, tag, 0x4000, 0x01, 0x02, true, false, 8, false, true, owner, clock) 00192 { 00193 } 00194 00195 sn76489a_device::sn76489a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) 00196 : sn76496_base_device(mconfig, SN76489A, tag, 0x10000, 0x04, 0x08, false, false, 8, false, true, owner, clock) 00197 { 00198 } 00199 00200 sn76494_device::sn76494_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) 00201 : sn76496_base_device(mconfig, SN76494, tag, 0x10000, 0x04, 0x08, false, false, 1, false, true, owner, clock) 00202 { 00203 } 00204 00205 sn94624_device::sn94624_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) 00206 : sn76496_base_device(mconfig, SN94624, tag, 0x4000, 0x01, 0x02, true, false, 1, false, true, owner, clock) 00207 { 00208 } 00209 00210 ncr8496_device::ncr8496_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) 00211 : sn76496_base_device(mconfig, NCR8496, tag, 0x8000, 0x02, 0x20, true, false, 8, true, true, owner, clock) 00212 { 00213 } 00214 00215 pssj3_device::pssj3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) 00216 : sn76496_base_device(mconfig, PSSJ3, tag, 0x8000, 0x02, 0x20, false, false, 8, true, true, owner, clock) 00217 { 00218 } 00219 00220 gamegear_device::gamegear_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) 00221 : sn76496_base_device(mconfig, GAMEGEAR, tag, 0x8000, 0x01, 0x08, true, true, 8, false, false, owner, clock) 00222 { 00223 } 00224 00225 segapsg_device::segapsg_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) 00226 : sn76496_base_device(mconfig, SEGAPSG, tag, 0x8000, 0x01, 0x08, true, false, 8, false, false, owner, clock) 00227 { 00228 } 00229 00230 void sn76496_base_device::device_start() 00231 { 00232 sample_rate = clock()/2; 00233 rate_add = RATE_MAX; 00234 rate_counter = 0; 00235 00236 int i; 00237 double out; 00238 int gain; 00239 00240 //m_ready_handler.resolve_safe(); 00241 00242 //m_sound = machine().sound().stream_alloc(*this, 0, (m_stereo? 2:1), sample_rate); 00243 00244 for (i = 0; i < 4; i++) m_volume[i] = 0; 00245 00246 m_last_register = m_sega_style_psg?3:0; // Sega VDP PSG defaults to selected period reg for 2nd channel 00247 for (i = 0; i < 8; i+=2) 00248 { 00249 m_register[i] = 0; 00250 m_register[i + 1] = 0x0; // volume = 0x0 (max volume) on reset; this needs testing on chips other than SN76489A and Sega VDP PSG 00251 } 00252 00253 for (i = 0; i < 4; i++) 00254 { 00255 m_output[i] = 0; 00256 m_period[i] = 0; 00257 m_count[i] = 0; 00258 } 00259 00260 m_RNG = m_feedback_mask; 00261 m_output[3] = m_RNG & 1; 00262 00263 m_cycles_to_ready = 1; // assume ready is not active immediately on init. is this correct? 00264 m_stereo_mask = 0xFF; // all channels enabled 00265 m_current_clock = m_clock_divider-1; 00266 00267 // set gain 00268 gain = 0; 00269 00270 gain &= 0xff; 00271 00272 // increase max output basing on gain (0.2 dB per step) 00273 out = MAX_OUTPUT / 4; // four channels, each gets 1/4 of the total range 00274 while (gain-- > 0) 00275 out *= 1.023292992; // = (10 ^ (0.2/20)) 00276 00277 // build volume table (2dB per step) 00278 for (i = 0; i < 15; i++) 00279 { 00280 // limit volume to avoid clipping 00281 if (out > MAX_OUTPUT / 4) m_vol_table[i] = MAX_OUTPUT / 4; 00282 else m_vol_table[i] = (int32_t)out; 00283 00284 out /= 1.258925412; /* = 10 ^ (2/20) = 2dB */ 00285 } 00286 m_vol_table[15] = 0; 00287 00288 m_ready_state = true; 00289 00290 //register_for_save_states(); 00291 } 00292 00293 void sn76496_base_device::device_clock_changed() 00294 { 00295 // m_sound->set_sample_rate(clock()/2); 00296 } 00297 00298 WRITE8_MEMBER( sn76496_base_device::stereo_w ) 00299 { 00300 (void)offset; 00301 (void)space; 00302 (void)data; 00303 // m_sound->update(); 00304 // if (m_stereo) m_stereo_mask = data; 00305 // else fatalerror("sn76496_base_device: Call to stereo write with mono chip!\n"); 00306 } 00307 00308 void sn76496_base_device::write(uint8_t data) 00309 { 00310 int n, r, c; 00311 00312 // update the output buffer before changing the registers 00313 // m_sound->update(); 00314 00315 // set number of cycles until READY is active; this is always one 00316 // 'sample', i.e. it equals the clock divider exactly 00317 m_cycles_to_ready = 1; 00318 00319 if (data & 0x80) 00320 { 00321 r = (data & 0x70) >> 4; 00322 m_last_register = r; 00323 if (((m_ncr_style_psg) && (r == 6)) && ((data&0x04) != (m_register[6]&0x04))) m_RNG = m_feedback_mask; 00324 m_register[r] = (m_register[r] & 0x3f0) | (data & 0x0f); 00325 } 00326 else 00327 { 00328 r = m_last_register; 00329 if ((m_ncr_style_psg) && ((r & 1) || (r == 6))) return; // NCR8496 ignores writes to regs 1, 3, 5, 6 and 7 with bit 7 clear 00330 } 00331 00332 c = r >> 1; 00333 switch (r) 00334 { 00335 case 0: // tone 0: frequency 00336 case 2: // tone 1: frequency 00337 case 4: // tone 2: frequency 00338 if ((data & 0x80) == 0) m_register[r] = (m_register[r] & 0x0f) | ((data & 0x3f) << 4); 00339 if ((m_register[r] != 0) || (!m_sega_style_psg)) m_period[c] = m_register[r]; 00340 else m_period[c] = 0x400; 00341 00342 if (r == 4) 00343 { 00344 // update noise shift frequency 00345 if ((m_register[6] & 0x03) == 0x03) m_period[3] = m_period[2]<<1; 00346 } 00347 break; 00348 case 1: // tone 0: volume 00349 case 3: // tone 1: volume 00350 case 5: // tone 2: volume 00351 case 7: // noise: volume 00352 m_volume[c] = m_vol_table[data & 0x0f]; 00353 if ((data & 0x80) == 0) m_register[r] = (m_register[r] & 0x3f0) | (data & 0x0f); 00354 break; 00355 case 6: // noise: frequency, mode 00356 { 00357 if ((data & 0x80) == 0) logerror("sn76496_base_device: write to reg 6 with bit 7 clear; data was %03x, new write is %02x! report this to LN!\n", m_register[6], data); 00358 if ((data & 0x80) == 0) m_register[r] = (m_register[r] & 0x3f0) | (data & 0x0f); 00359 n = m_register[6]; 00360 // N/512,N/1024,N/2048,Tone #3 output 00361 m_period[3] = ((n&3) == 3)? (m_period[2]<<1) : (1 << (5+(n&3))); 00362 if (!(m_ncr_style_psg)) m_RNG = m_feedback_mask; 00363 } 00364 break; 00365 } 00366 } 00367 00368 WRITE8_MEMBER( sn76496_base_device::write ) 00369 { 00370 (void)offset; 00371 (void)space; 00372 write(data); 00373 } 00374 00375 inline bool sn76496_base_device::in_noise_mode() 00376 { 00377 return ((m_register[6] & 4)!=0); 00378 } 00379 00380 void sn76496_base_device::countdown_cycles() 00381 { 00382 if (m_cycles_to_ready > 0) 00383 { 00384 m_cycles_to_ready--; 00385 //if (m_ready_state==true) m_ready_handler(CLEAR_LINE); 00386 m_ready_state = false; 00387 } 00388 else 00389 { 00390 //if (m_ready_state==false) m_ready_handler(ASSERT_LINE); 00391 m_ready_state = true; 00392 } 00393 } 00394 00395 void sn76496_base_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) 00396 { 00397 (void)stream; 00398 (void)inputs; 00399 int i; 00400 stream_sample_t *lbuffer = outputs[0]; 00401 stream_sample_t *rbuffer = (m_stereo)? outputs[1] : 0;//nullptr; 00402 00403 int16_t out; 00404 int16_t out2 = 0; 00405 00406 while (samples > 0) 00407 { 00408 // clock chip once 00409 if (m_current_clock > 0) // not ready for new divided clock 00410 { 00411 m_current_clock--; 00412 } 00413 else // ready for new divided clock, make a new sample 00414 { 00415 m_current_clock = m_clock_divider-1; 00416 // decrement Cycles to READY by one 00417 countdown_cycles(); 00418 00419 // handle channels 0,1,2 00420 for (i = 0; i < 3; i++) 00421 { 00422 m_count[i]--; 00423 if (m_count[i] <= 0) 00424 { 00425 m_output[i] ^= 1; 00426 m_count[i] = m_period[i]; 00427 } 00428 } 00429 00430 // handle channel 3 00431 m_count[3]--; 00432 if (m_count[3] <= 0) 00433 { 00434 // if noisemode is 1, both taps are enabled 00435 // if noisemode is 0, the lower tap, whitenoisetap2, is held at 0 00436 // The != was a bit-XOR (^) before 00437 if (((m_RNG & m_whitenoise_tap1)!=0) != (((m_RNG & m_whitenoise_tap2)!=(m_ncr_style_psg?(uint32_t)m_whitenoise_tap2:0)) && in_noise_mode())) 00438 { 00439 m_RNG >>= 1; 00440 m_RNG |= m_feedback_mask; 00441 } 00442 else 00443 { 00444 m_RNG >>= 1; 00445 } 00446 m_output[3] = m_RNG & 1; 00447 00448 m_count[3] = m_period[3]; 00449 } 00450 } 00451 00452 //Skip final generation if you don't need an actual sample 00453 rate_counter += rate_add; 00454 if (rate_counter < RATE_MAX) 00455 continue; 00456 rate_counter -= RATE_MAX; 00457 00458 if (m_stereo) 00459 { 00460 out = ((((m_stereo_mask & 0x10)!=0) && (m_output[0]!=0))? m_volume[0] : 0) 00461 + ((((m_stereo_mask & 0x20)!=0) && (m_output[1]!=0))? m_volume[1] : 0) 00462 + ((((m_stereo_mask & 0x40)!=0) && (m_output[2]!=0))? m_volume[2] : 0) 00463 + ((((m_stereo_mask & 0x80)!=0) && (m_output[3]!=0))? m_volume[3] : 0); 00464 00465 out2= ((((m_stereo_mask & 0x1)!=0) && (m_output[0]!=0))? m_volume[0] : 0) 00466 + ((((m_stereo_mask & 0x2)!=0) && (m_output[1]!=0))? m_volume[1] : 0) 00467 + ((((m_stereo_mask & 0x4)!=0) && (m_output[2]!=0))? m_volume[2] : 0) 00468 + ((((m_stereo_mask & 0x8)!=0) && (m_output[3]!=0))? m_volume[3] : 0); 00469 } 00470 else 00471 { 00472 out= ((m_output[0]!=0)? m_volume[0]:0) 00473 +((m_output[1]!=0)? m_volume[1]:0) 00474 +((m_output[2]!=0)? m_volume[2]:0) 00475 +((m_output[3]!=0)? m_volume[3]:0); 00476 } 00477 00478 if (m_negate) { out = -out; out2 = -out2; } 00479 *(lbuffer++) = out; 00480 if (m_stereo) *(rbuffer++) = out2; 00481 samples--; 00482 } 00483 } 00484 00485 00486 void sn76496_base_device::convert_samplerate(int32_t target_rate) { 00487 //Simple 10 bit shift for samplerate conversion 00488 rate_add = (int32_t)( RATE_MAX * (target_rate / (double)sample_rate) ); 00489 rate_counter = 0; 00490 } 00491 00492 void sn76496_base_device::SaveState( std::ostream& stream ) { 00493 WRITE_POD(&m_vol_table, m_vol_table); 00494 WRITE_POD(&m_register, m_register); 00495 WRITE_POD(&m_last_register, m_last_register); 00496 WRITE_POD(&m_volume, m_volume); 00497 WRITE_POD(&m_RNG, m_RNG); 00498 //WRITE_POD(&m_clock_divider, m_clock_divider); 00499 WRITE_POD(&m_current_clock, m_current_clock); 00500 //WRITE_POD(&m_feedback_mask, m_feedback_mask); 00501 //WRITE_POD(&m_whitenoise_tap1, m_whitenoise_tap1); 00502 //WRITE_POD(&m_whitenoise_tap2, m_whitenoise_tap2); 00503 //WRITE_POD(&m_negate, m_negate); 00504 //WRITE_POD(&m_stereo, m_stereo); 00505 WRITE_POD(&m_stereo_mask, m_stereo_mask); 00506 WRITE_POD(&m_period, m_period); 00507 WRITE_POD(&m_count, m_count); 00508 WRITE_POD(&m_output, m_output); 00509 WRITE_POD(&m_cycles_to_ready, m_cycles_to_ready); 00510 //WRITE_POD(&m_sega_style_psg, m_sega_style_psg); 00511 } 00512 void sn76496_base_device::LoadState( std::istream& stream ) { 00513 READ_POD(&m_vol_table, m_vol_table); 00514 READ_POD(&m_register, m_register); 00515 READ_POD(&m_last_register, m_last_register); 00516 READ_POD(&m_volume, m_volume); 00517 READ_POD(&m_RNG, m_RNG); 00518 //READ_POD(&m_clock_divider, m_clock_divider); 00519 READ_POD(&m_current_clock, m_current_clock); 00520 //READ_POD(&m_feedback_mask, m_feedback_mask); 00521 //READ_POD(&m_whitenoise_tap1, m_whitenoise_tap1); 00522 //READ_POD(&m_whitenoise_tap2, m_whitenoise_tap2); 00523 //READ_POD(&m_negate, m_negate); 00524 //READ_POD(&m_stereo, m_stereo); 00525 READ_POD(&m_stereo_mask, m_stereo_mask); 00526 READ_POD(&m_period, m_period); 00527 READ_POD(&m_count, m_count); 00528 READ_POD(&m_output, m_output); 00529 READ_POD(&m_cycles_to_ready, m_cycles_to_ready); 00530 //READ_POD(&m_sega_style_psg, m_sega_style_psg); 00531 } 00532 00533 void sn76496_base_device::register_for_save_states() 00534 { 00535 save_item(NAME(m_vol_table)); 00536 save_item(NAME(m_register)); 00537 save_item(NAME(m_last_register)); 00538 save_item(NAME(m_volume)); 00539 save_item(NAME(m_RNG)); 00540 // save_item(NAME(m_clock_divider)); 00541 save_item(NAME(m_current_clock)); 00542 // save_item(NAME(m_feedback_mask)); 00543 // save_item(NAME(m_whitenoise_tap1)); 00544 // save_item(NAME(m_whitenoise_tap2)); 00545 // save_item(NAME(m_negate)); 00546 // save_item(NAME(m_stereo)); 00547 save_item(NAME(m_stereo_mask)); 00548 save_item(NAME(m_period)); 00549 save_item(NAME(m_count)); 00550 save_item(NAME(m_output)); 00551 save_item(NAME(m_cycles_to_ready)); 00552 // save_item(NAME(m_sega_style_psg)); 00553 } 00554 00555 DEFINE_DEVICE_TYPE(SN76496, sn76496_device, "sn76496", "SN76496") 00556 DEFINE_DEVICE_TYPE(U8106, u8106_device, "u8106", "U8106") 00557 DEFINE_DEVICE_TYPE(Y2404, y2404_device, "y2404", "Y2404") 00558 DEFINE_DEVICE_TYPE(SN76489, sn76489_device, "sn76489", "SN76489") 00559 DEFINE_DEVICE_TYPE(SN76489A, sn76489a_device, "sn76489a", "SN76489A") 00560 DEFINE_DEVICE_TYPE(SN76494, sn76494_device, "sn76494", "SN76494") 00561 DEFINE_DEVICE_TYPE(SN94624, sn94624_device, "sn94624", "SN94624") 00562 DEFINE_DEVICE_TYPE(NCR8496, ncr8496_device, "ncr8496", "NCR8496") 00563 DEFINE_DEVICE_TYPE(PSSJ3, pssj3_device, "pssj3", "PSSJ-3") 00564 DEFINE_DEVICE_TYPE(GAMEGEAR, gamegear_device, "gamegear_psg", "Game Gear PSG") 00565 DEFINE_DEVICE_TYPE(SEGAPSG, segapsg_device, "segapsg", "Sega VDP PSG") 00566