Subversion Repositories pentevo

Rev

Rev 1100 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed | ?url?

  1. // This file is taken from the openMSX project.
  2. // The file has been modified to be built in the blueMSX environment.
  3.  
  4. #ifndef __YMF262_HH__
  5. #define __YMF262_HH__
  6.  
  7. #include "../sysdefs.h"
  8.  
  9. using namespace std;
  10.  
  11.  
  12. typedef unsigned long  EmuTime;
  13.  
  14. #define MAX_BUFFER_SIZE 10000
  15.  
  16. class TimerCallback
  17. {
  18.         public:
  19.                 virtual void callback(u8 value) = 0;
  20. };
  21.  
  22. template<unsigned timerFreq, u8 flag>
  23. struct Timer
  24. {
  25.     unsigned tStatesPerTick;
  26.     EmuTime timerPeriod;
  27.     EmuTime startTime;
  28.     u8 flags;
  29.     bool isStarted;
  30.  
  31.     void init(unsigned tStatesPerSecond)
  32.     {
  33.         tStatesPerTick = tStatesPerSecond / timerFreq;
  34.         flags = 0;
  35.         isStarted = false;
  36.     }
  37.  
  38.     void setValue(u8 value)
  39.     {
  40.         timerPeriod = tStatesPerTick * (256 - value);
  41.     }
  42.  
  43.     void setStart(bool start, const EmuTime &time)
  44.     {
  45.         isStarted = start;
  46.         startTime = time;
  47.     }
  48.  
  49.     void resetFlags()
  50.     {
  51.         flags = 0;
  52.     }
  53.  
  54.     u8 poll(const EmuTime &time)
  55.     {
  56.         if (isStarted)
  57.         {
  58.             EmuTime dt = time - startTime;
  59.             while (dt > timerPeriod)
  60.             {
  61.                 dt -= timerPeriod;
  62.                 startTime += timerPeriod;
  63.                 flags |= (flag | 0x80);
  64.             }
  65.         }
  66.  
  67.         return flags;
  68.     }
  69. };
  70.  
  71. #ifndef OPENMSX_SOUNDDEVICE
  72. #define OPENMSX_SOUNDDEVICE
  73.  
  74. class SoundDevice
  75. {
  76.         public:
  77.         SoundDevice() : internalMuted(true) {}
  78.                 void setVolume(short newVolume) {
  79.                 setInternalVolume(newVolume);
  80.         }
  81.  
  82.         protected:
  83.                 virtual void setInternalVolume(short newVolume) = 0;
  84.         void setInternalMute(bool muted) { internalMuted = muted; }
  85.         bool isInternalMuted() const { return internalMuted; }
  86.         public:
  87.                 virtual void setSampleRate(int newSampleRate, int Oversampling) = 0;
  88.                 virtual int* updateBuffer(int length) = 0;
  89.  
  90.         private:
  91.                 bool internalMuted;
  92. };
  93.  
  94. #endif
  95.  
  96. class YMF262Slot
  97. {
  98.         public:
  99.                 YMF262Slot();
  100.                 inline int volume_calc(u8 LFO_AM);
  101.                 inline void FM_KEYON(u8 key_set);
  102.                 inline void FM_KEYOFF(u8 key_clr);
  103.  
  104.                 u8 ar;  // attack rate: AR<<2
  105.                 u8 dr;  // decay rate:  DR<<2
  106.                 u8 rr;  // release rate:RR<<2
  107.                 u8 KSR; // key scale rate
  108.                 u8 ksl; // keyscale level
  109.                 u8 ksr; // key scale rate: kcode>>KSR
  110.                 u8 mul; // multiple: mul_tab[ML]
  111.  
  112.                 // Phase Generator
  113.                 unsigned int Cnt;       // frequency counter
  114.                 unsigned int Incr;      // frequency counter step
  115.                 u8 FB;  // feedback shift value
  116.                 int op1_out[2]; // slot1 output for feedback
  117.                 u8 CON; // connection (algorithm) type
  118.  
  119.                 // Envelope Generator
  120.                 u8 eg_type;     // percussive/non-percussive mode
  121.                 u8 state;       // phase type
  122.                 unsigned int TL;        // total level: TL << 2
  123.                 int TLL;        // adjusted now TL
  124.                 int volume;     // envelope counter
  125.                 int sl;         // sustain level: sl_tab[SL]
  126.  
  127.                 unsigned int eg_m_ar;// (attack state)
  128.                 u8 eg_sh_ar;    // (attack state)
  129.                 u8 eg_sel_ar;   // (attack state)
  130.                 unsigned int eg_m_dr;// (decay state)
  131.                 u8 eg_sh_dr;    // (decay state)
  132.                 u8 eg_sel_dr;   // (decay state)
  133.                 unsigned int eg_m_rr;// (release state)
  134.                 u8 eg_sh_rr;    // (release state)
  135.                 u8 eg_sel_rr;   // (release state)
  136.  
  137.                 u8 key; // 0 = KEY OFF, >0 = KEY ON
  138.  
  139.                 // LFO
  140.                 u8  AMmask;     // LFO Amplitude Modulation enable mask
  141.                 u8 vib; // LFO Phase Modulation enable flag (active high)
  142.  
  143.                 // waveform select
  144.                 u8 waveform_number;
  145.                 unsigned int wavetable;
  146.  
  147.                 int connect;    // slot output pointer
  148. };
  149.  
  150. class YMF262Channel
  151. {
  152.         public:
  153.                 YMF262Channel();
  154.                 void chan_calc(u8 LFO_AM);
  155.                 void chan_calc_ext(u8 LFO_AM);
  156.                 void CALC_FCSLOT(YMF262Slot &slot);
  157.  
  158.                 YMF262Slot slots[2];
  159.  
  160.                 int block_fnum; // block+fnum
  161.                 int fc;         // Freq. Increment base
  162.                 int ksl_base;   // KeyScaleLevel Base step
  163.                 u8 kcode;       // key code (for key scaling)
  164.  
  165.                 // there are 12 2-operator channels which can be combined in pairs
  166.                 // to form six 4-operator channel, they are:
  167.                 //  0 and 3,
  168.                 //  1 and 4,
  169.                 //  2 and 5,
  170.                 //  9 and 12,
  171.                 //  10 and 13,
  172.                 //  11 and 14
  173.                 u8 extended;    // set to 1 if this channel forms up a 4op channel with another channel(only used by first of pair of channels, ie 0,1,2 and 9,10,11)
  174. };
  175.  
  176. // Bitmask for register 0x04
  177. static const int R04_ST1          = 0x01;       // Timer1 Start
  178. static const int R04_ST2          = 0x02;       // Timer2 Start
  179. static const int R04_MASK_T2      = 0x20;       // Mask Timer2 flag
  180. static const int R04_MASK_T1      = 0x40;       // Mask Timer1 flag
  181. static const int R04_IRQ_RESET    = 0x80;       // IRQ RESET
  182.  
  183. // Bitmask for status register
  184. static const int STATUS_T2      = R04_MASK_T2;
  185. static const int STATUS_T1      = R04_MASK_T1;
  186.  
  187. class YMF262 : public SoundDevice, public TimerCallback
  188. {
  189.         public:
  190.                 YMF262(short volume, const EmuTime &time);
  191.                 virtual ~YMF262();
  192.                
  193.                 void reset(const EmuTime &time, unsigned tStatesPerSecond);
  194.                 void writeReg(int r, u8 v, const EmuTime &time);
  195.                 u8 peekReg(int reg);
  196.                 u8 readReg(int reg);
  197.                 u8 peekStatus(const EmuTime& time);
  198.                 u8 readStatus(const EmuTime& time);
  199.                
  200.                 virtual void setInternalVolume(short volume);
  201.                 virtual void setSampleRate(int sampleRate, int Oversampling);
  202.                 virtual int* updateBuffer(int length);
  203.  
  204.                 void callback(u8 flag);
  205.  
  206.         private:
  207.                 void writeRegForce(int r, u8 v, const EmuTime &time);
  208.                 void init_tables(void);
  209.                 void setStatus(u8 flag);
  210.                 void resetStatus(u8 flag);
  211.                 void changeStatusMask(u8 flag);
  212.                 void advance_lfo();
  213.                 void advance();
  214.                 void chan_calc_rhythm(bool noise);
  215.                 void set_mul(u8 sl, u8 v);
  216.                 void set_ksl_tl(u8 sl, u8 v);
  217.                 void set_ar_dr(u8 sl, u8 v);
  218.                 void set_sl_rr(u8 sl, u8 v);
  219.                 void update_channels(YMF262Channel &ch);
  220.                 void checkMute();
  221.                 bool checkMuteHelper();
  222.  
  223.         int buffer[MAX_BUFFER_SIZE];
  224.                 Timer<12500, STATUS_T1> timer1; //  80us
  225.                 Timer< 3125, STATUS_T2> timer2; // 320us
  226.  
  227.         int oplOversampling;
  228.  
  229.         YMF262Channel channels[18];     // OPL3 chips have 18 channels
  230.  
  231.                 u8 reg[512];
  232.  
  233.         unsigned int pan[18*4];         // channels output masks (0xffffffff = enable); 4 masks per one channel
  234.  
  235.                 unsigned int eg_cnt;            // global envelope generator counter
  236.                 unsigned int eg_timer;          // global envelope generator counter works at frequency = chipclock/288 (288=8*36)
  237.                 unsigned int eg_timer_add;              // step of eg_timer
  238.  
  239.                 unsigned int fn_tab[1024];              // fnumber->increment counter
  240.  
  241.                 // LFO
  242.                 u8 LFO_AM;
  243.                 u8 LFO_PM;
  244.                
  245.                 u8 lfo_am_depth;
  246.                 u8 lfo_pm_depth_range;
  247.                 unsigned int lfo_am_cnt;
  248.                 unsigned int lfo_am_inc;
  249.                 unsigned int lfo_pm_cnt;
  250.                 unsigned int lfo_pm_inc;
  251.  
  252.                 unsigned int noise_rng;         // 23 bit noise shift register
  253.                 unsigned int noise_p;           // current noise 'phase'
  254.                 unsigned int noise_f;           // current noise period
  255.  
  256.                 bool OPL3_mode;                 // OPL3 extension enable flag
  257.                 u8 rhythm;                      // Rhythm mode
  258.                 u8 nts;                 // NTS (note select)
  259.  
  260.                 u8 status;                      // status flag
  261.                 u8 status2;
  262.                 u8 statusMask;          // status mask
  263.  
  264.                 int chanout[20];                // 18 channels + two phase modulation
  265.                 short maxVolume;
  266. };
  267.  
  268. #endif
  269.  
  270.