#include "../layout/dlist.h"
#include "hostside.h"
+#include "auproto-pic.h"
oop_source *events;
FILE *dump_stream= 0;
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;
}
/*---------- from hostside.c ----------*/
extern oop_source *events;
+extern FILE *picdebug_copy;
/*---------- from client.c ----------*/
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);
#!/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;
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;
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 }
};
#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[];