Diff for /np2/cbus/amd98.c between versions 1.6 and 1.16

version 1.6, 2003/12/08 00:55:30 version 1.16, 2005/05/13 05:47:24
Line 1 Line 1
 #include        "compiler.h"  #include        "compiler.h"
   #include        <math.h>
 #include        "pccore.h"  #include        "pccore.h"
 #include        "iocore.h"  #include        "iocore.h"
 #include        "cbuscore.h"  #include        "cbuscore.h"
Line 7 Line 8
 #include        "fmboard.h"  #include        "fmboard.h"
   
   
 static void setamd98event(BOOL absolute) {  // ないよりあったほーが良い程度のリズム…
   static struct {
           PMIXHDR hdr;
           PMIXTRK trk[4];
           UINT    rate;
           UINT    enable;
   } amd98r;
   
   
   static void pcmmake1(PMIXDAT *dat, UINT rate,
                                                                                           int vol, double hz, double env) {
   
           UINT    i;
           double  x;
           double  y;
           double  slast;
           double  s;
           double  v;
           UINT    size;
           SINT16  *ptr;
   
           x = 44100.0 * 2.0 * PI / ((double)rate * hz);
           y = 44100.0 / 256.0 / (double)rate;
           slast = 0.0;
           for (i=0; i<rate; i++) {
                   s = sin(x * (double)i);
                   v = pow(env, (double)i * y) * (double)vol;
                   if ((v < 128.0) && (slast < 0.0) && (s >= 0.0)) {
                           break;
                   }
                   slast = s;
           }
           size = i;
           if (!size) {
                   return;
           }
           ptr = (SINT16 *)_MALLOC(size * sizeof(SINT16), "AMD98");
           if (ptr == NULL) {
                   return;
           }
           for (i=0; i<size; i++) {
                   s = sin(x * (double)i);
                   v = pow(env, (double)i * y) * (double)vol;
                   ptr[i] = (SINT16)(s * v);
           }
           dat->sample = ptr;
           dat->samples = size;
   }
   
         SINT32  cnt;  static void pcmmake2(PMIXDAT *dat, UINT rate,
                                                                   int vol, double hz, double env, double k) {
   
         if (pit.value[3] > 8) {                                         // 根拠なし          UINT    i;
                 cnt = pc.multiple * pit.value[3];          double  x;
           double  y;
           double  p;
           double  s;
           double  slast;
           double  v;
           UINT    size;
           SINT16  *ptr;
   
           x = 2.0 * PI * hz / (double)rate;
           y = 44100.0 / 256.0 / (double)rate;
           p = 0.0;
           slast = 0.0;
           for (i=0; i<rate; i++) {
                   p += x * pow(k, (double)i * y);
                   s = sin(p);
                   v = pow(env, (double)i * y) * (double)vol;
                   if ((v < 128.0) && (slast < 0.0) && (s >= 0.0)) {
                           break;
                   }
                   slast = s;
           }
           size = i;
           if (!size) {
                   return;
           }
           ptr = (SINT16 *)_MALLOC(size * sizeof(SINT16), "AMD98");
           if (ptr == NULL) {
                   return;
           }
           p = 0.0;
           for (i=0; i<size; i++) {
                   p += x * pow(k, (double)i * y);
                   s = sin(p);
                   v = pow(env, (double)i * y) * (double)vol;
                   ptr[i] = (SINT16)(s * v);
           }
           dat->sample = ptr;
           dat->samples = size;
   }
   
   
   void amd98_initialize(UINT rate) {
   
           ZeroMemory(&amd98r, sizeof(amd98r));
           amd98r.rate = rate;
   }
   
   void amd98_deinitialize(void) {
   
           int             i;
           void    *ptr;
   
           amd98r.hdr.enable = 0;
           for (i=0; i<4; i++) {
                   ptr = amd98r.trk[i].data.sample;
                   amd98r.trk[i].data.sample = NULL;
                   if (ptr) {
                           _MFREE(ptr);
                   }
           }
   }
   
   static void amd98_rhythmload(void) {
   
           UINT    i;
   
           if (!amd98r.hdr.enable) {
                   TRACEOUT(("AMD98 Rhythm load"));
                   amd98r.hdr.enable = 0x0f;
                   // bd
                   pcmmake1(&amd98r.trk[0].data, amd98r.rate,
                                                           24000, 889.0476190476, 0.9446717478);
                   // lt
                   pcmmake2(&amd98r.trk[1].data, amd98r.rate,
                                                           6400, 172.9411764706, 0.8665145391, 0.9960000000);
                   // ht
                   pcmmake2(&amd98r.trk[2].data, amd98r.rate,
                                                           9600, 213.0000000000, 0.8665145391, 0.9960000000);
                   // sd
                   pcmmake1(&amd98r.trk[3].data, amd98r.rate,
                                                           12000, 255.4400000000, 0.8538230481);
                   for (i=0; i<4; i++) {
                           amd98r.trk[i].flag = PMIXFLAG_L | PMIXFLAG_R;
                           amd98r.trk[i].volume = 1 << 12;
                   }
           }
   }
   
   
   // ----
   
   static void amd98_rhythm(UINT map) {
   
           PMIXTRK *trk;
           UINT    bit;
   
           map &= 0x0f;
           if (map == 0) {
                   return;
           }
           sound_sync();
           trk = amd98r.trk;
           bit = 0x01;
           do {
                   if ((map & bit) && (trk->data.sample)) {
                           trk->pcm = trk->data.sample;
                           trk->remain = trk->data.samples;
                           amd98r.hdr.playing |= bit;
                   }
                   trk++;
                   bit <<= 1;
           } while (bit < 0x10);
   }
   
   
   // ----
   
   static void setamd98event(UINT32 cnt, BOOL absolute) {
   
           if (cnt > 8) {                                                          // 根拠なし
                   cnt *= pccore.multiple;
         }          }
         else {          else {
                 cnt = pc.multiple << 16;                  cnt = pccore.multiple << 16;
         }          }
         if (pc.baseclock == PCBASECLOCK25) {          if (!(pccore.cpumode & CPUMODE_8MHZ)) {
                 cnt = cnt * 16 / 13;                                    // cnt * 2457600 / 1996800                  cnt = cnt * 16 / 13;                                    // cnt * 2457600 / 1996800
         }          }
         nevent_set(NEVENT_MUSICGEN, cnt, amd98int, absolute);          nevent_set(NEVENT_MUSICGEN, cnt, amd98int, absolute);
Line 25  static void setamd98event(BOOL absolute) Line 195  static void setamd98event(BOOL absolute)
   
 void amd98int(NEVENTITEM item) {  void amd98int(NEVENTITEM item) {
   
           PITCH   pitch;
   
         if (item->flag & NEVENT_SETEVENT) {          if (item->flag & NEVENT_SETEVENT) {
                 if ((pit.mode[3] & 0x0c) == 0x04) {                  pitch = pit.ch + 4;
                   if ((pitch->ctrl & 0x0c) == 0x04) {
                         // レートジェネレータ                          // レートジェネレータ
                         setamd98event(NEVENT_RELATIVE);                          setamd98event(pitch->value, NEVENT_RELATIVE);
                 }                  }
         }          }
         pic_setirq(0x0d);          pic_setirq(0x0d);
Line 40  void amd98int(NEVENTITEM item) { Line 213  void amd98int(NEVENTITEM item) {
   
 static void IOOUTCALL amd_od8(UINT port, REG8 dat) {  static void IOOUTCALL amd_od8(UINT port, REG8 dat) {
   
         opn.opnreg = dat;          opn.addr = dat;
         (void)port;          (void)port;
 }  }
   
 static void IOOUTCALL amd_od9(UINT port, REG8 dat) {  static void IOOUTCALL amd_od9(UINT port, REG8 dat) {
   
         opn.extreg = dat;          opn.addr2 = dat;
         (void)port;          (void)port;
 }  }
   
 static void IOOUTCALL amd_oda(UINT port, REG8 dat) {  static void IOOUTCALL amd_oda(UINT port, REG8 dat) {
   
         if (opn.opnreg < 0x0e) {          UINT    addr;
                 psggen_setreg(&psg1, opn.opnreg, dat);  
           addr = opn.addr;
           if (addr < 0x0e) {
                   psggen_setreg(&psg1, addr, dat);
         }          }
         else if (opn.opnreg == 0x0f) {          else if (addr == 0x0f) {
                 psg1.reg.io2 = dat;                  psg1.reg.io2 = dat;
         }          }
         (void)port;          (void)port;
Line 63  static void IOOUTCALL amd_oda(UINT port, Line 239  static void IOOUTCALL amd_oda(UINT port,
   
 static void IOOUTCALL amd_odb(UINT port, REG8 dat) {  static void IOOUTCALL amd_odb(UINT port, REG8 dat) {
   
         if (opn.extreg < 0x0e) {          UINT    addr;
                 psggen_setreg(&psg2, opn.extreg, dat);  
           addr = opn.addr2;
           if (addr < 0x0e) {
                   psggen_setreg(&psg2, addr, dat);
         }          }
         else if (opn.extreg == 0x0f) {          else if (addr == 0x0f) {
                 REG8 b;                  REG8 b;
                 b = psg2.reg.io2;                  b = psg2.reg.io2;
                 if ((b & 1) > (dat & 1)) {                  if ((b & 1) > (dat & 1)) {
                         b &= 0xc2;                          b &= 0xc2;
                         if (b == 0x42) {                          if (b == 0x42) {
 //                              TRACEOUT(0xfff0, psg_1.reg.io2);  
                                 amd98.psg3reg = psg1.reg.io2;                                  amd98.psg3reg = psg1.reg.io2;
                         }                          }
                         else if (b == 0x40) {                          else if (b == 0x40) {
 //                              TRACEOUT(0xfff1, psg_1.reg.io2);  
                                 if (amd98.psg3reg < 0x0e) {                                  if (amd98.psg3reg < 0x0e) {
                                         psggen_setreg(&psg3, amd98.psg3reg,                                          psggen_setreg(&psg3, amd98.psg3reg, psg1.reg.io2);
                                                                                                 psg1.reg.io2);  
                                 }                                  }
                                 else if (amd98.psg3reg == 0x0f) {                                  else if (amd98.psg3reg == 0x0f) {
                                         int r;                                          amd98_rhythm(psg1.reg.io2);
 static const BYTE amdr[] = {0x01, 0x08, 0x10, 0x20, 0x06, 0x40};  
                                         sound_sync();  
                                         for (r=0; r<6; r++) {  
                                                 if (psg1.reg.io2 & amdr[r]) {  
 //                                                      rhythm_play(&rhythm, r, 0);  
                                                 }  
                                         }  
                                 }                                  }
                         }                          }
                 }                  }
Line 100  static const BYTE amdr[] = {0x01, 0x08,  Line 269  static const BYTE amdr[] = {0x01, 0x08, 
   
 static void IOOUTCALL amd_odc(UINT port, REG8 dat) {  static void IOOUTCALL amd_odc(UINT port, REG8 dat) {
   
         pit_setcount(3, dat);          PITCH   pitch;
         setamd98event(NEVENT_ABSOLUTE);  
           pitch = pit.ch + 4;
           if (pit_setcount(pitch, dat)) {
                   return;
           }
           setamd98event(pitch->value, NEVENT_ABSOLUTE);
         (void)port;          (void)port;
 }  }
   
 static void IOOUTCALL amd_ode(UINT port, REG8 dat) {  static void IOOUTCALL amd_ode(UINT port, REG8 dat) {
   
         pit_setflag(3, dat);          pit_setflag(pit.ch + 4, dat);
           (void)port;
   }
   
   static REG8 IOINPCALL amd_ida(UINT port) {
   
           UINT    addr;
   
           addr = opn.addr;
           if (addr < 0x0e) {
                   return(psggen_getreg(&psg1, addr));
           }
           else if (addr == 0x0f) {
                   return(psg1.reg.io2);
           }
           (void)port;
           return(0xff);
   }
   
   static REG8 IOINPCALL amd_idb(UINT port) {
   
           UINT    addr;
   
           addr = opn.addr2;
           if (addr < 0x0e) {
                   return(psggen_getreg(&psg2, addr));
           }
           else if (addr == 0x0f) {
                   return(psg2.reg.io2);
           }
         (void)port;          (void)port;
           return(0xff);
 }  }
   
   #if defined(TRACE)
   static REG8 IOINPCALL amd_inp(UINT port) {
   
           TRACEOUT(("amd inp - %.4x", port));
           return(0xff);
   }
   #endif
   
 // ----  // ----
   
Line 123  static void psgpanset(PSGGEN psg) { Line 334  static void psgpanset(PSGGEN psg) {
   
 void amd98_bind(void) {  void amd98_bind(void) {
   
           amd98_rhythmload();
   
         psgpanset(&psg1);          psgpanset(&psg1);
         psgpanset(&psg2);          psgpanset(&psg2);
         psgpanset(&psg3);          psgpanset(&psg3);
           psggen_restore(&psg1);
           psggen_restore(&psg2);
           psggen_restore(&psg3);
         sound_streamregist(&psg1, (SOUNDCB)psggen_getpcm);          sound_streamregist(&psg1, (SOUNDCB)psggen_getpcm);
         sound_streamregist(&psg2, (SOUNDCB)psggen_getpcm);          sound_streamregist(&psg2, (SOUNDCB)psggen_getpcm);
         sound_streamregist(&psg3, (SOUNDCB)psggen_getpcm);          sound_streamregist(&psg3, (SOUNDCB)psggen_getpcm);
 //      sound_streamregist(&rhythm, (SOUNDCB)rhythm_getpcm);          sound_streamregist(&amd98r, (SOUNDCB)pcmmix_getpcm);
         iocore_attachout(0xd8, amd_od8);          iocore_attachout(0xd8, amd_od8);
         iocore_attachout(0xd9, amd_od9);          iocore_attachout(0xd9, amd_od9);
         iocore_attachout(0xda, amd_oda);          iocore_attachout(0xda, amd_oda);
         iocore_attachout(0xdb, amd_odb);          iocore_attachout(0xdb, amd_odb);
         iocore_attachout(0xdc, amd_odc);          iocore_attachout(0xdc, amd_odc);
         iocore_attachout(0xde, amd_ode);          iocore_attachout(0xde, amd_ode);
   
           iocore_attachinp(0xda, amd_ida);
           iocore_attachinp(0xdb, amd_idb);
   #if defined(TRACE)
           iocore_attachinp(0xd8, amd_inp);
           iocore_attachinp(0xd9, amd_inp);
           iocore_attachinp(0xdc, amd_inp);
           iocore_attachinp(0xde, amd_inp);
   #endif
 }  }
   

Removed from v.1.6  
changed lines
  Added in v.1.16


RetroPC.NET-CVS <cvs@retropc.net>