summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/machine/74123.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/machine/74123.c')
-rw-r--r--src/emu/machine/74123.c190
1 files changed, 190 insertions, 0 deletions
diff --git a/src/emu/machine/74123.c b/src/emu/machine/74123.c
new file mode 100644
index 00000000000..c6199233665
--- /dev/null
+++ b/src/emu/machine/74123.c
@@ -0,0 +1,190 @@
+/*****************************************************************************
+
+ 74123 monoflop emulator - see 74123.h for pin out and truth table
+
+ Formulas came from the TI datasheet revised on March 1998
+
+ *****************************************************************************/
+
+#include "driver.h"
+#include "machine/74123.h"
+#include "rescap.h"
+
+
+#define LOG (0)
+
+
+typedef struct _TTL74123_state TTL74123_state;
+
+struct _TTL74123_state
+{
+ const TTL74123_interface *intf;
+ int which;
+
+ UINT8 A; /* pin 1/9 */
+ UINT8 B; /* pin 2/10 */
+ UINT8 clear; /* pin 3/11 */
+ emu_timer *timer;
+};
+
+static TTL74123_state chips[MAX_TTL74123];
+
+
+static attotime compute_duration(TTL74123_state *chip)
+{
+ double duration;
+
+ switch (chip->intf->connection_type)
+ {
+ case TTL74123_NOT_GROUNDED_NO_DIODE:
+ duration = 0.28 * chip->intf->res * chip->intf->cap * (1.0 + (0.7 / chip->intf->res));
+ break;
+
+ case TTL74123_NOT_GROUNDED_DIODE:
+ duration = 0.25 * chip->intf->res * chip->intf->cap * (1.0 + (0.7 / chip->intf->res));
+ break;
+
+ case TTL74123_GROUNDED:
+ default:
+ if (chip->intf->cap < CAP_U(0.1))
+ /* this is really a curve - a very flat one in the 0.1uF-.01uF range */
+ duration = 0.32 * chip->intf->res * chip->intf->cap;
+ else
+ duration = 0.33 * chip->intf->res * chip->intf->cap;
+ break;
+ }
+
+ return double_to_attotime(duration);
+}
+
+
+static int timer_running(TTL74123_state *chip)
+{
+ return (attotime_compare(timer_timeleft(chip->timer), attotime_zero) > 0) &&
+ (attotime_compare(timer_timeleft(chip->timer), attotime_never) != 0);
+}
+
+
+static void set_output(TTL74123_state *chip)
+{
+ int output = timer_running(chip);
+
+ chip->intf->output_changed_cb(output);
+
+ if (LOG) logerror("74123 #%d: Output: %d\n", chip->which, output);
+}
+
+
+static TIMER_CALLBACK_PTR( clear_callback )
+{
+ TTL74123_state *chip = param;
+
+ set_output(chip);
+}
+
+
+void TTL74123_config(int which, const TTL74123_interface *intf)
+{
+ TTL74123_state *chip;
+
+ assert_always(which < MAX_TTL74123, "Exceeded maximum number of 74123 chips");
+ assert_always(intf, "No interface specified");
+ assert_always((intf->connection_type == TTL74123_GROUNDED) && (intf->cap >= CAP_U(0.01)), "Only capacitors >= 0.01uF supported for GROUNDED type");
+ assert_always(intf->cap >= CAP_P(1000), "Only capacitors >= 1000pF supported ");
+
+ chip = &chips[which];
+
+ chip->intf = intf;
+ chip->which = which;
+ chip->timer = timer_alloc_ptr(clear_callback, chip);
+
+ /* start with the defaults */
+ chip->A = intf->A;
+ chip->B = intf->B;
+ chip->clear = intf->clear;
+
+ /* register for state saving */
+ state_save_register_item("TTL74123", which, chip->A);
+ state_save_register_item("TTL74123", which, chip->B);
+ state_save_register_item("TTL74123", which, chip->clear);
+}
+
+
+void TTL74123_reset(int which)
+{
+ TTL74123_state *chip = &chips[which];
+
+ set_output(chip);
+}
+
+
+static void start_pulse(TTL74123_state *chip)
+{
+ attotime duration = compute_duration(chip);
+
+ if (timer_running(chip))
+ {
+ /* retriggering, but not if we are called to quickly */
+ attotime delay_time = attotime_make(0, ATTOSECONDS_PER_SECOND * chip->intf->cap * 220);
+
+ if (attotime_compare(timer_timeelapsed(chip->timer), delay_time) >= 0)
+ {
+ timer_adjust_ptr(chip->timer, duration, attotime_never);
+
+ if (LOG) logerror("74123 #%d: Retriggering pulse. Duration: %f\n", chip->which, attotime_to_double(duration));
+ }
+ else
+ {
+ if (LOG) logerror("74123 #%d: Retriggering failed.\n", chip->which);
+ }
+ }
+ else
+ {
+ /* starting */
+ timer_adjust_ptr(chip->timer, duration, attotime_never);
+
+ set_output(chip);
+
+ if (LOG) logerror("74123 #%d: Starting pulse. Duration: %f\n", chip->which, attotime_to_double(duration));
+ }
+}
+
+
+void TTL74123_A_w(int which, int data)
+{
+ TTL74123_state *chip = &chips[which];
+
+ /* start/regtrigger pulse if B=HI and falling edge on A (while clear is HI) */
+ if (!data && chip->A && chip->B && chip->clear)
+ start_pulse(chip);
+
+ chip->A = data;
+}
+
+
+void TTL74123_B_w(int which, int data)
+{
+ TTL74123_state *chip = &chips[which];
+
+ /* start/regtrigger pulse if A=LO and rising edge on B (while clear is HI) */
+ if (data && !chip->B && !chip->A && chip->clear)
+ start_pulse(chip);
+
+ chip->B = data;
+}
+
+
+void TTL74123_clear_w(int which, int data)
+{
+ TTL74123_state *chip = &chips[which];
+
+ /* clear the output if A=LO, B=HI and falling edge on clear */
+ if (!data && chip->clear && chip->B && !chip->A && !chip->clear)
+ {
+ timer_adjust_ptr(chip->timer, attotime_zero, attotime_never);
+
+ if (LOG) logerror("74123 #%d: Cleared\n", which);
+ }
+
+ chip->clear = data;
+}