Previous 199869 Revisions Next

r44381 Saturday 23rd January, 2016 at 18:00:32 UTC by AJR
More configuration fixes
- terrafb: remove unused NB1414M4
- segas16b.cpp: sanity check forgotten in last confix
- sega16sp.cpp: fix region width, make required (as last confix allows)
[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]armedf.cpp berzerk.cpp fidel6502.cpp fidelz80.cpp psychic5.cpp segas16b.cpp st_mp200.cpp wolfpack.cpp
[src/mame/includes]fidelz80.h wolfpack.h
[src/mame/video]sega16sp.cpp sega16sp.h

trunk/scripts/src/sound.lua
r252892r252893
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---------------------------------------------------
944958-- Texas Instruments SN76477 analog chip
945959--@src/devices/sound/sn76477.h,SOUNDS["SN76477"] = true
946960---------------------------------------------------
trunk/scripts/target/mame/arcade.lua
r252892r252893
226226SOUNDS["ES8712"] = true
227227SOUNDS["CDP1869"] = true
228228SOUNDS["S14001A"] = true
229SOUNDS["S14001A_NEW"] = true
229230SOUNDS["WAVE"] = true
230231SOUNDS["SID6581"] = true
231232SOUNDS["SID8580"] = true
trunk/scripts/target/mame/mess.lua
r252892r252893
228228--SOUNDS["ES8712"] = true
229229SOUNDS["CDP1869"] = true
230230SOUNDS["S14001A"] = true
231SOUNDS["S14001A_NEW"] = true
231232SOUNDS["WAVE"] = true
232233SOUNDS["SID6581"] = true
233234SOUNDS["SID8580"] = true
trunk/src/devices/sound/s14001a.cpp
r252892r252893
11// license:BSD-3-Clause
2// copyright-holders:Ed Bernard, Jonathan Gevaryahu, hap
3// thanks-to:Kevin Horton
2// copyright-holders:Jonathan Gevaryahu,R. Belmont,Zsolt Vasvari
43/*
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
94
10    TODO:
11    - nothing at the moment?
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
1210
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
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.
1834*/
1935
2036/* Chip Pinout:
r252892r252893
8399START is pulled high when a word is to be said and the word number is on the
84100word select/speech address input lines. The Canon 'Canola' uses a separate 'rom
85101strobe' 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,
102Its likely that they did this to be able to force the speech chip to stop talking,
87103which is normally impossible. The later 'version 3' TSI speech board as featured in
88104an advertisement in the John Cater book probably also has this feature, in addition
89105to external speech rom banking.
r252892r252893
94110
95111Because it requires -10V to operate, the chip manufacturing process must be PMOS.
96112
97* Operation:
113/-----------\
114> Operation <
115\-----------/
98116Put the 6-bit address of the word to be said onto the C0-C5 word select/speech
99117address bus lines. Next, clock the START line low-high-low. As long as the START
100118line is held high, the first address byte of the first word will be read repeatedly
r252892r252893
103121/BUSY line will go low until 3 clocks after the chip is done speaking.
104122*/
105123
106#include "emu.h"
107#include "s14001a.h"
108124
109// device definition
110const device_type S14001A = &device_creator<s14001a_device>;
125/* state map:
111126
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}
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)
121134
122//-------------------------------------------------
123//  device_start - device-specific startup
124//-------------------------------------------------
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
125141
126ALLOW_SAVE_TYPE(s14001a_device::states); // allow save_item on a non-fundamental type
142 * state 2(GetLoWord):
143 *   grab byte at (wordinput<<1)+1 -> register_WL
144 *   next state is 3(GetHiPhon)
127145
128void s14001a_device::device_start()
129{
130   m_stream = machine().sound().stream_alloc(*this, 0, 1, clock() ? clock() : machine().sample_rate());
146 * state 3(GetHiPhon):
147 *   grab byte at ((register_WH<<8) + (register_WL))>>4 -> phoneaddress
148 *   next state is 4(GetLoPhon)
131149
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 * 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
150166
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));
164167
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));
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
170174
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));
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)
176184
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}
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)
182193
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)
183202
184//-------------------------------------------------
185//  sound_stream_update - handle a stream update
186//-------------------------------------------------
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)
187212
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}
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
197216
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*/
198229
199/**************************************************************************
200    External interface
201**************************************************************************/
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 */
202240
203void s14001a_device::force_update()
204{
205   m_stream->update();
206}
241#undef ACCURATE_SQUEAL
207242
208READ_LINE_MEMBER(s14001a_device::romen_r)
209{
210   m_stream->update();
211   return (m_bPhase1) ? 1 : 0;
212}
243#include "emu.h"
244#include "s14001a.h"
213245
214READ_LINE_MEMBER(s14001a_device::busy_r)
215{
216   m_stream->update();
217   return (m_bBusyP1) ? 1 : 0;
218}
219246
220WRITE8_MEMBER(s14001a_device::data_w)
221{
222   m_stream->update();
223   m_uWord = data & 0x3f; // C0-C5
224}
247//#define DEBUGSTATE
225248
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}
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.
232251
233void s14001a_device::set_clock(UINT32 clock)
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] =
234260{
235   m_stream->update();
236   m_stream->set_sample_rate(clock);
237}
261   { -3, -3, -1, -1, },
262   { -1, -1,  0,  0, },
263   {  0,  0,  1,  1, },
264   {  1,  1,  3,  3  },
265};
238266
239
240/**************************************************************************
241    Device emulation
242**************************************************************************/
243
244UINT8 s14001a_device::readmem(UINT16 offset, bool phase)
267#ifdef ACCURATE_SQUEAL
268INT16 s14001a_device::audiofilter() /* rewrite me to better match the real filter! */
245269{
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));
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;
248276}
249277
250bool s14001a_device::Clock()
278void s14001a_device::shiftIntoFilter(INT16 inputvalue)
251279{
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)
280   UINT8 temp1;
281   for (temp1 = 7; temp1 > 0; temp1--)
263282   {
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;
283      m_filtervals[temp1] = m_filtervals[(temp1 - 1)];
289284   }
290   m_bPhase1 = true;
285   m_filtervals[0] = inputvalue;
286}
287#endif
291288
292   // logic done during phase 1
293   switch (m_uStateP1)
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
294297   {
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)
298#ifdef DEBUGSTATE
299      fprintf(stderr,"1: MIRRORMODE was on\n");
300#endif
301      if (m_RepeatCounter == 0x8) // exceeded 3 bits?
379302      {
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)
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)
424310         {
425            m_uLengthP1 = 0; // emulate 7 bit counter
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
426315         }
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         }
427333      }
428
429      if (m_bVoicedP2 && m_bRepeatCarryP2) // repeat complete
334      else // repeatcounter did NOT carry out of 3 bits so leave length counter alone
430335      {
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
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;
435341      }
436      if (!m_bVoicedP2 && m_bDAR04To00CarryP2)
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?
437349      {
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
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         }
442368      }
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}
443377
444      // construct m_RomAddrP1
445      m_RomAddrP1 = m_uDAR04To00P1;
446      if (m_bVoicedP2 && m_uLengthP1&0x1) // mirroring
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)
447398      {
448         m_RomAddrP1 ^= 0x1f; // count backwards
399         m_DACOutput = SILENCE;
400         m_OldDelta = 2;
449401      }
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)
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)
456405      {
457         m_uStateP1  = DARMSB;
458         m_RomAddrP1 = m_uCWARP1; // output correct address
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;
459505      }
460      else m_uStateP1 = PLAY;
461      break;
462   }
463506
464   case DELAY:
465      m_uOutputP1 = 7;
466      if (m_bStart) m_uStateP1 = WORDWAIT;
467      else          m_uStateP1 = IDLE;
468      break;
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);
469518   }
519}
470520
471   return true;
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));
472525}
473526
474UINT8 s14001a_device::Mux8To2(bool bVoicedP2, UINT8 uPPQtrP2, UINT8 uDeltaAdrP2, UINT8 uRomDataP2)
527
528/**************************************************************************
529   MAME glue code
530 **************************************************************************/
531
532void s14001a_device::force_update()
475533{
476   // pick two bits of rom data as delta
534   m_stream->update();
535}
477536
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;
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);
495544}
496545
497void s14001a_device::CalculateIncrement(bool bVoicedP2, UINT8 uPPQtrP2, bool bPPQStartP2, UINT8 uDelta, UINT8 uDeltaOldP2, UINT8 &uDeltaOldP1, UINT8 &uIncrementP2, bool &bAddP2)
546void s14001a_device::reg_w(int data)
498547{
499   // uPPQtr, pitch period quarter counter; 2 lsb of uLength
500   // bPPStart, start of a pitch period
501   // implemented to mimic silicon (a bit)
548   m_stream->update();
549   m_WordInput = data;
550}
502551
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   };
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}
516559
517#define MIRROR  (uPPQtrP2&0x01)
560void s14001a_device::set_clock(int clock)
561{
562   m_stream->set_sample_rate(clock);
563}
518564
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
565void s14001a_device::set_volume(int volume)
566{
567   m_stream->update();
568   m_VSU1000_amp = volume;
533569}
534570
535UINT8 s14001a_device::CalculateOutput(bool bVoiced, bool bXSilence, UINT8 uPPQtr, bool bPPQStart, UINT8 uLOutput, UINT8 uIncrementP2, bool bAddP2)
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)
536580{
537   // implemented to mimic silicon (a bit)
538   // limits output to 0x00 and 0x0f
539   UINT8 uTmp; // used for subtraction
581}
540582
541#define SILENCE (uPPQtr&0x02)
583//-------------------------------------------------
584//  device_start - device-specific startup
585//-------------------------------------------------
542586
543   // determine output
544   if (bXSilence || (bVoiced && SILENCE)) return 7;
587void s14001a_device::device_start()
588{
589   m_GlobalSilenceState = 1;
590   m_OldDelta = 0x02;
591   m_DACOutput = SILENCE;
592   m_VSU1000_amp = 15;
545593
546   // beginning of a pitch period
547   if (uPPQtr == 0x00 && bPPQStart) // note this is done for voiced and nonvoiced
594   for (int i = 0; i < 8; i++)
548595   {
549      uLOutput = 7;
596      m_filtervals[i] = SILENCE;
550597   }
551598
552   // adder
553   uTmp = uLOutput;
554   if (!bAddP2) uTmp ^= 0x0F; // turns subtraction into addition
599   m_stream = machine().sound().stream_alloc(*this, 0, 1, clock() ? clock() : machine().sample_rate());
555600
556   // add 0, 1, 3; limit at 15
557   uTmp += uIncrementP2;
558   if (uTmp > 15) uTmp = 15;
601   // resolve callbacks
602   m_ext_read_handler.resolve();
603   m_bsy_handler.resolve();
559604
560   if (!bAddP2) uTmp ^= 0x0F; // turns addition back to subtraction
561   return uTmp;
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));
562625}
563626
564void s14001a_device::ClearStatistics()
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)
565632{
566   m_uNPitchPeriods = 0;
567   m_uNVoiced       = 0;
568   m_uPrintLevel    = 0;
569   m_uNControlWords = 0;
570}
633   int i;
571634
572void s14001a_device::GetStatistics(UINT32 &uNPitchPeriods, UINT32 &uNVoiced, UINT32 uNControlWords)
573{
574   uNPitchPeriods = m_uNPitchPeriods;
575   uNVoiced = m_uNVoiced;
576   uNControlWords = m_uNControlWords;
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      }
577653}
trunk/src/devices/sound/s14001a.h
r252892r252893
11// license:BSD-3-Clause
2// copyright-holders:Ed Bernard, Jonathan Gevaryahu, hap
3// thanks-to:Kevin Horton
2// copyright-holders:Jonathan Gevaryahu,R. Belmont,Zsolt Vasvari
3#pragma once
44/*
5    SSi TSI S14001A speech IC emulator
6*/
5    Copyright (C) 2006-2013 Jonathan Gevaryahu AKA Lord Nightmare
76
7*/
88#ifndef __S14001A_H__
99#define __S14001A_H__
1010
r252892r252893
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);
r252892r252893
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   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
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();
3635
3736protected:
3837   // device-level overrides
r252892r252893
4241   virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override;
4342
4443private:
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 readmem(UINT16 offset, bool phase);
52   bool Clock(); // called once to toggle external clock twice
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
5371
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;
72   void PostPhoneme();
73   void s14001a_clock();
74   UINT8 readmem(UINT16 offset);
13375};
13476
13577extern const device_type S14001A;
trunk/src/devices/sound/s14001a_new.cpp
r0r252893
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
r0r252893
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
r252892r252893
149149      m_roffset(0),
150150      m_irq_cb(*this),
151151      m_main_irq_cb(*this),
152      m_ram_region(*this, DEVICE_SELF),
152153      m_BUFPTR(0),
153154      m_SCSPRAM(nullptr),
154155      m_SCSPRAM_LENGTH(0),
r252892r252893
515516      m_Master = 0;
516517   }
517518
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)
519   if (m_ram_region != NULL)
522520   {
523      m_SCSPRAM = ram_region->base();
524      m_SCSPRAM_LENGTH = ram_region->bytes();
521      m_SCSPRAM = m_ram_region->base();
522      m_SCSPRAM_LENGTH = m_ram_region->bytes();
525523      m_DSP.SCSPRAM = (UINT16 *)m_SCSPRAM;
526524      m_DSP.SCSPRAM_LENGTH = m_SCSPRAM_LENGTH / 2;
527525      m_SCSPRAM += m_roffset;
trunk/src/devices/sound/scsp.h
r252892r252893
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;
107108
108109   union
109110   {
trunk/src/mame/drivers/armedf.cpp
r252892r252893
12651265   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.80)
12661266MACHINE_CONFIG_END
12671267
1268static MACHINE_CONFIG_DERIVED( terrafb, terraf )
1269   MCFG_DEVICE_REMOVE("nb1414m4")
1270MACHINE_CONFIG_END
1271
12681272static MACHINE_CONFIG_START( kozure, armedf_state )
12691273
12701274   /* basic machine hardware */
r252892r252893
21902194GAME( 1987, terrafu,  terraf,   terraf,   terraf,   armedf_state,   terrafu,  ROT0,   "Nichibutsu USA",                "Terra Force (US)", MACHINE_SUPPORTS_SAVE )
21912195GAME( 1987, terrafj,  terraf,   terraf,   terraf,   armedf_state,   terrafu,  ROT0,   "Nichibutsu Japan",              "Terra Force (Japan)", MACHINE_SUPPORTS_SAVE )
21922196GAME( 1987, terrafjb, terraf,   terrafjb, terraf,   armedf_state,   terrafjb, ROT0,   "bootleg",                       "Terra Force (Japan, bootleg with additional Z80)", MACHINE_SUPPORTS_SAVE )
2193GAME( 1987, terrafb,  terraf,   terraf,   terraf,   armedf_state,   terraf,   ROT0,   "bootleg",                       "Terra Force (Japan, bootleg set 2)", MACHINE_SUPPORTS_SAVE )
2197GAME( 1987, terrafb,  terraf,   terrafb,  terraf,   armedf_state,   terraf,   ROT0,   "bootleg",                       "Terra Force (Japan, bootleg set 2)", MACHINE_SUPPORTS_SAVE )
21942198
21952199GAME( 1987, kozure,   0,        kozure,   kozure,   armedf_state,   kozure,   ROT0,   "Nichibutsu",                    "Kozure Ookami (Japan)", MACHINE_SUPPORTS_SAVE )
21962200
trunk/src/mame/drivers/berzerk.cpp
r252892r252893
1515#include "audio/exidy.h"
1616#include "machine/74181.h"
1717#include "machine/nvram.h"
18#include "sound/s14001a.h"
18#include "sound/s14001a_new.h"
1919#include "video/resnet.h"
2020
2121
r252892r252893
3535   { }
3636
3737   required_device<cpu_device> m_maincpu;
38   required_device<s14001a_device> m_s14001a;
38   required_device<s14001a_new_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;
r252892r252893
11201120   /* audio hardware */
11211121   MCFG_SPEAKER_STANDARD_MONO("mono")
11221122
1123   MCFG_SOUND_ADD("speech", S14001A, S14001_CLOCK/16/8) /* placeholder - the clock is software controllable */
1123   MCFG_SOUND_ADD("speech", S14001A_NEW, 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
r252892r252893
332332
333333   /* sound hardware */
334334   MCFG_SPEAKER_STANDARD_MONO("mono")
335   MCFG_SOUND_ADD("speech", S14001A, 25000) // around 25khz
335   MCFG_SOUND_ADD("speech", S14001A_NEW, 25000) // around 25khz
336336   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.75)
337337MACHINE_CONFIG_END
338338
trunk/src/mame/drivers/fidelz80.cpp
r252892r252893
14301430
14311431   /* sound hardware */
14321432   MCFG_SPEAKER_STANDARD_MONO("mono")
1433   MCFG_SOUND_ADD("speech", S14001A, 25000) // R/C circuit, around 25khz
1433   MCFG_SOUND_ADD("speech", S14001A_NEW, 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
r252892r252893
14581458
14591459   /* sound hardware */
14601460   MCFG_SPEAKER_STANDARD_MONO("mono")
1461   MCFG_SOUND_ADD("speech", S14001A, 25000) // R/C circuit, around 25khz
1461   MCFG_SOUND_ADD("speech", S14001A_NEW, 25000) // R/C circuit, around 25khz
14621462   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.75)
14631463
14641464   MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0)
r252892r252893
14831483
14841484   /* sound hardware */
14851485   MCFG_SPEAKER_STANDARD_MONO("mono")
1486   MCFG_SOUND_ADD("speech", S14001A, 25000) // R/C circuit, around 25khz
1486   MCFG_SOUND_ADD("speech", S14001A_NEW, 25000) // R/C circuit, around 25khz
14871487   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.75)
14881488MACHINE_CONFIG_END
14891489
r252892r252893
14951495
14961496ROM_START( cc10 )
14971497   ROM_REGION( 0x10000, "maincpu", 0 )
1498   ROM_LOAD( "cc10.bin", 0x0000, 0x1000, BAD_DUMP CRC(bb9e6055) SHA1(18276e57cf56465a6352239781a828c5f3d5ba63) ) // second half empty
1498   ROM_LOAD( "cc10.bin", 0x0000, 0x1000, CRC(bb9e6055) SHA1(18276e57cf56465a6352239781a828c5f3d5ba63) )
14991499ROM_END
15001500
15011501
r252892r252893
15121512
15131513ROM_START( vccg )
15141514   ROM_REGION( 0x10000, "maincpu", 0 )
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) )
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?
15181518
15191519   ROM_REGION( 0x2000, "speech", 0 )
1520   ROM_LOAD("vcc-german.bin", 0x0000, 0x2000, BAD_DUMP CRC(6c85e310) SHA1(20d1d6543c1e6a1f04184a2df2a468f33faec3ff) ) // taken from fexcelv
1520   ROM_LOAD("vcc-german.bin", 0x0000, 0x2000, BAD_DUMP CRC(6c85e310) SHA1(20d1d6543c1e6a1f04184a2df2a468f33faec3ff) ) // at location c4?
15211521ROM_END
15221522
15231523ROM_START( vccfr )
15241524   ROM_REGION( 0x10000, "maincpu", 0 )
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) )
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?
15281528
15291529   ROM_REGION( 0x2000, "speech", 0 )
1530   ROM_LOAD("vcc-french.bin", 0x0000, 0x2000, BAD_DUMP CRC(fe8c5c18) SHA1(2b64279ab3747ee81c86963c13e78321c6cfa3a3) ) // taken from fexcelv
1530   ROM_LOAD("vcc-french.bin", 0x0000, 0x2000, BAD_DUMP CRC(fe8c5c18) SHA1(2b64279ab3747ee81c86963c13e78321c6cfa3a3) ) // at location c4?
15311531ROM_END
15321532
15331533ROM_START( vccsp )
15341534   ROM_REGION( 0x10000, "maincpu", 0 )
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) )
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?
15381538
15391539   ROM_REGION( 0x2000, "speech", 0 )
1540   ROM_LOAD("vcc-spanish.bin", 0x0000, 0x2000, CRC(8766e128) SHA1(78c7413bf240159720b131ab70bfbdf4e86eb1e9) )
1540   ROM_LOAD("vcc-spanish.bin", 0x0000, 0x2000, CRC(8766e128) SHA1(78c7413bf240159720b131ab70bfbdf4e86eb1e9) ) // at location c4?
15411541ROM_END
15421542
15431543
trunk/src/mame/drivers/psychic5.cpp
r252892r252893
714714
715715   /* video hardware */
716716   MCFG_SCREEN_ADD("screen", RASTER)
717   MCFG_SCREEN_RAW_PARAMS(XTAL_12MHz/2,394, 0, 256, 282, 16, 256) // was 53.8 Hz before, assume same as Bombs Away
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)
718722   MCFG_SCREEN_UPDATE_DRIVER(psychic5_state, screen_update_psychic5)
719723
720724   MCFG_GFXDECODE_ADD("gfxdecode", "palette", psychic5)
r252892r252893
766770
767771   /* video hardware */
768772   MCFG_SCREEN_ADD("screen", RASTER)
769   MCFG_SCREEN_RAW_PARAMS(XTAL_12MHz/2,394, 0, 256, 282, 16, 256) /* Guru says : VSync - 54Hz . HSync - 15.25kHz */
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)
770777   MCFG_SCREEN_UPDATE_DRIVER(psychic5_state, screen_update_bombsa)
771778
772779   MCFG_GFXDECODE_ADD("gfxdecode", "palette", bombsa)
trunk/src/mame/drivers/segas16b.cpp
r252892r252893
11271127         //  D0 : Output to coin counter 1
11281128         //
11291129         m_segaic16vid->tilemap_set_flip(0, data & 0x40);
1130         m_sprites->set_flip(data & 0x40);
1130         if (m_sprites.found())
1131            m_sprites->set_flip(data & 0x40);
11311132         if (!m_disable_screen_blanking)
11321133            m_segaic16vid->set_display_enable(data & 0x20);
11331134         output().set_led_value(1, data & 0x08);
trunk/src/mame/drivers/st_mp200.cpp
r252892r252893
1919#include "machine/genpin.h"
2020#include "cpu/m6800/m6800.h"
2121#include "machine/6821pia.h"
22#include "sound/s14001a.h"
22#include "sound/s14001a_new.h"
2323#include "st_mp200.lh"
2424
2525#define S14001_CLOCK                (25e5)
r252892r252893
8181   virtual void machine_start() override;
8282   virtual void machine_reset() override;
8383   required_device<m6800_cpu_device> m_maincpu;
84   optional_device<s14001a_device> m_s14001a;
84   optional_device<s14001a_new_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;
r252892r252893
619619
620620static MACHINE_CONFIG_DERIVED( st_mp201, st_mp200 )
621621   MCFG_SPEAKER_STANDARD_MONO("mono")
622   MCFG_SOUND_ADD("speech", S14001A, S14001_CLOCK)
622   MCFG_SOUND_ADD("speech", S14001A_NEW, S14001_CLOCK)
623623   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
624624MACHINE_CONFIG_END
625625
trunk/src/mame/drivers/wolfpack.cpp
r252892r252893
319319
320320   /* sound hardware */
321321   MCFG_SPEAKER_STANDARD_MONO("mono")
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 */
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 */
323323   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
324324MACHINE_CONFIG_END
325325
trunk/src/mame/includes/fidelz80.h
r252892r252893
77******************************************************************************/
88
99#include "emu.h"
10#include "sound/s14001a.h"
10#include "sound/s14001a_new.h"
1111
1212class fidelz80base_state : public driver_device
1313{
r252892r252893
2626   // devices/pointers
2727   required_device<cpu_device> m_maincpu;
2828   optional_ioport_array<10> m_inp_matrix; // max 10
29   optional_device<s14001a_device> m_speech;
29   optional_device<s14001a_new_device> m_speech;
3030   optional_region_ptr<UINT8> m_speech_rom;
3131
3232   // misc common
trunk/src/mame/includes/wolfpack.h
r252892r252893
66
77***************************************************************************/
88
9#include "sound/s14001a.h"
9#include "sound/s14001a_new.h"
1010
1111class wolfpack_state : public driver_device
1212{
r252892r252893
2929   // devices, pointers
3030   required_shared_ptr<UINT8> m_alpha_num_ram;
3131   required_device<cpu_device> m_maincpu;
32   required_device<s14001a_device> m_s14001a;
32   required_device<s14001a_new_device> m_s14001a;
3333   required_device<gfxdecode_device> m_gfxdecode;
3434   required_device<screen_device> m_screen;
3535   required_device<palette_device> m_palette;
trunk/src/mame/video/sega16sp.cpp
r252892r252893
869869   //
870870
871871   // render the sprites in order
872   const UINT16 *spritebase = reinterpret_cast<const UINT16 *>(&m_sprite_region_ptr[0]);
872   const UINT16 *spritebase = &m_sprite_region_ptr[0];
873873   UINT8 numbanks = m_sprite_region_ptr.bytes() / 0x20000;
874874   UINT16 *ramend = spriteram() + spriteram_elements();
875875   for (UINT16 *data = spriteram(); data < ramend; data += 8)
trunk/src/mame/video/sega16sp.h
r252892r252893
203203   virtual void draw(bitmap_ind16 &bitmap, const rectangle &cliprect) override;
204204
205205   // memory regions
206   optional_region_ptr<UINT8> m_sprite_region_ptr;
206   required_region_ptr<UINT16> m_sprite_region_ptr;
207207};
208208
209209


Previous 199869 Revisions Next


© 1997-2024 The MAME Team