convertir de Shift-JIS a UTF-8

por eso es que no deseaba aceptar el uso de NSFplay
This commit is contained in:
tildearrow 2022-05-01 22:13:11 -05:00
parent 6c517292dd
commit f6fe93b0ed
32 changed files with 552 additions and 3977 deletions

View file

@ -1,22 +0,0 @@
/* YM2413 tone by Mitsutaka Okazaki, 2020 */
/* https://github.com/digital-sound-antiques/emu2413/blob/d2b9c8dfc5e84b7f8a535fdfee0149ac7bd84ca2/emu2413.c#L34
*/
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0: Original
0x71, 0x61, 0x1e, 0x17, 0xd0, 0x78, 0x00, 0x17, // 1: Violin
0x13, 0x41, 0x1a, 0x0d, 0xd8, 0xf7, 0x23, 0x13, // 2: Guitar
0x13, 0x01, 0x99, 0x00, 0xf2, 0xc4, 0x21, 0x23, // 3: Piano
0x11, 0x61, 0x0e, 0x07, 0x8d, 0x64, 0x70, 0x27, // 4: Flute
0x32, 0x21, 0x1e, 0x06, 0xe1, 0x76, 0x01, 0x28, // 5: Clarinet
0x31, 0x22, 0x16, 0x05, 0xe0, 0x71, 0x00, 0x18, // 6: Oboe
0x21, 0x61, 0x1d, 0x07, 0x82, 0x81, 0x11, 0x07, // 7: Trumpet
0x33, 0x21, 0x2d, 0x13, 0xb0, 0x70, 0x00, 0x07, // 8: Organ
0x61, 0x61, 0x1b, 0x06, 0x64, 0x65, 0x10, 0x17, // 9: Horn
0x41, 0x61, 0x0b, 0x18, 0x85, 0xf0, 0x81, 0x07, // A: Synthesizer
0x33, 0x01, 0x83, 0x11, 0xea, 0xef, 0x10, 0x04, // B: Harpsichord
0x17, 0xc1, 0x24, 0x07, 0xf8, 0xf8, 0x22, 0x12, // C: Vibraphone
0x61, 0x50, 0x0c, 0x05, 0xd2, 0xf5, 0x40, 0x42, // D: Synthsizer Bass
0x01, 0x01, 0x55, 0x03, 0xe9, 0x90, 0x03, 0x02, // E: Acoustic Bass
0x41, 0x41, 0x89, 0x03, 0xf1, 0xe4, 0xc0, 0x13, // F: Electric Guitar
0x01, 0x01, 0x18, 0x0f, 0xdf, 0xf8, 0x6a, 0x6d, // R: Bass Drum (from VRC7)
0x01, 0x01, 0x00, 0x00, 0xc8, 0xd8, 0xa7, 0x68, // R: High-Hat(M) / Snare Drum(C) (from VRC7)
0x05, 0x01, 0x00, 0x00, 0xf8, 0xaa, 0x59, 0x55, // R: Tom-tom(M) / Top Cymbal(C) (from VRC7)

View file

@ -1,20 +0,0 @@
/* YMF281B tone by Chabin (4/10/2004) */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x62,0x21,0x1a,0x07,0xf0,0x6f,0x00,0x16,
0x00,0x10,0x44,0x02,0xf6,0xf4,0x54,0x23,
0x03,0x01,0x97,0x04,0xf3,0xf3,0x13,0xf3,
0x01,0x61,0x0a,0x0f,0xfa,0x64,0x70,0x17,
0x22,0x21,0x1e,0x06,0xf0,0x76,0x00,0x28,
0x00,0x61,0x8a,0x0e,0xc0,0x61,0x00,0x07,
0x21,0x61,0x1b,0x07,0x84,0x80,0x17,0x17,
0x37,0x32,0xc9,0x01,0x66,0x64,0x40,0x28,
0x01,0x21,0x06,0x03,0xa5,0x71,0x51,0x07,
0x06,0x11,0x5e,0x07,0xf3,0xf2,0xf6,0x11,
0x00,0x20,0x18,0x06,0xf5,0xf3,0x20,0x26,
0x97,0x41,0x20,0x07,0xff,0xf4,0x22,0x22,
0x65,0x61,0x15,0x00,0xf7,0xf3,0x16,0xf4,
0x01,0x31,0x0e,0x07,0xfa,0xf3,0xff,0xff,
0x48,0x61,0x09,0x07,0xf1,0x94,0xf0,0xf5,
0x07,0x21,0x14,0x00,0xee,0xf8,0xff,0xf8,
0x01,0x31,0x00,0x00,0xf8,0xf7,0xf8,0xf7,
0x25,0x11,0x00,0x00,0xf8,0xfa,0xf8,0x55,

View file

@ -1,363 +0,0 @@
/****************************************************************************
emu2149.c -- YM2149/AY-3-8910 emulator by Mitsutaka Okazaki 2001
2001 04-28 : Version 1.00beta -- 1st Beta Release.
2001 08-14 : Version 1.10
2001 10-03 : Version 1.11 -- Added PSG_set_quality().
2002 03-02 : Version 1.12 -- Removed PSG_init & PSG_close.
2002 10-13 : Version 1.14 -- Fixed the envelope unit.
2003 09-19 : Version 1.15 -- Added PSG_setMask and PSG_toggleMask
2004 01-11 : Version 1.16 -- Fixed an envelope problem where the envelope
frequency register is written before key-on.
References:
psg.vhd -- 2000 written by Kazuhiro Tsujikawa.
s_fme7.c -- 1999,2000 written by Mamiya (NEZplug).
ay8910.c -- 1998-2001 Author unknown (MAME).
MSX-Datapack -- 1991 ASCII Corp.
AY-3-8910 data sheet
*****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "emu2149.h"
static e_uint32 voltbl[2][32] = {
{0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x07, 0x09,
0x0B, 0x0D, 0x0F, 0x12,
0x16, 0x1A, 0x1F, 0x25, 0x2D, 0x35, 0x3F, 0x4C, 0x5A, 0x6A, 0x7F, 0x97,
0xB4, 0xD6, 0xEB, 0xFF},
{0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x05, 0x05, 0x07, 0x07,
0x0B, 0x0B, 0x0F, 0x0F,
0x16, 0x16, 0x1F, 0x1F, 0x2D, 0x2D, 0x3F, 0x3F, 0x5A, 0x5A, 0x7F, 0x7F,
0xB4, 0xB4, 0xFF, 0xFF}
};
#define GETA_BITS 24
static void
internal_refresh (PSG * psg)
{
if (psg->quality)
{
psg->base_incr = 1 << GETA_BITS;
psg->realstep = (e_uint32) ((1 << 31) / psg->rate);
psg->psgstep = (e_uint32) ((1 << 31) / (psg->clk / 16));
psg->psgtime = 0;
}
else
{
psg->base_incr =
(e_uint32) ((double) psg->clk * (1 << GETA_BITS) / (16 * psg->rate));
}
}
EMU2149_API void
PSG_set_rate (PSG * psg, e_uint32 r)
{
psg->rate = r ? r : 44100;
internal_refresh (psg);
}
EMU2149_API void
PSG_set_quality (PSG * psg, e_uint32 q)
{
psg->quality = q;
internal_refresh (psg);
}
EMU2149_API PSG *
PSG_new (e_uint32 c, e_uint32 r)
{
PSG *psg;
psg = (PSG *) malloc (sizeof (PSG));
if (psg == NULL)
return NULL;
PSG_setVolumeMode (psg, EMU2149_VOL_DEFAULT);
psg->clk = c;
psg->rate = r ? r : 44100;
PSG_set_quality (psg, 0);
return psg;
}
EMU2149_API void
PSG_setVolumeMode (PSG * psg, int type)
{
switch (type)
{
case 1:
psg->voltbl = voltbl[EMU2149_VOL_YM2149];
break;
case 2:
psg->voltbl = voltbl[EMU2149_VOL_AY_3_8910];
break;
default:
psg->voltbl = voltbl[EMU2149_VOL_DEFAULT];
break;
}
}
EMU2149_API e_uint32
PSG_setMask (PSG *psg, e_uint32 mask)
{
e_uint32 ret = 0;
if(psg)
{
ret = psg->mask;
psg->mask = mask;
}
return ret;
}
EMU2149_API e_uint32
PSG_toggleMask (PSG *psg, e_uint32 mask)
{
e_uint32 ret = 0;
if(psg)
{
ret = psg->mask;
psg->mask ^= mask;
}
return ret;
}
EMU2149_API void
PSG_reset (PSG * psg)
{
int i;
psg->base_count = 0;
for (i = 0; i < 3; i++)
{
psg->cout[i] = 0;
psg->count[i] = 0x1000;
psg->freq[i] = 0;
psg->edge[i] = 0;
psg->volume[i] = 0;
}
psg->mask = 0;
for (i = 0; i < 16; i++)
psg->reg[i] = 0;
psg->adr = 0;
psg->noise_seed = 0xffff;
psg->noise_count = 0x40;
psg->noise_freq = 0;
psg->env_volume = 0;
psg->env_ptr = 0;
psg->env_freq = 0;
psg->env_count = 0;
psg->env_pause = 1;
psg->out = 0;
}
EMU2149_API void
PSG_delete (PSG * psg)
{
free (psg);
}
EMU2149_API e_uint8
PSG_readIO (PSG * psg)
{
return (e_uint8) (psg->reg[psg->adr]);
}
EMU2149_API e_uint8
PSG_readReg (PSG * psg, e_uint32 reg)
{
return (e_uint8) (psg->reg[reg & 0x1f]);
}
EMU2149_API void
PSG_writeIO (PSG * psg, e_uint32 adr, e_uint32 val)
{
if (adr & 1)
PSG_writeReg (psg, psg->adr, val);
else
psg->adr = val & 0x1f;
}
INLINE static e_int16
calc (PSG * psg)
{
int i, noise;
e_uint32 incr;
e_int32 mix = 0;
psg->base_count += psg->base_incr;
incr = (psg->base_count >> GETA_BITS);
psg->base_count &= (1 << GETA_BITS) - 1;
/* Envelope */
psg->env_count += incr;
while (psg->env_count>=0x10000 && psg->env_freq!=0)
{
if (!psg->env_pause)
{
if(psg->env_face)
psg->env_ptr = (psg->env_ptr + 1) & 0x3f ;
else
psg->env_ptr = (psg->env_ptr + 0x3f) & 0x3f;
}
if (psg->env_ptr & 0x20) /* if carry or borrow */
{
if (psg->env_continue)
{
if (psg->env_alternate^psg->env_hold) psg->env_face ^= 1;
if (psg->env_hold) psg->env_pause = 1;
psg->env_ptr = psg->env_face?0:0x1f;
}
else
{
psg->env_pause = 1;
psg->env_ptr = 0;
}
}
psg->env_count -= psg->env_freq;
}
/* Noise */
psg->noise_count += incr;
if (psg->noise_count & 0x40)
{
if (psg->noise_seed & 1)
psg->noise_seed ^= 0x24000;
psg->noise_seed >>= 1;
psg->noise_count -= psg->noise_freq;
}
noise = psg->noise_seed & 1;
/* Tone */
for (i = 0; i < 3; i++)
{
psg->count[i] += incr;
if (psg->count[i] & 0x1000)
{
if (psg->freq[i] > 1)
{
psg->edge[i] = !psg->edge[i];
psg->count[i] -= psg->freq[i];
}
else
{
psg->edge[i] = 1;
}
}
psg->cout[i] = 0; // maintaining cout for stereo mix
if (psg->mask&PSG_MASK_CH(i))
continue;
if ((psg->tmask[i] || psg->edge[i]) && (psg->nmask[i] || noise))
{
if (!(psg->volume[i] & 32))
psg->cout[i] = psg->voltbl[psg->volume[i] & 31];
else
psg->cout[i] = psg->voltbl[psg->env_ptr];
mix += psg->cout[i];
}
}
return (e_int16) mix;
}
EMU2149_API e_int16
PSG_calc (PSG * psg)
{
if (!psg->quality)
return (e_int16) (calc (psg) << 4);
/* Simple rate converter */
while (psg->realstep > psg->psgtime)
{
psg->psgtime += psg->psgstep;
psg->out += calc (psg);
psg->out >>= 1;
}
psg->psgtime = psg->psgtime - psg->realstep;
return (e_int16) (psg->out << 4);
}
EMU2149_API void
PSG_writeReg (PSG * psg, e_uint32 reg, e_uint32 val)
{
int c;
if (reg > 15) return;
psg->reg[reg] = (e_uint8) (val & 0xff);
switch (reg)
{
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
c = reg >> 1;
psg->freq[c] = ((psg->reg[c * 2 + 1] & 15) << 8) + psg->reg[c * 2];
break;
case 6:
psg->noise_freq = (val == 0) ? 1 : ((val & 31) << 1);
break;
case 7:
psg->tmask[0] = (val & 1);
psg->tmask[1] = (val & 2);
psg->tmask[2] = (val & 4);
psg->nmask[0] = (val & 8);
psg->nmask[1] = (val & 16);
psg->nmask[2] = (val & 32);
break;
case 8:
case 9:
case 10:
psg->volume[reg - 8] = val << 1;
break;
case 11:
case 12:
psg->env_freq = (psg->reg[12] << 8) + psg->reg[11];
break;
case 13:
psg->env_continue = (val >> 3) & 1;
psg->env_attack = (val >> 2) & 1;
psg->env_alternate = (val >> 1) & 1;
psg->env_hold = val & 1;
psg->env_face = psg->env_attack;
psg->env_pause = 0;
psg->env_count = 0x10000 - psg->env_freq;
psg->env_ptr = psg->env_face?0:0x1f;
break;
case 14:
case 15:
default:
break;
}
return;
}

