chiark / gitweb /
fixes during movpos wip
[trains.git] / hostside / commands.c
index c80c8458aca82be8960ed0fb7018b60c7fabd3d2..1c9953ae156a4f28ffbc0e17fe2d29f374d82014 100644 (file)
@@ -6,7 +6,7 @@
 #include <assert.h>
 #include <string.h>
 
-#include "hostside.h"
+#include "realtime.h"
 #include "auproto-pic.h"
 
 #define NMRA_MAX_NARGS 10
@@ -16,7 +16,7 @@ struct ManualRetransmitNode {
   ManualRetransmitNode *back, *next;
   char *name;
   int lname;
-  RetransmitNode rn;
+  RetransmitUrgentNode rn;
 };
 
 #define bogus_volatile /*empty*/
@@ -33,6 +33,10 @@ struct NmraParseEncodeCaller {
   jmp_buf jb;
 };
 
+static void ouack(const CmdInfo *ci) {
+  oprintf(UPO, "ack %s\n", ci->name);
+}
+
 unsigned long nmra_argnumber(NmraParseEncodeCaller *pec, int argi) {
   return pec->arg[argi];
 }
@@ -42,7 +46,7 @@ void nmra_problem(NmraParseEncodeCaller *pec, const char *problem) {
   longjmp(pec->jb, 1);
 }
 
