diff options
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 |
commit | d6d2b0d91716d653102b2a0cfcf6cbc88f3977f1 (patch) | |
tree | e1bd00f8e9612e8e9aba1d4ddb8204ec13794c7f | |
parent | 09d5082cdd5e0420526f890d9694e22c3f894409 (diff) |
s14001a: added optional devcb callbacks for mem read and BSY pin
-rw-r--r-- | src/devices/sound/s14001a.cpp | 51 | ||||
-rw-r--r-- | src/devices/sound/s14001a.h | 14 |
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; |