View file

@ -1,94 +0,0 @@
/* emu2149.h */
#ifndef _EMU2149_H_
#define _EMU2149_H_
#include "emutypes.h"
#ifdef EMU2149_DLL_EXPORTS
#define EMU2149_API __declspec(dllexport)
#elif EMU2149_DLL_IMPORTS
#define EMU2149_API __declspec(dllimport)
#else
#define EMU2149_API
#endif
#define EMU2149_VOL_DEFAULT 1
#define EMU2149_VOL_YM2149 0
#define EMU2149_VOL_AY_3_8910 1
#define PSG_MASK_CH(x) (1<<(x))
#ifdef __cplusplus
extern "C"
{
#endif
typedef struct __PSG
{
/* Volume Table */
e_uint32 *voltbl;
e_uint8 reg[0x20];
e_int32 out;
e_int32 cout[3];
e_uint32 clk, rate, base_incr, quality;
e_uint32 count[3];
e_uint32 volume[3];
e_uint32 freq[3];
e_uint32 edge[3];
e_uint32 tmask[3];
e_uint32 nmask[3];
e_uint32 mask;
e_uint32 base_count;
e_uint32 env_volume;
e_uint32 env_ptr;
e_uint32 env_face;
e_uint32 env_continue;
e_uint32 env_attack;
e_uint32 env_alternate;
e_uint32 env_hold;
e_uint32 env_pause;
e_uint32 env_reset;
e_uint32 env_freq;
e_uint32 env_count;
e_uint32 noise_seed;
e_uint32 noise_count;
e_uint32 noise_freq;
/* rate converter */
e_uint32 realstep;
e_uint32 psgtime;
e_uint32 psgstep;
/* I/O Ctrl */
e_uint32 adr;
}
PSG;
EMU2149_API void PSG_set_quality (PSG * psg, e_uint32 q);
EMU2149_API void PSG_set_rate (PSG * psg, e_uint32 r);
EMU2149_API PSG *PSG_new (e_uint32 clk, e_uint32 rate);
EMU2149_API void PSG_reset (PSG *);
EMU2149_API void PSG_delete (PSG *);
EMU2149_API void PSG_writeReg (PSG *, e_uint32 reg, e_uint32 val);
EMU2149_API void PSG_writeIO (PSG * psg, e_uint32 adr, e_uint32 val);
EMU2149_API e_uint8 PSG_readReg (PSG * psg, e_uint32 reg);
EMU2149_API e_uint8 PSG_readIO (PSG * psg);
EMU2149_API e_int16 PSG_calc (PSG *);
EMU2149_API void PSG_setVolumeMode (PSG * psg, int type);
EMU2149_API e_uint32 PSG_setMask (PSG *, e_uint32 mask);
EMU2149_API e_uint32 PSG_toggleMask (PSG *, e_uint32 mask);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -1,485 +0,0 @@
/****************************************************************************
emu2212.c -- S.C.C. emulator by Mitsutaka Okazaki 2001
2001 09-30 : Version 1.00
2001 10-03 : Version 1.01 -- Added SCC_set_quality().
2002 02-14 : Version 1.10 -- Added SCC_writeReg(), SCC_set_type().
Fixed SCC_write().
2002 02-17 : Version 1.11 -- Fixed SCC_write().
2002 03-02 : Version 1.12 -- Removed SCC_init & SCC_close.
2003 09-19 : Version 1.13 -- Added SCC_setMask() and SCC_toggleMask()
2004 10-21 : Version 1.14 -- Fixed the problem where SCC+ is disabled.
Registar map for SCC_writeReg()
$00-1F : WaveTable CH.A
$20-3F : WaveTable CH.B
$40-5F : WaveTable CH.C
$60-7F : WaveTable CH.D&E(SCC), CH.D(SCC+)
$80-9F : WaveTable CH.E
$C0 : CH.A Freq(L)
$C1 : CH.A Freq(H)
$C2 : CH.B Freq(L)
$C3 : CH.B Freq(H)
$C4 : CH.C Freq(L)
$C5 : CH.C Freq(H)
$C6 : CH.D Freq(L)
$C7 : CH.D Freq(H)
$C8 : CH.E Freq(L)
$C9 : CH.E Freq(H)
$D0 : CH.A Volume
$D1 : CH.B Volume
$D2 : CH.C Volume
$D3 : CH.D Volume
$D4 : CH.E Volume
$E0 : Bit0 = 0:SCC, 1:SCC+
$E1 : CH mask
$E2 : Extra Flags
*****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "emu2212.h"
#define GETA_BITS 22
static void
internal_refresh (SCC * scc)
{
if (scc->quality)
{
scc->base_incr = 2 << GETA_BITS;
scc->realstep = (e_uint32) ((1 << 31) / scc->rate);
scc->sccstep = (e_uint32) ((1 << 31) / (scc->clk / 2));
scc->scctime = 0;
}
else
{
scc->base_incr = (e_uint32) ((double) scc->clk * (1 << GETA_BITS) / scc->rate);
}
}
EMU2212_API e_uint32
SCC_setMask (SCC *scc, e_uint32 mask)
{
e_uint32 ret = 0;
if(scc)
{
ret = scc->mask;
scc->mask = mask;
}
return ret;
}
EMU2212_API e_uint32
SCC_toggleMask (SCC *scc, e_uint32 mask)
{
e_uint32 ret = 0;
if(scc)
{
ret = scc->mask;
scc->mask ^= mask;
}
return ret;
}
EMU2212_API void
SCC_set_quality (SCC * scc, e_uint32 q)
{
scc->quality = q;
internal_refresh (scc);
}
EMU2212_API void
SCC_set_rate (SCC * scc, e_uint32 r)
{
scc->rate = r ? r : 44100;
internal_refresh (scc);
}
EMU2212_API SCC *
SCC_new (e_uint32 c, e_uint32 r)
{
SCC *scc;
scc = (SCC *) malloc (sizeof (SCC));
if (scc == NULL)
return NULL;
memset(scc, 0, sizeof (SCC));
scc->clk = c;
scc->rate = r ? r : 44100;
SCC_set_quality (scc, 0);
scc->type = SCC_ENHANCED;
return scc;
}
EMU2212_API void
SCC_reset (SCC * scc)
{
int i, j;
if (scc == NULL)
return;
scc->mode = 0;
scc->active = 0;
scc->base_adr = 0x9000;
for (i = 0; i < 5; i++)
{
for (j = 0; j < 5; j++)
scc->wave[i][j] = 0;
scc->count[i] = 0;
scc->freq[i] = 0;
scc->phase[i] = 0;
scc->volume[i] = 0;
scc->offset[i] = 0;
scc->rotate[i] = 0;
}
memset(scc->reg,0,0x100-0xC0);
scc->mask = 0;
scc->ch_enable = 0xff;
scc->ch_enable_next = 0xff;
scc->cycle_4bit = 0;
scc->cycle_8bit = 0;
scc->refresh = 0;
scc->out = 0;
scc->prev = 0;
scc->next = 0;
return;
}
EMU2212_API void
SCC_delete (SCC * scc)
{
if (scc != NULL)
free (scc);
}
INLINE static e_int16
calc (SCC * scc)
{
int i;
e_int32 mix = 0;
for (i = 0; i < 5; i++)
{
scc->count[i] = (scc->count[i] + scc->incr[i]);
if (scc->count[i] & (1 << (GETA_BITS + 5)))
{
scc->count[i] &= ((1 << (GETA_BITS + 5)) - 1);
scc->offset[i] = (scc->offset[i] + 31) & scc->rotate[i];
scc->ch_enable &= ~(1 << i);
scc->ch_enable |= scc->ch_enable_next & (1 << i);
}
if (scc->ch_enable & (1 << i))
{
scc->phase[i] = ((scc->count[i] >> (GETA_BITS)) + scc->offset[i]) & 0x1F;
if(!(scc->mask&SCC_MASK_CH(i)))
mix += ((((e_int8) (scc->wave[i][scc->phase[i]]) * (e_int8) scc->volume[i]))) >> 4;
}
}
return (e_int16) (mix << 4);
}
EMU2212_API e_int16
SCC_calc (SCC * scc)
{
if (!scc->quality)
return calc (scc);
while (scc->realstep > scc->scctime)
{
scc->scctime += scc->sccstep;
scc->prev = scc->next;
scc->next = calc (scc);
}
scc->scctime -= scc->realstep;
scc->out = (e_int16) (((double) scc->next * (scc->sccstep - scc->scctime) + (double) scc->prev * scc->scctime) / scc->sccstep);
return (e_int16) (scc->out);
}
EMU2212_API e_uint32
SCC_readReg (SCC * scc, e_uint32 adr)
{
if (adr < 0xA0)
return scc->wave[adr >> 5][adr & 0x1f];
else if( 0xC0 < adr && adr < 0xF0 )
return scc->reg[adr-0xC0];
else
return 0;
}
EMU2212_API void
SCC_writeReg (SCC * scc, e_uint32 adr, e_uint32 val)
{
int ch;
e_uint32 freq;
adr &= 0xFF;
if (adr < 0xA0)
{
ch = (adr & 0xF0) >> 5;
if (!scc->rotate[ch])
{
scc->wave[ch][adr & 0x1F] = (e_int8) val;
if (scc->mode == 0 && ch == 3)
scc->wave[4][adr & 0x1F] = (e_int8) val;
}
}
else if (0xC0 <= adr && adr <= 0xC9)
{
scc->reg[adr-0xC0] = val;
ch = (adr & 0x0F) >> 1;
if (adr & 1)
scc->freq[ch] = ((val & 0xF) << 8) | (scc->freq[ch] & 0xFF);
else
scc->freq[ch] = (scc->freq[ch] & 0xF00) | (val & 0xFF);
if (scc->refresh)
scc->count[ch] = 0;
freq = scc->freq[ch];
if (scc->cycle_8bit)
freq &= 0xFF;
if (scc->cycle_4bit)
freq >>= 8;
if (freq <= 8)
scc->incr[ch] = 0;
else
scc->incr[ch] = scc->base_incr / (freq + 1);
}
else if (0xD0 <= adr && adr <= 0xD4)
{
scc->reg[adr-0xC0] = val;
scc->volume[adr & 0x0F] = (e_uint8) (val & 0xF);
}
else if (adr == 0xE0)
{
scc->reg[adr-0xC0] = val;
scc->mode = (e_uint8) val & 1;
}
else if (adr == 0xE1)
{
scc->reg[adr-0xC0] = val;
scc->ch_enable_next = (e_uint8) val & 0x1F;
}
else if (adr == 0xE2)
{
scc->reg[adr-0xC0] = val;
scc->cycle_4bit = val & 1;
scc->cycle_8bit = val & 2;
scc->refresh = val & 32;
if (val & 64)
for (ch = 0; ch < 5; ch++)
scc->rotate[ch] = 0x1F;
else
for (ch = 0; ch < 5; ch++)
scc->rotate[ch] = 0;
if (val & 128)
scc->rotate[3] = scc->rotate[4] = 0x1F;
}
return;
}
INLINE static void
write_standard (SCC * scc, e_uint32 adr, e_uint32 val)
{
adr &= 0xFF;
if (adr < 0x80) /* wave */
{
SCC_writeReg (scc, adr, val);
}
else if (adr < 0x8A) /* freq */
{
SCC_writeReg (scc, adr + 0xC0 - 0x80, val);
}
else if (adr < 0x8F) /* volume */
{
SCC_writeReg (scc, adr + 0xD0 - 0x8A, val);
}
else if (adr == 0x8F) /* ch enable */
{
SCC_writeReg (scc, 0xE1, val);
}
else if (0xE0 <= adr) /* flags */
{
SCC_writeReg (scc, 0xE2, val);
}
}
INLINE static void
write_enhanced (SCC * scc, e_uint32 adr, e_uint32 val)
{
adr &= 0xFF;
if (adr < 0xA0) /* wave */
{
SCC_writeReg (scc, adr, val);
}
else if (adr < 0xAA) /* freq */
{
SCC_writeReg (scc, adr + 0xC0 - 0xA0, val);
}
else if (adr < 0xAF) /* volume */
{
SCC_writeReg (scc, adr + 0xD0 - 0xAA, val);
}
else if (adr == 0xAF) /* ch enable */
{
SCC_writeReg (scc, 0xE1, val);
}
else if (0xC0 <= adr && adr <= 0xDF) /* flags */
{
SCC_writeReg (scc, 0xE2, val);
}
}
INLINE static e_uint32
read_enhanced (SCC * scc, e_uint32 adr)
{
adr &= 0xFF;
if (adr < 0xA0)
return SCC_readReg (scc, adr);
else if (adr < 0xAA)
return SCC_readReg (scc, adr + 0xC0 - 0xA0);
else if (adr < 0xAF)
return SCC_readReg (scc, adr + 0xD0 - 0xAA);
else if (adr == 0xAF)
return SCC_readReg (scc, 0xE1);
else if (0xC0 <= adr && adr <= 0xDF)
return SCC_readReg (scc, 0xE2);
else
return 0;
}
INLINE static e_uint32
read_standard (SCC * scc, e_uint32 adr)
{
adr &= 0xFF;
if(adr<0x80)
return SCC_readReg (scc, adr);
else if (0xA0<=adr&&adr<=0xBF)
return SCC_readReg (scc, 0x80+(adr&0x1F));
else if (adr < 0x8A)
return SCC_readReg (scc, adr + 0xC0 - 0x80);
else if (adr < 0x8F)
return SCC_readReg (scc, adr + 0xD0 - 0x8A);
else if (adr == 0x8F)
return SCC_readReg (scc, 0xE1);
else if (0xE0 <= adr)
return SCC_readReg (scc, 0xE2);
else return 0;
}
EMU2212_API e_uint32
SCC_read (SCC * scc, e_uint32 adr)
{
if( scc->type == SCC_ENHANCED && (adr&0xFFFE) == 0xBFFE )
return (scc->base_adr>>8)&0x20;
if( adr < scc->base_adr ) return 0;
adr -= scc->base_adr;
if( adr == 0 )
{
if(scc->mode) return 0x80; else return 0x3F;
}
if(!scc->active||adr<0x800||0x8FF<adr) return 0;
switch (scc->type)
{
case SCC_STANDARD:
return read_standard (scc, adr);
break;
case SCC_ENHANCED:
if(!scc->mode)
return read_standard (scc, adr);
else
return read_enhanced (scc, adr);
break;
default:
break;
}
return 0;
}
EMU2212_API void
SCC_write (SCC * scc, e_uint32 adr, e_uint32 val)
{
val = val & 0xFF;
if( scc->type == SCC_ENHANCED && (adr&0xFFFE) == 0xBFFE )
{
scc->base_adr = 0x9000 | ((val&0x20)<<8);
return;
}
if( adr < scc->base_adr ) return;
adr -= scc->base_adr;
if(adr == 0)
{
if( val == 0x3F )
{
scc->mode = 0;
scc->active = 1;
}
else if( val&0x80 && scc->type == SCC_ENHANCED)
{
scc->mode = 1;
scc->active = 1;
}
else
{
scc->mode = 0;
scc->active = 0;
}
return;
}
if(!scc->active||adr<0x800||0x8FF<adr) return;
switch (scc->type)
{
case SCC_STANDARD:
write_standard (scc, adr, val);
break;
case SCC_ENHANCED:
if(scc->mode)
write_enhanced (scc, adr, val);
else
write_standard (scc, adr, val);
default:
break;
}
return;
}
EMU2212_API void
SCC_set_type (SCC * scc, e_uint32 type)
{
scc->type = type;
}

