10 #include "auproto-pic.h"
12 #define NMRA_MAX_NARGS 10
14 typedef struct ManualRetransmitNode ManualRetransmitNode;
15 struct ManualRetransmitNode {
16 ManualRetransmitNode *back, *next;
22 #define bogus_volatile /*empty*/
26 #define bogus_volatile volatile
30 struct NmraParseEncodeCaller {
32 unsigned long arg[NMRA_MAX_NARGS];
36 unsigned long nmra_argnumber(NmraParseEncodeCaller *pec, int argi) {
37 return pec->arg[argi];
40 void nmra_problem(NmraParseEncodeCaller *pec, const char *problem) {
41 badcmd(pec->ps,problem);
45 static int cmd_nmra_command(ParseState *ps, RetransmitNode *rn) {
49 bogus_volatile int argc, checksum;
50 NmraParseEncodeCaller pec;
55 switch (ps->remain[0]) {
56 case '_': ps->remain++; return ps_needhextoend(ps, rn->pi.d, &rn->pi.l);
57 case '=': hex=1; checksum=1; break;
58 case ':': hex=1; checksum=0; break;
59 default: hex=0; checksum=1; break;
64 nmra.l= NMRA_PACKET_MAX - checksum;
65 if (!ps_needhextoend(ps, nmra.d, &nmra.l))
68 if (!ps_needword(ps)) return 0;
70 lcmdarg= ps->lthisword;
75 if (argc >= NMRA_MAX_NARGS) {
76 badcmd(ps,"far too many nmra args");
80 errno=0; pec.arg[argc++]= strtoul(ps->thisword, &ep, 0);
81 if (errno || ep != ps->thisword + ps->lthisword)
82 { badcmd(ps,"bad numeric argument for nmra"); return 0; }
87 nmra_parse_encode(&nmra, cmdarg,lcmdarg, argc, &pec);
90 nmra_addchecksum(&nmra);
92 nmra_encodeforpic(&nmra, &rn->pi);
96 static void cmd_nmra(ParseState *ps, const CmdInfo *ci) {
97 static struct { ManualRetransmitNode *head, *tail; } mrns;
99 ManualRetransmitNode *mrn;
100 RetransmitNode *rn, rn_buf;
102 if (ps->remain && ps->remain[0]=='*') {
107 mrname= ps->thisword+1;
108 lmrname= ps->lthisword-1;
111 !(mrn->lname == lmrname &&
112 !memcmp(mrn->name, mrname, lmrname));
115 retransmit_cancel(&mrn->rn);
117 mrn= mmalloc(sizeof(*mrn));
118 mrn->name= mmalloc(lmrname);
119 memcpy(mrn->name, mrname, lmrname);
128 badcmd(ps,"nmra must have slot to cancel or data to send");
136 rn= mrn ? &mrn->rn : &rn_buf;
137 rn->pi.l= sizeof(rn->pi.d);
139 if (!cmd_nmra_command(ps, rn)) {
140 if (mrn) { free(mrn->name); free(mrn); }
145 retransmit_queue(&mrn->rn);
147 serial_transmit(&rn->pi);
150 static void cmd_noop(ParseState *ps, const CmdInfo *ci) {
151 oprintf(&ps->cl->ch,"noop successful\n");
154 typedef struct PicCmdInfo PicCmdInfo;
161 static void cmd_pic(ParseState *ps, const CmdInfo *ci) {
162 const PicInsnInfo *pii;
166 if (ps->remain && ps->remain[0]=='=') {
169 if (!ps_needhextoend(ps, pi.d, &pi.l)) return;
171 pii= some_needword_lookup(ps,pic_command_infos,"pic command");
175 if (!ps_neednumber(ps, &arg, 0, (1L << pii->argbits) - 1,
176 "pic object number"))
181 if (!ps_neednoargs(ps))
183 enco_pic_anyinsn(&pi, pii, arg);
185 serial_transmit(&pi);
188 const CmdInfo toplevel_cmds[]= {
190 { "nmra", cmd_nmra, },
191 { "noop", cmd_noop },