diff options
author | AJR <ajrhacker@users.noreply.github.com> | 2020-12-24 09:56:49 -0500 |
---|---|---|
committer | AJR <ajrhacker@users.noreply.github.com> | 2020-12-24 09:56:49 -0500 |
commit | 5bf175cb0599ca0f76621bb6ba5ac6195977e376 (patch) | |
tree | d2734cf1bd8ed7473ebace23051757faeca781fc /src/devices/machine | |
parent | 051c0374538b17d957db5fe766dfdf71f22e4642 (diff) |
New device: Fairchild 4702B Bit Rate Generator
Diffstat (limited to 'src/devices/machine')
-rw-r--r-- | src/devices/machine/f4702.cpp | 274 | ||||
-rw-r--r-- | src/devices/machine/f4702.h | 76 |
2 files changed, 350 insertions, 0 deletions
diff --git a/src/devices/machine/f4702.cpp b/src/devices/machine/f4702.cpp new file mode 100644 index 00000000000..40a1d0be517 --- /dev/null +++ b/src/devices/machine/f4702.cpp @@ -0,0 +1,274 @@ +// 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 "machine/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) + , 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_resolve_objects - resolve objects that +// may be needed for other devices to set +// initial conditions at start time +//------------------------------------------------- + +void f4702_device::device_resolve_objects() +{ + // resolve callbacks + m_s_callback.resolve_safe(15); + m_z_callback.resolve_safe(); +} + + +//------------------------------------------------- +// 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 +//------------------------------------------------- + +WRITE_LINE_MEMBER(f4702_device::im_w) +{ + 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); +} diff --git a/src/devices/machine/f4702.h b/src/devices/machine/f4702.h new file mode 100644 index 00000000000..c48601b1e3c --- /dev/null +++ b/src/devices/machine/f4702.h @@ -0,0 +1,76 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/**************************************************************************** + + Fairchild 4702B Programmable Bit Rate Generator + +***************************************************************************** + ____ ____ + Q0 1 |* \_/ | 16 Vdd + Q1 2 | | 15 Im + Q2 3 | | 14 S0 + _Ecp 4 | | 13 S1 + CP 5 | 4702BPC | 12 S2 + Ox 6 | | 11 S3 + Ix 7 | | 10 Z + Vss 8 |___________| 9 CO + +****************************************************************************/ + +#ifndef MAME_MACHINE_F4702_H +#define MAME_MACHINE_F4702_H + +#pragma once + + +// ======================> f4702_device + +class f4702_device : public device_t, public device_execute_interface +{ +public: + f4702_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + // callback configuration + auto s_callback() { return m_s_callback.bind(); } + auto z_callback() { return m_z_callback.bind(); } + + // external rate input + DECLARE_WRITE_LINE_MEMBER(im_w); + + // reset control (optional) + void reset_counters(); + +protected: + // device-level overrides + virtual void device_resolve_objects() override; + virtual void device_start() override; + + // device_execute_interface overrides + virtual void execute_run() override; + +private: + // internal helpers + bool z_output() const; + + // input & output callbacks + devcb_read8 m_s_callback; + devcb_write8 m_z_callback; + + // internal counters + u16 m_main_counter; + u8 m_div_200_50; + u8 m_div_134_5; + u8 m_div_110; + u8 m_div_1800; + + // miscellaneous state + bool m_im; + u8 m_s; + s32 m_icount; +}; + +// device type declaration +DECLARE_DEVICE_TYPE(F4702, f4702_device) + +#endif // MAME_MACHINE_F4702_H + |