From d2eec74a4d8c21aad495ba61539486b24d7ab8dc Mon Sep 17 00:00:00 2001 From: Guenter Geiger Date: Wed, 9 Oct 2002 10:19:04 +0000 Subject: moved from zexy/zexy to zexy svn path=/trunk/externals/zexy/; revision=169 --- src/z_lp.c | 132 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 src/z_lp.c (limited to 'src/z_lp.c') diff --git a/src/z_lp.c b/src/z_lp.c new file mode 100644 index 0000000..c9dba09 --- /dev/null +++ b/src/z_lp.c @@ -0,0 +1,132 @@ + /* + (c) 2005:forum::für::umläute:2000 + + write to the parallel port + extended to write to any port (if we do have permissions) + +*/ +#define BASE0 0x3bc +#define BASE1 0x378 +#define BASE2 0x278 + +#define MODE_IOPERM 1 +#define MODE_IOPL 0 + +#include "zexy.h" + +#include +#include + +/* ----------------------- lp --------------------- */ + +static int count_iopl = 0; + +static t_class *lp_class; + +typedef struct _lp +{ + t_object x_obj; + + unsigned long port; + + int mode; // MODE_IOPERM, MODE_IOPL +} t_lp; + +static void lp_float(t_lp *x, t_floatarg f) +{ + if (x->port) { + unsigned char b = f; + outb(b, x->port); + } +} + +static void *lp_new(t_symbol *s, int argc, t_atom *argv) +{ + t_lp *x = (t_lp *)pd_new(lp_class); + + x->port = 0; + + if ((argc==0)||(argv->a_type==A_FLOAT)) { + /* FLOAT specifies a parallel port */ + switch ((int)((argc)?atom_getfloat(argv):0)) { + case 0: + x->port = BASE0; + break; + case 1: + x->port = BASE1; + break; + case 2: + x->port = BASE2; + break; + default: + error("lp : only lp0, lp1 and lp2 are accessible"); + x->port = 0; + return (x); + } + } else { + /* SYMBOL might be a file or a hex port-number; + we ignore the file (device) case by now; + LATER think about this + */ + x->port=strtol(atom_getsymbol(argv)->s_name, 0, 16); + } + + if (!x->port || x->port>65535){ + post("lp : bad port %x", x->port); + x->port = 0; + return (x); + } + + if (x->port && x->port < 0x400){ + if (ioperm(x->port, 8, 1)) { + error("lp : couldn't get write permissions"); + x->port = 0; + return (x); + } + x->mode = MODE_IOPERM; + } else { + if (iopl(3)){ + error("lp : couldn't get write permissions"); + x->port = 0; + return (x); + } + x->mode=MODE_IOPL; + count_iopl++; + post("iopl.............................%d", count_iopl); + } + + post("connected to port %x in mode '%s'", x->port, (x->mode==MODE_IOPL)?"iopl":"ioperm"); + if (x->mode==MODE_IOPL)post("warning: this might seriously damage your pc..."); + + return (x); +} + +static void lp_free(t_lp *x) +{ + if (x->port) { + if (x->mode==MODE_IOPERM && ioperm(x->port, 8, 0)) error("lp: couldn't clean up device"); + else if (x->mode==MODE_IOPL && (!--count_iopl) && iopl(0)) + error("lp: couldn't clean up device"); + } +} + + +static void helper(t_lp *x) +{ + post("\n%c lp :: direct access to the parallel port", HEARTSYMBOL); + post("\t: write byte to the parallel-port"); + post("\ncreation:\t\"lp []\": connect to parallel port (0..2)"); + post("\t\t\"lp \": connect to port @ (hex)"); +} + +void z_lp_setup(void) +{ + lp_class = class_new(gensym("lp"), + (t_newmethod)lp_new, (t_method)lp_free, + sizeof(t_lp), 0, A_GIMME, 0); + + class_addfloat(lp_class, (t_method)lp_float); + + class_addmethod(lp_class, (t_method)helper, gensym("help"), 0); + class_sethelpsymbol(lp_class, gensym("zexy/lp")); +} -- cgit v1.2.1