summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author angelosa <salese_corp_ltd@email.it>2017-09-17 02:57:10 +0200
committer angelosa <salese_corp_ltd@email.it>2017-09-17 02:57:10 +0200
commita0b2a6f719cccb3c246901b8b730d9b8d86b63e9 (patch)
tree4038e7ac63bd27ffe643049ef38ea4dd2894cad6
parentbd4ce51a1c08590836c60c457a9550a24c337dde (diff)
ymf271.cpp: added slot end status bits, fixes at least missing shots samples for Desert War [Angelo Salese]
-rw-r--r--src/devices/sound/ymf271.cpp31
-rw-r--r--src/devices/sound/ymf271.h4
2 files changed, 31 insertions, 4 deletions
diff --git a/src/devices/sound/ymf271.cpp b/src/devices/sound/ymf271.cpp
index f36cfd83972..c559eef11bc 100644
--- a/src/devices/sound/ymf271.cpp
+++ b/src/devices/sound/ymf271.cpp
@@ -11,7 +11,7 @@
- A/L bit (alternate loop)
- EN and EXT Out bits
- Src B and Src NOTE bits
- - statusreg Busy and End bits
+ - statusreg Busy flag
- timer register 0x11
- ch2/ch3 (4 speakers)
- PFM (FM using external PCM waveform)
@@ -245,6 +245,28 @@ inline bool ymf271_device::check_envelope_end(YMF271Slot *slot)
return false;
}
+// calculate status end disable/enable (Desert War shots relies on this)
+inline void ymf271_device::calculate_status_end(int slotnum, bool state)
+{
+ // guess: don't enable/disable if slot isn't a multiple of 4
+ if(slotnum & 3)
+ return;
+
+ /*
+ bit scheme is kinda twisted
+ status1 Busy End36 End24 End12 End0 ---- TimB TimA
+ status2 End44 End32 End20 End8 End40 End28 End16 End4
+ */
+ uint8_t subbit = slotnum / 12;
+ uint8_t bankbit = ((slotnum % 12) >> 2);
+
+ if(state == false)
+ m_end_status &= ~(1 << (subbit+bankbit*4));
+ else
+ m_end_status |= (1 << (subbit+bankbit*4));
+
+}
+
void ymf271_device::update_envelope(YMF271Slot *slot)
{
switch (slot->env_state)
@@ -450,6 +472,7 @@ void ymf271_device::update_pcm(int slotnum, int32_t *mixp, int length)
if ((slot->stepptr>>16) > slot->endaddr)
{
slot->stepptr = slot->stepptr - ((uint64_t)slot->endaddr<<16) + ((uint64_t)slot->loopaddr<<16);
+ calculate_status_end(slotnum,true);
if ((slot->stepptr>>16) > slot->endaddr)
{
// overflow
@@ -1003,6 +1026,7 @@ void ymf271_device::write_register(int slotnum, int reg, uint8_t data)
slot->active = 1;
calculate_step(slot);
+ calculate_status_end(slotnum,false);
init_envelope(slot);
init_lfo(slot);
slot->feedback_modulation0 = 0;
@@ -1476,11 +1500,11 @@ READ8_MEMBER( ymf271_device::read )
switch (offset & 0xf)
{
case 0x0:
- return m_status;
+ return m_status | ((m_end_status & 0xf) << 3);
case 0x1:
// statusreg 2
- return 0;
+ return m_end_status >> 4;
case 0x2:
{
@@ -1692,6 +1716,7 @@ void ymf271_device::init_state()
save_item(NAME(m_timerB));
save_item(NAME(m_irqstate));
save_item(NAME(m_status));
+ save_item(NAME(m_end_status));
save_item(NAME(m_enable));
save_item(NAME(m_ext_address));
save_item(NAME(m_ext_rw));
diff --git a/src/devices/sound/ymf271.h b/src/devices/sound/ymf271.h
index b9302f8f082..fada2fce874 100644
--- a/src/devices/sound/ymf271.h
+++ b/src/devices/sound/ymf271.h
@@ -119,7 +119,8 @@ private:
inline int get_internal_keycode(int block, int fns);
inline int get_external_keycode(int block, int fns);
inline bool check_envelope_end(YMF271Slot *slot);
-
+ inline void calculate_status_end(int slotnum, bool state);
+
// lookup tables
std::unique_ptr<int16_t[]> m_lut_waves[8];
std::unique_ptr<double[]> m_lut_plfo[4][8];
@@ -141,6 +142,7 @@ private:
uint32_t m_timerB;
uint8_t m_irqstate;
uint8_t m_status;
+ uint16_t m_end_status;
uint8_t m_enable;
uint32_t m_ext_address;