--- np2/win9x/juliet.cpp 2003/10/21 11:51:16 1.3 +++ np2/win9x/juliet.cpp 2004/02/03 08:24:40 1.4 @@ -1,167 +1,206 @@ #include "compiler.h" + +#if defined(SUPPORT_ROMEO) + #include "romeo.h" #include "juliet.h" enum { ROMEO_AVAIL = 0x01, - ROMEO_YMF288 = 0x02, // 必ず存在する筈? + ROMEO_YMF288 = 0x02, ROMEO_YM2151 = 0x04 }; typedef struct { - HMODULE mod; + HMODULE mod; - PCIFINDDEV finddev; - PCICFGREAD32 read32; - PCIMEMWR8 out8; - PCIMEMWR16 out16; - PCIMEMWR32 out32; - PCIMEMRD8 in8; - PCIMEMRD16 in16; - PCIMEMRD32 in32; - - ULONG addr; - ULONG irq; - ULONG avail; + ULONG (WINAPI * finddev)(ULONG ven, ULONG dev, ULONG index); + ULONG (WINAPI * read32)(ULONG pciaddr, ULONG regaddr); + void (WINAPI * out8)(ULONG addr, UCHAR param); + void (WINAPI * out16)(ULONG addr, USHORT param); + void (WINAPI * out32)(ULONG addr, ULONG param); + UCHAR (WINAPI * in8)(ULONG addr); + USHORT (WINAPI * in16)(ULONG addr); + ULONG (WINAPI * in32)(ULONG addr); + + ULONG addr; + ULONG irq; + ULONG avail; + + UINT8 algo[8]; + UINT8 ttl[8*4]; + UINT8 psgmix; } _ROMEO; -#define ROMEO_TPTR(member) (int)&(((_ROMEO *)NULL)->member) - +static const UINT8 opmask[] = {0x08,0x08,0x08,0x08,0x0c,0x0e,0x0e,0x0f}; typedef struct { - char *symbol; - int addr; -} DLLPROCESS; +const char *symbol; + UINT addr; +} 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 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}; -static _ROMEO romeo = {NULL}; +// pciFindPciDevice使うと、OS起動後一発目に見つけられないことが多いので、 +// 自前で検索する(矢野さん方式) + +#define PCIBUSDEVFUNC(b, d, f) (((b) << 8) | ((d) << 3) | (f)) +#define DEVVEND(v, d) ((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) { - UINT i; -const DLLPROCESS *dp; - BOOL r = SUCCESS; - juliet_unload(); +BOOL juliet_initialize(void) { - romeo.mod = LoadLibrary(PCIDEBUG_DLL); - if (romeo.mod == NULL) { - return(FAILURE); + HMODULE mod; +const DLLPROC *d; +const DLLPROC *dterm; + long proc; + ULONG pciaddr; + + juliet_deinitialize(); + + mod = LoadLibrary(PCIDEBUG_DLL); + if (mod == NULL) { + goto jini_err1; } - for (i=0, dp=dllproc; isymbol); - if (proc == NULL) { - r = FAILURE; - break; + romeo.mod = mod; + d = dllproc; + dterm = d + sizeof(dllproc)/sizeof(DLLPROC); + while(d < dterm) { + proc = (long)GetProcAddress(mod, d->symbol); + 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(); -void juliet_unload(void) { +jini_err1: + return(FAILURE); +} + +void juliet_deinitialize(void) { if (romeo.mod) { FreeLibrary(romeo.mod); } ZeroMemory(&romeo, sizeof(romeo)); + FillMemory(romeo.ttl, 8*4, 0x7f); + romeo.psgmix = 0x3f; } -// ---- - -ULONG juliet_prepare(void) { - - ULONG r; - ULONG pciaddr; +// ---- YMF288部 - if (romeo.mod == NULL) { - return(FAILURE); - } +static void YMF288A(UINT8 addr, UINT8 data) { - r = romeo.finddev(ROMEO_VENDORID, ROMEO_DEVICEID, 0); - if (r & 0xff) { - r = romeo.finddev(ROMEO_VENDORID, ROMEO_DEVICEID2, 0); + while(romeo.in8(romeo.addr + ROMEO_YMF288ADDR1) & 0x80) { + Sleep(0); } - pciaddr = r >> 16; - 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(); - } + romeo.out8(romeo.addr + ROMEO_YMF288ADDR1, addr); + while(romeo.in8(romeo.addr + ROMEO_YMF288ADDR1) & 0x80) { + Sleep(0); } - return(r); + romeo.out8(romeo.addr + ROMEO_YMF288DATA1, data); } +static void YMF288B(UINT8 addr, UINT8 data) { -// ---- YM2151部 - -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; - } + while(romeo.in8(romeo.addr + ROMEO_YMF288ADDR1) & 0x80) { + Sleep(0); } + 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) -{ - return (( romeo.avail&ROMEO_YM2151 )?TRUE:FALSE); -} +static void setvolume(UINT8 ch, int vol) { -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 )); -} - -void juliet_YM2151W(BYTE reg, BYTE data) -{ - if ( romeo.avail&ROMEO_YM2151) { - romeo.out8(romeo.addr + ROMEO_YM2151ADDR, reg); - while ( (romeo.in8(romeo.addr + ROMEO_CMDQUEUE)&0x0f)!=0x0f ) { - Sleep(0); + send = (ch & 4)?YMF288B:YMF288A; + mask = opmask[romeo.algo[ch & 7] & 7]; + pttl = romeo.ttl + ((ch & 4) << 2); + ch = 0x40 + (ch & 3); + do { + if (mask & 1) { + ttl = pttl[ch & 0x0f] & 0x7f; + ttl -= vol; + 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) { if (romeo.avail & ROMEO_YMF288) { @@ -172,52 +211,60 @@ 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)); } -void juliet_YMF288A(BYTE addr, BYTE data) { +void juliet_YMF288A(UINT8 addr, UINT8 data) { if (romeo.avail & ROMEO_YMF288) { - while(romeo.in8(romeo.addr + ROMEO_YMF288ADDR1) & 0x80) { - Sleep(0); + if (addr == 0x07) { // psg mix + romeo.psgmix = data; } - romeo.out8(romeo.addr + ROMEO_YMF288ADDR1, addr); - while(romeo.in8(romeo.addr + ROMEO_YMF288ADDR1) & 0x80) { - Sleep(0); + else if ((addr & 0xf0) == 0x40) { // ttl + romeo.ttl[addr & 0x0f] = data; } - romeo.out8(romeo.addr + ROMEO_YMF288DATA1, data); - { - char buf[128]; - wsprintf(buf, "A-%02x %02x\n", addr, data); - OutputDebugString(buf); + else if ((addr & 0xfc) == 0xb0) { // algorithm + romeo.algo[addr & 3] = data; } + YMF288A(addr, data); } } -void juliet_YMF288B(BYTE addr, BYTE data) { +void juliet_YMF288B(UINT8 addr, UINT8 data) { if (romeo.avail & ROMEO_YMF288) { - while(romeo.in8(romeo.addr + ROMEO_YMF288ADDR1) & 0x80) { - Sleep(0); + if ((addr & 0xf0) == 0x40) { // ttl + 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); - while(romeo.in8(romeo.addr + ROMEO_YMF288ADDR1) & 0x80) { - Sleep(0); - } - romeo.out8(romeo.addr + ROMEO_YMF288DATA2, data); - { - char buf[128]; - wsprintf(buf, "B-%02x %02x\n", addr, data); - OutputDebugString(buf); + YMF288B(addr, data); + } +} + +void juliet_YMF288Enable(BOOL enable) { + + UINT8 ch; + int vol; + + 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 +