OSDN Git Service

[FMGEN][OPN2] Fix FTBFS.
[csp-qt/common_source_project-fm7.git] / source / src / vm / fmgen / opna.h
1 // ---------------------------------------------------------------------------
2 //      OPN/A/B interface with ADPCM support
3 //      Copyright (C) cisc 1998, 2003.
4 // ---------------------------------------------------------------------------
5 //      $Id: opna.h,v 1.33 2003/06/12 13:14:37 cisc Exp $
6
7 #ifndef FM_OPNA_H
8 #define FM_OPNA_H
9
10 #include "../../common.h"
11 #include "fmgen.h"
12 #include "fmtimer.h"
13 #include "psg.h"
14
15 class csp_state_utils;
16 class CSP_Logger;
17 // ---------------------------------------------------------------------------
18 //      class OPN/OPNA
19 //      OPN/OPNA \82É\97Ç\82­\8e\97\82½\89¹\82ð\90\90¬\82·\82é\89¹\8c¹\83\86\83j\83b\83g
20 //      
21 //      interface:
22 //      bool Init(uint clock, uint rate, bool, const _TCHAR* path);
23 //              \8f\89\8aú\89»\81D\82±\82Ì\83N\83\89\83X\82ð\8eg\97p\82·\82é\91O\82É\82©\82È\82ç\82¸\8cÄ\82ñ\82Å\82¨\82­\82±\82Æ\81D
24 //              OPNA \82Ì\8fê\8d\87\82Í\82±\82Ì\8aÖ\90\94\82Å\83\8a\83Y\83\80\83T\83\93\83v\83\8b\82ð\93Ç\82Ý\8d\9e\82Þ
25 //
26 //              clock:  OPN/OPNA/OPNB \82Ì\83N\83\8d\83b\83N\8eü\94g\90\94(Hz)
27 //
28 //              rate:   \90\90¬\82·\82é PCM \82Ì\95W\96{\8eü\94g\90\94(Hz)
29 //
30 //              path:   \83\8a\83Y\83\80\83T\83\93\83v\83\8b\82Ì\83p\83X(OPNA \82Ì\82Ý\97L\8cø)
31 //                              \8fÈ\97ª\8e\9e\82Í\83J\83\8c\83\93\83g\83f\83B\83\8c\83N\83g\83\8a\82©\82ç\93Ç\82Ý\8d\9e\82Þ
32 //                              \95\8e\9a\97ñ\82Ì\96\96\94ö\82É\82Í '\' \82â '/' \82È\82Ç\82ð\82Â\82¯\82é\82±\82Æ
33 //
34 //              \95Ô\82è\92l  \8f\89\8aú\89»\82É\90¬\8c÷\82·\82ê\82Πtrue
35 //
36 //      bool LoadRhythmSample(const _TCHAR* path)
37 //              (OPNA ONLY)
38 //              Rhythm \83T\83\93\83v\83\8b\82ð\93Ç\82Ý\92¼\82·\81D
39 //              path \82Í Init \82Ì path \82Æ\93¯\82\81D
40 //              
41 //      bool SetRate(uint clock, uint rate, bool)
42 //              \83N\83\8d\83b\83N\82â PCM \83\8c\81[\83g\82ð\95Ï\8dX\82·\82é
43 //              \88ø\90\94\93\99\82Í Init \82ð\8eQ\8fÆ\82Ì\82±\82Æ\81D
44 //      
45 //      void Mix(FM_SAMPLETYPE* dest, int nsamples)
46 //              Stereo PCM \83f\81[\83^\82ð nsamples \95ª\8d\87\90¬\82µ\81C dest \82Å\8en\82Ü\82é\94z\97ñ\82É
47 //              \89Á\82¦\82é(\89Á\8eZ\82·\82é)
48 //              \81Edest \82É\82Í sample*2 \8cÂ\95ª\82Ì\97Ì\88æ\82ª\95K\97v
49 //              \81E\8ai\94[\8c`\8e®\82Í L, R, L, R... \82Æ\82È\82é\81D
50 //              \81E\82 \82­\82Ü\82Å\89Á\8eZ\82È\82Ì\82Å\81C\82 \82ç\82©\82\82ß\94z\97ñ\82ð\83[\83\8d\83N\83\8a\83A\82·\82é\95K\97v\82ª\82 \82é
51 //              \81EFM_SAMPLETYPE \82ª short \8c^\82Ì\8fê\8d\87\83N\83\8a\83b\83s\83\93\83O\82ª\8ds\82í\82ê\82é.
52 //              \81E\82±\82Ì\8aÖ\90\94\82Í\89¹\8c¹\93à\95\94\82Ì\83^\83C\83}\81[\82Æ\82Í\93Æ\97§\82µ\82Ä\82¢\82é\81D
53 //                Timer \82Í Count \82Æ GetNextEvent \82Å\91\80\8dì\82·\82é\95K\97v\82ª\82 \82é\81D
54 //      
55 //      void Reset()
56 //              \89¹\8c¹\82ð\83\8a\83Z\83b\83g(\8f\89\8aú\89»)\82·\82é
57 //
58 //      void SetReg(uint reg, uint data)
59 //              \89¹\8c¹\82Ì\83\8c\83W\83X\83^ reg \82É data \82ð\8f\91\82«\8d\9e\82Þ
60 //      
61 //      uint GetReg(uint reg)
62 //              \89¹\8c¹\82Ì\83\8c\83W\83X\83^ reg \82Ì\93à\97e\82ð\93Ç\82Ý\8fo\82·
63 //              \93Ç\82Ý\8d\9e\82Þ\82±\82Æ\82ª\8fo\97\88\82é\83\8c\83W\83X\83^\82Í PSG, ADPCM \82Ì\88ê\95\94\81CID(0xff) \82Æ\82©
64 //      
65 //      uint ReadStatus()/ReadStatusEx()
66 //              \89¹\8c¹\82Ì\83X\83e\81[\83^\83X\83\8c\83W\83X\83^\82ð\93Ç\82Ý\8fo\82·
67 //              ReadStatusEx \82Í\8ag\92£\83X\83e\81[\83^\83X\83\8c\83W\83X\83^\82Ì\93Ç\82Ý\8fo\82µ(OPNA)
68 //              busy \83t\83\89\83O\82Í\8fí\82É 0
69 //      
70 //      bool ReadIRQ()
71 //              IRQ \8fo\97Í\82ð\93Ç\82Ý\8fo\82·
72 //      
73 //      bool Count(uint32 t)
74 //              \89¹\8c¹\82Ì\83^\83C\83}\81[\82ð t [clock] \90i\82ß\82é\81D
75 //              \89¹\8c¹\82Ì\93à\95\94\8fó\91Ô\82É\95Ï\89»\82ª\82 \82Á\82½\8e\9e(timer \83I\81[\83o\81[\83t\83\8d\81[)
76 //              true \82ð\95Ô\82·
77 //
78 //      uint32 GetNextEvent()
79 //              \89¹\8c¹\82Ì\83^\83C\83}\81[\82Ì\82Ç\82¿\82ç\82©\82ª\83I\81[\83o\81[\83t\83\8d\81[\82·\82é\82Ü\82Å\82É\95K\97v\82È
80 //              \8e\9e\8aÔ[clock]\82ð\95Ô\82·
81 //              \83^\83C\83}\81[\82ª\92â\8e~\82µ\82Ä\82¢\82é\8fê\8d\87\82Í ULONG_MAX \82ð\95Ô\82·\81\82Æ\8ev\82¤
82 //      
83 //      void SetVolumeFM(int db_l, int db_r)/SetVolumePSG(int db_l, int db_r) ...
84 //              \8ae\89¹\8c¹\82Ì\89¹\97Ê\82ð\81{\81|\95û\8cü\82É\92²\90ß\82·\82é\81D\95W\8f\80\92l\82Í 0.
85 //              \92P\88Ê\82Í\96ñ 1/2 dB\81C\97L\8cø\94Í\88Í\82Ì\8fã\8cÀ\82Í 20 (10dB)
86 //
87 namespace FM
88 {
89         //      OPN Base -------------------------------------------------------
90         class DLL_PREFIX OPNBase : public Timer
91         {
92         protected:
93                 int chip_num;
94         public:
95                 OPNBase();
96                 virtual ~OPNBase() {}
97                 
98                 bool    Init(uint c, uint r);
99                 virtual void Reset();
100                 bool    ReadIRQ();
101                 
102                 void    SetVolumeFM(int db_l, int db_r);
103                 void    SetVolumePSG(int db_l, int db_r);
104                 void    SetLPFCutoff(uint freq) {}      // obsolete
105                 
106                 bool is_ay3_891x;
107
108         protected:
109                 void    SetParameter(Channel4* ch, uint addr, uint data);
110                 void    SetPrescaler(uint p);
111                 void    RebuildTimeTable();
112                 void    Intr(bool value);
113                 
114                 void DeclState(void *f);
115                 void SaveState(void *f);
116                 bool LoadState(void *f);
117                 
118                 int             fmvolume_l;
119                 int             fmvolume_r;
120                 
121                 uint    clock;                          // OPN \83N\83\8d\83b\83N
122                 uint    rate;                           // FM \89¹\8c¹\8d\87\90¬\83\8c\81[\83g
123                 uint    psgrate;                        // FMGen  \8fo\97Í\83\8c\81[\83g
124                 uint    status;
125                 bool    interrupt;
126                 Channel4* csmch;
127                 
128
129                 static  uint32 lfotable[8];
130         
131         private:
132                 void    TimerA();
133                 
134         protected:
135                 uint8   prescale;
136                 Chip    chip;
137                 PSG             psg;
138         };
139
140         //      OPNA Base ------------------------------------------------------
141         class DLL_PREFIX OPNABase : public OPNBase
142         {
143         public:
144                 OPNABase();
145                 ~OPNABase();
146                 
147                 uint    ReadStatus() { return status & 0x03; }
148                 uint    ReadStatusEx();
149                 void    SetChannelMask(uint mask);
150         
151         private:
152                 void    MakeTable2();
153         
154         protected:
155                 bool    Init(uint c, uint r, bool);
156                 bool    SetRate(uint c, uint r, bool);
157
158                 void    Reset();
159                 void    SetReg(uint addr, uint data);
160                 void    SetADPCMBReg(uint reg, uint data);
161                 uint    GetReg(uint addr);      
162                 
163                 void DeclState(void *f);
164                 void SaveState(void *f);
165                 bool LoadState(void *f);
166         
167         protected:
168                 void    FMMix(Sample* buffer, int nsamples);
169                 void    Mix6(Sample* buffer, int nsamples, int activech);
170                 
171                 void    MixSubS(int activech, ISample**);
172                 void    MixSubSL(int activech, ISample**);
173
174                 void    SetStatus(uint bit);
175                 void    ResetStatus(uint bit);
176                 void    UpdateStatus();
177                 void    LFO();
178
179                 void    DecodeADPCMB();
180                 void    ADPCMBMix(Sample* dest, uint count);
181
182                 void    WriteRAM(uint data);
183                 uint    ReadRAM();
184                 int             ReadRAMN();
185                 int             DecodeADPCMBSample(uint);
186                 
187         // FM \89¹\8c¹\8aÖ\8cW
188                 uint8   pan[6];
189                 uint8   fnum2[9];
190                 
191                 uint8   reg22;
192                 uint    reg29;          // OPNA only?
193                 
194                 uint    stmask;
195                 uint    statusnext;
196
197                 uint32  lfocount;
198                 uint32  lfodcount;
199                 
200                 uint    fnum[6];
201                 uint    fnum3[3];
202                 
203         // ADPCM \8aÖ\8cW
204                 uint8*  adpcmbuf;               // ADPCM RAM
205                 uint    adpcmmask;              // \83\81\83\82\83\8a\83A\83h\83\8c\83X\82É\91Î\82·\82é\83r\83b\83g\83}\83X\83N
206                 uint    adpcmnotice;    // ADPCM \8dÄ\90\8fI\97¹\8e\9e\82É\82½\82Â\83r\83b\83g
207                 uint    startaddr;              // Start address
208                 uint    stopaddr;               // Stop address
209                 uint    memaddr;                // \8dÄ\90\92\86\83A\83h\83\8c\83X
210                 uint    limitaddr;              // Limit address/mask
211                 int             adpcmlevel;             // ADPCM \89¹\97Ê
212                 int             adpcmvolume_l;
213                 int             adpcmvolume_r;
214                 int             adpcmvol_l;
215                 int             adpcmvol_r;
216                 uint    deltan;                 // \87\99N
217                 int             adplc;                  // \8eü\94g\90\94\95Ï\8a·\97p\95Ï\90\94
218                 int             adpld;                  // \8eü\94g\90\94\95Ï\8a·\97p\95Ï\90\94\8d·\95ª\92l
219                 uint    adplbase;               // adpld \82Ì\8c³
220                 int             adpcmx;                 // ADPCM \8d\87\90¬\97p x
221                 int             adpcmd;                 // ADPCM \8d\87\90¬\97\87\99
222                 int             adpcmout_l;             // ADPCM \8d\87\90¬\8cã\82Ì\8fo\97Í
223                 int             adpcmout_r;             // ADPCM \8d\87\90¬\8cã\82Ì\8fo\97Í
224                 int             apout0_l;                       // out(t-2)+out(t-1)
225                 int             apout0_r;                       // out(t-2)+out(t-1)
226                 int             apout1_l;                       // out(t-1)+out(t)
227                 int             apout1_r;                       // out(t-1)+out(t)
228
229                 uint    adpcmreadbuf;   // ADPCM \83\8a\81[\83h\97p\83o\83b\83t\83@
230                 bool    adpcmplay;              // ADPCM \8dÄ\90\92\86
231                 int8    granuality;             
232                 bool    adpcmmask_;
233
234                 uint8   control1;               // ADPCM \83R\83\93\83g\83\8d\81[\83\8b\83\8c\83W\83X\83^\82P
235                 uint8   control2;               // ADPCM \83R\83\93\83g\83\8d\81[\83\8b\83\8c\83W\83X\83^\82Q
236                 uint8   adpcmreg[8];    // ADPCM \83\8c\83W\83X\83^\82Ì\88ê\95\94\95ª
237
238                 int             rhythmmask_;
239
240                 Channel4 ch[6];
241
242                 static void     BuildLFOTable();
243                 static int amtable[FM_LFOENTS];
244                 static int pmtable[FM_LFOENTS];
245                 static int32 tltable[FM_TLENTS+FM_TLPOS];
246                 static bool     tablehasmade;
247         };
248
249         //      OPN2 Base ------------------------------------------------------
250         class DLL_PREFIX OPN2Base : public OPNBase
251         {
252         public:
253                 OPN2Base();
254                 ~OPN2Base();
255                 
256                 uint    ReadStatus() { return status & 0x03; }
257                 uint    ReadStatusEx();
258                 void    SetChannelMask(uint mask);
259         
260         private:
261                 void    MakeTable2();
262         
263         protected:
264                 bool    Init(uint c, uint r, bool);
265                 bool    SetRate(uint c, uint r, bool);
266
267                 void    Reset();
268                 void    SetReg(uint addr, uint data);
269                 uint    GetReg(uint addr);      
270                 
271                 void DeclState(void *f);
272                 void SaveState(void *f);
273                 bool LoadState(void *f);
274         
275         protected:
276                 void    FMMix(Sample* buffer, int nsamples);
277                 void    Mix6(Sample* buffer, int nsamples, int activech);
278                 
279                 void    MixSubS(int activech, ISample**);
280                 void    MixSubSL(int activech, ISample**);
281
282                 void    SetStatus(uint bit);
283                 void    ResetStatus(uint bit);
284                 void    UpdateStatus();
285                 void    LFO();
286
287         // FM \89¹\8c¹\8aÖ\8cW
288                 uint8   pan[6];
289                 uint8   fnum2[9];
290                 
291                 uint8   reg22;
292                 uint    reg29;          // OPNA only?
293                 
294                 uint    stmask;
295                 uint    statusnext;
296
297                 uint32  lfocount;
298                 uint32  lfodcount;
299                 
300                 uint    fnum[6];
301                 uint    fnum3[3];
302                 
303                 Channel4 ch[6];
304
305                 static void     BuildLFOTable();
306                 static int amtable[FM_LFOENTS];
307                 static int pmtable[FM_LFOENTS];
308                 static int32 tltable[FM_TLENTS+FM_TLPOS];
309                 static bool     tablehasmade;
310         };
311         //      YM2203(OPN) ----------------------------------------------------
312         class DLL_PREFIX OPN : public OPNBase
313         {
314         public:
315                 OPN();
316                 virtual ~OPN() {}
317                 
318                 bool    Init(uint c, uint r, bool=false, const char* =0);
319                 bool    SetRate(uint c, uint r, bool=false);
320                 
321                 void    Reset();
322                 void    Mix(Sample* buffer, int nsamples);
323                 void    SetReg(uint addr, uint data);
324                 uint    GetReg(uint addr);
325                 uint    ReadStatus() { return status & 0x03; }
326                 uint    ReadStatusEx() { return 0xff; }
327                 
328                 void    SetChannelMask(uint mask);
329                 
330                 int             dbgGetOpOut(int c, int s) { return ch[c].op[s].dbgopout_; }
331                 int             dbgGetPGOut(int c, int s) { return ch[c].op[s].dbgpgout_; }
332                 Channel4* dbgGetCh(int c) { return &ch[c]; }
333                 
334                 void DeclState(void *f);
335                 void SaveState(void *f);
336                 bool LoadState(void *f);
337         
338         private:
339                 void    SetStatus(uint bit);
340                 void    ResetStatus(uint bit);
341                 
342                 uint    fnum[3];
343                 uint    fnum3[3];
344                 uint8   fnum2[6];
345                 
346                 Channel4 ch[3];
347         };
348
349         //      YM2608(OPNA) ---------------------------------------------------
350         class DLL_PREFIX OPNA : public OPNABase
351         {
352         public:
353                 OPNA();
354                 virtual ~OPNA();
355                 
356                 bool    Init(uint c, uint r, bool  = false, const _TCHAR* rhythmpath=0);
357                 bool    LoadRhythmSample(const _TCHAR*);
358         
359                 bool    SetRate(uint c, uint r, bool = false);
360                 void    Mix(Sample* buffer, int nsamples);
361
362                 void    Reset();
363                 void    SetReg(uint addr, uint data);
364                 uint    GetReg(uint addr);
365
366                 void    SetVolumeADPCM(int db_l, int db_r);
367                 void    SetVolumeRhythmTotal(int db_l, int db_r);
368                 void    SetVolumeRhythm(int index, int db_l, int db_r);
369
370                 uint8*  GetADPCMBuffer() { return adpcmbuf; }
371
372                 int             dbgGetOpOut(int c, int s) { return ch[c].op[s].dbgopout_; }
373                 int             dbgGetPGOut(int c, int s) { return ch[c].op[s].dbgpgout_; }
374                 Channel4* dbgGetCh(int c) { return &ch[c]; }
375
376                 void DeclState(void *f);
377                 void SaveState(void *f);
378                 bool LoadState(void *f);
379                 
380         private:
381                 struct Rhythm
382                 {
383                         uint8   pan;            // \82Ï\82ñ
384                         int8    level;          // \82¨\82ñ\82è\82å\82¤
385                         int             volume_l;               // \82¨\82ñ\82è\82å\82¤\82¹\82Á\82Ä\82¢
386                         int             volume_r;               // \82¨\82ñ\82è\82å\82¤\82¹\82Á\82Ä\82¢
387                         int16*  sample;         // \82³\82ñ\82Õ\82é
388                         uint    size;           // \82³\82¢\82¸
389                         uint    pos;            // \82¢\82¿
390                         uint    step;           // \82·\82Ä\82Á\82Õ\82¿
391                         uint    rate;           // \82³\82ñ\82Õ\82é\82Ì\82ê\81[\82Æ
392                 };
393         
394                 void    RhythmMix(Sample* buffer, uint count);
395
396         // \83\8a\83Y\83\80\89¹\8c¹\8aÖ\8cW
397                 Rhythm  rhythm[6];
398                 int8    rhythmtl;               // \83\8a\83Y\83\80\91S\91Ì\82Ì\89¹\97Ê
399                 int             rhythmtvol_l;           
400                 int             rhythmtvol_r;           
401                 uint8   rhythmkey;              // \83\8a\83Y\83\80\82Ì\83L\81[
402         };
403
404         //      YM2610/B(OPNB) ---------------------------------------------------
405         class DLL_PREFIX OPNB : public OPNABase
406         {
407         public:
408                 OPNB();
409                 virtual ~OPNB();
410                 
411                 bool    Init(uint c, uint r, bool = false,
412                                          uint8 *_adpcma = 0, int _adpcma_size = 0,
413                                          uint8 *_adpcmb = 0, int _adpcmb_size = 0);
414         
415                 bool    SetRate(uint c, uint r, bool = false);
416                 void    Mix(Sample* buffer, int nsamples);
417
418                 void    Reset();
419                 void    SetReg(uint addr, uint data);
420                 uint    GetReg(uint addr);
421                 uint    ReadStatusEx();
422
423                 void    SetVolumeADPCMATotal(int db_l, int db_r);
424                 void    SetVolumeADPCMA(int index, int db_l, int db_r);
425                 void    SetVolumeADPCMB(int db_l, int db_r);
426
427 //              void    SetChannelMask(uint mask);
428                 
429         private:
430                 struct ADPCMA
431                 {
432                         uint8   pan;            // \82Ï\82ñ
433                         int8    level;          // \82¨\82ñ\82è\82å\82¤
434                         int             volume_l;               // \82¨\82ñ\82è\82å\82¤\82¹\82Á\82Ä\82¢
435                         int             volume_r;               // \82¨\82ñ\82è\82å\82¤\82¹\82Á\82Ä\82¢
436                         uint    pos;            // \82¢\82¿
437                         uint    step;           // \82·\82Ä\82Á\82Õ\82¿
438
439                         uint    start;          // \8aJ\8en
440                         uint    stop;           // \8fI\97¹
441                         uint    nibble;         // \8e\9f\82Ì 4 bit
442                         int             adpcmx;         // \95Ï\8a·\97p
443                         int             adpcmd;         // \95Ï\8a·\97p
444                 };
445         
446                 int             DecodeADPCMASample(uint);
447                 void    ADPCMAMix(Sample* buffer, uint count);
448                 static void InitADPCMATable();
449                 
450         // ADPCMA \8aÖ\8cW
451                 uint8*  adpcmabuf;              // ADPCMA ROM
452                 int             adpcmasize;
453                 ADPCMA  adpcma[6];
454                 int8    adpcmatl;               // ADPCMA \91S\91Ì\82Ì\89¹\97Ê
455                 int             adpcmatvol_l;           
456                 int             adpcmatvol_r;           
457                 uint8   adpcmakey;              // ADPCMA \82Ì\83L\81[
458                 int             adpcmastep;
459                 uint8   adpcmareg[32];
460  
461                 static int jedi_table[(48+1)*16];
462
463                 Channel4 ch[6];
464         };
465
466         //      YM2612/3438(OPN2) ----------------------------------------------------
467         class OPN2 : public OPN2Base
468         {
469         public:
470                 OPN2();
471                 virtual ~OPN2();
472                 
473                 bool    Init(uint c, uint r, bool=false, const char* =0);
474                 bool    SetRate(uint c, uint r, bool);
475                 
476                 void    Reset();
477                 void    Mix(Sample* buffer, int nsamples);
478                 void    SetReg(uint addr, uint data);
479                 uint    GetReg(uint addr);
480                 uint    ReadStatus() { return status & 0x03; }
481                 uint    ReadStatusEx() { return 0xff; }
482                 void DeclState(void *f);
483                 void SaveState(void *f);
484                 bool LoadState(void *f);
485
486         private:
487                 //void  SetStatus(uint bit);
488                 //void  ResetStatus(uint bit);
489         // \90ü\8c`\95â\8aÔ\97p\83\8f\81[\83N
490                 int32   mixc, mixc1;
491                 
492         };
493 }
494
495 // ---------------------------------------------------------------------------
496
497 inline void FM::OPNBase::RebuildTimeTable()
498 {
499         int p = prescale;
500         prescale = -1;
501         SetPrescaler(p);
502 }
503
504 inline void FM::OPNBase::SetVolumePSG(int db_l, int db_r)
505 {
506         psg.SetVolume(db_l, db_r, is_ay3_891x);
507 }
508
509 #endif // FM_OPNA_H