View file

@ -1,77 +0,0 @@
#ifndef _EMU2212_H_
#define _EMU2212_H_
#ifdef EMU2212_DLL_EXPORTS
#define EMU2212_API __declspec(dllexport)
#elif defined(EMU2212_DLL_IMPORTS)
#define EMU2212_API __declspec(dllimport)
#else
#define EMU2212_API
#endif
#ifdef __cplusplus
extern "C" {
#endif
#include "emutypes.h"
#define SCC_STANDARD 0
#define SCC_ENHANCED 1
#define SCC_MASK_CH(x) (1<<(x))
typedef struct __SCC {
e_uint32 clk, rate ,base_incr, quality ;
e_int32 out, prev, next;
e_uint32 type ;
e_uint32 mode ;
e_uint32 active;
e_uint32 base_adr;
e_uint32 mask ;
e_uint32 realstep ;
e_uint32 scctime ;
e_uint32 sccstep ;
e_uint32 incr[5] ;
e_int8 wave[5][32] ;
e_uint32 count[5] ;
e_uint32 freq[5] ;
e_uint32 phase[5] ;
e_uint32 volume[5] ;
e_uint32 offset[5] ;
e_uint8 reg[0x100-0xC0];
int ch_enable ;
int ch_enable_next ;
int cycle_4bit ;
int cycle_8bit ;
int refresh ;
int rotate[5] ;
} SCC ;
EMU2212_API SCC *SCC_new(e_uint32 c, e_uint32 r) ;
EMU2212_API void SCC_reset(SCC *scc) ;
EMU2212_API void SCC_set_rate(SCC *scc, e_uint32 r);
EMU2212_API void SCC_set_quality(SCC *scc, e_uint32 q) ;
EMU2212_API void SCC_set_type(SCC *scc, e_uint32 type) ;
EMU2212_API void SCC_delete(SCC *scc) ;
EMU2212_API e_int16 SCC_calc(SCC *scc) ;
EMU2212_API void SCC_write(SCC *scc, e_uint32 adr, e_uint32 val) ;
EMU2212_API void SCC_writeReg(SCC *scc, e_uint32 adr, e_uint32 val) ;
EMU2212_API e_uint32 SCC_read(SCC *scc, e_uint32 adr) ;
EMU2212_API e_uint32 SCC_setMask(SCC *scc, e_uint32 adr) ;
EMU2212_API e_uint32 SCC_toggleMask(SCC *scc, e_uint32 adr) ;
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,247 +0,0 @@
#ifndef _EMU2413_H_
#define _EMU2413_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define OPLL_DEBUG 0
enum OPLL_TONE_ENUM {
OPLL_VRC7_TONE = 0,
OPLL_VRC7_RW_TONE,
OPLL_VRC7_FT36_TONE,
OPLL_VRC7_FT35_TONE,
OPLL_VRC7_MO_TONE,
OPLL_VRC7_KT2_TONE,
OPLL_VRC7_KT1_TONE,
OPLL_2413_TONE,
OPLL_281B_TONE
};
/* voice data */
typedef struct __OPLL_PATCH {
uint32_t TL, FB, EG, ML, AR, DR, SL, RR, KR, KL, AM, PM, WS;
} OPLL_PATCH;
/* slot */
typedef struct __OPLL_SLOT {
uint8_t number;
/* type flags:
* 000000SM
* |+-- M: 0:modulator 1:carrier
* +--- S: 0:normal 1:single slot mode (sd, tom, hh or cym)
*/
uint8_t type;
OPLL_PATCH *patch; /* voice parameter */
/* slot output */
int32_t output[2]; /* output value, latest and previous. */
/* phase generator (pg) */
uint16_t *wave_table; /* wave table */
uint32_t pg_phase; /* pg phase */
uint32_t pg_out; /* pg output, as index of wave table */
uint8_t pg_keep; /* if 1, pg_phase is preserved when key-on */
uint16_t blk_fnum; /* (block << 9) | f-number */
uint16_t fnum; /* f-number (9 bits) */
uint8_t blk; /* block (3 bits) */
/* envelope generator (eg) */
uint8_t eg_state; /* current state */
int32_t volume; /* current volume */
uint8_t key_flag; /* key-on flag 1:on 0:off */
uint8_t sus_flag; /* key-sus option 1:on 0:off */
uint16_t tll; /* total level + key scale level*/
uint8_t rks; /* key scale offset (rks) for eg speed */
uint8_t eg_rate_h; /* eg speed rate high 4bits */
uint8_t eg_rate_l; /* eg speed rate low 2bits */
uint32_t eg_shift; /* shift for eg global counter, controls envelope speed */
uint32_t eg_out; /* eg output */
uint32_t update_requests; /* flags to debounce update */
#if OPLL_DEBUG
uint8_t last_eg_state;
#endif
} OPLL_SLOT;
/* mask */
#define OPLL_MASK_CH(x) (1 << (x))
#define OPLL_MASK_HH (1 << (9))
#define OPLL_MASK_CYM (1 << (10))
#define OPLL_MASK_TOM (1 << (11))
#define OPLL_MASK_SD (1 << (12))
#define OPLL_MASK_BD (1 << (13))
#define OPLL_MASK_RHYTHM (OPLL_MASK_HH | OPLL_MASK_CYM | OPLL_MASK_TOM | OPLL_MASK_SD | OPLL_MASK_BD)
/* rate conveter */
typedef struct __OPLL_RateConv {
int ch;
double timer;
double f_ratio;
int16_t *sinc_table;
int16_t **buf;
} OPLL_RateConv;
OPLL_RateConv *OPLL_RateConv_new(double f_inp, double f_out, int ch);
void OPLL_RateConv_reset(OPLL_RateConv *conv);
void OPLL_RateConv_putData(OPLL_RateConv *conv, int ch, int16_t data);
int16_t OPLL_RateConv_getData(OPLL_RateConv *conv, int ch);
void OPLL_RateConv_delete(OPLL_RateConv *conv);
typedef struct __OPLL {
uint32_t clk;
uint32_t rate;
uint8_t chip_type;
uint32_t adr;
uint32_t inp_step;
uint32_t out_step;
uint32_t out_time;
uint8_t reg[0x40];
uint8_t test_flag;
uint32_t slot_key_status;
uint8_t rhythm_mode;
uint32_t eg_counter;
uint32_t pm_phase;
int32_t am_phase;
uint8_t lfo_am;
uint32_t noise;
uint8_t short_noise;
int32_t patch_number[9];
OPLL_SLOT slot[18];
OPLL_PATCH patch[19 * 2];
uint8_t pan[16];
float pan_fine[16][2];
uint32_t mask;
/* channel output */
/* 0..8:tone 9:bd 10:hh 11:sd 12:tom 13:cym */
int16_t ch_out[14];
int16_t mix_out[2];
OPLL_RateConv *conv;
} OPLL;
OPLL *OPLL_new(uint32_t clk, uint32_t rate);
void OPLL_delete(OPLL *);
void OPLL_reset(OPLL *);
void OPLL_resetPatch(OPLL *, uint8_t);
/**
* Set output wave sampling rate.
* @param rate sampling rate. If clock / 72 (typically 49716 or 49715 at 3.58MHz) is set, the internal rate converter is
* disabled.
*/
void OPLL_setRate(OPLL *opll, uint32_t rate);
/**
* Set internal calcuration quality. Currently no effects, just for compatibility.
* >= v1.0.0 always synthesizes internal output at clock/72 Hz.
*/
void OPLL_setQuality(OPLL *opll, uint8_t q);
/**
* Set pan pot (extra function - not YM2413 chip feature)
* @param ch 0..8:tone 9:bd 10:hh 11:sd 12:tom 13:cym 14,15:reserved
* @param pan 0:mute 1:right 2:left 3:center
* ```
* pan: 76543210
* |+- bit 1: enable Left output
* +-- bit 0: enable Right output
* ```
*/
void OPLL_setPan(OPLL *opll, uint32_t ch, uint8_t pan);
/**
* Set fine-grained panning
* @param ch 0..8:tone 9:bd 10:hh 11:sd 12:tom 13:cym 14,15:reserved
* @param pan output strength of left/right channel.
* pan[0]: left, pan[1]: right. pan[0]=pan[1]=1.0f for center.
*/
void OPLL_setPanFine(OPLL *opll, uint32_t ch, float pan[2]);
/**
* Set chip type. If vrc7 is selected, r#14 is ignored.
* This method not change the current ROM patch set.
* To change ROM patch set, use OPLL_resetPatch.
* @param type 0:YM2413 1:VRC7
*/
void OPLL_setChipType(OPLL *opll, uint8_t type);
void OPLL_writeIO(OPLL *opll, uint32_t reg, uint8_t val);
void OPLL_writeReg(OPLL *opll, uint32_t reg, uint8_t val);
/**
* Calculate one sample
*/
int16_t OPLL_calc(OPLL *opll);
/**
* Calulate stereo sample
*/
void OPLL_calcStereo(OPLL *opll, int32_t out[2]);
void OPLL_setPatch(OPLL *, const uint8_t *dump);
void OPLL_copyPatch(OPLL *, int32_t, OPLL_PATCH *);
/**
* Force to refresh.
* External program should call this function after updating patch parameters.
*/
void OPLL_forceRefresh(OPLL *);
void OPLL_dumpToPatch(const uint8_t *dump, OPLL_PATCH *patch);
void OPLL_patchToDump(const OPLL_PATCH *patch, uint8_t *dump);
void OPLL_getDefaultPatch(int32_t type, int32_t num, OPLL_PATCH *);
/**
* Set channel mask
* @param mask mask flag: OPLL_MASK_* can be used.
* - bit 0..8: mask for ch 1 to 9 (OPLL_MASK_CH(i))
* - bit 9: mask for Hi-Hat (OPLL_MASK_HH)
* - bit 10: mask for Top-Cym (OPLL_MASK_CYM)
* - bit 11: mask for Tom (OPLL_MASK_TOM)
* - bit 12: mask for Snare Drum (OPLL_MASK_SD)
* - bit 13: mask for Bass Drum (OPLL_MASK_BD)
*/
uint32_t OPLL_setMask(OPLL *, uint32_t mask);
/**
* Toggler channel mask flag
*/
uint32_t OPLL_toggleMask(OPLL *, uint32_t mask);
/* for compatibility */
#define OPLL_set_rate OPLL_setRate
#define OPLL_set_quality OPLL_setQuality
#define OPLL_set_pan OPLL_setPan
#define OPLL_set_pan_fine OPLL_setPanFine
#define OPLL_calc_stereo OPLL_calcStereo
#define OPLL_reset_patch OPLL_resetPatch
#define OPLL_dump2patch OPLL_dumpToPatch
#define OPLL_patch2dump OPLL_patchToDump
#define OPLL_setChipMode OPLL_setChipType
#ifdef __cplusplus
}
#endif
#endif

