10 void nmra_encodeforpic(const Nmra *packet, PicInsn *pi) {
14 unsigned working, newbits;
21 assert(length <= NMRA_PACKET_MAX);
23 working= 0xfffc; /* 16-bit temp register. Top working_qty bits */
24 working_qty= 15; /* are some data bits to encode, rest are clear. */
25 /* we start with the 14-bit preamble and the packet start bit */
27 assert(working_qty >= 0);
28 if (working_qty < 7) {
30 /* plonk new data bits just to right of old data bits */
34 newbits |= !length; /* 9 bits, bottom one is `end of packet' */
35 working |= (newbits << (7-working_qty));
37 } else if (!working_qty) {
41 /* pad with exactly enough 1 bits to make up the encoded byte */
42 working |= 0xffU << (8-working_qty);
46 assert(encp < pi->d + COMMAND_ENCODED_MAX);
47 *encp++= ((working >> 9) & 0x7f) | 0x80;
48 /* top 7 bits, right-justified, plus `more command' bit */
53 encp[-1] &= ~0x80; /* clear `more command' bit */
57 void nmra_addchecksum(Nmra *packet) {
58 /* calculates checksum, S9.2 B l.63 */
63 assert(packet->l >=0 && packet->l < NMRA_PACKET_MAX);
65 for (left=packet->l, running=0, bp=packet->d;
74 static long argnumber(NmraParseEncodeCaller *pec, int argi,
75 unsigned long *au, int argc,
80 if (argi >= argc) nmra_problem(pec,"missing numeric arg value");
82 l= nmra_argnumber(pec, argi);
85 assert(!(*au & abit));
88 if (l<min || l>LONG_MAX || l>max)
89 nmra_problem(pec,"numeric arg value out of range");
93 void nmra_parse_encode(Nmra *out, const char *arg, int argl,
94 int argc, NmraParseEncodeCaller *pec) {
97 #define Aint(x,i) , argnumber(pec,i,&au,argc, INT_MIN,INT_MAX)
98 #define Abitmap(x,i) , argnumber(pec,i,&au,argc, 0,~0u>>1)
99 #define Abyte(x,i) , argnumber(pec,i,&au,argc, 0,0xff)
101 #define NMRA(n,al,body) \
102 if (argl == sizeof(#n)-1 && !memcmp(arg,#n,argl)) { \
103 enco_nmra_##n(out al); \
105 #include "nmra-packets.h"
107 nmra_problem(pec,"unknown instruction");
109 if (au != (1ul << argc)-1)
110 nmra_problem(pec,"too many args for packet type");