From: ian Date: Sun, 1 Jan 2006 15:21:56 +0000 (+0000) Subject: wip hostside found on liberator X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ijackson/git?a=commitdiff_plain;h=4ae80e06648798a515dde92fa562a8ab5e93d0df;p=trains.git wip hostside found on liberator --- diff --git a/hostside/hostside.c b/hostside/hostside.c index 6b92d86..8127a35 100644 --- a/hostside/hostside.c +++ b/hostside/hostside.c @@ -8,6 +8,7 @@ #include "../layout/dlist.h" #include "hostside.h" +#include "auproto-pic.h" oop_source *events; FILE *dump_stream= 0; @@ -20,12 +21,88 @@ static OutBufferChain serial_ochain= { (char*)"serial", -1, serial_error }; static void *serial_exception(oop_source *evts, int fd, oop_event evt, void *cl_v) { - die("serial port - exception"); + char bufc; + int r; + + r= read(serial_fd, &bufc, 1); + if (r==-1) diee("serial port - exception"); + else if (r==0) die("serial port - exception, reads EOF"); + else die("serial port - exception but readable"); +} + +static int serial_buf_used; +static PicInsn serial_buf; + +void oopicio(const char *dirn, const PicInsnInfo *pii, int objnum) { + if (!pii->argbits) + ooprintf(sel_picio, "picio %s %s\n", dirn, pii->name); + else + ooprintf(sel_picio, "picio %s %s %u\n", dirn, pii->name, objnum); +} + +static void serial_incoming(const PicInsn *pi) { + const PicInsnInfo *pii; + int objnum; + + output_hex(sel_picioh, "picioh in", pi->d, pi->l); + picinsn_decode(pi, pic_reply_infos, &pii, &objnum); + + if (pii) { + oopicio("in",pii,objnum); + pii->input_fn(pii,pi,objnum); + } else { + Byte byte0; + + assert(pi->l); + byte0= pi->d[0]; + + if ((byte0 & 0xc0) == 0x40 || + (byte0 & 0xe0) == 0x20) { + ooprintf(sel_picdebug, "picdebug `%c'", byte0); + } else if (byte0 == 0x0a) { + ooprintf(sel_picdebug, "picdebug newline"); + } else { + ooprintf(sel_picio, "picio in unknown\n"); + return; + } + if (picdebug_copy) { + if (fputc(byte0, picdebug_copy) == EOF) + diee("picdebug stream write"); + } + } } static void *serial_readable(oop_source *evts, int fd, oop_event evt, void *u0) { - events->cancel_fd(events, serial_fd, OOP_READ); + const Byte *ep; + int r; + + r= read(serial_fd, &serial_buf.d, sizeof(serial_buf.d) - serial_buf_used); + if (r==0) die("serial port - eof"); + if (r==-1) { + if (errno == EWOULDBLOCK || errno == EINTR) + return OOP_CONTINUE; + diee("serial port - read error"); + } + serial_buf_used += r; + + for (;;) { + for (serial_buf.l= 0, ep= serial_buf.d; + serial_buf.l < serial_buf_used; + serial_buf.l++, ep++) + if (!(*ep & 0x80u)) + goto found_end; + + assert(serial_buf.l == serial_buf_used); + if (serial_buf.l == sizeof(serial_buf.d)) + die("serial port - packet too long"); + break; + + found_end: + serial_incoming(&serial_buf); + serial_buf_used -= serial_buf.l; + memmove(serial_buf.d, serial_buf.d + serial_buf.l, serial_buf_used); + } return OOP_CONTINUE; } diff --git a/hostside/hostside.h b/hostside/hostside.h index db981f5..f47d0ea 100644 --- a/hostside/hostside.h +++ b/hostside/hostside.h @@ -67,6 +67,7 @@ struct OrdinaryPicMessage { /*---------- from hostside.c ----------*/ extern oop_source *events; +extern FILE *picdebug_copy; /*---------- from client.c ----------*/ diff --git a/hostside/output.c b/hostside/output.c index b432222..72c044a 100644 --- a/hostside/output.c +++ b/hostside/output.c @@ -43,27 +43,14 @@ void output_hex(Selector sel, const char *word, void serial_transmit(const PicInsn *pi) { const PicInsnInfo *pii; - unsigned val; - - pii= pi->l > 0 ? lookup_byopcode(pi->d[0], pic_command_infos) : 0; - - if (pii) { - val= pi->d[0]; - if (pii->argbits <= 6) { - if (pi->l != 1) pii= 0; - } else { - if (pi->l == 2) { val <<= 8; val |= pi->d[1]; } - else pii= 0; - } - } + int objnum; + + picinsn_decode(pi, pic_command_infos, &pii, &objnum); if (!pii) ooprintf(sel_picio, "picio out unknown\n"); - else if (!pii->argbits) - ooprintf(sel_picio, "picio out %s\n", pii->name); else - ooprintf(sel_picio, "picio out %s %u\n", pii->name, - val & ((1u << pii->argbits) - 1)); + oopicio("out",pii,objnum); output_hex(sel_picioh, "picioh out", pi->d, pi->l); serial_transmit_now(pi->d, pi->l); diff --git a/hostside/selectors.h.gen b/hostside/selectors.h.gen index ec5dbb7..a997298 100755 --- a/hostside/selectors.h.gen +++ b/hostside/selectors.h.gen @@ -1,8 +1,10 @@ #!/usr/bin/perl $bit= 1; +printf "/* autogenerated - do not edit */\n" or die $!; foreach $f (qw( picio picioh + picdebug )) { printf "#define sel_%-10s 0x%08lxLU\n", $f, $bit; $bit <<= 1; diff --git a/hostside/skelproto-pic.c b/hostside/skelproto-pic.c index 5e2339c..d4403e4 100644 --- a/hostside/skelproto-pic.c +++ b/hostside/skelproto-pic.c @@ -24,12 +24,6 @@ extern void enco_pic_anyinsn(PicInsn *out, const PicInsnInfo *pii, out->d[0] |= pii->opcode; } -#if 0 -const char *pi_getarg(const PicInsn *pi, const PicInsnInfo *pi, long *a_r) { - -const PicInsn *pi, long *arg_o, -#endif - const PicInsnInfo *lookup_byopcode(Byte byte0, const PicInsnInfo *table) { const PicInsnInfo *pi; for (pi= table; @@ -40,12 +34,33 @@ const PicInsnInfo *lookup_byopcode(Byte byte0, const PicInsnInfo *table) { return 0; } +void picinsn_decode(const PicInsn *pi, const PicInsnInfo *table, + const PicInsnInfo **pii_r, int *objnum_r) { + const PicInsnInfo *pii; + unsigned val= 0; + + pii= pi->l > 0 ? lookup_byopcode(pi->d[0], table) : 0; + + if (pii) { + val= pi->d[0]; + if (pii->argbits <= 6) { + if (pi->l != 1) pii= 0; + } else { + if (pi->l == 2) { val <<= 8; val |= pi->d[1]; } + else pii= 0; + } + } + + *pii_r= pii; + if (objnum_r) *objnum_r= val & ((1u << pii->argbits) - 1); +} + const PicInsnInfo pic_command_infos[]= { - { "@cnameyn@", @opcodeyn@, @opcodemaskyn@, @arglen@ }, @h2p@ + { "@cnameyn@", @opcodeyn@, @opcodemaskyn@, @arglen@, 0 }, @h2p@ { 0 } }; const PicInsnInfo pic_reply_infos[]= { - { "@cnameyn@", @opcodeyn@, @opcodemaskyn@, @arglen@ }, @p2h@ + { "@cnameyn@", @opcodeyn@, @opcodemaskyn@, @arglen@, on_pic_@cnameyn@ },@p2h@ { 0 } }; diff --git a/hostside/skelproto-pic.h b/hostside/skelproto-pic.h index e42b48c..d2e9036 100644 --- a/hostside/skelproto-pic.h +++ b/hostside/skelproto-pic.h @@ -11,25 +11,27 @@ #define AUPROTO_PIC_H typedef struct PicInsnInfo PicInsnInfo; +typedef void PicInputFn(const PicInsnInfo *pii, const PicInsn *pi, int objnum); void enco_pic_@cname@(PicInsn *out); @h2p@ @arglentf=0@ void enco_pic_@cname@(PicInsn *out, int objum); @h2p@ @arglentf=1@ - -void on_pic_@cnameyn@(void); @p2h@ @arglentf=0@ -void on_pic_@cnameyn@(int objnum); @p2h@ @arglentf=1@ +PicInputFn on_pic_@cnameyn@; @p2h@ extern void enco_pic_polarity_begin(PicInsn *out); extern void enco_pic_polarity_setbit(PicInsn *out, int objnum); -extern void on_pic_debug(int ch); extern void enco_pic_anyinsn(PicInsn *out, const PicInsnInfo *pii, int objnum); const PicInsnInfo *lookup_byopcode(Byte byte0, const PicInsnInfo *table); +void picinsn_decode(const PicInsn *pi, const PicInsnInfo *table, + const PicInsnInfo **pii_r, int *objnum_r); +void oopicio(const char *dirn, const PicInsnInfo *pii, int objnum); struct PicInsnInfo { const char *name; Byte opcode, mask; int argbits; + PicInputFn *input_fn; }; extern const PicInsnInfo pic_command_infos[], pic_reply_infos[];