diff options
Diffstat (limited to 'src/mame/audio/xavix.cpp')
-rw-r--r-- | src/mame/audio/xavix.cpp | 66 |
1 files changed, 57 insertions, 9 deletions
diff --git a/src/mame/audio/xavix.cpp b/src/mame/audio/xavix.cpp index ff7f0d5b596..2dd8ecae8d8 100644 --- a/src/mame/audio/xavix.cpp +++ b/src/mame/audio/xavix.cpp @@ -435,7 +435,7 @@ READ8_MEMBER(xavix_state::sound_timer3_r) return m_sndtimer[3]; } -WRITE8_MEMBER(xavix_state::sound_timer3_w) +WRITE8_MEMBER(xavix_state::sound_timer3_w) // this one is used by ekara (uk carts) , enabled with 08 in 75fe { m_sndtimer[3] = data; LOG("%s: sound_timer3_w %02x\n", machine().describe_context(), data); @@ -446,23 +446,56 @@ WRITE8_MEMBER(xavix_state::sound_timer3_w) READ8_MEMBER(xavix_state::sound_irqstatus_r) { // rad_rh checks this after doing something that looks like an irq ack - // rad_bass does the same, but returning the wrong status bits causes it to corrupt memory and crash in certain situations, see code around 0037D5 - if (m_sound_irqstatus & 0x08) // hack for rad_rh - return 0xf0 | m_sound_irqstatus; - - return m_sound_irqstatus; // otherwise, keep rad_bass happy + // the UK ekara sets check the upper bit to see if the interrupt is from the sound timer (rather than checking interrupt source register) + // and decrease a counter that controls the tempo (the US / Japan sets don't enable the sound timer at all) + return m_sound_irqstatus; } WRITE8_MEMBER(xavix_state::sound_irqstatus_w) { // these look like irq ack bits, 4 sources? // related to sound_timer0_w , sound_timer1_w, sound_timer2_w, sound_timer3_w ? - if (data & 0xf0) + + for (int t = 0; t < 4; t++) { - m_sound_irqstatus &= ~data & 0xf0; + int bit = (1 << t) << 4; + + if (data & bit) + { + m_sound_irqstatus &= ~data & bit; + } + } + + // check if all interrupts have been cleared to see if the line should be lowered + if (m_sound_irqstatus & 0xf0) + m_irqsource |= 0x80; + else + m_irqsource &= ~0x80; + + update_irqs(); + + + for (int t = 0; t < 4; t++) + { + int bit = 1 << t; + + if ((m_sound_irqstatus & bit) != (data & bit)) + { + if (data & bit) + { + // period should be based on m_sndtimer[t] at least, maybe also some other regs? + m_sound_timer[t]->adjust(attotime::from_usec(1000), t, attotime::from_usec(1000)); + } + else + { + m_sound_timer[t]->adjust(attotime::never, t); + } + } } - m_sound_irqstatus = data & 0x0f; // look like IRQ enable flags - 4 sources? voices? timers? + // see if we're enabling any timers (should probably check if they're already running so we don't end up restarting them) + m_sound_irqstatus |= data & 0x0f; // look like IRQ enable flags - 4 sources? voices? timers? + LOG("%s: sound_irqstatus_w %02x\n", machine().describe_context(), data); } @@ -475,3 +508,18 @@ WRITE8_MEMBER(xavix_state::sound_75ff_w) LOG("%s: sound_75ff_w %02x\n", machine().describe_context(), data); } +// used by ekara (UK cartridges), rad_bass, rad_crdn +TIMER_CALLBACK_MEMBER(xavix_state::sound_timer_done) +{ + // param = timer number 0,1,2 or 3 + int bit = (1 << param) << 4; + m_sound_irqstatus |= bit; + + // if any of the sound timers are causing an interrupt... + if (m_sound_irqstatus & 0xf0) + m_irqsource |= 0x80; + else + m_irqsource &= ~0x80; + + update_irqs(); +} |