aboutsummaryrefslogtreecommitdiff
path: root/cmos/cd4014.c
diff options
context:
space:
mode:
Diffstat (limited to 'cmos/cd4014.c')
-rwxr-xr-xcmos/cd4014.c251
1 files changed, 251 insertions, 0 deletions
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 */
+