diff options
Diffstat (limited to 'src/mame/audio/redalert.cpp')
-rw-r--r-- | src/mame/audio/redalert.cpp | 206 |
1 files changed, 121 insertions, 85 deletions
diff --git a/src/mame/audio/redalert.cpp b/src/mame/audio/redalert.cpp index a104dc3e6e7..d1e2e9c7b70 100644 --- a/src/mame/audio/redalert.cpp +++ b/src/mame/audio/redalert.cpp @@ -10,11 +10,13 @@ ****************************************************************************/ #include "emu.h" -#include "includes/redalert.h" +#include "redalert.h" #include "cpu/m6800/m6800.h" #include "cpu/m6502/m6502.h" #include "machine/rescap.h" +#include "sound/hc55516.h" + #include "speaker.h" @@ -34,23 +36,73 @@ #define DEMONEYE_AY8910_CLOCK (DEMONEYE_AUDIO_PCB_CLOCK / 2) /* what's the real divisor? */ -TIMER_CALLBACK_MEMBER(redalert_state::audio_irq_on) +DEFINE_DEVICE_TYPE(IREM_M37B_AUDIO, irem_m37b_audio_device, "irem_m37b_audio", "Irem M37B audio") +DEFINE_DEVICE_TYPE(PANTHER_AUDIO, panther_audio_device, "panther_audio", "Irem M37B audio (Panther)") +DEFINE_DEVICE_TYPE(IREM_M37B_UE17B_AUDIO, irem_m37b_ue17b_audio_device, "irem_m37b_ue17b_audio", "Irem M37B/UE17B audio/voice") +DEFINE_DEVICE_TYPE(DEMONEYE_AUDIO, demoneye_audio_device, "demoneye_audio", "Irem Demoneye-X audio") + + +irem_m37b_audio_device::irem_m37b_audio_device(const machine_config &config, const char *tag, device_t *owner, uint32_t clock) : + irem_m37b_audio_device(config, IREM_M37B_AUDIO, tag, owner, clock) +{ +} + +irem_m37b_audio_device::irem_m37b_audio_device(const machine_config &config, device_type type, const char *tag, device_t *owner, uint32_t clock) : + device_t(config, type, tag, owner, clock), + m_audiocpu(*this, "audiocpu"), + m_ay8910(*this, "aysnd"), + m_soundlatch(*this, "soundlatch") +{ +} + + +panther_audio_device::panther_audio_device(const machine_config &config, const char *tag, device_t *owner, uint32_t clock) : + irem_m37b_audio_device(config, PANTHER_AUDIO, tag, owner, clock) { - if (m_sndpia.found()) - m_sndpia->cb1_w(0); // guess - else - m_audiocpu->set_input_line(m6502_device::IRQ_LINE, ASSERT_LINE); +} + + +irem_m37b_ue17b_audio_device::irem_m37b_ue17b_audio_device(const machine_config &config, const char *tag, device_t *owner, uint32_t clock) : + irem_m37b_audio_device(config, IREM_M37B_UE17B_AUDIO, tag, owner, clock), + m_voicecpu(*this, "voice"), + m_soundlatch2(*this, "soundlatch2") +{ +} + + +demoneye_audio_device::demoneye_audio_device(const machine_config &config, const char *tag, device_t *owner, uint32_t clock) : + device_t(config, DEMONEYE_AUDIO, tag, owner, clock), + m_audiocpu(*this, "audiocpu"), + m_ay(*this, "ay%u", 1U), + m_sndpia(*this, "sndpia"), + m_soundlatch(*this, "soundlatch") +{ +} + + +TIMER_CALLBACK_MEMBER(irem_m37b_audio_device::audio_irq_on) +{ + m_audiocpu->set_input_line(m6502_device::IRQ_LINE, ASSERT_LINE); m_audio_irq_off_timer->adjust(REDALERT_AUDIO_CPU_IRQ_TIME); } +TIMER_CALLBACK_MEMBER(irem_m37b_audio_device::audio_irq_off) +{ + m_audiocpu->set_input_line(m6502_device::IRQ_LINE, CLEAR_LINE); +} + -TIMER_CALLBACK_MEMBER(redalert_state::audio_irq_off) +TIMER_CALLBACK_MEMBER(demoneye_audio_device::audio_irq_on) { - if (m_sndpia.found()) - m_sndpia->cb1_w(1); // guess - else - m_audiocpu->set_input_line(m6502_device::IRQ_LINE, CLEAR_LINE); + m_sndpia->cb1_w(0); // guess + + m_audio_irq_off_timer->adjust(REDALERT_AUDIO_CPU_IRQ_TIME); +} + +TIMER_CALLBACK_MEMBER(demoneye_audio_device::audio_irq_off) +{ + m_sndpia->cb1_w(1); // guess } @@ -60,7 +112,7 @@ TIMER_CALLBACK_MEMBER(redalert_state::audio_irq_off) * *************************************/ -void redalert_state::redalert_analog_w(uint8_t data) +void irem_m37b_audio_device::analog_w(uint8_t data) { /* this port triggers analog sounds D0 = Formation Aircraft? @@ -82,7 +134,14 @@ void redalert_state::redalert_analog_w(uint8_t data) * *************************************/ -void redalert_state::redalert_audio_command_w(uint8_t data) +CUSTOM_INPUT_MEMBER(irem_m37b_audio_device::sound_status_r) +{ + // communication handshake between host and sound CPU + // at least Panther uses it, unconfirmed for Red Alert and Demoneye-X + return m_sound_hs; +} + +void irem_m37b_audio_device::audio_command_w(uint8_t data) { /* the byte is connected to port A of the AY8910 */ m_soundlatch->write(data); @@ -95,7 +154,7 @@ void redalert_state::redalert_audio_command_w(uint8_t data) } -void redalert_state::redalert_AY8910_w(uint8_t data) +void irem_m37b_audio_device::ay8910_w(uint8_t data) { /* BC2 is connected to a pull-up resistor, so BC2=1 always */ switch (data & 0x03) @@ -121,34 +180,35 @@ void redalert_state::redalert_AY8910_w(uint8_t data) } -uint8_t redalert_state::redalert_ay8910_latch_1_r() +uint8_t irem_m37b_audio_device::ay8910_latch_1_r() { return m_ay8910_latch_1; } -void redalert_state::redalert_ay8910_latch_2_w(uint8_t data) +void irem_m37b_audio_device::ay8910_latch_2_w(uint8_t data) { m_ay8910_latch_2 = data; } -void redalert_state::redalert_audio_map(address_map &map) +void irem_m37b_audio_device::redalert_audio_map(address_map &map) { map.global_mask(0x7fff); map(0x0000, 0x03ff).mirror(0x0c00).ram(); - map(0x1000, 0x1000).mirror(0x0ffe).nopr().w(FUNC(redalert_state::redalert_AY8910_w)); - map(0x1001, 0x1001).mirror(0x0ffe).rw(FUNC(redalert_state::redalert_ay8910_latch_1_r), FUNC(redalert_state::redalert_ay8910_latch_2_w)); + map(0x1000, 0x1000).mirror(0x0ffe).nopr().w(FUNC(irem_m37b_audio_device::ay8910_w)); + map(0x1001, 0x1001).mirror(0x0ffe).rw(FUNC(irem_m37b_audio_device::ay8910_latch_1_r), FUNC(irem_m37b_audio_device::ay8910_latch_2_w)); map(0x2000, 0x6fff).noprw(); map(0x7000, 0x77ff).mirror(0x0800).rom(); } -void redalert_state::panther_audio_map(address_map &map) +void panther_audio_device::panther_audio_map(address_map &map) { redalert_audio_map(map); + // Panther maps these two to $2000 while Red Alert to $1000, different PAL addressing? map(0x1000, 0x1fff).unmaprw(); - map(0x2000, 0x2000).mirror(0x0ffe).nopr().w(FUNC(redalert_state::redalert_AY8910_w)); - map(0x2001, 0x2001).mirror(0x0ffe).rw(FUNC(redalert_state::redalert_ay8910_latch_1_r), FUNC(redalert_state::redalert_ay8910_latch_2_w)); + map(0x2000, 0x2000).mirror(0x0ffe).nopr().w(FUNC(panther_audio_device::ay8910_w)); + map(0x2001, 0x2001).mirror(0x0ffe).rw(FUNC(panther_audio_device::ay8910_latch_1_r), FUNC(panther_audio_device::ay8910_latch_2_w)); } /************************************* @@ -157,10 +217,10 @@ void redalert_state::panther_audio_map(address_map &map) * *************************************/ -void redalert_state::sound_start() +void irem_m37b_audio_device::device_start() { - m_audio_irq_on_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(redalert_state::audio_irq_on), this)); - m_audio_irq_off_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(redalert_state::audio_irq_off), this)); + m_audio_irq_on_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(irem_m37b_audio_device::audio_irq_on), this)); + m_audio_irq_off_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(irem_m37b_audio_device::audio_irq_off), this)); m_audio_irq_on_timer->adjust(REDALERT_AUDIO_CPU_IRQ_FREQ, 0, REDALERT_AUDIO_CPU_IRQ_FREQ); @@ -176,26 +236,14 @@ void redalert_state::sound_start() * *************************************/ -void redalert_state::redalert_voice_command_w(uint8_t data) +void irem_m37b_ue17b_audio_device::voice_command_w(uint8_t data) { m_soundlatch2->write((data & 0x78) >> 3); m_voicecpu->set_input_line(I8085_RST75_LINE, (~data & 0x80) ? ASSERT_LINE : CLEAR_LINE); } -WRITE_LINE_MEMBER(redalert_state::sod_callback) -{ - m_cvsd->digit_w(state); -} - - -READ_LINE_MEMBER(redalert_state::sid_callback) -{ - return m_cvsd->clock_state_r(); -} - - -void redalert_state::redalert_voice_map(address_map &map) +void irem_m37b_ue17b_audio_device::redalert_voice_map(address_map &map) { map(0x0000, 0x3fff).rom(); map(0x4000, 0x7fff).noprw(); @@ -211,37 +259,42 @@ void redalert_state::redalert_voice_map(address_map &map) * *************************************/ -void redalert_state::redalert_audio_m37b(machine_config &config) +void irem_m37b_audio_device::device_add_mconfig(machine_config &config) { M6502(config, m_audiocpu, REDALERT_AUDIO_CPU_CLOCK); - m_audiocpu->set_addrmap(AS_PROGRAM, &redalert_state::redalert_audio_map); + m_audiocpu->set_addrmap(AS_PROGRAM, &irem_m37b_audio_device::redalert_audio_map); GENERIC_LATCH_8(config, m_soundlatch); + SPEAKER(config, "mono").front_center(); + AY8910(config, m_ay8910, REDALERT_AY8910_CLOCK); m_ay8910->port_a_read_callback().set(m_soundlatch, FUNC(generic_latch_8_device::read)); - m_ay8910->port_b_write_callback().set(FUNC(redalert_state::redalert_analog_w)); + m_ay8910->port_b_write_callback().set(FUNC(irem_m37b_audio_device::analog_w)); m_ay8910->add_route(0, "mono", 0.50); m_ay8910->add_route(1, "mono", 0.50); /* channel C is used a noise source and is not connected to a speaker */ } + /************************************* * * Red Alert voice board (ue17b) * *************************************/ -void redalert_state::redalert_audio_voice(machine_config &config) +void irem_m37b_ue17b_audio_device::device_add_mconfig(machine_config &config) { + irem_m37b_audio_device::device_add_mconfig(config); + I8085A(config, m_voicecpu, REDALERT_VOICE_CPU_CLOCK); - m_voicecpu->set_addrmap(AS_PROGRAM, &redalert_state::redalert_voice_map); - m_voicecpu->in_sid_func().set(FUNC(redalert_state::sid_callback)); - m_voicecpu->out_sod_func().set(FUNC(redalert_state::sod_callback)); + m_voicecpu->set_addrmap(AS_PROGRAM, &irem_m37b_ue17b_audio_device::redalert_voice_map); + m_voicecpu->in_sid_func().set("cvsd", FUNC(hc55516_device::clock_state_r)); + m_voicecpu->out_sod_func().set("cvsd", FUNC(hc55516_device::digit_w)); GENERIC_LATCH_8(config, m_soundlatch2); - HC55516(config, m_cvsd, REDALERT_HC55516_CLOCK).add_route(ALL_OUTPUTS, "mono", 0.50); + HC55516(config, "cvsd", REDALERT_HC55516_CLOCK).add_route(ALL_OUTPUTS, "mono", 0.50); } /************************************* @@ -250,43 +303,32 @@ void redalert_state::redalert_audio_voice(machine_config &config) * *************************************/ -void redalert_state::redalert_audio(machine_config &config) +void panther_audio_device::device_add_mconfig(machine_config &config) { - SPEAKER(config, "mono").front_center(); + irem_m37b_audio_device::device_add_mconfig(config); - redalert_audio_m37b(config); - redalert_audio_voice(config); + m_audiocpu->set_addrmap(AS_PROGRAM, &panther_audio_device::panther_audio_map); } /************************************* * - * Red Alert + * Demoneye-X audio board * *************************************/ -void redalert_state::ww3_audio(machine_config &config) +void demoneye_audio_device::device_start() { - SPEAKER(config, "mono").front_center(); - - redalert_audio_m37b(config); -} + m_audio_irq_on_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(demoneye_audio_device::audio_irq_on), this)); + m_audio_irq_off_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(demoneye_audio_device::audio_irq_off), this)); -void redalert_state::panther_audio(machine_config &config) -{ - SPEAKER(config, "mono").front_center(); + m_audio_irq_on_timer->adjust(REDALERT_AUDIO_CPU_IRQ_FREQ, 0, REDALERT_AUDIO_CPU_IRQ_FREQ); - redalert_audio_m37b(config); - m_audiocpu->set_addrmap(AS_PROGRAM, &redalert_state::panther_audio_map); + save_item(NAME(m_ay8910_latch_1)); + save_item(NAME(m_ay8910_latch_2)); } -/************************************* - * - * Demoneye-X audio board - * - *************************************/ - -void redalert_state::demoneye_audio_command_w(uint8_t data) +void demoneye_audio_device::audio_command_w(uint8_t data) { /* the byte is connected to port A of the AY8910 */ m_soundlatch->write(data); @@ -294,57 +336,51 @@ void redalert_state::demoneye_audio_command_w(uint8_t data) } -void redalert_state::demoneye_ay8910_latch_1_w(uint8_t data) +void demoneye_audio_device::ay8910_latch_1_w(uint8_t data) { m_ay8910_latch_1 = data; } -uint8_t redalert_state::demoneye_ay8910_latch_2_r() +uint8_t demoneye_audio_device::ay8910_latch_2_r() { return m_ay8910_latch_2; } -void redalert_state::demoneye_ay8910_data_w(uint8_t data) +void demoneye_audio_device::ay8910_data_w(uint8_t data) { switch (m_ay8910_latch_1 & 0x03) { case 0x00: if (m_ay8910_latch_1 & 0x10) m_ay[0]->data_w(data); - if (m_ay8910_latch_1 & 0x20) m_ay[1]->data_w(data); - break; case 0x01: if (m_ay8910_latch_1 & 0x10) m_ay8910_latch_2 = m_ay[0]->data_r(); - if (m_ay8910_latch_1 & 0x20) m_ay8910_latch_2 = m_ay[1]->data_r(); - break; case 0x03: if (m_ay8910_latch_1 & 0x10) m_ay[0]->address_w(data); - if (m_ay8910_latch_1 & 0x20) m_ay[1]->address_w(data); - break; default: - logerror("demoneye_ay8910_data_w called with latch %02X data %02X\n", m_ay8910_latch_1, data); + logerror("demoneye_audio_device::ay8910_data_w called with latch %02X data %02X\n", m_ay8910_latch_1, data); break; } } -void redalert_state::demoneye_audio_map(address_map &map) +void demoneye_audio_device::demoneye_audio_map(address_map &map) { map(0x0500, 0x0503).mirror(0xc000).rw(m_sndpia, FUNC(pia6821_device::read), FUNC(pia6821_device::write)); map(0x2000, 0x3fff).mirror(0xc000).rom(); @@ -358,15 +394,15 @@ void redalert_state::demoneye_audio_map(address_map &map) * *************************************/ -void redalert_state::demoneye_audio(machine_config &config) +void demoneye_audio_device::device_add_mconfig(machine_config &config) { M6802(config, m_audiocpu, DEMONEYE_AUDIO_CPU_CLOCK); - m_audiocpu->set_addrmap(AS_PROGRAM, &redalert_state::demoneye_audio_map); + m_audiocpu->set_addrmap(AS_PROGRAM, &demoneye_audio_device::demoneye_audio_map); PIA6821(config, m_sndpia); - m_sndpia->readpa_handler().set(FUNC(redalert_state::demoneye_ay8910_latch_2_r)); - m_sndpia->writepa_handler().set(FUNC(redalert_state::demoneye_ay8910_data_w)); - m_sndpia->writepb_handler().set(FUNC(redalert_state::demoneye_ay8910_latch_1_w)); + m_sndpia->readpa_handler().set(FUNC(demoneye_audio_device::ay8910_latch_2_r)); + m_sndpia->writepa_handler().set(FUNC(demoneye_audio_device::ay8910_data_w)); + m_sndpia->writepb_handler().set(FUNC(demoneye_audio_device::ay8910_latch_1_w)); m_sndpia->irqb_handler().set_inputline(m_audiocpu, M6802_IRQ_LINE); SPEAKER(config, "mono").front_center(); |