summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author hap <happppp@users.noreply.github.com>2016-01-18 10:53:00 +0100
committer hap <happppp@users.noreply.github.com>2016-01-18 10:53:00 +0100
commitd6d2b0d91716d653102b2a0cfcf6cbc88f3977f1 (patch)
treee1bd00f8e9612e8e9aba1d4ddb8204ec13794c7f
parent09d5082cdd5e0420526f890d9694e22c3f894409 (diff)
s14001a: added optional devcb callbacks for mem read and BSY pin
-rw-r--r--src/devices/sound/s14001a.cpp51
-rw-r--r--src/devices/sound/s14001a.h14
2 files changed, 47 insertions, 18 deletions
diff --git a/src/devices/sound/s14001a.cpp b/src/devices/sound/s14001a.cpp
index 7c12a097e04..c89ff1ed3d2 100644
--- a/src/devices/sound/s14001a.cpp
+++ b/src/devices/sound/s14001a.cpp
@@ -401,26 +401,26 @@ void s14001a_device::s14001a_clock() /* called once per clock */
}
m_audioout = (m_GlobalSilenceState || LOCALSILENCESTATE) ? SILENCE : m_DACOutput; // when either silence state is 1, output silence.
// DIGITAL OUTPUT *might* be driven onto the test pins on this cycle?
- switch(m_machineState) // HUUUUUGE switch statement
+ switch(m_machineState)
{
case 0: // idle state
m_nextstate = 0;
break;
case 1: // read starting syllable high byte from word table
m_SyllableAddress = 0; // clear syllable address
- m_SyllableAddress |= m_SpeechRom[(m_LatchedWord<<1)]<<4;
+ m_SyllableAddress |= readmem((m_LatchedWord<<1))<<4;
m_nextstate = m_resetState ? 1 : 2;
break;
case 2: // read starting syllable low byte from word table
- m_SyllableAddress |= m_SpeechRom[(m_LatchedWord<<1)+1]>>4;
+ m_SyllableAddress |= readmem((m_LatchedWord<<1)+1)>>4;
m_nextstate = 3;
break;
case 3: // read starting phone address
- m_PhoneAddress = m_SpeechRom[m_SyllableAddress]<<4;
+ m_PhoneAddress = readmem(m_SyllableAddress)<<4;
m_nextstate = 4;
break;
case 4: // read playback parameters and prepare for play
- m_PlayParams = m_SpeechRom[m_SyllableAddress+1];
+ m_PlayParams = readmem(m_SyllableAddress+1);
m_GlobalSilenceState = SILENCEFLAG; // load phone silence flag
m_LengthCounter = LENGTHCOUNT; // load length counter
m_RepeatCounter = REPEATCOUNT; // load repeat counter
@@ -431,25 +431,25 @@ void s14001a_device::s14001a_clock() /* called once per clock */
m_nextstate = 5;
break;
case 5: // Play phone forward, shift = 0 (also load)
- CurDelta = (m_SpeechRom[(m_PhoneAddress)+m_PhoneOffset]&0xc0)>>6; // grab current delta from high 2 bits of high nybble
+ CurDelta = (readmem((m_PhoneAddress)+m_PhoneOffset)&0xc0)>>6; // grab current delta from high 2 bits of high nybble
m_DACOutput += DeltaTable[CurDelta][m_OldDelta]; // send data to forward delta table and add result to accumulator
m_OldDelta = CurDelta; // Move current delta to old
m_nextstate = 6;
break;
case 6: // Play phone forward, shift = 2
- CurDelta = (m_SpeechRom[(m_PhoneAddress)+m_PhoneOffset]&0x30)>>4; // grab current delta from low 2 bits of high nybble
+ CurDelta = (readmem((m_PhoneAddress)+m_PhoneOffset)&0x30)>>4; // grab current delta from low 2 bits of high nybble
m_DACOutput += DeltaTable[CurDelta][m_OldDelta]; // send data to forward delta table and add result to accumulator
m_OldDelta = CurDelta; // Move current delta to old
m_nextstate = 7;
break;
case 7: // Play phone forward, shift = 4
- CurDelta = (m_SpeechRom[(m_PhoneAddress)+m_PhoneOffset]&0xc)>>2; // grab current delta from high 2 bits of low nybble
+ CurDelta = (readmem((m_PhoneAddress)+m_PhoneOffset)&0xc)>>2; // grab current delta from high 2 bits of low nybble
m_DACOutput += DeltaTable[CurDelta][m_OldDelta]; // send data to forward delta table and add result to accumulator
m_OldDelta = CurDelta; // Move current delta to old
m_nextstate = 8;
break;
case 8: // Play phone forward, shift = 6 (increment address if needed)
- CurDelta = m_SpeechRom[(m_PhoneAddress)+m_PhoneOffset]&0x3; // grab current delta from low 2 bits of low nybble
+ CurDelta = readmem((m_PhoneAddress)+m_PhoneOffset)&0x3; // grab current delta from low 2 bits of low nybble
m_DACOutput += DeltaTable[CurDelta][m_OldDelta]; // send data to forward delta table and add result to accumulator
m_OldDelta = CurDelta; // Move current delta to old
m_PhoneOffset++; // increment phone offset
@@ -464,7 +464,7 @@ void s14001a_device::s14001a_clock() /* called once per clock */
}
break;
case 9: // Play phone backward, shift = 6 (also load)
- CurDelta = (m_SpeechRom[(m_PhoneAddress)+m_PhoneOffset]&0x3); // grab current delta from low 2 bits of low nybble
+ CurDelta = (readmem((m_PhoneAddress)+m_PhoneOffset)&0x3); // grab current delta from low 2 bits of low nybble
if (m_laststate != 8) // ignore first (bogus) dac change in mirrored backwards mode. observations and the patent show this.
{
m_DACOutput -= DeltaTable[m_OldDelta][CurDelta]; // send data to forward delta table and subtract result from accumulator
@@ -473,19 +473,19 @@ void s14001a_device::s14001a_clock() /* called once per clock */
m_nextstate = 10;
break;
case 10: // Play phone backward, shift = 4
- CurDelta = (m_SpeechRom[(m_PhoneAddress)+m_PhoneOffset]&0xc)>>2; // grab current delta from high 2 bits of low nybble
+ CurDelta = (readmem((m_PhoneAddress)+m_PhoneOffset)&0xc)>>2; // grab current delta from high 2 bits of low nybble
m_DACOutput -= DeltaTable[m_OldDelta][CurDelta]; // send data to forward delta table and subtract result from accumulator
m_OldDelta = CurDelta; // Move current delta to old
m_nextstate = 11;
break;
case 11: // Play phone backward, shift = 2
- CurDelta = (m_SpeechRom[(m_PhoneAddress)+m_PhoneOffset]&0x30)>>4; // grab current delta from low 2 bits of high nybble
+ CurDelta = (readmem((m_PhoneAddress)+m_PhoneOffset)&0x30)>>4; // grab current delta from low 2 bits of high nybble
m_DACOutput -= DeltaTable[m_OldDelta][CurDelta]; // send data to forward delta table and subtract result from accumulator
m_OldDelta = CurDelta; // Move current delta to old
m_nextstate = 12;
break;
case 12: // Play phone backward, shift = 0 (increment address if needed)
- CurDelta = (m_SpeechRom[(m_PhoneAddress)+m_PhoneOffset]&0xc0)>>6; // grab current delta from high 2 bits of high nybble
+ CurDelta = (readmem((m_PhoneAddress)+m_PhoneOffset)&0xc0)>>6; // grab current delta from high 2 bits of high nybble
m_DACOutput -= DeltaTable[m_OldDelta][CurDelta]; // send data to forward delta table and subtract result from accumulator
m_OldDelta = CurDelta; // Move current delta to old
m_PhoneOffset--; // decrement phone offset
@@ -503,17 +503,28 @@ void s14001a_device::s14001a_clock() /* called once per clock */
m_nextstate = 0;
break;
}
+
+ /* the dac is 4 bits wide. if a delta step forced it outside of 4 bits, mask it back over here */
+ m_DACOutput &= 0xF;
+
#ifdef DEBUGSTATE
fprintf(stderr, "Machine state is now %d, was %d, PhoneOffset is %d\n", m_nextstate, m_machineState, m_PhoneOffset);
#endif
m_laststate = m_machineState;
m_machineState = m_nextstate;
- /* the dac is 4 bits wide. if a delta step forced it outside of 4 bits, mask it back over here */
- m_DACOutput &= 0xF;
+ if (bool(m_laststate) != bool(m_machineState) && !m_bsy_handler.isnull())
+ m_bsy_handler((m_machineState) ? 1 : 0);
}
}
+UINT8 s14001a_device::readmem(UINT16 offset)
+{
+ offset &= 0xfff; // 11-bit internal
+ return ((m_ext_read_handler.isnull()) ? m_ext_read_handler(offset) : m_SpeechRom[offset]);
+}
+
+
/**************************************************************************
MAME glue code
**************************************************************************/
@@ -559,6 +570,8 @@ s14001a_device::s14001a_device(const machine_config &mconfig, std::string tag, d
device_sound_interface(mconfig, *this),
m_SpeechRom(*this, DEVICE_SELF),
m_stream(nullptr),
+ m_bsy_handler(*this),
+ m_ext_read_handler(*this),
m_WordInput(0),
m_LatchedWord(0),
m_SyllableAddress(0),
@@ -587,19 +600,21 @@ s14001a_device::s14001a_device(const machine_config &mconfig, std::string tag, d
void s14001a_device::device_start()
{
- int i;
-
m_GlobalSilenceState = 1;
m_OldDelta = 0x02;
m_DACOutput = SILENCE;
- for (i = 0; i < 8; i++)
+ for (int i = 0; i < 8; i++)
{
m_filtervals[i] = SILENCE;
}
m_stream = machine().sound().stream_alloc(*this, 0, 1, clock() ? clock() : machine().sample_rate());
+ // resolve callbacks
+ m_ext_read_handler.resolve_safe(0);
+ m_bsy_handler.resolve_safe();
+
save_item(NAME(m_WordInput));
save_item(NAME(m_LatchedWord));
save_item(NAME(m_SyllableAddress));
diff --git a/src/devices/sound/s14001a.h b/src/devices/sound/s14001a.h
index 5f03ec495ce..c9ce1680318 100644
--- a/src/devices/sound/s14001a.h
+++ b/src/devices/sound/s14001a.h
@@ -8,6 +8,12 @@
#ifndef __S14001A_H__
#define __S14001A_H__
+#define MCFG_S14001A_BSY_HANDLER(_devcb) \
+ devcb = &s14001a_device::set_bsy_handler(*device, DEVCB_##_devcb);
+
+#define MCFG_S14001A_EXT_READ_HANDLER(_devcb) \
+ devcb = &s14001a_device::set_ext_read_handler(*device, DEVCB_##_devcb);
+
class s14001a_device : public device_t,
public device_sound_interface
@@ -16,6 +22,10 @@ public:
s14001a_device(const machine_config &mconfig, std::string tag, device_t *owner, UINT32 clock);
~s14001a_device() {}
+ // static configuration helpers
+ template<class _Object> static devcb_base &set_bsy_handler(device_t &device, _Object object) { return downcast<s14001a_device &>(device).m_bsy_handler.set_callback(object); }
+ template<class _Object> static devcb_base &set_ext_read_handler(device_t &device, _Object object) { return downcast<s14001a_device &>(device).m_ext_read_handler.set_callback(object); }
+
int bsy_r(); /* read BUSY pin */
void reg_w(int data); /* write to input latch */
void rst_w(int data); /* write to RESET pin */
@@ -34,6 +44,9 @@ private:
required_region_ptr<UINT8> m_SpeechRom;
sound_stream * m_stream;
+ devcb_write_line m_bsy_handler;
+ devcb_read8 m_ext_read_handler;
+
UINT8 m_WordInput; // value on word input bus
UINT8 m_LatchedWord; // value latched from input bus
UINT16 m_SyllableAddress; // address read from word table
@@ -57,6 +70,7 @@ private:
void PostPhoneme();
void s14001a_clock();
+ UINT8 readmem(UINT16 offset);
};
extern const device_type S14001A;