chiark / gitweb /
fixes during movpos wip
[trains.git] / hostside / commands.c
index b14ed033052579e1c4e53162f871744372c3bccc..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->pi.d, &rn->pi.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->pi);
+  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,52 +121,44 @@ 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->pi.l= sizeof(rn->pi.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->pi);
+    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;
@@ -180,14 +181,43 @@ static void cmd_pic(ParseState *ps, const CmdInfo *ci) {
     }
     if (!ps_neednoargs(ps))
       return;
-    enco_pic_anyinsn(&pi, pii, arg);
+    enco_pic_pii(&pi, pii, arg);
   }
   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;
+  }
+
+  ouack(ci);  
 }
 
 const CmdInfo toplevel_cmds[]= {
   { "pic",        cmd_pic         },
   { "nmra",       cmd_nmra,       },
   { "noop",       cmd_noop        },
+  { "movfeat",    cmd_movfeat     },
   { 0 }
 };