> 0 0010 001 (11) ON Power on
> 0 0010 000 (10) OFF Power off
-;> 1 0101 YWW 0 WWWWWWW (a1) WAGGLE Set pin WWWWWWWWW to level Y
+ > 1 0101 WWW 0 WWWWWWV (a1) WAGGLE Set pin WWWWWWWWW to level V
;> 00000000 CRASHED Acknowledge panic, go to readout mode
;> 00001010 (0a) TELLMODE Confirm mode - say HELLO or CRASHED
;----------------------------------------------------------------------
command_waggle @
+ ; 1010 1sss OSS wwwwV
+ ;
; ie 1010 1sss
; OSS wwwwV
bt_f_if0 waggle_slave, 7
static int cmd_pic(ParseState *ps, const CmdInfo *ci) {
const PicInsnInfo *pii;
PicInsn pi;
- long arg;
+ long obj, v;
if (ps->remain && ps->remain[0]=='=') {
ps->remain++;
pii= some_needword_lookup(ps,pic_command_infos,"pic command");
if (!pii) return EC_BadCmd;
- if (pii->argbits) {
- MUSTECR( ps_neednumber(ps, &arg, 0, (1L << pii->argbits) - 1,
+ if (pii->argsbits) {
+ MUSTECR( ps_neednumber(ps, &obj, 0,
+ (1L << (pii->argsbits - pii->vbits)) - 1,
"pic object number") );
} else {
- arg= 0;
+ obj= 0;
+ }
+ if (pii->vbits) {
+ MUSTECR( ps_neednumber(ps, &v, 0, (1L << pii->vbits) - 1,
+ "pic command value") );
+ } else {
+ v= 0;
}
MUSTECR( ps_neednoargs(ps) );
- enco_pic_pii(&pi, pii, arg);
+ enco_pic_pii(&pi, pii, obj, v);
}
serial_transmit(&pi);
return 0;
if ($msg =~ m/^0[01]{7}$/) {
$opcode= $&;
$opcodemask= '11111111';
- $arglen= 0;
+ $argslen= 0;
+ $vbits= 0;
$ybit= 0;
} else {
$ybit= substr($msg,0,8);
$ybit =~ y/Y01A-Z/10/;
$ybit =~ m/1.*1/ and die "$msg/$ybit?";
$msg =~ s/Y/0/g;
- $msg =~ m/[A-Z]/ or die "$msg?";
+ $msg =~ m/[A-UW-Z]/ or die "$msg?";
$oplet= $&;
$msg =~ s/$oplet/_/g;
- die "$msg?" if $msg =~ m/[A-Z]/;
- die "$msg?" unless $msg =~ m/^(1[01][01_]{6})0_{7}$/ or
- $msg =~ m/^(0[01][01_]{6})$/;
+ die "$msg?" if $msg =~ m/[A-UW-Z]/;
+ die "$msg?" unless $msg =~ m/^(1[01][01V_]{6})0[V_]{7}$/ or
+ $msg =~ m/^(0[01][01V_]{6})$/;
$opcode= $1;
- die if $opcode =~ m/_[01]/;
+ die if $opcode =~ m/[V_][01]/;
$opcodemask= $opcode;
- $opcodemask =~ y/01_/110/;
- $opcode =~ s/_/0/g;
- $arglen= $msg;
- $arglen =~ s/[01]//g;
- $arglen= length $arglen;
+ $opcodemask =~ y/01V_/1100/;
+ $opcode =~ s/[V_]/0/g;
+
+ $argspat= $msg;
+ $argspat =~ s/[01]//g;
+ $argslen= length $argspat;
+ $argspat =~ m/^_*(V*)$/ or die "$msg/$argspat?";
+ $vbits= length($1);
$ybit= oct("0b$ybit");
}
for $yval (($ybit && $doyn) ? (0,1) : '') {
$v{opcodeyn}= b2xh($opcode, $ybit * $yval);
$v{opcodemask}= b2xh($opcodemask, 0);
$v{opcodemaskyn}= b2xh($opcodemask, $ybit);
- $v{arglen}= $arglen;
- $v{arglentf}= sprintf "%d", !!$arglen;
+ $v{vlen}= $vbits;
+ $v{argslen}= $argslen;
+ $v{arglen}= $argslen - $vbits;
+ $v{nargs}= sprintf "%d", !!$argslen+!!$vbits;
expand_and_write();
}
}
}
}
-void oupicio(const char *dirn, const PicInsnInfo *pii, int objnum) {
- if (!pii->argbits)
+void oupicio(const char *dirn, const PicInsnInfo *pii, int obj, int v) {
+ if (!pii->argsbits)
oprintf(UPO, "picio %s %s\n", dirn, pii->name);
+ else if (!pii->vbits)
+ oprintf(UPO, "picio %s %s %#x\n", dirn, pii->name, obj);
else
- oprintf(UPO, "picio %s %s %#x\n", dirn, pii->name, objnum);
+ oprintf(UPO, "picio %s %s %#x %d\n", dirn, pii->name, obj, v);
}
static void obc_error(OutBufferChain *ch, const char *e1, const char *e2) {
void serial_transmit(const PicInsn *pi) {
const PicInsnInfo *pii;
- int objnum, suppress=0;
+ int obj, v, suppress=0;
if ((pi->d[0] & 0xf8) == 0x90) {
SEG_IV;
else
oprint_nmradata(pi);
} else {
- picinsn_decode(pi, pic_command_infos, &pii, &objnum);
+ picinsn_decode(pi, pic_command_infos, &pii, &obj, &v);
if (!pii)
oprintf(UPO, "picio out unknown\n");
else if (pii->noiselevel > picio_send_noise)
suppress= 1;
else
- oupicio("out",pii,objnum);
+ oupicio("out",pii,obj,v);
}
if (!suppress && picio_send_noise >= 2)
/*---------- from/for realtime.c ----------*/
-void oupicio(const char *dirn, const PicInsnInfo *pii, int objnum);
+void oupicio(const char *dirn, const PicInsnInfo *pii, int obj, int v);
void ouhexi(const char *word, const Byte *command, int length);
void ouhexo(const char *word, const Byte *command, int length);
#include "common.h"
#include "auproto-pic.h"
-extern void enco_pic_any(PicInsn *out, int opcode, int argbits, int objnum) {
- unsigned long as= objnum;
+static void enco_pic_any(PicInsn *out, int opcode, int argsbits, int argsval) {
+ unsigned long as= argsval;
int i;
- assert(!(as & (~0UL << argbits)));
- out->l= 1 + argbits/7;
+ assert(!(as & (~0UL << argsbits)));
+ out->l= 1 + argsbits/7;
for (i= out->l - 1;
i >= 0;
i--, as >>= 7)
out->d[0] |= opcode;
}
+static void enco_pic_anyobjv(PicInsn *out, int opcode, int argsbits, int vbits,
+ int obj, int v) {
+ assert((unsigned)v < (1u << vbits));
+ enco_pic_any(out, opcode, argsbits, obj << vbits | v);
+}
+
#define C ,
-#define ENCO(w, xa, opcode, argbits, objnum) \
- extern void enco_pic_##w(PicInsn *out xa) { \
- return enco_pic_any(out, opcode, argbits, objnum); \
+
+#define ENCO(w, xa, opcode, argsbits, obj) \
+ extern void enco_pic_##w(PicInsn *out xa) { \
+ enco_pic_any(out, opcode, argsbits, obj); \
+ }
+
+#define ENCO2A(w, opcode, vbits, argsbits) \
+ extern void enco_pic_##w(PicInsn *out, int obj, int v) { \
+ enco_pic_anyobjv(out, opcode, argsbits, vbits, obj, v); \
}
-ENCO(pii, C const PicInsnInfo *pii C int objn,pii->opcode,pii->argbits,objn)
-ENCO(@cnameyn@, , @opcodeyn@, 0,0) @h2p@ @arglentf=0@
-ENCO(@cnameyn@, C int objnum, @opcodeyn@, @arglen@,objnum) @h2p@ @arglentf=1@
+ENCO(@cnameyn@, , @opcodeyn@, 0, 0) @h2p@ @nargs=0@
+ENCO(@cnameyn@, C int obj, @opcodeyn@, @arglen@, obj) @h2p@ @nargs=1@
+ENCO2A(@cnameyn@, @opcodeyn@, @arglen@, @vlen@) @h2p@ @nargs=2@
+
+extern void enco_pic_pii(PicInsn *out, const PicInsnInfo *pii,
+ int obj, int v) {
+ enco_pic_anyobjv(out, pii->opcode, pii->argsbits, pii->vbits, obj, v);
+}
const PicInsnInfo *lookup_byopcode(Byte byte0, const PicInsnInfo *table) {
const PicInsnInfo *pi;
}
void picinsn_decode(const PicInsn *pi, const PicInsnInfo *table,
- const PicInsnInfo **pii_r, int *objnum_r) {
+ const PicInsnInfo **pii_r, int *objnum_r, int *v_r) {
const PicInsnInfo *pii;
unsigned val= 0;
if (pii) {
val= pi->d[0];
- if (pii->argbits <= 6) {
+ if (pii->argsbits <= 6) {
if (pi->l != 1) pii= 0;
} else {
if (pi->l == 2 && !(pi->d[1] & 0x80u)) { val <<= 7; val |= pi->d[1]; }
}
}
- if (objnum_r && pii) *objnum_r= val & ((1u << pii->argbits) - 1);
+ if (pii) {
+ if (objnum_r) *objnum_r= (val & ((1u << pii->argsbits) - 1)) >> pii->vbits;
+ if (v_r) *v_r= val & ((1u << pii->vbits) - 1);
+ }
*pii_r= pii;
}
const PicInsnInfo pic_command_infos[]= {
- { "@cnameyn@", @opcodeyn@, @opcodemaskyn@, @arglen@, @noiselevel@, 0 }, @h2p@
+ { "@cnameyn@", @opcodeyn@, @opcodemaskyn@, @argslen@, @vlen@, @noiselevel@, 0 }, @h2p@
{ 0 }
};
const PicInsnInfo pic_reply_infos[]= {
- { "@cnameyn@", @opcodeyn@, @opcodemaskyn@, @arglen@, @noiselevel@, on_pic_@cnameyn@ },@p2h@
+ { "@cnameyn@", @opcodeyn@, @opcodemaskyn@, @argslen@, @vlen@, @noiselevel@, on_pic_@cnameyn@ },@p2h@
{ 0 }
};
typedef struct PicInsnInfo PicInsnInfo;
typedef void PicInputFn(const PicInsnInfo *pii, const PicInsn *pi, int objnum);
-void enco_pic_@cnameyn@(PicInsn *out); @h2p@ @arglentf=0@
-void enco_pic_@cnameyn@(PicInsn *out, int objum); @h2p@ @arglentf=1@
+void enco_pic_@cnameyn@(PicInsn *out); @h2p@ @nargs=0@
+void enco_pic_@cnameyn@(PicInsn *out, int objum); @h2p@ @nargs=1@
+void enco_pic_@cnameyn@(PicInsn *out, int objum, int v); @h2p@ @nargs=2@
PicInputFn on_pic_@cnameyn@; @p2h@
#define PICMSG_@cnameynu@ @opcodeyn@
#define PICMSG_@cnameynu@_M @opcodemaskyn@
extern void enco_pic_polarity_begin(PicInsn *out);
extern void enco_pic_polarity_setbit(PicInsn *out, int objnum);
-extern void enco_pic_pii(PicInsn *out, const PicInsnInfo *pii, int objnum);
-extern void enco_pic_any(PicInsn *out, int opcode, int argbits, int objnum);
+extern void enco_pic_pii(PicInsn *out, const PicInsnInfo *pii, int obj, int v);
const PicInsnInfo *lookup_byopcode(Byte byte0, const PicInsnInfo *table);
void picinsn_decode(const PicInsn *pi, const PicInsnInfo *table,
- const PicInsnInfo **pii_r, int *objnum_r);
+ const PicInsnInfo **pii_r, int *objnum_r, int *v_r);
void oopicio(const char *dirn, const PicInsnInfo *pii, int objnum);
struct PicInsnInfo {
const char *name;
Byte opcode, mask;
- int argbits, noiselevel;
+ int argsbits, vbits, noiselevel;
PicInputFn *input_fn;
};
void serial_moredata(PicInsn *buf) {
const PicInsnInfo *pii;
- int objnum, suppress;
+ int obj, v, suppress;
Byte *ep;
/* Called when more data is received from PICs.
found_end:
/* Aha! */
buf->l= ep - buf->d + 1;
- picinsn_decode(buf, pic_reply_infos, &pii, &objnum);
+ picinsn_decode(buf, pic_reply_infos, &pii, &obj, &v);
suppress= pii && pii->noiselevel > picio_send_noise;
if (!suppress && picio_send_noise >= 2)
if (!pii) { oprintf(UPO, "picio in unknown\n"); return; }
if (!suppress)
- oupicio("in",pii,objnum);
- pii->input_fn(pii,buf,objnum);
+ oupicio("in",pii,obj,v);
+ pii->input_fn(pii,buf,obj);
}
void on_pic_pong(const PicInsnInfo *pii, const PicInsn *pi, int objnum) {
# -> global object number
sub boob2objnum_waggle {
- my ($boob,$boardnum,$objnum) = @_;
+ my ($boob,$boardnum,$obj) = @_;
mistake("waggle encoding out of range") if
$boardnum >= (1 << (9 - $maxwaggleixln2));
- die if $objnum >= (1 << $maxwaggleixln2);
- return ($boardnum << ($maxwaggleixln2+1)) | $objnum;
+ die if $obj >= (1 << $maxwaggleixln2);
+ # waggle command is 1010 1sss OSS wwwwV
+ # so waggler objnum is sss SS wwww
+ $boardnum= (($boardnum & 0x07) << 2) | ($boardnum >> 3);
+ return ($boardnum << ($maxwaggleixln2+1)) | $obj;
}
sub boob2objnum_pt {
mistake("object reference $genkind ($kind) $board.$obj out of range".
" for board type $type")
unless defined $pi->[$obj];
-print STDERR "so_boob >$kind|$board $obj|$pi->[$obj]<\n" if $kind eq 'waggle';
+#print STDERR "so_boob >$kind|$board $obj|$pi->[$obj]<\n" if $kind eq 'waggle';
$objnum= boob2objnum($mkused,$bo);
#print "so_boob >$objnum_rr|$$objnum_rr< = $objnum\n";
$$objnum_rr= $objnum;
$indiv= $r->{Indiv};
#print STDERR "redact >$board|$indiv<\n";
my $boardtype= boardtype($board);
- mistake("unknown pin name $boardtype.$indiv for $what")
- unless defined $pin_info_indiv{$boardtype}{$indiv};
- $r->{Obj}= $pin_info_indiv{$boardtype}{$indiv};
+ if (defined $pin_info_indiv{$boardtype}{$indiv}) {
+ $r->{Obj}= $pin_info_indiv{$boardtype}{$indiv};
+ } else {
+ mistake("unknown pin name $boardtype.$indiv for $what");
+ $r->{Obj}= 0;
+ }
}
sub redaction () {