c+=sizeof(m)
#define FUNCS(v) \
+ ADDR; \
nmra_errchk(cn, bitmap, !(bitmap & ~0x1fffu)); \
*c++= (v)
#define nmra_errchk(cn, v, truth) \
- if (!truth) nmra_errchk_fail(cn, v, #v, #truth);
+ if (!(truth)) nmra_errchk_fail(cn, v, #v, #truth);
static void nmra_errchk_fail(const char *m, long v,
const char *vn, const char *truth) {
return ap;
}
-#define Aint(v) , int v
-#define Abitmap(v) , unsigned v
-#define Abyte(v) , Byte v
+#define Aint(v,i) , int v
+#define Abitmap(v,i) , unsigned v
+#define Abyte(v,i) , Byte v
#define Anone
#define NMRA(n,al,body) \
fprintf(stderr,"bad usage: %s\n",why); exit(8);
}
-static long argnumber(const char ***argv, long min, long max) {
+static long argnumber(const char *const *argv, int argc, int argi,
+ unsigned long *au,
+ long min, long max) {
long l;
+ unsigned long abit;
const char *arg;
char *ep;
- if (!(arg= *(*argv)++)) badusage("missing numeric arg value");
+ if (argi > argc) badusage("missing numeric arg value");
+ abit= 1ul << argi;
+ assert(!(*au & abit));
+ *au |= abit;
+ arg= argv[argi];
+
l= strtoul(arg,&ep,0); if (*ep) badusage("bad numeric arg value");
if (l<min || l>max) badusage("numeric arg value out of range");
return l;
BARE(nmra_bytes)
#undef BARE
{
- #define Aint(x) , argnumber(&argv,INT_MIN,INT_MAX)
- #define Abitmap(x) , argnumber(&argv,0,~0u)
- #define Abyte(x) , argnumber(&argv,0,0xff)
+ unsigned long au=0;
+ for (argc=0; argv[argc]; argc++);
+ #define Aint(x,i) , argnumber(argv,argc,i,&au, INT_MIN,INT_MAX)
+ #define Abitmap(x,i) , argnumber(argv,argc,i,&au, 0,~0u>>1)
+ #define Abyte(x,i) , argnumber(argv,argc,i,&au, 0,0xff)
#define Anone
#define NMRA(n,al,body) \
if (!strcmp(arg,#n)) { \
{
badusage("unknown instruction");
}
- if (*argv) badusage("too many args for packet type");
+ if (au != (1ul << argc)-1) badusage("too many args for packet type");
xmitter= xmit_nmra_bytes;
}
* strange macros - do not use directly, usually
*/
-NMRA(speed28, Aint(addr) Aint(speed) Aint(reverse), {
+NMRA(speed28, Aint(addr,0) Aint(speed,1) Aint(reverse,2), {
/* 0<=speed<=28 or <=126; reverse: 0 forwards, non-0 backwards */
int adj;
ADDR;
*c |= adj >> 1;
}
c++;
-});
-NMRA(estop1, Aint(addr), {
+})
+NMRA(estop1, Aint(addr,0), {
/* Baseline Speed and direction Forwards E-Stop(I) S9.2 B table l.56 */
ADDR;
*c++= 0x71;
-});
-NMRA(speed126, Aint(addr) Aint(speed) Aint(reverse), {
+})
+NMRA(speed126, Aint(addr,0) Aint(speed,1) Aint(reverse,2), {
/* Advanced Operations 128 Speed Step Control
* (actually speeds 0..126) RP9.2.1 C l.200- */
ADDR;
nmra_errchk(cn, speed, speed>=0 && speed<=126);
*c++= 0x3f;
*c++= (speed ? speed + 1 : 0) | (reverse ? 0 : 0x80);
-});
+})
NMRA(estop, Anone, {
/* Baseline Broadcast stop Forwards(I) Emergency S9.2 B l.98- */
CONST(0x00, 0x71);
-});
+})
NMRA(reset, Anone, {
/* Baseline Decoder Reset S9.2 B l.77- */
CONST(0x00, 0x00);
-});
+})
NMRA(idle, Anone, {
/* Baseline Idle S9.2 B l.87- */
CONST(0xff, 0x00);
-});
+})
/* For functions:
* bit 0 is FL aka F0; bits 1-12 are F1-F12; do not call with bits
* outside 0-12 set; bits in 0-12 but not relevant for the relevant
* command are ignored. */
-NMRA(funcs0to4, Aint(addr) Abitmap(bitmap), {
+NMRA(funcs0to4, Aint(addr,0) Abitmap(bitmap,1), {
/* Function Group One RP9.2.1 C l.234- */
FUNCS(0x80 | ((bitmap >> 1) & 0x0f) | ((bitmap << 4 & 0x10)));
-});
-NMRA(funcs5to9, Aint(addr) Abitmap(bitmap), {
+})
+NMRA(funcs5to9, Aint(addr,0) Abitmap(bitmap,1), {
/* Function Group Two RP9.2.1 C l.246- */
FUNCS(0xa0 | ((bitmap >> 5) & 0x0f));
-});
-NMRA(funcs9to12, Aint(addr) Abitmap(bitmap), {
+})
+NMRA(funcs9to12, Aint(addr,0) Abitmap(bitmap,1), {
/* Function Group Two RP9.2.1 C l.246- */
FUNCS(0xb0 | ((bitmap >> 9) & 0x0f));
-});
-NMRA(cvwrite, Aint(addr) Aint(cv) Abyte(value), {
+})
+NMRA(cvwrite, Aint(addr,0) Aint(cv,1) Abyte(value,2), {
/* Configuration Variable Access Long Form RP9.2.1 C l.286- */
int adj;
ADDR;
*c++= 0xec | (adj >> 8);
*c++= adj;
*c++= value;
-});
+})
#undef Aint
#undef Abitmap
#ifndef NMRA_H
#define NMRA_H
-#define Aint(v) , int v
-#define Abitmap(v) , unsigned v
-#define Abyte(v) , Byte v
+#define Aint(v,i) , int v
+#define Abitmap(v,i) , unsigned v
+#define Abyte(v,i) , Byte v
#define Anone
-#define NMRA(n,al,body) void enco_nmra_##n(Nmra *packet_r al)
+#define NMRA(n,al,body) void enco_nmra_##n(Nmra *packet_r al);
#include "nmra-packets.h"
#endif /*NMRA_H*/