mirror of
https://github.com/holub/mame
synced 2025-04-19 07:00:31 +03:00
s14001a_new is now s14001a
This commit is contained in:
parent
60e8206509
commit
098b43d520
@ -940,20 +940,6 @@ end
|
||||
|
||||
|
||||
|
||||
---------------------------------------------------
|
||||
-- S14001A_NEW speech synthesizer
|
||||
--@src/devices/sound/s14001a_new.h,SOUNDS["S14001A_NEW"] = true
|
||||
---------------------------------------------------
|
||||
|
||||
if (SOUNDS["S14001A_NEW"]~=null) then
|
||||
files {
|
||||
MAME_DIR .. "src/devices/sound/s14001a_new.cpp",
|
||||
MAME_DIR .. "src/devices/sound/s14001a_new.h",
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
|
||||
---------------------------------------------------
|
||||
-- Texas Instruments SN76477 analog chip
|
||||
--@src/devices/sound/sn76477.h,SOUNDS["SN76477"] = true
|
||||
|
@ -226,7 +226,6 @@ SOUNDS["VOTRAX"] = true
|
||||
SOUNDS["ES8712"] = true
|
||||
SOUNDS["CDP1869"] = true
|
||||
SOUNDS["S14001A"] = true
|
||||
SOUNDS["S14001A_NEW"] = true
|
||||
SOUNDS["WAVE"] = true
|
||||
SOUNDS["SID6581"] = true
|
||||
SOUNDS["SID8580"] = true
|
||||
|
@ -228,7 +228,6 @@ SOUNDS["VOTRAX"] = true
|
||||
--SOUNDS["ES8712"] = true
|
||||
SOUNDS["CDP1869"] = true
|
||||
SOUNDS["S14001A"] = true
|
||||
SOUNDS["S14001A_NEW"] = true
|
||||
SOUNDS["WAVE"] = true
|
||||
SOUNDS["SID6581"] = true
|
||||
SOUNDS["SID8580"] = true
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,10 +1,10 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Jonathan Gevaryahu,R. Belmont,Zsolt Vasvari
|
||||
#pragma once
|
||||
// copyright-holders:Ed Bernard, Jonathan Gevaryahu, hap
|
||||
// thanks-to:Kevin Horton
|
||||
/*
|
||||
Copyright (C) 2006-2013 Jonathan Gevaryahu AKA Lord Nightmare
|
||||
|
||||
SSi TSI S14001A speech IC emulator
|
||||
*/
|
||||
|
||||
#ifndef __S14001A_H__
|
||||
#define __S14001A_H__
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
|
||||
|
||||
class s14001a_device : public device_t,
|
||||
public device_sound_interface
|
||||
public device_sound_interface
|
||||
{
|
||||
public:
|
||||
s14001a_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
@ -26,12 +26,13 @@ public:
|
||||
template<class _Object> static devcb_base &set_bsy_handler(device_t &device, _Object object) { return downcast<s14001a_device &>(device).m_bsy_handler.set_callback(object); }
|
||||
template<class _Object> static devcb_base &set_ext_read_handler(device_t &device, _Object object) { return downcast<s14001a_device &>(device).m_ext_read_handler.set_callback(object); }
|
||||
|
||||
int bsy_r(); /* read BUSY pin */
|
||||
void reg_w(int data); /* write to input latch */
|
||||
void rst_w(int data); /* write to RESET pin */
|
||||
void set_clock(int clock); /* set VSU-1000 clock */
|
||||
void set_volume(int volume); /* set VSU-1000 volume control */
|
||||
void force_update();
|
||||
DECLARE_READ_LINE_MEMBER(busy_r); // /BUSY (pin 40)
|
||||
DECLARE_READ_LINE_MEMBER(romen_r); // ROM /EN (pin 9)
|
||||
DECLARE_WRITE_LINE_MEMBER(start_w); // START (pin 10)
|
||||
DECLARE_WRITE8_MEMBER(data_w); // 6-bit word
|
||||
|
||||
void set_clock(UINT32 clock); // set new CLK frequency
|
||||
void force_update(); // update stream, eg. before external ROM bankswitch
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
@ -41,37 +42,94 @@ protected:
|
||||
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override;
|
||||
|
||||
private:
|
||||
// internal state
|
||||
required_region_ptr<UINT8> m_SpeechRom;
|
||||
sound_stream * m_stream;
|
||||
|
||||
devcb_write_line m_bsy_handler;
|
||||
devcb_read8 m_ext_read_handler;
|
||||
|
||||
UINT8 m_WordInput; // value on word input bus
|
||||
UINT8 m_LatchedWord; // value latched from input bus
|
||||
UINT16 m_SyllableAddress; // address read from word table
|
||||
UINT16 m_PhoneAddress; // starting/current phone address from syllable table
|
||||
UINT8 m_PlayParams; // playback parameters from syllable table
|
||||
UINT8 m_PhoneOffset; // offset within phone
|
||||
UINT8 m_LengthCounter; // 4-bit counter which holds the inverted length of the word in phones, leftshifted by 1
|
||||
UINT8 m_RepeatCounter; // 3-bit counter which holds the inverted number of repeats per phone, leftshifted by 1
|
||||
UINT8 m_OutputCounter; // 2-bit counter to determine forward/backward and output/silence state.
|
||||
UINT8 m_machineState; // chip state machine state
|
||||
UINT8 m_nextstate; // chip state machine's new state
|
||||
UINT8 m_laststate; // chip state machine's previous state, needed for mirror increment masking
|
||||
UINT8 m_resetState; // reset line state
|
||||
UINT8 m_oddeven; // odd versus even cycle toggle
|
||||
UINT8 m_GlobalSilenceState; // same as above but for silent syllables instead of silent portions of mirrored syllables
|
||||
UINT8 m_OldDelta; // 2-bit old delta value
|
||||
UINT8 m_DACOutput; // 4-bit DAC Accumulator/output
|
||||
UINT8 m_audioout; // filtered audio output
|
||||
INT16 m_filtervals[8];
|
||||
UINT8 m_VSU1000_amp; // amplitude setting on VSU-1000 board
|
||||
UINT8 readmem(UINT16 offset, bool phase);
|
||||
bool Clock(); // called once to toggle external clock twice
|
||||
|
||||
void PostPhoneme();
|
||||
void s14001a_clock();
|
||||
UINT8 readmem(UINT16 offset);
|
||||
// emulator helper functions
|
||||
UINT8 Mux8To2(bool bVoicedP2, UINT8 uPPQtrP2, UINT8 uDeltaAdrP2, UINT8 uRomDataP2);
|
||||
void CalculateIncrement(bool bVoicedP2, UINT8 uPPQtrP2, bool bPPQStartP2, UINT8 uDeltaP2, UINT8 uDeltaOldP2, UINT8 &uDeltaOldP1, UINT8 &uIncrementP2, bool &bAddP2);
|
||||
UINT8 CalculateOutput(bool bVoicedP2, bool bXSilenceP2, UINT8 uPPQtrP2, bool bPPQStartP2, UINT8 uLOutputP2, UINT8 uIncrementP2, bool bAddP2);
|
||||
void ClearStatistics();
|
||||
void GetStatistics(UINT32 &uNPitchPeriods, UINT32 &uNVoiced, UINT32 uNControlWords);
|
||||
void SetPrintLevel(UINT32 uPrintLevel) { m_uPrintLevel = uPrintLevel; }
|
||||
|
||||
// internal state
|
||||
bool m_bPhase1; // 1 bit internal clock
|
||||
|
||||
enum states
|
||||
{
|
||||
IDLE = 0,
|
||||
WORDWAIT,
|
||||
CWARMSB, // read 8 CWAR MSBs
|
||||
CWARLSB, // read 4 CWAR LSBs from rom d7-d4
|
||||
DARMSB, // read 8 DAR MSBs
|
||||
CTRLBITS, // read Stop, Voiced, Silence, Length, XRepeat
|
||||
PLAY,
|
||||
DELAY
|
||||
};
|
||||
|
||||
// registers
|
||||
states m_uStateP1; // 3 bits
|
||||
states m_uStateP2;
|
||||
|
||||
UINT16 m_uDAR13To05P1; // 9 MSBs of delta address register
|
||||
UINT16 m_uDAR13To05P2; // incrementing uDAR05To13 advances ROM address by 8 bytes
|
||||
|
||||
UINT16 m_uDAR04To00P1; // 5 LSBs of delta address register
|
||||
UINT16 m_uDAR04To00P2; // 3 address ROM, 2 mux 8 bits of data into 2 bit delta
|
||||
// carry indicates end of quarter pitch period (32 cycles)
|
||||
|
||||
UINT16 m_uCWARP1; // 12 bits Control Word Address Register (syllable)
|
||||
UINT16 m_uCWARP2;
|
||||
|
||||
bool m_bStopP1;
|
||||
bool m_bStopP2;
|
||||
bool m_bVoicedP1;
|
||||
bool m_bVoicedP2;
|
||||
bool m_bSilenceP1;
|
||||
bool m_bSilenceP2;
|
||||
UINT8 m_uLengthP1; // 7 bits, upper three loaded from ROM length
|
||||
UINT8 m_uLengthP2; // middle two loaded from ROM repeat and/or uXRepeat
|
||||
// bit 0 indicates mirror in voiced mode
|
||||
// bit 1 indicates internal silence in voiced mode
|
||||
// incremented each pitch period quarter
|
||||
|
||||
UINT8 m_uXRepeatP1; // 2 bits, loaded from ROM repeat
|
||||
UINT8 m_uXRepeatP2;
|
||||
UINT8 m_uDeltaOldP1; // 2 bit old delta
|
||||
UINT8 m_uDeltaOldP2;
|
||||
UINT8 m_uOutputP1; // 4 bits audio output, calculated during phase 1
|
||||
|
||||
// derived signals
|
||||
bool m_bDAR04To00CarryP2;
|
||||
bool m_bPPQCarryP2;
|
||||
bool m_bRepeatCarryP2;
|
||||
bool m_bLengthCarryP2;
|
||||
UINT16 m_RomAddrP1; // rom address
|
||||
|
||||
// output pins
|
||||
UINT8 m_uOutputP2; // output changes on phase2
|
||||
UINT16 m_uRomAddrP2; // address pins change on phase 2
|
||||
bool m_bBusyP1; // busy changes on phase 1
|
||||
|
||||
// input pins
|
||||
bool m_bStart;
|
||||
UINT8 m_uWord; // 6 bit word noumber to be spoken
|
||||
|
||||
// emulator variables
|
||||
// statistics
|
||||
UINT32 m_uNPitchPeriods;
|
||||
UINT32 m_uNVoiced;
|
||||
UINT32 m_uNControlWords;
|
||||
|
||||
// diagnostic output
|
||||
UINT32 m_uPrintLevel;
|
||||
};
|
||||
|
||||
extern const device_type S14001A;
|
||||
|
@ -1,577 +0,0 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ed Bernard, Jonathan Gevaryahu, hap
|
||||
// thanks-to:Kevin Horton
|
||||
/*
|
||||
SSi TSI S14001A speech IC emulator
|
||||
aka CRC: Custom ROM Controller, designed in 1975, first usage in 1976 on TSI Speech+ calculator
|
||||
Originally written for MAME by Jonathan Gevaryahu(Lord Nightmare) 2006-2013,
|
||||
replaced with near-complete rewrite by Ed Bernard in 2016
|
||||
|
||||
TODO:
|
||||
- nothing at the moment?
|
||||
|
||||
Further reading:
|
||||
- http://www.vintagecalculators.com/html/speech-.html
|
||||
- http://www.vintagecalculators.com/html/development_of_the_tsi_speech-.html
|
||||
- http://www.vintagecalculators.com/html/speech-_state_machine.html
|
||||
- https://archive.org/stream/pdfy-QPCSwTWiFz1u9WU_/david_djvu.txt
|
||||
*/
|
||||
|
||||
/* Chip Pinout:
|
||||
The original datasheet (which is lost as far as I know) clearly called the
|
||||
s14001a chip the 'CRC chip', or 'Custom Rom Controller', as it appears with
|
||||
this name on the Stern and Canon schematics, as well as on some TSI speech
|
||||
print advertisements.
|
||||
Labels are not based on the labels used by the Atari wolf pack and Stern
|
||||
schematics, as these are inconsistent. Atari calls the word select/speech address
|
||||
input pins SAx while Stern calls them Cx. Also Atari and Canon both have the bit
|
||||
ordering for the word select/speech address bus backwards, which may indicate it
|
||||
was so on the original datasheet. Stern has it correct, and I've used their Cx
|
||||
labeling.
|
||||
|
||||
______ ______
|
||||
_|o \__/ |_
|
||||
+5V -- |_|1 40|_| -> /BUSY*
|
||||
_| |_
|
||||
?TEST ?? |_|2 39|_| <- ROM D7
|
||||
_| |_
|
||||
XTAL CLOCK/CKC -> |_|3 38|_| -> ROM A11
|
||||
_| |_
|
||||
ROM CLOCK/CKR <- |_|4 37|_| <- ROM D6
|
||||
_| |_
|
||||
DIGITAL OUT 0 <- |_|5 36|_| -> ROM A10
|
||||
_| |_
|
||||
DIGITAL OUT 1 <- |_|6 35|_| -> ROM A9
|
||||
_| |_
|
||||
DIGITAL OUT 2 <- |_|7 34|_| <- ROM D5
|
||||
_| |_
|
||||
DIGITAL OUT 3 <- |_|8 33|_| -> ROM A8
|
||||
_| |_
|
||||
ROM /EN <- |_|9 32|_| <- ROM D4
|
||||
_| S |_
|
||||
START -> |_|10 7 1 T 31|_| -> ROM A7
|
||||
_| 7 4 S |_
|
||||
AUDIO OUT <- |_|11 3 0 I 30|_| <- ROM D3
|
||||
_| 7 0 |_
|
||||
ROM A0 <- |_|12 1 29|_| -> ROM A6
|
||||
_| A |_
|
||||
SPCH ADR BUS C0 -> |_|13 28|_| <- SPCH ADR BUS C5
|
||||
_| |_
|
||||
ROM A1 <- |_|14 27|_| <- ROM D2
|
||||
_| |_
|
||||
SPCH ADR BUS C1 -> |_|15 26|_| <- SPCH ADR BUS C4
|
||||
_| |_
|
||||
ROM A2 <- |_|16 25|_| <- ROM D1
|
||||
_| |_
|
||||
SPCH ADR BUS C2 -> |_|17 24|_| <- SPCH ADR BUS C3
|
||||
_| |_
|
||||
ROM A3 <- |_|18 23|_| <- ROM D0
|
||||
_| |_
|
||||
ROM A4 <- |_|19 22|_| -> ROM A5
|
||||
_| |_
|
||||
GND -- |_|20 21|_| -- -10V
|
||||
|________________|
|
||||
|
||||
*Note from Kevin Horton when testing the hookup of the S14001A: the /BUSY line
|
||||
is not a standard voltage line: when it is in its HIGH state (i.e. not busy) it
|
||||
puts out a voltage of -10 volts, so it needs to be dropped back to a sane
|
||||
voltage level before it can be passed to any sort of modern IC. The address
|
||||
lines for the speech rom (A0-A11) do not have this problem, they output at a
|
||||
TTL/CMOS compatible voltage. The AUDIO OUT pin also outputs a voltage below GND,
|
||||
and the TEST pins may do so too.
|
||||
|
||||
START is pulled high when a word is to be said and the word number is on the
|
||||
word select/speech address input lines. The Canon 'Canola' uses a separate 'rom
|
||||
strobe' signal independent of the chip to either enable or clock the speech rom.
|
||||
It's likely that they did this to be able to force the speech chip to stop talking,
|
||||
which is normally impossible. The later 'version 3' TSI speech board as featured in
|
||||
an advertisement in the John Cater book probably also has this feature, in addition
|
||||
to external speech rom banking.
|
||||
|
||||
The Digital out pins supply a copy of the 4-bit waveform which also goes to the
|
||||
internal DAC. They are only valid every other clock cycle. It is possible that
|
||||
on 'invalid' cycles they act as a 4 bit input to drive the dac.
|
||||
|
||||
Because it requires -10V to operate, the chip manufacturing process must be PMOS.
|
||||
|
||||
* Operation:
|
||||
Put the 6-bit address of the word to be said onto the C0-C5 word select/speech
|
||||
address bus lines. Next, clock the START line low-high-low. As long as the START
|
||||
line is held high, the first address byte of the first word will be read repeatedly
|
||||
every clock, with the rom enable line enabled constantly (i.e. it doesn't toggle on
|
||||
and off as it normally does during speech). Once START has gone low-high-low, the
|
||||
/BUSY line will go low until 3 clocks after the chip is done speaking.
|
||||
*/
|
||||
|
||||
#include "emu.h"
|
||||
#include "s14001a_new.h"
|
||||
|
||||
// device definition
|
||||
const device_type S14001A_NEW = &device_creator<s14001a_new_device>;
|
||||
|
||||
s14001a_new_device::s14001a_new_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, S14001A_NEW, "S14001A_NEW", tag, owner, clock, "s14001a_new", __FILE__),
|
||||
device_sound_interface(mconfig, *this),
|
||||
m_SpeechRom(*this, DEVICE_SELF),
|
||||
m_stream(nullptr),
|
||||
m_bsy_handler(*this),
|
||||
m_ext_read_handler(*this)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
ALLOW_SAVE_TYPE(s14001a_new_device::states); // allow save_item on a non-fundamental type
|
||||
|
||||
void s14001a_new_device::device_start()
|
||||
{
|
||||
m_stream = machine().sound().stream_alloc(*this, 0, 1, clock() ? clock() : machine().sample_rate());
|
||||
|
||||
// resolve callbacks
|
||||
m_ext_read_handler.resolve();
|
||||
m_bsy_handler.resolve();
|
||||
|
||||
// note: zerofill is done already by MAME core
|
||||
ClearStatistics();
|
||||
m_uOutputP1 = m_uOutputP2 = 7;
|
||||
|
||||
// register for savestates
|
||||
save_item(NAME(m_bPhase1));
|
||||
save_item(NAME(m_uStateP1));
|
||||
save_item(NAME(m_uStateP2));
|
||||
save_item(NAME(m_uDAR13To05P1));
|
||||
save_item(NAME(m_uDAR13To05P2));
|
||||
save_item(NAME(m_uDAR04To00P1));
|
||||
save_item(NAME(m_uDAR04To00P2));
|
||||
save_item(NAME(m_uCWARP1));
|
||||
save_item(NAME(m_uCWARP2));
|
||||
|
||||
save_item(NAME(m_bStopP1));
|
||||
save_item(NAME(m_bStopP2));
|
||||
save_item(NAME(m_bVoicedP1));
|
||||
save_item(NAME(m_bVoicedP2));
|
||||
save_item(NAME(m_bSilenceP1));
|
||||
save_item(NAME(m_bSilenceP2));
|
||||
save_item(NAME(m_uLengthP1));
|
||||
save_item(NAME(m_uLengthP2));
|
||||
save_item(NAME(m_uXRepeatP1));
|
||||
save_item(NAME(m_uXRepeatP2));
|
||||
save_item(NAME(m_uDeltaOldP1));
|
||||
save_item(NAME(m_uDeltaOldP2));
|
||||
save_item(NAME(m_uOutputP1));
|
||||
|
||||
save_item(NAME(m_bDAR04To00CarryP2));
|
||||
save_item(NAME(m_bPPQCarryP2));
|
||||
save_item(NAME(m_bRepeatCarryP2));
|
||||
save_item(NAME(m_bLengthCarryP2));
|
||||
save_item(NAME(m_RomAddrP1));
|
||||
|
||||
save_item(NAME(m_uOutputP2));
|
||||
save_item(NAME(m_uRomAddrP2));
|
||||
save_item(NAME(m_bBusyP1));
|
||||
save_item(NAME(m_bStart));
|
||||
save_item(NAME(m_uWord));
|
||||
|
||||
save_item(NAME(m_uNPitchPeriods));
|
||||
save_item(NAME(m_uNVoiced));
|
||||
save_item(NAME(m_uNControlWords));
|
||||
save_item(NAME(m_uPrintLevel));
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// sound_stream_update - handle a stream update
|
||||
//-------------------------------------------------
|
||||
|
||||
void s14001a_new_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
|
||||
{
|
||||
for (int i = 0; i < samples; i++)
|
||||
{
|
||||
Clock();
|
||||
INT16 sample = m_uOutputP2 - 7; // range -7..8
|
||||
outputs[0][i] = sample * 0xf00;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
External interface
|
||||
**************************************************************************/
|
||||
|
||||
void s14001a_new_device::force_update()
|
||||
{
|
||||
m_stream->update();
|
||||
}
|
||||
|
||||
READ_LINE_MEMBER(s14001a_new_device::romen_r)
|
||||
{
|
||||
m_stream->update();
|
||||
return (m_bPhase1) ? 1 : 0;
|
||||
}
|
||||
|
||||
READ_LINE_MEMBER(s14001a_new_device::busy_r)
|
||||
{
|
||||
m_stream->update();
|
||||
return (m_bBusyP1) ? 1 : 0;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(s14001a_new_device::data_w)
|
||||
{
|
||||
m_stream->update();
|
||||
m_uWord = data & 0x3f; // C0-C5
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(s14001a_new_device::start_w)
|
||||
{
|
||||
m_stream->update();
|
||||
m_bStart = (state != 0);
|
||||
if (m_bStart) m_uStateP1 = WORDWAIT;
|
||||
}
|
||||
|
||||
void s14001a_new_device::set_clock(UINT32 clock)
|
||||
{
|
||||
m_stream->update();
|
||||
m_stream->set_sample_rate(clock);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
Device emulation
|
||||
**************************************************************************/
|
||||
|
||||
UINT8 s14001a_new_device::readmem(UINT16 offset, bool phase)
|
||||
{
|
||||
offset &= 0xfff; // 11-bit internal
|
||||
return ((m_ext_read_handler.isnull()) ? m_SpeechRom[offset & (m_SpeechRom.bytes() - 1)] : m_ext_read_handler(offset));
|
||||
}
|
||||
|
||||
bool s14001a_new_device::Clock()
|
||||
{
|
||||
// effectively toggles external clock twice, one cycle
|
||||
// internal clock toggles on external clock transition from 0 to 1 so internal clock will always transition here
|
||||
// return false if some emulator problem detected
|
||||
|
||||
// On the actual chip, all register phase 1 values needed to be refreshed from phase 2 values
|
||||
// or else risk losing their state due to charge loss.
|
||||
// But on a computer the values are static.
|
||||
// So to reduce code clutter, phase 1 values are only modified if they are different
|
||||
// from the preceeding phase 2 values.
|
||||
|
||||
if (m_bPhase1)
|
||||
{
|
||||
// transition to phase2
|
||||
m_bPhase1 = false;
|
||||
|
||||
// transfer phase1 variables to phase2
|
||||
m_uStateP2 = m_uStateP1;
|
||||
m_uDAR13To05P2 = m_uDAR13To05P1;
|
||||
m_uDAR04To00P2 = m_uDAR04To00P1;
|
||||
m_uCWARP2 = m_uCWARP1;
|
||||
m_bStopP2 = m_bStopP1;
|
||||
m_bVoicedP2 = m_bVoicedP1;
|
||||
m_bSilenceP2 = m_bSilenceP1;
|
||||
m_uLengthP2 = m_uLengthP1;
|
||||
m_uXRepeatP2 = m_uXRepeatP1;
|
||||
m_uDeltaOldP2 = m_uDeltaOldP1;
|
||||
|
||||
m_uOutputP2 = m_uOutputP1;
|
||||
m_uRomAddrP2 = m_RomAddrP1;
|
||||
|
||||
// setup carries from phase 2 values
|
||||
m_bDAR04To00CarryP2 = m_uDAR04To00P2 == 0x1F;
|
||||
m_bPPQCarryP2 = m_bDAR04To00CarryP2 && ((m_uLengthP2&0x03) == 0x03); // pitch period quarter
|
||||
m_bRepeatCarryP2 = m_bPPQCarryP2 && ((m_uLengthP2&0x0C) == 0x0C);
|
||||
m_bLengthCarryP2 = m_bRepeatCarryP2 && ( m_uLengthP2 == 0x7F);
|
||||
|
||||
return true;
|
||||
}
|
||||
m_bPhase1 = true;
|
||||
|
||||
// logic done during phase 1
|
||||
switch (m_uStateP1)
|
||||
{
|
||||
case IDLE:
|
||||
m_uOutputP1 = 7;
|
||||
if (m_bStart) m_uStateP1 = WORDWAIT;
|
||||
|
||||
if (m_bBusyP1 && !m_bsy_handler.isnull())
|
||||
m_bsy_handler(0);
|
||||
m_bBusyP1 = false;
|
||||
break;
|
||||
|
||||
case WORDWAIT:
|
||||
// the delta address register latches the word number into bits 03 to 08
|
||||
// all other bits forced to 0. 04 to 08 makes a multiply by two.
|
||||
m_uDAR13To05P1 = (m_uWord&0x3C)>>2;
|
||||
m_uDAR04To00P1 = (m_uWord&0x03)<<3;
|
||||
m_RomAddrP1 = (m_uDAR13To05P1<<3)|(m_uDAR04To00P1>>2); // remove lower two bits
|
||||
m_uOutputP1 = 7;
|
||||
if (m_bStart) m_uStateP1 = WORDWAIT;
|
||||
else m_uStateP1 = CWARMSB;
|
||||
|
||||
if (!m_bBusyP1 && !m_bsy_handler.isnull())
|
||||
m_bsy_handler(1);
|
||||
m_bBusyP1 = true;
|
||||
break;
|
||||
|
||||
case CWARMSB:
|
||||
if (m_uPrintLevel >= 1)
|
||||
printf("\n speaking word %02x",m_uWord);
|
||||
|
||||
// use uDAR to load uCWAR 8 msb
|
||||
m_uCWARP1 = readmem(m_uRomAddrP2,m_bPhase1)<<4; // note use of rom address setup in previous state
|
||||
// increment DAR by 4, 2 lsb's count deltas within a byte
|
||||
m_uDAR04To00P1 += 4;
|
||||
if (m_uDAR04To00P1 >= 32) m_uDAR04To00P1 = 0; // emulate 5 bit counter
|
||||
m_RomAddrP1 = (m_uDAR13To05P1<<3)|(m_uDAR04To00P1>>2); // remove lower two bits
|
||||
|
||||
m_uOutputP1 = 7;
|
||||
if (m_bStart) m_uStateP1 = WORDWAIT;
|
||||
else m_uStateP1 = CWARLSB;
|
||||
break;
|
||||
|
||||
case CWARLSB:
|
||||
m_uCWARP1 = m_uCWARP2|(readmem(m_uRomAddrP2,m_bPhase1)>>4); // setup in previous state
|
||||
m_RomAddrP1 = m_uCWARP1;
|
||||
|
||||
m_uOutputP1 = 7;
|
||||
if (m_bStart) m_uStateP1 = WORDWAIT;
|
||||
else m_uStateP1 = DARMSB;
|
||||
break;
|
||||
|
||||
case DARMSB:
|
||||
m_uDAR13To05P1 = readmem(m_uRomAddrP2,m_bPhase1)<<1; // 9 bit counter, 8 MSBs from ROM, lsb zeroed
|
||||
m_uDAR04To00P1 = 0;
|
||||
m_uCWARP1++;
|
||||
m_RomAddrP1 = m_uCWARP1;
|
||||
m_uNControlWords++; // statistics
|
||||
|
||||
m_uOutputP1 = 7;
|
||||
if (m_bStart) m_uStateP1 = WORDWAIT;
|
||||
else m_uStateP1 = CTRLBITS;
|
||||
break;
|
||||
|
||||
case CTRLBITS:
|
||||
m_bStopP1 = readmem(m_uRomAddrP2,m_bPhase1)&0x80? true: false;
|
||||
m_bVoicedP1 = readmem(m_uRomAddrP2,m_bPhase1)&0x40? true: false;
|
||||
m_bSilenceP1 = readmem(m_uRomAddrP2,m_bPhase1)&0x20? true: false;
|
||||
m_uXRepeatP1 = readmem(m_uRomAddrP2,m_bPhase1)&0x03;
|
||||
m_uLengthP1 =(readmem(m_uRomAddrP2,m_bPhase1)&0x1F)<<2; // includes external length and repeat
|
||||
m_uDAR04To00P1 = 0;
|
||||
m_uCWARP1++; // gets ready for next DARMSB
|
||||
m_RomAddrP1 = (m_uDAR13To05P1<<3)|(m_uDAR04To00P1>>2); // remove lower two bits
|
||||
|
||||
m_uOutputP1 = 7;
|
||||
if (m_bStart) m_uStateP1 = WORDWAIT;
|
||||
else m_uStateP1 = PLAY;
|
||||
|
||||
if (m_uPrintLevel >= 2)
|
||||
printf("\n cw %d %d %d %d %d",m_bStopP1,m_bVoicedP1,m_bSilenceP1,m_uLengthP1>>4,m_uXRepeatP1);
|
||||
|
||||
break;
|
||||
|
||||
case PLAY:
|
||||
{
|
||||
// statistics
|
||||
if (m_bPPQCarryP2)
|
||||
{
|
||||
// pitch period end
|
||||
if (m_uPrintLevel >= 3)
|
||||
printf("\n ppe: RomAddr %03x",m_uRomAddrP2);
|
||||
|
||||
m_uNPitchPeriods++;
|
||||
if (m_bVoicedP2) m_uNVoiced++;
|
||||
}
|
||||
// end statistics
|
||||
|
||||
// modify output
|
||||
UINT8 uDeltaP2; // signal line
|
||||
UINT8 uIncrementP2; // signal lines
|
||||
bool bAddP2; // signal line
|
||||
uDeltaP2 = Mux8To2(m_bVoicedP2,
|
||||
m_uLengthP2 & 0x03, // pitch period quater counter
|
||||
m_uDAR04To00P2 & 0x03, // two bit delta address within byte
|
||||
readmem(m_uRomAddrP2,m_bPhase1)
|
||||
);
|
||||
CalculateIncrement(m_bVoicedP2,
|
||||
m_uLengthP2 & 0x03, // pitch period quater counter
|
||||
m_uDAR04To00P2 == 0, // pitch period quarter start
|
||||
uDeltaP2,
|
||||
m_uDeltaOldP2, // input
|
||||
m_uDeltaOldP1, // output
|
||||
uIncrementP2, // output 0, 1, or 3
|
||||
bAddP2 // output
|
||||
);
|
||||
m_uOutputP1 = CalculateOutput(m_bVoicedP2,
|
||||
m_bSilenceP2,
|
||||
m_uLengthP2 & 0x03, // pitch period quater counter
|
||||
m_uDAR04To00P2 == 0, // pitch period quarter start
|
||||
m_uOutputP2, // last output
|
||||
uIncrementP2,
|
||||
bAddP2
|
||||
);
|
||||
|
||||
// advance counters
|
||||
m_uDAR04To00P1++;
|
||||
if (m_bDAR04To00CarryP2) // pitch period quarter end
|
||||
{
|
||||
m_uDAR04To00P1 = 0; // emulate 5 bit counter
|
||||
|
||||
m_uLengthP1++; // lower two bits of length count quarter pitch periods
|
||||
if (m_uLengthP1 >= 0x80)
|
||||
{
|
||||
m_uLengthP1 = 0; // emulate 7 bit counter
|
||||
}
|
||||
}
|
||||
|
||||
if (m_bVoicedP2 && m_bRepeatCarryP2) // repeat complete
|
||||
{
|
||||
m_uLengthP1 &= 0x70; // keep current "length"
|
||||
m_uLengthP1 |= (m_uXRepeatP1<<2); // load repeat from external repeat
|
||||
m_uDAR13To05P1++; // advances ROM address 8 bytes
|
||||
if (m_uDAR13To05P1 >= 0x200) m_uDAR13To05P1 = 0; // emulate 9 bit counter
|
||||
}
|
||||
if (!m_bVoicedP2 && m_bDAR04To00CarryP2)
|
||||
{
|
||||
// unvoiced advances each quarter pitch period
|
||||
// note repeat counter not reloaded for non voiced speech
|
||||
m_uDAR13To05P1++; // advances ROM address 8 bytes
|
||||
if (m_uDAR13To05P1 >= 0x200) m_uDAR13To05P1 = 0; // emulate 9 bit counter
|
||||
}
|
||||
|
||||
// construct m_RomAddrP1
|
||||
m_RomAddrP1 = m_uDAR04To00P1;
|
||||
if (m_bVoicedP2 && m_uLengthP1&0x1) // mirroring
|
||||
{
|
||||
m_RomAddrP1 ^= 0x1f; // count backwards
|
||||
}
|
||||
m_RomAddrP1 = (m_uDAR13To05P1<<3) | m_RomAddrP1>>2;
|
||||
|
||||
// next state
|
||||
if (m_bStart) m_uStateP1 = WORDWAIT;
|
||||
else if (m_bStopP2 && m_bLengthCarryP2) m_uStateP1 = DELAY;
|
||||
else if (m_bLengthCarryP2)
|
||||
{
|
||||
m_uStateP1 = DARMSB;
|
||||
m_RomAddrP1 = m_uCWARP1; // output correct address
|
||||
}
|
||||
else m_uStateP1 = PLAY;
|
||||
break;
|
||||
}
|
||||
|
||||
case DELAY:
|
||||
m_uOutputP1 = 7;
|
||||
if (m_bStart) m_uStateP1 = WORDWAIT;
|
||||
else m_uStateP1 = IDLE;
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
UINT8 s14001a_new_device::Mux8To2(bool bVoicedP2, UINT8 uPPQtrP2, UINT8 uDeltaAdrP2, UINT8 uRomDataP2)
|
||||
{
|
||||
// pick two bits of rom data as delta
|
||||
|
||||
if (bVoicedP2 && uPPQtrP2&0x01) // mirroring
|
||||
{
|
||||
uDeltaAdrP2 ^= 0x03; // count backwards
|
||||
}
|
||||
// emulate 8 to 2 mux to obtain delta from byte (bigendian)
|
||||
switch (uDeltaAdrP2)
|
||||
{
|
||||
case 0x00:
|
||||
return (uRomDataP2&0xC0)>>6;
|
||||
case 0x01:
|
||||
return (uRomDataP2&0x30)>>4;
|
||||
case 0x02:
|
||||
return (uRomDataP2&0x0C)>>2;
|
||||
case 0x03:
|
||||
return (uRomDataP2&0x03)>>0;
|
||||
}
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
void s14001a_new_device::CalculateIncrement(bool bVoicedP2, UINT8 uPPQtrP2, bool bPPQStartP2, UINT8 uDelta, UINT8 uDeltaOldP2, UINT8 &uDeltaOldP1, UINT8 &uIncrementP2, bool &bAddP2)
|
||||
{
|
||||
// uPPQtr, pitch period quarter counter; 2 lsb of uLength
|
||||
// bPPStart, start of a pitch period
|
||||
// implemented to mimic silicon (a bit)
|
||||
|
||||
// beginning of a pitch period
|
||||
if (uPPQtrP2 == 0x00 && bPPQStartP2) // note this is done for voiced and unvoiced
|
||||
{
|
||||
uDeltaOldP2 = 0x02;
|
||||
}
|
||||
static const UINT8 uIncrements[4][4] =
|
||||
{
|
||||
// 00 01 10 11
|
||||
{ 3, 3, 1, 1,}, // 00
|
||||
{ 1, 1, 0, 0,}, // 01
|
||||
{ 0, 0, 1, 1,}, // 10
|
||||
{ 1, 1, 3, 3 }, // 11
|
||||
};
|
||||
|
||||
#define MIRROR (uPPQtrP2&0x01)
|
||||
|
||||
// calculate increment from delta, always done even if silent to update uDeltaOld
|
||||
// in silicon a PLA determined 0,1,3 and add/subtract and passed uDelta to uDeltaOld
|
||||
if (!bVoicedP2 || !MIRROR)
|
||||
{
|
||||
uIncrementP2 = uIncrements[uDelta][uDeltaOldP2];
|
||||
bAddP2 = uDelta >= 0x02;
|
||||
}
|
||||
else
|
||||
{
|
||||
uIncrementP2 = uIncrements[uDeltaOldP2][uDelta];
|
||||
bAddP2 = uDeltaOldP2 < 0x02;
|
||||
}
|
||||
uDeltaOldP1 = uDelta;
|
||||
if (bVoicedP2 && bPPQStartP2 && MIRROR) uIncrementP2 = 0; // no change when first starting mirroring
|
||||
}
|
||||
|
||||
UINT8 s14001a_new_device::CalculateOutput(bool bVoiced, bool bXSilence, UINT8 uPPQtr, bool bPPQStart, UINT8 uLOutput, UINT8 uIncrementP2, bool bAddP2)
|
||||
{
|
||||
// implemented to mimic silicon (a bit)
|
||||
// limits output to 0x00 and 0x0f
|
||||
UINT8 uTmp; // used for subtraction
|
||||
|
||||
#define SILENCE (uPPQtr&0x02)
|
||||
|
||||
// determine output
|
||||
if (bXSilence || (bVoiced && SILENCE)) return 7;
|
||||
|
||||
// beginning of a pitch period
|
||||
if (uPPQtr == 0x00 && bPPQStart) // note this is done for voiced and nonvoiced
|
||||
{
|
||||
uLOutput = 7;
|
||||
}
|
||||
|
||||
// adder
|
||||
uTmp = uLOutput;
|
||||
if (!bAddP2) uTmp ^= 0x0F; // turns subtraction into addition
|
||||
|
||||
// add 0, 1, 3; limit at 15
|
||||
uTmp += uIncrementP2;
|
||||
if (uTmp > 15) uTmp = 15;
|
||||
|
||||
if (!bAddP2) uTmp ^= 0x0F; // turns addition back to subtraction
|
||||
return uTmp;
|
||||
}
|
||||
|
||||
void s14001a_new_device::ClearStatistics()
|
||||
{
|
||||
m_uNPitchPeriods = 0;
|
||||
m_uNVoiced = 0;
|
||||
m_uPrintLevel = 0;
|
||||
m_uNControlWords = 0;
|
||||
}
|
||||
|
||||
void s14001a_new_device::GetStatistics(UINT32 &uNPitchPeriods, UINT32 &uNVoiced, UINT32 uNControlWords)
|
||||
{
|
||||
uNPitchPeriods = m_uNPitchPeriods;
|
||||
uNVoiced = m_uNVoiced;
|
||||
uNControlWords = m_uNControlWords;
|
||||
}
|
@ -1,138 +0,0 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ed Bernard, Jonathan Gevaryahu, hap
|
||||
// thanks-to:Kevin Horton
|
||||
/*
|
||||
SSi TSI S14001A speech IC emulator
|
||||
*/
|
||||
|
||||
#ifndef __S14001A_H__
|
||||
#define __S14001A_H__
|
||||
|
||||
#define MCFG_S14001A_BSY_HANDLER(_devcb) \
|
||||
devcb = &s14001a_new_device::set_bsy_handler(*device, DEVCB_##_devcb);
|
||||
|
||||
#define MCFG_S14001A_EXT_READ_HANDLER(_devcb) \
|
||||
devcb = &s14001a_new_device::set_ext_read_handler(*device, DEVCB_##_devcb);
|
||||
|
||||
|
||||
class s14001a_new_device : public device_t,
|
||||
public device_sound_interface
|
||||
{
|
||||
public:
|
||||
s14001a_new_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
~s14001a_new_device() {}
|
||||
|
||||
// static configuration helpers
|
||||
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); }
|
||||
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); }
|
||||
|
||||
DECLARE_READ_LINE_MEMBER(busy_r); // /BUSY (pin 40)
|
||||
DECLARE_READ_LINE_MEMBER(romen_r); // ROM /EN (pin 9)
|
||||
DECLARE_WRITE_LINE_MEMBER(start_w); // START (pin 10)
|
||||
DECLARE_WRITE8_MEMBER(data_w); // 6-bit word
|
||||
|
||||
void set_clock(UINT32 clock); // set new CLK frequency
|
||||
void force_update(); // update stream, eg. before external ROM bankswitch
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start() override;
|
||||
|
||||
// sound stream update overrides
|
||||
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override;
|
||||
|
||||
private:
|
||||
required_region_ptr<UINT8> m_SpeechRom;
|
||||
sound_stream * m_stream;
|
||||
|
||||
devcb_write_line m_bsy_handler;
|
||||
devcb_read8 m_ext_read_handler;
|
||||
|
||||
UINT8 readmem(UINT16 offset, bool phase);
|
||||
bool Clock(); // called once to toggle external clock twice
|
||||
|
||||
// emulator helper functions
|
||||
UINT8 Mux8To2(bool bVoicedP2, UINT8 uPPQtrP2, UINT8 uDeltaAdrP2, UINT8 uRomDataP2);
|
||||
void CalculateIncrement(bool bVoicedP2, UINT8 uPPQtrP2, bool bPPQStartP2, UINT8 uDeltaP2, UINT8 uDeltaOldP2, UINT8 &uDeltaOldP1, UINT8 &uIncrementP2, bool &bAddP2);
|
||||
UINT8 CalculateOutput(bool bVoicedP2, bool bXSilenceP2, UINT8 uPPQtrP2, bool bPPQStartP2, UINT8 uLOutputP2, UINT8 uIncrementP2, bool bAddP2);
|
||||
void ClearStatistics();
|
||||
void GetStatistics(UINT32 &uNPitchPeriods, UINT32 &uNVoiced, UINT32 uNControlWords);
|
||||
void SetPrintLevel(UINT32 uPrintLevel) { m_uPrintLevel = uPrintLevel; }
|
||||
|
||||
// internal state
|
||||
bool m_bPhase1; // 1 bit internal clock
|
||||
|
||||
enum states
|
||||
{
|
||||
IDLE = 0,
|
||||
WORDWAIT,
|
||||
CWARMSB, // read 8 CWAR MSBs
|
||||
CWARLSB, // read 4 CWAR LSBs from rom d7-d4
|
||||
DARMSB, // read 8 DAR MSBs
|
||||
CTRLBITS, // read Stop, Voiced, Silence, Length, XRepeat
|
||||
PLAY,
|
||||
DELAY
|
||||
};
|
||||
|
||||
// registers
|
||||
states m_uStateP1; // 3 bits
|
||||
states m_uStateP2;
|
||||
|
||||
UINT16 m_uDAR13To05P1; // 9 MSBs of delta address register
|
||||
UINT16 m_uDAR13To05P2; // incrementing uDAR05To13 advances ROM address by 8 bytes
|
||||
|
||||
UINT16 m_uDAR04To00P1; // 5 LSBs of delta address register
|
||||
UINT16 m_uDAR04To00P2; // 3 address ROM, 2 mux 8 bits of data into 2 bit delta
|
||||
// carry indicates end of quarter pitch period (32 cycles)
|
||||
|
||||
UINT16 m_uCWARP1; // 12 bits Control Word Address Register (syllable)
|
||||
UINT16 m_uCWARP2;
|
||||
|
||||
bool m_bStopP1;
|
||||
bool m_bStopP2;
|
||||
bool m_bVoicedP1;
|
||||
bool m_bVoicedP2;
|
||||
bool m_bSilenceP1;
|
||||
bool m_bSilenceP2;
|
||||
UINT8 m_uLengthP1; // 7 bits, upper three loaded from ROM length
|
||||
UINT8 m_uLengthP2; // middle two loaded from ROM repeat and/or uXRepeat
|
||||
// bit 0 indicates mirror in voiced mode
|
||||
// bit 1 indicates internal silence in voiced mode
|
||||
// incremented each pitch period quarter
|
||||
|
||||
UINT8 m_uXRepeatP1; // 2 bits, loaded from ROM repeat
|
||||
UINT8 m_uXRepeatP2;
|
||||
UINT8 m_uDeltaOldP1; // 2 bit old delta
|
||||
UINT8 m_uDeltaOldP2;
|
||||
UINT8 m_uOutputP1; // 4 bits audio output, calculated during phase 1
|
||||
|
||||
// derived signals
|
||||
bool m_bDAR04To00CarryP2;
|
||||
bool m_bPPQCarryP2;
|
||||
bool m_bRepeatCarryP2;
|
||||
bool m_bLengthCarryP2;
|
||||
UINT16 m_RomAddrP1; // rom address
|
||||
|
||||
// output pins
|
||||
UINT8 m_uOutputP2; // output changes on phase2
|
||||
UINT16 m_uRomAddrP2; // address pins change on phase 2
|
||||
bool m_bBusyP1; // busy changes on phase 1
|
||||
|
||||
// input pins
|
||||
bool m_bStart;
|
||||
UINT8 m_uWord; // 6 bit word noumber to be spoken
|
||||
|
||||
// emulator variables
|
||||
// statistics
|
||||
UINT32 m_uNPitchPeriods;
|
||||
UINT32 m_uNVoiced;
|
||||
UINT32 m_uNControlWords;
|
||||
|
||||
// diagnostic output
|
||||
UINT32 m_uPrintLevel;
|
||||
};
|
||||
|
||||
extern const device_type S14001A_NEW;
|
||||
|
||||
|
||||
#endif /* __S14001A_H__ */
|
@ -15,7 +15,7 @@
|
||||
#include "audio/exidy.h"
|
||||
#include "machine/74181.h"
|
||||
#include "machine/nvram.h"
|
||||
#include "sound/s14001a_new.h"
|
||||
#include "sound/s14001a.h"
|
||||
#include "video/resnet.h"
|
||||
|
||||
|
||||
@ -35,7 +35,7 @@ public:
|
||||
{ }
|
||||
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<s14001a_new_device> m_s14001a;
|
||||
required_device<s14001a_device> m_s14001a;
|
||||
required_device<ttl74181_device> m_ls181_10c;
|
||||
required_device<ttl74181_device> m_ls181_12c;
|
||||
required_device<exidy_sound_device> m_custom;
|
||||
@ -1120,7 +1120,7 @@ static MACHINE_CONFIG_START( berzerk, berzerk_state )
|
||||
/* audio hardware */
|
||||
MCFG_SPEAKER_STANDARD_MONO("mono")
|
||||
|
||||
MCFG_SOUND_ADD("speech", S14001A_NEW, S14001_CLOCK/16/8) /* placeholder - the clock is software controllable */
|
||||
MCFG_SOUND_ADD("speech", S14001A, S14001_CLOCK/16/8) /* placeholder - the clock is software controllable */
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
|
||||
MCFG_SOUND_ADD("exidy", EXIDY, 0)
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.33)
|
||||
|
@ -332,7 +332,7 @@ static MACHINE_CONFIG_START( csc, fidel6502_state )
|
||||
|
||||
/* sound hardware */
|
||||
MCFG_SPEAKER_STANDARD_MONO("mono")
|
||||
MCFG_SOUND_ADD("speech", S14001A_NEW, 25000) // around 25khz
|
||||
MCFG_SOUND_ADD("speech", S14001A, 25000) // around 25khz
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.75)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
|
@ -1430,7 +1430,7 @@ static MACHINE_CONFIG_START( vcc, fidelz80_state )
|
||||
|
||||
/* sound hardware */
|
||||
MCFG_SPEAKER_STANDARD_MONO("mono")
|
||||
MCFG_SOUND_ADD("speech", S14001A_NEW, 25000) // R/C circuit, around 25khz
|
||||
MCFG_SOUND_ADD("speech", S14001A, 25000) // R/C circuit, around 25khz
|
||||
MCFG_S14001A_EXT_READ_HANDLER(READ8(fidelz80_state, vcc_speech_r))
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.75)
|
||||
MACHINE_CONFIG_END
|
||||
@ -1458,7 +1458,7 @@ static MACHINE_CONFIG_START( vsc, fidelz80_state )
|
||||
|
||||
/* sound hardware */
|
||||
MCFG_SPEAKER_STANDARD_MONO("mono")
|
||||
MCFG_SOUND_ADD("speech", S14001A_NEW, 25000) // R/C circuit, around 25khz
|
||||
MCFG_SOUND_ADD("speech", S14001A, 25000) // R/C circuit, around 25khz
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.75)
|
||||
|
||||
MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0)
|
||||
@ -1483,7 +1483,7 @@ static MACHINE_CONFIG_START( vbrc, fidelz80_state )
|
||||
|
||||
/* sound hardware */
|
||||
MCFG_SPEAKER_STANDARD_MONO("mono")
|
||||
MCFG_SOUND_ADD("speech", S14001A_NEW, 25000) // R/C circuit, around 25khz
|
||||
MCFG_SOUND_ADD("speech", S14001A, 25000) // R/C circuit, around 25khz
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.75)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
|
@ -19,7 +19,7 @@ ToDo:
|
||||
#include "machine/genpin.h"
|
||||
#include "cpu/m6800/m6800.h"
|
||||
#include "machine/6821pia.h"
|
||||
#include "sound/s14001a_new.h"
|
||||
#include "sound/s14001a.h"
|
||||
#include "st_mp200.lh"
|
||||
|
||||
#define S14001_CLOCK (25e5)
|
||||
@ -81,7 +81,7 @@ private:
|
||||
virtual void machine_start() override;
|
||||
virtual void machine_reset() override;
|
||||
required_device<m6800_cpu_device> m_maincpu;
|
||||
optional_device<s14001a_new_device> m_s14001a;
|
||||
optional_device<s14001a_device> m_s14001a;
|
||||
required_device<pia6821_device> m_pia_u10;
|
||||
required_device<pia6821_device> m_pia_u11;
|
||||
required_ioport m_io_test;
|
||||
@ -619,7 +619,7 @@ MACHINE_CONFIG_END
|
||||
|
||||
static MACHINE_CONFIG_DERIVED( st_mp201, st_mp200 )
|
||||
MCFG_SPEAKER_STANDARD_MONO("mono")
|
||||
MCFG_SOUND_ADD("speech", S14001A_NEW, S14001_CLOCK)
|
||||
MCFG_SOUND_ADD("speech", S14001A, S14001_CLOCK)
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
|
@ -319,7 +319,7 @@ static MACHINE_CONFIG_START( wolfpack, wolfpack_state )
|
||||
|
||||
/* sound hardware */
|
||||
MCFG_SPEAKER_STANDARD_MONO("mono")
|
||||
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 */
|
||||
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 */
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
******************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "sound/s14001a_new.h"
|
||||
#include "sound/s14001a.h"
|
||||
|
||||
class fidelz80base_state : public driver_device
|
||||
{
|
||||
@ -26,7 +26,7 @@ public:
|
||||
// devices/pointers
|
||||
required_device<cpu_device> m_maincpu;
|
||||
optional_ioport_array<10> m_inp_matrix; // max 10
|
||||
optional_device<s14001a_new_device> m_speech;
|
||||
optional_device<s14001a_device> m_speech;
|
||||
optional_region_ptr<UINT8> m_speech_rom;
|
||||
|
||||
// misc common
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "sound/s14001a_new.h"
|
||||
#include "sound/s14001a.h"
|
||||
|
||||
class wolfpack_state : public driver_device
|
||||
{
|
||||
@ -29,7 +29,7 @@ public:
|
||||
// devices, pointers
|
||||
required_shared_ptr<UINT8> m_alpha_num_ram;
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<s14001a_new_device> m_s14001a;
|
||||
required_device<s14001a_device> m_s14001a;
|
||||
required_device<gfxdecode_device> m_gfxdecode;
|
||||
required_device<screen_device> m_screen;
|
||||
required_device<palette_device> m_palette;
|
||||
|
Loading…
Reference in New Issue
Block a user