View file

@ -1,41 +0,0 @@
#ifndef _EMUTYPES_H_
#define _EMUTYPES_H_
#if defined(_MSC_VER)
#define INLINE __forceinline
#elif defined(__GNUC__)
#define INLINE __inline__
#elif defined(_MWERKS_)
#define INLINE inline
#else
#define INLINE
#endif
#if defined(EMU_DLL_IMPORTS)
#define EMU2149_DLL_IMPORTS
#define EMU2212_DLL_IMPORTS
#define EMU2413_DLL_IMPORTS
#define EMU8950_DLL_IMPORTS
#define EMU76489_DLL_IMPORTS
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef unsigned int e_uint;
typedef signed int e_int;
typedef unsigned char e_uint8 ;
typedef signed char e_int8 ;
typedef unsigned short e_uint16 ;
typedef signed short e_int16 ;
typedef unsigned int e_uint32 ;
typedef signed int e_int32 ;
#ifdef __cplusplus
}
#endif
#endif

View file

@ -1,20 +0,0 @@
// patch set by Mitsutaka Okazaki used in FamiTracker 0.3.5 and prior (6/24/2001)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x33, 0x01, 0x09, 0x0e, 0x94, 0x90, 0x40, 0x01,
0x13, 0x41, 0x0f, 0x0d, 0xce, 0xd3, 0x43, 0x13,
0x01, 0x12, 0x1b, 0x06, 0xff, 0xd2, 0x00, 0x32,
0x61, 0x61, 0x1b, 0x07, 0xaf, 0x63, 0x20, 0x28,
0x22, 0x21, 0x1e, 0x06, 0xf0, 0x76, 0x08, 0x28,
0x66, 0x21, 0x15, 0x00, 0x93, 0x94, 0x20, 0xf8,
0x21, 0x61, 0x1c, 0x07, 0x82, 0x81, 0x10, 0x17,
0x23, 0x21, 0x20, 0x1f, 0xc0, 0x71, 0x07, 0x47,
0x25, 0x31, 0x26, 0x05, 0x64, 0x41, 0x18, 0xf8,
0x17, 0x21, 0x28, 0x07, 0xff, 0x83, 0x02, 0xf8,
0x97, 0x81, 0x25, 0x07, 0xcf, 0xc8, 0x02, 0x14,
0x21, 0x21, 0x54, 0x0f, 0x80, 0x7f, 0x07, 0x07,
0x01, 0x01, 0x56, 0x03, 0xd3, 0xb2, 0x43, 0x58,
0x31, 0x21, 0x0c, 0x03, 0x82, 0xc0, 0x40, 0x07,
0x21, 0x01, 0x0c, 0x03, 0xd4, 0xd3, 0x40, 0x84,
0x04, 0x21, 0x28, 0x00, 0xdf, 0xf8, 0xff, 0xf8,
0x23, 0x22, 0x00, 0x00, 0xa8, 0xf8, 0xf8, 0xf8,
0x25, 0x18, 0x00, 0x00, 0xf8, 0xa9, 0xf8, 0x55,

