aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Peach <mrpeach@users.sourceforge.net>2007-03-20 16:06:17 +0000
committerMartin Peach <mrpeach@users.sourceforge.net>2007-03-20 16:06:17 +0000
commit8a36990c0305ea2effba5e869351b902ecb429b0 (patch)
tree01aa72be2cddadbe1f26db56ce17c84f3bf99127
parentaf3619555f5c60450da97c74ec3c1f9c14f3133d (diff)
CMOS digital logic emulation objects
svn path=/trunk/externals/mrpeach/; revision=7509
-rwxr-xr-xcmos/cd4000.c102
-rwxr-xr-xcmos/cd4001.c85
-rwxr-xr-xcmos/cd4002.c119
-rwxr-xr-xcmos/cd4008.c212
-rwxr-xr-xcmos/cd4011.c85
-rwxr-xr-xcmos/cd4012.c119
-rwxr-xr-xcmos/cd4013.c183
-rwxr-xr-xcmos/cd4014.c251
-rwxr-xr-xcmos/cd4015.c126
-rwxr-xr-xcmos/cd4017.c152
-rwxr-xr-xcmos/cd40193.c250
-rwxr-xr-xcmos/cd4023.c102
-rwxr-xr-xcmos/cd4024.c125
-rwxr-xr-xcmos/cd4025.c102
-rwxr-xr-xcmos/cd4027.c210
-rwxr-xr-xcmos/cd4070.c85
-rwxr-xr-xcmos/cd4071.c85
-rwxr-xr-xcmos/cd4072.c119
-rwxr-xr-xcmos/cd4073.c102
-rwxr-xr-xcmos/cd4075.c102
-rwxr-xr-xcmos/cd4076.c256
-rwxr-xr-xcmos/cd4081.c85
-rwxr-xr-xcmos/cd4082.c119
-rwxr-xr-xcmos/cd4094.c186
-rwxr-xr-xcmos/cd4516.c256
25 files changed, 3618 insertions, 0 deletions
diff --git a/cmos/cd4000.c b/cmos/cd4000.c
new file mode 100755
index 0000000..a2a4e45
--- /dev/null
+++ b/cmos/cd4000.c
@@ -0,0 +1,102 @@
+/* cd4000.c MP 20070312 */
+/* Emulate a cd4000b */
+#include "m_pd.h"
+
+typedef struct _cd4000
+{
+ t_object x_obj;
+ t_int x_in1;
+ t_int x_in2;
+ t_int x_in3;
+ t_outlet *x_out;
+ t_inlet *x_inlet2;/* Second inlet is 'live' like the first */
+ t_inlet *x_inlet3;/* Third inlet is 'live' like the first */
+} t_cd4000;
+
+static t_class *cd4000_class;
+
+void cd4000_setup(void);
+static void *cd4000_new(t_symbol *s, int argc, t_atom *argv);
+static void cd4000_free(t_cd4000 *x);
+static void cd4000_bang(t_cd4000 *x);
+static void cd4000_float(t_cd4000 *x, t_float f);
+static void cd4000_inlet2(t_cd4000 *x, t_float f);
+static void cd4000_inlet3(t_cd4000 *x, t_float f);
+static void cd4000_update_outlets(t_cd4000 *x);
+
+static void cd4000_float(t_cd4000 *x, t_float f)
+{
+ if (f == 1) x->x_in1 = 1;
+ else if (f == 0) x->x_in1 = 0;
+ else
+ {
+ post("cd4000 inlet 2 accepts 1 or 0.");
+ return;
+ }
+ cd4000_update_outlets(x);
+}
+
+static void cd4000_bang(t_cd4000 *x)
+{
+ cd4000_update_outlets(x);
+}
+
+static void cd4000_inlet2(t_cd4000 *x, t_float f)
+{
+ if (f == 1) x->x_in2 = 1;
+ else if (f == 0) x->x_in2 = 0;
+ else
+ {
+ post("cd4000 inlet 2 accepts 1 or 0.");
+ return;
+ }
+ cd4000_update_outlets(x);
+}
+
+static void cd4000_inlet3(t_cd4000 *x, t_float f)
+{
+ if (f == 1) x->x_in3 = 1;
+ else if (f == 0) x->x_in3 = 0;
+ else
+ {
+ post("cd4000 inlet 3 accepts 1 or 0.");
+ return;
+ }
+ cd4000_update_outlets(x);
+}
+
+static void cd4000_update_outlets(t_cd4000 *x)
+{ /* Triple NOR function */
+ outlet_float(x->x_out, ((x->x_in1 + x->x_in2 + x->x_in3) != 0)?0:1);
+}
+
+static void cd4000_free(t_cd4000 *x)
+{
+ return;
+}
+
+static void *cd4000_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_cd4000 *x;
+
+ x = (t_cd4000 *)pd_new(cd4000_class);
+ if (x == NULL) return (x);
+ x->x_out = outlet_new((t_object *)x, &s_float);
+ x->x_inlet2 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("inlet2"));
+ x->x_inlet3 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("inlet3"));
+ return (x);
+}
+
+void cd4000_setup(void)
+{
+ cd4000_class = class_new(gensym("cd4000"),
+ (t_newmethod)cd4000_new,
+ (t_method)cd4000_free,
+ sizeof(t_cd4000), 0, 0); /* no arguments */
+ class_addbang(cd4000_class, cd4000_bang);
+ class_addfloat(cd4000_class, cd4000_float);
+ class_addmethod(cd4000_class, (t_method)cd4000_inlet2, gensym("inlet2"), A_FLOAT, 0);
+ class_addmethod(cd4000_class, (t_method)cd4000_inlet3, gensym("inlet3"), A_FLOAT, 0);
+}
+/* end cd4000.c */
+
diff --git a/cmos/cd4001.c b/cmos/cd4001.c
new file mode 100755
index 0000000..0fbbfb9
--- /dev/null
+++ b/cmos/cd4001.c
@@ -0,0 +1,85 @@
+/* cd4001.c MP 20070312 */
+/* Emulate a cd4001b */
+#include "m_pd.h"
+
+typedef struct _cd4001
+{
+ t_object x_obj;
+ t_int x_in1;
+ t_int x_in2;
+ t_outlet *x_out;
+ t_inlet *x_inlet2;/* Second inlet is 'live' like the first */
+} t_cd4001;
+
+static t_class *cd4001_class;
+
+void cd4001_setup(void);
+static void *cd4001_new(t_symbol *s, int argc, t_atom *argv);
+static void cd4001_free(t_cd4001 *x);
+static void cd4001_bang(t_cd4001 *x);
+static void cd4001_float(t_cd4001 *x, t_float f);
+static void cd4001_inlet2(t_cd4001 *x, t_float f);
+static void cd4001_update_outlets(t_cd4001 *x);
+
+static void cd4001_float(t_cd4001 *x, t_float f)
+{
+ if (f == 1) x->x_in1 = 1;
+ else if (f == 0) x->x_in1 = 0;
+ else
+ {
+ post("cd4001 inlet 2 accepts 1 or 0.");
+ return;
+ }
+ cd4001_update_outlets(x);
+}
+
+static void cd4001_bang(t_cd4001 *x)
+{
+ cd4001_update_outlets(x);
+}
+
+static void cd4001_inlet2(t_cd4001 *x, t_float f)
+{
+ if (f == 1) x->x_in2 = 1;
+ else if (f == 0) x->x_in2 = 0;
+ else
+ {
+ post("cd4001 inlet 2 accepts 1 or 0.");
+ return;
+ }
+ cd4001_update_outlets(x);
+}
+
+static void cd4001_update_outlets(t_cd4001 *x)
+{ /* Double NOR function */
+ outlet_float(x->x_out, ((x->x_in1 + x->x_in2) != 0)?0:1);
+}
+
+static void cd4001_free(t_cd4001 *x)
+{
+ return;
+}
+
+static void *cd4001_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_cd4001 *x;
+
+ x = (t_cd4001 *)pd_new(cd4001_class);
+ if (x == NULL) return (x);
+ x->x_out = outlet_new((t_object *)x, &s_float);
+ x->x_inlet2 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("inlet2"));
+ return (x);
+}
+
+void cd4001_setup(void)
+{
+ cd4001_class = class_new(gensym("cd4001"),
+ (t_newmethod)cd4001_new,
+ (t_method)cd4001_free,
+ sizeof(t_cd4001), 0, 0); /* no arguments */
+ class_addbang(cd4001_class, cd4001_bang);
+ class_addfloat(cd4001_class, cd4001_float);
+ class_addmethod(cd4001_class, (t_method)cd4001_inlet2, gensym("inlet2"), A_FLOAT, 0);
+}
+/* end cd4001.c */
+
diff --git a/cmos/cd4002.c b/cmos/cd4002.c
new file mode 100755
index 0000000..b55769f
--- /dev/null
+++ b/cmos/cd4002.c
@@ -0,0 +1,119 @@
+/* cd4002.c MP 20070315 */
+/* Emulate a cd4002b */
+#include "m_pd.h"
+
+typedef struct _cd4002
+{
+ t_object x_obj;
+ t_int x_in1;
+ t_int x_in2;
+ t_int x_in3;
+ t_int x_in4;
+ t_outlet *x_out;
+ t_inlet *x_inlet2;/* extra inlets are 'live' like the first */
+ t_inlet *x_inlet3;
+ t_inlet *x_inlet4;
+} t_cd4002;
+
+static t_class *cd4002_class;
+
+void cd4002_setup(void);
+static void *cd4002_new(t_symbol *s, int argc, t_atom *argv);
+static void cd4002_free(t_cd4002 *x);
+static void cd4002_bang(t_cd4002 *x);
+static void cd4002_float(t_cd4002 *x, t_float f);
+static void cd4002_inlet2(t_cd4002 *x, t_float f);
+static void cd4002_inlet3(t_cd4002 *x, t_float f);
+static void cd4002_inlet4(t_cd4002 *x, t_float f);
+static void cd4002_update_outlets(t_cd4002 *x);
+
+static void cd4002_float(t_cd4002 *x, t_float f)
+{
+ if (f == 1) x->x_in1 = 1;
+ else if (f == 0) x->x_in1 = 0;
+ else
+ {
+ post("cd4002 inlet 2 accepts 1 or 0.");
+ return;
+ }
+ cd4002_update_outlets(x);
+}
+
+static void cd4002_bang(t_cd4002 *x)
+{
+ cd4002_update_outlets(x);
+}
+
+static void cd4002_inlet2(t_cd4002 *x, t_float f)
+{
+ if (f == 1) x->x_in2 = 1;
+ else if (f == 0) x->x_in2 = 0;
+ else
+ {
+ post("cd4002 inlet 2 accepts 1 or 0.");
+ return;
+ }
+ cd4002_update_outlets(x);
+}
+
+static void cd4002_inlet3(t_cd4002 *x, t_float f)
+{
+ if (f == 1) x->x_in3 = 1;
+ else if (f == 0) x->x_in3 = 0;
+ else
+ {
+ post("cd4002 inlet 3 accepts 1 or 0.");
+ return;
+ }
+ cd4002_update_outlets(x);
+}
+
+static void cd4002_inlet4(t_cd4002 *x, t_float f)
+{
+ if (f == 1) x->x_in4 = 1;
+ else if (f == 0) x->x_in4 = 0;
+ else
+ {
+ post("cd4002 inlet 4 accepts 1 or 0.");
+ return;
+ }
+ cd4002_update_outlets(x);
+}
+
+static void cd4002_update_outlets(t_cd4002 *x)
+{ /* Quadruple NOR function */
+ outlet_float(x->x_out, ((x->x_in1 + x->x_in2 + x->x_in3 + x->x_in4) != 0)?0:1);
+}
+
+static void cd4002_free(t_cd4002 *x)
+{
+ return;
+}
+
+static void *cd4002_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_cd4002 *x;
+
+ x = (t_cd4002 *)pd_new(cd4002_class);
+ if (x == NULL) return (x);
+ x->x_out = outlet_new((t_object *)x, &s_float);
+ x->x_inlet2 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("inlet2"));
+ x->x_inlet3 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("inlet3"));
+ x->x_inlet4 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("inlet4"));
+ return (x);
+}
+
+void cd4002_setup(void)
+{
+ cd4002_class = class_new(gensym("cd4002"),
+ (t_newmethod)cd4002_new,
+ (t_method)cd4002_free,
+ sizeof(t_cd4002), 0, 0); /* no arguments */
+ class_addbang(cd4002_class, cd4002_bang);
+ class_addfloat(cd4002_class, cd4002_float);
+ class_addmethod(cd4002_class, (t_method)cd4002_inlet2, gensym("inlet2"), A_FLOAT, 0);
+ class_addmethod(cd4002_class, (t_method)cd4002_inlet3, gensym("inlet3"), A_FLOAT, 0);
+ class_addmethod(cd4002_class, (t_method)cd4002_inlet4, gensym("inlet4"), A_FLOAT, 0);
+}
+/* end cd4002.c */
+
diff --git a/cmos/cd4008.c b/cmos/cd4008.c
new file mode 100755
index 0000000..06fbe47
--- /dev/null
+++ b/cmos/cd4008.c
@@ -0,0 +1,212 @@
+/* cd4008.c MP 20070315 */
+/* Emulate a cd4008b */
+#include "m_pd.h"
+
+typedef struct _cd4008
+{
+ t_object x_obj;
+ t_int x_A1;
+ t_int x_A2;
+ t_int x_A3;
+ t_int x_A4;
+ t_int x_B1;
+ t_int x_B2;
+ t_int x_B3;
+ t_int x_B4;
+ t_int x_CarryIn;
+ t_outlet *x_outS1;
+ t_outlet *x_outS2;
+ t_outlet *x_outS3;
+ t_outlet *x_outS4;
+ t_outlet *x_outC;
+ t_inlet *x_inA1;/* extra inlets are 'live' like the first */
+ t_inlet *x_inA2;
+ t_inlet *x_inA3;
+ t_inlet *x_inA4;
+ t_inlet *x_inB1;
+ t_inlet *x_inB2;
+ t_inlet *x_inB3;
+ t_inlet *x_inB4;
+} t_cd4008;
+
+static t_class *cd4008_class;
+
+void cd4008_setup(void);
+static void *cd4008_new(t_symbol *s, int argc, t_atom *argv);
+static void cd4008_free(t_cd4008 *x);
+static void cd4008_float(t_cd4008 *x, t_float f);
+static void cd4008_inA1(t_cd4008 *x, t_float f);
+static void cd4008_inA2(t_cd4008 *x, t_float f);
+static void cd4008_inA3(t_cd4008 *x, t_float f);
+static void cd4008_inA4(t_cd4008 *x, t_float f);
+static void cd4008_inB1(t_cd4008 *x, t_float f);
+static void cd4008_inB2(t_cd4008 *x, t_float f);
+static void cd4008_inB3(t_cd4008 *x, t_float f);
+static void cd4008_inB4(t_cd4008 *x, t_float f);
+static void cd4008_update_outlets(t_cd4008 *x);
+
+static void cd4008_float(t_cd4008 *x, t_float f)
+{
+ if (f == 1) x->x_CarryIn = 1;
+ else if (f == 0) x->x_CarryIn = 0;
+ else
+ {
+ post("cd4008 Carry inlet accepts 1 or 0.");
+ return;
+ }
+ cd4008_update_outlets(x);
+}
+
+static void cd4008_inA1(t_cd4008 *x, t_float f)
+{
+ if (f == 1) x->x_A1 = 1;
+ else if (f == 0) x->x_A1 = 0;
+ else
+ {
+ post("cd4008 inlet A1 accepts 1 or 0.");
+ return;
+ }
+ cd4008_update_outlets(x);
+}
+
+static void cd4008_inA2(t_cd4008 *x, t_float f)
+{
+ if (f == 1) x->x_A2 = 1;
+ else if (f == 0) x->x_A2 = 0;
+ else
+ {
+ post("cd4008 inlet A2 accepts 1 or 0.");
+ return;
+ }
+ cd4008_update_outlets(x);
+}
+
+static void cd4008_inA3(t_cd4008 *x, t_float f)
+{
+ if (f == 1) x->x_A3 = 1;
+ else if (f == 0) x->x_A3 = 0;
+ else
+ {
+ post("cd4008 inlet A3 accepts 1 or 0.");
+ return;
+ }
+ cd4008_update_outlets(x);
+}
+
+static void cd4008_inA4(t_cd4008 *x, t_float f)
+{
+ if (f == 1) x->x_A4 = 1;
+ else if (f == 0) x->x_A4 = 0;
+ else
+ {
+ post("cd4008 inlet A4 accepts 1 or 0.");
+ return;
+ }
+ cd4008_update_outlets(x);
+}
+
+static void cd4008_inB1(t_cd4008 *x, t_float f)
+{
+ if (f == 1) x->x_B1 = 1;
+ else if (f == 0) x->x_B1 = 0;
+ else
+ {
+ post("cd4008 inlet B1 accepts 1 or 0.");
+ return;
+ }
+ cd4008_update_outlets(x);
+}
+
+static void cd4008_inB2(t_cd4008 *x, t_float f)
+{
+ if (f == 1) x->x_B2 = 1;
+ else if (f == 0) x->x_B2 = 0;
+ else
+ {
+ post("cd4008 inlet B2 accepts 1 or 0.");
+ return;
+ }
+ cd4008_update_outlets(x);
+}
+
+static void cd4008_inB3(t_cd4008 *x, t_float f)
+{
+ if (f == 1) x->x_B3 = 1;
+ else if (f == 0) x->x_B3 = 0;
+ else
+ {
+ post("cd4008 inlet B3 accepts 1 or 0.");
+ return;
+ }
+ cd4008_update_outlets(x);
+}
+
+static void cd4008_inB4(t_cd4008 *x, t_float f)
+{
+ if (f == 1) x->x_B4 = 1;
+ else if (f == 0) x->x_B4 = 0;
+ else
+ {
+ post("cd4008 inlet B4 accepts 1 or 0.");
+ return;
+ }
+ cd4008_update_outlets(x);
+}
+
+static void cd4008_update_outlets(t_cd4008 *x)
+{ /* Quadruple add function */
+ t_int sum;
+
+ sum = x->x_CarryIn + x->x_A1 + x->x_B1 + 2*(x->x_A2 + x->x_B2) + 4*(x->x_A3 + x->x_B3) + 8*(x->x_A4 + x->x_B4);
+ outlet_float(x->x_outC, ((sum & 16) != 0)?1:0);
+ outlet_float(x->x_outS4, ((sum & 8) != 0)?1:0);
+ outlet_float(x->x_outS3, ((sum & 4) != 0)?1:0);
+ outlet_float(x->x_outS2, ((sum & 2) != 0)?1:0);
+ outlet_float(x->x_outS1, ((sum & 1) != 0)?1:0);
+}
+
+static void cd4008_free(t_cd4008 *x)
+{
+ return;
+}
+
+static void *cd4008_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_cd4008 *x;
+
+ x = (t_cd4008 *)pd_new(cd4008_class);
+ if (x == NULL) return (x);
+ x->x_outS1 = outlet_new((t_object *)x, &s_float);
+ x->x_outS2 = outlet_new((t_object *)x, &s_float);
+ x->x_outS3 = outlet_new((t_object *)x, &s_float);
+ x->x_outS4 = outlet_new((t_object *)x, &s_float);
+ x->x_outC = outlet_new((t_object *)x, &s_float);
+ x->x_inA1 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("A1"));
+ x->x_inA2 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("A2"));
+ x->x_inA3 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("A3"));
+ x->x_inA4 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("A4"));
+ x->x_inB1 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("B1"));
+ x->x_inB2 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("B2"));
+ x->x_inB3 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("B3"));
+ x->x_inB4 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("B4"));
+ return (x);
+}
+
+void cd4008_setup(void)
+{
+ cd4008_class = class_new(gensym("cd4008"),
+ (t_newmethod)cd4008_new,
+ (t_method)cd4008_free,
+ sizeof(t_cd4008), 0, 0); /* no arguments */
+ class_addfloat(cd4008_class, cd4008_float);
+ class_addmethod(cd4008_class, (t_method)cd4008_inA1, gensym("A1"), A_FLOAT, 0);
+ class_addmethod(cd4008_class, (t_method)cd4008_inA2, gensym("A2"), A_FLOAT, 0);
+ class_addmethod(cd4008_class, (t_method)cd4008_inA3, gensym("A3"), A_FLOAT, 0);
+ class_addmethod(cd4008_class, (t_method)cd4008_inA4, gensym("A4"), A_FLOAT, 0);
+ class_addmethod(cd4008_class, (t_method)cd4008_inB1, gensym("B1"), A_FLOAT, 0);
+ class_addmethod(cd4008_class, (t_method)cd4008_inB2, gensym("B2"), A_FLOAT, 0);
+ class_addmethod(cd4008_class, (t_method)cd4008_inB3, gensym("B3"), A_FLOAT, 0);
+ class_addmethod(cd4008_class, (t_method)cd4008_inB4, gensym("B4"), A_FLOAT, 0);
+}
+/* end cd4008.c */
+
diff --git a/cmos/cd4011.c b/cmos/cd4011.c
new file mode 100755
index 0000000..e04ee14
--- /dev/null
+++ b/cmos/cd4011.c
@@ -0,0 +1,85 @@
+/* cd4011.c MP 20070315 */
+/* Emulate a cd4011b */
+#include "m_pd.h"
+
+typedef struct _cd4011
+{
+ t_object x_obj;
+ t_int x_in1;
+ t_int x_in2;
+ t_outlet *x_out;
+ t_inlet *x_inlet2;/* Second inlet is 'live' like the first */
+} t_cd4011;
+
+static t_class *cd4011_class;
+
+void cd4011_setup(void);
+static void *cd4011_new(t_symbol *s, int argc, t_atom *argv);
+static void cd4011_free(t_cd4011 *x);
+static void cd4011_bang(t_cd4011 *x);
+static void cd4011_float(t_cd4011 *x, t_float f);
+static void cd4011_inlet2(t_cd4011 *x, t_float f);
+static void cd4011_update_outlets(t_cd4011 *x);
+
+static void cd4011_float(t_cd4011 *x, t_float f)
+{
+ if (f == 1) x->x_in1 = 1;
+ else if (f == 0) x->x_in1 = 0;
+ else
+ {
+ post("cd4011 inlet 2 accepts 1 or 0.");
+ return;
+ }
+ cd4011_update_outlets(x);
+}
+
+static void cd4011_bang(t_cd4011 *x)
+{
+ cd4011_update_outlets(x);
+}
+
+static void cd4011_inlet2(t_cd4011 *x, t_float f)
+{
+ if (f == 1) x->x_in2 = 1;
+ else if (f == 0) x->x_in2 = 0;
+ else
+ {
+ post("cd4011 inlet 2 accepts 1 or 0.");
+ return;
+ }
+ cd4011_update_outlets(x);
+}
+
+static void cd4011_update_outlets(t_cd4011 *x)
+{ /* Double NAND function */
+ outlet_float(x->x_out, ((x->x_in1 + x->x_in2) == 2)?0:1);
+}
+
+static void cd4011_free(t_cd4011 *x)
+{
+ return;
+}
+
+static void *cd4011_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_cd4011 *x;
+
+ x = (t_cd4011 *)pd_new(cd4011_class);
+ if (x == NULL) return (x);
+ x->x_out = outlet_new((t_object *)x, &s_float);
+ x->x_inlet2 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("inlet2"));
+ return (x);
+}
+
+void cd4011_setup(void)
+{
+ cd4011_class = class_new(gensym("cd4011"),
+ (t_newmethod)cd4011_new,
+ (t_method)cd4011_free,
+ sizeof(t_cd4011), 0, 0); /* no arguments */
+ class_addbang(cd4011_class, cd4011_bang);
+ class_addfloat(cd4011_class, cd4011_float);
+ class_addmethod(cd4011_class, (t_method)cd4011_inlet2, gensym("inlet2"), A_FLOAT, 0);
+}
+/* end cd4011.c */
+
diff --git a/cmos/cd4012.c b/cmos/cd4012.c
new file mode 100755
index 0000000..752d8c1
--- /dev/null
+++ b/cmos/cd4012.c
@@ -0,0 +1,119 @@
+/* cd4012.c MP 20070315 */
+/* Emulate a cd4012b */
+#include "m_pd.h"
+
+typedef struct _cd4012
+{
+ t_object x_obj;
+ t_int x_in1;
+ t_int x_in2;
+ t_int x_in3;
+ t_int x_in4;
+ t_outlet *x_out;
+ t_inlet *x_inlet2;/* extra inlets are 'live' like the first */
+ t_inlet *x_inlet3;
+ t_inlet *x_inlet4;
+} t_cd4012;
+
+static t_class *cd4012_class;
+
+void cd4012_setup(void);
+static void *cd4012_new(t_symbol *s, int argc, t_atom *argv);
+static void cd4012_free(t_cd4012 *x);
+static void cd4012_bang(t_cd4012 *x);
+static void cd4012_float(t_cd4012 *x, t_float f);
+static void cd4012_inlet2(t_cd4012 *x, t_float f);
+static void cd4012_inlet3(t_cd4012 *x, t_float f);
+static void cd4012_inlet4(t_cd4012 *x, t_float f);
+static void cd4012_update_outlets(t_cd4012 *x);
+
+static void cd4012_float(t_cd4012 *x, t_float f)
+{
+ if (f == 1) x->x_in1 = 1;
+ else if (f == 0) x->x_in1 = 0;
+ else
+ {
+ post("cd4012 inlet 2 accepts 1 or 0.");
+ return;
+ }
+ cd4012_update_outlets(x);
+}
+
+static void cd4012_bang(t_cd4012 *x)
+{
+ cd4012_update_outlets(x);
+}
+
+static void cd4012_inlet2(t_cd4012 *x, t_float f)
+{
+ if (f == 1) x->x_in2 = 1;
+ else if (f == 0) x->x_in2 = 0;
+ else
+ {
+ post("cd4012 inlet 2 accepts 1 or 0.");
+ return;
+ }
+ cd4012_update_outlets(x);
+}
+
+static void cd4012_inlet3(t_cd4012 *x, t_float f)
+{
+ if (f == 1) x->x_in3 = 1;
+ else if (f == 0) x->x_in3 = 0;
+ else
+ {
+ post("cd4012 inlet 3 accepts 1 or 0.");
+ return;
+ }
+ cd4012_update_outlets(x);
+}
+
+static void cd4012_inlet4(t_cd4012 *x, t_float f)
+{
+ if (f == 1) x->x_in4 = 1;
+ else if (f == 0) x->x_in4 = 0;
+ else
+ {
+ post("cd4012 inlet 4 accepts 1 or 0.");
+ return;
+ }
+ cd4012_update_outlets(x);
+}
+
+static void cd4012_update_outlets(t_cd4012 *x)
+{ /* Quadruple NAND function */
+ outlet_float(x->x_out, ((x->x_in1 + x->x_in2 + x->x_in3 + x->x_in4) == 4)?0:1);
+}
+
+static void cd4012_free(t_cd4012 *x)
+{
+ return;
+}
+
+static void *cd4012_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_cd4012 *x;
+
+ x = (t_cd4012 *)pd_new(cd4012_class);
+ if (x == NULL) return (x);
+ x->x_out = outlet_new((t_object *)x, &s_float);
+ x->x_inlet2 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("inlet2"));
+ x->x_inlet3 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("inlet3"));
+ x->x_inlet4 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("inlet4"));
+ return (x);
+}
+
+void cd4012_setup(void)
+{
+ cd4012_class = class_new(gensym("cd4012"),
+ (t_newmethod)cd4012_new,
+ (t_method)cd4012_free,
+ sizeof(t_cd4012), 0, 0); /* no arguments */
+ class_addbang(cd4012_class, cd4012_bang);
+ class_addfloat(cd4012_class, cd4012_float);
+ class_addmethod(cd4012_class, (t_method)cd4012_inlet2, gensym("inlet2"), A_FLOAT, 0);
+ class_addmethod(cd4012_class, (t_method)cd4012_inlet3, gensym("inlet3"), A_FLOAT, 0);
+ class_addmethod(cd4012_class, (t_method)cd4012_inlet4, gensym("inlet4"), A_FLOAT, 0);
+}
+/* end cd4012.c */
+
diff --git a/cmos/cd4013.c b/cmos/cd4013.c
new file mode 100755
index 0000000..c92f635
--- /dev/null
+++ b/cmos/cd4013.c
@@ -0,0 +1,183 @@
+/* cd4013.c MP 20070306 */
+/* Emulate a cd4013b */
+#include "m_pd.h"
+
+typedef struct _cd4013
+{
+ t_object x_obj;
+ t_int x_state;/* set = bit0, clock = bit1, reset = bit2 j = bit3 k = bit4 q = bit 5 */
+ t_outlet *x_Q;
+ t_outlet *x_notQ;
+ t_inlet *x_set;/* set takes one or zero as acceptable inputs. */
+ t_inlet *x_reset;/* reset takes one or zero as acceptable inputs. */
+ t_inlet *x_d;/* d takes one or zero as acceptable inputs. */
+ /* The main inlet (clock) should accept a bang or a one as valid clocks. */
+ /* If a one is received, it must be followed by a zero before the clock will work again. */
+} t_cd4013;
+
+#define SET_4013 1
+#define CLOCK_4013 2
+#define RESET_4013 4
+#define D_4013 8
+#define Q_4013 16
+#define UPDATING_4013 32
+#define CHANGED_4013 64
+
+static t_class *cd4013_class;
+
+void cd4013_setup(void);
+static void *cd4013_new(t_symbol *s, int argc, t_atom *argv);
+static void cd4013_free(t_cd4013 *x);
+static void cd4013_bang(t_cd4013 *x);
+static void cd4013_float(t_cd4013 *x, t_float f);
+static void cd4013_set(t_cd4013 *x, t_float f);
+static void cd4013_reset(t_cd4013 *x, t_float f);
+static void cd4013_d(t_cd4013 *x, t_float f);
+static void cd4013_update_outlets(t_cd4013 *x);
+static void cd4013_printstate (t_cd4013 *x);
+
+static void cd4013_float(t_cd4013 *x, t_float f)
+{
+ if (f == 1)
+ { /* if clock is high and was low, clock it. */
+ if ((x->x_state & CLOCK_4013) == 0) cd4013_bang(x);
+ x->x_state |= CLOCK_4013;
+ }
+ else if (f == 0) x->x_state &= ~CLOCK_4013;
+ else post("cd4013 accepts bang, 1 or 0.");
+}
+
+static void cd4013_printstate (t_cd4013 *x)
+{
+ post ("SET %d RESET %d D %d Q %d", ((x->x_state & SET_4013) != 0)?1:0
+ , ((x->x_state & RESET_4013) != 0)?1:0
+ , ((x->x_state & D_4013) != 0)?1:0
+ , ((x->x_state & Q_4013) != 0)?1:0);
+}
+
+static void cd4013_bang(t_cd4013 *x)
+{
+ if ((x->x_state & (SET_4013 | RESET_4013)) == 0)
+ { /* if set is low and reset is low, clock forward */
+ if ((x->x_state & D_4013) != 0) x->x_state |= Q_4013;
+ else x->x_state &= ~Q_4013;
+ cd4013_update_outlets(x);
+ }
+}
+
+static void cd4013_set(t_cd4013 *x, t_float f)
+{
+ if (f == 1)
+ {
+ x->x_state |= SET_4013; /* set = 1 */
+ }
+ else if (f == 0)
+ {
+ x->x_state &= ~SET_4013; /* set = 0 */
+ }
+ else
+ {
+ post("cd4013 set takes 1 or 0 only.");
+ return;
+ }
+ /* update outlets if not already doing that */
+ if ((x->x_state & UPDATING_4013) == 0)
+ {
+ cd4013_update_outlets(x);
+ }
+ else
+ {
+ x->x_state |= CHANGED_4013;
+ }
+ return;
+}
+
+static void cd4013_reset(t_cd4013 *x, t_float f)
+{
+ if (f == 1)
+ {
+ x->x_state |= RESET_4013; /* reset = 1 */
+ }
+ else if (f == 0)
+ {
+ x->x_state &= ~RESET_4013; /* reset = 0 */
+ }
+ else
+ {
+ return;
+ }
+ /* update outlets if not already doing that */
+ if ((x->x_state & UPDATING_4013) == 0)
+ {
+ cd4013_update_outlets(x);
+ }
+ else
+ {
+ x->x_state |= CHANGED_4013;
+ }
+ return;
+}
+
+static void cd4013_d(t_cd4013 *x, t_float f)
+{
+ if (f == 1)
+ {
+ x->x_state |= D_4013; /* d = 1 */
+ }
+ else if (f == 0)
+ {
+ x->x_state &= ~D_4013; /* d = 0 */
+ }
+ else post("cd4013 d takes 1 or 0 only.");
+ return;
+}
+
+static void cd4013_update_outlets(t_cd4013 *x)
+{
+ /* cd4013_printstate (x); */
+ x->x_state |= UPDATING_4013;/* updating outlets */
+reset:
+ if ((x->x_state & SET_4013) != 0) x->x_state |= Q_4013;
+ else if ((x->x_state & RESET_4013) != 0) x->x_state &= ~Q_4013;
+ x->x_state &= ~CHANGED_4013; /* prepare to flag any changes that occur during outlet_update */
+ outlet_float(x->x_notQ, ((x->x_state & Q_4013) == 0)?1:0);
+/* we might get set or reset as a result of feedback from one of these outlets. */
+ if ((x->x_state & CHANGED_4013) != 0) goto reset;
+ outlet_float(x->x_Q, ((x->x_state & Q_4013) != 0)?1:0);
+ if ((x->x_state & CHANGED_4013) != 0) goto reset;
+ x->x_state &= ~UPDATING_4013;/* finished updating outlets */
+}
+
+static void cd4013_free(t_cd4013 *x)
+{
+ return;
+}
+
+static void *cd4013_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_cd4013 *x;
+
+ x = (t_cd4013 *)pd_new(cd4013_class);
+ if (x == NULL) return (x);
+ x->x_Q = outlet_new((t_object *)x, &s_float);
+ x->x_notQ = outlet_new((t_object *)x, &s_float);
+ x->x_set = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("set"));
+ x->x_reset = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("reset"));
+ x->x_d = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("d"));
+ return (x);
+}
+
+void cd4013_setup(void)
+{
+ cd4013_class = class_new(gensym("cd4013"),
+ (t_newmethod)cd4013_new,
+ (t_method)cd4013_free,
+ sizeof(t_cd4013), 0, 0); /* no arguments */
+ class_addbang(cd4013_class, cd4013_bang);
+ class_addfloat(cd4013_class, cd4013_float);
+ class_addmethod(cd4013_class, (t_method)cd4013_reset, gensym("reset"), A_FLOAT, 0);
+ class_addmethod(cd4013_class, (t_method)cd4013_set, gensym("set"), A_FLOAT, 0);
+ class_addmethod(cd4013_class, (t_method)cd4013_d, gensym("d"), A_FLOAT, 0);
+}
+/* end cd4013.c */
+
diff --git a/cmos/cd4014.c b/cmos/cd4014.c
new file mode 100755
index 0000000..7485f5f
--- /dev/null
+++ b/cmos/cd4014.c
@@ -0,0 +1,251 @@
+/* cd4014.c MP 20070315 */
+/* Emulate a cd4014b */
+#include "m_pd.h"
+
+typedef struct _cd4014
+{
+ t_object x_obj;
+ t_int x_P1;
+ t_int x_P2;
+ t_int x_P3;
+ t_int x_P4;
+ t_int x_P5;
+ t_int x_P6;
+ t_int x_P7;
+ t_int x_P8;
+ t_int x_SerialIn;
+ t_int x_Clk;
+ t_int x_Q;
+ t_int x_ParallelSerial;
+ t_outlet *x_outQ6;
+ t_outlet *x_outQ7;
+ t_outlet *x_outQ8;
+ t_inlet *x_inP1;/* extra inlets are 'live' like the first */
+ t_inlet *x_inP2;
+ t_inlet *x_inP3;
+ t_inlet *x_inP4;
+ t_inlet *x_inP5;
+ t_inlet *x_inP6;
+ t_inlet *x_inP7;
+ t_inlet *x_inP8;
+ t_inlet *x_inParallelSerial;
+ t_inlet *x_inSerial;
+} t_cd4014;
+
+static t_class *cd4014_class;
+
+void cd4014_setup(void);
+static void *cd4014_new(t_symbol *s, int argc, t_atom *argv);
+static void cd4014_free(t_cd4014 *x);
+static void cd4014_float(t_cd4014 *x, t_float f);
+static void cd4014_bang(t_cd4014 *x);
+static void cd4014_inP1(t_cd4014 *x, t_float f);
+static void cd4014_inP2(t_cd4014 *x, t_float f);
+static void cd4014_inP3(t_cd4014 *x, t_float f);
+static void cd4014_inP4(t_cd4014 *x, t_float f);
+static void cd4014_inP5(t_cd4014 *x, t_float f);
+static void cd4014_inP6(t_cd4014 *x, t_float f);
+static void cd4014_inP7(t_cd4014 *x, t_float f);
+static void cd4014_inP8(t_cd4014 *x, t_float f);
+static void cd4014_inParallelSerial(t_cd4014 *x, t_float f);
+static void cd4014_inSerial(t_cd4014 *x, t_float f);
+static void cd4014_update_outlets(t_cd4014 *x);
+
+static void cd4014_float(t_cd4014 *x, t_float f)
+{
+ if (f == 1)
+ {
+ if (x->x_Clk == 0)
+ {
+ x->x_Clk = 1;
+ cd4014_bang(x);
+ }
+ }
+ else if (f == 0) x->x_Clk = 0;
+ else
+ {
+ post("cd4014 Clock inlet accepts 1 or 0.");
+ return;
+ }
+}
+
+static void cd4014_bang(t_cd4014 *x)
+{
+ if (x->x_ParallelSerial == 0)
+ { /* shift left by one */
+ x->x_Q <<= 1;
+ x->x_Q |= x->x_SerialIn;
+ }
+ else
+ { /* parallel load */
+ x->x_Q = 128*x->x_P8 + 64*x->x_P7 + 32*x->x_P6 + 16*x->x_P5 + 8*x->x_P4 + 4*x->x_P3 + 2*x->x_P2 + x->x_P1;
+ }
+ cd4014_update_outlets(x);
+}
+
+static void cd4014_inP1(t_cd4014 *x, t_float f)
+{
+ if (f == 1) x->x_P1 = 1;
+ else if (f == 0) x->x_P1 = 0;
+ else
+ {
+ post("cd4014 inlet P1 accepts 1 or 0.");
+ return;
+ }
+}
+
+static void cd4014_inP2(t_cd4014 *x, t_float f)
+{
+ if (f == 1) x->x_P2 = 2;
+ else if (f == 0) x->x_P2 = 0;
+ else
+ {
+ post("cd4014 inlet P2 accepts 1 or 0.");
+ return;
+ }
+}
+
+static void cd4014_inP3(t_cd4014 *x, t_float f)
+{
+ if (f == 1) x->x_P3 = 1;
+ else if (f == 0) x->x_P3 = 0;
+ else
+ {
+ post("cd4014 inlet P3 accepts 1 or 0.");
+ return;
+ }
+}
+
+static void cd4014_inP4(t_cd4014 *x, t_float f)
+{
+ if (f == 1) x->x_P4 = 1;
+ else if (f == 0) x->x_P4 = 0;
+ else
+ {
+ post("cd4014 inlet P4 accepts 1 or 0.");
+ return;
+ }
+}
+
+static void cd4014_inP5(t_cd4014 *x, t_float f)
+{
+ if (f == 1) x->x_P5 = 1;
+ else if (f == 0) x->x_P5 = 0;
+ else
+ {
+ post("cd4014 inlet P5 accepts 1 or 0.");
+ return;
+ }
+}
+
+static void cd4014_inP6(t_cd4014 *x, t_float f)
+{
+ if (f == 1) x->x_P6 = 1;
+ else if (f == 0) x->x_P6 = 0;
+ else
+ {
+ post("cd4014 inlet P6 accepts 1 or 0.");
+ return;
+ }
+}
+
+static void cd4014_inP7(t_cd4014 *x, t_float f)
+{
+ if (f == 1) x->x_P7 = 1;
+ else if (f == 0) x->x_P7 = 0;
+ else
+ {
+ post("cd4014 inlet P7 accepts 1 or 0.");
+ return;
+ }
+}
+
+static void cd4014_inP8(t_cd4014 *x, t_float f)
+{
+ if (f == 1) x->x_P8 = 1;
+ else if (f == 0) x->x_P8 = 0;
+ else
+ {
+ post("cd4014 inlet P8 accepts 1 or 0.");
+ return;
+ }
+}
+
+static void cd4014_inParallelSerial(t_cd4014 *x, t_float f)
+{
+ if (f == 1) x->x_ParallelSerial = 1;
+ else if (f == 0) x->x_ParallelSerial = 0;
+ else
+ {
+ post("cd4014 inlet ParallelSerial accepts 1 or 0.");
+ return;
+ }
+}
+
+static void cd4014_inSerial(t_cd4014 *x, t_float f)
+{
+ if (f == 1) x->x_SerialIn = 1;
+ else if (f == 0) x->x_SerialIn = 0;
+ else
+ {
+ post("cd4014 inlet Serial accepts 1 or 0.");
+ return;
+ }
+}
+
+static void cd4014_update_outlets(t_cd4014 *x)
+{ /* Output Q8, Q7, Q6 */
+
+ outlet_float(x->x_outQ8, ((x->x_Q & 128) != 0)?1:0);
+ outlet_float(x->x_outQ7, ((x->x_Q & 64) != 0)?1:0);
+ outlet_float(x->x_outQ6, ((x->x_Q & 32) != 0)?1:0);
+}
+
+static void cd4014_free(t_cd4014 *x)
+{
+ return;
+}
+
+static void *cd4014_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_cd4014 *x;
+
+ x = (t_cd4014 *)pd_new(cd4014_class);
+ if (x == NULL) return (x);
+ x->x_outQ6 = outlet_new((t_object *)x, &s_float);
+ x->x_outQ7 = outlet_new((t_object *)x, &s_float);
+ x->x_outQ8 = outlet_new((t_object *)x, &s_float);
+ x->x_inP1 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("P1"));
+ x->x_inP2 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("P2"));
+ x->x_inP3 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("P3"));
+ x->x_inP4 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("P4"));
+ x->x_inP5 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("P5"));
+ x->x_inP6 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("P6"));
+ x->x_inP7 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("P7"));
+ x->x_inP8 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("P8"));
+ x->x_inParallelSerial = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ParallelSerial"));
+ x->x_inSerial = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("Serial"));
+ return (x);
+}
+
+void cd4014_setup(void)
+{
+ cd4014_class = class_new(gensym("cd4014"),
+ (t_newmethod)cd4014_new,
+ (t_method)cd4014_free,
+ sizeof(t_cd4014), 0, 0); /* no arguments */
+ class_addfloat(cd4014_class, cd4014_float);
+ class_addbang(cd4014_class, cd4014_bang);
+ class_addmethod(cd4014_class, (t_method)cd4014_inP1, gensym("P1"), A_FLOAT, 0);
+ class_addmethod(cd4014_class, (t_method)cd4014_inP2, gensym("P2"), A_FLOAT, 0);
+ class_addmethod(cd4014_class, (t_method)cd4014_inP3, gensym("P3"), A_FLOAT, 0);
+ class_addmethod(cd4014_class, (t_method)cd4014_inP4, gensym("P4"), A_FLOAT, 0);
+ class_addmethod(cd4014_class, (t_method)cd4014_inP5, gensym("P5"), A_FLOAT, 0);
+ class_addmethod(cd4014_class, (t_method)cd4014_inP6, gensym("P6"), A_FLOAT, 0);
+ class_addmethod(cd4014_class, (t_method)cd4014_inP7, gensym("P7"), A_FLOAT, 0);
+ class_addmethod(cd4014_class, (t_method)cd4014_inP8, gensym("P8"), A_FLOAT, 0);
+ class_addmethod(cd4014_class, (t_method)cd4014_inParallelSerial, gensym("ParallelSerial"), A_FLOAT, 0);
+ class_addmethod(cd4014_class, (t_method)cd4014_inSerial, gensym("Serial"), A_FLOAT, 0);
+}
+/* end cd4014.c */
+
diff --git a/cmos/cd4015.c b/cmos/cd4015.c
new file mode 100755
index 0000000..d2f0d68
--- /dev/null
+++ b/cmos/cd4015.c
@@ -0,0 +1,126 @@
+/* cd4015.c MP 20070315 */
+/* Emulate a cd4015b */
+#include "m_pd.h"
+
+typedef struct _cd4015
+{
+ t_object x_obj;
+ t_int x_D;
+ t_int x_R;
+ t_int x_Clk;
+ t_int x_Q;
+ t_outlet *x_outQ1;
+ t_outlet *x_outQ2;
+ t_outlet *x_outQ3;
+ t_outlet *x_outQ4;
+ t_inlet *x_inD;/* extra inlets are 'live' like the first */
+ t_inlet *x_inR;
+} t_cd4015;
+
+static t_class *cd4015_class;
+
+void cd4015_setup(void);
+static void *cd4015_new(t_symbol *s, int argc, t_atom *argv);
+static void cd4015_free(t_cd4015 *x);
+static void cd4015_float(t_cd4015 *x, t_float f);
+static void cd4015_bang(t_cd4015 *x);
+static void cd4015_inD(t_cd4015 *x, t_float f);
+static void cd4015_inR(t_cd4015 *x, t_float f);
+static void cd4015_update_outlets(t_cd4015 *x);
+
+static void cd4015_float(t_cd4015 *x, t_float f)
+{
+ if (f == 1)
+ {
+ if (x->x_Clk == 0)
+ {
+ x->x_Clk = 1;
+ cd4015_bang(x);
+ }
+ }
+ else if (f == 0) x->x_Clk = 0;
+ else
+ {
+ post("cd4015 Clock inlet accepts 1 or 0.");
+ return;
+ }
+}
+
+static void cd4015_bang(t_cd4015 *x)
+{
+ if (x->x_R == 0)
+ { /* shift left by one */
+ x->x_Q <<= 1;
+ x->x_Q |= x->x_D;
+ cd4015_update_outlets(x);
+ }
+}
+
+static void cd4015_inD(t_cd4015 *x, t_float f)
+{
+ if (f == 1) x->x_D = 1;
+ else if (f == 0) x->x_D = 0;
+ else
+ {
+ post("cd4015 D inlet accepts 1 or 0.");
+ return;
+ }
+}
+
+static void cd4015_inR(t_cd4015 *x, t_float f)
+{
+ if (f == 1)
+ {
+ x->x_R = 1;
+ x->x_Q = 0;
+ cd4015_update_outlets(x);
+ }
+ else if (f == 0) x->x_R = 0;
+ else
+ {
+ post("cd4015 R inlet accepts 1 or 0.");
+ return;
+ }
+}
+
+static void cd4015_update_outlets(t_cd4015 *x)
+{
+ outlet_float(x->x_outQ4, ((x->x_Q & 8) != 0)?1:0);
+ outlet_float(x->x_outQ3, ((x->x_Q & 4) != 0)?1:0);
+ outlet_float(x->x_outQ2, ((x->x_Q & 2) != 0)?1:0);
+ outlet_float(x->x_outQ1, ((x->x_Q & 1) != 0)?1:0);
+}
+
+static void cd4015_free(t_cd4015 *x)
+{
+ return;
+}
+
+static void *cd4015_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_cd4015 *x;
+
+ x = (t_cd4015 *)pd_new(cd4015_class);
+ if (x == NULL) return (x);
+ x->x_outQ1 = outlet_new((t_object *)x, &s_float);
+ x->x_outQ2 = outlet_new((t_object *)x, &s_float);
+ x->x_outQ3 = outlet_new((t_object *)x, &s_float);
+ x->x_outQ4 = outlet_new((t_object *)x, &s_float);
+ x->x_inD = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("D"));
+ x->x_inR = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("R"));
+ return (x);
+}
+
+void cd4015_setup(void)
+{
+ cd4015_class = class_new(gensym("cd4015"),
+ (t_newmethod)cd4015_new,
+ (t_method)cd4015_free,
+ sizeof(t_cd4015), 0, 0); /* no arguments */
+ class_addfloat(cd4015_class, cd4015_float);
+ class_addbang(cd4015_class, cd4015_bang);
+ class_addmethod(cd4015_class, (t_method)cd4015_inD, gensym("D"), A_FLOAT, 0);
+ class_addmethod(cd4015_class, (t_method)cd4015_inR, gensym("R"), A_FLOAT, 0);
+}
+/* end cd4015.c */
+
diff --git a/cmos/cd4017.c b/cmos/cd4017.c
new file mode 100755
index 0000000..d5bcc97
--- /dev/null
+++ b/cmos/cd4017.c
@@ -0,0 +1,152 @@
+/* cd4017.c MP 20070305 */
+/* Emulate a cd4017b */
+#include "m_pd.h"
+
+typedef struct _cd4017
+{
+ t_object x_obj;
+ t_int x_state;/* clock_inhibit value in bit 0, clock level in bit 1, reset level in bit 2 */
+ t_int x_count;
+ t_outlet *x_0;
+ t_outlet *x_1;
+ t_outlet *x_2;
+ t_outlet *x_3;
+ t_outlet *x_4;
+ t_outlet *x_5;
+ t_outlet *x_6;
+ t_outlet *x_7;
+ t_outlet *x_8;
+ t_outlet *x_9;
+ t_outlet *x_carry_out;/* Outputs 1 when any of outlets 0-3 is one */
+ t_inlet *x_clock_inhibit;/* clock_inhibit takes one or zero as acceptable inputs. 1 inhibits the clock. */
+ t_inlet *x_reset;/* reset */
+ /* The main inlet (clcok) should accept a bang or a one as valid clocks. */
+ /* If a one is received, it must be followed by a zero before the clock will work again. */
+} t_cd4017;
+
+static t_class *cd4017_class;
+
+void cd4017_setup(void);
+static void *cd4017_new(t_symbol *s, int argc, t_atom *argv);
+static void cd4017_free(t_cd4017 *x);
+static void cd4017_bang(t_cd4017 *x);
+static void cd4017_float(t_cd4017 *x, t_float f);
+static void cd4017_clock_inhibit(t_cd4017 *x, t_float f);
+static void cd4017_reset(t_cd4017 *x, t_float f);
+static void cd4017_update_outlets(t_cd4017 *x);
+
+static void cd4017_float(t_cd4017 *x, t_float f)
+{
+ if (f == 1)
+ { /* if clock is high and was low, clock it. */
+ if ((x->x_state & 2) == 0) cd4017_bang(x);
+ x->x_state |= 2;
+ }
+ else if (f == 0) x->x_state &= ~2;
+ else post("cd4017 accepts bang, 1 or 0.");
+}
+
+static void cd4017_bang(t_cd4017 *x)
+{
+ if ((x->x_state & 5) == 0)
+ { /* if clock inhibit is low and reset is low, clock forward */
+ x->x_count = ((x->x_count + 1)%10);
+ cd4017_update_outlets(x);
+ }
+}
+
+static void cd4017_clock_inhibit(t_cd4017 *x, t_float f)
+{
+ if (f == 1) x->x_state |= 1; /* clock inhibited */
+ else if (f == 0) x->x_state &= ~1; /* clock uninhibited */
+ else post("cd4017 clock inhibit takes 1 or 0 only.");
+ return;
+}
+
+static void cd4017_reset(t_cd4017 *x, t_float f)
+{
+ if (f == 1)
+ {
+ x->x_count = 0;
+ x->x_state |= 4; /* reset */
+ if ((x->x_state & 8) == 0) /* don't reenter any update_oulets in progress */
+ {
+ cd4017_update_outlets(x);
+ }
+ else x->x_state |= 16; /* reset during outlet_update */
+ }
+ else if (f == 0) x->x_state &= ~4; /* no reset */
+}
+
+static void cd4017_update_outlets(t_cd4017 *x)
+{
+ x->x_state |= 8;/* updating outlets */
+reset:
+ x->x_state &= ~16; /* clear reset during outlet_update */
+ outlet_float(x->x_0, (x->x_count == 0)?1:0);
+/* we might get reset as a result of feedback from one of these outlets. */
+ if ((x->x_state & 16) != 0) goto reset;
+ outlet_float(x->x_1, (x->x_count == 1)?1:0);
+ if ((x->x_state & 16) != 0) goto reset;
+ outlet_float(x->x_2, (x->x_count == 2)?1:0);
+ if ((x->x_state & 16) != 0) goto reset;
+ outlet_float(x->x_3, (x->x_count == 3)?1:0);
+ if ((x->x_state & 16) != 0) goto reset;
+ outlet_float(x->x_4, (x->x_count == 4)?1:0);
+ if ((x->x_state & 16) != 0) goto reset;
+ outlet_float(x->x_5, (x->x_count == 5)?1:0);
+ if ((x->x_state & 16) != 0) goto reset;
+ outlet_float(x->x_6, (x->x_count == 6)?1:0);
+ if ((x->x_state & 16) != 0) goto reset;
+ outlet_float(x->x_7, (x->x_count == 7)?1:0);
+ if ((x->x_state & 16) != 0) goto reset;
+ outlet_float(x->x_8, (x->x_count == 8)?1:0);
+ if ((x->x_state & 16) != 0) goto reset;
+ outlet_float(x->x_9, (x->x_count == 9)?1:0);
+ if ((x->x_state & 16) != 0) goto reset;
+ outlet_float(x->x_carry_out, (x->x_count < 5)?1:0);
+ if ((x->x_state & 16) != 0) goto reset;
+ x->x_state &= ~8;/* finished updating outlets */
+}
+
+static void cd4017_free(t_cd4017 *x)
+{
+ return;
+}
+
+static void *cd4017_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_cd4017 *x;
+
+ x = (t_cd4017 *)pd_new(cd4017_class);
+ if (x == NULL) return (x);
+ x->x_0 = outlet_new((t_object *)x, &s_float);
+ x->x_1 = outlet_new((t_object *)x, &s_float);
+ x->x_2 = outlet_new((t_object *)x, &s_float);
+ x->x_3 = outlet_new((t_object *)x, &s_float);
+ x->x_4 = outlet_new((t_object *)x, &s_float);
+ x->x_5 = outlet_new((t_object *)x, &s_float);
+ x->x_6 = outlet_new((t_object *)x, &s_float);
+ x->x_7 = outlet_new((t_object *)x, &s_float);
+ x->x_8 = outlet_new((t_object *)x, &s_float);
+ x->x_9 = outlet_new((t_object *)x, &s_float);
+ x->x_carry_out = outlet_new((t_object *)x, &s_float);
+ x->x_clock_inhibit = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("clock_inhibit"));
+ x->x_reset = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("reset"));
+
+ return (x);
+}
+
+void cd4017_setup(void)
+{
+ cd4017_class = class_new(gensym("cd4017"),
+ (t_newmethod)cd4017_new,
+ (t_method)cd4017_free,
+ sizeof(t_cd4017), 0, 0); /* no arguments */
+ class_addbang(cd4017_class, cd4017_bang);
+ class_addfloat(cd4017_class, cd4017_float);
+ class_addmethod(cd4017_class, (t_method)cd4017_reset, gensym("reset"), A_FLOAT, 0);
+ class_addmethod(cd4017_class, (t_method)cd4017_clock_inhibit, gensym("clock_inhibit"), A_FLOAT, 0);
+}
+/* end cd4017.c */
+
diff --git a/cmos/cd40193.c b/cmos/cd40193.c
new file mode 100755
index 0000000..22bdcbc
--- /dev/null
+++ b/cmos/cd40193.c
@@ -0,0 +1,250 @@
+/* cd40193.c MP 20070312 */
+/* Emulate a cd40193b */
+#include "m_pd.h"
+
+typedef struct _cd40193
+{
+ t_object x_obj;
+ t_outlet *x_QAOut;
+ t_outlet *x_QBOut;
+ t_outlet *x_QCOut;
+ t_outlet *x_QDOut;
+ t_outlet *x_CarryOut;
+ t_outlet *x_BorrowOut;
+ t_int x_countUp;
+ t_int x_countDown;
+ t_int x_dataA;
+ t_int x_dataB;
+ t_int x_dataC;
+ t_int x_dataD;
+ t_int x_load;
+ t_int x_clear;
+ t_int x_count;
+ t_inlet *x_CountDownIn;/* All inlets take one or zero as acceptable inputs. */
+ t_inlet *x_ClearIn;
+ t_inlet *x_LoadIn;
+ t_inlet *x_DataAIn;
+ t_inlet *x_DataBIn;
+ t_inlet *x_DataCIn;
+ t_inlet *x_DataDIn;
+ /* The main inlet (clock) should accept a bang or a one as valid clocks. */
+ /* If a one is received, it must be followed by a zero before the clock will work again. */
+} t_cd40193;
+
+static t_class *cd40193_class;
+
+void cd40193_setup(void);
+static void *cd40193_new(t_symbol *s, int argc, t_atom *argv);
+static void cd40193_free(t_cd40193 *x);
+static void cd40193_bang(t_cd40193 *x);
+static void cd40193_float(t_cd40193 *x, t_float f);
+static void cd40193_clear(t_cd40193 *x, t_float f);
+static void cd40193_load(t_cd40193 *x, t_float f);
+static void cd40193_count_down(t_cd40193 *x, t_float f);
+static void cd40193_data_A(t_cd40193 *x, t_float f);
+static void cd40193_data_B(t_cd40193 *x, t_float f);
+static void cd40193_data_C(t_cd40193 *x, t_float f);
+static void cd40193_data_D(t_cd40193 *x, t_float f);
+static void cd40193_update_outlets(t_cd40193 *x);
+
+static void cd40193_float(t_cd40193 *x, t_float f)
+{
+ if (f == 1)
+ { /* if clock is high and was low, count up. */
+ if ((x->x_countUp == 0)&&(x->x_countDown == 1)&&(x->x_clear == 0)&&(x->x_load == 1))
+ {
+ x->x_countUp = 1;
+ x->x_count = (x->x_count + 1)%16;
+ cd40193_update_outlets(x);
+ }
+ }
+ else if (f == 0)
+ {
+ if ((x->x_countUp == 1) && (x->x_count == 15)) outlet_float(x->x_CarryOut, 0);
+ x->x_countUp = 0;
+ }
+ else post("cd40193 accepts bang, 1 or 0.");
+}
+
+static void cd40193_bang(t_cd40193 *x)
+{
+ if ((x->x_countDown == 1)&&(x->x_clear == 0)&&(x->x_load == 1))
+ {
+ x->x_countUp = 1;
+ x->x_count = (x->x_count + 1)%16;
+ cd40193_update_outlets(x);
+ if (x->x_count == 15) outlet_float(x->x_CarryOut, 0);
+ }
+}
+
+static void cd40193_clear(t_cd40193 *x, t_float f)
+{
+ if (f == 1)
+ {
+ if (x->x_clear == 0)
+ {
+ x->x_count = 0;
+ cd40193_update_outlets(x);
+ x->x_clear = 1;
+ }
+ }
+ else if (f == 0)
+ {
+ x->x_clear = 0;
+ if (x->x_load == 0)
+ { /* the strange case of a low-going clear enabling an already low load */
+ x->x_count = x->x_dataA + 2*x->x_dataB + 4*x->x_dataC + 8*x->x_dataD;
+ cd40193_update_outlets(x);
+ }
+ }
+ else
+ {
+ post("cd40193 clear takes 1 or 0 only.");
+ return;
+ }
+}
+
+static void cd40193_load(t_cd40193 *x, t_float f)
+{
+ if (f == 1)
+ {
+ x->x_load = 1;
+ }
+ else if (f == 0)
+ {
+ if (x->x_load == 1)
+ {
+ x->x_load = 0;
+ if (x->x_clear == 0)
+ {
+ x->x_count = x->x_dataA + 2*x->x_dataB + 4*x->x_dataC + 8*x->x_dataD;
+ cd40193_update_outlets(x);
+ }
+ }
+ }
+ else
+ {
+ post("cd40193 load takes 1 or 0 only.");
+ return;
+ }
+}
+
+static void cd40193_count_down(t_cd40193 *x, t_float f)
+{
+ if (f == 1)
+ { /* if clock is high and was low, count down. */
+ if (x->x_countDown == 0)
+ {
+ x->x_countDown = 1;
+ if((x->x_countUp == 1)&&(x->x_clear == 0)&&(x->x_load = 1))
+ {
+ x->x_count = (x->x_count - 1)%16;
+ cd40193_update_outlets(x);
+ }
+ }
+ }
+ else if (f == 0)
+ {
+ if ((x->x_countDown == 1) && (x->x_count == 0)) outlet_float(x->x_BorrowOut, 0);
+ x->x_countDown = 0;
+ }
+ else post("cd40193 count down accepts bang, 1 or 0.");
+}
+
+static void cd40193_data_A(t_cd40193 *x, t_float f)
+{
+ if (f == 1) x->x_dataA = 1;
+ else if (f == 0) x->x_dataA = 0;
+ else
+ {
+ post("cd40193 data A takes 1 or 0 only.");
+ return;
+ }
+}
+static void cd40193_data_B(t_cd40193 *x, t_float f)
+{
+ if (f == 1) x->x_dataB = 1;
+ else if (f == 0) x->x_dataB = 0;
+ else
+ {
+ post("cd40193 data B takes 1 or 0 only.");
+ return;
+ }
+}
+static void cd40193_data_C(t_cd40193 *x, t_float f)
+{
+ if (f == 1) x->x_dataC = 1;
+ else if (f == 0) x->x_dataC = 0;
+ else
+ {
+ post("cd40193 data C takes 1 or 0 only.");
+ return;
+ }
+}
+static void cd40193_data_D(t_cd40193 *x, t_float f)
+{
+ if (f == 1) x->x_dataD = 1;
+ else if (f == 0) x->x_dataD = 0;
+ else
+ {
+ post("cd40193 data D takes 1 or 0 only.");
+ return;
+ }
+}
+
+static void cd40193_update_outlets(t_cd40193 *x)
+{
+ outlet_float(x->x_BorrowOut, 1);
+ outlet_float(x->x_CarryOut, 1);
+ outlet_float(x->x_QDOut, ((x->x_count & 8) != 0)?1:0);
+ outlet_float(x->x_QCOut, ((x->x_count & 4) != 0)?1:0);
+ outlet_float(x->x_QBOut, ((x->x_count & 2) != 0)?1:0);
+ outlet_float(x->x_QAOut, ((x->x_count & 1) != 0)?1:0);
+}
+
+static void cd40193_free(t_cd40193 *x)
+{
+ return;
+}
+
+static void *cd40193_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_cd40193 *x;
+
+ x = (t_cd40193 *)pd_new(cd40193_class);
+ if (x == NULL) return (x);
+ x->x_QAOut = outlet_new((t_object *)x, &s_float);
+ x->x_QBOut = outlet_new((t_object *)x, &s_float);
+ x->x_QCOut = outlet_new((t_object *)x, &s_float);
+ x->x_QDOut = outlet_new((t_object *)x, &s_float);
+ x->x_CarryOut = outlet_new((t_object *)x, &s_float);
+ x->x_BorrowOut = outlet_new((t_object *)x, &s_float);
+
+ x->x_CountDownIn = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("countdown"));
+ x->x_ClearIn = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("clear"));
+ x->x_LoadIn = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("load"));
+ x->x_DataAIn = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("dataA"));
+ x->x_DataBIn = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("dataB"));
+ x->x_DataCIn = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("dataC"));
+ x->x_DataDIn = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("dataD"));
+ return (x);
+}
+
+void cd40193_setup(void)
+{
+ cd40193_class = class_new(gensym("cd40193"),
+ (t_newmethod)cd40193_new,
+ (t_method)cd40193_free,
+ sizeof(t_cd40193), 0, 0); /* no arguments */
+ class_addbang(cd40193_class, cd40193_bang);
+ class_addfloat(cd40193_class, cd40193_float);
+ class_addmethod(cd40193_class, (t_method)cd40193_count_down, gensym("countdown"), A_FLOAT, 0);
+ class_addmethod(cd40193_class, (t_method)cd40193_load, gensym("load"), A_FLOAT, 0);
+ class_addmethod(cd40193_class, (t_method)cd40193_clear, gensym("clear"), A_FLOAT, 0);
+ class_addmethod(cd40193_class, (t_method)cd40193_data_A, gensym("dataA"), A_FLOAT, 0);
+ class_addmethod(cd40193_class, (t_method)cd40193_data_B, gensym("dataB"), A_FLOAT, 0);
+ class_addmethod(cd40193_class, (t_method)cd40193_data_C, gensym("dataC"), A_FLOAT, 0);
+ class_addmethod(cd40193_class, (t_method)cd40193_data_D, gensym("dataD"), A_FLOAT, 0);
+}
+/* end cd40193.c */
+
diff --git a/cmos/cd4023.c b/cmos/cd4023.c
new file mode 100755
index 0000000..ff60255
--- /dev/null
+++ b/cmos/cd4023.c
@@ -0,0 +1,102 @@
+/* cd4023.c MP 20070312 */
+/* Emulate a cd4023b */
+#include "m_pd.h"
+
+typedef struct _cd4023
+{
+ t_object x_obj;
+ t_int x_in1;
+ t_int x_in2;
+ t_int x_in3;
+ t_outlet *x_out;
+ t_inlet *x_inlet2;/* Second inlet is 'live' like the first */
+ t_inlet *x_inlet3;/* Third inlet is 'live' like the first */
+} t_cd4023;
+
+static t_class *cd4023_class;
+
+void cd4023_setup(void);
+static void *cd4023_new(t_symbol *s, int argc, t_atom *argv);
+static void cd4023_free(t_cd4023 *x);
+static void cd4023_bang(t_cd4023 *x);
+static void cd4023_float(t_cd4023 *x, t_float f);
+static void cd4023_inlet2(t_cd4023 *x, t_float f);
+static void cd4023_inlet3(t_cd4023 *x, t_float f);
+static void cd4023_update_outlets(t_cd4023 *x);
+
+static void cd4023_float(t_cd4023 *x, t_float f)
+{
+ if (f == 1) x->x_in1 = 1;
+ else if (f == 0) x->x_in1 = 0;
+ else
+ {
+ post("cd4023 inlet 2 accepts 1 or 0.");
+ return;
+ }
+ cd4023_update_outlets(x);
+}
+
+static void cd4023_bang(t_cd4023 *x)
+{
+ cd4023_update_outlets(x);
+}
+
+static void cd4023_inlet2(t_cd4023 *x, t_float f)
+{
+ if (f == 1) x->x_in2 = 1;
+ else if (f == 0) x->x_in2 = 0;
+ else
+ {
+ post("cd4023 inlet 2 accepts 1 or 0.");
+ return;
+ }
+ cd4023_update_outlets(x);
+}
+
+static void cd4023_inlet3(t_cd4023 *x, t_float f)
+{
+ if (f == 1) x->x_in3 = 1;
+ else if (f == 0) x->x_in3 = 0;
+ else
+ {
+ post("cd4023 inlet 3 accepts 1 or 0.");
+ return;
+ }
+ cd4023_update_outlets(x);
+}
+
+static void cd4023_update_outlets(t_cd4023 *x)
+{ /* Triple NAND function */
+ outlet_float(x->x_out, ((x->x_in1 + x->x_in2 + x->x_in3) == 3)?0:1);
+}
+
+static void cd4023_free(t_cd4023 *x)
+{
+ return;
+}
+
+static void *cd4023_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_cd4023 *x;
+
+ x = (t_cd4023 *)pd_new(cd4023_class);
+ if (x == NULL) return (x);
+ x->x_out = outlet_new((t_object *)x, &s_float);
+ x->x_inlet2 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("inlet2"));
+ x->x_inlet3 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("inlet3"));
+ return (x);
+}
+
+void cd4023_setup(void)
+{
+ cd4023_class = class_new(gensym("cd4023"),
+ (t_newmethod)cd4023_new,
+ (t_method)cd4023_free,
+ sizeof(t_cd4023), 0, 0); /* no arguments */
+ class_addbang(cd4023_class, cd4023_bang);
+ class_addfloat(cd4023_class, cd4023_float);
+ class_addmethod(cd4023_class, (t_method)cd4023_inlet2, gensym("inlet2"), A_FLOAT, 0);
+ class_addmethod(cd4023_class, (t_method)cd4023_inlet3, gensym("inlet3"), A_FLOAT, 0);
+}
+/* end cd4023.c */
+
diff --git a/cmos/cd4024.c b/cmos/cd4024.c
new file mode 100755
index 0000000..93c3bf4
--- /dev/null
+++ b/cmos/cd4024.c
@@ -0,0 +1,125 @@
+/* cd4024.c MP 20070319 */
+/* Emulate a cd4024b */
+#include "m_pd.h"
+
+typedef struct _cd4024
+{
+ t_object x_obj;
+ t_int x_reset;
+ t_int x_clock;
+ t_int x_count;
+ t_int x_updating;
+ t_outlet *x_Q1;
+ t_outlet *x_Q2;
+ t_outlet *x_Q3;
+ t_outlet *x_Q4;
+ t_outlet *x_Q5;
+ t_outlet *x_Q6;
+ t_outlet *x_Q7;
+ t_inlet *x_resetIn;/* reset */
+ /* The main inlet (clcok) should accept a bang or a one as valid clocks. */
+ /* If a one is received, it must be followed by a zero before the clock will work again. */
+} t_cd4024;
+
+static t_class *cd4024_class;
+
+void cd4024_setup(void);
+static void *cd4024_new(t_symbol *s, int argc, t_atom *argv);
+static void cd4024_free(t_cd4024 *x);
+static void cd4024_bang(t_cd4024 *x);
+static void cd4024_float(t_cd4024 *x, t_float f);
+static void cd4024_reset(t_cd4024 *x, t_float f);
+static void cd4024_update_outlets(t_cd4024 *x);
+
+static void cd4024_float(t_cd4024 *x, t_float f)
+{
+ if (f == 0)
+ { /* if clock is low and was high, clock it. */
+ if (x->x_clock == 1)
+ {
+ x->x_clock = 0;
+ cd4024_bang(x);
+ }
+ }
+ else if (f == 1) x->x_clock = 1;
+ else post("cd4024 clock accepts bang, 1 or 0.");
+}
+
+static void cd4024_bang(t_cd4024 *x)
+{
+ if (x->x_reset == 0)
+ { /* if reset is low, clock forward */
+ x->x_count = (x->x_count + 1)%128;
+ cd4024_update_outlets(x);
+ }
+}
+
+static void cd4024_reset(t_cd4024 *x, t_float f)
+{
+ if (f == 1)
+ {
+ x->x_count = 0;
+ x->x_reset = 1;
+ if (x->x_updating != 0) x->x_updating |= 2;
+ else cd4024_update_outlets(x);
+ }
+ else if (f == 0) x->x_reset = 0;
+}
+
+static void cd4024_update_outlets(t_cd4024 *x)
+{
+reset:
+ x->x_updating = 1;/* updating outlets */
+ outlet_float(x->x_Q7, ((x->x_count & 64) != 0)?1:0);
+/* we might get reset as a result of feedback from one of these outlets. */
+ if ((x->x_updating & 2) != 0) goto reset;
+ outlet_float(x->x_Q6, ((x->x_count & 32) != 0)?1:0);
+ if ((x->x_updating & 2) != 0) goto reset;
+ outlet_float(x->x_Q5, ((x->x_count & 16) != 0)?1:0);
+ if ((x->x_updating & 2) != 0) goto reset;
+ outlet_float(x->x_Q4, ((x->x_count & 8) != 0)?1:0);
+ if ((x->x_updating & 2) != 0) goto reset;
+ outlet_float(x->x_Q3, ((x->x_count & 4) != 0)?1:0);
+ if ((x->x_updating & 2) != 0) goto reset;
+ outlet_float(x->x_Q2, ((x->x_count & 2) != 0)?1:0);
+ if ((x->x_updating & 2) != 0) goto reset;
+ outlet_float(x->x_Q1, ((x->x_count & 1) != 0)?1:0);
+ if ((x->x_updating & 2) != 0) goto reset;
+ x->x_updating = 0; /* finished updating outlets */
+}
+
+static void cd4024_free(t_cd4024 *x)
+{
+ return;
+}
+
+static void *cd4024_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_cd4024 *x;
+
+ x = (t_cd4024 *)pd_new(cd4024_class);
+ if (x == NULL) return (x);
+ x->x_Q1 = outlet_new((t_object *)x, &s_float);
+ x->x_Q2 = outlet_new((t_object *)x, &s_float);
+ x->x_Q3 = outlet_new((t_object *)x, &s_float);
+ x->x_Q4 = outlet_new((t_object *)x, &s_float);
+ x->x_Q5 = outlet_new((t_object *)x, &s_float);
+ x->x_Q6 = outlet_new((t_object *)x, &s_float);
+ x->x_Q7 = outlet_new((t_object *)x, &s_float);
+ x->x_resetIn = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("reset"));
+
+ return (x);
+}
+
+void cd4024_setup(void)
+{
+ cd4024_class = class_new(gensym("cd4024"),
+ (t_newmethod)cd4024_new,
+ (t_method)cd4024_free,
+ sizeof(t_cd4024), 0, 0); /* no arguments */
+ class_addbang(cd4024_class, cd4024_bang);
+ class_addfloat(cd4024_class, cd4024_float);
+ class_addmethod(cd4024_class, (t_method)cd4024_reset, gensym("reset"), A_FLOAT, 0);
+}
+/* end cd4024.c */
+
diff --git a/cmos/cd4025.c b/cmos/cd4025.c
new file mode 100755
index 0000000..5124f14
--- /dev/null
+++ b/cmos/cd4025.c
@@ -0,0 +1,102 @@
+/* cd4025.c MP 20070312 */
+/* Emulate a cd4025b */
+#include "m_pd.h"
+
+typedef struct _cd4025
+{
+ t_object x_obj;
+ t_int x_in1;
+ t_int x_in2;
+ t_int x_in3;
+ t_outlet *x_out;
+ t_inlet *x_inlet2;/* Second inlet is 'live' like the first */
+ t_inlet *x_inlet3;/* Third inlet is 'live' like the first */
+} t_cd4025;
+
+static t_class *cd4025_class;
+
+void cd4025_setup(void);
+static void *cd4025_new(t_symbol *s, int argc, t_atom *argv);
+static void cd4025_free(t_cd4025 *x);
+static void cd4025_bang(t_cd4025 *x);
+static void cd4025_float(t_cd4025 *x, t_float f);
+static void cd4025_inlet2(t_cd4025 *x, t_float f);
+static void cd4025_inlet3(t_cd4025 *x, t_float f);
+static void cd4025_update_outlets(t_cd4025 *x);
+
+static void cd4025_float(t_cd4025 *x, t_float f)
+{
+ if (f == 1) x->x_in1 = 1;
+ else if (f == 0) x->x_in1 = 0;
+ else
+ {
+ post("cd4025 inlet 2 accepts 1 or 0.");
+ return;
+ }
+ cd4025_update_outlets(x);
+}
+
+static void cd4025_bang(t_cd4025 *x)
+{
+ cd4025_update_outlets(x);
+}
+
+static void cd4025_inlet2(t_cd4025 *x, t_float f)
+{
+ if (f == 1) x->x_in2 = 1;
+ else if (f == 0) x->x_in2 = 0;
+ else
+ {
+ post("cd4025 inlet 2 accepts 1 or 0.");
+ return;
+ }
+ cd4025_update_outlets(x);
+}
+
+static void cd4025_inlet3(t_cd4025 *x, t_float f)
+{
+ if (f == 1) x->x_in3 = 1;
+ else if (f == 0) x->x_in3 = 0;
+ else
+ {
+ post("cd4025 inlet 3 accepts 1 or 0.");
+ return;
+ }
+ cd4025_update_outlets(x);
+}
+
+static void cd4025_update_outlets(t_cd4025 *x)
+{ /* Triple NOR function */
+ outlet_float(x->x_out, ((x->x_in1 + x->x_in2 + x->x_in3) != 0)?0:1);
+}
+
+static void cd4025_free(t_cd4025 *x)
+{
+ return;
+}
+
+static void *cd4025_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_cd4025 *x;
+
+ x = (t_cd4025 *)pd_new(cd4025_class);
+ if (x == NULL) return (x);
+ x->x_out = outlet_new((t_object *)x, &s_float);
+ x->x_inlet2 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("inlet2"));
+ x->x_inlet3 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("inlet3"));
+ return (x);
+}
+
+void cd4025_setup(void)
+{
+ cd4025_class = class_new(gensym("cd4025"),
+ (t_newmethod)cd4025_new,
+ (t_method)cd4025_free,
+ sizeof(t_cd4025), 0, 0); /* no arguments */
+ class_addbang(cd4025_class, cd4025_bang);
+ class_addfloat(cd4025_class, cd4025_float);
+ class_addmethod(cd4025_class, (t_method)cd4025_inlet2, gensym("inlet2"), A_FLOAT, 0);
+ class_addmethod(cd4025_class, (t_method)cd4025_inlet3, gensym("inlet3"), A_FLOAT, 0);
+}
+/* end cd4025.c */
+
diff --git a/cmos/cd4027.c b/cmos/cd4027.c
new file mode 100755
index 0000000..69aaf48
--- /dev/null
+++ b/cmos/cd4027.c
@@ -0,0 +1,210 @@
+/* cd4027.c MP 20070306 */
+/* Emulate a cd4027b */
+#include "m_pd.h"
+
+typedef struct _cd4027
+{
+ t_object x_obj;
+ t_int x_state;/* set = bit0, clock = bit1, reset = bit2 j = bit3 k = bit4 q = bit 5 */
+ t_outlet *x_Q;
+ t_outlet *x_notQ;
+ t_inlet *x_set;/* set takes one or zero as acceptable inputs. */
+ t_inlet *x_reset;/* reset takes one or zero as acceptable inputs. */
+ t_inlet *x_j;/* j takes one or zero as acceptable inputs. */
+ t_inlet *x_k;/* k takes one or zero as acceptable inputs. */
+ /* The main inlet (clock) should accept a bang or a one as valid clocks. */
+ /* If a one is received, it must be followed by a zero before the clock will work again. */
+} t_cd4027;
+#define SET_4027 1
+#define CLOCK_4027 2
+#define RESET_4027 4
+#define J_4027 8
+#define K_4027 16
+#define Q_4027 32
+#define UPDATING_4027 64
+#define CHANGED_4027 128
+
+static t_class *cd4027_class;
+
+void cd4027_setup(void);
+static void *cd4027_new(t_symbol *s, int argc, t_atom *argv);
+static void cd4027_free(t_cd4027 *x);
+static void cd4027_bang(t_cd4027 *x);
+static void cd4027_float(t_cd4027 *x, t_float f);
+static void cd4027_set(t_cd4027 *x, t_float f);
+static void cd4027_reset(t_cd4027 *x, t_float f);
+static void cd4027_j(t_cd4027 *x, t_float f);
+static void cd4027_k(t_cd4027 *x, t_float f);
+static void cd4027_update_outlets(t_cd4027 *x);
+static void cd4027_printstate (t_cd4027 *x);
+
+static void cd4027_float(t_cd4027 *x, t_float f)
+{
+ if (f == 1)
+ { /* if clock is high and was low, clock it. */
+ if ((x->x_state & CLOCK_4027) == 0) cd4027_bang(x);
+ x->x_state |= CLOCK_4027;
+ }
+ else if (f == 0) x->x_state &= ~CLOCK_4027;
+ else post("cd4027 accepts bang, 1 or 0.");
+}
+
+static void cd4027_printstate (t_cd4027 *x)
+{
+ post ("SET %d RESET %d J %d K %d Q %d", ((x->x_state & SET_4027) != 0)?1:0
+ , ((x->x_state & RESET_4027) != 0)?1:0
+ , ((x->x_state & J_4027) != 0)?1:0
+ , ((x->x_state & K_4027) != 0)?1:0
+ , ((x->x_state & Q_4027) != 0)?1:0);
+}
+
+static void cd4027_bang(t_cd4027 *x)
+{
+ if ((x->x_state & (SET_4027 | RESET_4027)) == 0)
+ { /* if set is low and reset is low, clock forward */
+ if ((x->x_state & Q_4027) != 0)
+ { /* Q is high */
+ if ((x->x_state & K_4027)== 0) x->x_state |= Q_4027;
+ else x->x_state &= ~Q_4027;
+ }
+ else
+ { /* Q is low */
+ if ((x->x_state & J_4027) != 0) x->x_state |= Q_4027;
+ else x->x_state &= ~Q_4027;
+ }
+ cd4027_update_outlets(x);
+ }
+}
+
+static void cd4027_set(t_cd4027 *x, t_float f)
+{
+ if (f == 1)
+ {
+ x->x_state |= SET_4027; /* set = 1 */
+ }
+ else if (f == 0)
+ {
+ x->x_state &= ~SET_4027; /* set = 0 */
+ }
+ else
+ {
+ post("cd4027 set takes 1 or 0 only.");
+ return;
+ }
+ /* update outlets if not already doing that */
+ if ((x->x_state & UPDATING_4027) == 0)
+ {
+ cd4027_update_outlets(x);
+ }
+ else
+ {
+ x->x_state |= CHANGED_4027;
+ }
+ return;
+}
+
+static void cd4027_reset(t_cd4027 *x, t_float f)
+{
+ if (f == 1)
+ {
+ x->x_state |= RESET_4027; /* reset = 1 */
+ }
+ else if (f == 0)
+ {
+ x->x_state &= ~RESET_4027; /* reset = 0 */
+ }
+ else
+ {
+ return;
+ }
+ /* update outlets if not already doing that */
+ if ((x->x_state & UPDATING_4027) == 0)
+ {
+ cd4027_update_outlets(x);
+ }
+ else
+ {
+ x->x_state |= CHANGED_4027;
+ }
+ return;
+}
+
+static void cd4027_j(t_cd4027 *x, t_float f)
+{
+ if (f == 1)
+ {
+ x->x_state |= J_4027; /* j = 1 */
+ }
+ else if (f == 0)
+ {
+ x->x_state &= ~J_4027; /* j = 0 */
+ }
+ else post("cd4027 j takes 1 or 0 only.");
+ return;
+}
+
+static void cd4027_k(t_cd4027 *x, t_float f)
+{
+ if (f == 1)
+ {
+ x->x_state |= K_4027; /* k = 1 */
+ }
+ else if (f == 0)
+ {
+ x->x_state &= ~K_4027; /* k = 0 */
+ }
+ else post("cd4027 k takes 1 or 0 only.");
+ return;
+}
+
+static void cd4027_update_outlets(t_cd4027 *x)
+{
+ /* cd4027_printstate (x); */
+ x->x_state |= UPDATING_4027;/* updating outlets */
+reset:
+ if ((x->x_state & SET_4027) != 0) x->x_state |= Q_4027;
+ else if ((x->x_state & RESET_4027) != 0) x->x_state &= ~Q_4027;
+ x->x_state &= ~CHANGED_4027; /* prepare to flag any changes that occur during outlet_update */
+ outlet_float(x->x_notQ, ((x->x_state & Q_4027) == 0)?1:0);
+/* we might get set or reset as a result of feedback from one of these outlets. */
+ if ((x->x_state & CHANGED_4027) != 0) goto reset;
+ outlet_float(x->x_Q, ((x->x_state & Q_4027) != 0)?1:0);
+ if ((x->x_state & CHANGED_4027) != 0) goto reset;
+ x->x_state &= ~UPDATING_4027;/* finished updating outlets */
+}
+
+static void cd4027_free(t_cd4027 *x)
+{
+ return;
+}
+
+static void *cd4027_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_cd4027 *x;
+
+ x = (t_cd4027 *)pd_new(cd4027_class);
+ if (x == NULL) return (x);
+ x->x_Q = outlet_new((t_object *)x, &s_float);
+ x->x_notQ = outlet_new((t_object *)x, &s_float);
+ x->x_set = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("set"));
+ x->x_reset = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("reset"));
+ x->x_j = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("j"));
+ x->x_k = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("k"));
+ return (x);
+}
+
+void cd4027_setup(void)
+{
+ cd4027_class = class_new(gensym("cd4027"),
+ (t_newmethod)cd4027_new,
+ (t_method)cd4027_free,
+ sizeof(t_cd4027), 0, 0); /* no arguments */
+ class_addbang(cd4027_class, cd4027_bang);
+ class_addfloat(cd4027_class, cd4027_float);
+ class_addmethod(cd4027_class, (t_method)cd4027_reset, gensym("reset"), A_FLOAT, 0);
+ class_addmethod(cd4027_class, (t_method)cd4027_set, gensym("set"), A_FLOAT, 0);
+ class_addmethod(cd4027_class, (t_method)cd4027_j, gensym("j"), A_FLOAT, 0);
+ class_addmethod(cd4027_class, (t_method)cd4027_k, gensym("k"), A_FLOAT, 0);
+}
+/* end cd4027.c */
+
diff --git a/cmos/cd4070.c b/cmos/cd4070.c
new file mode 100755
index 0000000..ece39b0
--- /dev/null
+++ b/cmos/cd4070.c
@@ -0,0 +1,85 @@
+/* cd4070.c MP 20070305 */
+/* Emulate a cd4070b */
+#include "m_pd.h"
+
+typedef struct _cd4070
+{
+ t_object x_obj;
+ t_int x_in1;
+ t_int x_in2;
+ t_outlet *x_out;
+ t_inlet *x_inlet2;/* Second inlet is 'live' like the first */
+} t_cd4070;
+
+static t_class *cd4070_class;
+
+void cd4070_setup(void);
+static void *cd4070_new(t_symbol *s, int argc, t_atom *argv);
+static void cd4070_free(t_cd4070 *x);
+static void cd4070_bang(t_cd4070 *x);
+static void cd4070_float(t_cd4070 *x, t_float f);
+static void cd4070_inlet2(t_cd4070 *x, t_float f);
+static void cd4070_update_outlets(t_cd4070 *x);
+
+static void cd4070_float(t_cd4070 *x, t_float f)
+{
+ if (f == 1) x->x_in1 = 1;
+ else if (f == 0) x->x_in1 = 0;
+ else
+ {
+ post("cd4070 inlet 2 accepts 1 or 0.");
+ return;
+ }
+ cd4070_update_outlets(x);
+}
+
+static void cd4070_bang(t_cd4070 *x)
+{
+ cd4070_update_outlets(x);
+}
+
+static void cd4070_inlet2(t_cd4070 *x, t_float f)
+{
+ if (f == 1) x->x_in2 = 1;
+ else if (f == 0) x->x_in2 = 0;
+ else
+ {
+ post("cd4070 inlet 2 accepts 1 or 0.");
+ return;
+ }
+ cd4070_update_outlets(x);
+}
+
+static void cd4070_update_outlets(t_cd4070 *x)
+{
+ outlet_float(x->x_out, (x->x_in1 != x->x_in2)?1:0);
+}
+
+static void cd4070_free(t_cd4070 *x)
+{
+ return;
+}
+
+static void *cd4070_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_cd4070 *x;
+
+ x = (t_cd4070 *)pd_new(cd4070_class);
+ if (x == NULL) return (x);
+ x->x_out = outlet_new((t_object *)x, &s_float);
+ x->x_inlet2 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("inlet2"));
+ return (x);
+}
+
+void cd4070_setup(void)
+{
+ cd4070_class = class_new(gensym("cd4070"),
+ (t_newmethod)cd4070_new,
+ (t_method)cd4070_free,
+ sizeof(t_cd4070), 0, 0); /* no arguments */
+ class_addbang(cd4070_class, cd4070_bang);
+ class_addfloat(cd4070_class, cd4070_float);
+ class_addmethod(cd4070_class, (t_method)cd4070_inlet2, gensym("inlet2"), A_FLOAT, 0);
+}
+/* end cd4070.c */
+
diff --git a/cmos/cd4071.c b/cmos/cd4071.c
new file mode 100755
index 0000000..d6f49e7
--- /dev/null
+++ b/cmos/cd4071.c
@@ -0,0 +1,85 @@
+/* cd4071.c MP 20070308 */
+/* Emulate a cd4071b */
+#include "m_pd.h"
+
+typedef struct _cd4071
+{
+ t_object x_obj;
+ t_int x_in1;
+ t_int x_in2;
+ t_outlet *x_out;
+ t_inlet *x_inlet2;/* Second inlet is 'live' like the first */
+} t_cd4071;
+
+static t_class *cd4071_class;
+
+void cd4071_setup(void);
+static void *cd4071_new(t_symbol *s, int argc, t_atom *argv);
+static void cd4071_free(t_cd4071 *x);
+static void cd4071_bang(t_cd4071 *x);
+static void cd4071_float(t_cd4071 *x, t_float f);
+static void cd4071_inlet2(t_cd4071 *x, t_float f);
+static void cd4071_update_outlets(t_cd4071 *x);
+
+static void cd4071_float(t_cd4071 *x, t_float f)
+{
+ if (f == 1) x->x_in1 = 1;
+ else if (f == 0) x->x_in1 = 0;
+ else
+ {
+ post("cd4071 inlet 2 accepts 1 or 0.");
+ return;
+ }
+ cd4071_update_outlets(x);
+}
+
+static void cd4071_bang(t_cd4071 *x)
+{
+ cd4071_update_outlets(x);
+}
+
+static void cd4071_inlet2(t_cd4071 *x, t_float f)
+{
+ if (f == 1) x->x_in2 = 1;
+ else if (f == 0) x->x_in2 = 0;
+ else
+ {
+ post("cd4071 inlet 2 accepts 1 or 0.");
+ return;
+ }
+ cd4071_update_outlets(x);
+}
+
+static void cd4071_update_outlets(t_cd4071 *x)
+{ /* OR function */
+ outlet_float(x->x_out, ((x->x_in1 + x->x_in2) != 0)?1:0);
+}
+
+static void cd4071_free(t_cd4071 *x)
+{
+ return;
+}
+
+static void *cd4071_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_cd4071 *x;
+
+ x = (t_cd4071 *)pd_new(cd4071_class);
+ if (x == NULL) return (x);
+ x->x_out = outlet_new((t_object *)x, &s_float);
+ x->x_inlet2 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("inlet2"));
+ return (x);
+}
+
+void cd4071_setup(void)
+{
+ cd4071_class = class_new(gensym("cd4071"),
+ (t_newmethod)cd4071_new,
+ (t_method)cd4071_free,
+ sizeof(t_cd4071), 0, 0); /* no arguments */
+ class_addbang(cd4071_class, cd4071_bang);
+ class_addfloat(cd4071_class, cd4071_float);
+ class_addmethod(cd4071_class, (t_method)cd4071_inlet2, gensym("inlet2"), A_FLOAT, 0);
+}
+/* end cd4071.c */
+
diff --git a/cmos/cd4072.c b/cmos/cd4072.c
new file mode 100755
index 0000000..9ce4b80
--- /dev/null
+++ b/cmos/cd4072.c
@@ -0,0 +1,119 @@
+/* cd4072.c MP 20070312 */
+/* Emulate a cd4072b */
+#include "m_pd.h"
+
+typedef struct _cd4072
+{
+ t_object x_obj;
+ t_int x_in1;
+ t_int x_in2;
+ t_int x_in3;
+ t_int x_in4;
+ t_outlet *x_out;
+ t_inlet *x_inlet2;/* Second inlet is 'live' like the first */
+ t_inlet *x_inlet3;/* Third inlet is 'live' like the first */
+ t_inlet *x_inlet4;/* Fourth inlet is 'live' like the first */
+} t_cd4072;
+
+static t_class *cd4072_class;
+
+void cd4072_setup(void);
+static void *cd4072_new(t_symbol *s, int argc, t_atom *argv);
+static void cd4072_free(t_cd4072 *x);
+static void cd4072_bang(t_cd4072 *x);
+static void cd4072_float(t_cd4072 *x, t_float f);
+static void cd4072_inlet2(t_cd4072 *x, t_float f);
+static void cd4072_inlet3(t_cd4072 *x, t_float f);
+static void cd4072_inlet4(t_cd4072 *x, t_float f);
+static void cd4072_update_outlets(t_cd4072 *x);
+
+static void cd4072_float(t_cd4072 *x, t_float f)
+{
+ if (f == 1) x->x_in1 = 1;
+ else if (f == 0) x->x_in1 = 0;
+ else
+ {
+ post("cd4072 inlet 2 accepts 1 or 0.");
+ return;
+ }
+ cd4072_update_outlets(x);
+}
+
+static void cd4072_bang(t_cd4072 *x)
+{
+ cd4072_update_outlets(x);
+}
+
+static void cd4072_inlet2(t_cd4072 *x, t_float f)
+{
+ if (f == 1) x->x_in2 = 1;
+ else if (f == 0) x->x_in2 = 0;
+ else
+ {
+ post("cd4072 inlet 2 accepts 1 or 0.");
+ return;
+ }
+ cd4072_update_outlets(x);
+}
+
+static void cd4072_inlet3(t_cd4072 *x, t_float f)
+{
+ if (f == 1) x->x_in3 = 1;
+ else if (f == 0) x->x_in3 = 0;
+ else
+ {
+ post("cd4072 inlet 3 accepts 1 or 0.");
+ return;
+ }
+ cd4072_update_outlets(x);
+}
+
+static void cd4072_inlet4(t_cd4072 *x, t_float f)
+{
+ if (f == 1) x->x_in4 = 1;
+ else if (f == 0) x->x_in4 = 0;
+ else
+ {
+ post("cd4072 inlet 4 accepts 1 or 0.");
+ return;
+ }
+ cd4072_update_outlets(x);
+}
+
+static void cd4072_update_outlets(t_cd4072 *x)
+{ /* QUAD OR function */
+ outlet_float(x->x_out, ((x->x_in1 + x->x_in2 + x->x_in3 + x->x_in4) != 0)?1:0);
+}
+
+static void cd4072_free(t_cd4072 *x)
+{
+ return;
+}
+
+static void *cd4072_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_cd4072 *x;
+
+ x = (t_cd4072 *)pd_new(cd4072_class);
+ if (x == NULL) return (x);
+ x->x_out = outlet_new((t_object *)x, &s_float);
+ x->x_inlet2 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("inlet2"));
+ x->x_inlet3 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("inlet3"));
+ x->x_inlet4 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("inlet4"));
+ return (x);
+}
+
+void cd4072_setup(void)
+{
+ cd4072_class = class_new(gensym("cd4072"),
+ (t_newmethod)cd4072_new,
+ (t_method)cd4072_free,
+ sizeof(t_cd4072), 0, 0); /* no arguments */
+ class_addbang(cd4072_class, cd4072_bang);
+ class_addfloat(cd4072_class, cd4072_float);
+ class_addmethod(cd4072_class, (t_method)cd4072_inlet2, gensym("inlet2"), A_FLOAT, 0);
+ class_addmethod(cd4072_class, (t_method)cd4072_inlet3, gensym("inlet3"), A_FLOAT, 0);
+ class_addmethod(cd4072_class, (t_method)cd4072_inlet4, gensym("inlet4"), A_FLOAT, 0);
+}
+/* end cd4072.c */
+
diff --git a/cmos/cd4073.c b/cmos/cd4073.c
new file mode 100755
index 0000000..530444b
--- /dev/null
+++ b/cmos/cd4073.c
@@ -0,0 +1,102 @@
+/* cd4073.c MP 20070312 */
+/* Emulate a cd4073b */
+#include "m_pd.h"
+
+typedef struct _cd4073
+{
+ t_object x_obj;
+ t_int x_in1;
+ t_int x_in2;
+ t_int x_in3;
+ t_outlet *x_out;
+ t_inlet *x_inlet2;/* Second inlet is 'live' like the first */
+ t_inlet *x_inlet3;/* Third inlet is 'live' like the first */
+} t_cd4073;
+
+static t_class *cd4073_class;
+
+void cd4073_setup(void);
+static void *cd4073_new(t_symbol *s, int argc, t_atom *argv);
+static void cd4073_free(t_cd4073 *x);
+static void cd4073_bang(t_cd4073 *x);
+static void cd4073_float(t_cd4073 *x, t_float f);
+static void cd4073_inlet2(t_cd4073 *x, t_float f);
+static void cd4073_inlet3(t_cd4073 *x, t_float f);
+static void cd4073_update_outlets(t_cd4073 *x);
+
+static void cd4073_float(t_cd4073 *x, t_float f)
+{
+ if (f == 1) x->x_in1 = 1;
+ else if (f == 0) x->x_in1 = 0;
+ else
+ {
+ post("cd4073 inlet 2 accepts 1 or 0.");
+ return;
+ }
+ cd4073_update_outlets(x);
+}
+
+static void cd4073_bang(t_cd4073 *x)
+{
+ cd4073_update_outlets(x);
+}
+
+static void cd4073_inlet2(t_cd4073 *x, t_float f)
+{
+ if (f == 1) x->x_in2 = 1;
+ else if (f == 0) x->x_in2 = 0;
+ else
+ {
+ post("cd4073 inlet 2 accepts 1 or 0.");
+ return;
+ }
+ cd4073_update_outlets(x);
+}
+
+static void cd4073_inlet3(t_cd4073 *x, t_float f)
+{
+ if (f == 1) x->x_in3 = 1;
+ else if (f == 0) x->x_in3 = 0;
+ else
+ {
+ post("cd4073 inlet 3 accepts 1 or 0.");
+ return;
+ }
+ cd4073_update_outlets(x);
+}
+
+static void cd4073_update_outlets(t_cd4073 *x)
+{ /* Triple AND function */
+ outlet_float(x->x_out, ((x->x_in1 + x->x_in2 + x->x_in3) == 3)?1:0);
+}
+
+static void cd4073_free(t_cd4073 *x)
+{
+ return;
+}
+
+static void *cd4073_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_cd4073 *x;
+
+ x = (t_cd4073 *)pd_new(cd4073_class);
+ if (x == NULL) return (x);
+ x->x_out = outlet_new((t_object *)x, &s_float);
+ x->x_inlet2 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("inlet2"));
+ x->x_inlet3 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("inlet3"));
+ return (x);
+}
+
+void cd4073_setup(void)
+{
+ cd4073_class = class_new(gensym("cd4073"),
+ (t_newmethod)cd4073_new,
+ (t_method)cd4073_free,
+ sizeof(t_cd4073), 0, 0); /* no arguments */
+ class_addbang(cd4073_class, cd4073_bang);
+ class_addfloat(cd4073_class, cd4073_float);
+ class_addmethod(cd4073_class, (t_method)cd4073_inlet2, gensym("inlet2"), A_FLOAT, 0);
+ class_addmethod(cd4073_class, (t_method)cd4073_inlet3, gensym("inlet3"), A_FLOAT, 0);
+}
+/* end cd4073.c */
+
diff --git a/cmos/cd4075.c b/cmos/cd4075.c
new file mode 100755
index 0000000..6274f9c
--- /dev/null
+++ b/cmos/cd4075.c
@@ -0,0 +1,102 @@
+/* cd4075.c MP 20070312 */
+/* Emulate a cd4075b */
+#include "m_pd.h"
+
+typedef struct _cd4075
+{
+ t_object x_obj;
+ t_int x_in1;
+ t_int x_in2;
+ t_int x_in3;
+ t_outlet *x_out;
+ t_inlet *x_inlet2;/* Second inlet is 'live' like the first */
+ t_inlet *x_inlet3;/* Third inlet is 'live' like the first */
+} t_cd4075;
+
+static t_class *cd4075_class;
+
+void cd4075_setup(void);
+static void *cd4075_new(t_symbol *s, int argc, t_atom *argv);
+static void cd4075_free(t_cd4075 *x);
+static void cd4075_bang(t_cd4075 *x);
+static void cd4075_float(t_cd4075 *x, t_float f);
+static void cd4075_inlet2(t_cd4075 *x, t_float f);
+static void cd4075_inlet3(t_cd4075 *x, t_float f);
+static void cd4075_update_outlets(t_cd4075 *x);
+
+static void cd4075_float(t_cd4075 *x, t_float f)
+{
+ if (f == 1) x->x_in1 = 1;
+ else if (f == 0) x->x_in1 = 0;
+ else
+ {
+ post("cd4075 inlet 2 accepts 1 or 0.");
+ return;
+ }
+ cd4075_update_outlets(x);
+}
+
+static void cd4075_bang(t_cd4075 *x)
+{
+ cd4075_update_outlets(x);
+}
+
+static void cd4075_inlet2(t_cd4075 *x, t_float f)
+{
+ if (f == 1) x->x_in2 = 1;
+ else if (f == 0) x->x_in2 = 0;
+ else
+ {
+ post("cd4075 inlet 2 accepts 1 or 0.");
+ return;
+ }
+ cd4075_update_outlets(x);
+}
+
+static void cd4075_inlet3(t_cd4075 *x, t_float f)
+{
+ if (f == 1) x->x_in3 = 1;
+ else if (f == 0) x->x_in3 = 0;
+ else
+ {
+ post("cd4075 inlet 3 accepts 1 or 0.");
+ return;
+ }
+ cd4075_update_outlets(x);
+}
+
+static void cd4075_update_outlets(t_cd4075 *x)
+{ /* Triple OR function */
+ outlet_float(x->x_out, ((x->x_in1 + x->x_in2 + x->x_in3) != 0)?1:0);
+}
+
+static void cd4075_free(t_cd4075 *x)
+{
+ return;
+}
+
+static void *cd4075_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_cd4075 *x;
+
+ x = (t_cd4075 *)pd_new(cd4075_class);
+ if (x == NULL) return (x);
+ x->x_out = outlet_new((t_object *)x, &s_float);
+ x->x_inlet2 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("inlet2"));
+ x->x_inlet3 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("inlet3"));
+ return (x);
+}
+
+void cd4075_setup(void)
+{
+ cd4075_class = class_new(gensym("cd4075"),
+ (t_newmethod)cd4075_new,
+ (t_method)cd4075_free,
+ sizeof(t_cd4075), 0, 0); /* no arguments */
+ class_addbang(cd4075_class, cd4075_bang);
+ class_addfloat(cd4075_class, cd4075_float);
+ class_addmethod(cd4075_class, (t_method)cd4075_inlet2, gensym("inlet2"), A_FLOAT, 0);
+ class_addmethod(cd4075_class, (t_method)cd4075_inlet3, gensym("inlet3"), A_FLOAT, 0);
+}
+/* end cd4075.c */
+
diff --git a/cmos/cd4076.c b/cmos/cd4076.c
new file mode 100755
index 0000000..5edcefc
--- /dev/null
+++ b/cmos/cd4076.c
@@ -0,0 +1,256 @@
+/* cd4076.c MP 20070312 */
+/* Emulate a cd4076b */
+#include "m_pd.h"
+
+typedef struct _cd4076
+{
+ t_object x_obj;
+ t_outlet *x_output_A;
+ t_outlet *x_output_B;
+ t_outlet *x_output_C;
+ t_outlet *x_output_D;
+ t_int x_clock;
+ t_int x_QA;
+ t_int x_QB;
+ t_int x_QC;
+ t_int x_QD;
+ t_int x_inA;
+ t_int x_inB;
+ t_int x_inC;
+ t_int x_inD;
+ t_int x_InDis1;
+ t_int x_InDis2;
+ t_int x_OutDis1;
+ t_int x_OutDis2;
+ t_int x_Clear;
+ t_inlet *x_clear;/* clear takes one or zero as acceptable inputs. */
+ t_inlet *x_input_disable_1;/* input_disable_1 takes one or zero as acceptable inputs. */
+ t_inlet *x_input_disable_2;/* input_disable_2 takes one or zero as acceptable inputs. */
+ t_inlet *x_output_disable_1;/* output_disable_1 takes one or zero as acceptable inputs. */
+ t_inlet *x_output_disable_2;/* output_disable_2 takes one or zero as acceptable inputs. */
+ t_inlet *x_input_A;/* input_A takes one or zero as acceptable inputs. */
+ t_inlet *x_input_B;/* input_B takes one or zero as acceptable inputs. */
+ t_inlet *x_input_C;/* input_C takes one or zero as acceptable inputs. */
+ t_inlet *x_input_D;/* input_D takes one or zero as acceptable inputs. */
+ /* The main inlet (clock) should accept a bang or a one as valid clocks. */
+ /* If a one is received, it must be followed by a zero before the clock will work again. */
+} t_cd4076;
+
+static t_class *cd4076_class;
+
+void cd4076_setup(void);
+static void *cd4076_new(t_symbol *s, int argc, t_atom *argv);
+static void cd4076_free(t_cd4076 *x);
+static void cd4076_bang(t_cd4076 *x);
+static void cd4076_float(t_cd4076 *x, t_float f);
+static void cd4076_clear(t_cd4076 *x, t_float f);
+static void cd4076_input_disable_1(t_cd4076 *x, t_float f);
+static void cd4076_input_disable_2(t_cd4076 *x, t_float f);
+static void cd4076_output_disable_1(t_cd4076 *x, t_float f);
+static void cd4076_output_disable_2(t_cd4076 *x, t_float f);
+static void cd4076_input_a(t_cd4076 *x, t_float f);
+static void cd4076_input_b(t_cd4076 *x, t_float f);
+static void cd4076_input_c(t_cd4076 *x, t_float f);
+static void cd4076_input_d(t_cd4076 *x, t_float f);
+static void cd4076_update_outlets(t_cd4076 *x);
+
+static void cd4076_float(t_cd4076 *x, t_float f)
+{
+ if (f == 1)
+ { /* if clock is high and was low, clock it. */
+ if ((x->x_clock) == 0) cd4076_bang(x);
+ x->x_clock = 1;
+ }
+ else if (f == 0) x->x_clock = 0;
+ else post("cd4076 accepts bang, 1 or 0.");
+}
+
+static void cd4076_bang(t_cd4076 *x)
+{
+ if ((x->x_InDis1 + x->x_InDis2 + x->x_Clear) == 0)
+ {
+ x->x_QA = x->x_inA;
+ x->x_QB = x->x_inB;
+ x->x_QC = x->x_inC;
+ x->x_QD = x->x_inD;
+ }
+ cd4076_update_outlets(x);
+}
+
+static void cd4076_clear(t_cd4076 *x, t_float f)
+{
+ if (f == 1)
+ {
+ x->x_Clear = 1;
+ x->x_QA = 0;
+ x->x_QB = 0;
+ x->x_QC = 0;
+ x->x_QD = 0;
+ cd4076_update_outlets(x);
+ }
+ else if (f == 0)
+ {
+ x->x_Clear = 0;
+ }
+ else
+ {
+ post("cd4076 clear takes 1 or 0 only.");
+ return;
+ }
+}
+
+static void cd4076_input_disable_1(t_cd4076 *x, t_float f)
+{
+ if (f == 1) x->x_InDis1 = 1;
+ else if (f == 0) x->x_InDis1 = 0;
+ else
+ {
+ post("cd4076 input disable 1 takes 1 or 0 only.");
+ return;
+ }
+}
+
+static void cd4076_input_disable_2(t_cd4076 *x, t_float f)
+{
+ if (f == 1) x->x_InDis2 = 1;
+ else if (f == 0) x->x_InDis2 = 0;
+ else
+ {
+ post("cd4076 input disable 2 takes 1 or 0 only.");
+ return;
+ }
+}
+
+static void cd4076_output_disable_1(t_cd4076 *x, t_float f)
+{
+ if (f == 1) x->x_OutDis1 = 1;
+ else if (f == 0)
+ {
+ x->x_OutDis1 = 0;
+ cd4076_update_outlets(x);
+ }
+ else
+ {
+ post("cd4076 output disable 1 takes 1 or 0 only.");
+ return;
+ }
+}
+
+static void cd4076_output_disable_2(t_cd4076 *x, t_float f)
+{
+ if (f == 1) x->x_OutDis2 = 1;
+ else if (f == 0)
+ {
+ x->x_OutDis2 = 0;
+ cd4076_update_outlets(x);
+ }
+ else
+ {
+ post("cd4076 output disable 2 takes 1 or 0 only.");
+ return;
+ }
+}
+
+static void cd4076_input_a(t_cd4076 *x, t_float f)
+{
+ if (f == 1) x->x_inA = 1;
+ else if (f == 0) x->x_inA = 0;
+ else
+ {
+ post("cd4076 input A takes 1 or 0 only.");
+ return;
+ }
+}
+
+static void cd4076_input_b(t_cd4076 *x, t_float f)
+{
+ if (f == 1) x->x_inB = 1;
+ else if (f == 0) x->x_inB = 0;
+ else
+ {
+ post("cd4076 input B takes 1 or 0 only.");
+ return;
+ }
+}
+
+static void cd4076_input_c(t_cd4076 *x, t_float f)
+{
+ if (f == 1) x->x_inC = 1;
+ else if (f == 0) x->x_inC = 0;
+ else
+ {
+ post("cd4076 input C takes 1 or 0 only.");
+ return;
+ }
+}
+
+static void cd4076_input_d(t_cd4076 *x, t_float f)
+{
+ if (f == 1) x->x_inD = 1;
+ else if (f == 0) x->x_inD = 0;
+ else
+ {
+ post("cd4076 input D takes 1 or 0 only.");
+ return;
+ }
+}
+
+static void cd4076_update_outlets(t_cd4076 *x)
+{
+ if (x->x_OutDis1 + x->x_OutDis2 == 0)
+ {
+ outlet_float(x->x_output_D, ((x->x_QD) == 1)?1:0);
+ outlet_float(x->x_output_C, ((x->x_QC) == 1)?1:0);
+ outlet_float(x->x_output_B, ((x->x_QB) == 1)?1:0);
+ outlet_float(x->x_output_A, ((x->x_QA) == 1)?1:0);
+ }
+}
+
+static void cd4076_free(t_cd4076 *x)
+{
+ return;
+}
+
+static void *cd4076_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_cd4076 *x;
+
+ x = (t_cd4076 *)pd_new(cd4076_class);
+ if (x == NULL) return (x);
+ x->x_output_A = outlet_new((t_object *)x, &s_float);
+ x->x_output_B = outlet_new((t_object *)x, &s_float);
+ x->x_output_C = outlet_new((t_object *)x, &s_float);
+ x->x_output_D = outlet_new((t_object *)x, &s_float);
+
+ x->x_clear = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("clear"));
+ x->x_input_disable_1 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("inputdisable1"));
+ x->x_input_disable_2 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("inputdisable2"));
+ x->x_output_disable_1 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("outputdisable1"));
+ x->x_output_disable_2 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("outputdisable2"));
+ x->x_input_A = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("inputA"));
+ x->x_input_B = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("inputB"));
+ x->x_input_C = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("inputC"));
+ x->x_input_D = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("inputD"));
+ return (x);
+}
+
+void cd4076_setup(void)
+{
+ cd4076_class = class_new(gensym("cd4076"),
+ (t_newmethod)cd4076_new,
+ (t_method)cd4076_free,
+ sizeof(t_cd4076), 0, 0); /* no arguments */
+ class_addbang(cd4076_class, cd4076_bang);
+ class_addfloat(cd4076_class, cd4076_float);
+ class_addmethod(cd4076_class, (t_method)cd4076_clear, gensym("clear"), A_FLOAT, 0);
+ class_addmethod(cd4076_class, (t_method)cd4076_input_disable_1, gensym("inputdisable1"), A_FLOAT, 0);
+ class_addmethod(cd4076_class, (t_method)cd4076_input_disable_2, gensym("inputdisable2"), A_FLOAT, 0);
+ class_addmethod(cd4076_class, (t_method)cd4076_output_disable_1, gensym("outputdisable1"), A_FLOAT, 0);
+ class_addmethod(cd4076_class, (t_method)cd4076_output_disable_2, gensym("outputdisable2"), A_FLOAT, 0);
+ class_addmethod(cd4076_class, (t_method)cd4076_input_a, gensym("inputA"), A_FLOAT, 0);
+ class_addmethod(cd4076_class, (t_method)cd4076_input_b, gensym("inputB"), A_FLOAT, 0);
+ class_addmethod(cd4076_class, (t_method)cd4076_input_c, gensym("inputC"), A_FLOAT, 0);
+ class_addmethod(cd4076_class, (t_method)cd4076_input_d, gensym("inputD"), A_FLOAT, 0);
+}
+/* end cd4076.c */
+
diff --git a/cmos/cd4081.c b/cmos/cd4081.c
new file mode 100755
index 0000000..0770bcc
--- /dev/null
+++ b/cmos/cd4081.c
@@ -0,0 +1,85 @@
+/* cd4081.c MP 20070308 */
+/* Emulate a cd4081b */
+#include "m_pd.h"
+
+typedef struct _cd4081
+{
+ t_object x_obj;
+ t_int x_in1;
+ t_int x_in2;
+ t_outlet *x_out;
+ t_inlet *x_inlet2;/* Second inlet is 'live' like the first */
+} t_cd4081;
+
+static t_class *cd4081_class;
+
+void cd4081_setup(void);
+static void *cd4081_new(t_symbol *s, int argc, t_atom *argv);
+static void cd4081_free(t_cd4081 *x);
+static void cd4081_bang(t_cd4081 *x);
+static void cd4081_float(t_cd4081 *x, t_float f);
+static void cd4081_inlet2(t_cd4081 *x, t_float f);
+static void cd4081_update_outlets(t_cd4081 *x);
+
+static void cd4081_float(t_cd4081 *x, t_float f)
+{
+ if (f == 1) x->x_in1 = 1;
+ else if (f == 0) x->x_in1 = 0;
+ else
+ {
+ post("cd4081 inlet 2 accepts 1 or 0.");
+ return;
+ }
+ cd4081_update_outlets(x);
+}
+
+static void cd4081_bang(t_cd4081 *x)
+{
+ cd4081_update_outlets(x);
+}
+
+static void cd4081_inlet2(t_cd4081 *x, t_float f)
+{
+ if (f == 1) x->x_in2 = 1;
+ else if (f == 0) x->x_in2 = 0;
+ else
+ {
+ post("cd4081 inlet 2 accepts 1 or 0.");
+ return;
+ }
+ cd4081_update_outlets(x);
+}
+
+static void cd4081_update_outlets(t_cd4081 *x)
+{ /* AND function */
+ outlet_float(x->x_out, ((x->x_in1 + x->x_in2) == 2)?1:0);
+}
+
+static void cd4081_free(t_cd4081 *x)
+{
+ return;
+}
+
+static void *cd4081_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_cd4081 *x;
+
+ x = (t_cd4081 *)pd_new(cd4081_class);
+ if (x == NULL) return (x);
+ x->x_out = outlet_new((t_object *)x, &s_float);
+ x->x_inlet2 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("inlet2"));
+ return (x);
+}
+
+void cd4081_setup(void)
+{
+ cd4081_class = class_new(gensym("cd4081"),
+ (t_newmethod)cd4081_new,
+ (t_method)cd4081_free,
+ sizeof(t_cd4081), 0, 0); /* no arguments */
+ class_addbang(cd4081_class, cd4081_bang);
+ class_addfloat(cd4081_class, cd4081_float);
+ class_addmethod(cd4081_class, (t_method)cd4081_inlet2, gensym("inlet2"), A_FLOAT, 0);
+}
+/* end cd4081.c */
+
diff --git a/cmos/cd4082.c b/cmos/cd4082.c
new file mode 100755
index 0000000..1ee6f91
--- /dev/null
+++ b/cmos/cd4082.c
@@ -0,0 +1,119 @@
+/* cd4082.c MP 20070312 */
+/* Emulate a cd4082b */
+#include "m_pd.h"
+
+typedef struct _cd4082
+{
+ t_object x_obj;
+ t_int x_in1;
+ t_int x_in2;
+ t_int x_in3;
+ t_int x_in4;
+ t_outlet *x_out;
+ t_inlet *x_inlet2;/* Second inlet is 'live' like the first */
+ t_inlet *x_inlet3;/* Third inlet is 'live' like the first */
+ t_inlet *x_inlet4;/* Fourth inlet is 'live' like the first */
+} t_cd4082;
+
+static t_class *cd4082_class;
+
+void cd4082_setup(void);
+static void *cd4082_new(t_symbol *s, int argc, t_atom *argv);
+static void cd4082_free(t_cd4082 *x);
+static void cd4082_bang(t_cd4082 *x);
+static void cd4082_float(t_cd4082 *x, t_float f);
+static void cd4082_inlet2(t_cd4082 *x, t_float f);
+static void cd4082_inlet3(t_cd4082 *x, t_float f);
+static void cd4082_inlet4(t_cd4082 *x, t_float f);
+static void cd4082_update_outlets(t_cd4082 *x);
+
+static void cd4082_float(t_cd4082 *x, t_float f)
+{
+ if (f == 1) x->x_in1 = 1;
+ else if (f == 0) x->x_in1 = 0;
+ else
+ {
+ post("cd4082 inlet 2 accepts 1 or 0.");
+ return;
+ }
+ cd4082_update_outlets(x);
+}
+
+static void cd4082_bang(t_cd4082 *x)
+{
+ cd4082_update_outlets(x);
+}
+
+static void cd4082_inlet2(t_cd4082 *x, t_float f)
+{
+ if (f == 1) x->x_in2 = 1;
+ else if (f == 0) x->x_in2 = 0;
+ else
+ {
+ post("cd4082 inlet 2 accepts 1 or 0.");
+ return;
+ }
+ cd4082_update_outlets(x);
+}
+
+static void cd4082_inlet3(t_cd4082 *x, t_float f)
+{
+ if (f == 1) x->x_in3 = 1;
+ else if (f == 0) x->x_in3 = 0;
+ else
+ {
+ post("cd4082 inlet 3 accepts 1 or 0.");
+ return;
+ }
+ cd4082_update_outlets(x);
+}
+
+static void cd4082_inlet4(t_cd4082 *x, t_float f)
+{
+ if (f == 1) x->x_in4 = 1;
+ else if (f == 0) x->x_in4 = 0;
+ else
+ {
+ post("cd4082 inlet 4 accepts 1 or 0.");
+ return;
+ }
+ cd4082_update_outlets(x);
+}
+
+static void cd4082_update_outlets(t_cd4082 *x)
+{ /* QUAD AND function */
+ outlet_float(x->x_out, ((x->x_in1 + x->x_in2 + x->x_in3 + x->x_in4) == 4)?1:0);
+}
+
+static void cd4082_free(t_cd4082 *x)
+{
+ return;
+}
+
+static void *cd4082_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_cd4082 *x;
+
+ x = (t_cd4082 *)pd_new(cd4082_class);
+ if (x == NULL) return (x);
+ x->x_out = outlet_new((t_object *)x, &s_float);
+ x->x_inlet2 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("inlet2"));
+ x->x_inlet3 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("inlet3"));
+ x->x_inlet4 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("inlet4"));
+ return (x);
+}
+
+void cd4082_setup(void)
+{
+ cd4082_class = class_new(gensym("cd4082"),
+ (t_newmethod)cd4082_new,
+ (t_method)cd4082_free,
+ sizeof(t_cd4082), 0, 0); /* no arguments */
+ class_addbang(cd4082_class, cd4082_bang);
+ class_addfloat(cd4082_class, cd4082_float);
+ class_addmethod(cd4082_class, (t_method)cd4082_inlet2, gensym("inlet2"), A_FLOAT, 0);
+ class_addmethod(cd4082_class, (t_method)cd4082_inlet3, gensym("inlet3"), A_FLOAT, 0);
+ class_addmethod(cd4082_class, (t_method)cd4082_inlet4, gensym("inlet4"), A_FLOAT, 0);
+}
+/* end cd4082.c */
+
diff --git a/cmos/cd4094.c b/cmos/cd4094.c
new file mode 100755
index 0000000..0d7097a
--- /dev/null
+++ b/cmos/cd4094.c
@@ -0,0 +1,186 @@
+/* cd4094.c MP 20070312 */
+/* Emulate a cd4094b */
+#include "m_pd.h"
+
+typedef struct _cd4094
+{
+ t_object x_obj;
+ t_outlet *x_Q1Out;
+ t_outlet *x_Q2Out;
+ t_outlet *x_Q3Out;
+ t_outlet *x_Q4Out;
+ t_outlet *x_Q5Out;
+ t_outlet *x_Q6Out;
+ t_outlet *x_Q7Out;
+ t_outlet *x_Q8Out;
+ t_outlet *x_QSOut;
+ t_outlet *x_QprimeSOut;
+ t_int x_clock;
+ t_int x_data;
+ t_int x_data_in;
+ t_int x_strobe;
+ t_int x_output_enable;
+ t_int x_qprime;
+ t_inlet *x_StrobeIn;/* Strobe takes one or zero as acceptable inputs. */
+ t_inlet *x_DataIn;/* Data takes one or zero as acceptable inputs. */
+ t_inlet *x_OutputEnable;/* Output Enable takes one or zero as acceptable inputs. */
+ /* The main inlet (clock) should accept a bang or a one as valid clocks. */
+ /* If a one is received, it must be followed by a zero before the clock will work again. */
+} t_cd4094;
+
+static t_class *cd4094_class;
+
+void cd4094_setup(void);
+static void *cd4094_new(t_symbol *s, int argc, t_atom *argv);
+static void cd4094_free(t_cd4094 *x);
+static void cd4094_bang(t_cd4094 *x);
+static void cd4094_float(t_cd4094 *x, t_float f);
+static void cd4094_strobe(t_cd4094 *x, t_float f);
+static void cd4094_data(t_cd4094 *x, t_float f);
+static void cd4094_output_enable(t_cd4094 *x, t_float f);
+static void cd4094_update_outlets(t_cd4094 *x);
+
+static void cd4094_float(t_cd4094 *x, t_float f)
+{
+ if (f == 1)
+ { /* if clock is high and was low, clock it. */
+ if ((x->x_clock == 0)&&(x->x_strobe == 1))
+ {
+ x->x_data <<= 1;
+ if (x->x_data_in != 0) x->x_data |= 1;
+ cd4094_update_outlets(x);
+ }
+ x->x_clock = 1;
+ }
+ else if (f == 0)
+ {
+ if (x->x_clock == 1) /* if clock was high and is low, clock Q prime. */
+ {
+ x->x_qprime = ((x->x_data & 256) != 0)?1:0;
+ outlet_float(x->x_QprimeSOut, x->x_qprime);
+ }
+ x->x_clock = 0;
+ }
+ else post("cd4094 accepts bang, 1 or 0.");
+}
+
+static void cd4094_bang(t_cd4094 *x)
+{
+ if (x->x_strobe == 1)
+ {
+ /* rising edge clock */
+ x->x_data <<= 1;
+ if (x->x_data_in != 0) x->x_data |= 1;
+ cd4094_update_outlets(x);
+ /* Q'7 is clocked on a falling edge */
+ x->x_qprime = ((x->x_data & 256) != 0)?1:0;
+ outlet_float(x->x_QprimeSOut, x->x_qprime);
+ }
+}
+
+static void cd4094_strobe(t_cd4094 *x, t_float f)
+{
+ if (f == 1)
+ {
+ x->x_strobe = 1;
+ }
+ else if (f == 0)
+ {
+ x->x_strobe = 0;
+ }
+ else
+ {
+ post("cd4094 strobe takes 1 or 0 only.");
+ return;
+ }
+}
+
+static void cd4094_output_enable(t_cd4094 *x, t_float f)
+{
+ if (f == 1)
+ {
+ x->x_output_enable = 1;
+ cd4094_update_outlets(x);
+ }
+ else if (f == 0)
+ {
+ x->x_output_enable = 0;
+ }
+ else
+ {
+ post("cd4094 output enable takes 1 or 0 only.");
+ return;
+ }
+}
+
+static void cd4094_data(t_cd4094 *x, t_float f)
+{
+ if (f == 1) x->x_data_in = 1;
+ else if (f == 0) x->x_data_in = 0;
+ else
+ {
+ post("cd4094 data takes 1 or 0 only.");
+ return;
+ }
+}
+
+static void cd4094_update_outlets(t_cd4094 *x)
+{
+ outlet_float(x->x_QprimeSOut, ((x->x_qprime) != 0)?1:0);
+ outlet_float(x->x_QSOut, ((x->x_data & 256) != 0)?1:0);
+ if (x->x_output_enable != 0)
+ {
+ outlet_float(x->x_QSOut, ((x->x_data & 256) != 0)?1:0);
+ outlet_float(x->x_Q8Out, ((x->x_data & 128) != 0)?1:0);
+ outlet_float(x->x_Q7Out, ((x->x_data & 64) != 0)?1:0);
+ outlet_float(x->x_Q6Out, ((x->x_data & 32) != 0)?1:0);
+ outlet_float(x->x_Q5Out, ((x->x_data & 16) != 0)?1:0);
+ outlet_float(x->x_Q4Out, ((x->x_data & 8) != 0)?1:0);
+ outlet_float(x->x_Q3Out, ((x->x_data & 4) != 0)?1:0);
+ outlet_float(x->x_Q2Out, ((x->x_data & 2) != 0)?1:0);
+ outlet_float(x->x_Q1Out, ((x->x_data & 1) != 0)?1:0);
+ }
+}
+
+static void cd4094_free(t_cd4094 *x)
+{
+ return;
+}
+
+static void *cd4094_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_cd4094 *x;
+
+ x = (t_cd4094 *)pd_new(cd4094_class);
+ if (x == NULL) return (x);
+ x->x_Q1Out = outlet_new((t_object *)x, &s_float);
+ x->x_Q2Out = outlet_new((t_object *)x, &s_float);
+ x->x_Q3Out = outlet_new((t_object *)x, &s_float);
+ x->x_Q4Out = outlet_new((t_object *)x, &s_float);
+ x->x_Q5Out = outlet_new((t_object *)x, &s_float);
+ x->x_Q6Out = outlet_new((t_object *)x, &s_float);
+ x->x_Q7Out = outlet_new((t_object *)x, &s_float);
+ x->x_Q8Out = outlet_new((t_object *)x, &s_float);
+ x->x_QSOut = outlet_new((t_object *)x, &s_float);
+ x->x_QprimeSOut = outlet_new((t_object *)x, &s_float);
+
+ x->x_StrobeIn = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("strobe"));
+ x->x_DataIn = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("data"));
+ x->x_OutputEnable = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("enableoutput"));
+ return (x);
+}
+
+void cd4094_setup(void)
+{
+ cd4094_class = class_new(gensym("cd4094"),
+ (t_newmethod)cd4094_new,
+ (t_method)cd4094_free,
+ sizeof(t_cd4094), 0, 0); /* no arguments */
+ class_addbang(cd4094_class, cd4094_bang);
+ class_addfloat(cd4094_class, cd4094_float);
+ class_addmethod(cd4094_class, (t_method)cd4094_strobe, gensym("strobe"), A_FLOAT, 0);
+ class_addmethod(cd4094_class, (t_method)cd4094_data, gensym("data"), A_FLOAT, 0);
+ class_addmethod(cd4094_class, (t_method)cd4094_output_enable, gensym("enableoutput"), A_FLOAT, 0);
+}
+/* end cd4094.c */
+
diff --git a/cmos/cd4516.c b/cmos/cd4516.c
new file mode 100755
index 0000000..2949dcf
--- /dev/null
+++ b/cmos/cd4516.c
@@ -0,0 +1,256 @@
+/* cd4516.c MP 20070312 */
+/* Emulate a cd4516b */
+#include "m_pd.h"
+
+typedef struct _cd4516
+{
+ t_object x_obj;
+ t_outlet *x_Q1Out;
+ t_outlet *x_Q2Out;
+ t_outlet *x_Q3Out;
+ t_outlet *x_Q4Out;
+ t_outlet *x_CarryOut;
+ t_int x_clock;
+ t_int x_upDown;
+ t_int x_preset_enable;
+ t_int x_carry;
+ t_int x_P1;
+ t_int x_P2;
+ t_int x_P3;
+ t_int x_P4;
+ t_int x_reset;
+ t_int x_count;
+ t_inlet *x_UpDownIn;/* All inlets take one or zero as acceptable inputs. */
+ t_inlet *x_ResetIn;
+ t_inlet *x_PresetEnableIn;
+ t_inlet *x_CarryIn;
+ t_inlet *x_P1In;
+ t_inlet *x_P2In;
+ t_inlet *x_P3In;
+ t_inlet *x_P4In;
+ /* The main inlet (clock) should accept a bang or a one as valid clocks. */
+ /* If a one is received, it must be followed by a zero before the clock will work again. */
+} t_cd4516;
+
+static t_class *cd4516_class;
+
+void cd4516_setup(void);
+static void *cd4516_new(t_symbol *s, int argc, t_atom *argv);
+static void cd4516_free(t_cd4516 *x);
+static void cd4516_bang(t_cd4516 *x);
+static void cd4516_float(t_cd4516 *x, t_float f);
+static void cd4516_reset(t_cd4516 *x, t_float f);
+static void cd4516_preset_enable(t_cd4516 *x, t_float f);
+static void cd4516_up_down(t_cd4516 *x, t_float f);
+static void cd4516_carry(t_cd4516 *x, t_float f);
+static void cd4516_P1(t_cd4516 *x, t_float f);
+static void cd4516_P2(t_cd4516 *x, t_float f);
+static void cd4516_P3(t_cd4516 *x, t_float f);
+static void cd4516_P4(t_cd4516 *x, t_float f);
+static void cd4516_update_outlets(t_cd4516 *x);
+
+static void cd4516_float(t_cd4516 *x, t_float f)
+{
+ if (f == 1)
+ { /* if clock is high and was low, count up. */
+ if ((x->x_clock == 0)&&(x->x_reset == 0)&&(x->x_preset_enable == 0)&&(x->x_carry == 0))
+ {
+ x->x_clock = 1;
+ if (x->x_upDown == 1) x->x_count = (x->x_count + 1)%16;
+ else x->x_count = (x->x_count - 1)%16;
+ cd4516_update_outlets(x);
+ }
+ }
+ else if (f == 0)
+ {
+ x->x_clock = 0;
+ }
+ else post("cd4516 accepts bang, 1 or 0.");
+}
+
+static void cd4516_bang(t_cd4516 *x)
+{
+ if ((x->x_reset == 0)&&(x->x_preset_enable == 0)&&(x->x_carry == 0))
+ {
+ if (x->x_upDown == 1)x->x_count = (x->x_count + 1)%16;
+ else x->x_count = (x->x_count - 1)%16;
+ cd4516_update_outlets(x);
+ }
+}
+
+static void cd4516_reset(t_cd4516 *x, t_float f)
+{
+ if (f == 1)
+ {
+ if (x->x_reset == 0)
+ {
+ x->x_count = 0;
+ cd4516_update_outlets(x);
+ x->x_reset = 1;
+ }
+ }
+ else if (f == 0)
+ {
+ x->x_reset = 0;
+ if (x->x_preset_enable == 1)
+ { /* the strange case of a low-going reset enabling an already high preset enable */
+ x->x_count = x->x_P1 + 2*x->x_P2 + 4*x->x_P3 + 8*x->x_P4;
+ cd4516_update_outlets(x);
+ }
+ }
+ else
+ {
+ post("cd4516 reset takes 1 or 0 only.");
+ return;
+ }
+}
+
+static void cd4516_preset_enable(t_cd4516 *x, t_float f)
+{
+ if (f == 0)
+ {
+ x->x_preset_enable = 0;
+ }
+ else if (f == 1)
+ {
+ if (x->x_preset_enable == 0)
+ {
+ x->x_preset_enable = 1;
+ if (x->x_reset == 0)
+ {
+ x->x_count = x->x_P1 + 2*x->x_P2 + 4*x->x_P3 + 8*x->x_P4;
+ cd4516_update_outlets(x);
+ }
+ }
+ }
+ else
+ {
+ post("cd4516 x_preset_enable takes 1 or 0 only.");
+ return;
+ }
+}
+
+static void cd4516_up_down(t_cd4516 *x, t_float f)
+{
+ if (f == 1)
+ {
+ x->x_upDown = 1;
+ }
+ else if (f == 0)
+ {
+ x->x_upDown = 0;
+ }
+ else post("cd4516 updown accepts bang, 1 or 0.");
+}
+
+static void cd4516_carry(t_cd4516 *x, t_float f)
+{
+ if (f == 1)
+ {
+ x->x_carry = 1;
+ }
+ else if (f == 0)
+ {
+ x->x_carry = 0;
+ }
+ else post("cd4516 carry accepts bang, 1 or 0.");
+}
+
+static void cd4516_P1(t_cd4516 *x, t_float f)
+{
+ if (f == 1) x->x_P1 = 1;
+ else if (f == 0) x->x_P1 = 0;
+ else
+ {
+ post("cd4516 P1 takes 1 or 0 only.");
+ return;
+ }
+}
+static void cd4516_P2(t_cd4516 *x, t_float f)
+{
+ if (f == 1) x->x_P2 = 1;
+ else if (f == 0) x->x_P2 = 0;
+ else
+ {
+ post("cd4516 P2 takes 1 or 0 only.");
+ return;
+ }
+}
+static void cd4516_P3(t_cd4516 *x, t_float f)
+{
+ if (f == 1) x->x_P3 = 1;
+ else if (f == 0) x->x_P3 = 0;
+ else
+ {
+ post("cd4516 P3 takes 1 or 0 only.");
+ return;
+ }
+}
+static void cd4516_P4(t_cd4516 *x, t_float f)
+{
+ if (f == 1) x->x_P4 = 1;
+ else if (f == 0) x->x_P4 = 0;
+ else
+ {
+ post("cd4516 P4 takes 1 or 0 only.");
+ return;
+ }
+}
+
+static void cd4516_update_outlets(t_cd4516 *x)
+{
+ if (x->x_upDown == 1) outlet_float(x->x_CarryOut, (x->x_count == 15)?0:1);
+ else outlet_float(x->x_CarryOut, (x->x_count == 0)?0:1);
+ outlet_float(x->x_Q4Out, ((x->x_count & 8) != 0)?1:0);
+ outlet_float(x->x_Q3Out, ((x->x_count & 4) != 0)?1:0);
+ outlet_float(x->x_Q2Out, ((x->x_count & 2) != 0)?1:0);
+ outlet_float(x->x_Q1Out, ((x->x_count & 1) != 0)?1:0);
+}
+
+static void cd4516_free(t_cd4516 *x)
+{
+ return;
+}
+
+static void *cd4516_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_cd4516 *x;
+
+ x = (t_cd4516 *)pd_new(cd4516_class);
+ if (x == NULL) return (x);
+ x->x_Q1Out = outlet_new((t_object *)x, &s_float);
+ x->x_Q2Out = outlet_new((t_object *)x, &s_float);
+ x->x_Q3Out = outlet_new((t_object *)x, &s_float);
+ x->x_Q4Out = outlet_new((t_object *)x, &s_float);
+ x->x_CarryOut = outlet_new((t_object *)x, &s_float);
+
+ x->x_UpDownIn = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("updown"));
+ x->x_ResetIn = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("reset"));
+ x->x_PresetEnableIn = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("presetenable"));
+ x->x_CarryIn = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("carry"));
+ x->x_P1In = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("P1"));
+ x->x_P2In = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("P2"));
+ x->x_P3In = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("P3"));
+ x->x_P4In = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("P4"));
+ return (x);
+}
+
+void cd4516_setup(void)
+{
+ cd4516_class = class_new(gensym("cd4516"),
+ (t_newmethod)cd4516_new,
+ (t_method)cd4516_free,
+ sizeof(t_cd4516), 0, 0); /* no arguments */
+ class_addbang(cd4516_class, cd4516_bang);
+ class_addfloat(cd4516_class, cd4516_float);
+ class_addmethod(cd4516_class, (t_method)cd4516_up_down, gensym("updown"), A_FLOAT, 0);
+ class_addmethod(cd4516_class, (t_method)cd4516_preset_enable, gensym("presetenable"), A_FLOAT, 0);
+ class_addmethod(cd4516_class, (t_method)cd4516_reset, gensym("reset"), A_FLOAT, 0);
+ class_addmethod(cd4516_class, (t_method)cd4516_carry, gensym("carry"), A_FLOAT, 0);
+ class_addmethod(cd4516_class, (t_method)cd4516_P1, gensym("P1"), A_FLOAT, 0);
+ class_addmethod(cd4516_class, (t_method)cd4516_P2, gensym("P2"), A_FLOAT, 0);
+ class_addmethod(cd4516_class, (t_method)cd4516_P3, gensym("P3"), A_FLOAT, 0);
+ class_addmethod(cd4516_class, (t_method)cd4516_P4, gensym("P4"), A_FLOAT, 0);
+}
+/* end cd4516.c */
+