summaryrefslogblamecommitdiffstatshomepage
path: root/src/devices/sound/ym2413.h
blob: 52bd1907ecc11cd6e3deca4be5b85b095328a55f (plain) (tree)
1
2
3
4
5
6
7
8
9
                   
                                                   

                           
 
            
 
 
                                                                    

       
                                                                                                       
 
                                           
 

                                      
 
          

                                                                                                                         

                                             
                                                     




                                                                                                                                          

                                    


                        






                                                                            

                                     



                                                                                   

                                        


















                                                                            

                         

                                                                                             

                                     
                                           





                                           




                                                                                            























                                                                             

                                           


                                                      


                                                               
                                          








                                                                       
                                                                                                      
 


                                                                                                                   
                                                                                                                
 
                                                                            

                 





                             
 


                                                                            


                         
  



                                        
  
                                
 
                                                                            
 
                                                                            
 
                             
 

                                 
 


                                               

                                                                                             

                                                            

                                                        





                                                       

                                                                           
                                     
 
  
 
                                          
 










                                                                                                        
                             
// license:GPL-2.0+
// copyright-holders:Jarek Burczynski,Ernesto Corvi
#ifndef MAME_SOUND_YM2413_H
#define MAME_SOUND_YM2413_H

#pragma once


class ym2413_device : public device_t, public device_sound_interface
{
public:
	ym2413_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

	void write(offs_t offset, u8 data);

	void register_port_w(u8 data);
	void data_port_w(u8 data);

protected:
	ym2413_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);

	// device-level overrides
	virtual void device_start() override;
	virtual void device_clock_changed() override;
	virtual void device_reset() override;

	// sound stream update overrides
	virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override;

	uint8_t m_inst_table[19][8];

private:
	struct OPLL_SLOT
	{
		uint32_t  ar = 0;         /* attack rate: AR<<2           */
		uint32_t  dr = 0;         /* decay rate:  DR<<2           */
		uint32_t  rr = 0;         /* release rate:RR<<2           */
		uint8_t   KSR = 0;        /* key scale rate               */
		uint8_t   ksl = 0;        /* keyscale level               */
		uint8_t   ksr = 0;        /* key scale rate: kcode>>KSR   */
		uint8_t   mul = 0;        /* multiple: mul_tab[ML]        */

		/* Phase Generator */
		uint32_t  phase = 0;      /* frequency counter            */
		uint32_t  freq = 0;       /* frequency counter step       */
		uint8_t   fb_shift = 0;   /* feedback shift value         */
		int32_t   op1_out[2] = { 0, 0 }; /* slot1 output for feedback    */

		/* Envelope Generator */
		uint8_t   eg_type = 0;    /* percussive/nonpercussive mode*/
		uint8_t   state = 0;      /* phase type                   */
		uint32_t  TL = 0;         /* total level: TL << 2         */
		int32_t   TLL = 0;        /* adjusted now TL              */
		int32_t   volume = 0;     /* envelope counter             */
		uint32_t  sl = 0;         /* sustain level: sl_tab[SL]    */

		uint8_t   eg_sh_dp = 0;   /* (dump state)                 */
		uint8_t   eg_sel_dp = 0;  /* (dump state)                 */
		uint8_t   eg_sh_ar = 0;   /* (attack state)               */
		uint8_t   eg_sel_ar = 0;  /* (attack state)               */
		uint8_t   eg_sh_dr = 0;   /* (decay state)                */
		uint8_t   eg_sel_dr = 0;  /* (decay state)                */
		uint8_t   eg_sh_rr = 0;   /* (release state for non-perc.)*/
		uint8_t   eg_sel_rr = 0;  /* (release state for non-perc.)*/
		uint8_t   eg_sh_rs = 0;   /* (release state for perc.mode)*/
		uint8_t   eg_sel_rs = 0;  /* (release state for perc.mode)*/

		uint32_t  key = 0;        /* 0 = KEY OFF, >0 = KEY ON     */

		/* LFO */
		uint32_t  AMmask = 0;     /* LFO Amplitude Modulation enable mask */
		uint8_t   vib = 0;        /* LFO Phase Modulation enable flag (active high)*/

		/* waveform select */
		unsigned int wavetable = 0;
	};

	struct OPLL_CH
	{
		OPLL_SLOT SLOT[2];
		/* phase generator state */
		uint32_t  block_fnum = 0; /* block+fnum                   */
		uint32_t  fc = 0;         /* Freq. freqement base         */
		uint32_t  ksl_base = 0;   /* KeyScaleLevel Base step      */
		uint8_t   kcode = 0;      /* key code (for key scaling)   */
		uint8_t   sus = 0;        /* sus on/off (release speed in percussive mode)*/
	};

	enum {
		RATE_STEPS = (8),

		/* sinwave entries */
		SIN_BITS =       10,
		SIN_LEN  =       (1<<SIN_BITS),
		SIN_MASK =       (SIN_LEN-1),

		TL_RES_LEN =     (256),   /* 8 bits addressing (real chip) */

		/*  TL_TAB_LEN is calculated as:
		 *   11 - sinus amplitude bits     (Y axis)
		 *   2  - sinus sign bit           (Y axis)
		 *   TL_RES_LEN - sinus resolution (X axis)
		 */
		TL_TAB_LEN = (11*2*TL_RES_LEN),

		LFO_AM_TAB_ELEMENTS = 210

	};

	static const double ksl_tab[8*16];
	static const uint32_t ksl_shift[4];
	static const uint32_t sl_tab[16];
	static const uint8_t eg_inc[15*RATE_STEPS];
	static const uint8_t eg_rate_select[16+64+16];
	static const uint8_t eg_rate_shift[16+64+16];
	static const uint8_t mul_tab[16];
	static const uint8_t lfo_am_table[LFO_AM_TAB_ELEMENTS];
	static const int8_t lfo_pm_table[8*8];
	static const uint8_t table[19][8];

	int tl_tab[TL_TAB_LEN];

	/* sin waveform table in 'decibel' scale */
	/* two waveforms on OPLL type chips */
	unsigned int sin_tab[SIN_LEN * 2];


	OPLL_CH P_CH[9];                /* OPLL chips have 9 channels*/
	uint8_t   instvol_r[9];           /* instrument/volume (or volume/volume in percussive mode)*/

	uint32_t  eg_cnt;                 /* global envelope generator counter    */
	uint32_t  eg_timer;               /* global envelope generator counter works at frequency = chipclock/72 */
	uint32_t  eg_timer_add;           /* step of eg_timer                     */
	uint32_t  eg_timer_overflow;      /* envelope generator timer overflows every 1 sample (on real chip) */

	uint8_t   rhythm;                 /* Rhythm mode                  */

	/* LFO */
	uint32_t  LFO_AM;
	int32_t   LFO_PM;
	uint32_t  lfo_am_cnt;
	uint32_t  lfo_am_inc;
	uint32_t  lfo_pm_cnt;
	uint32_t  lfo_pm_inc;

	uint32_t  noise_rng;              /* 23 bit noise shift register  */
	uint32_t  noise_p;                /* current noise 'phase'        */
	uint32_t  noise_f;                /* current noise period         */


