summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Michael Zapf <Michael.Zapf@mizapf.de>2017-06-06 16:21:51 +0200
committer Michael Zapf <Michael.Zapf@mizapf.de>2017-06-06 16:21:51 +0200
commit6e577c54653e7d1d53426166d7de23216d88699a (patch)
treea555fec5a4d8258d764b57e64d7503a489207e3d
parentb58178449496788531644f3e08a586c26a66fcbe (diff)
ti99: Hexbus implementation; floppy HX5102 early WIP
-rw-r--r--scripts/src/bus.lua6
-rw-r--r--src/devices/bus/ti99/hexbus/hexbus.cpp282
-rw-r--r--src/devices/bus/ti99/hexbus/hexbus.h141
-rw-r--r--src/devices/bus/ti99/hexbus/hx5102.cpp28
-rw-r--r--src/devices/bus/ti99/hexbus/hx5102.h34
-rw-r--r--src/devices/bus/ti99/internal/998board.cpp12
-rw-r--r--src/devices/bus/ti99/internal/998board.h5
-rw-r--r--src/devices/bus/ti99/ti99defs.h1
-rw-r--r--src/mame/drivers/ti99_8.cpp4
9 files changed, 509 insertions, 4 deletions
diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua
index 49600891ed3..3f7e1d1a341 100644
--- a/scripts/src/bus.lua
+++ b/scripts/src/bus.lua
@@ -2362,7 +2362,7 @@ end
--@src/devices/bus/ti99/joyport/joyport.h,BUSES["TI99"] = true
--@src/devices/bus/ti99/peb/peribox.h,BUSES["TI99"] = true
--@src/devices/bus/ti99/internal/genboard.h,BUSES["TI99"] = true
-
+--@src/devices/bus/ti99/hexbus/hexbus.h,BUSES["TI99"] = true
---------------------------------------------------
if (BUSES["TI99"]~=null) then
@@ -2392,6 +2392,10 @@ if (BUSES["TI99"]~=null) then
MAME_DIR .. "src/devices/bus/ti99/gromport/multiconn.h",
MAME_DIR .. "src/devices/bus/ti99/gromport/singleconn.cpp",
MAME_DIR .. "src/devices/bus/ti99/gromport/singleconn.h",
+ MAME_DIR .. "src/devices/bus/ti99/hexbus/hexbus.cpp",
+ MAME_DIR .. "src/devices/bus/ti99/hexbus/hexbus.h",
+ MAME_DIR .. "src/devices/bus/ti99/hexbus/hx5102.cpp",
+ MAME_DIR .. "src/devices/bus/ti99/hexbus/hx5102.h",
MAME_DIR .. "src/devices/bus/ti99/joyport/handset.cpp",
MAME_DIR .. "src/devices/bus/ti99/joyport/handset.h",
MAME_DIR .. "src/devices/bus/ti99/joyport/joyport.cpp",
diff --git a/src/devices/bus/ti99/hexbus/hexbus.cpp b/src/devices/bus/ti99/hexbus/hexbus.cpp
new file mode 100644
index 00000000000..794d1d344d3
--- /dev/null
+++ b/src/devices/bus/ti99/hexbus/hexbus.cpp
@@ -0,0 +1,282 @@
+// license:LGPL-2.1+
+// copyright-holders:Michael Zapf
+/****************************************************************************
+
+ =========== Hexbus peripheral bus ===========
+
+ The Hexbus is a 4-bit peripheral bus with master/slave coordination. Bytes
+ are written over the bus in two passes. Hexbus was the designated standard
+ peripheral bus for TI computers before TI left the home computer market.
+
+ The Hexbus was also named IPB = Intelligent Peripheral Bus [1]
+
+ Existing devices are floppy drive, RS232 serial adapter, and
+ a "Wafertape" drive (kind of tape streamer)
+
+ Hexbus connector (console)
+ +---+---+---+---+
+ | 4 | 3 | 2 | 1 | 4 = L; 3 = BAV*; 2 = ADB1; 1 = ADB0
+ +---+---+---+---+
+ | 8 | 7 | 6 | 5 | 8 = ADB3; 7 = ADB2; 6 = nc; 5 = HSK*
+ +---+---+---+---+
+
+ ADBx = Hexbus data bit X (x=0..3)
+ HSK* = Handshake
+ BAV* = Bus available (0=yes)
+
+ Theory of operation
+ -------------------
+ The bus connects all devices in a daisy chain. The lines are inactive high
+ and pulled down by any device that sets them to 0.
+
+ HSK* is a synchronization line for transmitting single bytes.
+ BAV* is a synchronization line for complete request-response pairs
+
+ Before a byte can be sent, the sender must check the BAV* line. When it is
+ inactive (1), it pulls it down, and then starts transmitting. The line
+ is raised again when the response has been fully received.
+
+ For transmitting a byte, the HSK* line must first be pulled down by the
+ sender. Then, the lower nibble is transmitted first, and the sender
+ releases the HSK* line. Every receiver that has completely received the
+ nibble and is ready for the next one releases the HSK* line. The sender
+ must check the HSK* line until it goes high again (which means that the
+ slowest receiver has got the nibble). This is repeated for the high nibble.
+
+ When the BAV* signal is asserted (0), the HSK* line must not be high for
+ more than 20 ms, or a bus timeout occurs.
+
+ The device address is transmitted as part of the request header. All
+ devices with a non-matching device code must ignore the rest of the
+ message until BAV* goes inactive (1) again.
+
+ If there is no matching device, HSK* will remain 1 after the end of the
+ master's request, and after 20ms, a timeout will occur. Declaring a timeout
+ is a matter of the devices, not of the bus.
+
+ Message format
+ --------------
+
+ +-------------+-------------+-------------+-------------+
+ | Device Code | Command code| LogUnitNum | RecNum LSB |
+ +-------------+-------------+-------------+-------------+
+ | RecNum MSB | Buflen LSB | Buflen MSB | DataLen LSB |
+ +-------------+-------------+-------------+-------------+
+ | DataLen MSB | |
+ +-------------+ |
+ | Data ... (not padded) |
+ | |
+ | |
+ +-------------+-------------+-------------+-------------+
+
+ Device codes
+ ------------
+
+ 0 - all devices (but none will respond, forcing a timeout)
+ 1-8 - Tape mass storage
+ 10-17 - Printer / plotter
+ 20-27 - RS-232 interface
+ 30-37 - TV interface (color)
+ 40-47 - TV interface (B/W)
+ 50-57 - Centronics interface
+ 60-67 - Calculator in slave mode
+ 70-77 - Modem
+ 80-87 - GPIB interface (?)
+ 90-97 - Bar code reader
+ 100-107 - Floppy disk drive
+
+ Usage in MAME
+ -------------
+
+ Single device usage:
+ mame <driver> -hexbus <device>
+
+ Multiple device usage:
+ mame <driver> -hexbus chain -hexbus:chain:1 <device> ... -hexbus:chain:4 <device>
+
+ We currently assume a maximum length of 4 devices which can be increased
+ if desired. The chain positions should be used starting from 1 with no
+ gaps, but this is not enforced.
+
+ References
+ ----------
+
+ [1] Intelligent Peripheral Bus: Structure, Timing, and Protocol Specification
+ Texas Instruments Inc., Consumer Products Group, Calculator Division,
+ 7/3/82, Revision 2.8
+
+ Michael Zapf
+ June 2017
+
+*****************************************************************************/
+#include "emu.h"
+#include "hexbus.h"
+
+// Devices
+#include "hx5102.h"
+
+// Hexbus instance
+DEFINE_DEVICE_TYPE_NS(TI_HEXBUS, bus::ti99::hexbus, hexbus_device, "ti_hexbus", "Hexbus")
+
+// Hexbus daisy chain
+DEFINE_DEVICE_TYPE_NS(TI_HEXBUS_CHAIN, bus::ti99::hexbus, hexbus_chain_device, "ti_hexbus_chain", "Hexbus chain")
+
+// Single slot of the Hexbus
+DEFINE_DEVICE_TYPE_NS(TI_HEXBUS_SLOT, bus::ti99::hexbus, hexbus_slot_device, "ti_hexbus_slot", "Hexbus position")
+
+namespace bus { namespace ti99 { namespace hexbus {
+
+enum
+{
+ NOTCONN = -1
+};
+
+hexbus_device::hexbus_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ device_t(mconfig, TI_HEXBUS, tag, owner, clock),
+ device_slot_interface(mconfig, *this),
+ m_master(nullptr),
+ m_slave(nullptr)
+{
+}
+
+void hexbus_device::device_start()
+{
+}
+
+void hexbus_device::device_config_complete()
+{
+ m_slave = static_cast<hexbus_attached_device*>(subdevices().first());
+ if (m_slave != nullptr)
+ m_slave->set_hexbus(this);
+}
+
+void hexbus_device::send()
+{
+ uint8_t sum = m_master->get_value();
+ if (m_slave != nullptr)
+ {
+ sum &= m_slave->get_value();
+ m_slave->receive(sum);
+ }
+ m_master->receive(sum);
+}
+
+// ------------------------------------------------------------------------
+
+hexbus_chain_device::hexbus_chain_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ hexbus_attached_device(mconfig, TI_HEXBUS_CHAIN, tag, owner, clock)
+{
+}
+
+uint8_t hexbus_chain_device::get_value()
+{
+ uint8_t sum = 0xff;
+
+ // Do the wired AND
+ for (device_t &child : subdevices())
+ {
+ hexbus_slot_device* slot = downcast<hexbus_slot_device *>(&child);
+ sum &= slot->get_value();
+ }
+
+ return sum;
+}
+
+void hexbus_chain_device::receive(uint8_t value)
+{
+ // Propagate
+ for (device_t &child : subdevices())
+ {
+ hexbus_slot_device* slot = downcast<hexbus_slot_device *>(&child);
+ slot->receive(value);
+ }
+}
+
+void hexbus_chain_device::device_start()
+{
+}
+
+SLOT_INTERFACE_START( ti_hexbus_chain_slot )
+// SLOT_INTERFACE("hx5102", TI_HX5102) // not an option yet
+SLOT_INTERFACE_END
+
+MACHINE_CONFIG_MEMBER( hexbus_chain_device::device_add_mconfig )
+ MCFG_HEXBUS_SLOT_ADD( "1", ti_hexbus_chain_slot )
+ MCFG_HEXBUS_SLOT_ADD( "2", ti_hexbus_chain_slot )
+ MCFG_HEXBUS_SLOT_ADD( "3", ti_hexbus_chain_slot )
+ MCFG_HEXBUS_SLOT_ADD( "4", ti_hexbus_chain_slot )
+MACHINE_CONFIG_END
+
+// ------------------------------------------------------------------------
+
+int hexbus_slot_device::get_index_from_tagname()
+{
+ const char *mytag = tag();
+ int maxlen = strlen(mytag);
+ int i;
+ for (i=maxlen-1; i >=0; i--)
+ if (mytag[i] < 48 || mytag[i] > 57) break;
+
+ return atoi(mytag+i+1);
+}
+
+hexbus_slot_device::hexbus_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, TI_HEXBUS_SLOT, tag, owner, clock),
+ device_slot_interface(mconfig, *this),
+ m_hexbdev(nullptr)
+{
+}
+
+/* Called from the Hexbus instance */
+int hexbus_slot_device::get_index()
+{
+ if (m_hexbdev == nullptr) return NOTCONN;
+ return get_index_from_tagname();
+}
+
+uint8_t hexbus_slot_device::get_value()
+{
+ return (m_hexbdev != nullptr)? m_hexbdev->get_value() : 0xff;
+}
+
+void hexbus_slot_device::receive(uint8_t value)
+{
+ if (m_hexbdev != nullptr)
+ m_hexbdev->receive(value);
+}
+
+void hexbus_slot_device::device_start()
+{
+}
+
+void hexbus_slot_device::device_config_complete()
+{
+ m_hexbus = dynamic_cast<hexbus_device*>(owner());
+ m_hexbdev = downcast<hexbus_attached_device *>(subdevices().first());
+}
+
+// ------------------------------------------------------------------------
+
+hexbus_attached_device::hexbus_attached_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
+ device_t(mconfig, type, tag, owner, clock),
+ device_slot_card_interface(mconfig, *this)
+{
+}
+
+void hexbus_attached_device::device_start()
+{
+}
+
+void hexbus_attached_device::hexbus_send(uint8_t value)
+{
+ m_value = value;
+ m_hexbus->send();
+}
+
+} } } // end namespace bus::ti99::hexbus
+
+SLOT_INTERFACE_START( ti_hexbus_conn )
+// SLOT_INTERFACE("hx5102", TI_HX5102) // not an option yet
+ SLOT_INTERFACE("chain", TI_HEXBUS_CHAIN)
+SLOT_INTERFACE_END
+
diff --git a/src/devices/bus/ti99/hexbus/hexbus.h b/src/devices/bus/ti99/hexbus/hexbus.h
new file mode 100644
index 00000000000..c29a9813e37
--- /dev/null
+++ b/src/devices/bus/ti99/hexbus/hexbus.h
@@ -0,0 +1,141 @@
+// license:LGPL-2.1+
+// copyright-holders:Michael Zapf
+/****************************************************************************
+
+ Hexbus peripheral bus
+ See hexbus.cpp for documentation
+
+ Michael Zapf
+ June 2017
+
+ -hexbus:1 hx5102 -hexbus:2 ...
+
+*****************************************************************************/
+
+#ifndef MAME_BUS_TI99_HEXBUS_HEXBUS_H
+#define MAME_BUS_TI99_HEXBUS_HEXBUS_H
+
+#pragma once
+
+#include "bus/ti99/ti99defs.h"
+
+namespace bus { namespace ti99 { namespace hexbus {
+
+enum
+{
+ MAX_DEVICES = 4
+};
+
+class hexbus_attached_device;
+class hexbus_slot_device;
+
+class hexbus_device : public device_t, public device_slot_interface
+{
+ friend class hexbus_attached_device;
+
+public:
+ hexbus_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ void connect_master(hexbus_attached_device *masterdev) { m_master = masterdev; }
+
+protected:
+ void device_start() override;
+ void device_config_complete() override;
+
+private:
+ hexbus_attached_device *m_master;
+ hexbus_attached_device *m_slave;
+
+ // Called from a slot, samples all values from the devices, and propagates
+ // the logical product to all connected devices
+ void send();
+};
+
+/*****************************************************************************
+ The parent class for all Hexbus devices
+******************************************************************************/
+
+class hexbus_attached_device : public device_t, public device_slot_card_interface
+{
+ friend class hexbus_slot_device;
+ friend class hexbus_device;
+
+protected:
+ hexbus_attached_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
+ void device_start() override;
+
+ void hexbus_send(uint8_t value);
+ uint8_t hexbus_receive() { return m_busvalue; }
+
+ virtual void receive(uint8_t value) { m_busvalue = value; }
+ virtual uint8_t get_value() { return m_value; }
+
+private:
+ void set_hexbus(hexbus_device* hexbus) { m_hexbus = hexbus; }
+
+ uint8_t m_value;
+ uint8_t m_busvalue;
+ hexbus_device *m_hexbus; // Link to the Hexbus
+};
+
+// ------------------------------------------------------------------------
+
+class hexbus_chain_device : public hexbus_attached_device
+{
+public:
+ hexbus_chain_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ void device_add_mconfig(machine_config &config) override;
+
+private:
+ void device_start() override;
+ void receive(uint8_t value) override;
+ uint8_t get_value() override;
+};
+
+// ------------------------------------------------------------------------
+
+class hexbus_slot_device : public device_t, public device_slot_interface
+{
+ friend class hexbus_attached_device;
+ friend class hexbus_chain_device;
+
+public:
+ hexbus_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ // Called from the hexbus (direction to attached device)
+ void receive(uint8_t value);
+
+ // Called from the hexbus
+ uint8_t get_value();
+
+protected:
+ void device_start() override;
+ void device_config_complete() override;
+
+ // Called from the Hexbus instance
+ int get_index();
+
+private:
+ int get_index_from_tagname();
+
+ hexbus_attached_device* m_hexbdev;
+ hexbus_device* m_hexbus;
+};
+
+
+#define MCFG_HEXBUS_ADD( _tag ) \
+ MCFG_DEVICE_ADD(_tag, TI_HEXBUS, 0) \
+ MCFG_DEVICE_SLOT_INTERFACE( ti_hexbus_conn, nullptr, false)
+
+#define MCFG_HEXBUS_SLOT_ADD(_tag, _slot_intf) \
+ MCFG_DEVICE_ADD(_tag, TI_HEXBUS_SLOT, 0) \
+ MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, nullptr, false)
+
+} } } // end namespace bus::ti99::hexbus
+
+SLOT_INTERFACE_EXTERN( ti_hexbus_conn );
+
+DECLARE_DEVICE_TYPE_NS(TI_HEXBUS, bus::ti99::hexbus, hexbus_device)
+DECLARE_DEVICE_TYPE_NS(TI_HEXBUS_CHAIN, bus::ti99::hexbus, hexbus_chain_device)
+DECLARE_DEVICE_TYPE_NS(TI_HEXBUS_SLOT, bus::ti99::hexbus, hexbus_slot_device)
+
+#endif // MAME_BUS_TI99_HEXBUS_HEXBUS_H
diff --git a/src/devices/bus/ti99/hexbus/hx5102.cpp b/src/devices/bus/ti99/hexbus/hx5102.cpp
new file mode 100644
index 00000000000..250c015b0d6
--- /dev/null
+++ b/src/devices/bus/ti99/hexbus/hx5102.cpp
@@ -0,0 +1,28 @@
+// license:LGPL-2.1+
+// copyright-holders:Michael Zapf
+/****************************************************************************
+
+ Hexbus floppy disk drive
+ HX5102
+
+ Work in progress
+
+ Michael Zapf
+ June 2017
+
+*****************************************************************************/
+
+#include "emu.h"
+#include "hx5102.h"
+
+DEFINE_DEVICE_TYPE_NS(TI_HX5102, bus::ti99::hexbus, hx5102_device, "ti_hx5102", "TI Hexbus Floppy")
+
+namespace bus { namespace ti99 { namespace hexbus {
+
+hx5102_device::hx5102_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock):
+ hexbus_attached_device(mconfig, TI_HX5102, tag, owner, clock)
+{
+}
+
+} } } // end namespace bus::ti99::hexbus
+
diff --git a/src/devices/bus/ti99/hexbus/hx5102.h b/src/devices/bus/ti99/hexbus/hx5102.h
new file mode 100644
index 00000000000..1381ffd4c86
--- /dev/null
+++ b/src/devices/bus/ti99/hexbus/hx5102.h
@@ -0,0 +1,34 @@
+// license:LGPL-2.1+
+// copyright-holders:Michael Zapf
+/****************************************************************************
+
+ Hexbus floppy disk drive
+ HX5102
+
+ See hx5102.cpp for documentation
+
+ Michael Zapf
+ June 2017
+
+*****************************************************************************/
+
+#ifndef MAME_BUS_TI99_HEXBUS_HX5102_H
+#define MAME_BUS_TI99_HEXBUS_HX5102_H
+
+#pragma once
+
+#include "hexbus.h"
+
+namespace bus { namespace ti99 { namespace hexbus {
+
+class hx5102_device : public hexbus_attached_device
+{
+public:
+ hx5102_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+};
+
+} } } // end namespace bus::ti99::hexbus
+
+DECLARE_DEVICE_TYPE_NS(TI_HX5102, bus::ti99::hexbus, hx5102_device)
+
+#endif // MAME_BUS_TI99_HEXBUS_HX5102_H
diff --git a/src/devices/bus/ti99/internal/998board.cpp b/src/devices/bus/ti99/internal/998board.cpp
index ea93c9b77cb..e8e47be74fb 100644
--- a/src/devices/bus/ti99/internal/998board.cpp
+++ b/src/devices/bus/ti99/internal/998board.cpp
@@ -2232,8 +2232,12 @@ enum
SHSK = 0x01
};
-oso_device::oso_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : device_t(mconfig, TI99_OSO, tag, owner, clock), m_data(0), m_status(0), m_control(0), m_xmit(0)
+oso_device::oso_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ bus::ti99::hexbus::hexbus_attached_device(mconfig, TI99_OSO, tag, owner, clock),
+ m_data(0),
+ m_status(0),
+ m_control(0),
+ m_xmit(0)
{
}
@@ -2296,6 +2300,10 @@ void oso_device::device_start()
{
logerror("Starting\n");
m_status = m_xmit = m_control = m_data = 0;
+
+ m_hexbus = downcast<bus::ti99::hexbus::hexbus_device*>(machine().device(TI_HEXBUS_TAG));
+ m_hexbus->connect_master(this);
+
save_item(NAME(m_data));
save_item(NAME(m_status));
save_item(NAME(m_control));
diff --git a/src/devices/bus/ti99/internal/998board.h b/src/devices/bus/ti99/internal/998board.h
index ca1b7c1e5ba..240cb2c6951 100644
--- a/src/devices/bus/ti99/internal/998board.h
+++ b/src/devices/bus/ti99/internal/998board.h
@@ -20,6 +20,7 @@
#include "bus/ti99/ti99defs.h"
#include "bus/ti99/gromport/gromport.h"
+#include "bus/ti99/hexbus/hexbus.h"
#include "bus/ti99/internal/ioport.h"
#include "machine/ram.h"
@@ -371,7 +372,7 @@ private:
/*
Custom chip: OSO
*/
-class oso_device : public device_t
+class oso_device : public bus::ti99::hexbus::hexbus_attached_device
{
public:
oso_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
@@ -384,6 +385,8 @@ private:
uint8_t m_status;
uint8_t m_control;
uint8_t m_xmit;
+
+ bus::ti99::hexbus::hexbus_device* m_hexbus;
};
class mainboard8_device : public device_t
diff --git a/src/devices/bus/ti99/ti99defs.h b/src/devices/bus/ti99/ti99defs.h
index 1f0d549e2bb..43f18796ce0 100644
--- a/src/devices/bus/ti99/ti99defs.h
+++ b/src/devices/bus/ti99/ti99defs.h
@@ -43,6 +43,7 @@
#define MAPPER_TAG "mapper"
#define MAINBOARD8_TAG "mainboard8"
#define SPEECHSYN_TAG "speech"
+#define TI_HEXBUS_TAG "hexbus"
#define ROM0_REG "rom0_region"
#define ROM1_REG "rom1_region"
diff --git a/src/mame/drivers/ti99_8.cpp b/src/mame/drivers/ti99_8.cpp
index 8e74cf7b71e..adbb8f7e65c 100644
--- a/src/mame/drivers/ti99_8.cpp
+++ b/src/mame/drivers/ti99_8.cpp
@@ -183,6 +183,7 @@ Known Issues (MZ, 2010-11-07)
#include "bus/ti99/internal/998board.h"
#include "bus/ti99/gromport/gromport.h"
+#include "bus/ti99/hexbus/hexbus.h"
#include "bus/ti99/joyport/joyport.h"
#include "bus/ti99/internal/ioport.h"
@@ -763,6 +764,9 @@ static MACHINE_CONFIG_START( ti99_8 )
MCFG_IOPORT_EXTINT_HANDLER( WRITELINE(ti99_8_state, extint) )
MCFG_IOPORT_READY_HANDLER( DEVWRITELINE(MAINBOARD8_TAG, bus::ti99::internal::mainboard8_device, pbox_ready) )
+ // Hexbus
+ MCFG_HEXBUS_ADD( TI_HEXBUS_TAG )
+
// Sound hardware
MCFG_SPEAKER_STANDARD_MONO("sound_out")
MCFG_SOUND_ADD(TISOUNDCHIP_TAG, SN76496, 3579545) /* 3.579545 MHz */