View file

@ -1,21 +0,0 @@
// patch set by quietust (1/18/2004), used in FamiTracker 0.3.6
// Source: http://nesdev.com/cgi-bin/wwwthreads/showpost.pl?Board=NESemdev&Number=1440
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x21, 0x04, 0x06, 0x8D, 0xF2, 0x42, 0x17,
0x13, 0x41, 0x05, 0x0E, 0x99, 0x96, 0x63, 0x12,
0x31, 0x11, 0x10, 0x0A, 0xF0, 0x9C, 0x32, 0x02,
0x21, 0x61, 0x1D, 0x07, 0x9F, 0x64, 0x20, 0x27,
0x22, 0x21, 0x1E, 0x06, 0xF0, 0x76, 0x08, 0x28,
0x02, 0x01, 0x06, 0x00, 0xF0, 0xF2, 0x03, 0x95,
0x21, 0x61, 0x1C, 0x07, 0x82, 0x81, 0x16, 0x07,
0x23, 0x21, 0x1A, 0x17, 0xEF, 0x82, 0x25, 0x15,
0x25, 0x11, 0x1F, 0x00, 0x86, 0x41, 0x20, 0x11,
0x85, 0x01, 0x1F, 0x0F, 0xE4, 0xA2, 0x11, 0x12,
0x07, 0xC1, 0x2B, 0x45, 0xB4, 0xF1, 0x24, 0xF4,
0x61, 0x23, 0x11, 0x06, 0x96, 0x96, 0x13, 0x16,
0x01, 0x02, 0xD3, 0x05, 0x82, 0xA2, 0x31, 0x51,
0x61, 0x22, 0x0D, 0x02, 0xC3, 0x7F, 0x24, 0x05,
0x21, 0x62, 0x0E, 0x00, 0xA1, 0xA0, 0x44, 0x17,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

View file

@ -1,21 +0,0 @@
// patch set 1 by kevtris (11/14/1999)
// http://kevtris.org/nes/vrcvii.txt
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x03, 0x10, 0x06, 0x74, 0xA1, 0x13, 0xF4,
0x05, 0x01, 0x16, 0x00, 0xF9, 0xA2, 0x15, 0xF5,
0x01, 0x41, 0x11, 0x00, 0xA0, 0xA0, 0x83, 0x95,
0x01, 0x41, 0x17, 0x00, 0x60, 0xF0, 0x83, 0x95,
0x24, 0x41, 0x1F, 0x00, 0x50, 0xB0, 0x94, 0x94,
0x05, 0x01, 0x0B, 0x04, 0x65, 0xA0, 0x54, 0x95,
0x11, 0x41, 0x0E, 0x04, 0x70, 0xC7, 0x13, 0x10,
0x02, 0x44, 0x16, 0x06, 0xE0, 0xE0, 0x31, 0x35,
0x48, 0x22, 0x22, 0x07, 0x50, 0xA1, 0xA5, 0xF4,
0x05, 0xA1, 0x18, 0x00, 0xA2, 0xA2, 0xF5, 0xF5,
0x07, 0x81, 0x2B, 0x05, 0xA5, 0xA5, 0x03, 0x03,
0x01, 0x41, 0x08, 0x08, 0xA0, 0xA0, 0x83, 0x95,
0x21, 0x61, 0x12, 0x00, 0x93, 0x92, 0x74, 0x75,
0x21, 0x62, 0x21, 0x00, 0x84, 0x85, 0x34, 0x15,
0x21, 0x62, 0x0E, 0x00, 0xA1, 0xA0, 0x34, 0x15,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

View file

@ -1,21 +0,0 @@
// patch set 2 by kevtris (11/15/1999)
// http://kevtris.org/nes/vrcvii.txt
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x31, 0x22, 0x23, 0x07, 0xF0, 0xF0, 0xE8, 0xF7,
0x03, 0x31, 0x68, 0x05, 0xF2, 0x74, 0x79, 0x9C,
0x01, 0x51, 0x72, 0x04, 0xF1, 0xD3, 0x9D, 0x8B,
0x22, 0x61, 0x1B, 0x05, 0xC0, 0xA1, 0xF8, 0xE8,
0x22, 0x61, 0x2C, 0x03, 0xD2, 0xA1, 0xA7, 0xE8,
0x31, 0x22, 0xFA, 0x01, 0xF1, 0xF1, 0xF4, 0xEE,
0x21, 0x61, 0x28, 0x06, 0xF1, 0xF1, 0xCE, 0x9B,
0x27, 0x61, 0x60, 0x00, 0xF0, 0xF0, 0xFF, 0xFD,
0x60, 0x21, 0x2B, 0x06, 0x85, 0xF1, 0x79, 0x9D,
0x31, 0xA1, 0xFF, 0x0A, 0x53, 0x62, 0x5E, 0xAF,
0x03, 0xA1, 0x70, 0x0F, 0xD4, 0xA3, 0x94, 0xBE,
0x2B, 0x61, 0xE4, 0x07, 0xF6, 0x93, 0xBD, 0xAC,
0x21, 0x63, 0xED, 0x07, 0x77, 0xF1, 0xC7, 0xE8,
0x21, 0x61, 0x2A, 0x03, 0xF3, 0xE2, 0xB6, 0xD9,
0x21, 0x63, 0x37, 0x03, 0xF3, 0xE2, 0xB6, 0xD9,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

View file

