chiark / gitweb /
support lookup by feature address too; specify feature commands
authorian <ian>
Sun, 13 Jul 2008 18:59:48 +0000 (18:59 +0000)
committerian <ian>
Sun, 13 Jul 2008 18:59:48 +0000 (18:59 +0000)
hostside/README.commands
hostside/actual.c
hostside/realtime.h
hostside/record.c

index 9f1c396408fa90fce5821082d04e2be08f4c9e65..26175bbeffc5a7cd5f4e4201289204c0057d239d 100644 (file)
@@ -183,10 +183,8 @@ INCOMPLETE LIST OF OTHER COMMANDS
 
  speed <stuff>...
 
- feature <trainortarg> -|+|^ <feature>|*
- !feature <trainortarg> -|+|^ <feature>|*|<nmranum>
-       fixme ???
-       nb if <nmranum> is spec'd then <trainortarg> must be a name
+ feature   <feattargetname>       -|+|^ <feature>|* [[-|+|^] ...]
+ !nmrafeat <trainpname>|<addrnum> -|+|^ <nmranum>   [[-|+|^] ...]
 
  route            <seg> <movposcomb>  [<maxms>]
  route <before>|- <seg> <after>|-     [<maxms>]    any suitable movposcomb
index e38f81a797d915f6053acca0a5a659fd5a3a9853..d4d03dc5840cfdb712bf9df3a12e047523e912a4 100644 (file)
@@ -76,22 +76,23 @@ void features_updated(FeaturesAddr *a) {
   feat_updated_funcs(a,1, enco_nmra_funcs5to8,  0x001e0);
   feat_updated_funcs(a,2, enco_nmra_funcs9to12, 0x01e00);
 
-  if (a->all & FEATURES_SPEEDSTEP_BIT) {
+  if (a->all & FEATS_SPEEDSTEP_BIT) {
     Nmra n;
     enco_nmra_speed126(&n, a->addr,
-                      a->current & FEATURES_SPEEDSTEP_BIT
+                      a->current & FEATS_SPEEDSTEP_BIT
                       ? a->speedstep : 0,
-                      !!(a->all & FEATURES_SPEEDSTEP_REVERSE));
+                      !!(a->all & FEATS_SPEEDSTEP_REVERSE));
     feat_updated_cmd(a,3, &n);
   }
 }
 
 void features_start_xmit(void) {
-  FeaturesAddr *a;
+  FeaturesAddr **ap;
   Nmra n;
-  int ix;
+  int ix, ai;
 
-  for (a=feataddrs_head; a; a=a->next) {
+  for (ai=0,ap=feataddrs; ai<n_feataddrs; ai++,ap++) {
+    FeaturesAddr *a= *ap;
     for (ix=0; ix<FEATURESADDR_TRANSMITS; ix++) {
       RetransmitRelaxedNode *rn= &a->rn[ix];
       if (!rn->pi.l) {
index 2b76cb0d49c20bb0acfaa7325a7a243175c9ec30..6df39a7451704e2a6e314b64b59a64f243434322 100644 (file)
@@ -73,13 +73,13 @@ void retransmit_relaxed_cancel(RetransmitRelaxedNode *rn);
   /* 0..2 are func0to4 func5to8 func9to12 and speed cmd
    * pi.l is 0 if not transmitting */
 
-#define FEATURES_SPEEDSTEP_BIT     0x4000u /* in a->current, a->all, f->bits */
-#define FEATURES_SPEEDSTEP_REVERSE 0x8000u /* in a->all */
+#define FEATS_SPEEDSTEP_BIT     0x4000u /* a->{current,all,permit}, f->bits */
+#define FEATS_SPEEDSTEP_REVERSE 0x8000u /* in a->all */
 
 typedef struct FeaturesAddr {
   struct FeaturesAddr *next;
   int addr, speedstep;
-  unsigned current, all;
+  unsigned current, permit, all;
   RetransmitRelaxedNode rn[FEATURESADDR_TRANSMITS];
 } FeaturesAddr;
 
@@ -99,9 +99,9 @@ extern int n_trains;
 extern Train *trains;
 extern Segment *segments;
 
-extern int n_feattargs;
+extern int n_feattargs, n_feataddrs;
 extern FeaturesTarget *feattargs;
-extern FeaturesAddr *feataddrs_head;
+extern FeaturesAddr **feataddrs;
 
 /*---------- global variables, in realtime.c ----------*/
 
index d76747840fbf4aa5bbdbe387d56a3a2557d88986..672b7430e7b8a4709514e0075998fb90caf7f077 100644 (file)
@@ -23,9 +23,9 @@
 #include "record-i.h"
 #include "record-l.h"
 
-int n_feattargs;
+int n_feattargs, n_feataddrs;
 FeaturesTarget *feattargs;
-FeaturesAddr *feataddrs_head;
+FeaturesAddr **feataddrs;
 
 /*---------- input and error handling ----------*/
 
@@ -91,21 +91,24 @@ Segment *record_pname2seg(const char *pname) {
   }while(0)
 
 FeaturesAddr *record_feataddr(int num) {
-  FeaturesAddr **search, *node;
+  FeaturesAddr **search;
+  int ix;
   
   if (num<1 || num>0x3ff) record_yyerror("feature address out of range");
 
-  SLIST_FIND_OR_INSERT
-    (feataddrs_head,search,node, node->addr == num, ({
+  ARY_FIND_OR_APPEND
+    (feataddrs,n_feataddrs, ix,search, (*search)->addr == num, ({
       int i;
-      node->next= 0;
-      node->addr= num;
-      node->speedstep= 0;
-      node->current= node->all= 0;
-      for (i=0; i<4; i++) node->rn[i].pi.l= 0;
+      FeaturesAddr *item= mmalloc(sizeof(*item));
+      item->next= 0;
+      item->addr= num;
+      item->speedstep= 0;
+      item->current= item->permit= item->all= 0;
+      for (i=0; i<4; i++) item->rn[i].pi.l= 0;
+      *search= item;
     }));
   
-  return node;
+  return *search;
 }
 
 FeaturesFeature *record_pname2feature(const char *targpn, const char *featpn) {
@@ -238,6 +241,7 @@ static void record_feature_bits(FeaturesFeature *feat, FeaturesAddr *addr,
     record_yyerror("feature includes multiple decoder addresses");
   feat->a= addr;
   feat->bits |= bits;
+  addr->permit |= bits;
   addr->all |= bits;
 }
 
@@ -260,11 +264,11 @@ void record_feature_motor(FeaturesFeature *feat, FeaturesAddr *addr,
   if (!speed) record_yyerror("zero motor speed?!");
   if (addr->speedstep) record_yyerror("feature specifies multiple speeds");
 
-  record_feature_bits(feat,addr,FEATURES_SPEEDSTEP_BIT);
+  record_feature_bits(feat,addr,FEATS_SPEEDSTEP_BIT);
 
   addr->speedstep= speed;
   if (addr->speedstep<0) {
-    addr->all |= FEATURES_SPEEDSTEP_REVERSE;
+    addr->all |= FEATS_SPEEDSTEP_REVERSE;
     addr->speedstep= -addr->speedstep;
   }
 }
@@ -275,11 +279,18 @@ static int pname1st_compar(const void *av, const void *bv) {
   return strcmp(*a,*b);
 }
 
+static int feataddrp_compar(const void *av, const void *bv) {
+  const FeaturesAddr *const *a= av;
+  const FeaturesAddr *const *b= bv;
+  return (*a)->addr - (*b)->addr;
+}
+
 static void features_postprocess(void) {
   int i;
   FeaturesTarget *targ;
   
   qsort(feattargs, n_feattargs, sizeof(*feattargs), pname1st_compar);
+  qsort(feataddrs, n_feataddrs, sizeof(*feataddrs), feataddrp_compar);
 
   for (i=0, targ=feattargs;
        i<n_feattargs;