summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Lord-Nightmare <Lord-Nightmare@users.noreply.github.com>2018-06-12 00:36:57 -0400
committer Lord-Nightmare <Lord-Nightmare@users.noreply.github.com>2018-06-12 00:36:57 -0400
commit200d03c46a05bf83f2f770974b24c76cd88274f3 (patch)
tree0b18a5feced41852499bff26074ccfb2b2bb55e9
parent7f06e4f6c26c513c6f5e0e0556879d261fb306da (diff)
a2echoii: replaced read flag, write flag and write latch implementation with one which matches actual hardware tracing [Lord Nightmare, Tony Diaz]
-rw-r--r--src/devices/bus/a2bus/a2echoii.cpp132
-rw-r--r--src/devices/bus/a2bus/a2echoii.h12
2 files changed, 93 insertions, 51 deletions
diff --git a/src/devices/bus/a2bus/a2echoii.cpp b/src/devices/bus/a2bus/a2echoii.cpp
index 89ef73ac00e..6e300c39c55 100644
--- a/src/devices/bus/a2bus/a2echoii.cpp
+++ b/src/devices/bus/a2bus/a2echoii.cpp
@@ -4,9 +4,21 @@
a2echoii.c
- Implementation of the Street Electronics Echo II speech card
- Ready logic traced by Jonathan Gevaryahu
+ Implementation of the Street Electronics Echo II and EchoIIb speech card
+ Ready logic traced by Lord Nightmare and Tony Diaz
+ Notes from Tony Diaz:
+ Capacitor values:
+ C1,C2 - .47nF C3,C4 - 16v 10uF C5 - 16v 100uF C7,C7,C8 .1uF
+
+ Pictures:
+ Original EchoII card, S/N 789 with ?original? TMS5200: http://mirrors.apple2.org.za/Apple%20II%20Documentation%20Project/Interface%20Cards/Speech/Street%20Echo%20II/Photos/SEC%20-%20Echo%20II%20rev.A%20-%20Front.jpg
+ Original EchoII card, S/N 103, with a much later 1987 non-original TSP5220C installed: https://upload.wikimedia.org/wikipedia/en/e/ee/Echo2Card.jpg
+ Later EchoII without the VSM socket footprints, and with the 'FREQ' potentiometer: http://mirrors.apple2.org.za/Apple%20II%20Documentation%20Project/Interface%20Cards/Speech/Street%20Echo%20II/Photos/Echo%20II%20-%20Front.jpg
+ EchoIIb, similar to later EchoII but without the 'FREQ' potentiometer and with the 74LS92 clock divider: http://mirrors.apple2.org.za/Apple%20II%20Documentation%20Project/Interface%20Cards/Speech/Street%20Echo%20II/Photos/Echo%20IIb%20-%20Front.jpg
+
+ TODO: separate cards for the EchoII(both the freq adjustable and the older non-adjustable version, and maybe a tms5200 version?), EchoIIb (tms5220c)
+ TODO: echo+ is in a2mockinboard.cpp and really should be a sub-device inherited from here, to reduce duplicated code.
*********************************************************************/
#include "emu.h"
@@ -14,6 +26,11 @@
#include "sound/tms5220.h"
#include "speaker.h"
+#undef DEBUG_ECHOII_READYQ
+#undef DEBUG_ECHOII_READ
+#undef DEBUG_ECHOII_WRITE
+
+
/***************************************************************************
PARAMETERS
***************************************************************************/
@@ -36,8 +53,13 @@ DEFINE_DEVICE_TYPE(A2BUS_ECHOII, a2bus_echoii_device, "a2echoii", "Street Electr
MACHINE_CONFIG_START(a2bus_echoii_device::device_add_mconfig)
SPEAKER(config, "echoii").front_center();
- MCFG_DEVICE_ADD(TMS_TAG, TMS5220, 640000) // Note the Echo II card has a "FREQ" potentiometer which can be used to adjust the tms5220's clock frequency; 640khz is the '8khz' value according to the tms5220 datasheet
- MCFG_TMS52XX_READYQ_HANDLER(WRITELINE(*this, a2bus_echoii_device, ready_w))
+ MCFG_DEVICE_ADD(TMS_TAG, TMS5220, 640000) // Note the Echo II card has an R/C circuit (and sometimes a 'FREQ' potentiometer) to control the tms5220[c]'s clock frequency; 640khz is the nominal '8khz' value according to the TMS5220 datasheet.
+ // The EchoIIb card however has a 74LS92 which divides the apple2's Q3 ((14.318/7)MHz asymmetrical) clock by 6 to produce a 681.809khz/2 clock, which doesn't actually make sense, since the tms5220, unless it has a mask option (mentioned on the datasheet) to use a ceramic resonator instead of an r/c circuit, needs a clock at twice that speed. Could it be that the EchoIIb uses tsp5220C chips with a special mask option?
+ // Some Old EchoII cards shipped with TMS5200(really?), some with TMS5220. Many (most?) were retrofitted with a TMS5220 or TMS5220C later.
+ // The later VSM-socket-less EchoII shipped with a TMS5220.
+ // The EchoIIb and later cards shipped with a TMS5220C
+ //MCFG_TMS52XX_IRQ_HANDLER(WRITELINE(*this, a2bus_echoii_device, tms_irq_callback))
+ MCFG_TMS52XX_READYQ_HANDLER(WRITELINE(*this, a2bus_echoii_device, tms_readyq_callback))
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "echoii", 1.0)
MACHINE_CONFIG_END
@@ -63,65 +85,87 @@ a2bus_echoii_device::a2bus_echoii_device(const machine_config &mconfig, const ch
void a2bus_echoii_device::device_start()
{
- m_timer = timer_alloc(0);
- m_timer->adjust(attotime::never);
-
- save_item(NAME(m_latch));
- save_item(NAME(m_ready));
- save_item(NAME(m_byte_in_latch));
+ m_writelatch_data = 0xff;
+ m_readlatch_flag = true; // /RESET presets this latch
+ m_writelatch_flag = true; // not initialized but we need to set it somewhere.
+ save_item(NAME(m_writelatch_data));
+ save_item(NAME(m_readlatch_flag));
+ save_item(NAME(m_writelatch_flag));
}
void a2bus_echoii_device::device_reset()
{
- m_byte_in_latch = false;
- m_ready = 0;
- m_latch = 0;
+ m_readlatch_flag = true; // /RESET presets this latch
+ m_tms->rsq_w(m_readlatch_flag); // update the rsq pin
}
-uint8_t a2bus_echoii_device::read_c0nx(uint8_t offset)
+/*
+WRITE_LINE_MEMBER(a2bus_echoii_device::tms_irq_callback)
{
- switch (offset)
- {
- case 0:
- return 0x1f | m_tms->read_status();
- }
-
- return 0;
+ update_irq_to_maincpu();
}
+*/
-void a2bus_echoii_device::write_c0nx(uint8_t offset, uint8_t data)
+WRITE_LINE_MEMBER(a2bus_echoii_device::tms_readyq_callback)
{
- switch (offset)
+ if (state == ASSERT_LINE)
{
- case 0:
- m_latch = data;
- if (!m_ready)
- m_tms->write_data(m_latch);
- else
- m_byte_in_latch = true;
- break;
+#ifdef DEBUG_ECHOII_READYQ
+ logerror("ReadyQ callback called with state of %d! NOT READY\n", state);
+#endif
+ // the rising edge of /READY doesn't really do anything.
+ }
+ else
+ {
+#ifdef DEBUG_ECHOII_READYQ
+ logerror("ReadyQ callback called with state of %d! READY\n", state);
+#endif
+ m_writelatch_flag = true;
+ m_tms->wsq_w(m_writelatch_flag);
}
}
-bool a2bus_echoii_device::take_c800()
+uint8_t a2bus_echoii_device::read_c0nx(uint8_t offset)
{
- return false;
+ // offset is completely ignored, the same register maps to the entire space.
+ uint8_t retval = 0xff; // pull-up resistor pack on the tms5220 bus
+
+ // upon the falling edge of /DEVREAD, the active part of the read...
+ if (m_readlatch_flag == false) // /RS was low, so we need to return a value from the tms5220
+ {
+ retval = 0x1f | m_tms->status_r(machine().dummy_space(), 0, 0xff);
+#ifdef DEBUG_ECHOII_READ
+ logerror("Returning status of speech chip, which is %02x\n", retval);
+ }
+ else
+ {
+ logerror("chip status read on odd cycle, returning pull-up value of %02x\n", retval);
+#endif
+ }
+
+ // upon the rising edge of /DEVREAD, i.e. after the read has finished (so no updating retval after this)
+ m_readlatch_flag = (!m_readlatch_flag); // latch inverts itself upon each read...
+ m_tms->rsq_w(m_readlatch_flag); // update the /RS pin
+ return retval;
}
-void a2bus_echoii_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+void a2bus_echoii_device::write_c0nx(uint8_t offset, uint8_t data)
{
- m_tms->write_data(m_latch);
- m_byte_in_latch = false;
- m_timer->adjust(attotime::never);
+ // offset is completely ignored, the same register maps to the entire space.
+ if (m_writelatch_flag == false)
+ logerror("Data in echoii latch (%02x) was clobbered with new write (%02x) before being read by speech chip!\n", m_writelatch_data, data);
+#ifdef DEBUG_ECHOII_WRITE
+ else
+ logerror("Data written to latch of %02x\n", data);
+#endif
+ m_writelatch_data = data;
+
+ m_writelatch_flag = false; // /DEVWRITE clears the latch on its falling edge
+ m_tms->wsq_w(m_writelatch_flag);
+ m_tms->data_w(machine().dummy_space(), 0, m_writelatch_data);
}
-WRITE_LINE_MEMBER( a2bus_echoii_device::ready_w )
+bool a2bus_echoii_device::take_c800()
{
- // if /Ready falls, write the byte in the latch if there is one
- if ((m_ready) && (!state) && (m_byte_in_latch))
- {
- m_timer->adjust(attotime::zero);
- }
-
- m_ready = state;
+ return false;
}
diff --git a/src/devices/bus/a2bus/a2echoii.h b/src/devices/bus/a2bus/a2echoii.h
index 7e304e5b5b9..7cb1c401550 100644
--- a/src/devices/bus/a2bus/a2echoii.h
+++ b/src/devices/bus/a2bus/a2echoii.h
@@ -36,20 +36,18 @@ protected:
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_add_mconfig(machine_config &config) override;
- virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
// overrides of standard a2bus slot functions
virtual uint8_t read_c0nx(uint8_t offset) override;
virtual void write_c0nx(uint8_t offset, uint8_t data) override;
virtual bool take_c800() override;
- DECLARE_WRITE_LINE_MEMBER( ready_w );
-
private:
- uint8_t m_latch;
- int m_ready;
- emu_timer *m_timer;
- bool m_byte_in_latch;
+ //DECLARE_WRITE_LINE_MEMBER(tms_irq_callback);
+ DECLARE_WRITE_LINE_MEMBER(tms_readyq_callback);
+ uint8_t m_writelatch_data; // 74ls373 latch
+ bool m_readlatch_flag; // 74c74 1st half
+ bool m_writelatch_flag; // 74c74 2nd half
};
// device type definition