From 8a36990c0305ea2effba5e869351b902ecb429b0 Mon Sep 17 00:00:00 2001 From: Martin Peach Date: Tue, 20 Mar 2007 16:06:17 +0000 Subject: CMOS digital logic emulation objects svn path=/trunk/externals/mrpeach/; revision=7509 --- cmos/cd4000.c | 102 +++++++++++++++++++++++ cmos/cd4001.c | 85 +++++++++++++++++++ cmos/cd4002.c | 119 +++++++++++++++++++++++++++ cmos/cd4008.c | 212 +++++++++++++++++++++++++++++++++++++++++++++++ cmos/cd4011.c | 85 +++++++++++++++++++ cmos/cd4012.c | 119 +++++++++++++++++++++++++++ cmos/cd4013.c | 183 +++++++++++++++++++++++++++++++++++++++++ cmos/cd4014.c | 251 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ cmos/cd4015.c | 126 ++++++++++++++++++++++++++++ cmos/cd4017.c | 152 ++++++++++++++++++++++++++++++++++ cmos/cd40193.c | 250 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ cmos/cd4023.c | 102 +++++++++++++++++++++++ cmos/cd4024.c | 125 ++++++++++++++++++++++++++++ cmos/cd4025.c | 102 +++++++++++++++++++++++ cmos/cd4027.c | 210 ++++++++++++++++++++++++++++++++++++++++++++++ cmos/cd4070.c | 85 +++++++++++++++++++ cmos/cd4071.c | 85 +++++++++++++++++++ cmos/cd4072.c | 119 +++++++++++++++++++++++++++ cmos/cd4073.c | 102 +++++++++++++++++++++++ cmos/cd4075.c | 102 +++++++++++++++++++++++ cmos/cd4076.c | 256 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ cmos/cd4081.c | 85 +++++++++++++++++++ cmos/cd4082.c | 119 +++++++++++++++++++++++++++ cmos/cd4094.c | 186 +++++++++++++++++++++++++++++++++++++++++ cmos/cd4516.c | 256 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 25 files changed, 3618 insertions(+) create mode 100755 cmos/cd4000.c create mode 100755 cmos/cd4001.c create mode 100755 cmos/cd4002.c create mode 100755 cmos/cd4008.c create mode 100755 cmos/cd4011.c create mode 100755 cmos/cd4012.c create mode 100755 cmos/cd4013.c create mode 100755 cmos/cd4014.c create mode 100755 cmos/cd4015.c create mode 100755 cmos/cd4017.c create mode 100755 cmos/cd40193.c create mode 100755 cmos/cd4023.c create mode 100755 cmos/cd4024.c create mode 100755 cmos/cd4025.c create mode 100755 cmos/cd4027.c create mode 100755 cmos/cd4070.c create mode 100755 cmos/cd4071.c create mode 100755 cmos/cd4072.c create mode 100755 cmos/cd4073.c create mode 100755 cmos/cd4075.c create mode 100755 cmos/cd4076.c create mode 100755 cmos/cd4081.c create mode 100755 cmos/cd4082.c create mode 100755 cmos/cd4094.c create mode 100755 cmos/cd4516.c 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 */ + -- cgit v1.2.1