chiark / gitweb /
Merge and end branch-hostside-wip-2008-01-25 PROPERLY; cvs up -j branch-hostside...
[trains.git] / hostside / skelproto-pic.c
1 /* @skeleton@ @1@ @L@ */
2 /*
3  * definitions of
4  *  enco_pic_WHATEVER
5  *  on_pic_WHATEVER
6  * and the tables
7  * and related functions
8  */
9
10 #include <assert.h>
11
12 #include "common.h"
13 #include "auproto-pic.h"
14
15 extern void enco_pic_any(PicInsn *out, int opcode, int argbits, int objnum) {
16   unsigned long as= objnum;
17   int i;
18
19   assert(!(as & (~0UL << argbits)));
20   out->l= 1 + argbits/7;
21   for (i= out->l - 1;
22        i >= 0;
23        i--, as >>= 7)
24     out->d[i]= (as & 0x07fUL) | 0x080UL;
25   out->d[out->l - 1] &= ~0x080UL;
26   out->d[0] |= opcode;
27 }
28
29 #define C ,
30 #define ENCO(w, xa, opcode, argbits, objnum)            \
31   extern void enco_pic_##w(PicInsn *out  xa) {          \
32     return enco_pic_any(out, opcode, argbits, objnum);  \
33   }
34
35 ENCO(pii, C const PicInsnInfo *pii C int objn,pii->opcode,pii->argbits,objn)
36 ENCO(@cnameyn@,             , @opcodeyn@, 0,0)             @h2p@ @arglentf=0@
37 ENCO(@cnameyn@, C int objnum, @opcodeyn@, @arglen@,objnum) @h2p@ @arglentf=1@
38
39 const PicInsnInfo *lookup_byopcode(Byte byte0, const PicInsnInfo *table) {
40   const PicInsnInfo *pi;
41   for (pi= table;
42        pi->name;
43        pi++)
44     if ((byte0 & pi->mask) == pi->opcode)
45       return pi;
46   return 0;
47 }
48
49 void picinsn_decode(const PicInsn *pi, const PicInsnInfo *table,
50                     const PicInsnInfo **pii_r, int *objnum_r) {
51   const PicInsnInfo *pii;
52   unsigned val= 0;
53
54   pii= pi->l > 0 ? lookup_byopcode(pi->d[0], table) : 0;
55
56   if (pii) {
57     val= pi->d[0];
58     if (pii->argbits <= 6) {
59       if (pi->l != 1) pii= 0;
60     } else {
61       if (pi->l == 2 && !(pi->d[1] & 0x80u)) { val <<= 7; val |= pi->d[1]; }
62       else pii= 0;
63     }
64   }
65
66   if (objnum_r && pii) *objnum_r= val & ((1u << pii->argbits) - 1);
67   *pii_r= pii;
68 }
69
70 const PicInsnInfo pic_command_infos[]= {
71   { "@cnameyn@", @opcodeyn@, @opcodemaskyn@, @arglen@, @noiselevel@, 0 }, @h2p@
72   { 0 }
73 };
74
75 const PicInsnInfo pic_reply_infos[]= {
76   { "@cnameyn@", @opcodeyn@, @opcodemaskyn@, @arglen@, @noiselevel@, on_pic_@cnameyn@ },@p2h@
77   { 0 }
78 };