/* instrument settings */
/*
    0-user instrument
    1-15 - fixed instruments
    16 -bass drum settings
    17,18 - other percussion instruments
*/
	uint8_t inst_tab[19][8];

	uint32_t  fn_tab[1024];           /* fnumber->increment counter   */

	uint8_t address;                  /* address register             */

	signed int output[2];

	// internal state
	sound_stream *  m_stream;

	int limit( int val, int max, int min );
	void advance_lfo();
	void advance();
	int op_calc(uint32_t phase, unsigned int env, signed int pm, unsigned int wave_tab);
	int op_calc1(uint32_t phase, unsigned int env, signed int pm, unsigned int wave_tab);
	void chan_calc( OPLL_CH *CH );
	void rhythm_calc( OPLL_CH *CH, unsigned int noise );
	void key_on(OPLL_SLOT *SLOT, uint32_t key_set);
	void key_off(OPLL_SLOT *SLOT, uint32_t key_clr);
	void calc_fcslot(OPLL_CH *CH, OPLL_SLOT *SLOT);
	void set_mul(int slot,int v);
	void set_ksl_tl(int chan,int v);
	void set_ksl_wave_fb(int chan,int v);
	void set_ar_dr(int slot,int v);
	void set_sl_rr(int slot,int v);
	void load_instrument(uint32_t chan, uint32_t slot, uint8_t* inst );
	void update_instrument_zero( uint8_t r );
	void write_reg(int r, int v);

};

DECLARE_DEVICE_TYPE(YM2413, ym2413_device)

class vrc7snd_device : public ym2413_device
{
public:
	vrc7snd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

private:
	static const uint8_t vrc7_table[19][8];
};

DECLARE_DEVICE_TYPE(VRC7, vrc7snd_device)

#endif // MAME_SOUND_YM2413_H