chiark / gitweb /
hostside: more length for bavarian
[trains.git] / hostside / skelproto-pic.c
index 92c847d9caa787aba911f8cf09bd2c8ef2810be1..ae775c26166365d42136d74989d6d364ef038a89 100644 (file)
 #include "common.h"
 #include "auproto-pic.h"
 
-extern void enco_pic_any(PicInsn *out, int opcode, int argbits, 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;
 
-  assert(!(as & (~0UL << argbits)));
-  out->l= 1 + argbits/7;
+  assert(!(as & (~0UL << argsbits)));
+  out->l= 1 + argsbits/7;
   for (i= out->l - 1;
        i >= 0;
        i--, as >>= 7)
@@ -26,15 +26,32 @@ extern void enco_pic_any(PicInsn *out, int opcode, int argbits, int objnum) {
   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, argbits, objnum)           \
-  extern void enco_pic_##w(PicInsn *out  xa) {         \
-    return enco_pic_any(out, opcode, argbits, objnum); \
+
+#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(pii, C const PicInsnInfo *pii C int objn,pii->opcode,pii->argbits,objn)
-ENCO(@cnameyn@,             , @opcodeyn@, 0,0)             @h2p@ @arglentf=0@
-ENCO(@cnameyn@, C int objnum, @opcodeyn@, @arglen@,objnum) @h2p@ @arglentf=1@
+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;
@@ -47,7 +64,7 @@ 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) {
+                   const PicInsnInfo **pii_r, int *objnum_r, int *v_r) {
   const PicInsnInfo *pii;
   unsigned val= 0;
 
@@ -55,7 +72,7 @@ void picinsn_decode(const PicInsn *pi, const PicInsnInfo *table,
 
   if (pii) {
     val= pi->d[0];
-    if (pii->argbits <= 6) {
+    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]; }
@@ -63,16 +80,19 @@ void picinsn_decode(const PicInsn *pi, const PicInsnInfo *table,
     }
   }
 
-  if (objnum_r && pii) *objnum_r= val & ((1u << pii->argbits) - 1);
+  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@, @opcodemaskyn@, @arglen@, @noiselevel@, 0 }, @h2p@
+  { "@cnameyn@", @opcodeyn@, @opcodemaskyn@, @argslen@, @vlen@, @noiselevel@, 0 }, @h2p@
   { 0 }
 };
 
 const PicInsnInfo pic_reply_infos[]= {
-  { "@cnameyn@", @opcodeyn@, @opcodemaskyn@, @arglen@, @noiselevel@, on_pic_@cnameyn@ },@p2h@
+  { "@cnameyn@", @opcodeyn@, @opcodemaskyn@, @argslen@, @vlen@, @noiselevel@, on_pic_@cnameyn@ },@p2h@
   { 0 }
 };