diff options
Diffstat (limited to 'cmos/cd4014.c')
-rwxr-xr-x | cmos/cd4014.c | 251 |
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 */ + |