DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
src/hardware/mame/sn76496.h
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