Permalink
Browse files

taito_en: Hook up ES5510 effects DSP [cam900, R. Belmont]

  • Loading branch information...
rb6502 committed Feb 17, 2018
1 parent 3f160f7 commit 4aa6f2a3429868945510181c1415885d97852ca8
View
@@ -6,7 +6,7 @@
TODO:
* Implement ES5510 ESP
* ES5510 ESP emulation is not perfect, Verify ES5505 Output Channels
* Where does the MB8421 go? Taito F3 (and Super Chase) have 2 of them on
the sound area, Taito JC has one.
@@ -15,6 +15,7 @@
#include "emu.h"
#include "taito_en.h"
#include "speaker.h"
#include <algorithm>
DEFINE_DEVICE_TYPE(TAITO_EN, taito_en_device, "taito_en", "Taito Ensoniq Sound System")
@@ -23,13 +24,13 @@ taito_en_device::taito_en_device(const machine_config &mconfig, const char *tag,
: device_t(mconfig, TAITO_EN, tag, owner, clock),
m_audiocpu(*this, "audiocpu"),
m_ensoniq(*this, "ensoniq"),
m_esp(*this, "esp"),
m_pump(*this, "pump"),
m_duart68681(*this, "duart68681"),
m_mb87078(*this, "mb87078"),
m_es5510_dol_latch(0),
m_es5510_dil_latch(0),
m_es5510_dadr_latch(0),
m_es5510_gpr_latch(0),
m_es5510_ram_sel(0)
m_osram(*this, "osram"),
m_osrom(*this, "audiocpu"),
m_cpubank(*this, "cpubank%u", 1)
{
}
@@ -39,36 +40,27 @@ taito_en_device::taito_en_device(const machine_config &mconfig, const char *tag,
void taito_en_device::device_start()
{
// TODO: 16Mx32? Not likely!
m_es5510_dram = std::make_unique<uint32_t[]>(1<<24);
save_pointer(NAME(m_es5510_dram.get()), 1<<24);
save_item(NAME(m_es5510_dsp_ram));
save_item(NAME(m_es5510_gpr));
save_item(NAME(m_es5510_dol_latch));
save_item(NAME(m_es5510_dil_latch));
save_item(NAME(m_es5510_dadr_latch));
save_item(NAME(m_es5510_gpr_latch));
save_item(NAME(m_es5510_ram_sel));
m_pump->set_otis(m_ensoniq);
m_pump->set_esp(m_esp);
uint8_t *ROM = m_osrom->base();
uint32_t max = (m_osrom->bytes() - 0x100000) / 0x20000;
for (int i = 0; i < 3; i++)
m_cpubank[i]->configure_entries(0, max, &ROM[0x100000], 0x20000);
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void taito_en_device::device_reset()
{
/* Sound cpu program loads to 0xc00000 so we use a bank */
uint16_t *ROM = (uint16_t *)memregion("audiocpu")->base();
uint16_t *sound_ram = (uint16_t *)memshare("share1")->ptr();
membank("bank1")->set_base(&ROM[0x80000]);
membank("bank2")->set_base(&ROM[0x90000]);
membank("bank3")->set_base(&ROM[0xa0000]);
sound_ram[0] = ROM[0x80000]; /* Stack and Reset vectors */
sound_ram[1] = ROM[0x80001];
sound_ram[2] = ROM[0x80002];
sound_ram[3] = ROM[0x80003];
for (int i = 0; i < 3; i++)
m_cpubank[i]->set_entry(i);
uint16_t *ROM = (uint16_t *)m_osrom->base();
std::copy(&ROM[0x80000], &ROM[0x80004], &m_osram[0]); /* Stack and Reset vectors */
/* reset CPU to catch any banking of startup vectors */
m_audiocpu->reset();
@@ -97,118 +89,24 @@ WRITE8_MEMBER( taito_en_device::en_volume_w )
}
/*************************************
*
* ES5510
*
*************************************/
//todo: hook up cpu/es5510
READ16_MEMBER( taito_en_device::es5510_dsp_r )
{
switch (offset)
{
case 0x09: return (m_es5510_dil_latch >> 16) & 0xff;
case 0x0a: return (m_es5510_dil_latch >> 8) & 0xff;
case 0x0b: return (m_es5510_dil_latch >> 0) & 0xff; // TODO: docs says that this always returns 0
default: break;
}
if (offset==0x12) return 0;
// if (offset>4)
if (offset==0x16) return 0x27;
return m_es5510_dsp_ram[offset];
}
WRITE16_MEMBER( taito_en_device::es5510_dsp_w )
{
uint8_t *snd_mem = (uint8_t *)memregion(":ensoniq.0")->base();
// if (offset>4 && offset!=0x80 && offset!=0xa0 && offset!=0xc0 && offset!=0xe0)
// logerror("%06x: DSP write offset %04x %04x\n",m_audiocpu->pc(),offset,data);
COMBINE_DATA(&m_es5510_dsp_ram[offset]);
switch (offset) {
case 0x00: m_es5510_gpr_latch=(m_es5510_gpr_latch&0x00ffff)|((data&0xff)<<16); break;
case 0x01: m_es5510_gpr_latch=(m_es5510_gpr_latch&0xff00ff)|((data&0xff)<< 8); break;
case 0x02: m_es5510_gpr_latch=(m_es5510_gpr_latch&0xffff00)|((data&0xff)<< 0); break;
/* 0x03 to 0x08 INSTR Register */
/* 0x09 to 0x0b DIL Register (r/o) */
case 0x0c: m_es5510_dol_latch=(m_es5510_dol_latch&0x00ffff)|((data&0xff)<<16); break;
case 0x0d: m_es5510_dol_latch=(m_es5510_dol_latch&0xff00ff)|((data&0xff)<< 8); break;
case 0x0e: m_es5510_dol_latch=(m_es5510_dol_latch&0xffff00)|((data&0xff)<< 0); break; //TODO: docs says that this always returns 0xff
case 0x0f:
m_es5510_dadr_latch=(m_es5510_dadr_latch&0x00ffff)|((data&0xff)<<16);
if(m_es5510_ram_sel)
m_es5510_dil_latch = m_es5510_dram[m_es5510_dadr_latch];
else
m_es5510_dram[m_es5510_dadr_latch] = m_es5510_dol_latch;
break;
case 0x10: m_es5510_dadr_latch=(m_es5510_dadr_latch&0xff00ff)|((data&0xff)<< 8); break;
case 0x11: m_es5510_dadr_latch=(m_es5510_dadr_latch&0xffff00)|((data&0xff)<< 0); break;
/* 0x12 Host Control */
case 0x14: m_es5510_ram_sel = data & 0x80; /* bit 6 is i/o select, everything else is undefined */break;
/* 0x16 Program Counter (test purpose, r/o?) */
/* 0x17 Internal Refresh counter (test purpose) */
/* 0x18 Host Serial Control */
/* 0x1f Halt enable (w) / Frame Counter (r) */
case 0x80: /* Read select - GPR + INSTR */
// logerror("ES5510: Read GPR/INSTR %06x (%06x)\n",data,m_es5510_gpr[data]);
/* Check if a GPR is selected */
if (data<0xc0) {
//es_tmp=0;
m_es5510_gpr_latch=m_es5510_gpr[data];
}// else es_tmp=1;
break;
case 0xa0: /* Write select - GPR */
// logerror("ES5510: Write GPR %06x %06x (0x%04x:=0x%06x\n",data,m_es5510_gpr_latch,data,snd_mem[m_es5510_gpr_latch>>8]);
if (data<0xc0)
m_es5510_gpr[data]=snd_mem[m_es5510_gpr_latch>>8];
break;
case 0xc0: /* Write select - INSTR */
// logerror("ES5510: Write INSTR %06x %06x\n",data,m_es5510_gpr_latch);
break;
case 0xe0: /* Write select - GPR + INSTR */
// logerror("ES5510: Write GPR/INSTR %06x %06x\n",data,m_es5510_gpr_latch);
break;
}
}
/*************************************
*
* 68000 memory map
*
*************************************/
ADDRESS_MAP_START(taito_en_device::en_sound_map)
AM_RANGE(0x000000, 0x00ffff) AM_RAM AM_MIRROR(0x30000) AM_SHARE("share1")
AM_RANGE(0x000000, 0x00ffff) AM_RAM AM_MIRROR(0x30000) AM_SHARE("osram")
AM_RANGE(0x140000, 0x140fff) AM_DEVREADWRITE8("dpram", mb8421_device, right_r, right_w, 0xff00)
AM_RANGE(0x200000, 0x20001f) AM_DEVREADWRITE("ensoniq", es5505_device, read, write)
AM_RANGE(0x260000, 0x2601ff) AM_READWRITE(es5510_dsp_r, es5510_dsp_w) //todo: hook up cpu/es5510
AM_RANGE(0x260000, 0x2601ff) AM_DEVREADWRITE8("esp", es5510_device, host_r, host_w, 0x00ff)
AM_RANGE(0x280000, 0x28001f) AM_DEVREADWRITE8("duart68681", mc68681_device, read, write, 0x00ff)
AM_RANGE(0x300000, 0x30003f) AM_WRITE(en_es5505_bank_w)
AM_RANGE(0x340000, 0x340003) AM_WRITE8(en_volume_w, 0xff00)
AM_RANGE(0xc00000, 0xc1ffff) AM_ROMBANK("bank1")
AM_RANGE(0xc20000, 0xc3ffff) AM_ROMBANK("bank2")
AM_RANGE(0xc40000, 0xc7ffff) AM_ROMBANK("bank3")
AM_RANGE(0xff0000, 0xffffff) AM_RAM AM_SHARE("share1") // mirror
AM_RANGE(0xc00000, 0xc1ffff) AM_ROMBANK("cpubank1")
AM_RANGE(0xc20000, 0xc3ffff) AM_ROMBANK("cpubank2")
AM_RANGE(0xc40000, 0xc7ffff) AM_ROMBANK("cpubank3")
AM_RANGE(0xff0000, 0xffffff) AM_RAM AM_SHARE("osram") // mirror
ADDRESS_MAP_END
@@ -222,7 +120,12 @@ WRITE8_MEMBER(taito_en_device::mb87078_gain_changed)
{
if (offset > 1)
{
// TODO : ES5505 Volume control is correct?
m_ensoniq->set_output_gain(offset & 1, data / 100.0);
m_ensoniq->set_output_gain(2|(offset & 1), data / 100.0);
m_ensoniq->set_output_gain(4|(offset & 1), data / 100.0);
m_ensoniq->set_output_gain(6|(offset & 1), data / 100.0);
m_pump->set_output_gain(offset & 1, data / 100.0);
}
}
@@ -265,6 +168,25 @@ WRITE_LINE_MEMBER(taito_en_device::duart_irq_handler)
IP5: 1MHz
*/
WRITE8_MEMBER(taito_en_device::duart_output)
{
if (data & 0x40)
{
if (!m_pump->get_esp_halted())
{
logerror("Asserting ESPHALT\n");
m_pump->set_esp_halted(true);
}
}
else
{
if (m_pump->get_esp_halted())
{
logerror("Clearing ESPHALT\n");
m_pump->set_esp_halted(false);
}
}
}
//-------------------------------------------------
// device_add_mconfig - add device configuration
@@ -276,21 +198,35 @@ MACHINE_CONFIG_START(taito_en_device::device_add_mconfig)
MCFG_CPU_ADD("audiocpu", M68000, XTAL(30'476'100) / 2)
MCFG_CPU_PROGRAM_MAP(en_sound_map)
MCFG_CPU_ADD("esp", ES5510, XTAL(10'000'000)) // ES5510 Clock is unverified
MCFG_DEVICE_DISABLE()
MCFG_DEVICE_ADD("duart68681", MC68681, XTAL(16'000'000) / 4)
MCFG_MC68681_SET_EXTERNAL_CLOCKS(XTAL(16'000'000)/2/8, XTAL(16'000'000)/2/16, XTAL(16'000'000)/2/16, XTAL(16'000'000)/2/8)
MCFG_MC68681_IRQ_CALLBACK(WRITELINE(taito_en_device, duart_irq_handler))
MCFG_MC68681_OUTPORT_CALLBACK(WRITE8(taito_en_device, duart_output))
MCFG_DEVICE_ADD("mb87078", MB87078, 0)
MCFG_MB87078_GAIN_CHANGED_CB(WRITE8(taito_en_device, mb87078_gain_changed))
MCFG_DEVICE_ADD("dpram", MB8421, 0) // host accesses this from the other side
/* sound hardware */
MCFG_SOUND_ADD("pump", ESQ_5505_5510_PUMP, XTAL(30'476'100) / (2 * 16 * 32))
MCFG_SOUND_ROUTE(0, "lspeaker", 1.0)
MCFG_SOUND_ROUTE(1, "rspeaker", 1.0)
MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
MCFG_SOUND_ADD("ensoniq", ES5505, XTAL(30'476'100) / 2)
MCFG_ES5505_REGION0("ensoniq.0")
MCFG_ES5505_REGION1("ensoniq.0")
MCFG_ES5506_CHANNELS(1)
MCFG_SOUND_ROUTE(0, "lspeaker", 0.08)
MCFG_SOUND_ROUTE(1, "rspeaker", 0.08)
MCFG_ES5506_CHANNELS(4) // TODO : Verify output channels
MCFG_SOUND_ROUTE_EX(0, "pump", 1.0, 0)
MCFG_SOUND_ROUTE_EX(1, "pump", 1.0, 1)
MCFG_SOUND_ROUTE_EX(2, "pump", 1.0, 2)
MCFG_SOUND_ROUTE_EX(3, "pump", 1.0, 3)
MCFG_SOUND_ROUTE_EX(4, "pump", 1.0, 4)
MCFG_SOUND_ROUTE_EX(5, "pump", 1.0, 5)
MCFG_SOUND_ROUTE_EX(6, "pump", 1.0, 6)
MCFG_SOUND_ROUTE_EX(7, "pump", 1.0, 7)
MACHINE_CONFIG_END
View
@@ -10,8 +10,10 @@
#pragma once
#include "cpu/es5510/es5510.h"
#include "cpu/m68000/m68000.h"
#include "sound/es5506.h"
#include "sound/esqpump.h"
#include "machine/mc68681.h"
#include "machine/mb87078.h"
#include "machine/mb8421.h"
@@ -20,14 +22,14 @@ class taito_en_device : public device_t
{
public:
static constexpr feature_type imperfect_features() { return feature::SOUND; }
taito_en_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
DECLARE_WRITE16_MEMBER( en_es5505_bank_w );
DECLARE_WRITE8_MEMBER( en_volume_w );
//todo: hook up cpu/es5510
DECLARE_READ16_MEMBER( es5510_dsp_r );
DECLARE_WRITE16_MEMBER( es5510_dsp_w );
void set_bank(int bank, int entry) { m_cpubank[bank]->set_entry(entry); }
void en_sound_map(address_map &map);
protected:
@@ -40,20 +42,18 @@ class taito_en_device : public device_t
// inherited devices/pointers
required_device<cpu_device> m_audiocpu;
required_device<es5505_device> m_ensoniq;
required_device<es5510_device> m_esp;
required_device<esq_5505_5510_pump_device> m_pump;
required_device<mc68681_device> m_duart68681;
required_device<mb87078_device> m_mb87078;
//todo: hook up cpu/es5510
std::unique_ptr<uint32_t[]> m_es5510_dram;
uint16_t m_es5510_dsp_ram[0x200];
uint32_t m_es5510_gpr[0xc0];
uint32_t m_es5510_dol_latch;
uint32_t m_es5510_dil_latch;
uint32_t m_es5510_dadr_latch;
uint32_t m_es5510_gpr_latch;
uint8_t m_es5510_ram_sel;
required_shared_ptr<uint16_t> m_osram;
required_memory_region m_osrom;
required_memory_bank_array<3> m_cpubank;
DECLARE_WRITE_LINE_MEMBER(duart_irq_handler);
DECLARE_WRITE8_MEMBER(duart_output);
DECLARE_WRITE8_MEMBER(mb87078_gain_changed);
};
@@ -9,7 +9,7 @@
Board Info:
CPU : 68EC020 68000
SOUND : Ensoniq
SOUND : Ensoniq ES5505 + ES5510
OSC. : 40.000MHz 16.000MHz 30.47618MHz
* This board (K11J0717A) uses following chips:
@@ -34,7 +34,6 @@
#include "emu.h"
#include "includes/taito_f3.h"
#include "audio/taito_en.h"
#include "cpu/m68000/m68000.h"
#include "machine/eepromser.h"
@@ -121,8 +120,7 @@ WRITE32_MEMBER(taito_f3_state::f3_sound_reset_1_w)
WRITE32_MEMBER(taito_f3_state::f3_sound_bankswitch_w)
{
if (m_f3_game==KIRAMEKI) {
uint16_t *rom = (uint16_t *)memregion("taito_en:audiocpu")->base();
uint32_t idx;
int idx;
idx = (offset << 1) & 0x1e;
if (ACCESSING_BITS_0_15)
@@ -133,7 +131,7 @@ WRITE32_MEMBER(taito_f3_state::f3_sound_bankswitch_w)
/* Banks are 0x20000 bytes each, divide by two to get data16
pointer rather than byte pointer */
membank("taito_en:bank2")->set_base(&rom[(idx*0x20000)/2 + 0x80000]);
m_taito_en->set_bank(1,idx);
} else {
logerror("Sound bankswitch in unsupported game\n");
@@ -558,7 +558,7 @@ READ8_MEMBER(taitojc_state::mcu_comm_r)
return m_mcu_data_main;
case 0x04:
return m_mcu_comm_main | 0x14;
return m_mcu_comm_main;
default:
logerror("mcu_comm_r: %02X at %08X\n", offset, m_maincpu->pc());
Oops, something went wrong.

3 comments on commit 4aa6f2a

@MASHinfo

This comment has been minimized.

Show comment
Hide comment
@MASHinfo

MASHinfo Feb 17, 2018

Contributor

For the ARCADE build
SOUNDS["ESQPUMP"] = true
must be enabled in scripts\target\mame\arcade.lua

Contributor

MASHinfo replied Feb 17, 2018

For the ARCADE build
SOUNDS["ESQPUMP"] = true
must be enabled in scripts\target\mame\arcade.lua

@Tafoid

This comment has been minimized.

Show comment
Hide comment
@Tafoid

Tafoid Feb 18, 2018

Contributor

Today's testing came across this..

Fatal error: memory_bank::set_entry called with out-of-range entry 2

All sets in gunbustr.cpp
Many sets in taito_f3.cpp
arabianm, arabianmj, arabianmu, cleopatr, commandw, cupfinal, dungeonm, dungeonmu, gseeker, gseekerj, gseekeru, hthero93, hthero93u, ktiger2, landmakr, lightbr, lightbrj, prmtmfgt, prmtmfgto, quizhuhu, recalh, ridingf, ridingfj, ridingfu, ringrage, ringragej, ringrageu, scfinals, scfinals0, spcinvdj, tcobra2, tcobra2u, trstarj, trstaro, trstaroj
All sets in undrfire.cpp

Contributor

Tafoid replied Feb 18, 2018

Today's testing came across this..

Fatal error: memory_bank::set_entry called with out-of-range entry 2

All sets in gunbustr.cpp
Many sets in taito_f3.cpp
arabianm, arabianmj, arabianmu, cleopatr, commandw, cupfinal, dungeonm, dungeonmu, gseeker, gseekerj, gseekeru, hthero93, hthero93u, ktiger2, landmakr, lightbr, lightbrj, prmtmfgt, prmtmfgto, quizhuhu, recalh, ridingf, ridingfj, ridingfu, ringrage, ringragej, ringrageu, scfinals, scfinals0, spcinvdj, tcobra2, tcobra2u, trstarj, trstaro, trstaroj
All sets in undrfire.cpp

@Tafoid

This comment has been minimized.

Show comment
Hide comment
@Tafoid

Tafoid Feb 19, 2018

Contributor

All sets in superchs.cpp as well suffer from this same Fatal Error.

Contributor

Tafoid replied Feb 19, 2018

All sets in superchs.cpp as well suffer from this same Fatal Error.

Please sign in to comment.