@ -1,20 +0,0 @@
/* VRC7 TONES by okazaki@angel.ne.jp (4/10/2004) */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x33,0x01,0x09,0x0e,0x94,0x90,0x40,0x01,
0x13,0x41,0x0f,0x0d,0xce,0xd3,0x43,0x13,
0x01,0x12,0x1b,0x06,0xff,0xd2,0x00,0x32,
0x61,0x61,0x1b,0x07,0xaf,0x63,0x20,0x28,
0x22,0x21,0x1e,0x06,0xf0,0x76,0x08,0x28,
0x66,0x21,0x15,0x00,0x93,0x94,0x20,0xf8,
0x21,0x61,0x1c,0x07,0x82,0x81,0x10,0x17,
0x23,0x21,0x20,0x1f,0xc0,0x71,0x07,0x47,
0x25,0x31,0x26,0x05,0x64,0x41,0x18,0xf8,
0x17,0x21,0x28,0x07,0xff,0x83,0x02,0xf8,
0x97,0x81,0x25,0x07,0xcf,0xc8,0x02,0x14,
0x21,0x21,0x54,0x0f,0x80,0x7f,0x07,0x07,
0x01,0x01,0x56,0x03,0xd3,0xb2,0x43,0x58,
0x31,0x21,0x0c,0x03,0x82,0xc0,0x40,0x07,
0x21,0x01,0x0c,0x03,0xd4,0xd3,0x40,0x84,
0x07,0x21,0x14,0x00,0xee,0xf8,0xff,0xf8,
0x01,0x31,0x00,0x00,0xf8,0xf7,0xf8,0xf7,
0x25,0x11,0x00,0x00,0xf8,0xfa,0xf8,0x55,

View file

@ -1,21 +0,0 @@
// patch set by Nuke.YKT (3/15/2019)
// https://siliconpr0n.org/archive/doku.php?id=vendor:yamaha:opl2#ym2413_instruments
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x21, 0x05, 0x06, 0xE8, 0x81, 0x42, 0x27,
0x13, 0x41, 0x14, 0x0D, 0xD8, 0xF6, 0x23, 0x12,
0x11, 0x11, 0x08, 0x08, 0xFA, 0xB2, 0x20, 0x12,
0x31, 0x61, 0x0C, 0x07, 0xA8, 0x64, 0x61, 0x27,
0x32, 0x21, 0x1E, 0x06, 0xE1, 0x76, 0x01, 0x28,
0x02, 0x01, 0x06, 0x00, 0xA3, 0xE2, 0xF4, 0xF4,
0x21, 0x61, 0x1D, 0x07, 0x82, 0x81, 0x11, 0x07,
0x23, 0x21, 0x22, 0x17, 0xA2, 0x72, 0x01, 0x17,
0x35, 0x11, 0x25, 0x00, 0x40, 0x73, 0x72, 0x01,
0xB5, 0x01, 0x0F, 0x0F, 0xA8, 0xA5, 0x51, 0x02,
0x17, 0xC1, 0x24, 0x07, 0xF8, 0xF8, 0x22, 0x12,
0x71, 0x23, 0x11, 0x06, 0x65, 0x74, 0x18, 0x16,
0x01, 0x02, 0xD3, 0x05, 0xC9, 0x95, 0x03, 0x02,
0x61, 0x63, 0x0C, 0x00, 0x94, 0xC0, 0x33, 0xF6,
0x21, 0x72, 0x0D, 0x00, 0xC1, 0xD5, 0x56, 0x06,
0x01, 0x01, 0x18, 0x0F, 0xDF, 0xF8, 0x6A, 0x6D,
0x01, 0x01, 0x00, 0x00, 0xC8, 0xD8, 0xA7, 0x68,
0x05, 0x01, 0x00, 0x00, 0xF8, 0xAA, 0x59, 0x55,

View file

@ -1,21 +0,0 @@
// patch set by rainwarrior (8/01/2012)
// http://forums.nesdev.com/viewtopic.php?f=6&t=9141
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x21, 0x05, 0x06, 0xB8, 0x82, 0x42, 0x27,
0x13, 0x41, 0x13, 0x0D, 0xD8, 0xD6, 0x23, 0x12,
0x31, 0x11, 0x08, 0x08, 0xFA, 0x9A, 0x22, 0x02,
0x31, 0x61, 0x18, 0x07, 0x78, 0x64, 0x30, 0x27,
0x22, 0x21, 0x1E, 0x06, 0xF0, 0x76, 0x08, 0x28,
0x02, 0x01, 0x06, 0x00, 0xF0, 0xF2, 0x03, 0xF5,
0x21, 0x61, 0x1D, 0x07, 0x82, 0x81, 0x16, 0x07,
0x23, 0x21, 0x1A, 0x17, 0xCF, 0x72, 0x25, 0x17,
0x15, 0x11, 0x25, 0x00, 0x4F, 0x71, 0x00, 0x11,
0x85, 0x01, 0x12, 0x0F, 0x99, 0xA2, 0x40, 0x02,
0x07, 0xC1, 0x69, 0x07, 0xF3, 0xF5, 0xA7, 0x12,
0x71, 0x23, 0x0D, 0x06, 0x66, 0x75, 0x23, 0x16,
0x01, 0x02, 0xD3, 0x05, 0xA3, 0x92, 0xF7, 0x52,
0x61, 0x63, 0x0C, 0x00, 0x94, 0xAF, 0x34, 0x06,
0x21, 0x62, 0x0D, 0x00, 0xB1, 0xA0, 0x54, 0x17,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

View file

