summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/audio/xavix.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/audio/xavix.cpp')
-rw-r--r--src/mame/audio/xavix.cpp66
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();
+}