Viewing File: <root>/src/emu/sound/sn76496.h

    1  #pragma once
    2  
    3  #ifndef __SN76496_H__
    4  #define __SN76496_H__
    5  
    6  
    7  extern const device_type SN76496;
    8  extern const device_type U8106;
    9  extern const device_type Y2404;
   10  extern const device_type SN76489;
   11  extern const device_type SN76489A;
   12  extern const device_type SN76494;
   13  extern const device_type SN94624;
   14  extern const device_type NCR7496;
   15  extern const device_type GAMEGEAR;
   16  extern const device_type SEGAPSG;
   17  
   18  struct sn76496_config
   19  {
   20      devcb_write_line        ready;
   21  };
   22  
   23  class sn76496_base_device : public device_t, public device_sound_interface
   24  {
   25  public:
   26      sn76496_base_device(const machine_config &mconfig, device_type type,  const char *name, const char *tag,
   27          int feedbackmask, int noisetap1, int noisetap2, bool negate, bool stereo, int clockdivider, int freq0,
   28          device_t *owner, UINT32 clock);
   29      DECLARE_READ_LINE_MEMBER( ready_r );
   30      DECLARE_WRITE8_MEMBER( stereo_w );
   31      void write(UINT8 data);
   32      DECLARE_WRITE8_MEMBER( write );
   33  
   34  protected:
   35      void    device_start();
   36      void    sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
   37  
   38  private:
   39      inline bool     in_noise_mode();
   40      void            register_for_save_states();
   41      void            countdown_cycles();
   42  
   43      bool            m_ready_state;
   44  
   45      devcb_resolved_write_line   m_ready;
   46  
   47      sound_stream*   m_sound;
   48  
   49      const INT32     m_feedback_mask;    // mask for feedback
   50      const INT32     m_whitenoise_tap1;  // mask for white noise tap 1 (higher one, usually bit 14)
   51      const INT32     m_whitenoise_tap2;  // mask for white noise tap 2 (lower one, usually bit 13)
   52      const bool      m_negate;           // output negate flag
   53      const bool      m_stereo;           // whether we're dealing with stereo or not
   54      const INT32     m_clock_divider;    // clock divider
   55      const bool      m_freq0_is_max;     // flag for if frequency zero acts as if it is one more than max (0x3ff+1) or if it acts like 0
   56  
   57      INT32           m_vol_table[16];    // volume table (for 4-bit to db conversion)
   58      INT32           m_register[8];      // registers
   59      INT32           m_last_register;    // last register written
   60      INT32           m_volume[4];        // db volume of voice 0-2 and noise
   61      UINT32          m_RNG;              // noise generator LFSR
   62      INT32           m_current_clock;
   63      INT32           m_stereo_mask;      // the stereo output mask
   64      INT32           m_period[4];        // Length of 1/2 of waveform
   65      INT32           m_count[4];         // Position within the waveform
   66      INT32           m_output[4];        // 1-bit output of each channel, pre-volume
   67      INT32           m_cycles_to_ready;  // number of cycles until the READY line goes active
   68  };
   69  
   70  // SN76496: Whitenoise verified, phase verified, periodic verified (by Michael Zapf)
   71  class sn76496_device : public sn76496_base_device
   72  {
   73  public:
   74      sn76496_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
   75      :  sn76496_base_device(mconfig, SN76496, "SN76496", tag, 0x10000, 0x04, 0x08, false, false, 8, true, owner, clock)
   76      { }
   77  };
   78  
   79  // U8106 not verified yet. todo: verify; (a custom marked sn76489? only used on mr. do and maybe other universal games)
   80  class u8106_device : public sn76496_base_device
   81  {
   82  public:
   83      u8106_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
   84      :  sn76496_base_device(mconfig, U8106, "U8106", tag, 0x4000, 0x01, 0x02, true, false, 8, true, owner, clock)
   85      { }
   86  };
   87  
   88  // Y2404 not verified yet. todo: verify; (don't be fooled by the Y, it's a TI chip, not Yamaha)
   89  class y2404_device : public sn76496_base_device
   90  {
   91  public:
   92      y2404_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
   93      :  sn76496_base_device(mconfig, Y2404, "Y2404", tag, 0x10000, 0x04, 0x08, false, false, 8, true, owner, clock)
   94      { }
   95  };
   96  
   97  // SN76489 not verified yet. todo: verify;
   98  class sn76489_device : public sn76496_base_device
   99  {
  100  public:
  101      sn76489_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
  102      :  sn76496_base_device(mconfig, SN76489, "SN76489", tag, 0x4000, 0x01, 0x02, true, false, 8, true, owner, clock)
  103      { }
  104  };
  105  
  106  // SN76489A: whitenoise verified, phase verified, periodic verified (by plgdavid)
  107  class sn76489a_device : public sn76496_base_device
  108  {
  109  public:
  110      sn76489a_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
  111      :  sn76496_base_device(mconfig, SN76489A, "SN76489A", tag, 0x10000, 0x04, 0x08, false, false, 8, true, owner, clock)
  112      { }
  113  };
  114  
  115  // SN76494 not verified, (according to datasheet: same as sn76489a but without the /8 divider)
  116  class sn76494_device : public sn76496_base_device
  117  {
  118  public:
  119      sn76494_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
  120      :  sn76496_base_device(mconfig, SN76494, "SN76494", tag, 0x10000, 0x04, 0x08, false, false, 1, true, owner, clock)
  121      { }
  122  };
  123  
  124  // SN94624 whitenoise verified, phase verified, period verified; verified by PlgDavid
  125  class sn94624_device : public sn76496_base_device
  126  {
  127  public:
  128      sn94624_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
  129      :  sn76496_base_device(mconfig, SN94624, "SN94624", tag, 0x4000, 0x01, 0x02, true, false, 1, true, owner, clock)
  130      { }
  131  };
  132  
  133  // NCR7496 not verified; info from smspower wiki
  134  class ncr7496_device : public sn76496_base_device
  135  {
  136  public:
  137      ncr7496_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
  138      :  sn76496_base_device(mconfig, NCR7496, "NCR7496", tag, 0x8000, 0x02, 0x20, false, false, 8, true, owner, clock)
  139      { }
  140  };
  141  
  142  // Verified by Justin Kerk
  143  class gamegear_device : public sn76496_base_device
  144  {
  145  public:
  146      gamegear_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
  147      :  sn76496_base_device(mconfig, GAMEGEAR, "Game Gear PSG", tag, 0x8000, 0x01, 0x08, true, true, 8, false, owner, clock)
  148      { }
  149  };
  150  
  151  // todo: verify; from smspower wiki, assumed to have same invert as gamegear
  152  class segapsg_device : public sn76496_base_device
  153  {
  154  public:
  155      segapsg_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
  156      :  sn76496_base_device(mconfig, SEGAPSG, "SEGA VDP PSG", tag, 0x8000, 0x01, 0x08, true, false, 8, false, owner, clock)
  157      { }
  158  };
  159  
  160  #endif /* __SN76496_H__ */