@ -11,12 +11,12 @@ namespace xgm
int shifted = freq[i] >> sweep_amount[i]; int shifted = freq[i] >> sweep_amount[i];
if (i == 0 && sweep_mode[i]) shifted += 1; if (i == 0 && sweep_mode[i]) shifted += 1;
sfreq[i] = freq[i] + (sweep_mode[i] ? -shifted : shifted); sfreq[i] = freq[i] + (sweep_mode[i] ? -shifted : shifted);
//DEBUG_OUT("shifted[%d] = %d (%d >> %d)\n",i,shifted,freq[i],sweep_amount[i]); //DEBUG_OUT("shifted[%d] = %d (%d >> %d)¥n",i,shifted,freq[i],sweep_amount[i]);
} }
void NES_APU::FrameSequence(int s) void NES_APU::FrameSequence(int s)
{ {
//DEBUG_OUT("FrameSequence(%d)\n",s); //DEBUG_OUT("FrameSequence(%d)¥n",s);
if (s > 3) return; // no operation in step 4 if (s > 3) return; // no operation in step 4
@ -57,15 +57,15 @@ namespace xgm
if (sweep_enable[i]) if (sweep_enable[i])
{ {
//DEBUG_OUT("Clock sweep: %d\n", i); //DEBUG_OUT("Clock sweep: %d¥n", i);
--sweep_div[i]; --sweep_div[i];
if (sweep_div[i] <= 0) if (sweep_div[i] <= 0)
{ {
sweep_sqr(i); // calculate new sweep target sweep_sqr(i); // calculate new sweep target
//DEBUG_OUT("sweep_div[%d] (0/%d)\n",i,sweep_div_period[i]); //DEBUG_OUT("sweep_div[%d] (0/%d)¥n",i,sweep_div_period[i]);
//DEBUG_OUT("freq[%d]=%d > sfreq[%d]=%d\n",i,freq[i],i,sfreq[i]); //DEBUG_OUT("freq[%d]=%d > sfreq[%d]=%d¥n",i,freq[i],i,sfreq[i]);
if (freq[i] >= 8 && sfreq[i] < 0x800 && sweep_amount[i] > 0) // update frequency if appropriate if (freq[i] >= 8 && sfreq[i] < 0x800 && sweep_amount[i] > 0) // update frequency if appropriate
{ {
@ -73,7 +73,7 @@ namespace xgm
} }
sweep_div[i] = sweep_div_period[i] + 1; sweep_div[i] = sweep_div_period[i] + 1;
//DEBUG_OUT("freq[%d]=%d\n",i,freq[i]); //DEBUG_OUT("freq[%d]=%d¥n",i,freq[i]);
} }
if (sweep_write[i]) if (sweep_write[i])
@ -137,7 +137,7 @@ namespace xgm
out[1] = calc_sqr(1, clocks); out[1] = calc_sqr(1, clocks);
} }
// 生成される波形の振幅は0-8191 // ツ青カツ青ャツつウツづェツづゥツ波ツ形ツづ個振ツ閉敖づ0-8191
UINT32 NES_APU::Render (INT32 b[2]) UINT32 NES_APU::Render (INT32 b[2])
{ {
out[0] = (mask & 1) ? 0 : out[0]; out[0] = (mask & 1) ? 0 : out[0];
@ -200,7 +200,7 @@ namespace xgm
sm[c][t] = 128; sm[c][t] = 128;
} }
NES_APU::~NES_APU () NES_APU::NES_APU ()
{ {
} }
@ -321,7 +321,7 @@ namespace xgm
if (0x4000 <= adr && adr < 0x4008) if (0x4000 <= adr && adr < 0x4008)
{ {
//DEBUG_OUT("$%04X = %02X\n",adr,val); //DEBUG_OUT("$%04X = %02X¥n",adr,val);
adr &= 0xf; adr &= 0xf;
ch = adr >> 2; ch = adr >> 2;

View file

@ -22,7 +22,7 @@ namespace xgm
{ SQR0_MASK = 1, SQR1_MASK = 2, }; { SQR0_MASK = 1, SQR1_MASK = 2, };
protected: protected:
int option[OPT_END]; // 各種オプション int option[OPT_END]; // 各種オプション
int mask; int mask;
INT32 sm[2][2]; INT32 sm[2][2];
@ -66,7 +66,7 @@ namespace xgm
public: public:
NES_APU (); NES_APU ();
~NES_APU (); NES_APU ();
void FrameSequence(int s); void FrameSequence(int s);

View file

@ -67,7 +67,7 @@ namespace xgm
} }
NES_DMC::~NES_DMC () NES_DMC::NES_DMC ()
{ {
} }
@ -122,7 +122,7 @@ namespace xgm
void NES_DMC::FrameSequence(int s) void NES_DMC::FrameSequence(int s)
{ {
//DEBUG_OUT("FrameSequence: %d\n",s); //DEBUG_OUT("FrameSequence: %d¥n",s);
if (s > 3) return; // no operation in step 4 if (s > 3) return; // no operation in step 4
@ -193,7 +193,7 @@ namespace xgm
} }
// 三角波チャンネルの計算 戻り値は0-15 // 三角波チャンネルの計算 戻り値は0-15
UINT32 NES_DMC::calc_tri (UINT32 clocks) UINT32 NES_DMC::calc_tri (UINT32 clocks)
{ {
static UINT32 tritbl[32] = static UINT32 tritbl[32] =
@ -219,10 +219,10 @@ namespace xgm
return ret; return ret;
} }
// ノイズチャンネルの計算 戻り値は0-127 // ノイズチャンネルの計算 戻り値は0-127
// 低サンプリングレートで合成するとエイリアスノイズが激しいので // 低サンプリングレートで合成するとエイリアスノイズが激しいので
// ノイズだけはこの関数内で高クロック合成し、簡易なサンプリングレート // ノイズだけはこの関数内で高クロック合成し、簡易なサンプリングレート
// 変換を行っている。 // 変換を行っている。
UINT32 NES_DMC::calc_noise(UINT32 clocks) UINT32 NES_DMC::calc_noise(UINT32 clocks)
{ {
UINT32 env = envelope_disable ? noise_volume : envelope_counter; UINT32 env = envelope_disable ? noise_volume : envelope_counter;
@ -620,7 +620,7 @@ namespace xgm
if (adr == 0x4017) if (adr == 0x4017)
{ {
//DEBUG_OUT("4017 = %02X\n", val); //DEBUG_OUT("4017 = %02X¥n", val);
frame_irq_enable = ((val & 0x40) != 0x40); frame_irq_enable = ((val & 0x40) != 0x40);
if (frame_irq_enable) frame_irq = false; if (frame_irq_enable) frame_irq = false;
cpu->UpdateIRQ(NES_CPU::IRQD_FRAME, false); cpu->UpdateIRQ(NES_CPU::IRQD_FRAME, false);
@ -645,7 +645,7 @@ namespace xgm
reg[adr-0x4008] = val&0xff; reg[adr-0x4008] = val&0xff;
//DEBUG_OUT("$%04X %02X\n", adr, val); //DEBUG_OUT("$%04X %02X¥n", adr, val);
switch (adr) switch (adr)
{ {
@ -724,12 +724,12 @@ namespace xgm
case 0x4012: case 0x4012:
adr_reg = val&0xff; adr_reg = val&0xff;
// ここでdaddressは更新されない // ここでdaddressは更新されない
break; break;
case 0x4013: case 0x4013:
len_reg = val&0xff; len_reg = val&0xff;
// ここでlengthは更新されない // ここでlengthは更新されない
break; break;
default: default:

View file

@ -99,7 +99,7 @@ namespace xgm
public: public:
NES_DMC (); NES_DMC ();
~NES_DMC (); NES_DMC ();
void InitializeTNDTable(double wt, double wn, double wd); void InitializeTNDTable(double wt, double wn, double wd);
void SetPal (bool is_pal); void SetPal (bool is_pal);

View file

@ -22,7 +22,7 @@ NES_FDS::NES_FDS ()
Reset(); Reset();
} }
NES_FDS::~NES_FDS () NES_FDS::NES_FDS ()
{ {
} }

View file

@ -63,7 +63,7 @@ protected:
public: public:
NES_FDS (); NES_FDS ();
virtual ~ NES_FDS (); virtual NES_FDS ();
virtual void Reset (); virtual void Reset ();
virtual void Tick (UINT32 clocks); virtual void Tick (UINT32 clocks);

View file

@ -1,186 +0,0 @@
#include "nes_fme7.h"
using namespace xgm;
const int DIVIDER = 8; // TODO this is not optimal, rewrite PSG output
NES_FME7::NES_FME7 ()
{
psg = PSG_new ((e_uint32)DEFAULT_CLOCK, DEFAULT_RATE);
divider = 0;
for(int c=0;c<2;++c)
for(int t=0;t<3;++t)
sm[c][t] = 128;
}
NES_FME7::~NES_FME7 ()
{
if (psg)
PSG_delete (psg);
}
void NES_FME7::SetClock (double c)
{
this->clock = c * 2.0;
}
void NES_FME7::SetRate (double r)
{
//rate = r ? r : DEFAULT_RATE;
rate = DEFAULT_CLOCK / double(DIVIDER); // TODO rewrite PSG to integrate with clock
if (psg)
PSG_set_rate (psg, (e_uint32)rate);
}
void NES_FME7::SetOption (int id, int val)
{
if(id<OPT_END)
{
//option[id] = val;
}
}
void NES_FME7::Reset ()
{
for (int i=0; i<16; ++i) // blank all registers
{
Write(0xC000,i);
Write(0xE000,0);
}
Write(0xC000,0x07); // disable all tones
Write(0xE000,0x3F);
divider = 0;
if (psg)
PSG_reset (psg);
}
bool NES_FME7::Write (xgm::UINT32 adr, xgm::UINT32 val, xgm::UINT32 id)
{
if (adr == 0xC000)
{
if (psg)
PSG_writeIO (psg, 0, val);
return true;
}
if (adr == 0xE000)
{
if (psg)
PSG_writeIO (psg, 1, val);
return true;
}
else
return false;
}
bool NES_FME7::Read (xgm::UINT32 adr, xgm::UINT32 & val, xgm::UINT32 id)
{
// not sure why this was here - BS
//if (psg)
// val = PSG_readIO (psg);
return false;
}
void NES_FME7::Tick (xgm::UINT32 clocks)
{
divider += clocks;
while (divider >= DIVIDER)
{
divider -= DIVIDER;
if (psg) PSG_calc(psg);
}
}
xgm::UINT32 NES_FME7::Render (xgm::INT32 b[2])
{
b[0] = b[1] = 0;
for (int i=0; i < 3; ++i)
{
// note negative polarity
b[0] -= psg->cout[i] * sm[0][i];
b[1] -= psg->cout[i] * sm[1][i];
}
b[0] >>= (7-4);
b[1] >>= (7-4);
// master volume adjustment
const INT32 MASTER = INT32(0.64 * 256.0);
b[0] = (b[0] * MASTER) >> 8;
b[1] = (b[1] * MASTER) >> 8;
return 2;
}
void NES_FME7::SetStereoMix(int trk, xgm::INT16 mixl, xgm::INT16 mixr)
{
if (trk < 0) return;
if (trk > 2) return;
sm[0][trk] = mixl;
sm[1][trk] = mixr;
}
ITrackInfo *NES_FME7::GetTrackInfo(int trk)
{
assert(trk<5);
if(psg)
{
if (trk<3)
{
trkinfo[trk]._freq = psg->freq[trk];
if(psg->freq[trk])
trkinfo[trk].freq = psg->clk/32.0/psg->freq[trk];
else
trkinfo[trk].freq = 0;
trkinfo[trk].output = psg->cout[trk];
trkinfo[trk].max_volume = 15;
trkinfo[trk].volume = psg->volume[trk] >> 1;
//trkinfo[trk].key = (psg->cout[trk]>0)?true:false;
trkinfo[trk].key = !(psg->tmask[trk]);
trkinfo[trk].tone = (psg->tmask[trk]?2:0)+(psg->nmask[trk]?1:0);
}
else if (trk == 3) // envelope
{
trkinfo[trk]._freq = psg->env_freq;
if(psg->env_freq)
trkinfo[trk].freq = psg->clk/512.0/psg->env_freq;
else
trkinfo[trk].freq = 0;
if (psg->env_continue && psg->env_alternate && !psg->env_hold) // triangle wave
{
trkinfo[trk].freq *= 0.5f; // sounds an octave down
}
trkinfo[trk].output = psg->voltbl[psg->env_ptr];
trkinfo[trk].max_volume = 0;
trkinfo[trk].volume = 0;
trkinfo[trk].key = (((psg->volume[0]|psg->volume[1]|psg->volume[2])&32) != 0);
trkinfo[trk].tone =
(psg->env_continue ?8:0) |
(psg->env_attack ?4:0) |
(psg->env_alternate?2:0) |
(psg->env_hold ?1:0) ;
}
else if (trk == 4) // noise
{
trkinfo[trk]._freq = psg->noise_freq >> 1;
if(trkinfo[trk]._freq > 0)
trkinfo[trk].freq = psg->clk/16.0/psg->noise_freq;
else
trkinfo[trk].freq = 0;
trkinfo[trk].output = psg->noise_seed & 1;
trkinfo[trk].max_volume = 0;
trkinfo[trk].volume = 0;
//trkinfo[trk].key = ((psg->nmask[0]&psg->nmask[1]&psg->nmask[2]) == 0);
trkinfo[trk].key = false;
trkinfo[trk].tone = 0;
}
}
return &trkinfo[trk];
}

View file

@ -1,42 +0,0 @@
#ifndef _NES_FME7_H_
#define _NES_FME7_H_
#include "../device.h"
#include "legacy/emu2149.h"
namespace xgm
{
class NES_FME7:public ISoundChip
{
public:
enum
{
OPT_END
};
protected:
//int option[OPT_END];
INT32 sm[2][3]; // stereo mix
INT16 buf[2];
PSG *psg;
int divider; // clock divider
double clock, rate;
TrackInfoBasic trkinfo[5];
public:
NES_FME7 ();
~NES_FME7 ();
virtual void Reset ();
virtual void Tick (UINT32 clocks);
virtual UINT32 Render (INT32 b[2]);
virtual bool Read (UINT32 adr, UINT32 & val, UINT32 id=0);
virtual bool Write (UINT32 adr, UINT32 val, UINT32 id=0);
virtual void SetClock (double);
virtual void SetRate (double);
virtual void SetOption (int, int);
virtual void SetMask (int m){ if(psg) PSG_setMask(psg,m); }
virtual void SetStereoMix (int trk, xgm::INT16 mixl, xgm::INT16 mixr);
virtual ITrackInfo *GetTrackInfo(int trk);
};
} // namespace
#endif

View file

@ -35,7 +35,7 @@ namespace xgm
sm[c][t] = 128; sm[c][t] = 128;
} }
NES_MMC5::~NES_MMC5 () NES_MMC5::NES_MMC5 ()
{ {
} }

View file

@ -31,8 +31,8 @@ namespace xgm
INT32 out[3]; INT32 out[3];
bool enable[2]; bool enable[2];
bool envelope_disable[2]; // エンベロープ有効フラグ bool envelope_disable[2]; // エンベロープ有効フラグ
bool envelope_loop[2]; // エンベロープループ bool envelope_loop[2]; // エンベロープループ
bool envelope_write[2]; bool envelope_write[2];
int envelope_div_period[2]; int envelope_div_period[2];
int envelope_div[2]; int envelope_div[2];
@ -49,7 +49,7 @@ namespace xgm
TrackInfoBasic trkinfo[3]; TrackInfoBasic trkinfo[3];
public: public:
NES_MMC5 (); NES_MMC5 ();
~NES_MMC5 (); NES_MMC5 ();
void FrameSequence (); void FrameSequence ();
void TickFrameSequence (UINT32 clocks); void TickFrameSequence (UINT32 clocks);

View file

@ -18,7 +18,7 @@ NES_N106::NES_N106 ()
Reset(); Reset();
} }
NES_N106::~NES_N106 () NES_N106::NES_N106 ()
{ {
} }

View file

@ -54,7 +54,7 @@ protected:
public: public:
NES_N106 (); NES_N106 ();
~NES_N106 (); NES_N106 ();
virtual void Reset (); virtual void Reset ();
virtual void Tick (UINT32 clocks); virtual void Tick (UINT32 clocks);

View file

@ -16,7 +16,7 @@ namespace xgm
sm[c][t] = 128; sm[c][t] = 128;
} }
NES_VRC6::~NES_VRC6 () NES_VRC6::NES_VRC6 ()
{ {
} }

