chiark / gitweb /
service mode factory reset
[trains.git] / hostside / encode.c
1 /*
2  * arranges for the definitions of
3  *  enco_nmra_WHATEVER
4  */
5
6 #include <assert.h>
7 #include <stdlib.h>
8 #include <string.h>
9
10 #include "common.h"
11 #include "nmra.h"
12
13 #define CONST(...)                              \
14   static const Byte m[]= { __VA_ARGS__ };       \
15   memcpy(c,m,sizeof(m));                        \
16   c+=sizeof(m)
17
18 #define FUNCS(v)                                        \
19   ADDR;                                                 \
20   nmra_errchk(cn, bitmap, !(bitmap & ~0x1fffu));        \
21   *c++= (v)
22
23 #define nmra_errchk(cn, v, truth) \
24   if (!(truth)) nmra_errchk_fail(cn, v, #v, #truth);
25
26 static void nmra_errchk_fail(const char *m, long v,
27                              const char *vn, const char *truth) {
28   fprintf(stderr,"nmra encode %s: %s %ld (0x%lx) fails condition %s\n",
29           m, vn, (unsigned long)v, (unsigned long)v, truth);
30   exit(15);
31 }
32   
33 #define ADDR     c= encode_addr(cn, addr, c);
34
35 static Byte *encode_addr(const char *cn, int addr, Byte *ap) {
36   /* encodes decoder address */
37   nmra_errchk(cn, addr, addr>0 && addr<=0x3ff);
38   if (addr < 0x3f) {
39     /* Short addresses: S9.2 B l.41 which is the same as RP9.2.1 C l.65
40      * first sentence. */
41     *ap++= addr;
42   } else {
43     /* Long addresses: RP9.2.1 C l.65-69. */
44     *ap++= addr;
45     *ap++= (addr >> 8) | 0xc0;
46   }
47   return ap;
48 }
49
50 #define Aint(v,i)    , int v
51 #define Abitmap(v,i) , unsigned v
52 #define Abyte(v,i)   , Byte v
53 #define Anone
54
55 #define NMRA(n,al,body)                         \
56 void enco_nmra_##n(Nmra *p al) {                \
57   static const char cn[]= #n;                   \
58   Byte *c= p->d;                                \
59   (void)cn;                                     \
60   do { body } while(0);                         \
61   p->l= c - p->d;                               \
62   assert(p->l <= sizeof(p->d));                 \
63 }
64
65 #include "nmra-packets.h"