summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/f4702.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/f4702.cpp')
-rw-r--r--src/devices/machine/f4702.cpp260
1 files changed, 260 insertions, 0 deletions
diff --git a/src/devices/machine/f4702.cpp b/src/devices/machine/f4702.cpp
new file mode 100644
index 00000000000..499f1a6793a
--- /dev/null
+++ b/src/devices/machine/f4702.cpp
@@ -0,0 +1,260 @@
+// license:BSD-3-Clause
+// copyright-holders:AJR
+/****************************************************************************
+
+ Fairchild 4702B Programmable Bit Rate Generator
+
+ Originally numbered 34702 in Fairchild's isoplanar CMOS series (whose
+ lower-numbered products were logical equivalents of RCA CD4000 and
+ Motorola MC14500 series devices), this BRG incorporates some unusually
+ sophisticated features into its 16-pin package, which may be why
+ Fairchild classified it as a LSI IC.
+
+ The standard 2.4576 MHz master clock, either generated from a crystal
+ oscillator (Ix, Ox) or provided as a TTL input (CP), is first prescaled
+ by dividing by 8 and then divided further down through a network of
+ counters with differing periods. These counters are tapped at 13 points,
+ each frequency being 16 times a common baud rate. The rate output (Z),
+ whose changes are synchronized with the master clock, is multiplexed
+ from any one of these internal sources or an external rate input (Im) by
+ a 4-bit select code (S0, S1, S2, S3).
+
+ The buffered clock output (CO) and the three prescaler divisions (Q0,
+ Q1, Q2) are not only conveniently available externally for clocking
+ additional 4702s or other devices, but can also be exploited to
+ generate 8 baud rates simultaneously, with the aid of a Fairchild 93L34
+ (or compatible) addressable latch for demultiplexing the channels. In
+ this configuration, the CO, Q and Z outputs are respectively tied to the
+ latch's enable, address and data inputs, and the Q outputs are directly
+ or indirectly fed back into the S inputs. (Fairchild even suggested
+ scanning 9LS170 register files with the Q outputs so as to make each
+ rate individually programmable.)
+
+ The rate select codes are arranged so that connecting a simple five-
+ point switch to the S inputs can obtain 110, 150, 300, 1200 or 2400
+ baud, and only three binary switches are needed to select between all
+ five of those rates plus 1800, 4800 and 9600 baud. 19200 baud can also
+ be obtained by tapping the Q2 output, but no more than 4 internally
+ multiplexed rates can be used at once if Im is generated from Q2.
+
+ All inputs and outputs except Ix and Ox are TTL-compatible, with the
+ inputs also having internal pull-ups so switches can be connected
+ directly.
+
+ To enable the Ix/Ox oscillator circuit, Ecp must be high and CP must
+ remain low, since Ecp and CP both being high places the chip in a
+ continuous reset mode (except for the CO output). If Ecp is brought
+ low, the initialization circuit produces an internal master reset
+ pulse the first time CP goes high. Neither of these two reset methods
+ was used much in practice.
+
+ Intersil, one of not many companies to second-source the original 4702,
+ later produced IM4712, a minor variant which requires fewer external
+ discrete components to drive the crystal oscillator but is otherwise
+ logically identical.
+
+****************************************************************************/
+
+#include "emu.h"
+#include "f4702.h"
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// device type definition
+DEFINE_DEVICE_TYPE(F4702, f4702_device, "f4702", "Fairchild 4702B Bit Rate Generator")
+
+
+//**************************************************************************
+// DEVICE CONSTRUCTION AND INITIALIZATION
+//**************************************************************************
+
+//-------------------------------------------------
+// f4702_device - constructor
+//-------------------------------------------------
+
+f4702_device::f4702_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : device_t(mconfig, F4702, tag, owner, clock)
+ , device_execute_interface(mconfig, *this)
+ , m_s_callback(*this, 15)
+ , m_z_callback(*this)
+ , m_main_counter(0)
+ , m_div_200_50(0)
+ , m_div_134_5(0)
+ , m_div_110(0)
+ , m_div_1800(0)
+ , m_im(true)
+ , m_s(0)
+ , m_icount(0)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void f4702_device::device_start()
+{
+ set_icountptr(m_icount);
+
+ save_item(NAME(m_main_counter));
+ save_item(NAME(m_div_200_50));
+ save_item(NAME(m_div_134_5));
+ save_item(NAME(m_div_110));
+ save_item(NAME(m_div_1800));
+ save_item(NAME(m_im));
+ save_item(NAME(m_s));
+}
+
+
+//-------------------------------------------------
+// reset_counters - optional master reset
+//-------------------------------------------------
+
+void f4702_device::reset_counters()
+{
+ // Reset counter network
+ m_main_counter = 0;
+ m_div_200_50 = 0;
+ m_div_134_5 = 0;
+ m_div_1800 = 0;
+
+ // Reset Q and Z outputs
+ m_z_callback(0, 0);
+}
+
+
+//**************************************************************************
+// RATE GENERATION
+//**************************************************************************
+
+//-------------------------------------------------
+// im_w - set external rate input
+//-------------------------------------------------
+
+void f4702_device::im_w(int state)
+{
+ m_im = state;
+}
+
+
+//-------------------------------------------------
+// z_output - recalculate output state
+//-------------------------------------------------
+
+bool f4702_device::z_output() const
+{
+ // Select Z output from one of the 13 counter taps or the external input
+ switch (m_s)
+ {
+ // S3–S0 = LLLL or LLLH: multiplexed input
+ case 0:
+ case 1:
+ default:
+ return m_im;
+
+ // S3–S0 = LLHL: 50 baud
+ case 2:
+ return m_div_200_50 >= 12;
+
+ // S3–S0 = LLHH: 75 baud
+ case 3:
+ return BIT(m_main_counter, 10);
+
+ // S3–S0 = LHLL: 134.5 baud (-0.87% error)
+ case 4:
+ return m_div_134_5 >= 9;
+
+ // S3–S0 = LHLH: 200 baud
+ case 5:
+ return (m_div_200_50 % 6) >= 3;
+
+ // S3–S0 = LHHL: 600 baud
+ case 6:
+ return BIT(m_main_counter, 7);
+
+ // S3–S0 = LHHH or HHLL: 2400 baud
+ case 7:
+ case 12:
+ return BIT(m_main_counter, 5);
+
+ // S3–S0 = HLLL: 9600 baud
+ case 8:
+ return BIT(m_main_counter, 3);
+
+ // S3–S0 = HLLH: 4800 baud
+ case 9:
+ return BIT(m_main_counter, 4);
+
+ // S3–S0 = HLHL: 1800 baud
+ case 10:
+ return (m_div_1800 % 5) >= 2;
+
+ // S3–S0 = HLHH: 1200 baud
+ case 11:
+ return BIT(m_main_counter, 6);
+
+ // S3–S0 = HHLH: 300 baud
+ case 13:
+ return BIT(m_main_counter, 8);
+
+ // S3–S0 = HHHL: 150 baud
+ case 14:
+ return BIT(m_main_counter, 9);
+
+ // S3–S0 = HHHH: 110 baud (-0.83% error)
+ case 15:
+ return m_div_110 >= 11;
+ }
+}
+
+
+//-------------------------------------------------
+// execute_run - execute a timeslice's worth of
+// counting
+//-------------------------------------------------
+
+void f4702_device::execute_run()
+{
+ do {
+ // Drive the main scan and frequency counter
+ m_main_counter++;
+ if ((m_main_counter & 0x00f) == 0)
+ {
+ // Divide 9600 baud by 16/3 (16 = 5 + 5 + 6)
+ m_div_1800++;
+ if (m_div_1800 >= 16)
+ m_div_1800 = 0;
+
+ if ((m_main_counter & 0x03f) == 0)
+ {
+ // Divide 2400 baud by 18
+ m_div_134_5++;
+ if (m_div_134_5 >= 18)
+ m_div_134_5 = 0;
+
+ // Divide 2400 baud by 22 as well
+ m_div_110++;
+ if (m_div_110 >= 22)
+ m_div_110 = 0;
+
+ if ((m_main_counter & 0x07f) == 0)
+ {
+ // Divide 1200 baud by 6 and then again by 4
+ m_div_200_50++;
+ if (m_div_200_50 >= 24)
+ m_div_200_50 = 0;
+ }
+ }
+ }
+
+ // Update Q and Z outputs
+ m_z_callback(m_main_counter & 0x007, z_output());
+
+ // S3–S0 inputs are valid on the rising edge of CO
+ m_s = m_s_callback(m_main_counter & 0x007) & 15;
+ } while (--m_icount > 0);
+}