DOSBox-X
|
00001 // license:BSD-3-Clause 00002 // copyright-holders:Nicola Salmoria 00003 #ifndef MAME_SOUND_SN76496_H 00004 #define MAME_SOUND_SN76496_H 00005 00006 #pragma once 00007 00008 00009 DECLARE_DEVICE_TYPE(SN76496, sn76496_device) 00010 DECLARE_DEVICE_TYPE(U8106, u8106_device) 00011 DECLARE_DEVICE_TYPE(Y2404, y2404_device) 00012 DECLARE_DEVICE_TYPE(SN76489, sn76489_device) 00013 DECLARE_DEVICE_TYPE(SN76489A, sn76489a_device) 00014 DECLARE_DEVICE_TYPE(SN76494, sn76494_device) 00015 DECLARE_DEVICE_TYPE(SN94624, sn94624_device) 00016 DECLARE_DEVICE_TYPE(NCR8496, ncr8496_device) 00017 DECLARE_DEVICE_TYPE(PSSJ3, pssj3_device) 00018 DECLARE_DEVICE_TYPE(GAMEGEAR, gamegear_device) 00019 DECLARE_DEVICE_TYPE(SEGAPSG, segapsg_device) 00020 00021 #if 0 00022 00023 00024 #define MCFG_SN76496_READY_HANDLER(cb) \ 00025 downcast<sn76496_base_device &>(*device).set_ready_handler((DEVCB_##cb)); 00026 00027 #endif 00028 00029 class sn76496_base_device : public device_t, public device_sound_interface 00030 { 00031 public: 00032 // configuration helpers 00033 // template <class Object> devcb_base &set_ready_handler(Object &&cb) { return m_ready_handler.set_callback(std::forward<Object>(cb)); } 00034 00035 DECLARE_WRITE8_MEMBER( stereo_w ); 00036 void write(uint8_t data); 00037 DECLARE_WRITE8_MEMBER( write ); 00038 // DECLARE_READ_LINE_MEMBER( ready_r ) { return m_ready_state ? 1 : 0; } 00039 // auto ready_cb() { return m_ready_handler.bind(); } 00040 00041 void convert_samplerate(int32_t target_rate); 00042 void SaveState( std::ostream& stream ); 00043 void LoadState( std::istream& stream ); 00044 protected: 00045 sn76496_base_device( 00046 const machine_config &mconfig, 00047 device_type type, 00048 const char *tag, 00049 int feedbackmask, 00050 int noisetap1, 00051 int noisetap2, 00052 bool negate, 00053 bool stereo, 00054 int clockdivider, 00055 bool ncr, 00056 bool sega, 00057 device_t *owner, 00058 uint32_t clock); 00059 00060 virtual void device_start(); 00061 virtual void device_clock_changed(); 00062 virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples); 00063 00064 private: 00065 inline bool in_noise_mode(); 00066 void register_for_save_states(); 00067 void countdown_cycles(); 00068 00069 00070 00071 bool m_ready_state; 00072 00073 //devcb_write_line m_ready_handler; 00074 00075 //sound_stream* m_sound; 00076 00077 const int32_t m_feedback_mask; // mask for feedback 00078 const int32_t m_whitenoise_tap1; // mask for white noise tap 1 (higher one, usually bit 14) 00079 const int32_t m_whitenoise_tap2; // mask for white noise tap 2 (lower one, usually bit 13) 00080 const bool m_negate; // output negate flag 00081 const bool m_stereo; // whether we're dealing with stereo or not 00082 const int32_t m_clock_divider; // clock divider 00083 const bool m_ncr_style_psg; // flag to ignore writes to regs 1,3,5,6,7 with bit 7 low 00084 const bool m_sega_style_psg; // flag to make frequency zero acts as if it is one more than max (0x3ff+1) or if it acts like 0; the initial register is pointing to 0x3 instead of 0x0; the volume reg is preloaded with 0xF instead of 0x0 00085 00086 int32_t m_vol_table[16]; // volume table (for 4-bit to db conversion) 00087 int32_t m_register[8]; // registers 00088 int32_t m_last_register; // last register written 00089 int32_t m_volume[4]; // db volume of voice 0-2 and noise 00090 uint32_t m_RNG; // noise generator LFSR 00091 int32_t m_current_clock; 00092 int32_t m_stereo_mask; // the stereo output mask 00093 int32_t m_period[4]; // Length of 1/2 of waveform 00094 int32_t m_count[4]; // Position within the waveform 00095 int32_t m_output[4]; // 1-bit output of each channel, pre-volume 00096 int32_t m_cycles_to_ready; // number of cycles until the READY line goes active 00097 00098 //Modifications for easier sample conversion 00099 int32_t sample_rate; 00100 //Sample rate conversion 00101 int32_t rate_add; 00102 int32_t rate_counter; 00103 }; 00104 00105 // SN76496: Whitenoise verified, phase verified, periodic verified (by Michael Zapf) 00106 class sn76496_device : public sn76496_base_device 00107 { 00108 public: 00109 sn76496_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); 00110 }; 00111 00112 // U8106 not verified yet. todo: verify; (a custom marked sn76489? only used on mr. do and maybe other universal games) 00113 class u8106_device : public sn76496_base_device 00114 { 00115 public: 00116 u8106_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); 00117 }; 00118 00119 // Y2404 not verified yet. todo: verify; (don't be fooled by the Y, it's a TI chip, not Yamaha) 00120 class y2404_device : public sn76496_base_device 00121 { 00122 public: 00123 y2404_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); 00124 }; 00125 00126 // NCR8496 whitenoise verified, phase verified; verified by ValleyBell & NewRisingSun 00127 class sn76489_device : public sn76496_base_device 00128 { 00129 public: 00130 sn76489_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); 00131 }; 00132 00133 // PSSJ-3 whitenoise verified, phase verified; verified by ValleyBell & NewRisingSun 00134 class pssj3_device : public sn76496_base_device 00135 { 00136 public: 00137 pssj3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); 00138 }; 00139 00140 00141 // SN76489A: whitenoise verified, phase verified, periodic verified (by plgdavid) 00142 class sn76489a_device : public sn76496_base_device 00143 { 00144 public: 00145 sn76489a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); 00146 }; 00147 00148 // SN76494 not verified, (according to datasheet: same as sn76489a but without the /8 divider) 00149 class sn76494_device : public sn76496_base_device 00150 { 00151 public: 00152 sn76494_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); 00153 }; 00154 00155 // SN94624 whitenoise verified, phase verified, period verified; verified by PlgDavid 00156 class sn94624_device : public sn76496_base_device 00157 { 00158 public: 00159 sn94624_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); 00160 }; 00161 00162 // NCR8496 not verified; info from smspower wiki and vgmpf wiki 00163 class ncr8496_device : public sn76496_base_device 00164 { 00165 public: 00166 ncr8496_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); 00167 }; 00168 00169 // Verified by Justin Kerk 00170 class gamegear_device : public sn76496_base_device 00171 { 00172 public: 00173 gamegear_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); 00174 }; 00175 00176 // todo: verify; from smspower wiki, assumed to have same invert as gamegear 00177 class segapsg_device : public sn76496_base_device 00178 { 00179 public: 00180 segapsg_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); 00181 }; 00182 00183 #endif // MAME_SOUND_SN76496_H