Previous 199869 Revisions Next

r44382 Saturday 23rd January, 2016 at 18:08:11 UTC by Miodrag Milanović
Merge pull request #574 from ajrhacker/confix2

More configuration fixes
[scripts/src]sound.lua
[scripts/target/mame]arcade.lua mess.lua
[src/devices/sound]s14001a.cpp s14001a.h s14001a_new.cpp s14001a_new.h scsp.cpp scsp.h
[src/mame/drivers]berzerk.cpp fidel6502.cpp fidelz80.cpp psychic5.cpp st_mp200.cpp wolfpack.cpp
[src/mame/includes]fidelz80.h wolfpack.h

trunk/scripts/src/sound.lua
r252893r252894
941941
942942
943943---------------------------------------------------
944-- S14001A_NEW speech synthesizer
945--@src/devices/sound/s14001a_new.h,SOUNDS["S14001A_NEW"] = true
946---------------------------------------------------
947
948if (SOUNDS["S14001A_NEW"]~=null) then
949   files {
950      MAME_DIR .. "src/devices/sound/s14001a_new.cpp",
951      MAME_DIR .. "src/devices/sound/s14001a_new.h",
952   }
953end
954
955
956
957---------------------------------------------------
958944-- Texas Instruments SN76477 analog chip
959945--@src/devices/sound/sn76477.h,SOUNDS["SN76477"] = true
960946---------------------------------------------------
trunk/scripts/target/mame/arcade.lua
r252893r252894
226226SOUNDS["ES8712"] = true
227227SOUNDS["CDP1869"] = true
228228SOUNDS["S14001A"] = true
229SOUNDS["S14001A_NEW"] = true
230229SOUNDS["WAVE"] = true
231230SOUNDS["SID6581"] = true
232231SOUNDS["SID8580"] = true
trunk/scripts/target/mame/mess.lua
r252893r252894
228228--SOUNDS["ES8712"] = true
229229SOUNDS["CDP1869"] = true
230230SOUNDS["S14001A"] = true
231SOUNDS["S14001A_NEW"] = true
232231SOUNDS["WAVE"] = true
233232SOUNDS["SID6581"] = true
234233SOUNDS["SID8580"] = true
trunk/src/devices/sound/s14001a.cpp
r252893r252894
11// license:BSD-3-Clause
2// copyright-holders:Jonathan Gevaryahu,R. Belmont,Zsolt Vasvari
2// copyright-holders:Ed Bernard, Jonathan Gevaryahu, hap
3// thanks-to:Kevin Horton
34/*
5    SSi TSI S14001A speech IC emulator
6    aka CRC: Custom ROM Controller, designed in 1975, first usage in 1976 on TSI Speech+ calculator
7    Originally written for MAME by Jonathan Gevaryahu(Lord Nightmare) 2006-2013,
8    replaced with near-complete rewrite by Ed Bernard in 2016
49
5 TSI S14001A emulator v1.32
6 By Jonathan Gevaryahu ("Lord Nightmare") with help from Kevin Horton ("kevtris")
7 MAME conversion and integration by R. Belmont
8 Clock Frequency control updated by Zsolt Vasvari
9 Other fixes by AtariAce
10    TODO:
11    - nothing at the moment?
1012
11 Copyright (C) 2006-2013 Jonathan Gevaryahu aka Lord Nightmare
12
13 Version history:
14 0.8 initial version - LN
15 0.9 MAME conversion, glue code added - R. Belmont
16 1.0 partly fixed stream update - LN (0.111u4)
17 1.01 fixed clipping problem - LN (0.111u5)
18 1.1 add VSU-1000 features, fully fixed stream update by fixing word latching - LN (0.111u6)
19 1.11 fix signedness of output, pre-multiply, fixes clicking on VSU-1000 volume change - LN (0.111u7)
20 1.20 supports setting the clock freq directly - reset is done by external hardware,
21      the chip has no reset line ZV (0.122)
22 1.30 move main dac to 4 bits only with no extension (4->16 bit range extension is now done by output).
23 Added a somewhat better, but still not perfect, filtering system - LN
24 1.31 fix a minor bug with the dac range. wolfpack clips again, and I'm almost sure its an encoding error on the original speech - LN (0.125u9)
25 1.31a Add chip pinout and other notes - LN (0.128u4)
26 1.31b slight update to notes to clarify input bus stuff, mostly finish the state map in the comments - LN
27 1.31c remove usage of deprecat lib - AtariAce (0.128u5)
28 1.32 fix the squealing noise using a define; it isn't accurate to the chip exactly, but there are other issues which need to be fixed too. see TODO. - LN (0.136u2)
29
30 TODO:
31 * increase accuracy of internal S14001A 'filter' for both driven and undriven cycles (its not terribly inaccurate for undriven cycles, but the dc sliding of driven cycles is not emulated)
32 * add option for and attach Frank P.'s emulation of the Analog external filter from the vsu-1000 using the discrete core. (with the direction of independent sound core and analog stuff, this should actually be attached in the main berzerk/frenzy driver and not here)
33 * fix the local and global silence stuff to not force the dac to a specific level, but cease doing deltas (i.e. force all deltas to 0) after the last sample; this should fix the clipping in wolfpack and in the fidelity games in mess.
13    Further reading:
14    - http://www.vintagecalculators.com/html/speech-.html
15    - http://www.vintagecalculators.com/html/development_of_the_tsi_speech-.html
16    - http://www.vintagecalculators.com/html/speech-_state_machine.html
17    - https://archive.org/stream/pdfy-QPCSwTWiFz1u9WU_/david_djvu.txt
3418*/
3519
3620/* Chip Pinout:
r252893r252894
9983START is pulled high when a word is to be said and the word number is on the
10084word select/speech address input lines. The Canon 'Canola' uses a separate 'rom
10185strobe' signal independent of the chip to either enable or clock the speech rom.
102Its likely that they did this to be able to force the speech chip to stop talking,
86It's likely that they did this to be able to force the speech chip to stop talking,
10387which is normally impossible. The later 'version 3' TSI speech board as featured in
10488an advertisement in the John Cater book probably also has this feature, in addition
10589to external speech rom banking.
r252893r252894
11094
11195Because it requires -10V to operate, the chip manufacturing process must be PMOS.
11296
113/-----------\
114> Operation <
115\-----------/
97* Operation:
11698Put the 6-bit address of the word to be said onto the C0-C5 word select/speech
11799address bus lines. Next, clock the START line low-high-low. As long as the START
118100line is held high, the first address byte of the first word will be read repeatedly
r252893r252894
121103/BUSY line will go low until 3 clocks after the chip is done speaking.
122104*/
123105
106#include "emu.h"
107#include "s14001a.h"
124108
125/* state map:
109// device definition
110const device_type S14001A = &device_creator<s14001a_device>;
126111
127 * state machine 1: odd/even clock state
128 * on even clocks, audio output is floating, /romen is low so rom data bus is driven, input is latched?
129 * on odd clocks, audio output is driven, /romen is high, state machine 2 is clocked
130 * *****
131 * state machine 2: decoder state
132 * NOTE: holding the start line high forces the state machine 2 state to go to or remain in state 1!
133 * state 0(Idle): Idle (no sample rom bus activity, output at 0), next state is 0(Idle)
112s14001a_device::s14001a_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
113   : device_t(mconfig, S14001A, "S14001A", tag, owner, clock, "s14001a", __FILE__),
114      device_sound_interface(mconfig, *this),
115      m_SpeechRom(*this, DEVICE_SELF),
116      m_stream(nullptr),
117      m_bsy_handler(*this),
118      m_ext_read_handler(*this)
119{
120}
134121
135 * state 1(GetHiWord):
136 *   grab byte at (wordinput<<1) -> register_WH
137 *   reset output DAC accumulator to 0x8 <- ???
138 *   reset OldValHi to 1
139 *   reset OldValLo to 0
140 *   next state is 2(GetLoWord) UNLESS the PLAY line is still high, in which case the state remains at 1
122//-------------------------------------------------
123//  device_start - device-specific startup
124//-------------------------------------------------
141125
142 * state 2(GetLoWord):
143 *   grab byte at (wordinput<<1)+1 -> register_WL
144 *   next state is 3(GetHiPhon)
126ALLOW_SAVE_TYPE(s14001a_device::states); // allow save_item on a non-fundamental type
145127
146 * state 3(GetHiPhon):
147 *   grab byte at ((register_WH<<8) + (register_WL))>>4 -> phoneaddress
148 *   next state is 4(GetLoPhon)
128void s14001a_device::device_start()
129{
130   m_stream = machine().sound().stream_alloc(*this, 0, 1, clock() ? clock() : machine().sample_rate());
149131
150 * state 4(GetLoPhon):
151 *   grab byte at (((register_WH<<8) + (register_WL))>>4)+1 -> playparams
152 *   set phonepos register to 0
153 *   set oddphone register to 0
154 *   next state is 5(PlayForward1)
155 *   playparams:
156 *   7 6 5 4 3 2 1 0
157 *   G                G = LastPhone
158 *     B              B = PlayMode
159 *       Y            Y = Silenceflag
160 *         S S S      S = Length count load value
161 *               R R  R = Repeat count reload value (upon carry/overflow of 3 bits)
162 *   load the repeat counter with the bits 'R R 0'
163 *   load the length counter with the bits 'S S S 0'
164 *   NOTE: though only three bits of the length counter load value are controllable, there is a fourth lower bit which is assumed 0 on start and controls the direction of playback, i.e. forwards or backwards within a phone.
165 *   NOTE: though only two bits of the repeat counter reload value are controllable, there is a third bit which is loaded to 0 on phoneme start, and this hidden low-order bit of the counter itself is what controls whether the output is forced to silence in mirrored mode. the 'carry' from the highest bit of the 3 bit counter is what increments the address pointer for pointing to the next phoneme in mirrored mode
132   // resolve callbacks
133   m_ext_read_handler.resolve();
134   m_bsy_handler.resolve();
135   
136   // note: zerofill is done already by MAME core
137   ClearStatistics();
138   m_uOutputP1 = m_uOutputP2 = 7;
139   
140   // register for savestates
141   save_item(NAME(m_bPhase1));
142   save_item(NAME(m_uStateP1));
143   save_item(NAME(m_uStateP2));
144   save_item(NAME(m_uDAR13To05P1));
145   save_item(NAME(m_uDAR13To05P2));
146   save_item(NAME(m_uDAR04To00P1));
147   save_item(NAME(m_uDAR04To00P2));
148   save_item(NAME(m_uCWARP1));
149   save_item(NAME(m_uCWARP2));
166150
151   save_item(NAME(m_bStopP1));
152   save_item(NAME(m_bStopP2));
153   save_item(NAME(m_bVoicedP1));
154   save_item(NAME(m_bVoicedP2));
155   save_item(NAME(m_bSilenceP1));
156   save_item(NAME(m_bSilenceP2));
157   save_item(NAME(m_uLengthP1));
158   save_item(NAME(m_uLengthP2));
159   save_item(NAME(m_uXRepeatP1));
160   save_item(NAME(m_uXRepeatP2));
161   save_item(NAME(m_uDeltaOldP1));
162   save_item(NAME(m_uDeltaOldP2));
163   save_item(NAME(m_uOutputP1));
167164
168 *   shift register diagram:
169 *   F E D C B A 9 8 7 6 5 4 3 2 1 0
170 *   <new byte here>
171 *               C C                 C = Current delta sample read point
172 *                   O O             O = Old delta sample read point
173 * I *OPTIMIZED OUT* the shift register by making use of the fact that the device reads each rom byte 4 times
165   save_item(NAME(m_bDAR04To00CarryP2));
166   save_item(NAME(m_bPPQCarryP2));
167   save_item(NAME(m_bRepeatCarryP2));
168   save_item(NAME(m_bLengthCarryP2));
169   save_item(NAME(m_RomAddrP1));
174170
175 * state 5(PlayForward1):
176 *   grab byte at (((phoneaddress<<8)+(oddphone*8))+(phonepos>>2)) -> PlayRegister high end, bits F to 8
177 *   if Playmode is mirrored, set OldValHi and OldValLo to 1 and 0 respectively, otherwise leave them with whatever was in them before.
178 *   Put OldValHi in bit 7 of PlayRegister
179 *   Put OldValLo in bit 6 of PlayRegister
180 *   Get new OldValHi from bit 9
181 *   Get new OldValLo from bit 8
182 *   feed current delta (bits 9 and 8) and olddelta (bits 7 and 6) to delta demodulator table, delta demodulator table applies a delta to the accumulator, accumulator goes to enable/disable latch which Silenceflag enables or disables (forces output to 0x8 on disable), then to DAC to output.
183 *   next state: state 6(PlayForward2)
171   save_item(NAME(m_uOutputP2));
172   save_item(NAME(m_uRomAddrP2));
173   save_item(NAME(m_bBusyP1));
174   save_item(NAME(m_bStart));
175   save_item(NAME(m_uWord));
184176
185 * state 6(PlayForward2):
186 *   grab byte at (((phoneaddress<<8)+oddphone)+(phonepos>>2)) -> PlayRegister bits D to 6.
187 *   Put OldValHi in bit 7 of PlayRegister\____already done by above operation
188 *   Put OldValLo in bit 6 of PlayRegister/
189 *   Get new OldValHi from bit 9
190 *   Get new OldValLo from bit 8
191 *   feed current delta (bits 9 and 8) and olddelta (bits 7 and 6) to delta demodulator table, delta demodulator table applies a delta to the accumulator, accumulator goes to enable/disable latch which Silenceflag enables or disables (forces output to 0x8 on disable), then to DAC to output.
192 *   next state: state 7(PlayForward3)
177   save_item(NAME(m_uNPitchPeriods));
178   save_item(NAME(m_uNVoiced));
179   save_item(NAME(m_uNControlWords));
180   save_item(NAME(m_uPrintLevel));
181}
193182
194 * state 7(PlayForward3):
195 *   grab byte at (((phoneaddress<<8)+oddphone)+(phonepos>>2)) -> PlayRegister bits B to 4.
196 *   Put OldValHi in bit 7 of PlayRegister\____already done by above operation
197 *   Put OldValLo in bit 6 of PlayRegister/
198 *   Get new OldValHi from bit 9
199 *   Get new OldValLo from bit 8
200 *   feed current delta (bits 9 and 8) and olddelta (bits 7 and 6) to delta demodulator table, delta demodulator table applies a delta to the accumulator, accumulator goes to enable/disable latch which Silenceflag enables or disables (forces output to 0x8 on disable), then to DAC to output.
201 *   next state: state 8(PlayForward4)
202183
203 * state 8(PlayForward4):
204 *   grab byte at (((phoneaddress<<8)+oddphone)+(phonepos>>2)) -> PlayRegister bits 9 to 2.
205 *   Put OldValHi in bit 7 of PlayRegister\____already done by above operation
206 *   Put OldValLo in bit 6 of PlayRegister/
207 *   Get new OldValHi from bit 9
208 *   Get new OldValLo from bit 8
209 *   feed current delta (bits 9 and 8) and olddelta (bits 7 and 6) to delta demodulator table, delta demodulator table applies a delta to the accumulator, accumulator goes to enable/disable latch which Silenceflag enables or disables (forces output to 0x8 on disable), then to DAC to output.
210 *   if offset < 8, increment offset within 8-byte phone
211 *   if offset = 8: (see PostPhoneme code to understand how this part works, its a bit complicated)
184//-------------------------------------------------
185//  sound_stream_update - handle a stream update
186//-------------------------------------------------
212187
213 *   next state: depends on playparams:
214 *     if we're in mirrored mode, next will be LoadAndPlayBackward1
215 *     if we're in nonmirrored mode, next will be PlayForward1
188void s14001a_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
189{
190   for (int i = 0; i < samples; i++)
191   {
192      Clock();
193      INT16 sample = m_uOutputP2 - 7; // range -7..8
194      outputs[0][i] = sample * 0xf00;
195   }
196}
216197
217 * state 9(LoadAndPlayBackward1)
218 *   grab byte at (((phoneaddress<<8)+(oddphone*8))+(phonepos>>2)) -> PlayRegister high end, bits F to 8 <- check code on this, I think its backwards here but its correct in the code
219 *   see code for this, its basically the same as state 8 but with the byte grab mentioned above, and the values fed to the delta demod table are switched
220 * state 10(PlayBackward2)
221 *   see code for this, its basically the same as state 7 but the values fed to the delta demod table are switched
222 * state 11(PlayBackward3)
223 *   see code for this, its basically the same as state 6 but the values fed to the delta demod table are switched
224 * state 12(PlayBackward4)
225 *   see code for this, its basically the same as state 5 but with no byte grab, and the values fed to the delta demod table are switched, and a bit below similar to state 5
226 *   if offset > -1, decrement offset within 8-byte phone
227 *   if offset = -1: (see PostPhoneme code to understand how this part works, its a bit complicated)
228*/
229198
230/* increment address function:
231 *   increment repeat counter
232        if repeat counter produces a carry, do two things:
233           1. if mirrored mode is ON, increment oddphone. if oddphone carries out (i.e. if it was 1), increment phoneaddress and zero oddphone
234       2. increment lengthcounter. if lengthcounter carries out, we're done this phone.
235 *   increment output counter
236 *      if mirrored mode is on, output direction is
237 *   if mirrored mode is OFF, increment oddphone. if not, don't touch it here. if oddphone was 1 before the increment, increment phoneaddress and set oddphone to 0
238 *
239 */
199/**************************************************************************
200    External interface
201**************************************************************************/
240202
241#undef ACCURATE_SQUEAL
203void s14001a_device::force_update()
204{
205   m_stream->update();
206}
242207
243#include "emu.h"
244#include "s14001a.h"
208READ_LINE_MEMBER(s14001a_device::romen_r)
209{
210   m_stream->update();
211   return (m_bPhase1) ? 1 : 0;
212}
245213
214READ_LINE_MEMBER(s14001a_device::busy_r)
215{
216   m_stream->update();
217   return (m_bBusyP1) ? 1 : 0;
218}
246219
247//#define DEBUGSTATE
220WRITE8_MEMBER(s14001a_device::data_w)
221{
222   m_stream->update();
223   m_uWord = data & 0x3f; // C0-C5
224}
248225
249#define SILENCE 0x7 // value output when silent
250#define ALTFLAG 0xFF // value to tell renderer that this frame's output is the average of the 8 prior frames and not directly used.
226WRITE_LINE_MEMBER(s14001a_device::start_w)
227{
228   m_stream->update();
229   m_bStart = (state != 0);
230   if (m_bStart) m_uStateP1 = WORDWAIT;
231}
251232
252#define LASTSYLLABLE ((m_PlayParams & 0x80)>>7)
253#define MIRRORMODE ((m_PlayParams & 0x40)>>6)
254#define SILENCEFLAG ((m_PlayParams & 0x20)>>5)
255#define LENGTHCOUNT ((m_PlayParams & 0x1C)>>1) // remember: its 4 bits and the bottom bit is always zero!
256#define REPEATCOUNT ((m_PlayParams<<1)&0x6) // remember: its 3 bits and the bottom bit is always zero!
257#define LOCALSILENCESTATE ((m_OutputCounter & 0x2) && (MIRRORMODE)) // 1 when silent output, 0 when DAC output.
258
259static const INT8 DeltaTable[4][4] =
233void s14001a_device::set_clock(UINT32 clock)
260234{
261   { -3, -3, -1, -1, },
262   { -1, -1,  0,  0, },
263   {  0,  0,  1,  1, },
264   {  1,  1,  3,  3  },
265};
235   m_stream->update();
236   m_stream->set_sample_rate(clock);
237}
266238
267#ifdef ACCURATE_SQUEAL
268INT16 s14001a_device::audiofilter() /* rewrite me to better match the real filter! */
239
240/**************************************************************************
241    Device emulation
242**************************************************************************/
243
244UINT8 s14001a_device::readmem(UINT16 offset, bool phase)
269245{
270   UINT8 temp1;
271      INT16 temp2 = 0;
272   /* mean averaging filter! 1/n exponential *would* be somewhat better, but I'm lazy... */
273   for (temp1 = 0; temp1 < 8; temp1++) { temp2 += m_filtervals[temp1]; }
274   temp2 >>= 3;
275   return temp2;
246   offset &= 0xfff; // 11-bit internal
247   return ((m_ext_read_handler.isnull()) ? m_SpeechRom[offset & (m_SpeechRom.bytes() - 1)] : m_ext_read_handler(offset));
276248}
277249
278void s14001a_device::shiftIntoFilter(INT16 inputvalue)
250bool s14001a_device::Clock()
279251{
280   UINT8 temp1;
281   for (temp1 = 7; temp1 > 0; temp1--)
252   // effectively toggles external clock twice, one cycle
253   // internal clock toggles on external clock transition from 0 to 1 so internal clock will always transition here
254   // return false if some emulator problem detected
255
256   // On the actual chip, all register phase 1 values needed to be refreshed from phase 2 values
257   // or else risk losing their state due to charge loss.
258   // But on a computer the values are static.
259   // So to reduce code clutter, phase 1 values are only modified if they are different
260   // from the preceeding phase 2 values.
261
262   if (m_bPhase1)
282263   {
283      m_filtervals[temp1] = m_filtervals[(temp1 - 1)];
264      // transition to phase2
265      m_bPhase1 = false;
266
267      // transfer phase1 variables to phase2
268      m_uStateP2     = m_uStateP1;
269      m_uDAR13To05P2 = m_uDAR13To05P1;
270      m_uDAR04To00P2 = m_uDAR04To00P1;
271      m_uCWARP2      = m_uCWARP1;
272      m_bStopP2      = m_bStopP1;
273      m_bVoicedP2    = m_bVoicedP1;
274      m_bSilenceP2   = m_bSilenceP1;
275      m_uLengthP2    = m_uLengthP1;
276      m_uXRepeatP2   = m_uXRepeatP1;
277      m_uDeltaOldP2  = m_uDeltaOldP1;
278
279      m_uOutputP2    = m_uOutputP1;
280      m_uRomAddrP2   = m_RomAddrP1;
281
282      // setup carries from phase 2 values
283      m_bDAR04To00CarryP2  = m_uDAR04To00P2 == 0x1F;
284      m_bPPQCarryP2        = m_bDAR04To00CarryP2 && ((m_uLengthP2&0x03) == 0x03); // pitch period quarter
285      m_bRepeatCarryP2     = m_bPPQCarryP2       && ((m_uLengthP2&0x0C) == 0x0C);
286      m_bLengthCarryP2     = m_bRepeatCarryP2    && ( m_uLengthP2       == 0x7F);
287
288      return true;
284289   }
285   m_filtervals[0] = inputvalue;
286}
287#endif
290   m_bPhase1 = true;
288291
289void s14001a_device::PostPhoneme() /* figure out what the heck to do after playing a phoneme */
290{
291#ifdef DEBUGSTATE
292   fprintf(stderr,"0: entered PostPhoneme\n");
293#endif
294   m_RepeatCounter++; // increment the repeat counter
295   m_OutputCounter++; // increment the output counter
296   if (MIRRORMODE) // if mirroring is enabled
292   // logic done during phase 1
293   switch (m_uStateP1)
297294   {
298#ifdef DEBUGSTATE
299      fprintf(stderr,"1: MIRRORMODE was on\n");
300#endif
301      if (m_RepeatCounter == 0x8) // exceeded 3 bits?
295   case IDLE:
296      m_uOutputP1 = 7;
297      if (m_bStart) m_uStateP1 = WORDWAIT;
298
299      if (m_bBusyP1 && !m_bsy_handler.isnull())
300         m_bsy_handler(0);
301      m_bBusyP1 = false;
302      break;
303
304   case WORDWAIT:
305      // the delta address register latches the word number into bits 03 to 08
306      // all other bits forced to 0.  04 to 08 makes a multiply by two.
307      m_uDAR13To05P1 = (m_uWord&0x3C)>>2;
308      m_uDAR04To00P1 = (m_uWord&0x03)<<3;
309      m_RomAddrP1 = (m_uDAR13To05P1<<3)|(m_uDAR04To00P1>>2); // remove lower two bits
310      m_uOutputP1 = 7;
311      if (m_bStart) m_uStateP1 = WORDWAIT;
312      else          m_uStateP1 = CWARMSB;
313
314      if (!m_bBusyP1 && !m_bsy_handler.isnull())
315         m_bsy_handler(1);
316      m_bBusyP1 = true;
317      break;
318
319   case CWARMSB:
320      if (m_uPrintLevel >= 1)
321         printf("\n speaking word %02x",m_uWord);
322
323      // use uDAR to load uCWAR 8 msb
324      m_uCWARP1 = readmem(m_uRomAddrP2,m_bPhase1)<<4; // note use of rom address setup in previous state
325      // increment DAR by 4, 2 lsb's count deltas within a byte
326      m_uDAR04To00P1 += 4;
327      if (m_uDAR04To00P1 >= 32) m_uDAR04To00P1 = 0; // emulate 5 bit counter
328      m_RomAddrP1 = (m_uDAR13To05P1<<3)|(m_uDAR04To00P1>>2); // remove lower two bits
329
330      m_uOutputP1 = 7;
331      if (m_bStart) m_uStateP1 = WORDWAIT;
332      else          m_uStateP1 = CWARLSB;
333      break;
334
335   case CWARLSB:
336      m_uCWARP1   = m_uCWARP2|(readmem(m_uRomAddrP2,m_bPhase1)>>4); // setup in previous state
337      m_RomAddrP1 = m_uCWARP1;
338
339      m_uOutputP1 = 7;
340      if (m_bStart) m_uStateP1 = WORDWAIT;
341      else          m_uStateP1 = DARMSB;
342      break;
343
344   case DARMSB:
345      m_uDAR13To05P1 = readmem(m_uRomAddrP2,m_bPhase1)<<1; // 9 bit counter, 8 MSBs from ROM, lsb zeroed
346      m_uDAR04To00P1 = 0;
347      m_uCWARP1++;
348      m_RomAddrP1 = m_uCWARP1;
349      m_uNControlWords++; // statistics
350
351      m_uOutputP1 = 7;
352      if (m_bStart) m_uStateP1 = WORDWAIT;
353      else          m_uStateP1 = CTRLBITS;
354      break;
355
356   case CTRLBITS:
357      m_bStopP1    = readmem(m_uRomAddrP2,m_bPhase1)&0x80? true: false;
358      m_bVoicedP1  = readmem(m_uRomAddrP2,m_bPhase1)&0x40? true: false;
359      m_bSilenceP1 = readmem(m_uRomAddrP2,m_bPhase1)&0x20? true: false;
360      m_uXRepeatP1 = readmem(m_uRomAddrP2,m_bPhase1)&0x03;
361      m_uLengthP1  =(readmem(m_uRomAddrP2,m_bPhase1)&0x1F)<<2; // includes external length and repeat
362      m_uDAR04To00P1 = 0;
363      m_uCWARP1++; // gets ready for next DARMSB
364      m_RomAddrP1  = (m_uDAR13To05P1<<3)|(m_uDAR04To00P1>>2); // remove lower two bits
365
366      m_uOutputP1 = 7;
367      if (m_bStart) m_uStateP1 = WORDWAIT;
368      else          m_uStateP1 = PLAY;
369
370      if (m_uPrintLevel >= 2)
371         printf("\n cw %d %d %d %d %d",m_bStopP1,m_bVoicedP1,m_bSilenceP1,m_uLengthP1>>4,m_uXRepeatP1);
372
373      break;
374
375   case PLAY:
376   {
377      // statistics
378      if (m_bPPQCarryP2)
302379      {
303#ifdef DEBUGSTATE
304         fprintf(stderr,"2: RepeatCounter was == 8\n");
305#endif
306         // reset repeat counter, increment length counter
307         // but first check if lowest bit is set
308         m_RepeatCounter = REPEATCOUNT; // reload repeat counter with reload value
309         if (m_LengthCounter & 0x1) // if low bit is 1 (will carry after increment)
380         // pitch period end
381         if (m_uPrintLevel >= 3)
382            printf("\n ppe: RomAddr %03x",m_uRomAddrP2);
383
384         m_uNPitchPeriods++;
385         if (m_bVoicedP2) m_uNVoiced++;
386      }
387      // end statistics
388
389      // modify output
390      UINT8 uDeltaP2;     // signal line
391      UINT8 uIncrementP2; // signal lines
392      bool bAddP2;        // signal line
393      uDeltaP2 = Mux8To2(m_bVoicedP2,
394               m_uLengthP2 & 0x03,     // pitch period quater counter
395               m_uDAR04To00P2 & 0x03,  // two bit delta address within byte
396               readmem(m_uRomAddrP2,m_bPhase1)
397      );
398      CalculateIncrement(m_bVoicedP2,
399               m_uLengthP2 & 0x03,     // pitch period quater counter
400               m_uDAR04To00P2 == 0,    // pitch period quarter start
401               uDeltaP2,
402               m_uDeltaOldP2,          // input
403               m_uDeltaOldP1,          // output
404               uIncrementP2,           // output 0, 1, or 3
405               bAddP2                  // output
406      );
407      m_uOutputP1 = CalculateOutput(m_bVoicedP2,
408               m_bSilenceP2,
409               m_uLengthP2 & 0x03,     // pitch period quater counter
410               m_uDAR04To00P2 == 0,    // pitch period quarter start
411               m_uOutputP2,            // last output
412               uIncrementP2,
413               bAddP2
414      );
415
416      // advance counters
417      m_uDAR04To00P1++;
418      if (m_bDAR04To00CarryP2) // pitch period quarter end
419      {
420         m_uDAR04To00P1 = 0; // emulate 5 bit counter
421
422         m_uLengthP1++; // lower two bits of length count quarter pitch periods
423         if (m_uLengthP1 >= 0x80)
310424         {
311#ifdef DEBUGSTATE
312            fprintf(stderr,"3: LengthCounter's low bit was 1\n");
313#endif
314            m_PhoneAddress+=8; // go to next phone in this syllable
425            m_uLengthP1 = 0; // emulate 7 bit counter
315426         }
316         m_LengthCounter++;
317         if (m_LengthCounter == 0x10) // if Length counter carried out of 4 bits
318         {
319#ifdef DEBUGSTATE
320            fprintf(stderr,"3: LengthCounter overflowed\n");
321#endif
322            m_SyllableAddress += 2; // go to next syllable
323            m_nextstate = LASTSYLLABLE ? 13 : 3; // if we're on the last syllable, go to end state, otherwise go and load the next syllable.
324         }
325         else
326         {
327#ifdef DEBUGSTATE
328            fprintf(stderr,"3: LengthCounter's low bit wasn't 1 and it didn't overflow\n");
329#endif
330            m_PhoneOffset = (m_OutputCounter&1) ? 7 : 0;
331            m_nextstate = (m_OutputCounter&1) ? 9 : 5;
332         }
333427      }
334      else // repeatcounter did NOT carry out of 3 bits so leave length counter alone
428
429      if (m_bVoicedP2 && m_bRepeatCarryP2) // repeat complete
335430      {
336#ifdef DEBUGSTATE
337         fprintf(stderr,"2: RepeatCounter is less than 8 (its actually %d)\n", m_RepeatCounter);
338#endif
339         m_PhoneOffset = (m_OutputCounter&1) ? 7 : 0;
340         m_nextstate = (m_OutputCounter&1) ? 9 : 5;
431         m_uLengthP1 &= 0x70; // keep current "length"
432         m_uLengthP1 |= (m_uXRepeatP1<<2); // load repeat from external repeat
433         m_uDAR13To05P1++; // advances ROM address 8 bytes
434         if (m_uDAR13To05P1 >= 0x200) m_uDAR13To05P1 = 0; // emulate 9 bit counter
341435      }
342   }
343   else // if mirroring is NOT enabled
344   {
345#ifdef DEBUGSTATE
346      fprintf(stderr,"1: MIRRORMODE was off\n");
347#endif
348      if (m_RepeatCounter == 0x8) // exceeded 3 bits?
436      if (!m_bVoicedP2 && m_bDAR04To00CarryP2)
349437      {
350#ifdef DEBUGSTATE
351         fprintf(stderr,"2: RepeatCounter was == 8\n");
352#endif
353         // reset repeat counter, increment length counter
354         m_RepeatCounter = REPEATCOUNT; // reload repeat counter with reload value
355         m_LengthCounter++;
356         if (m_LengthCounter == 0x10) // if Length counter carried out of 4 bits
357         {
358#ifdef DEBUGSTATE
359            fprintf(stderr,"3: LengthCounter overflowed\n");
360#endif
361            m_SyllableAddress += 2; // go to next syllable
362            m_nextstate = LASTSYLLABLE ? 13 : 3; // if we're on the last syllable, go to end state, otherwise go and load the next syllable.
363#ifdef DEBUGSTATE
364            fprintf(stderr,"nextstate is now %d\n", m_nextstate); // see line below, same reason.
365#endif
366            return; // need a return here so we don't hit the 'nextstate = 5' line below
367         }
438         // unvoiced advances each quarter pitch period
439         // note repeat counter not reloaded for non voiced speech
440         m_uDAR13To05P1++; // advances ROM address 8 bytes
441         if (m_uDAR13To05P1 >= 0x200) m_uDAR13To05P1 = 0; // emulate 9 bit counter
368442      }
369      m_PhoneAddress += 8; // regardless of counters, the phone address always increments in non-mirrored mode
370      m_PhoneOffset = 0;
371      m_nextstate = 5;
372   }
373#ifdef DEBUGSTATE
374   fprintf(stderr,"nextstate is now %d\n", m_nextstate);
375#endif
376}
377443
378void s14001a_device::s14001a_clock() /* called once per clock */
379{
380   UINT8 CurDelta; // Current delta
381
382   /* on even clocks, audio output is floating, /romen is low so rom data bus is driven
383        * on odd clocks, audio output is driven, /romen is high, state machine 2 is clocked
384        */
385   m_oddeven = !(m_oddeven); // invert the clock
386   if (m_oddeven == 0) // even clock
387   {
388#ifdef ACCURATE_SQUEAL
389      m_audioout = ALTFLAG; // flag to the renderer that this output should be the average of the last 8
390#endif
391      // DIGITAL INPUT *MIGHT* occur on the test pins occurs on this cycle?
392   }
393   else // odd clock
394   {
395      // fix dac output between samples. theoretically this might be unnecessary but it would require some messy logic in state 5 on the first sample load.
396      // Note: this behavior is NOT accurate, and needs to be fixed. see TODO.
397      if (m_GlobalSilenceState || LOCALSILENCESTATE)
444      // construct m_RomAddrP1
445      m_RomAddrP1 = m_uDAR04To00P1;
446      if (m_bVoicedP2 && m_uLengthP1&0x1) // mirroring
398447      {
399         m_DACOutput = SILENCE;
400         m_OldDelta = 2;
448         m_RomAddrP1 ^= 0x1f; // count backwards
401449      }
402      m_audioout = (m_GlobalSilenceState || LOCALSILENCESTATE) ? SILENCE : m_DACOutput; // when either silence state is 1, output silence.
403      // DIGITAL OUTPUT *might* be driven onto the test pins on this cycle?
404      switch(m_machineState)
450      m_RomAddrP1 = (m_uDAR13To05P1<<3) | m_RomAddrP1>>2;
451
452      // next state
453      if (m_bStart) m_uStateP1 = WORDWAIT;
454      else if (m_bStopP2 && m_bLengthCarryP2) m_uStateP1 = DELAY;
455      else if (m_bLengthCarryP2)
405456      {
406      case 0: // idle state
407         m_nextstate = 0;
408         break;
409      case 1: // read starting syllable high byte from word table
410         m_SyllableAddress = 0; // clear syllable address
411         m_SyllableAddress |= readmem((m_LatchedWord<<1))<<4;
412         m_nextstate = m_resetState ? 1 : 2;
413         break;
414      case 2: // read starting syllable low byte from word table
415         m_SyllableAddress |= readmem((m_LatchedWord<<1)+1)>>4;
416         m_nextstate = 3;
417         break;
418      case 3: // read starting phone address
419         m_PhoneAddress = readmem(m_SyllableAddress)<<4;
420         m_nextstate = 4;
421         break;
422      case 4: // read playback parameters and prepare for play
423         m_PlayParams = readmem(m_SyllableAddress+1);
424         m_GlobalSilenceState = SILENCEFLAG; // load phone silence flag
425         m_LengthCounter = LENGTHCOUNT; // load length counter
426         m_RepeatCounter = REPEATCOUNT; // load repeat counter
427         m_OutputCounter = 0; // clear output counter and disable mirrored phoneme silence indirectly via LOCALSILENCESTATE
428         m_PhoneOffset = 0; // set offset within phone to zero
429         m_OldDelta = 0x2; // set old delta to 2 <- is this right?
430         m_DACOutput = SILENCE ; // set DAC output to center/silence position
431         m_nextstate = 5;
432         break;
433      case 5: // Play phone forward, shift = 0 (also load)
434         CurDelta = (readmem((m_PhoneAddress)+m_PhoneOffset)&0xc0)>>6; // grab current delta from high 2 bits of high nybble
435         m_DACOutput += DeltaTable[CurDelta][m_OldDelta]; // send data to forward delta table and add result to accumulator
436         m_OldDelta = CurDelta; // Move current delta to old
437         m_nextstate = 6;
438         break;
439      case 6: // Play phone forward, shift = 2
440         CurDelta = (readmem((m_PhoneAddress)+m_PhoneOffset)&0x30)>>4; // grab current delta from low 2 bits of high nybble
441         m_DACOutput += DeltaTable[CurDelta][m_OldDelta]; // send data to forward delta table and add result to accumulator
442         m_OldDelta = CurDelta; // Move current delta to old
443         m_nextstate = 7;
444         break;
445      case 7: // Play phone forward, shift = 4
446         CurDelta = (readmem((m_PhoneAddress)+m_PhoneOffset)&0xc)>>2; // grab current delta from high 2 bits of low nybble
447         m_DACOutput += DeltaTable[CurDelta][m_OldDelta]; // send data to forward delta table and add result to accumulator
448         m_OldDelta = CurDelta; // Move current delta to old
449         m_nextstate = 8;
450         break;
451      case 8: // Play phone forward, shift = 6 (increment address if needed)
452         CurDelta = readmem((m_PhoneAddress)+m_PhoneOffset)&0x3; // grab current delta from low 2 bits of low nybble
453         m_DACOutput += DeltaTable[CurDelta][m_OldDelta]; // send data to forward delta table and add result to accumulator
454         m_OldDelta = CurDelta; // Move current delta to old
455         m_PhoneOffset++; // increment phone offset
456         if (m_PhoneOffset == 0x8) // if we're now done this phone
457         {
458            /* call the PostPhoneme Function */
459            PostPhoneme();
460         }
461         else
462         {
463            m_nextstate = 5;
464         }
465         break;
466      case 9: // Play phone backward, shift = 6 (also load)
467         CurDelta = (readmem((m_PhoneAddress)+m_PhoneOffset)&0x3); // grab current delta from low 2 bits of low nybble
468         if (m_laststate != 8) // ignore first (bogus) dac change in mirrored backwards mode. observations and the patent show this.
469         {
470            m_DACOutput -= DeltaTable[m_OldDelta][CurDelta]; // send data to forward delta table and subtract result from accumulator
471         }
472         m_OldDelta = CurDelta; // Move current delta to old
473         m_nextstate = 10;
474         break;
475      case 10: // Play phone backward, shift = 4
476         CurDelta = (readmem((m_PhoneAddress)+m_PhoneOffset)&0xc)>>2; // grab current delta from high 2 bits of low nybble
477         m_DACOutput -= DeltaTable[m_OldDelta][CurDelta]; // send data to forward delta table and subtract result from accumulator
478         m_OldDelta = CurDelta; // Move current delta to old
479         m_nextstate = 11;
480         break;
481      case 11: // Play phone backward, shift = 2
482         CurDelta = (readmem((m_PhoneAddress)+m_PhoneOffset)&0x30)>>4; // grab current delta from low 2 bits of high nybble
483         m_DACOutput -= DeltaTable[m_OldDelta][CurDelta]; // send data to forward delta table and subtract result from accumulator
484         m_OldDelta = CurDelta; // Move current delta to old
485         m_nextstate = 12;
486         break;
487      case 12: // Play phone backward, shift = 0 (increment address if needed)
488         CurDelta = (readmem((m_PhoneAddress)+m_PhoneOffset)&0xc0)>>6; // grab current delta from high 2 bits of high nybble
489         m_DACOutput -= DeltaTable[m_OldDelta][CurDelta]; // send data to forward delta table and subtract result from accumulator
490         m_OldDelta = CurDelta; // Move current delta to old
491         m_PhoneOffset--; // decrement phone offset
492         if (m_PhoneOffset == 0xFF) // if we're now done this phone
493         {
494            /* call the PostPhoneme() function */
495            PostPhoneme();
496         }
497         else
498         {
499            m_nextstate = 9;
500         }
501         break;
502      case 13: // For those pedantic among us, consume an extra two clocks like the real chip does.
503         m_nextstate = 0;
504         break;
457         m_uStateP1  = DARMSB;
458         m_RomAddrP1 = m_uCWARP1; // output correct address
505459      }
460      else m_uStateP1 = PLAY;
461      break;
462   }
506463
507      /* the dac is 4 bits wide. if a delta step forced it outside of 4 bits, mask it back over here */
508      m_DACOutput &= 0xF;
509
510#ifdef DEBUGSTATE
511      fprintf(stderr, "Machine state is now %d, was %d, PhoneOffset is %d\n", m_nextstate, m_machineState, m_PhoneOffset);
512#endif
513      m_laststate = m_machineState;
514      m_machineState = m_nextstate;
515
516      if (bool(m_laststate) != bool(m_machineState) && !m_bsy_handler.isnull())
517         m_bsy_handler((m_machineState) ? 1 : 0);
464   case DELAY:
465      m_uOutputP1 = 7;
466      if (m_bStart) m_uStateP1 = WORDWAIT;
467      else          m_uStateP1 = IDLE;
468      break;
518469   }
519}
520470
521UINT8 s14001a_device::readmem(UINT16 offset)
522{
523   offset &= 0xfff; // 11-bit internal
524   return ((m_ext_read_handler.isnull()) ? m_SpeechRom[offset & (m_SpeechRom.bytes() - 1)] : m_ext_read_handler(offset));
471   return true;
525472}
526473
527
528/**************************************************************************
529   MAME glue code
530 **************************************************************************/
531
532void s14001a_device::force_update()
474UINT8 s14001a_device::Mux8To2(bool bVoicedP2, UINT8 uPPQtrP2, UINT8 uDeltaAdrP2, UINT8 uRomDataP2)
533475{
534   m_stream->update();
535}
476   // pick two bits of rom data as delta
536477
537int s14001a_device::bsy_r()
538{
539   m_stream->update();
540#ifdef DEBUGSTATE
541   fprintf(stderr,"busy state checked: %d\n",(m_machineState != 0) );
542#endif
543   return (m_machineState != 0);
478   if (bVoicedP2 && uPPQtrP2&0x01) // mirroring
479   {
480      uDeltaAdrP2 ^= 0x03; // count backwards
481   }
482   // emulate 8 to 2 mux to obtain delta from byte (bigendian)
483   switch (uDeltaAdrP2)
484   {
485   case 0x00:
486      return (uRomDataP2&0xC0)>>6;
487   case 0x01:
488      return (uRomDataP2&0x30)>>4;
489   case 0x02:
490      return (uRomDataP2&0x0C)>>2;
491   case 0x03:
492      return (uRomDataP2&0x03)>>0;
493   }
494   return 0xFF;
544495}
545496
546void s14001a_device::reg_w(int data)
497void s14001a_device::CalculateIncrement(bool bVoicedP2, UINT8 uPPQtrP2, bool bPPQStartP2, UINT8 uDelta, UINT8 uDeltaOldP2, UINT8 &uDeltaOldP1, UINT8 &uIncrementP2, bool &bAddP2)
547498{
548   m_stream->update();
549   m_WordInput = data;
550}
499   // uPPQtr, pitch period quarter counter; 2 lsb of uLength
500   // bPPStart, start of a pitch period
501   // implemented to mimic silicon (a bit)
551502
552void s14001a_device::rst_w(int data)
553{
554   m_stream->update();
555   m_LatchedWord = m_WordInput;
556   m_resetState = (data==1);
557   m_machineState = m_resetState ? 1 : m_machineState;
558}
503   // beginning of a pitch period
504   if (uPPQtrP2 == 0x00 && bPPQStartP2) // note this is done for voiced and unvoiced
505   {
506      uDeltaOldP2 = 0x02;
507   }
508   static const UINT8 uIncrements[4][4] =
509   {
510   //    00  01  10  11
511      { 3,  3,  1,  1,}, // 00
512      { 1,  1,  0,  0,}, // 01
513      { 0,  0,  1,  1,}, // 10
514      { 1,  1,  3,  3 }, // 11
515   };
559516
560void s14001a_device::set_clock(int clock)
561{
562   m_stream->set_sample_rate(clock);
563}
517#define MIRROR  (uPPQtrP2&0x01)
564518
565void s14001a_device::set_volume(int volume)
566{
567   m_stream->update();
568   m_VSU1000_amp = volume;
519   // calculate increment from delta, always done even if silent to update uDeltaOld
520   // in silicon a PLA determined 0,1,3 and add/subtract and passed uDelta to uDeltaOld
521   if (!bVoicedP2 || !MIRROR)
522   {
523      uIncrementP2 = uIncrements[uDelta][uDeltaOldP2];
524      bAddP2       = uDelta >= 0x02;
525   }
526   else
527   {
528      uIncrementP2 = uIncrements[uDeltaOldP2][uDelta];
529      bAddP2       = uDeltaOldP2 < 0x02;
530   }
531   uDeltaOldP1 = uDelta;
532   if (bVoicedP2 && bPPQStartP2 && MIRROR) uIncrementP2 = 0; // no change when first starting mirroring
569533}
570534
571const device_type S14001A = &device_creator<s14001a_device>;
572
573s14001a_device::s14001a_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
574   : device_t(mconfig, S14001A, "S14001A", tag, owner, clock, "s14001a", __FILE__),
575      device_sound_interface(mconfig, *this),
576      m_SpeechRom(*this, DEVICE_SELF),
577      m_stream(nullptr),
578      m_bsy_handler(*this),
579      m_ext_read_handler(*this)
535UINT8 s14001a_device::CalculateOutput(bool bVoiced, bool bXSilence, UINT8 uPPQtr, bool bPPQStart, UINT8 uLOutput, UINT8 uIncrementP2, bool bAddP2)
580536{
581}
537   // implemented to mimic silicon (a bit)
538   // limits output to 0x00 and 0x0f
539   UINT8 uTmp; // used for subtraction
582540
583//-------------------------------------------------
584//  device_start - device-specific startup
585//-------------------------------------------------
541#define SILENCE (uPPQtr&0x02)
586542
587void s14001a_device::device_start()
588{
589   m_GlobalSilenceState = 1;
590   m_OldDelta = 0x02;
591   m_DACOutput = SILENCE;
592   m_VSU1000_amp = 15;
543   // determine output
544   if (bXSilence || (bVoiced && SILENCE)) return 7;
593545
594   for (int i = 0; i < 8; i++)
546   // beginning of a pitch period
547   if (uPPQtr == 0x00 && bPPQStart) // note this is done for voiced and nonvoiced
595548   {
596      m_filtervals[i] = SILENCE;
549      uLOutput = 7;
597550   }
598551
599   m_stream = machine().sound().stream_alloc(*this, 0, 1, clock() ? clock() : machine().sample_rate());
552   // adder
553   uTmp = uLOutput;
554   if (!bAddP2) uTmp ^= 0x0F; // turns subtraction into addition
600555
601   // resolve callbacks
602   m_ext_read_handler.resolve();
603   m_bsy_handler.resolve();
556   // add 0, 1, 3; limit at 15
557   uTmp += uIncrementP2;
558   if (uTmp > 15) uTmp = 15;
604559
605   save_item(NAME(m_WordInput));
606   save_item(NAME(m_LatchedWord));
607   save_item(NAME(m_SyllableAddress));
608   save_item(NAME(m_PhoneAddress));
609   save_item(NAME(m_PlayParams));
610   save_item(NAME(m_PhoneOffset));
611   save_item(NAME(m_LengthCounter));
612   save_item(NAME(m_RepeatCounter));
613   save_item(NAME(m_OutputCounter));
614   save_item(NAME(m_machineState));
615   save_item(NAME(m_nextstate));
616   save_item(NAME(m_laststate));
617   save_item(NAME(m_resetState));
618   save_item(NAME(m_oddeven));
619   save_item(NAME(m_GlobalSilenceState));
620   save_item(NAME(m_OldDelta));
621   save_item(NAME(m_DACOutput));
622   save_item(NAME(m_audioout));
623   save_item(NAME(m_filtervals));
624   save_item(NAME(m_VSU1000_amp));
560   if (!bAddP2) uTmp ^= 0x0F; // turns addition back to subtraction
561   return uTmp;
625562}
626563
627//-------------------------------------------------
628//  sound_stream_update - handle a stream update
629//-------------------------------------------------
630
631void s14001a_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
564void s14001a_device::ClearStatistics()
632565{
633   int i;
566   m_uNPitchPeriods = 0;
567   m_uNVoiced       = 0;
568   m_uPrintLevel    = 0;
569   m_uNControlWords = 0;
570}
634571
635   for (i = 0; i < samples; i++)
636      {
637         s14001a_clock();
638   #ifdef ACCURATE_SQUEAL
639      if (m_audioout == ALTFLAG) // input from test pins -> output
640         {
641            shiftIntoFilter(chip, audiofilter(chip)); // shift over the previous outputs and stick in audioout.
642            outputs[0][i] = audiofilter(chip)*m_VSU1000_amp;
643         }
644      else // normal, dac-driven output
645         {
646            shiftIntoFilter(chip, ((((INT16)m_audioout)-8)<<9)); // shift over the previous outputs and stick in audioout 4 times. note <<9 instead of <<10, to prevent clipping, and to simulate that the filtered output normally has a somewhat lower amplitude than the driven one.
647   #endif
648            outputs[0][i] = ((((INT16)m_audioout)-8)<<10)*m_VSU1000_amp;
649   #ifdef ACCURATE_SQUEAL
650         }
651   #endif
652      }
572void s14001a_device::GetStatistics(UINT32 &uNPitchPeriods, UINT32 &uNVoiced, UINT32 uNControlWords)
573{
574   uNPitchPeriods = m_uNPitchPeriods;
575   uNVoiced = m_uNVoiced;
576   uNControlWords = m_uNControlWords;
653577}
trunk/src/devices/sound/s14001a.h
r252893r252894
11// license:BSD-3-Clause
2// copyright-holders:Jonathan Gevaryahu,R. Belmont,Zsolt Vasvari
3#pragma once
2// copyright-holders:Ed Bernard, Jonathan Gevaryahu, hap
3// thanks-to:Kevin Horton
44/*
5    Copyright (C) 2006-2013 Jonathan Gevaryahu AKA Lord Nightmare
5    SSi TSI S14001A speech IC emulator
6*/
67
7*/
88#ifndef __S14001A_H__
99#define __S14001A_H__
1010
r252893r252894
1616
1717
1818class s14001a_device : public device_t,
19                           public device_sound_interface
19                  public device_sound_interface
2020{
2121public:
2222   s14001a_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
r252893r252894
2626   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); }
2727   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); }
2828
29   int bsy_r();        /* read BUSY pin */
30   void reg_w(int data);     /* write to input latch */
31   void rst_w(int data);     /* write to RESET pin */
32   void set_clock(int clock);     /* set VSU-1000 clock */
33   void set_volume(int volume);    /* set VSU-1000 volume control */
34   void force_update();
29   DECLARE_READ_LINE_MEMBER(busy_r);   // /BUSY (pin 40)
30   DECLARE_READ_LINE_MEMBER(romen_r);  // ROM /EN (pin 9)
31   DECLARE_WRITE_LINE_MEMBER(start_w); // START (pin 10)
32   DECLARE_WRITE8_MEMBER(data_w);      // 6-bit word
33   
34   void set_clock(UINT32 clock);       // set new CLK frequency
35   void force_update();                // update stream, eg. before external ROM bankswitch
3536
3637protected:
3738   // device-level overrides
r252893r252894
4142   virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override;
4243
4344private:
44   // internal state
4545   required_region_ptr<UINT8> m_SpeechRom;
4646   sound_stream * m_stream;
4747
4848   devcb_write_line m_bsy_handler;
4949   devcb_read8 m_ext_read_handler;
5050
51   UINT8 m_WordInput; // value on word input bus
52   UINT8 m_LatchedWord; // value latched from input bus
53   UINT16 m_SyllableAddress; // address read from word table
54   UINT16 m_PhoneAddress; // starting/current phone address from syllable table
55   UINT8 m_PlayParams; // playback parameters from syllable table
56   UINT8 m_PhoneOffset; // offset within phone
57   UINT8 m_LengthCounter; // 4-bit counter which holds the inverted length of the word in phones, leftshifted by 1
58   UINT8 m_RepeatCounter; // 3-bit counter which holds the inverted number of repeats per phone, leftshifted by 1
59   UINT8 m_OutputCounter; // 2-bit counter to determine forward/backward and output/silence state.
60   UINT8 m_machineState; // chip state machine state
61   UINT8 m_nextstate; // chip state machine's new state
62   UINT8 m_laststate; // chip state machine's previous state, needed for mirror increment masking
63   UINT8 m_resetState; // reset line state
64   UINT8 m_oddeven; // odd versus even cycle toggle
65   UINT8 m_GlobalSilenceState; // same as above but for silent syllables instead of silent portions of mirrored syllables
66   UINT8 m_OldDelta; // 2-bit old delta value
67   UINT8 m_DACOutput; // 4-bit DAC Accumulator/output
68   UINT8 m_audioout; // filtered audio output
69   INT16 m_filtervals[8];
70   UINT8 m_VSU1000_amp; // amplitude setting on VSU-1000 board
51   UINT8 readmem(UINT16 offset, bool phase);
52   bool Clock(); // called once to toggle external clock twice
7153
72   void PostPhoneme();
73   void s14001a_clock();
74   UINT8 readmem(UINT16 offset);
54   // emulator helper functions
55   UINT8 Mux8To2(bool bVoicedP2, UINT8 uPPQtrP2, UINT8 uDeltaAdrP2, UINT8 uRomDataP2);
56   void CalculateIncrement(bool bVoicedP2, UINT8 uPPQtrP2, bool bPPQStartP2, UINT8 uDeltaP2, UINT8 uDeltaOldP2, UINT8 &uDeltaOldP1, UINT8 &uIncrementP2, bool &bAddP2);
57   UINT8 CalculateOutput(bool bVoicedP2, bool bXSilenceP2, UINT8 uPPQtrP2, bool bPPQStartP2, UINT8 uLOutputP2, UINT8 uIncrementP2, bool bAddP2);
58   void ClearStatistics();
59   void GetStatistics(UINT32 &uNPitchPeriods, UINT32 &uNVoiced, UINT32 uNControlWords);
60   void SetPrintLevel(UINT32 uPrintLevel) { m_uPrintLevel = uPrintLevel; }
61
62   // internal state
63   bool m_bPhase1; // 1 bit internal clock
64
65   enum states
66   {
67      IDLE = 0,
68      WORDWAIT,
69      CWARMSB,    // read 8 CWAR MSBs
70      CWARLSB,    // read 4 CWAR LSBs from rom d7-d4
71      DARMSB,     // read 8 DAR  MSBs
72      CTRLBITS,   // read Stop, Voiced, Silence, Length, XRepeat
73      PLAY,
74      DELAY
75   };
76
77   // registers
78   states m_uStateP1;          // 3 bits
79   states m_uStateP2;
80
81   UINT16 m_uDAR13To05P1;      // 9 MSBs of delta address register
82   UINT16 m_uDAR13To05P2;      // incrementing uDAR05To13 advances ROM address by 8 bytes
83   
84   UINT16 m_uDAR04To00P1;      // 5 LSBs of delta address register
85   UINT16 m_uDAR04To00P2;      // 3 address ROM, 2 mux 8 bits of data into 2 bit delta
86                               // carry indicates end of quarter pitch period (32 cycles)
87
88   UINT16 m_uCWARP1;           // 12 bits Control Word Address Register (syllable)
89   UINT16 m_uCWARP2;
90
91   bool m_bStopP1;
92   bool m_bStopP2;
93   bool m_bVoicedP1;
94   bool m_bVoicedP2;
95   bool m_bSilenceP1;
96   bool m_bSilenceP2;
97   UINT8 m_uLengthP1;          // 7 bits, upper three loaded from ROM length
98   UINT8 m_uLengthP2;          // middle two loaded from ROM repeat and/or uXRepeat
99                               // bit 0 indicates mirror in voiced mode
100                               // bit 1 indicates internal silence in voiced mode
101                               // incremented each pitch period quarter
102
103   UINT8 m_uXRepeatP1;         // 2 bits, loaded from ROM repeat
104   UINT8 m_uXRepeatP2;
105   UINT8 m_uDeltaOldP1;        // 2 bit old delta
106   UINT8 m_uDeltaOldP2;
107   UINT8 m_uOutputP1;          // 4 bits audio output, calculated during phase 1
108
109   // derived signals
110   bool m_bDAR04To00CarryP2;
111   bool m_bPPQCarryP2;
112   bool m_bRepeatCarryP2;
113   bool m_bLengthCarryP2;
114   UINT16 m_RomAddrP1;         // rom address
115
116   // output pins
117   UINT8 m_uOutputP2;          // output changes on phase2
118   UINT16 m_uRomAddrP2;        // address pins change on phase 2
119   bool m_bBusyP1;             // busy changes on phase 1
120
121   // input pins
122   bool m_bStart;
123   UINT8 m_uWord;              // 6 bit word noumber to be spoken
124
125   // emulator variables
126   // statistics
127   UINT32 m_uNPitchPeriods;
128   UINT32 m_uNVoiced;
129   UINT32 m_uNControlWords;
130
131   // diagnostic output
132   UINT32 m_uPrintLevel;
75133};
76134
77135extern const device_type S14001A;
trunk/src/devices/sound/s14001a_new.cpp
r252893r252894
1// license:BSD-3-Clause
2// copyright-holders:Ed Bernard, Jonathan Gevaryahu, hap
3// thanks-to:Kevin Horton
4/*
5    SSi TSI S14001A speech IC emulator
6    aka CRC: Custom ROM Controller, designed in 1975, first usage in 1976 on TSI Speech+ calculator
7    Originally written for MAME by Jonathan Gevaryahu(Lord Nightmare) 2006-2013,
8    replaced with near-complete rewrite by Ed Bernard in 2016
9
10    TODO:
11    - nothing at the moment?
12
13    Further reading:
14    - http://www.vintagecalculators.com/html/speech-.html
15    - http://www.vintagecalculators.com/html/development_of_the_tsi_speech-.html
16    - http://www.vintagecalculators.com/html/speech-_state_machine.html
17    - https://archive.org/stream/pdfy-QPCSwTWiFz1u9WU_/david_djvu.txt
18*/
19
20/* Chip Pinout:
21The original datasheet (which is lost as far as I know) clearly called the
22s14001a chip the 'CRC chip', or 'Custom Rom Controller', as it appears with
23this name on the Stern and Canon schematics, as well as on some TSI speech
24print advertisements.
25Labels are not based on the labels used by the Atari wolf pack and Stern
26schematics, as these are inconsistent. Atari calls the word select/speech address
27input pins SAx while Stern calls them Cx. Also Atari and Canon both have the bit
28ordering for the word select/speech address bus backwards, which may indicate it
29was so on the original datasheet. Stern has it correct, and I've used their Cx
30labeling.
31
32                      ______    ______
33                    _|o     \__/      |_
34            +5V -- |_|1             40|_| -> /BUSY*
35                    _|                |_
36          ?TEST ?? |_|2             39|_| <- ROM D7
37                    _|                |_
38 XTAL CLOCK/CKC -> |_|3             38|_| -> ROM A11
39                    _|                |_
40  ROM CLOCK/CKR <- |_|4             37|_| <- ROM D6
41                    _|                |_
42  DIGITAL OUT 0 <- |_|5             36|_| -> ROM A10
43                    _|                |_
44  DIGITAL OUT 1 <- |_|6             35|_| -> ROM A9
45                    _|                |_
46  DIGITAL OUT 2 <- |_|7             34|_| <- ROM D5
47                    _|                |_
48  DIGITAL OUT 3 <- |_|8             33|_| -> ROM A8
49                    _|                |_
50        ROM /EN <- |_|9             32|_| <- ROM D4
51                    _|       S        |_
52          START -> |_|10 7   1   T  31|_| -> ROM A7
53                    _|   7   4   S    |_
54      AUDIO OUT <- |_|11 3   0   I  30|_| <- ROM D3
55                    _|   7   0        |_
56         ROM A0 <- |_|12     1      29|_| -> ROM A6
57                    _|       A        |_
58SPCH ADR BUS C0 -> |_|13            28|_| <- SPCH ADR BUS C5
59                    _|                |_
60         ROM A1 <- |_|14            27|_| <- ROM D2
61                    _|                |_
62SPCH ADR BUS C1 -> |_|15            26|_| <- SPCH ADR BUS C4
63                    _|                |_
64         ROM A2 <- |_|16            25|_| <- ROM D1
65                    _|                |_
66SPCH ADR BUS C2 -> |_|17            24|_| <- SPCH ADR BUS C3
67                    _|                |_
68         ROM A3 <- |_|18            23|_| <- ROM D0
69                    _|                |_
70         ROM A4 <- |_|19            22|_| -> ROM A5
71                    _|                |_
72            GND -- |_|20            21|_| -- -10V
73                     |________________|
74
75*Note from Kevin Horton when testing the hookup of the S14001A: the /BUSY line
76is not a standard voltage line: when it is in its HIGH state (i.e. not busy) it
77puts out a voltage of -10 volts, so it needs to be dropped back to a sane
78voltage level before it can be passed to any sort of modern IC. The address
79lines for the speech rom (A0-A11) do not have this problem, they output at a
80TTL/CMOS compatible voltage. The AUDIO OUT pin also outputs a voltage below GND,
81and the TEST pins may do so too.
82
83START is pulled high when a word is to be said and the word number is on the
84word select/speech address input lines. The Canon 'Canola' uses a separate 'rom
85strobe' signal independent of the chip to either enable or clock the speech rom.
86It's likely that they did this to be able to force the speech chip to stop talking,
87which is normally impossible. The later 'version 3' TSI speech board as featured in
88an advertisement in the John Cater book probably also has this feature, in addition
89to external speech rom banking.
90
91The Digital out pins supply a copy of the 4-bit waveform which also goes to the
92internal DAC. They are only valid every other clock cycle. It is possible that
93on 'invalid' cycles they act as a 4 bit input to drive the dac.
94
95Because it requires -10V to operate, the chip manufacturing process must be PMOS.
96
97* Operation:
98Put the 6-bit address of the word to be said onto the C0-C5 word select/speech
99address bus lines. Next, clock the START line low-high-low. As long as the START
100line is held high, the first address byte of the first word will be read repeatedly
101every clock, with the rom enable line enabled constantly (i.e. it doesn't toggle on
102and off as it normally does during speech). Once START has gone low-high-low, the
103/BUSY line will go low until 3 clocks after the chip is done speaking.
104*/
105
106#include "emu.h"
107#include "s14001a_new.h"
108
109// device definition
110const device_type S14001A_NEW = &device_creator<s14001a_new_device>;
111
112s14001a_new_device::s14001a_new_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
113   : device_t(mconfig, S14001A_NEW, "S14001A_NEW", tag, owner, clock, "s14001a_new", __FILE__),
114      device_sound_interface(mconfig, *this),
115      m_SpeechRom(*this, DEVICE_SELF),
116      m_stream(nullptr),
117      m_bsy_handler(*this),
118      m_ext_read_handler(*this)
119{
120}
121
122//-------------------------------------------------
123//  device_start - device-specific startup
124//-------------------------------------------------
125
126ALLOW_SAVE_TYPE(s14001a_new_device::states); // allow save_item on a non-fundamental type
127
128void s14001a_new_device::device_start()
129{
130   m_stream = machine().sound().stream_alloc(*this, 0, 1, clock() ? clock() : machine().sample_rate());
131
132   // resolve callbacks
133   m_ext_read_handler.resolve();
134   m_bsy_handler.resolve();
135   
136   // note: zerofill is done already by MAME core
137   ClearStatistics();
138   m_uOutputP1 = m_uOutputP2 = 7;
139   
140   // register for savestates
141   save_item(NAME(m_bPhase1));
142   save_item(NAME(m_uStateP1));
143   save_item(NAME(m_uStateP2));
144   save_item(NAME(m_uDAR13To05P1));
145   save_item(NAME(m_uDAR13To05P2));
146   save_item(NAME(m_uDAR04To00P1));
147   save_item(NAME(m_uDAR04To00P2));
148   save_item(NAME(m_uCWARP1));
149   save_item(NAME(m_uCWARP2));
150
151   save_item(NAME(m_bStopP1));
152   save_item(NAME(m_bStopP2));
153   save_item(NAME(m_bVoicedP1));
154   save_item(NAME(m_bVoicedP2));
155   save_item(NAME(m_bSilenceP1));
156   save_item(NAME(m_bSilenceP2));
157   save_item(NAME(m_uLengthP1));
158   save_item(NAME(m_uLengthP2));
159   save_item(NAME(m_uXRepeatP1));
160   save_item(NAME(m_uXRepeatP2));
161   save_item(NAME(m_uDeltaOldP1));
162   save_item(NAME(m_uDeltaOldP2));
163   save_item(NAME(m_uOutputP1));
164
165   save_item(NAME(m_bDAR04To00CarryP2));
166   save_item(NAME(m_bPPQCarryP2));
167   save_item(NAME(m_bRepeatCarryP2));
168   save_item(NAME(m_bLengthCarryP2));
169   save_item(NAME(m_RomAddrP1));
170
171   save_item(NAME(m_uOutputP2));
172   save_item(NAME(m_uRomAddrP2));
173   save_item(NAME(m_bBusyP1));
174   save_item(NAME(m_bStart));
175   save_item(NAME(m_uWord));
176
177   save_item(NAME(m_uNPitchPeriods));
178   save_item(NAME(m_uNVoiced));
179   save_item(NAME(m_uNControlWords));
180   save_item(NAME(m_uPrintLevel));
181}
182
183
184//-------------------------------------------------
185//  sound_stream_update - handle a stream update
186//-------------------------------------------------
187
188void s14001a_new_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
189{
190   for (int i = 0; i < samples; i++)
191   {
192      Clock();
193      INT16 sample = m_uOutputP2 - 7; // range -7..8
194      outputs[0][i] = sample * 0xf00;
195   }
196}
197
198
199/**************************************************************************
200    External interface
201**************************************************************************/
202
203void s14001a_new_device::force_update()
204{
205   m_stream->update();
206}
207
208READ_LINE_MEMBER(s14001a_new_device::romen_r)
209{
210   m_stream->update();
211   return (m_bPhase1) ? 1 : 0;
212}
213
214READ_LINE_MEMBER(s14001a_new_device::busy_r)
215{
216   m_stream->update();
217   return (m_bBusyP1) ? 1 : 0;
218}
219
220WRITE8_MEMBER(s14001a_new_device::data_w)
221{
222   m_stream->update();
223   m_uWord = data & 0x3f; // C0-C5
224}
225
226WRITE_LINE_MEMBER(s14001a_new_device::start_w)
227{
228   m_stream->update();
229   m_bStart = (state != 0);
230   if (m_bStart) m_uStateP1 = WORDWAIT;
231}
232
233void s14001a_new_device::set_clock(UINT32 clock)
234{
235   m_stream->update();
236   m_stream->set_sample_rate(clock);
237}
238
239
240/**************************************************************************
241    Device emulation
242**************************************************************************/
243
244UINT8 s14001a_new_device::readmem(UINT16 offset, bool phase)
245{
246   offset &= 0xfff; // 11-bit internal
247   return ((m_ext_read_handler.isnull()) ? m_SpeechRom[offset & (m_SpeechRom.bytes() - 1)] : m_ext_read_handler(offset));
248}
249
250bool s14001a_new_device::Clock()
251{
252   // effectively toggles external clock twice, one cycle
253   // internal clock toggles on external clock transition from 0 to 1 so internal clock will always transition here
254   // return false if some emulator problem detected
255
256   // On the actual chip, all register phase 1 values needed to be refreshed from phase 2 values
257   // or else risk losing their state due to charge loss.
258   // But on a computer the values are static.
259   // So to reduce code clutter, phase 1 values are only modified if they are different
260   // from the preceeding phase 2 values.
261
262   if (m_bPhase1)
263   {
264      // transition to phase2
265      m_bPhase1 = false;
266
267      // transfer phase1 variables to phase2
268      m_uStateP2     = m_uStateP1;
269      m_uDAR13To05P2 = m_uDAR13To05P1;
270      m_uDAR04To00P2 = m_uDAR04To00P1;
271      m_uCWARP2      = m_uCWARP1;
272      m_bStopP2      = m_bStopP1;
273      m_bVoicedP2    = m_bVoicedP1;
274      m_bSilenceP2   = m_bSilenceP1;
275      m_uLengthP2    = m_uLengthP1;
276      m_uXRepeatP2   = m_uXRepeatP1;
277      m_uDeltaOldP2  = m_uDeltaOldP1;
278
279      m_uOutputP2    = m_uOutputP1;
280      m_uRomAddrP2   = m_RomAddrP1;
281
282      // setup carries from phase 2 values
283      m_bDAR04To00CarryP2  = m_uDAR04To00P2 == 0x1F;
284      m_bPPQCarryP2        = m_bDAR04To00CarryP2 && ((m_uLengthP2&0x03) == 0x03); // pitch period quarter
285      m_bRepeatCarryP2     = m_bPPQCarryP2       && ((m_uLengthP2&0x0C) == 0x0C);
286      m_bLengthCarryP2     = m_bRepeatCarryP2    && ( m_uLengthP2       == 0x7F);
287
288      return true;
289   }
290   m_bPhase1 = true;
291
292   // logic done during phase 1
293   switch (m_uStateP1)
294   {
295   case IDLE:
296      m_uOutputP1 = 7;
297      if (m_bStart) m_uStateP1 = WORDWAIT;
298
299      if (m_bBusyP1 && !m_bsy_handler.isnull())
300         m_bsy_handler(0);
301      m_bBusyP1 = false;
302      break;
303
304   case WORDWAIT:
305      // the delta address register latches the word number into bits 03 to 08
306      // all other bits forced to 0.  04 to 08 makes a multiply by two.
307      m_uDAR13To05P1 = (m_uWord&0x3C)>>2;
308      m_uDAR04To00P1 = (m_uWord&0x03)<<3;
309      m_RomAddrP1 = (m_uDAR13To05P1<<3)|(m_uDAR04To00P1>>2); // remove lower two bits
310      m_uOutputP1 = 7;
311      if (m_bStart) m_uStateP1 = WORDWAIT;
312      else          m_uStateP1 = CWARMSB;
313
314      if (!m_bBusyP1 && !m_bsy_handler.isnull())
315         m_bsy_handler(1);
316      m_bBusyP1 = true;
317      break;
318
319   case CWARMSB:
320      if (m_uPrintLevel >= 1)
321         printf("\n speaking word %02x",m_uWord);
322
323      // use uDAR to load uCWAR 8 msb
324      m_uCWARP1 = readmem(m_uRomAddrP2,m_bPhase1)<<4; // note use of rom address setup in previous state
325      // increment DAR by 4, 2 lsb's count deltas within a byte
326      m_uDAR04To00P1 += 4;
327      if (m_uDAR04To00P1 >= 32) m_uDAR04To00P1 = 0; // emulate 5 bit counter
328      m_RomAddrP1 = (m_uDAR13To05P1<<3)|(m_uDAR04To00P1>>2); // remove lower two bits
329
330      m_uOutputP1 = 7;
331      if (m_bStart) m_uStateP1 = WORDWAIT;
332      else          m_uStateP1 = CWARLSB;
333      break;
334
335   case CWARLSB:
336      m_uCWARP1   = m_uCWARP2|(readmem(m_uRomAddrP2,m_bPhase1)>>4); // setup in previous state
337      m_RomAddrP1 = m_uCWARP1;
338
339      m_uOutputP1 = 7;
340      if (m_bStart) m_uStateP1 = WORDWAIT;
341      else          m_uStateP1 = DARMSB;
342      break;
343
344   case DARMSB:
345      m_uDAR13To05P1 = readmem(m_uRomAddrP2,m_bPhase1)<<1; // 9 bit counter, 8 MSBs from ROM, lsb zeroed
346      m_uDAR04To00P1 = 0;
347      m_uCWARP1++;
348      m_RomAddrP1 = m_uCWARP1;
349      m_uNControlWords++; // statistics
350
351      m_uOutputP1 = 7;
352      if (m_bStart) m_uStateP1 = WORDWAIT;
353      else          m_uStateP1 = CTRLBITS;
354      break;
355
356   case CTRLBITS:
357      m_bStopP1    = readmem(m_uRomAddrP2,m_bPhase1)&0x80? true: false;
358      m_bVoicedP1  = readmem(m_uRomAddrP2,m_bPhase1)&0x40? true: false;
359      m_bSilenceP1 = readmem(m_uRomAddrP2,m_bPhase1)&0x20? true: false;
360      m_uXRepeatP1 = readmem(m_uRomAddrP2,m_bPhase1)&0x03;
361      m_uLengthP1  =(readmem(m_uRomAddrP2,m_bPhase1)&0x1F)<<2; // includes external length and repeat
362      m_uDAR04To00P1 = 0;
363      m_uCWARP1++; // gets ready for next DARMSB
364      m_RomAddrP1  = (m_uDAR13To05P1<<3)|(m_uDAR04To00P1>>2); // remove lower two bits
365
366      m_uOutputP1 = 7;
367      if (m_bStart) m_uStateP1 = WORDWAIT;
368      else          m_uStateP1 = PLAY;
369
370      if (m_uPrintLevel >= 2)
371         printf("\n cw %d %d %d %d %d",m_bStopP1,m_bVoicedP1,m_bSilenceP1,m_uLengthP1>>4,m_uXRepeatP1);
372
373      break;
374
375   case PLAY:
376   {
377      // statistics
378      if (m_bPPQCarryP2)
379      {
380         // pitch period end
381         if (m_uPrintLevel >= 3)
382            printf("\n ppe: RomAddr %03x",m_uRomAddrP2);
383
384         m_uNPitchPeriods++;
385         if (m_bVoicedP2) m_uNVoiced++;
386      }
387      // end statistics
388
389      // modify output
390      UINT8 uDeltaP2;     // signal line
391      UINT8 uIncrementP2; // signal lines
392      bool bAddP2;        // signal line
393      uDeltaP2 = Mux8To2(m_bVoicedP2,
394               m_uLengthP2 & 0x03,     // pitch period quater counter
395               m_uDAR04To00P2 & 0x03,  // two bit delta address within byte
396               readmem(m_uRomAddrP2,m_bPhase1)
397      );
398      CalculateIncrement(m_bVoicedP2,
399               m_uLengthP2 & 0x03,     // pitch period quater counter
400               m_uDAR04To00P2 == 0,    // pitch period quarter start
401               uDeltaP2,
402               m_uDeltaOldP2,          // input
403               m_uDeltaOldP1,          // output
404               uIncrementP2,           // output 0, 1, or 3
405               bAddP2                  // output
406      );
407      m_uOutputP1 = CalculateOutput(m_bVoicedP2,
408               m_bSilenceP2,
409               m_uLengthP2 & 0x03,     // pitch period quater counter
410               m_uDAR04To00P2 == 0,    // pitch period quarter start
411               m_uOutputP2,            // last output
412               uIncrementP2,
413               bAddP2
414      );
415
416      // advance counters
417      m_uDAR04To00P1++;
418      if (m_bDAR04To00CarryP2) // pitch period quarter end
419      {
420         m_uDAR04To00P1 = 0; // emulate 5 bit counter
421
422         m_uLengthP1++; // lower two bits of length count quarter pitch periods
423         if (m_uLengthP1 >= 0x80)
424         {
425            m_uLengthP1 = 0; // emulate 7 bit counter
426         }
427      }
428
429      if (m_bVoicedP2 && m_bRepeatCarryP2) // repeat complete
430      {
431         m_uLengthP1 &= 0x70; // keep current "length"
432         m_uLengthP1 |= (m_uXRepeatP1<<2); // load repeat from external repeat
433         m_uDAR13To05P1++; // advances ROM address 8 bytes
434         if (m_uDAR13To05P1 >= 0x200) m_uDAR13To05P1 = 0; // emulate 9 bit counter
435      }
436      if (!m_bVoicedP2 && m_bDAR04To00CarryP2)
437      {
438         // unvoiced advances each quarter pitch period
439         // note repeat counter not reloaded for non voiced speech
440         m_uDAR13To05P1++; // advances ROM address 8 bytes
441         if (m_uDAR13To05P1 >= 0x200) m_uDAR13To05P1 = 0; // emulate 9 bit counter
442      }
443
444      // construct m_RomAddrP1
445      m_RomAddrP1 = m_uDAR04To00P1;
446      if (m_bVoicedP2 && m_uLengthP1&0x1) // mirroring
447      {
448         m_RomAddrP1 ^= 0x1f; // count backwards
449      }
450      m_RomAddrP1 = (m_uDAR13To05P1<<3) | m_RomAddrP1>>2;
451
452      // next state
453      if (m_bStart) m_uStateP1 = WORDWAIT;
454      else if (m_bStopP2 && m_bLengthCarryP2) m_uStateP1 = DELAY;
455      else if (m_bLengthCarryP2)
456      {
457         m_uStateP1  = DARMSB;
458         m_RomAddrP1 = m_uCWARP1; // output correct address
459      }
460      else m_uStateP1 = PLAY;
461      break;
462   }
463
464   case DELAY:
465      m_uOutputP1 = 7;
466      if (m_bStart) m_uStateP1 = WORDWAIT;
467      else          m_uStateP1 = IDLE;
468      break;
469   }
470
471   return true;
472}
473
474UINT8 s14001a_new_device::Mux8To2(bool bVoicedP2, UINT8 uPPQtrP2, UINT8 uDeltaAdrP2, UINT8 uRomDataP2)
475{
476   // pick two bits of rom data as delta
477
478   if (bVoicedP2 && uPPQtrP2&0x01) // mirroring
479   {
480      uDeltaAdrP2 ^= 0x03; // count backwards
481   }
482   // emulate 8 to 2 mux to obtain delta from byte (bigendian)
483   switch (uDeltaAdrP2)
484   {
485   case 0x00:
486      return (uRomDataP2&0xC0)>>6;
487   case 0x01:
488      return (uRomDataP2&0x30)>>4;
489   case 0x02:
490      return (uRomDataP2&0x0C)>>2;
491   case 0x03:
492      return (uRomDataP2&0x03)>>0;
493   }
494   return 0xFF;
495}
496
497void s14001a_new_device::CalculateIncrement(bool bVoicedP2, UINT8 uPPQtrP2, bool bPPQStartP2, UINT8 uDelta, UINT8 uDeltaOldP2, UINT8 &uDeltaOldP1, UINT8 &uIncrementP2, bool &bAddP2)
498{
499   // uPPQtr, pitch period quarter counter; 2 lsb of uLength
500   // bPPStart, start of a pitch period
501   // implemented to mimic silicon (a bit)
502
503   // beginning of a pitch period
504   if (uPPQtrP2 == 0x00 && bPPQStartP2) // note this is done for voiced and unvoiced
505   {
506      uDeltaOldP2 = 0x02;
507   }
508   static const UINT8 uIncrements[4][4] =
509   {
510   //    00  01  10  11
511      { 3,  3,  1,  1,}, // 00
512      { 1,  1,  0,  0,}, // 01
513      { 0,  0,  1,  1,}, // 10
514      { 1,  1,  3,  3 }, // 11
515   };
516
517#define MIRROR  (uPPQtrP2&0x01)
518
519   // calculate increment from delta, always done even if silent to update uDeltaOld
520   // in silicon a PLA determined 0,1,3 and add/subtract and passed uDelta to uDeltaOld
521   if (!bVoicedP2 || !MIRROR)
522   {
523      uIncrementP2 = uIncrements[uDelta][uDeltaOldP2];
524      bAddP2       = uDelta >= 0x02;
525   }
526   else
527   {
528      uIncrementP2 = uIncrements[uDeltaOldP2][uDelta];
529      bAddP2       = uDeltaOldP2 < 0x02;
530   }
531   uDeltaOldP1 = uDelta;
532   if (bVoicedP2 && bPPQStartP2 && MIRROR) uIncrementP2 = 0; // no change when first starting mirroring
533}
534
535UINT8 s14001a_new_device::CalculateOutput(bool bVoiced, bool bXSilence, UINT8 uPPQtr, bool bPPQStart, UINT8 uLOutput, UINT8 uIncrementP2, bool bAddP2)
536{
537   // implemented to mimic silicon (a bit)
538   // limits output to 0x00 and 0x0f
539   UINT8 uTmp; // used for subtraction
540
541#define SILENCE (uPPQtr&0x02)
542
543   // determine output
544   if (bXSilence || (bVoiced && SILENCE)) return 7;
545
546   // beginning of a pitch period
547   if (uPPQtr == 0x00 && bPPQStart) // note this is done for voiced and nonvoiced
548   {
549      uLOutput = 7;
550   }
551
552   // adder
553   uTmp = uLOutput;
554   if (!bAddP2) uTmp ^= 0x0F; // turns subtraction into addition
555
556   // add 0, 1, 3; limit at 15
557   uTmp += uIncrementP2;
558   if (uTmp > 15) uTmp = 15;
559
560   if (!bAddP2) uTmp ^= 0x0F; // turns addition back to subtraction
561   return uTmp;
562}
563
564void s14001a_new_device::ClearStatistics()
565{
566   m_uNPitchPeriods = 0;
567   m_uNVoiced       = 0;
568   m_uPrintLevel    = 0;
569   m_uNControlWords = 0;
570}
571
572void s14001a_new_device::GetStatistics(UINT32 &uNPitchPeriods, UINT32 &uNVoiced, UINT32 uNControlWords)
573{
574   uNPitchPeriods = m_uNPitchPeriods;
575   uNVoiced = m_uNVoiced;
576   uNControlWords = m_uNControlWords;
577}
trunk/src/devices/sound/s14001a_new.h
r252893r252894
1// license:BSD-3-Clause
2// copyright-holders:Ed Bernard, Jonathan Gevaryahu, hap
3// thanks-to:Kevin Horton
4/*
5    SSi TSI S14001A speech IC emulator
6*/
7
8#ifndef __S14001A_H__
9#define __S14001A_H__
10
11#define MCFG_S14001A_BSY_HANDLER(_devcb) \
12   devcb = &s14001a_new_device::set_bsy_handler(*device, DEVCB_##_devcb);
13
14#define MCFG_S14001A_EXT_READ_HANDLER(_devcb) \
15   devcb = &s14001a_new_device::set_ext_read_handler(*device, DEVCB_##_devcb);
16
17
18class s14001a_new_device : public device_t,
19                  public device_sound_interface
20{
21public:
22   s14001a_new_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
23   ~s14001a_new_device() {}
24
25   // static configuration helpers
26   template<class _Object> static devcb_base &set_bsy_handler(device_t &device, _Object object) { return downcast<s14001a_new_device &>(device).m_bsy_handler.set_callback(object); }
27   template<class _Object> static devcb_base &set_ext_read_handler(device_t &device, _Object object) { return downcast<s14001a_new_device &>(device).m_ext_read_handler.set_callback(object); }
28
29   DECLARE_READ_LINE_MEMBER(busy_r);   // /BUSY (pin 40)
30   DECLARE_READ_LINE_MEMBER(romen_r);  // ROM /EN (pin 9)
31   DECLARE_WRITE_LINE_MEMBER(start_w); // START (pin 10)
32   DECLARE_WRITE8_MEMBER(data_w);      // 6-bit word
33   
34   void set_clock(UINT32 clock);       // set new CLK frequency
35   void force_update();                // update stream, eg. before external ROM bankswitch
36
37protected:
38   // device-level overrides
39   virtual void device_start() override;
40
41   // sound stream update overrides
42   virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override;
43
44private:
45   required_region_ptr<UINT8> m_SpeechRom;
46   sound_stream * m_stream;
47
48   devcb_write_line m_bsy_handler;
49   devcb_read8 m_ext_read_handler;
50
51   UINT8 readmem(UINT16 offset, bool phase);
52   bool Clock(); // called once to toggle external clock twice
53
54   // emulator helper functions
55   UINT8 Mux8To2(bool bVoicedP2, UINT8 uPPQtrP2, UINT8 uDeltaAdrP2, UINT8 uRomDataP2);
56   void CalculateIncrement(bool bVoicedP2, UINT8 uPPQtrP2, bool bPPQStartP2, UINT8 uDeltaP2, UINT8 uDeltaOldP2, UINT8 &uDeltaOldP1, UINT8 &uIncrementP2, bool &bAddP2);
57   UINT8 CalculateOutput(bool bVoicedP2, bool bXSilenceP2, UINT8 uPPQtrP2, bool bPPQStartP2, UINT8 uLOutputP2, UINT8 uIncrementP2, bool bAddP2);
58   void ClearStatistics();
59   void GetStatistics(UINT32 &uNPitchPeriods, UINT32 &uNVoiced, UINT32 uNControlWords);
60   void SetPrintLevel(UINT32 uPrintLevel) { m_uPrintLevel = uPrintLevel; }
61
62   // internal state
63   bool m_bPhase1; // 1 bit internal clock
64
65   enum states
66   {
67      IDLE = 0,
68      WORDWAIT,
69      CWARMSB,    // read 8 CWAR MSBs
70      CWARLSB,    // read 4 CWAR LSBs from rom d7-d4
71      DARMSB,     // read 8 DAR  MSBs
72      CTRLBITS,   // read Stop, Voiced, Silence, Length, XRepeat
73      PLAY,
74      DELAY
75   };
76
77   // registers
78   states m_uStateP1;          // 3 bits
79   states m_uStateP2;
80
81   UINT16 m_uDAR13To05P1;      // 9 MSBs of delta address register
82   UINT16 m_uDAR13To05P2;      // incrementing uDAR05To13 advances ROM address by 8 bytes
83   
84   UINT16 m_uDAR04To00P1;      // 5 LSBs of delta address register
85   UINT16 m_uDAR04To00P2;      // 3 address ROM, 2 mux 8 bits of data into 2 bit delta
86                               // carry indicates end of quarter pitch period (32 cycles)
87
88   UINT16 m_uCWARP1;           // 12 bits Control Word Address Register (syllable)
89   UINT16 m_uCWARP2;
90
91   bool m_bStopP1;
92   bool m_bStopP2;
93   bool m_bVoicedP1;
94   bool m_bVoicedP2;
95   bool m_bSilenceP1;
96   bool m_bSilenceP2;
97   UINT8 m_uLengthP1;          // 7 bits, upper three loaded from ROM length
98   UINT8 m_uLengthP2;          // middle two loaded from ROM repeat and/or uXRepeat
99                               // bit 0 indicates mirror in voiced mode
100                               // bit 1 indicates internal silence in voiced mode
101                               // incremented each pitch period quarter
102
103   UINT8 m_uXRepeatP1;         // 2 bits, loaded from ROM repeat
104   UINT8 m_uXRepeatP2;
105   UINT8 m_uDeltaOldP1;        // 2 bit old delta
106   UINT8 m_uDeltaOldP2;
107   UINT8 m_uOutputP1;          // 4 bits audio output, calculated during phase 1
108
109   // derived signals
110   bool m_bDAR04To00CarryP2;
111   bool m_bPPQCarryP2;
112   bool m_bRepeatCarryP2;
113   bool m_bLengthCarryP2;
114   UINT16 m_RomAddrP1;         // rom address
115
116   // output pins
117   UINT8 m_uOutputP2;          // output changes on phase2
118   UINT16 m_uRomAddrP2;        // address pins change on phase 2
119   bool m_bBusyP1;             // busy changes on phase 1
120
121   // input pins
122   bool m_bStart;
123   UINT8 m_uWord;              // 6 bit word noumber to be spoken
124
125   // emulator variables
126   // statistics
127   UINT32 m_uNPitchPeriods;
128   UINT32 m_uNVoiced;
129   UINT32 m_uNControlWords;
130
131   // diagnostic output
132   UINT32 m_uPrintLevel;
133};
134
135extern const device_type S14001A_NEW;
136
137
138#endif /* __S14001A_H__ */
trunk/src/devices/sound/scsp.cpp
r252893r252894
149149      m_roffset(0),
150150      m_irq_cb(*this),
151151      m_main_irq_cb(*this),
152      m_ram_region(*this, DEVICE_SELF),
153152      m_BUFPTR(0),
154153      m_SCSPRAM(nullptr),
155154      m_SCSPRAM_LENGTH(0),
r252893r252894
516515      m_Master = 0;
517516   }
518517
519   if (m_ram_region != NULL)
518   memory_region* ram_region = memregion(tag());
519   
520   // coolridr.c defines a region for the RAM, stv.c doesn't (uses set_ram_base instead, which seems to be more correct anyway?)
521   if (ram_region != NULL)
520522   {
521      m_SCSPRAM = m_ram_region->base();
522      m_SCSPRAM_LENGTH = m_ram_region->bytes();
523      m_SCSPRAM = ram_region->base();
524      m_SCSPRAM_LENGTH = ram_region->bytes();
523525      m_DSP.SCSPRAM = (UINT16 *)m_SCSPRAM;
524526      m_DSP.SCSPRAM_LENGTH = m_SCSPRAM_LENGTH / 2;
525527      m_SCSPRAM += m_roffset;
trunk/src/devices/sound/scsp.h
r252893r252894
104104   int m_roffset;                /* offset in the region */
105105   devcb_write8       m_irq_cb;  /* irq callback */
106106   devcb_write_line   m_main_irq_cb;
107   required_memory_region m_ram_region;
108107
109108   union
110109   {
trunk/src/mame/drivers/berzerk.cpp
r252893r252894
1515#include "audio/exidy.h"
1616#include "machine/74181.h"
1717#include "machine/nvram.h"
18#include "sound/s14001a_new.h"
18#include "sound/s14001a.h"
1919#include "video/resnet.h"
2020
2121
r252893r252894
3535   { }
3636
3737   required_device<cpu_device> m_maincpu;
38   required_device<s14001a_new_device> m_s14001a;
38   required_device<s14001a_device> m_s14001a;
3939   required_device<ttl74181_device> m_ls181_10c;
4040   required_device<ttl74181_device> m_ls181_12c;
4141   required_device<exidy_sound_device> m_custom;
r252893r252894
11201120   /* audio hardware */
11211121   MCFG_SPEAKER_STANDARD_MONO("mono")
11221122
1123   MCFG_SOUND_ADD("speech", S14001A_NEW, S14001_CLOCK/16/8) /* placeholder - the clock is software controllable */
1123   MCFG_SOUND_ADD("speech", S14001A, S14001_CLOCK/16/8) /* placeholder - the clock is software controllable */
11241124   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
11251125   MCFG_SOUND_ADD("exidy", EXIDY, 0)
11261126   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.33)
trunk/src/mame/drivers/fidel6502.cpp
r252893r252894
332332
333333   /* sound hardware */
334334   MCFG_SPEAKER_STANDARD_MONO("mono")
335   MCFG_SOUND_ADD("speech", S14001A_NEW, 25000) // around 25khz
335   MCFG_SOUND_ADD("speech", S14001A, 25000) // around 25khz
336336   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.75)
337337MACHINE_CONFIG_END
338338
trunk/src/mame/drivers/fidelz80.cpp
r252893r252894
14301430
14311431   /* sound hardware */
14321432   MCFG_SPEAKER_STANDARD_MONO("mono")
1433   MCFG_SOUND_ADD("speech", S14001A_NEW, 25000) // R/C circuit, around 25khz
1433   MCFG_SOUND_ADD("speech", S14001A, 25000) // R/C circuit, around 25khz
14341434   MCFG_S14001A_EXT_READ_HANDLER(READ8(fidelz80_state, vcc_speech_r))
14351435   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.75)
14361436MACHINE_CONFIG_END
r252893r252894
14581458
14591459   /* sound hardware */
14601460   MCFG_SPEAKER_STANDARD_MONO("mono")
1461   MCFG_SOUND_ADD("speech", S14001A_NEW, 25000) // R/C circuit, around 25khz
1461   MCFG_SOUND_ADD("speech", S14001A, 25000) // R/C circuit, around 25khz
14621462   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.75)
14631463
14641464   MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0)
r252893r252894
14831483
14841484   /* sound hardware */
14851485   MCFG_SPEAKER_STANDARD_MONO("mono")
1486   MCFG_SOUND_ADD("speech", S14001A_NEW, 25000) // R/C circuit, around 25khz
1486   MCFG_SOUND_ADD("speech", S14001A, 25000) // R/C circuit, around 25khz
14871487   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.75)
14881488MACHINE_CONFIG_END
14891489
r252893r252894
14951495
14961496ROM_START( cc10 )
14971497   ROM_REGION( 0x10000, "maincpu", 0 )
1498   ROM_LOAD( "cc10.bin", 0x0000, 0x1000, CRC(bb9e6055) SHA1(18276e57cf56465a6352239781a828c5f3d5ba63) )
1498   ROM_LOAD( "cc10.bin", 0x0000, 0x1000, BAD_DUMP CRC(bb9e6055) SHA1(18276e57cf56465a6352239781a828c5f3d5ba63) ) // second half empty
14991499ROM_END
15001500
15011501
r252893r252894
15121512
15131513ROM_START( vccg )
15141514   ROM_REGION( 0x10000, "maincpu", 0 )
1515   ROM_LOAD("101-32103.bin", 0x0000, 0x1000, CRC(257bb5ab) SHA1(f7589225bb8e5f3eac55f23e2bd526be780b38b5) ) // 32014.VCC??? at location b3?
1516   ROM_LOAD("vcc2.bin", 0x1000, 0x1000, CRC(f33095e7) SHA1(692fcab1b88c910b74d04fe4d0660367aee3f4f0) ) // at location a2?
1517   ROM_LOAD("vcc3.bin", 0x2000, 0x1000, CRC(624f0cd5) SHA1(7c1a4f4497fe5882904de1d6fecf510c07ee6fc6) ) // at location a1?
1515   ROM_LOAD("101-32103.bin", 0x0000, 0x1000, CRC(257bb5ab) SHA1(f7589225bb8e5f3eac55f23e2bd526be780b38b5) )
1516   ROM_LOAD("vcc2.bin", 0x1000, 0x1000, CRC(f33095e7) SHA1(692fcab1b88c910b74d04fe4d0660367aee3f4f0) )
1517   ROM_LOAD("vcc3.bin", 0x2000, 0x1000, CRC(624f0cd5) SHA1(7c1a4f4497fe5882904de1d6fecf510c07ee6fc6) )
15181518
15191519   ROM_REGION( 0x2000, "speech", 0 )
1520   ROM_LOAD("vcc-german.bin", 0x0000, 0x2000, BAD_DUMP CRC(6c85e310) SHA1(20d1d6543c1e6a1f04184a2df2a468f33faec3ff) ) // at location c4?
1520   ROM_LOAD("vcc-german.bin", 0x0000, 0x2000, BAD_DUMP CRC(6c85e310) SHA1(20d1d6543c1e6a1f04184a2df2a468f33faec3ff) ) // taken from fexcelv
15211521ROM_END
15221522
15231523ROM_START( vccfr )
15241524   ROM_REGION( 0x10000, "maincpu", 0 )
1525   ROM_LOAD("101-32103.bin", 0x0000, 0x1000, CRC(257bb5ab) SHA1(f7589225bb8e5f3eac55f23e2bd526be780b38b5) ) // 32014.VCC??? at location b3?
1526   ROM_LOAD("vcc2.bin", 0x1000, 0x1000, CRC(f33095e7) SHA1(692fcab1b88c910b74d04fe4d0660367aee3f4f0) ) // at location a2?
1527   ROM_LOAD("vcc3.bin", 0x2000, 0x1000, CRC(624f0cd5) SHA1(7c1a4f4497fe5882904de1d6fecf510c07ee6fc6) ) // at location a1?
1525   ROM_LOAD("101-32103.bin", 0x0000, 0x1000, CRC(257bb5ab) SHA1(f7589225bb8e5f3eac55f23e2bd526be780b38b5) )
1526   ROM_LOAD("vcc2.bin", 0x1000, 0x1000, CRC(f33095e7) SHA1(692fcab1b88c910b74d04fe4d0660367aee3f4f0) )
1527   ROM_LOAD("vcc3.bin", 0x2000, 0x1000, CRC(624f0cd5) SHA1(7c1a4f4497fe5882904de1d6fecf510c07ee6fc6) )
15281528
15291529   ROM_REGION( 0x2000, "speech", 0 )
1530   ROM_LOAD("vcc-french.bin", 0x0000, 0x2000, BAD_DUMP CRC(fe8c5c18) SHA1(2b64279ab3747ee81c86963c13e78321c6cfa3a3) ) // at location c4?
1530   ROM_LOAD("vcc-french.bin", 0x0000, 0x2000, BAD_DUMP CRC(fe8c5c18) SHA1(2b64279ab3747ee81c86963c13e78321c6cfa3a3) ) // taken from fexcelv
15311531ROM_END
15321532
15331533ROM_START( vccsp )
15341534   ROM_REGION( 0x10000, "maincpu", 0 )
1535   ROM_LOAD("101-32103.bin", 0x0000, 0x1000, CRC(257bb5ab) SHA1(f7589225bb8e5f3eac55f23e2bd526be780b38b5) ) // 32014.VCC??? at location b3?
1536   ROM_LOAD("vcc2.bin", 0x1000, 0x1000, CRC(f33095e7) SHA1(692fcab1b88c910b74d04fe4d0660367aee3f4f0) ) // at location a2?
1537   ROM_LOAD("vcc3.bin", 0x2000, 0x1000, CRC(624f0cd5) SHA1(7c1a4f4497fe5882904de1d6fecf510c07ee6fc6) ) // at location a1?
1535   ROM_LOAD("101-32103.bin", 0x0000, 0x1000, CRC(257bb5ab) SHA1(f7589225bb8e5f3eac55f23e2bd526be780b38b5) )
1536   ROM_LOAD("vcc2.bin", 0x1000, 0x1000, CRC(f33095e7) SHA1(692fcab1b88c910b74d04fe4d0660367aee3f4f0) )
1537   ROM_LOAD("vcc3.bin", 0x2000, 0x1000, CRC(624f0cd5) SHA1(7c1a4f4497fe5882904de1d6fecf510c07ee6fc6) )
15381538
15391539   ROM_REGION( 0x2000, "speech", 0 )
1540   ROM_LOAD("vcc-spanish.bin", 0x0000, 0x2000, CRC(8766e128) SHA1(78c7413bf240159720b131ab70bfbdf4e86eb1e9) ) // at location c4?
1540   ROM_LOAD("vcc-spanish.bin", 0x0000, 0x2000, CRC(8766e128) SHA1(78c7413bf240159720b131ab70bfbdf4e86eb1e9) )
15411541ROM_END
15421542
15431543
trunk/src/mame/drivers/psychic5.cpp
r252893r252894
714714
715715   /* video hardware */
716716   MCFG_SCREEN_ADD("screen", RASTER)
717   MCFG_SCREEN_REFRESH_RATE(53.8)
718   MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
719   /* frames per second hand tuned to match game and music speed */
720   MCFG_SCREEN_SIZE(32*8, 32*8)
721   MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 2*8, 30*8-1)
717   MCFG_SCREEN_RAW_PARAMS(XTAL_12MHz/2,394, 0, 256, 282, 16, 256) // was 53.8 Hz before, assume same as Bombs Away
722718   MCFG_SCREEN_UPDATE_DRIVER(psychic5_state, screen_update_psychic5)
723719
724720   MCFG_GFXDECODE_ADD("gfxdecode", "palette", psychic5)
r252893r252894
770766
771767   /* video hardware */
772768   MCFG_SCREEN_ADD("screen", RASTER)
773   MCFG_SCREEN_REFRESH_RATE(54)                /* Guru says : VSync - 54Hz . HSync - 15.25kHz */
774   MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
775   MCFG_SCREEN_SIZE(64*8, 32*8)
776   MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 2*8, 30*8-1)
769   MCFG_SCREEN_RAW_PARAMS(XTAL_12MHz/2,394, 0, 256, 282, 16, 256) /* Guru says : VSync - 54Hz . HSync - 15.25kHz */
777770   MCFG_SCREEN_UPDATE_DRIVER(psychic5_state, screen_update_bombsa)
778771
779772   MCFG_GFXDECODE_ADD("gfxdecode", "palette", bombsa)
trunk/src/mame/drivers/st_mp200.cpp
r252893r252894
1919#include "machine/genpin.h"
2020#include "cpu/m6800/m6800.h"
2121#include "machine/6821pia.h"
22#include "sound/s14001a_new.h"
22#include "sound/s14001a.h"
2323#include "st_mp200.lh"
2424
2525#define S14001_CLOCK                (25e5)
r252893r252894
8181   virtual void machine_start() override;
8282   virtual void machine_reset() override;
8383   required_device<m6800_cpu_device> m_maincpu;
84   optional_device<s14001a_new_device> m_s14001a;
84   optional_device<s14001a_device> m_s14001a;
8585   required_device<pia6821_device> m_pia_u10;
8686   required_device<pia6821_device> m_pia_u11;
8787   required_ioport m_io_test;
r252893r252894
619619
620620static MACHINE_CONFIG_DERIVED( st_mp201, st_mp200 )
621621   MCFG_SPEAKER_STANDARD_MONO("mono")
622   MCFG_SOUND_ADD("speech", S14001A_NEW, S14001_CLOCK)
622   MCFG_SOUND_ADD("speech", S14001A, S14001_CLOCK)
623623   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
624624MACHINE_CONFIG_END
625625
trunk/src/mame/drivers/wolfpack.cpp
r252893r252894
319319
320320   /* sound hardware */
321321   MCFG_SPEAKER_STANDARD_MONO("mono")
322   MCFG_SOUND_ADD("speech", S14001A_NEW, 20000) /* RC Clock (C=100pf, R=470K-670K ohms, adjustable) ranging from 14925.37313hz to 21276.59574hz, likely factory set to 20000hz since anything below 19500 is too slow */
322   MCFG_SOUND_ADD("speech", S14001A, 20000) /* RC Clock (C=100pf, R=470K-670K ohms, adjustable) ranging from 14925.37313hz to 21276.59574hz, likely factory set to 20000hz since anything below 19500 is too slow */
323323   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
324324MACHINE_CONFIG_END
325325
trunk/src/mame/includes/fidelz80.h
r252893r252894
77******************************************************************************/
88
99#include "emu.h"
10#include "sound/s14001a_new.h"
10#include "sound/s14001a.h"
1111
1212class fidelz80base_state : public driver_device
1313{
r252893r252894
2626   // devices/pointers
2727   required_device<cpu_device> m_maincpu;
2828   optional_ioport_array<10> m_inp_matrix; // max 10
29   optional_device<s14001a_new_device> m_speech;
29   optional_device<s14001a_device> m_speech;
3030   optional_region_ptr<UINT8> m_speech_rom;
3131
3232   // misc common
trunk/src/mame/includes/wolfpack.h
r252893r252894
66
77***************************************************************************/
88
9#include "sound/s14001a_new.h"
9#include "sound/s14001a.h"
1010
1111class wolfpack_state : public driver_device
1212{
r252893r252894
2929   // devices, pointers
3030   required_shared_ptr<UINT8> m_alpha_num_ram;
3131   required_device<cpu_device> m_maincpu;
32   required_device<s14001a_new_device> m_s14001a;
32   required_device<s14001a_device> m_s14001a;
3333   required_device<gfxdecode_device> m_gfxdecode;
3434   required_device<screen_device> m_screen;
3535   required_device<palette_device> m_palette;


Previous 199869 Revisions Next


© 1997-2024 The MAME Team