// 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); DECLARE_WRITE8_MEMBER( write ); DECLARE_WRITE8_MEMBER( register_port_w ); DECLARE_WRITE8_MEMBER( data_port_w ); protected: // 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; private: struct OPLL_SLOT { uint32_t ar; /* attack rate: AR<<2 */ uint32_t dr; /* decay rate: DR<<2 */ uint32_t rr; /* release rate:RR<<2 */ uint8_t KSR; /* key scale rate */ uint8_t ksl; /* keyscale level */ uint8_t ksr; /* key scale rate: kcode>>KSR */ uint8_t mul; /* multiple: mul_tab[ML] */ /* Phase Generator */ uint32_t phase; /* frequency counter */ uint32_t freq; /* frequency counter step */ uint8_t fb_shift; /* feedback shift value */ int32_t op1_out[2]; /* slot1 output for feedback */ /* Envelope Generator */ uint8_t eg_type; /* percussive/nonpercussive mode*/ uint8_t state; /* phase type */ uint32_t TL; /* total level: TL << 2 */ int32_t TLL; /* adjusted now TL */ int32_t volume; /* envelope counter */ uint32_t sl; /* sustain level: sl_tab[SL] */ uint8_t eg_sh_dp; /* (dump state) */ uint8_t eg_sel_dp; /* (dump state) */ uint8_t eg_sh_ar; /* (attack state) */ uint8_t eg_sel_ar; /* (attack state) */ uint8_t eg_sh_dr; /* (decay state) */ uint8_t eg_sel_dr; /* (decay state) */ uint8_t eg_sh_rr; /* (release state for non-perc.)*/ uint8_t eg_sel_rr; /* (release state for non-perc.)*/ uint8_t eg_sh_rs; /* (release state for perc.mode)*/ uint8_t eg_sel_rs; /* (release state for perc.mode)*/ uint32_t key; /* 0 = KEY OFF, >0 = KEY ON */ /* LFO */ uint32_t AMmask; /* LFO Amplitude Modulation enable mask */ uint8_t vib; /* LFO Phase Modulation enable flag (active high)*/ /* waveform select */ unsigned int wavetable; }; struct OPLL_CH { OPLL_SLOT SLOT[2]; /* phase generator state */ uint32_t block_fnum; /* block+fnum */ uint32_t fc; /* Freq. freqement base */ uint32_t ksl_base; /* KeyScaleLevel Base step */ uint8_t kcode; /* key code (for key scaling) */ uint8_t sus; /* sus on/off (release speed in percussive mode)*/ }; enum { RATE_STEPS = (8), /* sinwave entries */ SIN_BITS = 10, SIN_LEN = (1<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) #endif // MAME_SOUND_YM2413_H