-static int cmd_nmra_command(ParseState *ps, RetransmitNode *rn) {
+static int cmd_nmra_command(ParseState *ps, PicInsn *pi) {
   int hex;
   const char *cmdarg;
   int lcmdarg;
@@ -53,7 +57,7 @@ static int cmd_nmra_command(ParseState *ps, RetransmitNode *rn) {
 
   assert(ps->remain);
   switch (ps->remain[0]) {
-  case '_':  ps->remain++; return ps_needhextoend(ps, rn->d, &rn->l);
+  case '_':  ps->remain++; return ps_needhextoend(ps, pi->d, &pi->l);
   case '=':  hex=1;  checksum=1;  break;
   case ':':  hex=1;  checksum=0;  break;
   default:   hex=0;  checksum=1;  break;
@@ -89,17 +93,22 @@ static int cmd_nmra_command(ParseState *ps, RetransmitNode *rn) {
   if (checksum)
     nmra_addchecksum(&nmra);
 
-  nmra_encodeforpic(&nmra, rn->d, &rn->l);
+  nmra_encodeforpic(&nmra, pi);
   return 1;
 }
   
 static void cmd_nmra(ParseState *ps, const CmdInfo *ci) {
   static struct { ManualRetransmitNode *head, *tail; } mrns;
   
-  ManualRetransmitNode *mrn;
-  RetransmitNode *rn, rn_buf;
+  PicInsn *pi, pi_buf;
+  ManualRetransmitNode *mrn=0;
+  void (*retrans)(RetransmitUrgentNode *urg, Nmra *n)= 0;
   
-  if (ps->remain && ps->remain[0]=='*') {
+  if (ps->remain) {
+    if (ps->remain[0]=='*') retrans= retransmit_urgent_queue;
+    else if (ps->remain[0]=='%') retrans= retransmit_urgent_queue_relaxed;
+  }
+  if (retrans) {
     const char *mrname;
     int lmrname;
 
@@ -112,76 +121,103 @@ static void cmd_nmra(ParseState *ps, const CmdInfo *ci) {
           !memcmp(mrn->name, mrname, lmrname));
         mrn= mrn->next);
     if (mrn) {
-      retransmit_cancel(&mrn->rn);
+      retransmit_urgent_cancel(&mrn->rn);
     } else {
       mrn= mmalloc(sizeof(*mrn));
       mrn->name= mmalloc(lmrname);
       memcpy(mrn->name, mrname, lmrname);
       mrn->lname= lmrname;
     }
-  } else {
-    mrn= 0;
   }
 
   if (!ps->remain) {
-    if (!mrn) {
+    if (!retrans) {
       badcmd(ps,"nmra must have slot to cancel or data to send");
       return;
     }
     free(mrn->name);
     free(mrn);
+    ouack(ci);
     return;
   }
 
-  rn= mrn ? &mrn->rn : &rn_buf;
-  rn->l= sizeof(rn->d);
+  pi= retrans ? &mrn->rn.pi : &pi_buf;
   
-  if (!cmd_nmra_command(ps, rn)) {
-    if (mrn) { free(mrn->name); free(mrn); }
+  if (!cmd_nmra_command(ps, pi)) {
+    if (retrans) { free(mrn->name); free(mrn); }
     return;
   }
 
-  if (mrn)
-    retransmit_queue(&mrn->rn);
+  if (retrans)
+    retrans(&mrn->rn, 0);
   else
-    serial_transmit(rn->d, rn->l);
+    serial_transmit(pi);
+  ouack(ci);
 }
 
 static void cmd_noop(ParseState *ps, const CmdInfo *ci) {
-  oprintf(&ps->cl->ch,"noop successful\n");
+  ouack(ci);
 }
 
-typedef struct PicCmdInfo PicCmdInfo;
-struct PicCmdInfo {
-  const char *name;
-  Byte opcode;
-  int argbits;
-};
-
 static void cmd_pic(ParseState *ps, const CmdInfo *ci) {
   const PicInsnInfo *pii;
   PicInsn pi;
   long arg;
+
+  if (ps->remain && ps->remain[0]=='=') {
+    ps->remain++;
+    pi.l= sizeof(pi.d);
+    if (!ps_needhextoend(ps, pi.d, &pi.l)) return;
+  } else {
+    pii= some_needword_lookup(ps,pic_command_infos,"pic command");
+    if (!pii) return;
   
-  pii= some_needword_lookup(ps,pic_command_infos,"pic command");
-  if (!pii) return;
-  
-  if (pii->argbits) {
-    if (!ps_neednumber(ps, &arg, 0, (1L << pii->argbits) - 1,
-                      "pic object number"))
+    if (pii->argbits) {
+      if (!ps_neednumber(ps, &arg, 0, (1L << pii->argbits) - 1,
+                        "pic object number"))
+       return;
+    } else {
+      arg= 0;
+    }
+    if (!ps_neednoargs(ps))
       return;
-  } else {
-    arg= 0;
+    enco_pic_pii(&pi, pii, arg);
   }
-  if (!ps_neednoargs(ps))
+  serial_transmit(&pi);
+  ouack(ci);
+}
+
+static void cmd_movfeat(ParseState *ps, const CmdInfo *ci) {
+  Segment *back, *move, *fwd;
+  long ms;
+  ErrorCode ec;
+  
+  if (!ps_needsegment(ps,&back,0) ||
+      !ps_needsegment(ps,&move,0) ||
+      !ps_needsegment(ps,&fwd,0)) return;
+  
+  ms= INT_MAX;
+  if (ps->remain)
+    if (!ps_neednumber(ps,&ms,0,INT_MAX,"milliseconds")) return;
+
+  if (!ps_neednoargs(ps)) return;
+
+  ec= movpos_change(back,move,fwd,ms,0);
+  if (ec) {
+    badcmd(ps,"movfeat %s %s %s %ld %s",
+          back->i->pname, move->i->pname, fwd->i->pname,
+          ms==INT_MAX ? -1L : ms,
+          errorcodelist[ec]);
     return;
-  enco_pic_anyinsn(&pi, pii, arg);
-  serial_transmit(pi.d, pi.l);
+  }
+
+  ouack(ci);  
 }
 
 const CmdInfo toplevel_cmds[]= {
   { "pic",        cmd_pic         },
   { "nmra",       cmd_nmra,       },
   { "noop",       cmd_noop        },
+  { "movfeat",    cmd_movfeat     },
   { 0 }
 };