s14001a_new: small cleanup
This commit is contained in:
parent
a9e8924e7b
commit
cfa9bc1697
@ -33,7 +33,6 @@ void s14001a_new_device::device_start()
|
|||||||
m_bsy_handler.resolve();
|
m_bsy_handler.resolve();
|
||||||
|
|
||||||
m_uOutputP1 = m_uOutputP2 = 7;
|
m_uOutputP1 = m_uOutputP2 = 7;
|
||||||
//m_uPrintLevel = 10;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -46,38 +45,40 @@ void s14001a_new_device::sound_stream_update(sound_stream &stream, stream_sample
|
|||||||
for (int i = 0; i < samples; i++)
|
for (int i = 0; i < samples; i++)
|
||||||
{
|
{
|
||||||
Clock();
|
Clock();
|
||||||
outputs[0][i] = ((((INT16)GetOutput())-7)<<10)*15;
|
INT16 sample = INT16(m_uOutputP2) - 7;
|
||||||
|
outputs[0][i] = sample * 0x4000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
void s14001a_new_device::force_update()
|
void s14001a_new_device::force_update()
|
||||||
{
|
{
|
||||||
m_stream->update();
|
m_stream->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
int s14001a_new_device::bsy_r()
|
READ_LINE_MEMBER(s14001a_new_device::romclock_r)
|
||||||
{
|
{
|
||||||
m_stream->update();
|
m_stream->update();
|
||||||
return (GetBusy()) ? 1 : 0;
|
return (m_bPhase1) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void s14001a_new_device::reg_w(int data)
|
READ_LINE_MEMBER(s14001a_new_device::busy_r)
|
||||||
{
|
{
|
||||||
m_stream->update();
|
m_stream->update();
|
||||||
SetWord(data);
|
return (m_bBusyP1) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void s14001a_new_device::rst_w(int data)
|
WRITE8_MEMBER(s14001a_new_device::data_w)
|
||||||
{
|
{
|
||||||
m_stream->update();
|
m_stream->update();
|
||||||
SetStart(data != 0);
|
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;
|
if (m_bStart) m_uStateP1 = WORDWAIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,6 +91,11 @@ void s14001a_new_device::set_clock(int clock)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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()
|
bool s14001a_new_device::Clock()
|
||||||
{
|
{
|
||||||
@ -136,27 +142,30 @@ bool s14001a_new_device::Clock()
|
|||||||
// logic done during phase 1
|
// logic done during phase 1
|
||||||
switch (m_uStateP1)
|
switch (m_uStateP1)
|
||||||
{
|
{
|
||||||
// 0
|
|
||||||
case IDLE:
|
case IDLE:
|
||||||
m_bBusyP1 = false;
|
|
||||||
m_uOutputP1 = 7;
|
m_uOutputP1 = 7;
|
||||||
if (m_bStart) m_uStateP1 = WORDWAIT;
|
if (m_bStart) m_uStateP1 = WORDWAIT;
|
||||||
|
|
||||||
|
if (m_bBusyP1 && !m_bsy_handler.isnull())
|
||||||
|
m_bsy_handler(0);
|
||||||
|
m_bBusyP1 = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// 1
|
|
||||||
case WORDWAIT:
|
case WORDWAIT:
|
||||||
// the delta address register latches the word number into bits 03 to 08
|
// 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.
|
// all other bits forced to 0. 04 to 08 makes a multiply by two.
|
||||||
m_uDAR13To05P1 = (m_uWord&0x3C)>>2;
|
m_uDAR13To05P1 = (m_uWord&0x3C)>>2;
|
||||||
m_uDAR04To00P1 = (m_uWord&0x03)<<3;
|
m_uDAR04To00P1 = (m_uWord&0x03)<<3;
|
||||||
m_RomAddrP1 = (m_uDAR13To05P1<<3)|(m_uDAR04To00P1>>2); // remove lower two bits
|
m_RomAddrP1 = (m_uDAR13To05P1<<3)|(m_uDAR04To00P1>>2); // remove lower two bits
|
||||||
m_bBusyP1 = true;
|
|
||||||
m_uOutputP1 = 7;
|
m_uOutputP1 = 7;
|
||||||
if (m_bStart) m_uStateP1 = WORDWAIT;
|
if (m_bStart) m_uStateP1 = WORDWAIT;
|
||||||
else m_uStateP1 = CWARMSB;
|
else m_uStateP1 = CWARMSB;
|
||||||
|
|
||||||
|
if (!m_bBusyP1 && !m_bsy_handler.isnull())
|
||||||
|
m_bsy_handler(1);
|
||||||
|
m_bBusyP1 = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// 2
|
|
||||||
case CWARMSB:
|
case CWARMSB:
|
||||||
if (m_uPrintLevel >= 1)
|
if (m_uPrintLevel >= 1)
|
||||||
printf("\n speaking word %02x",m_uWord);
|
printf("\n speaking word %02x",m_uWord);
|
||||||
@ -173,7 +182,6 @@ bool s14001a_new_device::Clock()
|
|||||||
else m_uStateP1 = CWARLSB;
|
else m_uStateP1 = CWARLSB;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// 3
|
|
||||||
case CWARLSB:
|
case CWARLSB:
|
||||||
m_uCWARP1 = m_uCWARP2|(readmem(m_uRomAddrP2,m_bPhase1)>>4); // setup in previous state
|
m_uCWARP1 = m_uCWARP2|(readmem(m_uRomAddrP2,m_bPhase1)>>4); // setup in previous state
|
||||||
m_RomAddrP1 = m_uCWARP1;
|
m_RomAddrP1 = m_uCWARP1;
|
||||||
@ -183,7 +191,6 @@ bool s14001a_new_device::Clock()
|
|||||||
else m_uStateP1 = DARMSB;
|
else m_uStateP1 = DARMSB;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// 4
|
|
||||||
case DARMSB:
|
case DARMSB:
|
||||||
m_uDAR13To05P1 = readmem(m_uRomAddrP2,m_bPhase1)<<1; // 9 bit counter, 8 MSBs from ROM, lsb zeroed
|
m_uDAR13To05P1 = readmem(m_uRomAddrP2,m_bPhase1)<<1; // 9 bit counter, 8 MSBs from ROM, lsb zeroed
|
||||||
m_uDAR04To00P1 = 0;
|
m_uDAR04To00P1 = 0;
|
||||||
@ -196,7 +203,6 @@ bool s14001a_new_device::Clock()
|
|||||||
else m_uStateP1 = CTRLBITS;
|
else m_uStateP1 = CTRLBITS;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// 5
|
|
||||||
case CTRLBITS:
|
case CTRLBITS:
|
||||||
m_bStopP1 = readmem(m_uRomAddrP2,m_bPhase1)&0x80? true: false;
|
m_bStopP1 = readmem(m_uRomAddrP2,m_bPhase1)&0x80? true: false;
|
||||||
m_bVoicedP1 = readmem(m_uRomAddrP2,m_bPhase1)&0x40? true: false;
|
m_bVoicedP1 = readmem(m_uRomAddrP2,m_bPhase1)&0x40? true: false;
|
||||||
@ -216,7 +222,6 @@ bool s14001a_new_device::Clock()
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// 6
|
|
||||||
case PLAY:
|
case PLAY:
|
||||||
{
|
{
|
||||||
// statistics
|
// statistics
|
||||||
@ -306,7 +311,6 @@ bool s14001a_new_device::Clock()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 7
|
|
||||||
case DELAY:
|
case DELAY:
|
||||||
m_uOutputP1 = 7;
|
m_uOutputP1 = 7;
|
||||||
if (m_bStart) m_uStateP1 = WORDWAIT;
|
if (m_bStart) m_uStateP1 = WORDWAIT;
|
||||||
@ -351,7 +355,7 @@ void s14001a_new_device::CalculateIncrement(bool bVoicedP2, UINT8 uPPQtrP2, bool
|
|||||||
{
|
{
|
||||||
uDeltaOldP2 = 0x02;
|
uDeltaOldP2 = 0x02;
|
||||||
}
|
}
|
||||||
static UINT8 uIncrements[4][4] =
|
static const UINT8 uIncrements[4][4] =
|
||||||
{
|
{
|
||||||
// 00 01 10 11
|
// 00 01 10 11
|
||||||
{ 3, 3, 1, 1,}, // 00
|
{ 3, 3, 1, 1,}, // 00
|
||||||
|
@ -22,30 +22,11 @@ public:
|
|||||||
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_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); }
|
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); }
|
||||||
|
|
||||||
bool Clock(); // called once to toggle external clock twice
|
DECLARE_READ_LINE_MEMBER(busy_r);
|
||||||
|
DECLARE_READ_LINE_MEMBER(romclock_r);
|
||||||
|
DECLARE_WRITE_LINE_MEMBER(start_w);
|
||||||
|
DECLARE_WRITE8_MEMBER(data_w);
|
||||||
|
|
||||||
// output pin data
|
|
||||||
UINT16 GetRomAddr() { return m_uRomAddrP2; }
|
|
||||||
UINT8 GetOutput() { return m_uOutputP2; }
|
|
||||||
bool GetAddressRead() { return m_bPhase1; }
|
|
||||||
bool GetBusy() { return m_bBusyP1; }
|
|
||||||
|
|
||||||
// input pin data
|
|
||||||
void SetStart(bool bStart) { m_bStart = bStart; }
|
|
||||||
void SetWord(UINT8 uWord) { m_uWord = uWord; }
|
|
||||||
|
|
||||||
// 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; }
|
|
||||||
|
|
||||||
|
|
||||||
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_clock(int clock); /* set VSU-1000 clock */
|
||||||
// void set_volume(int volume); /* set VSU-1000 volume control */
|
// void set_volume(int volume); /* set VSU-1000 volume control */
|
||||||
void force_update();
|
void force_update();
|
||||||
@ -58,7 +39,6 @@ protected:
|
|||||||
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override;
|
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// internal state
|
|
||||||
required_region_ptr<UINT8> m_SpeechRom;
|
required_region_ptr<UINT8> m_SpeechRom;
|
||||||
sound_stream * m_stream;
|
sound_stream * m_stream;
|
||||||
|
|
||||||
@ -66,7 +46,17 @@ private:
|
|||||||
devcb_read8 m_ext_read_handler;
|
devcb_read8 m_ext_read_handler;
|
||||||
|
|
||||||
UINT8 readmem(UINT16 offset, bool phase);
|
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
|
bool m_bPhase1; // 1 bit internal clock
|
||||||
|
|
||||||
enum states
|
enum states
|
||||||
|
@ -92,7 +92,7 @@ WRITE8_MEMBER( csc_state::pia0_pa_w )
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// m_speech->reg_w(data & 0x3f);
|
// m_speech->data_w(space, 0, data & 0x3f);
|
||||||
|
|
||||||
// for avoid the digit flashing
|
// for avoid the digit flashing
|
||||||
m_selector |= 0x80;
|
m_selector |= 0x80;
|
||||||
@ -100,15 +100,14 @@ WRITE8_MEMBER( csc_state::pia0_pa_w )
|
|||||||
|
|
||||||
WRITE8_MEMBER( csc_state::pia0_pb_w )
|
WRITE8_MEMBER( csc_state::pia0_pb_w )
|
||||||
{
|
{
|
||||||
// m_speech->set_volume(15); // hack, s14001a core should assume a volume of 15 unless otherwise stated...
|
// m_speech->start_w(BIT(data, 1));
|
||||||
// m_speech->rst_w(BIT(data, 1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
READ8_MEMBER( csc_state::pia0_pb_r )
|
READ8_MEMBER( csc_state::pia0_pb_r )
|
||||||
{
|
{
|
||||||
UINT8 data = 0x04;
|
UINT8 data = 0x04;
|
||||||
|
|
||||||
if(m_speech->bsy_r())
|
if(m_speech->busy_r())
|
||||||
data |= 0x08;
|
data |= 0x08;
|
||||||
|
|
||||||
if (m_selector<9)
|
if (m_selector<9)
|
||||||
|
@ -817,8 +817,8 @@ WRITE8_MEMBER(fidelz80_state::vcc_ppi_porta_w)
|
|||||||
|
|
||||||
// d0-d5: TSI A0-A5
|
// d0-d5: TSI A0-A5
|
||||||
// d7: TSI START line
|
// d7: TSI START line
|
||||||
m_speech->reg_w(data & 0x3f);
|
m_speech->data_w(space, 0, data & 0x3f);
|
||||||
m_speech->rst_w(data >> 7 & 1);
|
m_speech->start_w(data >> 7 & 1);
|
||||||
|
|
||||||
// d6: language latch data
|
// d6: language latch data
|
||||||
// d7: language latch clock (latch on high)
|
// d7: language latch clock (latch on high)
|
||||||
@ -832,7 +832,7 @@ WRITE8_MEMBER(fidelz80_state::vcc_ppi_porta_w)
|
|||||||
READ8_MEMBER(fidelz80_state::vcc_ppi_portb_r)
|
READ8_MEMBER(fidelz80_state::vcc_ppi_portb_r)
|
||||||
{
|
{
|
||||||
// d7: TSI BSY line
|
// d7: TSI BSY line
|
||||||
return (m_speech->bsy_r()) ? 0x80 : 0x00;
|
return (m_speech->busy_r()) ? 0x80 : 0x00;
|
||||||
}
|
}
|
||||||
|
|
||||||
WRITE8_MEMBER(fidelz80_state::vcc_ppi_portb_w)
|
WRITE8_MEMBER(fidelz80_state::vcc_ppi_portb_w)
|
||||||
@ -893,7 +893,7 @@ void fidelz80_state::vsc_prepare_display()
|
|||||||
WRITE8_MEMBER(fidelz80_state::vsc_ppi_porta_w)
|
WRITE8_MEMBER(fidelz80_state::vsc_ppi_porta_w)
|
||||||
{
|
{
|
||||||
// d0-d5: TSI A0-A5
|
// d0-d5: TSI A0-A5
|
||||||
m_speech->reg_w(data & 0x3f);
|
m_speech->data_w(space, 0, data & 0x3f);
|
||||||
|
|
||||||
// d0-d7: data for the 4 7seg leds, bits are HGCBAFED (H is extra led)
|
// d0-d7: data for the 4 7seg leds, bits are HGCBAFED (H is extra led)
|
||||||
m_7seg_data = BITSWAP8(data,7,6,2,1,0,5,4,3);
|
m_7seg_data = BITSWAP8(data,7,6,2,1,0,5,4,3);
|
||||||
@ -932,7 +932,7 @@ READ8_MEMBER(fidelz80_state::vsc_pio_portb_r)
|
|||||||
UINT8 ret = 0;
|
UINT8 ret = 0;
|
||||||
|
|
||||||
// d4: TSI BSY line
|
// d4: TSI BSY line
|
||||||
ret |= (m_speech->bsy_r()) ? 0 : 0x10;
|
ret |= (m_speech->busy_r()) ? 0 : 0x10;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -946,7 +946,7 @@ WRITE8_MEMBER(fidelz80_state::vsc_pio_portb_w)
|
|||||||
m_speaker->level_w(data >> 2 & 1);
|
m_speaker->level_w(data >> 2 & 1);
|
||||||
|
|
||||||
// d6: TSI START line
|
// d6: TSI START line
|
||||||
m_speech->rst_w(data >> 6 & 1);
|
m_speech->start_w(data >> 6 & 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1073,11 +1073,11 @@ WRITE8_MEMBER(fidelz80_state::vbrc_speech_w)
|
|||||||
//printf("%X ",data);
|
//printf("%X ",data);
|
||||||
|
|
||||||
// todo: HALT THE z80 here, and set up a callback to poll the s14001a BSY line to resume z80
|
// todo: HALT THE z80 here, and set up a callback to poll the s14001a BSY line to resume z80
|
||||||
m_speech->reg_w(data & 0x1f);
|
m_speech->data_w(space, 0, data & 0x3f);
|
||||||
m_speech->rst_w(1);
|
m_speech->start_w(1);
|
||||||
m_speech->rst_w(0);
|
m_speech->start_w(0);
|
||||||
|
|
||||||
//m_speech->rst_w(BIT(data, 7));
|
//m_speech->start_w(BIT(data, 7));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ADDRESS_MAP_START( vbrc_main_map, AS_PROGRAM, 8, fidelz80_state )
|
static ADDRESS_MAP_START( vbrc_main_map, AS_PROGRAM, 8, fidelz80_state )
|
||||||
|
Loading…
Reference in New Issue
Block a user