#include <assert.h>
#include <string.h>
-#include "hostside.h"
+#include "realtime.h"
#include "auproto-pic.h"
#define NMRA_MAX_NARGS 10
ManualRetransmitNode *back, *next;
char *name;
int lname;
- RetransmitNode rn;
+ RetransmitUrgentNode rn;
};
#define bogus_volatile /*empty*/
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];
}
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;
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;
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;
!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);
- 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 }
};