From d96222a3f03b0208a60ff641edb33c2e397e2378 Mon Sep 17 00:00:00 2001 From: Michael Zapf Date: Thu, 27 Feb 2025 22:56:59 +0100 Subject: [PATCH] tms52xx: Remove legacy spchrom implementation. --- scripts/src/sound.lua | 2 - src/devices/bus/electron/m2105.cpp | 10 +- src/devices/bus/mpf1/ssb.cpp | 1 - src/devices/bus/ti99/internal/998board.h | 1 + src/devices/bus/ti99/peb/spchsyn.cpp | 20 +- src/devices/machine/spchrom.cpp | 139 ------------ src/devices/machine/spchrom.h | 43 ---- src/devices/sound/tms5220.cpp | 262 +++++++++++++---------- src/devices/sound/tms5220.h | 20 +- src/mame/acorn/bbc.cpp | 9 +- src/mame/acorn/bbc.h | 1 + src/mame/ti/exelv.cpp | 12 +- src/mame/ti/ti99_8.cpp | 13 +- 13 files changed, 193 insertions(+), 340 deletions(-) delete mode 100644 src/devices/machine/spchrom.cpp delete mode 100644 src/devices/machine/spchrom.h diff --git a/scripts/src/sound.lua b/scripts/src/sound.lua index 3746cc64bd6..fe2322a5bcc 100644 --- a/scripts/src/sound.lua +++ b/scripts/src/sound.lua @@ -1123,8 +1123,6 @@ if (SOUNDS["TMS5220"]~=null) then MAME_DIR .. "src/devices/sound/tms5220.cpp", MAME_DIR .. "src/devices/sound/tms5220.h", MAME_DIR .. "src/devices/sound/tms5110r.hxx", - MAME_DIR .. "src/devices/machine/spchrom.cpp", - MAME_DIR .. "src/devices/machine/spchrom.h", } end diff --git a/src/devices/bus/electron/m2105.cpp b/src/devices/bus/electron/m2105.cpp index 25f9e60a73f..d2aa5da9f55 100644 --- a/src/devices/bus/electron/m2105.cpp +++ b/src/devices/bus/electron/m2105.cpp @@ -114,16 +114,20 @@ void electron_m2105_device::device_add_mconfig(machine_config &config) output_latch_device &latch(OUTPUT_LATCH(config, "cent_data_out")); centronics.set_output_latch(latch); - SPEECHROM(config, "vsm", 0).set_reverse_bit_order(true); - tms5220_device &tms(TMS5220(config, "vsp", 640000)); - tms.set_speechrom_tag("vsm"); tms.ready_cb().set(m_via[0], FUNC(via6522_device::write_ca1)); tms.ready_cb().append(m_via[0], FUNC(via6522_device::write_pb2)); tms.irq_cb().set(m_via[0], FUNC(via6522_device::write_ca2)); tms.irq_cb().append(m_via[0], FUNC(via6522_device::write_pb3)); tms.add_route(ALL_OUTPUTS, "mono", 0.5); + TMS6100(config, "vsm", 0); + tms.m0_cb().set("vsm", FUNC(tms6100_device::m0_w)); + tms.m1_cb().set("vsm", FUNC(tms6100_device::m1_w)); + tms.addr_cb().set("vsm", FUNC(tms6100_device::add_w)); + tms.data_cb().set("vsm", FUNC(tms6100_device::data_line_r)); + tms.romclk_cb().set("vsm", FUNC(tms6100_device::clk_w)); + SPEAKER(config, "mono").front_center(); } diff --git a/src/devices/bus/mpf1/ssb.cpp b/src/devices/bus/mpf1/ssb.cpp index 1c6a00dd3d7..ef3188e6f64 100644 --- a/src/devices/bus/mpf1/ssb.cpp +++ b/src/devices/bus/mpf1/ssb.cpp @@ -14,7 +14,6 @@ #include "emu.h" #include "ssb.h" -#include "machine/spchrom.h" #include "sound/tms5220.h" #include "bus/generic/carts.h" #include "bus/generic/slot.h" diff --git a/src/devices/bus/ti99/internal/998board.h b/src/devices/bus/ti99/internal/998board.h index f1a1fa797bb..cf80377fce7 100644 --- a/src/devices/bus/ti99/internal/998board.h +++ b/src/devices/bus/ti99/internal/998board.h @@ -25,6 +25,7 @@ #include "machine/ram.h" #include "machine/tmc0430.h" #include "machine/tms9901.h" +#include "machine/tms6100.h" #include "sound/sn76496.h" #include "sound/tms5220.h" #include "video/tms9928a.h" diff --git a/src/devices/bus/ti99/peb/spchsyn.cpp b/src/devices/bus/ti99/peb/spchsyn.cpp index 8639f4ffa43..f8ec3095ae7 100644 --- a/src/devices/bus/ti99/peb/spchsyn.cpp +++ b/src/devices/bus/ti99/peb/spchsyn.cpp @@ -23,8 +23,6 @@ #include "emu.h" #include "spchsyn.h" - -#include "machine/spchrom.h" #include "speaker.h" #define LOG_WARN (1U << 1) // Warnings @@ -154,22 +152,18 @@ ROM_END void ti_speech_synthesizer_device::device_add_mconfig(machine_config& config) { - SPEECHROM(config, "vsm", 0).set_reverse_bit_order(true); SPEAKER(config, "speech_out").front_center(); CD2501E(config, m_vsp, 640000L); - m_vsp->set_speechrom_tag("vsm"); + m_vsp->ready_cb().set(FUNC(ti_speech_synthesizer_device::speech_ready)); m_vsp->add_route(ALL_OUTPUTS, "speech_out", 0.50); -/* - // FIXME: Make it work. Guess we need two VSM circuits @16K. - TMS6100(config, "vsm", 640_kHz_XTAL/4); - m_vsp->m0_cb().set("vsm", FUNC(tms6100_device::m0_w)); - m_vsp->m1_cb().set("vsm", FUNC(tms6100_device::m1_w)); - m_vsp->addr_cb().set("vsm", FUNC(tms6100_device::add_w)); - m_vsp->data_cb().set("vsm", FUNC(tms6100_device::data_line_r)); - m_vsp->romclk_cb().set("vsm", FUNC(tms6100_device::clk_w)); -*/ + TMS6100(config, "vsm", 0); + m_vsp->m0_cb().set("vsm", FUNC(tms6100_device::m0_w)); + m_vsp->m1_cb().set("vsm", FUNC(tms6100_device::m1_w)); + m_vsp->addr_cb().set("vsm", FUNC(tms6100_device::add_w)); + m_vsp->data_cb().set("vsm", FUNC(tms6100_device::data_line_r)); + m_vsp->romclk_cb().set("vsm", FUNC(tms6100_device::clk_w)); } INPUT_PORTS_START( ti99_speech ) diff --git a/src/devices/machine/spchrom.cpp b/src/devices/machine/spchrom.cpp deleted file mode 100644 index 3cd95b87c2e..00000000000 --- a/src/devices/machine/spchrom.cpp +++ /dev/null @@ -1,139 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Frank Palazzolo, Aaron Giles, Jonathan Gevaryahu, Raphael Nabet, Couriersud, Michael Zapf -/* - spchroms.c - This is an emulator for "typical" speech ROMs from TI, as used by TI99/4(a). - - In order to support its speech processor, TI designed some ROMs with a 1-bit data bus - and 4-bit address bus (multiplexed 5 times to provide a 18-bit address). - A fairly complete description of such a ROM (tms6100) is found in the tms5220 datasheet. - - One notable thing is that the address is a byte address (*NOT* a bit address). - - This file is designed to be interfaced with the tms5220 core. - Interfacing it with the tms5110 would make sense, too. - - TODO: - Create separate devices for TMS6100 & TMS6125 - Implement the serial protocol -*/ - -#include "emu.h" -#include "spchrom.h" - -#define TMS5220_ADDRESS_MASK 0x3FFFFUL /* 18-bit mask for tms5220 address */ - -// device type definition -DEFINE_DEVICE_TYPE(SPEECHROM, speechrom_device, "speechrom", "TI Speech ROM") - -speechrom_device::speechrom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, SPEECHROM, tag, owner, clock), m_speechrom_data(nullptr), m_speechROMlen(0), - m_speechROMaddr(0), - m_load_pointer(0), - m_ROM_bits_count(0), - m_reverse(false) -{ -} - -/* - Read 'count' bits serially from speech ROM - - Actually, the ROM is expected to have reversed bit order, but there are - many dumps with normal bit order. - - compatibility mode: 01234567 01234567 01234567 ... - correct mode: 76543210 76543210 76543210 ... -*/ -int speechrom_device::read(int count) -{ - int val; - int spchbyte; - int pos; - - if (m_load_pointer) - { /* first read after load address is ignored */ - m_load_pointer = 0; - count--; - } - - if (m_speechROMaddr < m_speechROMlen) - { - val = 0; - pos = 8 - m_ROM_bits_count; - - spchbyte = (m_reverse? (m_speechrom_data[m_speechROMaddr] >> pos) : (m_speechrom_data[m_speechROMaddr] << pos)) & 0xff; - - while (count > 0) - { - val = val << 1; - if ((spchbyte & (m_reverse? 0x01:0x80))!=0) val |= 1; - spchbyte = m_reverse? (spchbyte >> 1) : (spchbyte << 1); - count--; - if (pos == 7) - { - pos = 0; - m_speechROMaddr = (m_speechROMaddr + 1) & TMS5220_ADDRESS_MASK; - if (m_speechROMaddr >= m_speechROMlen) - count = 0; - else - spchbyte = m_speechrom_data[m_speechROMaddr]; - } - else pos++; - } - m_ROM_bits_count = 8 - pos; - } - else - { - val = 0; - } - - return val; -} - -/* - Write an address nibble to speech ROM -*/ -void speechrom_device::load_address(int data) -{ - /* tms5220 data sheet says that if we load only one 4-bit nibble, it won't work. - This code does not care about this. */ - m_speechROMaddr = ( (m_speechROMaddr & ~(0xf << m_load_pointer)) - | (((unsigned long) (data & 0xf)) << m_load_pointer) ) & TMS5220_ADDRESS_MASK; - m_load_pointer += 4; - m_ROM_bits_count = 8; -} - -/* - Perform a read and branch command -*/ -void speechrom_device::read_and_branch() -{ - /* tms5220 data sheet says that if more than one speech ROM (tms6100) is present, - there is a bus contention. This code does not care about this. */ - if (m_speechROMaddr < m_speechROMlen-1) - m_speechROMaddr = (m_speechROMaddr & 0x3c000UL) - | (((((unsigned long) m_speechrom_data[m_speechROMaddr]) << 8) - | m_speechrom_data[m_speechROMaddr+1]) & 0x3fffUL); - else if (m_speechROMaddr == m_speechROMlen-1) - m_speechROMaddr = (m_speechROMaddr & 0x3c000UL) - | ((((unsigned long) m_speechrom_data[m_speechROMaddr]) << 8) & 0x3fffUL); - else - m_speechROMaddr = (m_speechROMaddr & 0x3c000UL); - - m_ROM_bits_count = 8; -} - -void speechrom_device::device_start() -{ - memory_region *region = memregion(tag()); - if (region == nullptr) - { - throw emu_fatalerror("No region for device '%s'\n", tag()); - } - - m_speechrom_data = region->base(); - m_speechROMlen = region->bytes(); - - save_item(NAME(m_speechROMaddr)); - save_item(NAME(m_load_pointer)); - save_item(NAME(m_ROM_bits_count)); -} diff --git a/src/devices/machine/spchrom.h b/src/devices/machine/spchrom.h deleted file mode 100644 index c070fa31eac..00000000000 --- a/src/devices/machine/spchrom.h +++ /dev/null @@ -1,43 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Frank Palazzolo, Aaron Giles, Jonathan Gevaryahu, Raphael Nabet, Couriersud, Michael Zapf -/* - * Voice Synthesis Memory - * - */ - -#ifndef MAME_MACHINE_SPCHROM_H -#define MAME_MACHINE_SPCHROM_H - -#pragma once - - -class speechrom_device : public device_t -{ -public: - // construction/destruction - speechrom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - - /// TODO: implement bus behaviour - int read(int count); - void load_address(int data); - void read_and_branch(); - void set_reverse_bit_order(bool reverse) { m_reverse = reverse; } - -protected: - // device-level overrides - virtual void device_start() override ATTR_COLD; - -private: - uint8_t *m_speechrom_data; /* pointer to speech ROM data */ - unsigned int m_speechROMlen; /* length of data pointed by speechrom_data, from 0 to 2^18 */ - unsigned int m_speechROMaddr; /* 18 bit pointer in ROM */ - int m_load_pointer; /* which 4-bit nibble will be affected by load address */ - int m_ROM_bits_count; /* current bit position in ROM */ - bool m_reverse; -}; - - -// device type definition -DECLARE_DEVICE_TYPE(SPEECHROM, speechrom_device) - -#endif // MAME_MACHINE_SPCHROM_H diff --git a/src/devices/sound/tms5220.cpp b/src/devices/sound/tms5220.cpp index e63862b4f46..a762cc08cfd 100644 --- a/src/devices/sound/tms5220.cpp +++ b/src/devices/sound/tms5220.cpp @@ -366,41 +366,69 @@ emulating the tms5220 in MCU code). Look for a 16-pin chip at U6 labeled one B cycle per interpolation step) */ #define FORCE_SUBC_RELOAD 1 - /* *****debugging defines***** */ /* 5220 only; above dumps the data written to the tms52xx to the error log, useful for making logged data dumps for real hardware tests */ #define LOG_DUMP_INPUT_DATA (1U << 1) + // 5220 only; above debugs FIFO stuff: writes, reads and flag updates #define LOG_FIFO (1U << 2) + +// Show parsing events +#define LOG_PARSE (1U << 3) + // dumps each speech frame as binary -#define LOG_PARSE_FRAME_DUMP_BIN (1U << 3) +#define LOG_PARSE_FRAME_DUMP_BIN (1U << 4) + // dumps each speech frame as hex -#define LOG_PARSE_FRAME_DUMP_HEX (1U << 4) +#define LOG_PARSE_FRAME_DUMP_HEX (1U << 5) + // dumps info if a frame ran out of data #define LOG_FRAME_ERRORS (1U << 6) -// dumps all non-speech-data command writes -#define LOG_COMMAND_DUMP (1U << 7) -// dumps decoded info about command writes -#define LOG_COMMAND_VERBOSE (1U << 8) -// spams the error log with i/o ready messages whenever the ready or irq pin is read -#define LOG_PIN_READS (1U << 9) -// dumps debug information related to the sample generation loop, i.e. whether interpolation is inhibited or not, and what the current and target values for each frame are. -#define LOG_GENERATION (1U << 10) -// dumps MUCH MORE debug information related to the sample generation loop, namely the excitation, energy, pitch, k*, and output values for EVERY SINGLE SAMPLE during a frame. -#define LOG_GENERATION_VERBOSE (1U << 11) -// dumps the lattice filter state data each sample. -#define LOG_LATTICE (1U << 12) -// dumps info to the error log whenever the analog clip hardware is (or would be) clipping the signal. -#define LOG_CLIP (1U << 13) -// debugs the io ready callback timer -#define LOG_IO_READY (1U << 14) -// debugs the tms5220_data_r and data_w access methods which actually respect rs and ws -#define LOG_RS_WS (1U << 15) -// shows the byte being written by the CPU to the VSP -#define LOG_DATA_W (1U << 16) -//#define VERBOSE (LOG_GENERAL | LOG_DUMP_INPUT_DATA | LOG_FIFO | LOG_PARSE_FRAME_DUMP_HEX | LOG_FRAME_ERRORS | LOG_COMMAND_DUMP | LOG_COMMAND_VERBOSE | LOG_PIN_READS | LOG_GENERATION | LOG_GENERATION_VERBOSE | LOG_LATTICE | LOG_CLIP | LOG_IO_READY | LOG_RS_WS | LOG_DATA_W) +// dumps all non-speech-data command writes +#define LOG_COMMAND (1U << 7) + +// Additional information about command processing +#define LOG_COMMAND_VERBOSE (1U << 8) + +// Show NOP command (tends to be noisy) +#define LOG_COMMAND_NOP (1U << 9) + +// spams the error log with i/o ready messages whenever the ready or irq pin is read +#define LOG_PIN_READS (1U << 10) + +// dumps debug information related to the sample generation loop, i.e. whether interpolation is inhibited or not, and what the current and target values for each frame are. +#define LOG_GENERATION (1U << 11) + +// dumps MUCH MORE debug information related to the sample generation loop, namely the excitation, energy, pitch, k*, and output values for EVERY SINGLE SAMPLE during a frame. +#define LOG_GENERATION_VERBOSE (1U << 12) + +// dumps the lattice filter state data each sample. +#define LOG_LATTICE (1U << 13) + +// Show errors in matrix multiplication +#define LOG_MULTIPLY (1U << 14) + +// dumps info to the error log whenever the analog clip hardware is (or would be) clipping the signal. +#define LOG_CLIP (1U << 15) + +// debugs the io ready callback timer +#define LOG_IO_READY (1U << 16) + +// debugs the tms5220_data_r and data_w access methods which actually respect rs and ws +#define LOG_RS_WS (1U << 17) + +// Show the byte being written by the CPU to the VSP +#define LOG_DATA_W (1U << 18) + +// Show interactions with speech rom +#define LOG_VSM (1U << 19) + +// Show state changes +#define LOG_STATE (1U << 20) + +#define VERBOSE ( LOG_GENERAL ) #include "logmacro.h" #define MAX_SAMPLE_CHUNK 512 @@ -570,10 +598,10 @@ void tms5220_device::printbits(long data, int num) /********************************************************************************************** - tms5220_device::new_int_write -- wrap a write to the VSM + tms5220_device::vsm_write -- wrap a write sent to the VSM ***********************************************************************************************/ -void tms5220_device::new_int_write(uint8_t rc, uint8_t m0, uint8_t m1, uint8_t addr) +void tms5220_device::vsm_write(uint8_t rc, uint8_t m0, uint8_t m1, uint8_t addr) { m_m0_cb(m0); m_m1_cb(m1); @@ -587,32 +615,52 @@ void tms5220_device::new_int_write(uint8_t rc, uint8_t m0, uint8_t m1, uint8_t a /********************************************************************************************** - tms5220_device::new_int_write_addr -- wrap a 'load address' set of writes to the VSM + tms5220_device::vsm_write_addr -- wrap a 'load address' set of writes sent to the VSM ***********************************************************************************************/ -void tms5220_device::new_int_write_addr(uint8_t addr) +void tms5220_device::vsm_write_addr(uint8_t addr) { - new_int_write(1, 0, 1, addr); // romclk 1, m0 0, m1 1, addr bus nybble = xxxx - new_int_write(0, 0, 1, addr); // romclk 0, m0 0, m1 1, addr bus nybble = xxxx - new_int_write(1, 0, 0, addr); // romclk 1, m0 0, m1 0, addr bus nybble = xxxx - new_int_write(0, 0, 0, addr); // romclk 0, m0 0, m1 0, addr bus nybble = xxxx + vsm_write(1, 0, 1, addr); // romclk 1, m0 0, m1 1, addr bus nybble = xxxx + vsm_write(0, 0, 1, addr); // romclk 0, m0 0, m1 1, addr bus nybble = xxxx + vsm_write(1, 0, 0, addr); // romclk 1, m0 0, m1 0, addr bus nybble = xxxx + vsm_write(0, 0, 0, addr); // romclk 0, m0 0, m1 0, addr bus nybble = xxxx } /********************************************************************************************** - tms5220_device::new_int_write_addr -- wrap a 'read bit' set of writes to the VSM + tms5220_device::vsm_read -- wrap a 'read bit' set of writes sent to the VSM ***********************************************************************************************/ -uint8_t tms5220_device::new_int_read() +uint8_t tms5220_device::vsm_read() { - new_int_write(1, 1, 0, 0); // romclk 1, m0 1, m1 0, addr bus nybble = 0/open bus - new_int_write(0, 1, 0, 0); // romclk 0, m0 1, m1 0, addr bus nybble = 0/open bus - new_int_write(1, 0, 0, 0); // romclk 1, m0 0, m1 0, addr bus nybble = 0/open bus - new_int_write(0, 0, 0, 0); // romclk 0, m0 0, m1 0, addr bus nybble = 0/open bus + vsm_write(1, 1, 0, 0); // romclk 1, m0 1, m1 0, addr bus nybble = 0/open bus + vsm_write(0, 1, 0, 0); // romclk 0, m0 1, m1 0, addr bus nybble = 0/open bus + vsm_write(1, 0, 0, 0); // romclk 1, m0 0, m1 0, addr bus nybble = 0/open bus + vsm_write(0, 0, 0, 0); // romclk 0, m0 0, m1 0, addr bus nybble = 0/open bus + + uint8_t val = 0; + if (!m_data_cb.isunset()) - return m_data_cb(); - LOG("WARNING: CALLBACK MISSING, RETURNING 0!\n"); - return 0; + val = m_data_cb(); + else + LOGMASKED(LOG_VSM, "Warning: No speech memory attached, returning 0.\n"); + + return val; +} + +/********************************************************************************************** + + tms5220_device::vsm_read_and_branch -- wrap a 'read-and-branch' set of writes sent to the VSM + +***********************************************************************************************/ +void tms5220_device::vsm_read_and_branch() +{ + vsm_write(0, 1, 1, 0); // see tms5110.cpp + vsm_write(1, 1, 1, 0); // romclk 1, m0 1, m1 1, addr bus nybble = 0/open bus + vsm_write(0, 1, 1, 0); // romclk 0, m0 1, m1 1, addr bus nybble = 0/open bus + vsm_write(0, 0, 0, 0); // see tms5110.cpp + vsm_write(1, 0, 0, 0); // romclk 1, m0 0, m1 0, addr bus nybble = 0/open bus + vsm_write(0, 0, 0, 0); // romclk 0, m0 0, m1 0, addr bus nybble = 0/open bus } /********************************************************************************************** @@ -745,7 +793,7 @@ void tms5220_device::update_fifo_status_and_ints() // also, in this case, regardless if DDIS was set, unset it. if (m_previous_talk_status && !talk_status()) { - LOG("Talk status 1 -> 0, unsetting DDIS and firing an interrupt.\n"); + LOGMASKED(LOG_STATE, "Talk status 1 -> 0, unsetting DDIS and firing an interrupt.\n"); set_interrupt_state(1); m_DDIS = false; @@ -755,13 +803,13 @@ void tms5220_device::update_fifo_status_and_ints() // Then resume it. if (m_command_register != NOCOMMAND) { - LOGMASKED(LOG_COMMAND_DUMP, "Resume command execution: %02X\n", m_command_register); + LOGMASKED(LOG_STATE, "Resume command execution: %02X\n", m_command_register); process_command(m_command_register); // Is there another data transfer pending? Resume it as well. if (m_data_latched) { - LOGMASKED(LOG_COMMAND_DUMP, "Pending byte write: %02X\n", m_write_latch); + LOGMASKED(LOG_STATE, "Pending byte write: %02X\n", m_write_latch); m_timer_io_ready->adjust(clocks_to_attotime(16), 1); } else @@ -806,32 +854,33 @@ int tms5220_device::read_bits(int count) } else { -#ifndef USE_NEW_TMS6100_CODE -/** TODO: get rid of this old code */ - // extract from VSM (speech ROM) - if (m_speechrom) - val = m_speechrom->read(count); - else - val = (1<16383) { b-=32768; } while (b<-16384) { b+=32768; } result = ((a*b)>>9); /** TODO: this isn't technically right to the chip, which truncates the lowest result bit, but it causes glitches otherwise. **/ - if (result>16383) LOG("matrix multiplier overflowed! a: %x, b: %x, result: %x", a, b, result); - if (result<-16384) LOG("matrix multiplier underflowed! a: %x, b: %x, result: %x", a, b, result); + if (result>16383) LOGMASKED(LOG_MULTIPLY, "matrix multiplier overflowed! a: %x, b: %x, result: %x", a, b, result); + if (result<-16384) LOGMASKED(LOG_MULTIPLY, "matrix multiplier underflowed! a: %x, b: %x, result: %x", a, b, result); return result; } @@ -1343,25 +1392,22 @@ int32_t tms5220_device::lattice_filter() void tms5220_device::process_command(uint8_t cmd) { - LOGMASKED(LOG_COMMAND_DUMP, "process_command called with parameter %02X\n", cmd); - m_command_register = cmd; /* parse the command */ switch (cmd & 0x70) { case 0x10 : /* read byte */ - LOGMASKED(LOG_COMMAND_VERBOSE, "Read Byte command received\n"); + LOGMASKED(LOG_COMMAND, "Read Byte command received (%02X)\n", cmd); if (!talk_status()) /* TALKST must be clear for RDBY */ { if (m_schedule_dummy_read) { m_schedule_dummy_read = false; - if (m_speechrom) - m_speechrom->read(1); + perform_dummy_read(); } - if (m_speechrom) - m_read_byte_register = m_speechrom->read(8); /* read one byte from speech ROM... */ + + m_read_byte_register = read_bits(8); m_RDB_flag = true; m_command_register = NOCOMMAND; } @@ -1373,11 +1419,11 @@ void tms5220_device::process_command(uint8_t cmd) case 0x20: /* set rate (tms5220c and cd2501ecd only), otherwise NOP */ if (TMS5220_HAS_RATE_CONTROL) { - LOGMASKED(LOG_COMMAND_VERBOSE, "Set Rate (or NOP) command received\n"); + LOGMASKED(LOG_COMMAND_NOP, "Set Rate (or NOP) command received (%02X)\n", cmd); m_c_variant_rate = cmd&0x0F; } else - LOGMASKED(LOG_COMMAND_VERBOSE, "NOP command received\n"); + LOGMASKED(LOG_COMMAND_NOP, "NOP command received (%02X)\n", cmd); m_command_register = NOCOMMAND; break; @@ -1385,10 +1431,20 @@ void tms5220_device::process_command(uint8_t cmd) case 0x30 : /* read and branch */ if (!talk_status()) /* TALKST must be clear for RB */ { - LOGMASKED(LOG_COMMAND_VERBOSE, "Read and Branch command received\n"); + LOGMASKED(LOG_COMMAND, "Read and Branch command received (%02X)\n", cmd); m_RDB_flag = false; - if (m_speechrom) - m_speechrom->read_and_branch(); + + if (m_schedule_dummy_read) + { + m_schedule_dummy_read = false; + perform_dummy_read(); + } + + if (!m_m0_cb.isunset()) + vsm_read_and_branch(); + else + LOGMASKED(LOG_VSM, "WARNING: Read-and-branch: No memory attached to VSP\n"); + m_command_register = NOCOMMAND; } break; @@ -1396,11 +1452,13 @@ void tms5220_device::process_command(uint8_t cmd) case 0x40 : /* load address */ if (!talk_status()) /* TALKST must be clear for LA */ { - LOGMASKED(LOG_COMMAND_VERBOSE, "Load Address command received\n"); - /* tms5220 data sheet says that if we load only one 4-bit nibble, it won't work. - This code does not care about this. */ - if (m_speechrom) - m_speechrom->load_address(cmd & 0x0f); + LOGMASKED(LOG_COMMAND, "Load Address command received (%02X)\n", cmd); + + // tms5220 data sheet says that if we load only one 4-bit nibble, + // it won't work. This code does not care about this. + if (!m_m0_cb.isunset()) + vsm_write_addr(cmd & 0x0f); + m_schedule_dummy_read = true; m_command_register = NOCOMMAND; } @@ -1414,13 +1472,13 @@ void tms5220_device::process_command(uint8_t cmd) break; case 0x50 : /* speak */ - LOGMASKED(LOG_COMMAND_VERBOSE, "Speak (VSM) command received\n"); + LOGMASKED(LOG_COMMAND, "Speak (VSM) command received (%02X)\n", cmd); if (m_schedule_dummy_read) { m_schedule_dummy_read = false; - if (m_speechrom) - m_speechrom->read(1); + perform_dummy_read(); } + m_SPEN = 1; #ifdef FAST_START_HACK m_TALK = 1; @@ -1448,7 +1506,7 @@ void tms5220_device::process_command(uint8_t cmd) break; case 0x60 : /* speak external */ - LOGMASKED(LOG_COMMAND_VERBOSE, "Speak External command received\n"); + LOGMASKED(LOG_COMMAND, "Speak External command received (%02X)\n", cmd); // SPKEXT going active asserts /SPKEE for 2 clocks, which clears the FIFO and its counters std::fill(std::begin(m_fifo), std::end(m_fifo), 0); @@ -1478,13 +1536,13 @@ void tms5220_device::process_command(uint8_t cmd) break; case 0x70 : /* reset */ - LOGMASKED(LOG_COMMAND_VERBOSE, "Reset command received\n"); + LOGMASKED(LOG_COMMAND, "Reset command received (%02X)\n", cmd); if (m_schedule_dummy_read) { m_schedule_dummy_read = false; - if (m_speechrom) - m_speechrom->read(1); + perform_dummy_read(); } + reset(); m_command_register = NOCOMMAND; break; @@ -1595,9 +1653,9 @@ void tms5220_device::parse_frame() LOGMASKED(LOG_PARSE_FRAME_DUMP_BIN | LOG_PARSE_FRAME_DUMP_HEX, "\n"); if (m_DDIS) - LOG("Parsed a frame successfully in FIFO - %d bits remaining\n", (m_fifo_count*8)-(m_fifo_bits_taken)); + LOGMASKED(LOG_PARSE, "Parsed a frame successfully in FIFO - %d bits remaining\n", (m_fifo_count*8)-(m_fifo_bits_taken)); else - LOG("Parsed a frame successfully in ROM\n"); + LOGMASKED(LOG_PARSE, "Parsed a frame successfully in ROM\n"); return; ranout: @@ -1648,19 +1706,6 @@ void tms5220_device::update_ready_state() void tms5220_device::device_start() { - if (m_speechrom_tag) - { - m_speechrom = siblingdevice( m_speechrom_tag ); - if( !m_speechrom ) - { - throw new emu_fatalerror("Error: %s '%s' can't find speechrom '%s'\n", shortname(), tag(), m_speechrom_tag ); - } - } - else - { - m_speechrom = nullptr; - } - switch (m_variant) { case TMS5220_IS_TMC0281: @@ -1751,18 +1796,8 @@ void tms5220_device::device_reset() m_RNG = 0x1FFF; std::fill(std::begin(m_u), std::end(m_u), 0); std::fill(std::begin(m_x), std::end(m_x), 0); - m_schedule_dummy_read = false; - if (m_speechrom) - { - m_speechrom->load_address(0); - // MZ: Do the dummy read immediately. The previous line will cause a - // shift in the address pointer in the VSM. When the next command is a - // load_address, no dummy read will occur, hence the address will be - // incorrectly shifted. - m_speechrom->read(1); - m_schedule_dummy_read = false; - } + perform_dummy_read(); // 5110 specific stuff m_PDC = 0; @@ -2160,7 +2195,6 @@ tms5220_device::tms5220_device(const machine_config &mconfig, device_type type, , m_variant(variant) , m_irq_handler(*this) , m_readyq_handler(*this) - , m_speechrom_tag(nullptr) , m_m0_cb(*this) , m_m1_cb(*this) , m_addr_cb(*this) diff --git a/src/devices/sound/tms5220.h b/src/devices/sound/tms5220.h index 8b49852aebc..6aa0494164b 100644 --- a/src/devices/sound/tms5220.h +++ b/src/devices/sound/tms5220.h @@ -5,8 +5,6 @@ #pragma once -#include "machine/spchrom.h" - /* HACK: if defined, uses impossibly perfect 'straight line' interpolation */ #undef TMS5220_PERFECT_INTERPOLATION_HACK @@ -31,9 +29,6 @@ public: // Ready callback function, active low, i.e. state=0 auto ready_cb() { return m_readyq_handler.bind(); } - // old VSM support, remove me! - void set_speechrom_tag(const char *_tag) { m_speechrom_tag = _tag; } - // new VSM support auto m0_cb() { return m_m0_cb.bind(); } auto m1_cb() { return m_m1_cb.bind(); } @@ -80,10 +75,11 @@ protected: private: static constexpr unsigned FIFO_SIZE = 16; - // 51xx and VSM related - void new_int_write(uint8_t rc, uint8_t m0, uint8_t m1, uint8_t addr); - void new_int_write_addr(uint8_t addr); - uint8_t new_int_read(); + void vsm_write(uint8_t rc, uint8_t m0, uint8_t m1, uint8_t addr); + void vsm_write_addr(uint8_t addr); + uint8_t vsm_read(); + void vsm_read_and_branch(); + void perform_dummy_read(); // 52xx or common void register_for_save_states(); @@ -237,10 +233,8 @@ private: /* callbacks */ devcb_write_line m_irq_handler; devcb_write_line m_readyq_handler; - // next 2 lines are old speechrom handler, remove me! - const char *m_speechrom_tag; - speechrom_device *m_speechrom; - // next lines are new speechrom handler + + // Speech ROM handler devcb_write_line m_m0_cb; // the M0 line devcb_write_line m_m1_cb; // the M1 line devcb_write8 m_addr_cb; // Write to ADD1,2,4,8 - 4 address bits diff --git a/src/mame/acorn/bbc.cpp b/src/mame/acorn/bbc.cpp index 55e3dd153c2..d43648d43ab 100644 --- a/src/mame/acorn/bbc.cpp +++ b/src/mame/acorn/bbc.cpp @@ -1201,11 +1201,16 @@ void bbc_state::bbcb(machine_config &config) m_ram->set_default_size("32K"); /* speech hardware */ - SPEECHROM(config, "vsm", 0); TMS5220(config, m_tms, 640000); - m_tms->set_speechrom_tag("vsm"); m_tms->add_route(ALL_OUTPUTS, "mono", 1.0); + TMS6100(config, "vsm", 0); + m_tms->m0_cb().set("vsm", FUNC(tms6100_device::m0_w)); + m_tms->m1_cb().set("vsm", FUNC(tms6100_device::m1_w)); + m_tms->addr_cb().set("vsm", FUNC(tms6100_device::add_w)); + m_tms->data_cb().set("vsm", FUNC(tms6100_device::data_line_r)); + m_tms->romclk_cb().set("vsm", FUNC(tms6100_device::clk_w)); + /* user via */ MOS6522(config, m_via6522_1, 16_MHz_XTAL / 16); m_via6522_1->writepa_handler().set("cent_data_out", FUNC(output_latch_device::write)); diff --git a/src/mame/acorn/bbc.h b/src/mame/acorn/bbc.h index 95bf25373e4..0f5b111d8d9 100644 --- a/src/mame/acorn/bbc.h +++ b/src/mame/acorn/bbc.h @@ -27,6 +27,7 @@ #include "machine/i2cmem.h" #include "machine/bankdev.h" #include "machine/input_merger.h" +#include "machine/tms6100.h" #include "video/mc6845.h" #include "video/saa5050.h" #include "sound/sn76496.h" diff --git a/src/mame/ti/exelv.cpp b/src/mame/ti/exelv.cpp index 87f87ab60ed..62ce6c55563 100644 --- a/src/mame/ti/exelv.cpp +++ b/src/mame/ti/exelv.cpp @@ -99,7 +99,7 @@ TODO: #include "cpu/tms7000/tms7000.h" #include "imagedev/cassette.h" -#include "machine/spchrom.h" +#include "machine/tms6100.h" #include "machine/timer.h" #include "sound/tms5220.h" #include "sound/spkrdev.h" @@ -923,13 +923,17 @@ void exelv_state::exeltel(machine_config &config) PALETTE(config, "palette", palette_device::RGB_3BIT); - SPEECHROM(config, "vsm", 0); - /* sound */ SPEAKER(config, "mono").front_center(); TMS5220C(config, m_tms5220c, 9.8304_MHz_XTAL / 15); // unknown divider for "VSPCLK" (generated by TAHC06 gate array) - m_tms5220c->set_speechrom_tag("vsm"); m_tms5220c->add_route(ALL_OUTPUTS, "mono", 1.00); + + TMS6100(config, "vsm", 640_kHz_XTAL/4); + m_tms5220c->m0_cb().set("vsm", FUNC(tms6100_device::m0_w)); + m_tms5220c->m1_cb().set("vsm", FUNC(tms6100_device::m1_w)); + m_tms5220c->addr_cb().set("vsm", FUNC(tms6100_device::add_w)); + m_tms5220c->data_cb().set("vsm", FUNC(tms6100_device::data_line_r)); + m_tms5220c->romclk_cb().set("vsm", FUNC(tms6100_device::clk_w)); } diff --git a/src/mame/ti/ti99_8.cpp b/src/mame/ti/ti99_8.cpp index f9a17d59ca9..a17cf458308 100644 --- a/src/mame/ti/ti99_8.cpp +++ b/src/mame/ti/ti99_8.cpp @@ -652,10 +652,6 @@ void ti99_8_state::clock_out(int state) void ti99_8_state::driver_start() { - // Need to configure the speech ROM for inverse bit order -// speechrom_device* mem = subdevice(TI998_SPEECHROM_REG); -// mem->set_reverse_bit_order(true); - save_item(NAME(m_keyboard_column)); save_item(NAME(m_ready_old)); save_item(NAME(m_int1)); @@ -743,14 +739,19 @@ void ti99_8_state::ti99_8(machine_config& config) // Speech hardware // Note: SPEECHROM uses its tag for referencing the region - SPEECHROM(config, TI998_SPEECHROM_REG, 0).set_reverse_bit_order(true); SPEAKER(config, "speech_out").front_center(); cd2501ecd_device& vsp(CD2501ECD(config, TI998_SPEECHSYN_TAG, 640000L)); vsp.ready_cb().set(TI998_MAINBOARD_TAG, FUNC(mainboard8_device::speech_ready)); - vsp.set_speechrom_tag(TI998_SPEECHROM_REG); vsp.add_route(ALL_OUTPUTS, "speech_out", 0.50); + TMS6100(config, TI998_SPEECHROM_REG, 0); + vsp.m0_cb().set(TI998_SPEECHROM_REG, FUNC(tms6100_device::m0_w)); + vsp.m1_cb().set(TI998_SPEECHROM_REG, FUNC(tms6100_device::m1_w)); + vsp.addr_cb().set(TI998_SPEECHROM_REG, FUNC(tms6100_device::add_w)); + vsp.data_cb().set(TI998_SPEECHROM_REG, FUNC(tms6100_device::data_line_r)); + vsp.romclk_cb().set(TI998_SPEECHROM_REG, FUNC(tms6100_device::clk_w)); + // Cassette drive SPEAKER(config, "cass_out").front_center(); CASSETTE(config, "cassette", 0).add_route(ALL_OUTPUTS, "cass_out", 0.25);