View file

@ -36,7 +36,7 @@ namespace xgm
public: public:
NES_VRC6 (); NES_VRC6 ();
~NES_VRC6 (); NES_VRC6 ();
virtual void Reset (); virtual void Reset ();
virtual void Tick (UINT32 clocks); virtual void Tick (UINT32 clocks);

View file

@ -1,189 +0,0 @@
#include <cstring>
#include "nes_vrc7.h"
namespace xgm
{
NES_VRC7::NES_VRC7 ()
{
use_all_channels = false;
patch_set = OPLL_VRC7_TONE;
patch_custom = NULL;
divider = 0;
opll = OPLL_new ( 3579545, DEFAULT_RATE);
OPLL_reset_patch (opll, patch_set);
SetClock(DEFAULT_CLOCK);
for(int c=0;c<2;++c)
//for(int t=0;t<6;++t)
for(int t=0;t<9;++t) // HACK for YM2413 support
sm[c][t] = 128;
}
NES_VRC7::~NES_VRC7 ()
{
OPLL_delete (opll);
}
void NES_VRC7::UseAllChannels(bool b)
{
use_all_channels = b;
}
void NES_VRC7::SetPatchSet(int p)
{
patch_set = p;
}
void NES_VRC7::SetPatchSetCustom (const UINT8* pset)
{
patch_custom = pset;
}
void NES_VRC7::SetClock (double c)
{
clock = c / 36;
}
void NES_VRC7::SetRate (double r)
{
//rate = r ? r : DEFAULT_RATE;
(void)r; // rate is ignored
rate = 49716;
OPLL_set_quality(opll, 1); // quality always on (not really a CPU hog)
OPLL_set_rate(opll,(uint32_t)rate);
}
void NES_VRC7::SetOption (int id, int val)
{
if(id<OPT_END)
{
option[id] = val;
}
}
void NES_VRC7::Reset ()
{
for (int i=0; i < 0x40; ++i)
{
Write(0x9010,i);
Write(0x9030,0);
}
divider = 0;
OPLL_reset_patch (opll, patch_set);
if (patch_custom)
{
uint8_t dump[19 * 8];
memcpy(dump, patch_custom, 16 * 8);
memset(dump + 16 * 8, 0, 3 * 8);
OPLL_setPatch(opll, dump);
}
OPLL_reset (opll);
}
void NES_VRC7::SetStereoMix(int trk, xgm::INT16 mixl, xgm::INT16 mixr)
{
if (trk < 0) return;
//if (trk > 5) return;
if (trk > 8) return; // HACK YM2413
sm[0][trk] = mixl;
sm[1][trk] = mixr;
}
ITrackInfo *NES_VRC7::GetTrackInfo(int trk)
{
//if(opll&&trk<6)
if(opll&&trk<9) // HACK YM2413 (percussion mode isn't very diagnostic this way though)
{
trkinfo[trk].max_volume = 15;
trkinfo[trk].volume = 15 - ((opll->reg[0x30+trk])&15);
trkinfo[trk]._freq = opll->reg[0x10+trk]+((opll->reg[0x20+trk]&1)<<8);
int blk = (opll->reg[0x20+trk]>>1)&7;
trkinfo[trk].freq = clock*trkinfo[trk]._freq/(double)(0x80000>>blk);
trkinfo[trk].tone = (opll->reg[0x30+trk]>>4)&15;
//trkinfo[trk].key = (opll->reg[0x20+trk]&0x10)?true:false;
trkinfo[trk].key = opll->slot_key_status & (3 << trk)?true:false;
return &trkinfo[trk];
}
else
return NULL;
}
bool NES_VRC7::Write (UINT32 adr, UINT32 val, UINT32 id)
{
if (adr == 0x9010)
{
OPLL_writeIO (opll, 0, val);
return true;
}
if (adr == 0x9030)
{
OPLL_writeIO (opll, 1, val);
return true;
}
else
return false;
}
bool NES_VRC7::Read (UINT32 adr, UINT32 & val, UINT32 id)
{
return false;
}
void NES_VRC7::Tick (UINT32 clocks)
{
divider += clocks;
while (divider >= 36)
{
divider -= 36;
OPLL_calc(opll);
}
}
UINT32 NES_VRC7::Render (INT32 b[2])
{
b[0] = b[1] = 0;
for (int i=0; i < 6; ++i)
{
INT32 val = (mask & (1<<i)) ? 0 : opll->ch_out[i] >> 4;
b[0] += val * sm[0][i];
b[1] += val * sm[1][i];
}
// HACK for YM2413 support
if (use_all_channels)
{
for (int i=6; i < 9; ++i)
{
if (mask & (1<<i)) continue;
INT32 val;
if (opll->patch_number[i] > 15) // rhytm mode
{
if (i == 6) val = opll->ch_out[9]; // BD
else if (i == 7) val = opll->ch_out[10] + opll->ch_out[11]; // HH&SD
else val = opll->ch_out[12] + opll->ch_out[13]; // TOM&CYM
/* (i == 8) is implied */
}
else
{
val = opll->ch_out[i];
}
val >>= 4;
b[0] += val * sm[0][i];
b[1] += val * sm[1][i];
}
}
b[0] >>= (7 - 4);
b[1] >>= (7 - 4);
// master volume adjustment
const INT32 MASTER = INT32(1.15 * 256.0);
b[0] = (b[0] * MASTER) >> 8;
b[1] = (b[1] * MASTER) >> 8;
return 2;
}
}

View file

@ -1,53 +0,0 @@
#ifndef _NES_VRC7_H_
#define _NES_VRC7_H_
#include "../device.h"
#include "legacy/emu2413.h"
namespace xgm
{
class NES_VRC7 : public ISoundChip
{
public:
enum
{
OPT_OPLL=0,
OPT_END
};
protected:
int option[OPT_END];
int mask;
int patch_set;
const UINT8* patch_custom;
//INT32 sm[2][6]; // stereo mix
INT32 sm[2][9]; // stereo mix temporary HACK to support YM2413
INT16 buf[2];
OPLL *opll;
UINT32 divider; // clock divider
double clock, rate;
//TrackInfoBasic trkinfo[6];
TrackInfoBasic trkinfo[9]; // HACK to support YM2413
bool use_all_channels;
public:
NES_VRC7 ();
~NES_VRC7 ();
virtual void Reset ();
virtual void Tick (UINT32 clocks);
virtual UINT32 Render (INT32 b[2]);
virtual bool Read (UINT32 adr, UINT32 & val, UINT32 id=0);
virtual bool Write (UINT32 adr, UINT32 val, UINT32 id=0);
virtual void UseAllChannels (bool b);
virtual void SetPatchSet (int p);
virtual void SetPatchSetCustom (const UINT8* pset);
virtual void SetClock (double);
virtual void SetRate (double);
virtual void SetOption (int, int);
virtual void SetMask (int m){ mask = m; if(opll) OPLL_setMask(opll, m); }
virtual void SetStereoMix (int trk, xgm::INT16 mixl, xgm::INT16 mixr);
virtual ITrackInfo *GetTrackInfo(int trk);
};
} // namespace
#endif