From c6d0ce68a7c3dabfce70fc1ee6a19d1468e33067 Mon Sep 17 00:00:00 2001 From: cam900 Date: Wed, 20 Mar 2019 21:35:17 +0900 Subject: [PATCH] bus/nes/konami.cpp : Fix sound clock, volume for VRC7 ym2413.cpp : Implement instrument table for VRC7, Add notes --- src/devices/bus/nes/konami.cpp | 10 ++- src/devices/bus/nes/konami.h | 2 +- src/devices/sound/ym2413.cpp | 119 ++++++++++++++++++++++++++------- src/devices/sound/ym2413.h | 23 +++++-- 4 files changed, 120 insertions(+), 34 deletions(-) diff --git a/src/devices/bus/nes/konami.cpp b/src/devices/bus/nes/konami.cpp index e979132223d..2d3f20863cb 100644 --- a/src/devices/bus/nes/konami.cpp +++ b/src/devices/bus/nes/konami.cpp @@ -81,7 +81,7 @@ nes_konami_vrc6_device::nes_konami_vrc6_device(const machine_config &mconfig, co } nes_konami_vrc7_device::nes_konami_vrc7_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : nes_konami_vrc4_device(mconfig, NES_VRC7, tag, owner, clock), m_ym2413(*this, "ym") + : nes_konami_vrc4_device(mconfig, NES_VRC7, tag, owner, clock), m_vrc7snd(*this, "vrc7snd") { } @@ -681,11 +681,11 @@ void nes_konami_vrc7_device::write_h(offs_t offset, uint8_t data) case 0x1010: case 0x1018: - m_ym2413->register_port_w(data); + m_vrc7snd->register_port_w(data); break; case 0x1030: case 0x1038: - m_ym2413->data_port_w(data); + m_vrc7snd->data_port_w(data); break; case 0x2000: @@ -758,8 +758,6 @@ void nes_konami_vrc7_device::write_h(offs_t offset, uint8_t data) // and has one output pin for audio, multiplexed for all 6 channels; OPLL has two output pins, one for // FM and one for Rhythm, and has no special status pin. -// FIXME: we currently emulate this as a base YM2413! - void nes_konami_vrc7_device::device_add_mconfig(machine_config &config) { // additional sound hardware @@ -767,5 +765,5 @@ void nes_konami_vrc7_device::device_add_mconfig(machine_config &config) // TODO: this is not how VRC7 clock signaling works! // The board uses the CLK pin in reality, not hardcoded NTSC values! - YM2413(config, m_ym2413, XTAL(21'477'272)/12).add_route(ALL_OUTPUTS, "addon", 0.5); + VRC7(config, m_vrc7snd, XTAL(21'477'272)/6).add_route(0, "addon", 1.0).add_route(1, "addon", 0.0); } diff --git a/src/devices/bus/nes/konami.h b/src/devices/bus/nes/konami.h index ed8d0caea3c..86afa1832e1 100644 --- a/src/devices/bus/nes/konami.h +++ b/src/devices/bus/nes/konami.h @@ -157,7 +157,7 @@ protected: virtual void device_add_mconfig(machine_config &config) override; private: - required_device m_ym2413; + required_device m_vrc7snd; }; diff --git a/src/devices/sound/ym2413.cpp b/src/devices/sound/ym2413.cpp index 3935b1baa0e..4245130d951 100644 --- a/src/devices/sound/ym2413.cpp +++ b/src/devices/sound/ym2413.cpp @@ -42,6 +42,8 @@ to do: #include "emu.h" #include "ym2413.h" +#include + #define FREQ_SH 16 /* 16.16 fixed point (frequency calculations) */ #define EG_SH 16 /* 16.16 fixed point (EG timing) */ #define LFO_SH 24 /* 8.24 fixed point (LFO calculations) */ @@ -131,7 +133,7 @@ const uint32_t ym2413_device::sl_tab[16] = { }; #undef SC -const unsigned char ym2413_device::eg_inc[15*RATE_STEPS] = { +const uint8_t ym2413_device::eg_inc[15*RATE_STEPS] = { /*cycle:0 1 2 3 4 5 6 7*/ /* 0 */ 0,1, 0,1, 0,1, 0,1, /* rates 00..12 0 (increment by 0 or 1) */ @@ -158,7 +160,7 @@ const unsigned char ym2413_device::eg_inc[15*RATE_STEPS] = { #define O(a) (a*RATE_STEPS) /*note that there is no O(13) in this table - it's directly in the code */ -const unsigned char ym2413_device::eg_rate_select[16+64+16] = { /* Envelope Generator rates (16 + 64 rates + 16 RKS) */ +const uint8_t ym2413_device::eg_rate_select[16+64+16] = { /* Envelope Generator rates (16 + 64 rates + 16 RKS) */ /* 16 infinite time rates */ O(14),O(14),O(14),O(14),O(14),O(14),O(14),O(14), O(14),O(14),O(14),O(14),O(14),O(14),O(14),O(14), @@ -199,7 +201,7 @@ const unsigned char ym2413_device::eg_rate_select[16+64+16] = { /* Envelope Ge /*mask 8191, 4095, 2047, 1023, 511, 255, 127, 63, 31, 15, 7, 3, 1, 0, 0, 0 */ #define O(a) (a*1) -const unsigned char ym2413_device::eg_rate_shift[16+64+16] = { /* Envelope Generator counter shifts (16 + 64 rates + 16 RKS) */ +const uint8_t ym2413_device::eg_rate_shift[16+64+16] = { /* Envelope Generator counter shifts (16 + 64 rates + 16 RKS) */ /* 16 infinite time rates */ O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0), O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0), @@ -350,7 +352,7 @@ const int8_t ym2413_device::lfo_pm_table[8*8] = { - waveform DC and DM select are 100% correct */ -const unsigned char ym2413_device::table[19][8] = { +const uint8_t ym2413_device::table[19][8] = { /* MULT MULT modTL DcDmFb AR/DR AR/DR SL/RR SL/RR */ /* 0 1 2 3 4 5 6 7 */ {0x49, 0x4c, 0x4c, 0x12, 0x00, 0x00, 0x00, 0x00 }, //0 @@ -390,6 +392,44 @@ const unsigned char ym2413_device::table[19][8] = { {0x05, 0x01, 0x00, 0x00, 0xf8, 0xba, 0x49, 0x55 },/* TOM(multi,env verified), TOP CYM(multi verified, env verified) */ }; +// VRC7 Instruments : Dumped from internal ROM (melodic only) +// reference : https://siliconpr0n.org/archive/doku.php?id=vendor:yamaha:opl2 +const uint8_t vrc7snd_device::vrc7_table[19][8] = { +/* MULT MULT modTL DcDmFb AR/DR AR/DR SL/RR SL/RR */ +/* 0 1 2 3 4 5 6 7 */ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, //0 (Correct?) + + {0x03, 0x21, 0x05, 0x06, 0xe8, 0x81, 0x42, 0x27 }, //1 + {0x13, 0x41, 0x14, 0x0d, 0xd8, 0xf6, 0x23, 0x12 }, //2 + {0x11, 0x11, 0x08, 0x08, 0xfa, 0xb2, 0x20, 0x12 }, //3 + {0x31, 0x61, 0x0c, 0x07, 0xa8, 0x64, 0x61, 0x27 }, //4 + + {0x32, 0x21, 0x1e, 0x06, 0xe1, 0x76, 0x01, 0x28 }, //5 + + {0x02, 0x01, 0x06, 0x00, 0xa3, 0xe2, 0xf4, 0xf4 }, //6 + + {0x21, 0x61, 0x1d, 0x07, 0x82, 0x81, 0x11, 0x07 }, //7 + {0x23, 0x21, 0x22, 0x17, 0xa2, 0x72, 0x01, 0x17 }, //8 + {0x35, 0x11, 0x25, 0x00, 0x40, 0x73, 0x72, 0x01 }, //9 + + {0xb5, 0x01, 0x0f, 0x0f, 0xa8, 0xa5, 0x51, 0x02 }, //A + + {0x17, 0xc1, 0x24, 0x07, 0xf8, 0xf8, 0x22, 0x12 }, //B + {0x71, 0x23, 0x11, 0x06, 0x65, 0x74, 0x18, 0x16 }, //C + + {0x01, 0x02, 0xd3, 0x05, 0xc9, 0x95, 0x03, 0x02 }, //D + + {0x61, 0x63, 0x0c, 0x00, 0x94, 0xc0, 0x33, 0xf6 }, //E + {0x21, 0x72, 0x0d, 0x00, 0xc1, 0xd5, 0x56, 0x06 }, //F + +/* Not dumped drum instruments yet, and disconnected */ +/* MULTI MULTI modTL xxx AR/DR AR/DR SL/RR SL/RR */ +/* 0 1 2 3 4 5 6 7 */ + {0x01, 0x01, 0x18, 0x0f, 0xdf, 0xf8, 0x6a, 0x6d },/* BD(multi verified, modTL verified, mod env - verified(close), carr. env verifed) */ + {0x01, 0x01, 0x00, 0x00, 0xc8, 0xd8, 0xa7, 0x68 },/* HH(multi verified), SD(multi not used) */ + {0x05, 0x01, 0x00, 0x00, 0xf8, 0xaa, 0x59, 0x55 },/* TOM(multi,env verified), TOP CYM(multi verified, env verified) */ +}; + /* work table */ #define SLOT7_1 (&P_CH[7].SLOT[SLOT1]) #define SLOT7_2 (&P_CH[7].SLOT[SLOT2]) @@ -823,21 +863,21 @@ void ym2413_device::rhythm_calc( OPLL_CH *CH, unsigned int noise ) */ /* base frequency derived from operator 1 in channel 7 */ - unsigned char bit7 = ((SLOT7_1->phase>>FREQ_SH)>>7)&1; - unsigned char bit3 = ((SLOT7_1->phase>>FREQ_SH)>>3)&1; - unsigned char bit2 = ((SLOT7_1->phase>>FREQ_SH)>>2)&1; + uint8_t bit7 = ((SLOT7_1->phase>>FREQ_SH)>>7)&1; + uint8_t bit3 = ((SLOT7_1->phase>>FREQ_SH)>>3)&1; + uint8_t bit2 = ((SLOT7_1->phase>>FREQ_SH)>>2)&1; - unsigned char res1 = (bit2 ^ bit7) | bit3; + uint8_t res1 = (bit2 ^ bit7) | bit3; /* when res1 = 0 phase = 0x000 | 0xd0; */ /* when res1 = 1 phase = 0x200 | (0xd0>>2); */ uint32_t phase = res1 ? (0x200|(0xd0>>2)) : 0xd0; /* enable gate based on frequency of operator 2 in channel 8 */ - unsigned char bit5e= ((SLOT8_2->phase>>FREQ_SH)>>5)&1; - unsigned char bit3e= ((SLOT8_2->phase>>FREQ_SH)>>3)&1; + uint8_t bit5e= ((SLOT8_2->phase>>FREQ_SH)>>5)&1; + uint8_t bit3e= ((SLOT8_2->phase>>FREQ_SH)>>3)&1; - unsigned char res2 = (bit3e | bit5e); + uint8_t res2 = (bit3e | bit5e); /* when res2 = 0 pass the phase from calculation above (res1); */ /* when res2 = 1 phase = 0x200 | (0xd0>>2); */ @@ -868,7 +908,7 @@ void ym2413_device::rhythm_calc( OPLL_CH *CH, unsigned int noise ) if( env < ENV_QUIET ) { /* base frequency derived from operator 1 in channel 7 */ - unsigned char bit8 = ((SLOT7_1->phase>>FREQ_SH)>>8)&1; + uint8_t bit8 = ((SLOT7_1->phase>>FREQ_SH)>>8)&1; /* when bit8 = 0 phase = 0x100; */ /* when bit8 = 1 phase = 0x200; */ @@ -894,21 +934,21 @@ void ym2413_device::rhythm_calc( OPLL_CH *CH, unsigned int noise ) if( env < ENV_QUIET ) { /* base frequency derived from operator 1 in channel 7 */ - unsigned char bit7 = ((SLOT7_1->phase>>FREQ_SH)>>7)&1; - unsigned char bit3 = ((SLOT7_1->phase>>FREQ_SH)>>3)&1; - unsigned char bit2 = ((SLOT7_1->phase>>FREQ_SH)>>2)&1; + uint8_t bit7 = ((SLOT7_1->phase>>FREQ_SH)>>7)&1; + uint8_t bit3 = ((SLOT7_1->phase>>FREQ_SH)>>3)&1; + uint8_t bit2 = ((SLOT7_1->phase>>FREQ_SH)>>2)&1; - unsigned char res1 = (bit2 ^ bit7) | bit3; + uint8_t res1 = (bit2 ^ bit7) | bit3; /* when res1 = 0 phase = 0x000 | 0x100; */ /* when res1 = 1 phase = 0x200 | 0x100; */ uint32_t phase = res1 ? 0x300 : 0x100; /* enable gate based on frequency of operator 2 in channel 8 */ - unsigned char bit5e= ((SLOT8_2->phase>>FREQ_SH)>>5)&1; - unsigned char bit3e= ((SLOT8_2->phase>>FREQ_SH)>>3)&1; + uint8_t bit5e= ((SLOT8_2->phase>>FREQ_SH)>>5)&1; + uint8_t bit3e= ((SLOT8_2->phase>>FREQ_SH)>>3)&1; - unsigned char res2 = (bit3e | bit5e); + uint8_t res2 = (bit3e | bit5e); /* when res2 = 0 pass the phase from calculation above (res1); */ /* when res2 = 1 phase = 0x200 | 0x100; */ if (res2) @@ -1635,11 +1675,14 @@ void ym2413_device::device_reset() noise_rng = 1; /* noise shift register */ /* setup instruments table */ - for (int i=0; i<19; i++) + if (m_inst_table != nullptr) { - for (int c=0; c<8; c++) + for (int i=0; i<19; i++) { - inst_tab[i][c] = table[i][c]; + for (int c=0; c<8; c++) + { + inst_tab[i][c] = m_inst_table[i][c]; + } } } @@ -1686,7 +1729,37 @@ void ym2413_device::data_port_w(u8 data) DEFINE_DEVICE_TYPE(YM2413, ym2413_device, "ym2413", "Yamaha YM2413 OPLL") ym2413_device::ym2413_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, YM2413, tag, owner, clock) + : ym2413_device(mconfig, YM2413, tag, owner, clock) +{ + for (int i = 0; i < 19; i++) + { + for (int c = 0; c < 8; c++) + { + m_inst_table[i][c] = table[i][c]; + } + } +} + +ym2413_device::ym2413_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, type, tag, owner, clock) , device_sound_interface(mconfig, *this) { + for (int i = 0; i < 19; i++) + { + std::fill_n(&m_inst_table[i][0], 8, 0); + } +} + +DEFINE_DEVICE_TYPE(VRC7, vrc7snd_device, "vrc7snd", "Konami VRC7 (Sound)") + +vrc7snd_device::vrc7snd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : ym2413_device(mconfig, VRC7, tag, owner, clock) +{ + for (int i = 0; i < 19; i++) + { + for (int c = 0; c < 8; c++) + { + m_inst_table[i][c] = vrc7_table[i][c]; + } + } } diff --git a/src/devices/sound/ym2413.h b/src/devices/sound/ym2413.h index 32114624eff..1b0d9869770 100644 --- a/src/devices/sound/ym2413.h +++ b/src/devices/sound/ym2413.h @@ -17,6 +17,8 @@ public: void data_port_w(u8 data); protected: + ym2413_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + // device-level overrides virtual void device_start() override; virtual void device_clock_changed() override; @@ -25,6 +27,8 @@ protected: // sound stream update overrides virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + uint8_t m_inst_table[19][8]; + private: struct OPLL_SLOT { @@ -106,13 +110,13 @@ private: static const double ksl_tab[8*16]; static const uint32_t ksl_shift[4]; static const uint32_t sl_tab[16]; - static const unsigned char eg_inc[15*RATE_STEPS]; - static const unsigned char eg_rate_select[16+64+16]; - static const unsigned char eg_rate_shift[16+64+16]; + static const uint8_t eg_inc[15*RATE_STEPS]; + static const uint8_t eg_rate_select[16+64+16]; + static const uint8_t eg_rate_shift[16+64+16]; static const uint8_t mul_tab[16]; static const uint8_t lfo_am_table[LFO_AM_TAB_ELEMENTS]; static const int8_t lfo_pm_table[8*8]; - static const unsigned char table[19][8]; + static const uint8_t table[19][8]; int tl_tab[TL_TAB_LEN]; @@ -185,4 +189,15 @@ private: DECLARE_DEVICE_TYPE(YM2413, ym2413_device) +class vrc7snd_device : public ym2413_device +{ +public: + vrc7snd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +private: + static const uint8_t vrc7_table[19][8]; +}; + +DECLARE_DEVICE_TYPE(VRC7, vrc7snd_device) + #endif // MAME_SOUND_YM2413_H