diff options
| author | 2022-10-26 23:36:28 -0400 | |
|---|---|---|
| committer | 2022-10-26 23:36:28 -0400 | |
| commit | 0fdef71b9a497ae909f8471bd152073c0e761c49 (patch) | |
| tree | 9bbace85ce07811eef0458710ae699bc04eb9e20 | |
| parent | 8d039fe4caf8b790633d9d093f0454f6283e4ec2 (diff) | |
Terra Cresta and later Nichibutsu drivers: Consolidate some common configs down into their own machine_config sections, and reduce a lot of code duplication. Also fix audio volume balance to compensate for the fact that the YM3012 Serial DAC for the FM chips outputs at half the peak to peak voltage of the R2R DACs, and the YM2203's SSG channels have another, different peak output level as well. This also adds filtered sound to Legion, which didn't have it in the previous commit due to the complex configs it had. [Lord Nightmare]
| -rw-r--r-- | src/mame/nichibutsu/armedf.cpp | 169 | ||||
| -rw-r--r-- | src/mame/nichibutsu/armedf.h | 6 | ||||
| -rw-r--r-- | src/mame/nichibutsu/galivan.cpp | 88 | ||||
| -rw-r--r-- | src/mame/nichibutsu/galivan.h | 1 | ||||
| -rw-r--r-- | src/mame/nichibutsu/terracre.cpp | 52 |
5 files changed, 156 insertions, 160 deletions
diff --git a/src/mame/nichibutsu/armedf.cpp b/src/mame/nichibutsu/armedf.cpp index f31dce7c058..758a0c26aa2 100644 --- a/src/mame/nichibutsu/armedf.cpp +++ b/src/mame/nichibutsu/armedf.cpp @@ -641,13 +641,13 @@ void bigfghtr_state::bigfghtr_mcu_io_map(address_map &map) map(0x00600, 0x03fff).ram().share("sharedram"); } -void armedf_state::sound_map(address_map &map) +void armedf_state::sound_map(address_map &map) // common sound map for the terra force bottom pcb, also used on armed f, tatakae big fighter, etc { map(0x0000, 0xf7ff).rom(); map(0xf800, 0xffff).ram(); } -void armedf_state::cclimbr2_soundmap(address_map &map) +void armedf_state::cclimbr2_soundmap(address_map &map) // common sound map for the crazy climber 2 and legion bottom pcbs { map(0x0000, 0xbfff).rom(); map(0xc000, 0xffff).ram(); @@ -1106,12 +1106,10 @@ void armedf_state::video_config(machine_config &config, int hchar_start, int vst BUFFERED_SPRITERAM16(config, m_spriteram); } -void armedf_state::sound_config(machine_config &config) +void armedf_state::sound_config_common(machine_config &config) // common amongst all pcbs { - z80_device &audiocpu(Z80(config, "audiocpu", XTAL(24'000'000)/6)); // 4mhz - audiocpu.set_addrmap(AS_PROGRAM, &armedf_state::sound_map); - audiocpu.set_addrmap(AS_IO, &armedf_state::sound_portmap); - audiocpu.set_periodic_int(FUNC(armedf_state::irq0_line_hold), attotime::from_hz(XTAL(8'000'000)/2/512)); // ? + Z80(config, m_audiocpu, XTAL(24'000'000)/6); // 4mhz + m_audiocpu->set_periodic_int(FUNC(armedf_state::irq0_line_hold), attotime::from_hz(XTAL(8'000'000)/2/512)); // ? SPEAKER(config, "speaker").front_center(); @@ -1119,8 +1117,23 @@ void armedf_state::sound_config(machine_config &config) // Note: Component locations here come from the common terra force/sky robo // /takakae! big fighter sound pcb; the locations and components are not - // yet verified for other sound pcbs. + // yet verified for other sound pcbs, although from pictures of a legion + // pcb, while the component locations are different, the values appear + // to be the same. // The 3 mixing resistors for YM, DAC1 and DAC2 are all identical (1K). + // However, the actual volume output by the ym3014 dac and the r2r resistors + // is not the same range on each! + // The YM3014 dac has a DC offset of 1/2 VDD, then +- 1/4 VDD of signal, + // so min of 1.25v and max of 3.75v, vpp of 2.5v + // The R2R dacs are full range, min of 0v and max of (almost) 5v, vpp of ~5.0v + // Because of this, we have to compensate as MAME's ymfm core outputs full range. + // Math:: + // YMFM: 0.3333 * 0.5 = 0.16665 + // DAC1: 0.3333 * 1.0 = 0.3333 + // DAC2: 0.3333 * 1.0 = 0.3333 + // Sum: 0.83325 + // Multiply all 3 values by 1 / 0.83325 (i.e. 1.20012): + // Final values are: ym: 0.2; dac1: 0.4; dac2: 0.4 FILTER_BIQUAD(config, m_ymfilter).opamp_sk_lowpass_setup(RES_K(4.7), RES_K(4.7), RES_M(999.99), RES_R(0.001), CAP_N(3.3), CAP_N(1.0)); // R17, R16, nothing(infinite resistance), wire(short), C82, C68 m_ymfilter->add_route(ALL_OUTPUTS, "speaker", 1.0); FILTER_BIQUAD(config, m_dacfilter1).opamp_sk_lowpass_setup(RES_K(10), RES_K(10), RES_M(999.99), RES_R(0.001), CAP_N(10), CAP_N(4.7)); // R15, R10, nothing(infinite resistance), wire(short), C81, C60 @@ -1128,12 +1141,47 @@ void armedf_state::sound_config(machine_config &config) FILTER_BIQUAD(config, m_dacfilter2).opamp_sk_lowpass_setup(RES_K(10), RES_K(10), RES_M(999.99), RES_R(0.001), CAP_N(10), CAP_N(4.7)); // R13, R9, nothing(infinite resistance), wire(short), C66, C61 m_dacfilter2->add_route(ALL_OUTPUTS, "speaker", 1.0); - YM3812(config, "ymsnd", XTAL(24'000'000)/6).add_route(ALL_OUTPUTS, m_ymfilter, 0.333); // or YM3526? + DAC_8BIT_R2R(config, "dac1", 0).add_route(ALL_OUTPUTS, m_dacfilter1, 0.4); // SIP R2R DAC @ G11-1 with 74HC374P latch + DAC_8BIT_R2R(config, "dac2", 0).add_route(ALL_OUTPUTS, m_dacfilter2, 0.4); // SIP R2R DAC @ G11-2 with 74HC374P latch +} + +void armedf_state::sound_config(machine_config &config) // 3526, used on almost all non-bootlegs +{ + sound_config_common(config); + m_audiocpu->set_addrmap(AS_PROGRAM, &armedf_state::sound_map); + m_audiocpu->set_addrmap(AS_IO, &armedf_state::sound_3526_portmap); + + YM3526(config, "ymsnd", XTAL(24'000'000)/6).add_route(ALL_OUTPUTS, m_ymfilter, 0.2); +} + +void armedf_state::sound_config_3812(machine_config &config) // 3812, used on bootlegs and skyrobo/bigfghtr +{ + sound_config_common(config); + m_audiocpu->set_addrmap(AS_PROGRAM, &armedf_state::sound_map); + m_audiocpu->set_addrmap(AS_IO, &armedf_state::sound_portmap); + + YM3812(config, "ymsnd", XTAL(24'000'000)/6).add_route(ALL_OUTPUTS, m_ymfilter, 0.2); +} + +void armedf_state::sound_config_legion(machine_config &config) // 3526, used on non-bootleg legion and cclimbr2 +{ + sound_config_common(config); + m_audiocpu->set_addrmap(AS_PROGRAM, &armedf_state::cclimbr2_soundmap); + m_audiocpu->set_addrmap(AS_IO, &armedf_state::sound_3526_portmap); + + YM3526(config, "ymsnd", XTAL(24'000'000)/6).add_route(ALL_OUTPUTS, m_ymfilter, 0.2); +} + +void armedf_state::sound_config_legion_3812(machine_config &config) // 3812, used on legion bootlegs +{ + sound_config_common(config); + m_audiocpu->set_addrmap(AS_PROGRAM, &armedf_state::cclimbr2_soundmap); + m_audiocpu->set_addrmap(AS_IO, &armedf_state::sound_portmap); - DAC_8BIT_R2R(config, "dac1", 0).add_route(ALL_OUTPUTS, m_dacfilter1, 0.333); // SIP R2R DAC @ G11-1 with 74HC374P latch - DAC_8BIT_R2R(config, "dac2", 0).add_route(ALL_OUTPUTS, m_dacfilter2, 0.333); // SIP R2R DAC @ G11-2 with 74HC374P latch + YM3812(config, "ymsnd", XTAL(24'000'000)/6).add_route(ALL_OUTPUTS, m_ymfilter, 0.2); } + void armedf_state::terraf(machine_config &config) { M68000(config, m_maincpu, XTAL(16'000'000)/2); // 8mhz? @@ -1155,11 +1203,6 @@ void armedf_state::terrafjb(machine_config &config) m_maincpu->set_addrmap(AS_PROGRAM, &armedf_state::terrafjb_map); m_maincpu->set_vblank_int("screen", FUNC(armedf_state::irq1_line_assert)); - z80_device &audiocpu(Z80(config, "audiocpu", XTAL(24'000'000)/6)); // 4mhz - audiocpu.set_addrmap(AS_PROGRAM, &armedf_state::sound_map); - audiocpu.set_addrmap(AS_IO, &armedf_state::sound_portmap); - audiocpu.set_periodic_int(FUNC(armedf_state::irq0_line_hold), attotime::from_hz(XTAL(8'000'000)/2/512)); // ? - Z80(config, m_extra, XTAL(16'000'000)/4); // 4mhz? m_extra->set_addrmap(AS_PROGRAM, &armedf_state::terrafjb_extraz80_map); m_extra->set_addrmap(AS_IO, &armedf_state::terrafjb_extraz80_portmap); @@ -1168,25 +1211,7 @@ void armedf_state::terrafjb(machine_config &config) MCFG_VIDEO_START_OVERRIDE(armedf_state,terraf) /* sound hardware */ - SPEAKER(config, "speaker").front_center(); - - GENERIC_LATCH_8(config, m_soundlatch); - - // Note: Component locations here come from the common terra force/sky robo - // /takakae! big fighter sound pcb; the locations and components are not - // yet verified for other sound pcbs. - // The 3 mixing resistors for YM, DAC1 and DAC2 are all identical (1K). - FILTER_BIQUAD(config, m_ymfilter).opamp_sk_lowpass_setup(RES_K(4.7), RES_K(4.7), RES_M(999.99), RES_R(0.001), CAP_N(3.3), CAP_N(1.0)); // R17, R16, nothing(infinite resistance), wire(short), C82, C68 - m_ymfilter->add_route(ALL_OUTPUTS, "speaker", 1.0); - FILTER_BIQUAD(config, m_dacfilter1).opamp_sk_lowpass_setup(RES_K(10), RES_K(10), RES_M(999.99), RES_R(0.001), CAP_N(10), CAP_N(4.7)); // R15, R10, nothing(infinite resistance), wire(short), C81, C60 - m_dacfilter1->add_route(ALL_OUTPUTS, "speaker", 1.0); - FILTER_BIQUAD(config, m_dacfilter2).opamp_sk_lowpass_setup(RES_K(10), RES_K(10), RES_M(999.99), RES_R(0.001), CAP_N(10), CAP_N(4.7)); // R13, R9, nothing(infinite resistance), wire(short), C66, C61 - m_dacfilter2->add_route(ALL_OUTPUTS, "speaker", 1.0); - - YM3812(config, "ymsnd", XTAL(24'000'000)/6).add_route(ALL_OUTPUTS, m_ymfilter, 0.333); // or YM3526? - - DAC_8BIT_R2R(config, "dac1", 0).add_route(ALL_OUTPUTS, m_dacfilter1, 0.333); // SIP R2R DAC @ G11-1 with 74HC374P latch - DAC_8BIT_R2R(config, "dac2", 0).add_route(ALL_OUTPUTS, m_dacfilter2, 0.333); // SIP R2R DAC @ G11-2 with 74HC374P latch + sound_config_3812(config); } void armedf_state::terrafb(machine_config &config) @@ -1218,34 +1243,11 @@ void armedf_state::armedf(machine_config &config) m_maincpu->set_addrmap(AS_PROGRAM, &armedf_state::armedf_map); m_maincpu->set_vblank_int("screen", FUNC(armedf_state::irq1_line_assert)); - z80_device &audiocpu(Z80(config, "audiocpu", XTAL(24'000'000)/6)); // 4mhz - audiocpu.set_addrmap(AS_PROGRAM, &armedf_state::sound_map); - audiocpu.set_addrmap(AS_IO, &armedf_state::sound_portmap); - audiocpu.set_periodic_int(FUNC(armedf_state::irq0_line_hold), attotime::from_hz(XTAL(8'000'000)/2/512)); // ? - video_config(config, 12, 8, 248); MCFG_VIDEO_START_OVERRIDE(armedf_state,armedf) /* sound hardware */ - SPEAKER(config, "speaker").front_center(); - - GENERIC_LATCH_8(config, m_soundlatch); - - // Note: Component locations here come from the common terra force/sky robo - // /takakae! big fighter sound pcb; the locations and components are not - // yet verified for other sound pcbs. - // The 3 mixing resistors for YM, DAC1 and DAC2 are all identical (1K). - FILTER_BIQUAD(config, m_ymfilter).opamp_sk_lowpass_setup(RES_K(4.7), RES_K(4.7), RES_M(999.99), RES_R(0.001), CAP_N(3.3), CAP_N(1.0)); // R17, R16, nothing(infinite resistance), wire(short), C82, C68 - m_ymfilter->add_route(ALL_OUTPUTS, "speaker", 1.0); - FILTER_BIQUAD(config, m_dacfilter1).opamp_sk_lowpass_setup(RES_K(10), RES_K(10), RES_M(999.99), RES_R(0.001), CAP_N(10), CAP_N(4.7)); // R15, R10, nothing(infinite resistance), wire(short), C81, C60 - m_dacfilter1->add_route(ALL_OUTPUTS, "speaker", 1.0); - FILTER_BIQUAD(config, m_dacfilter2).opamp_sk_lowpass_setup(RES_K(10), RES_K(10), RES_M(999.99), RES_R(0.001), CAP_N(10), CAP_N(4.7)); // R13, R9, nothing(infinite resistance), wire(short), C66, C61 - m_dacfilter2->add_route(ALL_OUTPUTS, "speaker", 1.0); - - YM3812(config, "ymsnd", XTAL(24'000'000)/6).add_route(ALL_OUTPUTS, m_ymfilter, 0.333); // or YM3526? - - DAC_8BIT_R2R(config, "dac1", 0).add_route(ALL_OUTPUTS, m_dacfilter1, 0.333); // SIP R2R DAC @ G11-1 with 74HC374P latch - DAC_8BIT_R2R(config, "dac2", 0).add_route(ALL_OUTPUTS, m_dacfilter2, 0.333); // SIP R2R DAC @ G11-2 with 74HC374P latch + sound_config(config); } void armedf_state::cclimbr2(machine_config &config) @@ -1254,36 +1256,13 @@ void armedf_state::cclimbr2(machine_config &config) m_maincpu->set_addrmap(AS_PROGRAM, &armedf_state::cclimbr2_map); m_maincpu->set_vblank_int("screen", FUNC(armedf_state::irq2_line_assert)); - z80_device &audiocpu(Z80(config, "audiocpu", XTAL(24'000'000)/6)); // 4mhz - audiocpu.set_addrmap(AS_PROGRAM, &armedf_state::cclimbr2_soundmap); - audiocpu.set_addrmap(AS_IO, &armedf_state::sound_portmap); - audiocpu.set_periodic_int(FUNC(armedf_state::irq0_line_hold), attotime::from_hz(XTAL(8'000'000)/2/512)); // ? - NB1414M4(config, m_nb1414m4, 0); video_config(config, 14, 16, 240); MCFG_VIDEO_START_OVERRIDE(armedf_state,terraf) /* sound hardware */ - SPEAKER(config, "speaker").front_center(); - - GENERIC_LATCH_8(config, m_soundlatch); - - // Note: Component locations here come from the common terra force/sky robo - // /takakae! big fighter sound pcb; the locations and components are not - // yet verified for other sound pcbs. - // The 3 mixing resistors for YM, DAC1 and DAC2 are all identical (1K). - FILTER_BIQUAD(config, m_ymfilter).opamp_sk_lowpass_setup(RES_K(4.7), RES_K(4.7), RES_M(999.99), RES_R(0.001), CAP_N(3.3), CAP_N(1.0)); // R17, R16, nothing(infinite resistance), wire(short), C82, C68 - m_ymfilter->add_route(ALL_OUTPUTS, "speaker", 1.0); - FILTER_BIQUAD(config, m_dacfilter1).opamp_sk_lowpass_setup(RES_K(10), RES_K(10), RES_M(999.99), RES_R(0.001), CAP_N(10), CAP_N(4.7)); // R15, R10, nothing(infinite resistance), wire(short), C81, C60 - m_dacfilter1->add_route(ALL_OUTPUTS, "speaker", 1.0); - FILTER_BIQUAD(config, m_dacfilter2).opamp_sk_lowpass_setup(RES_K(10), RES_K(10), RES_M(999.99), RES_R(0.001), CAP_N(10), CAP_N(4.7)); // R13, R9, nothing(infinite resistance), wire(short), C66, C61 - m_dacfilter2->add_route(ALL_OUTPUTS, "speaker", 1.0); - - YM3812(config, "ymsnd", XTAL(24'000'000)/6).add_route(ALL_OUTPUTS, m_ymfilter, 0.333); // or YM3526? - - DAC_8BIT_R2R(config, "dac1", 0).add_route(ALL_OUTPUTS, m_dacfilter1, 0.333); // SIP R2R DAC @ G11-1 with 74HC374P latch - DAC_8BIT_R2R(config, "dac2", 0).add_route(ALL_OUTPUTS, m_dacfilter2, 0.333); // SIP R2R DAC @ G11-2 with 74HC374P latch + sound_config_legion(config); } void armedf_state::legion_common(machine_config &config) @@ -1291,20 +1270,8 @@ void armedf_state::legion_common(machine_config &config) M68000(config, m_maincpu, XTAL(16'000'000)/2); // 8mhz m_maincpu->set_vblank_int("screen", FUNC(armedf_state::irq2_line_assert)); - z80_device &audiocpu(Z80(config, "audiocpu", XTAL(24'000'000)/6)); // 4mhz - audiocpu.set_addrmap(AS_PROGRAM, &armedf_state::cclimbr2_soundmap); - audiocpu.set_periodic_int(FUNC(armedf_state::irq0_line_hold), attotime::from_hz(XTAL(8'000'000)/2/512)); // ? - video_config(config, 14, 16, 240); MCFG_VIDEO_START_OVERRIDE(armedf_state,terraf) - - /* sound hardware */ - SPEAKER(config, "speaker").front_center(); - - GENERIC_LATCH_8(config, m_soundlatch); - - DAC_8BIT_R2R(config, "dac1", 0).add_route(ALL_OUTPUTS, "speaker", 0.8); // 10-pin SIP with 74HC374P latch - DAC_8BIT_R2R(config, "dac2", 0).add_route(ALL_OUTPUTS, "speaker", 0.8); // 10-pin SIP with 74HC374P latch } void armedf_state::legion(machine_config &config) @@ -1313,11 +1280,10 @@ void armedf_state::legion(machine_config &config) m_maincpu->set_addrmap(AS_PROGRAM, &armedf_state::legion_map); - subdevice<z80_device>("audiocpu")->set_addrmap(AS_IO, &armedf_state::sound_3526_portmap); - NB1414M4(config, m_nb1414m4, 0); - YM3526(config, "ymsnd", XTAL(24'000'000)/6).add_route(ALL_OUTPUTS, "speaker", 0.5); // 4mhz + /* sound hardware */ + sound_config_legion(config); } void armedf_state::legionjb(machine_config &config) @@ -1326,9 +1292,8 @@ void armedf_state::legionjb(machine_config &config) m_maincpu->set_addrmap(AS_PROGRAM, &armedf_state::legionjb_map); - subdevice<z80_device>("audiocpu")->set_addrmap(AS_IO, &armedf_state::sound_portmap); - - YM3812(config, "ymsnd", XTAL(24'000'000)/6).add_route(ALL_OUTPUTS, "speaker", 0.5); // or YM3526? + /* sound hardware */ + sound_config_legion_3812(config); } void armedf_state::legionjb2(machine_config &config) @@ -1352,7 +1317,7 @@ void bigfghtr_state::bigfghtr(machine_config &config) video_config(config, 12, 8, 248); MCFG_VIDEO_START_OVERRIDE(bigfghtr_state,armedf) - sound_config(config); + sound_config_3812(config); } /************************************* diff --git a/src/mame/nichibutsu/armedf.h b/src/mame/nichibutsu/armedf.h index 73e6a482b3f..6f7cb1276e9 100644 --- a/src/mame/nichibutsu/armedf.h +++ b/src/mame/nichibutsu/armedf.h @@ -19,6 +19,7 @@ public: armedf_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) , m_maincpu(*this, "maincpu") + , m_audiocpu(*this, "audiocpu") , m_extra(*this, "extra") , m_nb1414m4(*this, "nb1414m4") , m_screen(*this, "screen") @@ -57,10 +58,15 @@ protected: virtual void machine_start() override; virtual void machine_reset() override; void video_config(machine_config &config, int hchar_start, int vstart, int vend); + void sound_config_common(machine_config &config); void sound_config(machine_config &config); + void sound_config_3812(machine_config &config); + void sound_config_legion(machine_config &config); + void sound_config_legion_3812(machine_config &config); // devices required_device<cpu_device> m_maincpu; + optional_device<cpu_device> m_audiocpu; optional_device<cpu_device> m_extra; optional_device<nb1414m4_device> m_nb1414m4; required_device<screen_device> m_screen; diff --git a/src/mame/nichibutsu/galivan.cpp b/src/mame/nichibutsu/galivan.cpp index ff847cf1640..551c60e535e 100644 --- a/src/mame/nichibutsu/galivan.cpp +++ b/src/mame/nichibutsu/galivan.cpp @@ -526,12 +526,10 @@ void galivan_state::video_config(machine_config &config) m_screen->set_palette(m_palette); } -void galivan_state::galivan(machine_config &config) +void galivan_state::galivan_common(machine_config &config) { /* basic machine hardware */ Z80(config, m_maincpu, XTAL(12'000'000)/2); /* 6 MHz? */ - m_maincpu->set_addrmap(AS_PROGRAM, &galivan_state::galivan_map); - m_maincpu->set_addrmap(AS_IO, &galivan_state::io_map); m_maincpu->set_vblank_int("screen", FUNC(galivan_state::irq0_line_assert)); z80_device &audiocpu(Z80(config, "audiocpu", XTAL(8'000'000)/2)); /* 4 MHz? */ @@ -539,14 +537,8 @@ void galivan_state::galivan(machine_config &config) audiocpu.set_addrmap(AS_IO, &galivan_state::sound_io_map); audiocpu.set_periodic_int(FUNC(galivan_state::irq0_line_hold), attotime::from_hz(XTAL(8'000'000)/2/512)); // ? - MCFG_MACHINE_START_OVERRIDE(galivan_state,galivan) - MCFG_MACHINE_RESET_OVERRIDE(galivan_state,galivan) - + /* video hardware */ video_config(config); - MCFG_VIDEO_START_OVERRIDE(galivan_state,galivan) - m_screen->set_screen_update(FUNC(galivan_state::screen_update_galivan)); - GFXDECODE(config, m_gfxdecode, m_palette, gfx_galivan); - PALETTE(config, m_palette, FUNC(galivan_state::galivan_palette), 16*16+16*16+256*16, 256); /* sound hardware */ SPEAKER(config, "speaker").front_center(); @@ -559,6 +551,19 @@ void galivan_state::galivan(machine_config &config) // Yamaha - 1kohm = 0.6597 of total // DAC1 - 4.7kohm = 0.1404 of total // DAC2 - 3.3kohm = 0.1999 of total + // However, the actual volume output by the ym3014 dac and the r2r resistors + // is not the same range on each! + // The YM3014 dac has a DC offset of 1/2 VDD, then +- 1/4 VDD of signal, + // so min of 1.25v and max of 3.75v, vpp of 2.5v + // The R2R dacs are full range, min of 0v and max of (almost) 5v, vpp of ~5.0v + // Because of this, we have to compensate as MAME's ymfm core outputs full range. + // Math: + // YMFM: 0.6597 * 0.5 = 0.32985 + // DAC1: 0.1404 * 1.0 = 0.1404 + // DAC2: 0.1999 * 1.0 = 0.1999 + // Sum: 0.67015 + // Multiply all 3 values by 1 / 0.67015 (i.e. 1.492203): + // Final values are: ym: 0.492203; dac1: 0.209505; dac2: 0.298291 FILTER_BIQUAD(config, m_ymfilter).opamp_sk_lowpass_setup(RES_K(4.7), RES_K(4.7), RES_M(999.99), RES_R(0.001), CAP_N(3.3), CAP_N(1.0)); // R15, R14, nothing(infinite resistance), wire(short), C9, C11 m_ymfilter->add_route(ALL_OUTPUTS, "speaker", 1.0); @@ -567,11 +572,29 @@ void galivan_state::galivan(machine_config &config) FILTER_BIQUAD(config, m_dacfilter2).opamp_sk_lowpass_setup(RES_K(10), RES_K(10), RES_M(999.99), RES_R(0.001), CAP_N(10), CAP_N(4.7)); // R13, R12, nothing(infinite resistance), wire(short), C8, C18 m_dacfilter2->add_route(ALL_OUTPUTS, "speaker", 1.0); - YM3526(config, "ymsnd", XTAL(8'000'000)/2).add_route(ALL_OUTPUTS, m_ymfilter, 0.6597); + YM3526(config, "ymsnd", XTAL(8'000'000)/2).add_route(ALL_OUTPUTS, m_ymfilter, 0.4922); // note the two dac channel volume mix values might be backwards, we need a pcb reference recording! - DAC_8BIT_R2R(config, "dac1", 0).add_route(ALL_OUTPUTS, m_dacfilter1, 0.1404); // SIP R2R DAC @ RA1 with 74HC374P latch - DAC_8BIT_R2R(config, "dac2", 0).add_route(ALL_OUTPUTS, m_dacfilter2, 0.1999); // SIP R2R DAC @ RA2 with 74HC374P latch + DAC_8BIT_R2R(config, "dac1", 0).add_route(ALL_OUTPUTS, m_dacfilter1, 0.2095); // SIP R2R DAC @ RA1 with 74HC374P latch + DAC_8BIT_R2R(config, "dac2", 0).add_route(ALL_OUTPUTS, m_dacfilter2, 0.2983); // SIP R2R DAC @ RA2 with 74HC374P latch +} + +void galivan_state::galivan(machine_config &config) +{ + galivan_common(config); + + /* basic machine hardware */ + m_maincpu->set_addrmap(AS_PROGRAM, &galivan_state::galivan_map); + m_maincpu->set_addrmap(AS_IO, &galivan_state::io_map); + + MCFG_MACHINE_START_OVERRIDE(galivan_state,galivan) + MCFG_MACHINE_RESET_OVERRIDE(galivan_state,galivan) + + /* video hardware */ + MCFG_VIDEO_START_OVERRIDE(galivan_state,galivan) + m_screen->set_screen_update(FUNC(galivan_state::screen_update_galivan)); + GFXDECODE(config, m_gfxdecode, m_palette, gfx_galivan); + PALETTE(config, m_palette, FUNC(galivan_state::galivan_palette), 16*16+16*16+256*16, 256); } void dangarj_state::dangarj(machine_config &config) @@ -584,16 +607,11 @@ void dangarj_state::dangarj(machine_config &config) void galivan_state::ninjemak(machine_config &config) { + galivan_common(config); + /* basic machine hardware */ - Z80(config, m_maincpu, XTAL(12'000'000)/2); /* 6 MHz? */ m_maincpu->set_addrmap(AS_PROGRAM, &galivan_state::ninjemak_map); m_maincpu->set_addrmap(AS_IO, &galivan_state::ninjemak_io_map); - m_maincpu->set_vblank_int("screen", FUNC(galivan_state::irq0_line_assert)); - - z80_device &audiocpu(Z80(config, "audiocpu", XTAL(8'000'000)/2)); /* 4 MHz? */ - audiocpu.set_addrmap(AS_PROGRAM, &galivan_state::sound_map); - audiocpu.set_addrmap(AS_IO, &galivan_state::sound_io_map); - audiocpu.set_periodic_int(FUNC(galivan_state::irq0_line_hold), attotime::from_hz(XTAL(8'000'000)/2/512)); // ? MCFG_MACHINE_START_OVERRIDE(galivan_state,ninjemak) MCFG_MACHINE_RESET_OVERRIDE(galivan_state,ninjemak) @@ -601,36 +619,10 @@ void galivan_state::ninjemak(machine_config &config) NB1414M4(config, m_nb1414m4, 0); /* video hardware */ - video_config(config); MCFG_VIDEO_START_OVERRIDE(galivan_state,ninjemak) m_screen->set_screen_update(FUNC(galivan_state::screen_update_ninjemak)); GFXDECODE(config, m_gfxdecode, m_palette, gfx_ninjemak); PALETTE(config, m_palette, FUNC(galivan_state::ninjemak_palette), 8*16+16*16+256*16, 256); - - /* sound hardware */ - SPEAKER(config, "speaker").front_center(); - - GENERIC_LATCH_8(config, m_soundlatch); - - // Note: The galivan filters are identical to the later Nichibutsu filters(armedf.cpp) - // with the sole exception of the mixing resistors and component locations. - // Mixing resistors: - // Yamaha - 1kohm = 0.6597 of total - // DAC1 - 4.7kohm = 0.1404 of total - // DAC2 - 3.3kohm = 0.1999 of total - - FILTER_BIQUAD(config, m_ymfilter).opamp_sk_lowpass_setup(RES_K(4.7), RES_K(4.7), RES_M(999.99), RES_R(0.001), CAP_N(3.3), CAP_N(1.0)); // R15, R14, nothing(infinite resistance), wire(short), C9, C11 - m_ymfilter->add_route(ALL_OUTPUTS, "speaker", 1.0); - FILTER_BIQUAD(config, m_dacfilter1).opamp_sk_lowpass_setup(RES_K(10), RES_K(10), RES_M(999.99), RES_R(0.001), CAP_N(10), CAP_N(4.7)); // R11, R10, nothing(infinite resistance), wire(short), C7, C17 - m_dacfilter1->add_route(ALL_OUTPUTS, "speaker", 1.0); - FILTER_BIQUAD(config, m_dacfilter2).opamp_sk_lowpass_setup(RES_K(10), RES_K(10), RES_M(999.99), RES_R(0.001), CAP_N(10), CAP_N(4.7)); // R13, R12, nothing(infinite resistance), wire(short), C8, C18 - m_dacfilter2->add_route(ALL_OUTPUTS, "speaker", 1.0); - - YM3526(config, "ymsnd", XTAL(8'000'000)/2).add_route(ALL_OUTPUTS, m_ymfilter, 0.6597); - - // note the two dac channel volume mix values might be backwards, we need a pcb reference recording! - DAC_8BIT_R2R(config, "dac1", 0).add_route(ALL_OUTPUTS, m_dacfilter1, 0.1404); // SIP R2R DAC @ RA1 with 74HC374P latch - DAC_8BIT_R2R(config, "dac2", 0).add_route(ALL_OUTPUTS, m_dacfilter2, 0.1999); // SIP R2R DAC @ RA2 with 74HC374P latch } void galivan_state::youmab(machine_config &config) @@ -1298,10 +1290,10 @@ void galivan_state::init_youmab() GAME( 1985, galivan, 0, galivan, galivan, galivan_state, empty_init, ROT270, "Nichibutsu", "Cosmo Police Galivan (12/26/1985)", MACHINE_SUPPORTS_SAVE ) GAME( 1985, galivan2, galivan, galivan, galivan, galivan_state, empty_init, ROT270, "Nichibutsu", "Cosmo Police Galivan (12/16/1985)", MACHINE_SUPPORTS_SAVE ) GAME( 1985, galivan3, galivan, galivan, galivan, galivan_state, empty_init, ROT270, "Nichibutsu", "Cosmo Police Galivan (12/11/1985)", MACHINE_SUPPORTS_SAVE ) -GAME( 1986, dangar, 0, galivan, dangar, galivan_state, empty_init, ROT270, "Nichibutsu", "Ufo Robo Dangar (4/07/1987)", MACHINE_SUPPORTS_SAVE ) // GV-1412-I and GV-1412-II pcbs +GAME( 1986, dangar, 0, galivan, dangar, galivan_state, empty_init, ROT270, "Nichibutsu", "Ufo Robo Dangar (4/09/1987)", MACHINE_SUPPORTS_SAVE ) // GV-1412-I and GV-1412-II pcbs GAME( 1986, dangara, dangar, galivan, dangar2, galivan_state, empty_init, ROT270, "Nichibutsu", "Ufo Robo Dangar (12/1/1986)", MACHINE_SUPPORTS_SAVE ) GAME( 1986, dangarj, dangar, dangarj, dangar2, dangarj_state, empty_init, ROT270, "Nichibutsu", "Ufo Robo Dangar (9/26/1986, Japan)", MACHINE_SUPPORTS_SAVE ) -GAME( 1986, dangarb, dangar, galivan, dangar2, galivan_state, empty_init, ROT270, "Nichibutsu", "Ufo Robo Dangar (9/26/1986, bootleg set 1)", MACHINE_SUPPORTS_SAVE ) // checks protection like dangarj but check readback is patched at 0x9d58 (also checks i/o port 0xc0?) +GAME( 1986, dangarb, dangar, galivan, dangar2, galivan_state, empty_init, ROT270, "bootleg", "Ufo Robo Dangar (9/26/1986, bootleg set 1)", MACHINE_SUPPORTS_SAVE ) // checks protection like dangarj but check readback is patched at 0x9d58 (also checks i/o port 0xc0?) GAME( 1986, dangarbt, dangar, galivan, dangarb, galivan_state, empty_init, ROT270, "bootleg", "Ufo Robo Dangar (9/26/1986, bootleg set 2)", MACHINE_SUPPORTS_SAVE ) // directly patched at entry point 0x9d44 GAME( 1986, ninjemak, 0, ninjemak, ninjemak, galivan_state, empty_init, ROT270, "Nichibutsu", "Ninja Emaki (US)", MACHINE_SUPPORTS_SAVE|MACHINE_UNEMULATED_PROTECTION ) GAME( 1986, youma, ninjemak, ninjemak, ninjemak, galivan_state, empty_init, ROT270, "Nichibutsu", "Youma Ninpou Chou (Japan)", MACHINE_SUPPORTS_SAVE|MACHINE_UNEMULATED_PROTECTION ) diff --git a/src/mame/nichibutsu/galivan.h b/src/mame/nichibutsu/galivan.h index 211e0afea88..cf9c964f9fb 100644 --- a/src/mame/nichibutsu/galivan.h +++ b/src/mame/nichibutsu/galivan.h @@ -38,6 +38,7 @@ public: , m_rombank(*this, "rombank") { } + void galivan_common(machine_config &config); void galivan(machine_config &config); void ninjemak(machine_config &config); void youmab(machine_config &config); diff --git a/src/mame/nichibutsu/terracre.cpp b/src/mame/nichibutsu/terracre.cpp index 0012d160ce6..a17412cda2a 100644 --- a/src/mame/nichibutsu/terracre.cpp +++ b/src/mame/nichibutsu/terracre.cpp @@ -488,6 +488,19 @@ void terracre_state::ym3526(machine_config &config) // R9 - Yamaha (digital/FM) - 1kohm = 0.4074 of total // R12 - DAC1 - 2.2kohm = 0.1852 of total // R8 - DAC2 - 1kohm = 0.4074 of total + // However, the actual volume output by the ym3014 dac and the r2r resistors + // is not the same range on each! + // The YM3014 dac has a DC offset of 1/2 VDD, then +- 1/4 VDD of signal, + // so min of 1.25v and max of 3.75v, vpp of 2.5v + // The R2R dacs are full range, min of 0v and max of (almost) 5v, vpp of ~5.0v + // Because of this, we have to compensate as MAME's ymfm core outputs full range. + // Math:: + // YMFM: 0.407407 * 0.5 = 0.203704 + // DAC1: 0.185185 * 1.0 = 0.185185 + // DAC2: 0.407407 * 1.0 = 0.407407 + // Sum: 0.796296 + // Multiply all 3 values by 1 / 0.796296 (i.e. 1.255814): + // Final values are: ym: 0.255814; dac1: 0.232558; dac2: 0.511628) FILTER_BIQUAD(config, m_ymfilter).opamp_sk_lowpass_setup(RES_K(4.7), RES_K(4.7), RES_M(999.99), RES_R(0.001), CAP_N(3.3), CAP_N(1.0)); // R10, R11, nothing(infinite resistance), wire(short), C11, C12 m_ymfilter->add_route(ALL_OUTPUTS, "speaker", 1.0); @@ -496,10 +509,11 @@ void terracre_state::ym3526(machine_config &config) FILTER_BIQUAD(config, m_dacfilter2).opamp_sk_lowpass_setup(RES_K(22), RES_K(22), RES_M(999.99), RES_R(0.001), CAP_N(10), CAP_N(4.7)); // R16, R15, nothing(infinite resistance), wire(short), C18, C21 m_dacfilter2->add_route(ALL_OUTPUTS, "speaker", 1.0); - YM3526(config, "ymsnd", XTAL(16'000'000)/4).add_route(ALL_OUTPUTS, m_ymfilter, 0.4074); // 4MHz verified on PCB + YM3526(config, "ymsnd", XTAL(16'000'000)/4).add_route(ALL_OUTPUTS, m_ymfilter, 0.2558); // 4MHz verified on PCB + + DAC_8BIT_R2R(config, "dac1", 0).add_route(ALL_OUTPUTS, m_dacfilter1, 0.2326); // SIP R2R DAC @ RA-1 with 74HC374P latch + DAC_8BIT_R2R(config, "dac2", 0).add_route(ALL_OUTPUTS, m_dacfilter2, 0.5116); // SIP R2R DAC @ RA-2 with 74HC374P latch - DAC_8BIT_R2R(config, "dac1", 0).add_route(ALL_OUTPUTS, m_dacfilter1, 0.1852); // SIP R2R DAC @ RA-1 with 74HC374P latch - DAC_8BIT_R2R(config, "dac2", 0).add_route(ALL_OUTPUTS, m_dacfilter2, 0.4074); // SIP R2R DAC @ RA-2 with 74HC374P latch } void terracre_state::ym2203(machine_config &config) @@ -517,6 +531,24 @@ void terracre_state::ym2203(machine_config &config) // R8 - DAC2 - 1kohm = 0.3500 of total // Yamaha (analog/SSG, channels A and B) - 3.3k = 0.1060 // Yamaha (analog/SSG, channel C) - 10k = 0.0350 + // However, the actual volume output by the ym3014 dac and the r2r resistors + // is not the same range on each! + // The YM3014 dac has a DC offset of 1/2 VDD, then +- 1/4 VDD of signal, + // so min of 1.25v and max of 3.75v, vpp of 2.5v + // The YM2203's 3 SSG analog channels each have a vpp of about 1.15v + // (i.e. midway between 0.95 and 1.35v on datasheet), before mixing. + // (we assume mixing is perfectly additive, which probably isn't 100% true) + // The R2R dacs are full range, min of 0v and max of (almost) 5v, vpp of ~5.0v + // Because of this, we have to compensate as MAME's ymfm core outputs full range. + // Math: (assuming a constant current for each component) + // YMFM: 0.350000 * 0.5 = 0.175 + // DAC1: 0.159000 * 1.0 = 0.159 + // DAC2: 0.350000 * 1.0 = 0.350 + // SSGA+B:0.106000 * 0.46 = 0.04876 + // SSGC: 0.035000 * 0.23 = 0.00805 + // Sum: 0.74081 + // Multiply all 5 values by 1 / 0.74081 (i.e. 1.349873): + // ym: 0.236228; dac1: 0.21463; dac2: 0.472456, ssgA+B: 0.06582; ssg3: 0.010866) FILTER_BIQUAD(config, m_ymfilter).opamp_sk_lowpass_setup(RES_K(4.7), RES_K(4.7), RES_M(999.99), RES_R(0.001), CAP_N(3.3), CAP_N(1.0)); // R10, R11, nothing(infinite resistance), wire(short), C11, C12 m_ymfilter->add_route(ALL_OUTPUTS, "speaker", 1.0); @@ -530,7 +562,7 @@ void terracre_state::ym2203(machine_config &config) // capacitance as the capacitor part of said circuit. (YR12, YR15). // Technically there may be some capacitance from YC3, although that is intended to be part of the SK filter below. FILTER_BIQUAD(config, m_ssgfilter_abgain).opamp_mfb_lowpass_setup(RES_K(4.7), 0.0, RES_K(10), 0.0, CAP_N(22)/100.0); // YR12, N/A(short), YR15, N/A(unpopulated), (parasitic capacitance from YC3) - m_ssgfilter_abgain->add_route(ALL_OUTPUTS, "speaker", 0.1060); + m_ssgfilter_abgain->add_route(ALL_OUTPUTS, "speaker", 1.0); // This filter is a 2nd order sallen-key lowpass, unity gain. FILTER_BIQUAD(config, m_ssgfilter_abfilt).opamp_sk_lowpass_setup(RES_K(10), RES_K(10), RES_M(999.99), RES_R(0.001), CAP_N(22), CAP_N(10)); // YR3, YR5, nothing(infinite resistance), wire(short), YC3, YC6 m_ssgfilter_abfilt->add_route(ALL_OUTPUTS, m_ssgfilter_abgain, 1.0); @@ -541,19 +573,19 @@ void terracre_state::ym2203(machine_config &config) // It turns out this cap is mathematically redundant vs the cap at YC1, and serves the // exact same purpose for calculating the cutoff. FILTER_BIQUAD(config, m_ssgfilter_cgain).opamp_mfb_lowpass_setup(RES_K(33), 0.0, RES_K(150), 0.0, CAP_N(100)); // YR8, N/A(short), YR7, N/A(unpopulated), YC1 - m_ssgfilter_cgain->add_route(ALL_OUTPUTS, "speaker", 0.0350); + m_ssgfilter_cgain->add_route(ALL_OUTPUTS, "speaker", 1.0); MIXER(config, m_ssgmixer); - m_ssgmixer->add_route(0, m_ssgfilter_abfilt, 1.0); + m_ssgmixer->add_route(0, m_ssgfilter_abfilt, 0.06582); ym2203_device &ym1(YM2203(config, "ym1", XTAL(16'000'000)/4)); // 4MHz verified on PCB ym1.add_route(0, m_ssgmixer, 1.0); ym1.add_route(1, m_ssgmixer, 1.0); - ym1.add_route(2, m_ssgfilter_cgain, 1.0); - ym1.add_route(3, m_ymfilter, 0.35); + ym1.add_route(2, m_ssgfilter_cgain, 0.010866); + ym1.add_route(3, m_ymfilter, 0.2362); - DAC_8BIT_R2R(config, "dac1", 0).add_route(ALL_OUTPUTS, m_dacfilter1, 0.1590); // SIP R2R DAC @ RA-1 with 74HC374P latch - DAC_8BIT_R2R(config, "dac2", 0).add_route(ALL_OUTPUTS, m_dacfilter2, 0.35); // SIP R2R DAC @ RA-2 with 74HC374P latch + DAC_8BIT_R2R(config, "dac1", 0).add_route(ALL_OUTPUTS, m_dacfilter1, 0.2146); // SIP R2R DAC @ RA-1 with 74HC374P latch + DAC_8BIT_R2R(config, "dac2", 0).add_route(ALL_OUTPUTS, m_dacfilter2, 0.4725); // SIP R2R DAC @ RA-2 with 74HC374P latch } void terracre_state::amazon_base(machine_config &config) |
