/* @skeleton@ @1@ @L@ */
/*
- * arranges for the declarations of
+ * definitions of
* enco_pic_WHATEVER
- * onrecv_pic_WHATEVER
+ * on_pic_WHATEVER
* and the tables
+ * and related functions
*/
-#include "hostside.h"
+#include <assert.h>
+
+#include "common.h"
#include "auproto-pic.h"
-extern void enco_pic_anyinsn(PicInsn *out, const PicInsnInfo *pii,
- int objnum) {
- unsigned long as= objnum;
+static void enco_pic_any(PicInsn *out, int opcode, int argsbits, int argsval) {
+ unsigned long as= argsval;
int i;
- out->l= 1 + pii->argbits/7;
+ assert(!(as & (~0UL << argsbits)));
+ out->l= 1 + argsbits/7;
for (i= out->l - 1;
i >= 0;
i--, as >>= 7)
out->d[i]= (as & 0x07fUL) | 0x080UL;
out->d[out->l - 1] &= ~0x080UL;
- out->d[0] |= pii->opcode;
+ out->d[0] |= opcode;
+}
+
+static void enco_pic_anyobjv(PicInsn *out, int opcode, int argsbits, int vbits,
+ int obj, int v) {
+ assert((unsigned)v < (1u << vbits));
+ enco_pic_any(out, opcode, argsbits, obj << vbits | v);
+}
+
+#define C ,
+
+#define ENCO(w, xa, opcode, argsbits, obj) \
+ extern void enco_pic_##w(PicInsn *out xa) { \
+ enco_pic_any(out, opcode, argsbits, obj); \
+ }
+
+#define ENCO2A(w, opcode, argsbits, vbits) \
+ extern void enco_pic_##w(PicInsn *out, int obj, int v) { \
+ enco_pic_anyobjv(out, opcode, argsbits, vbits, obj, v); \
+ }
+
+ENCO(@cnameyn@, , @opcodeyn@, 0, 0) @h2p@ @nargs=0@
+ENCO(@cnameyn@, C int obj, @opcodeyn@, @arglen@, obj) @h2p@ @nargs=1@
+ENCO2A(@cnameyn@, @opcodeyn@, @argslen@, @vlen@) @h2p@ @nargs=2@
+
+extern void enco_pic_pii(PicInsn *out, const PicInsnInfo *pii,
+ int obj, int v) {
+ enco_pic_anyobjv(out, pii->opcode, pii->argsbits, pii->vbits, obj, v);
+}
+
+const PicInsnInfo *lookup_byopcode(Byte byte0, const PicInsnInfo *table) {
+ const PicInsnInfo *pi;
+ for (pi= table;
+ pi->name;
+ pi++)
+ if ((byte0 & pi->mask) == pi->opcode)
+ return pi;
+ return 0;
+}
+
+void picinsn_decode(const PicInsn *pi, const PicInsnInfo *table,
+ const PicInsnInfo **pii_r, int *objnum_r, int *v_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->argsbits <= 6) {
+ if (pi->l != 1) pii= 0;
+ } else {
+ if (pi->l == 2 && !(pi->d[1] & 0x80u)) { val <<= 7; val |= pi->d[1]; }
+ else pii= 0;
+ }
+ }
+
+ if (pii) {
+ if (objnum_r) *objnum_r= (val & ((1u << pii->argsbits) - 1)) >> pii->vbits;
+ if (v_r) *v_r= val & ((1u << pii->vbits) - 1);
+ }
+ *pii_r= pii;
}
const PicInsnInfo pic_command_infos[]= {
- { "@cnameyn@", @opcodeyn@, @arglen@ }, @h2p@
+ { "@cnameyn@", @opcodeyn@, @opcodemaskyn@, @argslen@, @vlen@, @noiselevel@, 0 }, @h2p@
{ 0 }
};
const PicInsnInfo pic_reply_infos[]= {
- { "@cnameyn@", @opcodeyn@, @arglen@ }, @p2h@
+ { "@cnameyn@", @opcodeyn@, @opcodemaskyn@, @argslen@, @vlen@, @noiselevel@, on_pic_@cnameyn@ },@p2h@
{ 0 }
};