Diff for /np2/win9x/juliet.cpp between versions 1.1 and 1.5

version 1.1, 2003/10/16 17:58:49 version 1.5, 2004/02/13 08:01:12
Line 1 Line 1
 #include        <windows.h>  #include        "compiler.h"
 #include        "common.h"  
   #if defined(SUPPORT_ROMEO)
   
 #include        "romeo.h"  #include        "romeo.h"
 #include        "juliet.h"  #include        "juliet.h"
Line 7 Line 8
   
 enum {  enum {
         ROMEO_AVAIL                     = 0x01,          ROMEO_AVAIL                     = 0x01,
         ROMEO_YMF288            = 0x02,                 // 必ず存在する筈?          ROMEO_YMF288            = 0x02,
         ROMEO_YM2151            = 0x04          ROMEO_YM2151            = 0x04
 };  };
   
 typedef struct {  typedef struct {
         HMODULE                 mod;          HMODULE mod;
   
         PCIFINDDEV              finddev;          ULONG   (WINAPI * finddev)(ULONG ven, ULONG dev, ULONG index);
         PCICFGREAD32    read32;          ULONG   (WINAPI * read32)(ULONG pciaddr, ULONG regaddr);
         PCIMEMWR8               out8;          void    (WINAPI * out8)(ULONG addr, UCHAR param);
         PCIMEMWR16              out16;          void    (WINAPI * out16)(ULONG addr, USHORT param);
         PCIMEMWR32              out32;          void    (WINAPI * out32)(ULONG addr, ULONG param);
         PCIMEMRD8               in8;          UCHAR   (WINAPI * in8)(ULONG addr);
         PCIMEMRD16              in16;          USHORT  (WINAPI * in16)(ULONG addr);
         PCIMEMRD32              in32;          ULONG   (WINAPI * in32)(ULONG addr);
   
         ULONG                   addr;          ULONG   addr;
         ULONG                   irq;          ULONG   irq;
         ULONG                   avail;          ULONG   avail;
   
           UINT8   algo[8];
           UINT8   ttl[8*4];
           UINT8   psgmix;
 } _ROMEO;  } _ROMEO;
   
   
 #define ROMEO_TPTR(member)      (int)&(((_ROMEO *)NULL)->member)  static const UINT8 opmask[] = {0x08,0x08,0x08,0x08,0x0c,0x0e,0x0e,0x0f};
   
   
 typedef struct {  typedef struct {
         char    *symbol;  const char      *symbol;
         int             addr;          UINT    addr;
 } DLLPROCESS;  } DLLPROC;
   
   static const DLLPROC dllproc[] = {
                                   {FN_PCIFINDDEV,         offsetof(_ROMEO, finddev)},
                                   {FN_PCICFGREAD32,       offsetof(_ROMEO, read32)},
                                   {FN_PCIMEMWR8,          offsetof(_ROMEO, out8)},
                                   {FN_PCIMEMWR16,         offsetof(_ROMEO, out16)},
                                   {FN_PCIMEMWR32,         offsetof(_ROMEO, out32)},
                                   {FN_PCIMEMRD8,          offsetof(_ROMEO, in8)},
                                   {FN_PCIMEMRD16,         offsetof(_ROMEO, in16)},
                                   {FN_PCIMEMRD32,         offsetof(_ROMEO, in32)}};
   
   
   static  _ROMEO          romeo = {NULL};
   
 static const DLLPROCESS dllproc[] = {  
                                 {FN_PCIFINDDEV,         ROMEO_TPTR(finddev)},  
                                 {FN_PCICFGREAD32,       ROMEO_TPTR(read32)},  
                                 {FN_PCIMEMWR8,          ROMEO_TPTR(out8)},  
                                 {FN_PCIMEMWR16,         ROMEO_TPTR(out16)},  
                                 {FN_PCIMEMWR32,         ROMEO_TPTR(out32)},  
                                 {FN_PCIMEMRD8,          ROMEO_TPTR(in8)},  
                                 {FN_PCIMEMRD16,         ROMEO_TPTR(in16)},  
                                 {FN_PCIMEMRD32,         ROMEO_TPTR(in32)}};  
   
   
 static  _ROMEO          romeo = {NULL};  // pciFindPciDevice使うと、OS起動後一発目に見つけられないことが多いので、
   // 自前で検索する(矢野さん方式)
   
   #define PCIBUSDEVFUNC(b, d, f)  (((b) << 8) | ((d) << 3) | (f))
   #define DEVVEND(v, d)                   ((ULONG)((v) | ((d) << 16)))
   
   static ULONG searchRomeo(void) {
   
           UINT    bus;
           UINT    dev;
           UINT    func;
           ULONG   addr;
           ULONG   dev_vend;
   
           for (bus=0; bus<0x100; bus++) {
                   for (dev=0; dev<0x20; dev++) {
                           for (func=0; func<0x08; func++) {
                                   addr = PCIBUSDEVFUNC(bus, dev, func);
                                   dev_vend = romeo.read32(addr, 0x0000);
                                   if ((dev_vend == DEVVEND(ROMEO_VENDORID, ROMEO_DEVICEID)) ||
                                           (dev_vend == DEVVEND(ROMEO_VENDORID, ROMEO_DEVICEID2))) {
                                           return(addr);
                                   }
                           }
                   }
           }
           return((ULONG)0xffffffff);
   }
   
   
 BOOL juliet_load(void) {  
   
                 int                     i;  BOOL juliet_initialize(void) {
 const   DLLPROCESS      *dp;  
                 BOOL            r = SUCCESS;  
   
         juliet_unload();          HMODULE         mod;
   const DLLPROC   *d;
   const DLLPROC   *dterm;
           long            proc;
           ULONG           pciaddr;
   
         romeo.mod = LoadLibrary(PCIDEBUG_DLL);          juliet_deinitialize();
         if (romeo.mod == NULL) {  
                 return(FAILURE);          mod = LoadLibrary(PCIDEBUG_DLL);
           if (mod == NULL) {
                   goto jini_err1;
         }          }
         for (i=0, dp=dllproc; i<sizeof(dllproc)/sizeof(DLLPROCESS); i++, dp++) {          romeo.mod = mod;
                 FARPROC proc;          d = dllproc;
                 proc = GetProcAddress(romeo.mod, dp->symbol);          dterm = d + sizeof(dllproc)/sizeof(DLLPROC);
                 if (proc == NULL) {          while(d < dterm) {
                         r = FAILURE;                  proc = (long)GetProcAddress(mod, d->symbol);
                         break;                  if (proc == (long)NULL) {
                           MessageBox(NULL, "0", "?", MB_OK);
                           goto jini_err2;
                 }                  }
                 *(DWORD *)(((BYTE *)&romeo) + (dp->addr)) = (DWORD)proc;                  *(long *)(((BYTE *)&romeo) + (d->addr)) = proc;
                   d++;
         }          }
         if (r) {  
                 juliet_unload();          pciaddr = searchRomeo();
           if (pciaddr == (ULONG)0xffffffff) {
                   goto jini_err2;
         }          }
         return(r);          romeo.addr = romeo.read32(pciaddr, ROMEO_BASEADDRESS1);
 }          romeo.irq  = romeo.read32(pciaddr, ROMEO_PCIINTERRUPT) & 0xff;
           if (!romeo.addr) {
                   goto jini_err2;
           }
           romeo.avail = ROMEO_AVAIL | ROMEO_YMF288;
           juliet_YMF288Reset();
           TRACEOUT(("ROMEO enable"));
           return(SUCCESS);
   
   jini_err2:
           juliet_deinitialize();
   
   jini_err1:
           return(FAILURE);
   }
   
 void juliet_unload(void) {  void juliet_deinitialize(void) {
   
         if (romeo.mod) {          if (romeo.mod) {
                 FreeLibrary(romeo.mod);                  FreeLibrary(romeo.mod);
         }          }
         ZeroMemory(&romeo, sizeof(romeo));          ZeroMemory(&romeo, sizeof(romeo));
           FillMemory(romeo.ttl, 8*4, 0x7f);
           romeo.psgmix = 0x3f;
 }  }
   
   
 // ----  // ---- YMF288部
   
 ULONG juliet_prepare(void) {  
   
         ULONG   r;  static void YMF288A(UINT8 addr, UINT8 data) {
         ULONG   pciaddr;  
   
         if (romeo.mod == NULL) {          while(romeo.in8(romeo.addr + ROMEO_YMF288ADDR1) & 0x80) {
                 return(FAILURE);                  Sleep(0);
         }          }
           romeo.out8(romeo.addr + ROMEO_YMF288ADDR1, addr);
         r = romeo.finddev(ROMEO_VENDORID, ROMEO_DEVICEID, 0);          while(romeo.in8(romeo.addr + ROMEO_YMF288ADDR1) & 0x80) {
         if (r & 0xff) {                  Sleep(0);
                 r = romeo.finddev(ROMEO_VENDORID, ROMEO_DEVICEID2, 0);  
         }          }
         pciaddr = r >> 16;          romeo.out8(romeo.addr + ROMEO_YMF288DATA1, data);
         r &= 0xff;  
   
         if (!r) {  
                 romeo.addr = romeo.read32(pciaddr, ROMEO_BASEADDRESS1);  
                 romeo.irq  = romeo.read32(pciaddr, ROMEO_PCIINTERRUPT) & 0xff;  
                 if (romeo.addr) {  
                         romeo.avail = ROMEO_AVAIL | ROMEO_YMF288;  
                         juliet_YM2151Reset();  
                         juliet_YMF288Reset();  
                 }  
         }  
         return(r);  
 }  }
   
   static void YMF288B(UINT8 addr, UINT8 data) {
   
 // ---- YM2151部          while(romeo.in8(romeo.addr + ROMEO_YMF288ADDR1) & 0x80) {
                   Sleep(0);
 void juliet_YM2151Reset(void)  
 {  
         BYTE    flag;  
   
         if (romeo.avail & ROMEO_AVAIL) {  
                 romeo.out32(romeo.addr + ROMEO_YM2151CTRL, 0x00);  
                 Sleep(10);  
                 flag = romeo.in8(romeo.addr + ROMEO_YM2151DATA) + 1;  
                 romeo.out32(romeo.addr + ROMEO_YM2151CTRL, 0x80);  
                 Sleep(10);  
                 flag |= romeo.in8(romeo.addr + ROMEO_YM2151DATA);  
                 if (!flag) {  
                         romeo.avail |= ROMEO_YM2151;  
                 }  
         }          }
           romeo.out8(romeo.addr + ROMEO_YMF288ADDR2, addr);
           while(romeo.in8(romeo.addr + ROMEO_YMF288ADDR1) & 0x80) {
                   Sleep(0);
           }
           romeo.out8(romeo.addr + ROMEO_YMF288DATA2, data);
 }  }
   
 int juliet_YM2151IsEnable(void)  static void setvolume(UINT8 ch, int vol) {
 {  
         return (( romeo.avail&ROMEO_YM2151 )?TRUE:FALSE);  
 }  
   
 int juliet_YM2151IsBusy(void)          void    (*send)(UINT8 addr, UINT8 data);
 {          UINT8   mask;
           UINT8   *pttl;
           int             ttl;
   
         return ((!( romeo.avail&ROMEO_YM2151 ))|| ( ( romeo.in8(romeo.addr + ROMEO_CMDQUEUE)&0x0f )!=0x0f ));          send = (ch & 4)?YMF288B:YMF288A;
 }          mask = opmask[romeo.algo[ch & 7] & 7];
           pttl = romeo.ttl + ((ch & 4) << 2);
 void juliet_YM2151W(BYTE reg, BYTE data)          ch = 0x40 + (ch & 3);
 {          do {
         if ( romeo.avail&ROMEO_YM2151) {                  if (mask & 1) {
                 romeo.out8(romeo.addr + ROMEO_YM2151ADDR, reg);                          ttl = pttl[ch & 0x0f] & 0x7f;
                 while ( (romeo.in8(romeo.addr + ROMEO_CMDQUEUE)&0x0f)!=0x0f ) {                          ttl -= vol;
                         Sleep(0);                          if (ttl < 0) {
                                   ttl = 0;
                           }
                           else if (ttl > 0x7f) {
                                   ttl = 0x7f;
                           }
                           send(ch, (UINT8)ttl);
                 }                  }
                 romeo.out8(romeo.addr + ROMEO_YM2151DATA, data);                  ch += 4;
         }                  mask >>= 1;
           } while(mask);
 }  }
   
   
 // ---- YMF288部  
   
 void juliet_YMF288Reset(void) {  void juliet_YMF288Reset(void) {
   
         if (romeo.avail & ROMEO_YMF288) {          if (romeo.avail & ROMEO_YMF288) {
Line 174  void juliet_YMF288Reset(void) { Line 211  void juliet_YMF288Reset(void) {
         }          }
 }  }
   
 int juliet_YM288IsEnable(void) {  BOOL juliet_YMF288IsEnable(void) {
   
         return(TRUE);          return((romeo.avail & ROMEO_YMF288) != 0);
 }  }
   
 int juliet_YM288IsBusy(void) {  BOOL juliet_YMF288IsBusy(void) {
   
         return((!(romeo.avail&ROMEO_YMF288)) ||          return((!(romeo.avail & ROMEO_YMF288)) ||
                         ((romeo.in8(romeo.addr + ROMEO_YMF288ADDR1) & 0x80) != 0));                          ((romeo.in8(romeo.addr + ROMEO_YMF288ADDR1) & 0x80) != 0));
 }  }
   
 void juliet_YMF288A(BYTE addr, BYTE data) {  void juliet_YMF288A(UINT8 addr, UINT8 data) {
   
         if (romeo.avail & ROMEO_YMF288) {          if (romeo.avail & ROMEO_YMF288) {
                 while(romeo.in8(romeo.addr + ROMEO_YMF288ADDR1) & 0x80) {                  if (addr == 0x07) {                                                     // psg mix
                         Sleep(0);                          romeo.psgmix = data;
                 }                  }
                 romeo.out8(romeo.addr + ROMEO_YMF288ADDR1, addr);                  else if ((addr & 0xf0) == 0x40) {                       // ttl
                 while(romeo.in8(romeo.addr + ROMEO_YMF288ADDR1) & 0x80) {                          romeo.ttl[addr & 0x0f] = data;
                         Sleep(0);  
                 }                  }
                 romeo.out8(romeo.addr + ROMEO_YMF288DATA1, data);                  else if ((addr & 0xfc) == 0xb0) {                       // algorithm
                 {                          romeo.algo[addr & 3] = data;
                         char buf[128];  
                         wsprintf(buf, "A-%02x %02x\n", addr, data);  
                         OutputDebugString(buf);  
                 }                  }
                   YMF288A(addr, data);
         }          }
 }  }
   
 void juliet_YMF288B(BYTE addr, BYTE data) {  void juliet_YMF288B(UINT8 addr, UINT8 data) {
   
         if (romeo.avail & ROMEO_YMF288) {          if (romeo.avail & ROMEO_YMF288) {
                 while(romeo.in8(romeo.addr + ROMEO_YMF288ADDR1) & 0x80) {                  if ((addr & 0xf0) == 0x40) {                            // ttl
                         Sleep(0);                          romeo.ttl[0x10 + (addr & 0x0f)] = data;
                   }
                   else if ((addr & 0xfc) == 0xb0) {                       // algorithm
                           romeo.algo[4 + (addr & 3)] = data;
                 }                  }
                 romeo.out8(romeo.addr + ROMEO_YMF288ADDR2, addr);                  YMF288B(addr, data);
                 while(romeo.in8(romeo.addr + ROMEO_YMF288ADDR1) & 0x80) {          }
                         Sleep(0);  }
                 }  
                 romeo.out8(romeo.addr + ROMEO_YMF288DATA2, data);  void juliet_YMF288Enable(BOOL enable) {
                 {  
                         char buf[128];          UINT8   ch;
                         wsprintf(buf, "B-%02x %02x\n", addr, data);          int             vol;
                         OutputDebugString(buf);  
           if (romeo.avail & ROMEO_YMF288) {
                   YMF288A(0x07, (enable)?romeo.psgmix:0x3f);
                   vol = (enable)?0:-127;
                   for (ch=0; ch<3; ch++) {
                           setvolume(ch+0, vol);
                           setvolume(ch+4, vol);
                 }                  }
         }          }
 }  }
   
   #endif
   

Removed from v.1.1  
changed lines
  Added in v.1.5


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