+void pic33f_cmdlist(unsigned int list_len) {
+ /* commands are written as 4-byte little-endian records, where
+ the low 4 bits of first byte contains the command, and the
+ next three bytes contain the data.
+
+ Currently this only supports the SIX and REGOUT
+ instructions.
+
+ SIX instructions return no data. REGOUT instructions return
+ the 16-bit value read as two bytes, lower byte first.
+
+ The final two bytes of the response are the 2's complement
+ inverse of the sum of the response words. i.e., if the
+ response is correctly recieved, the sum of the words should
+ be 0.
+
+ This is sent when the goodfet is done running the command
+ list, and is ready for further commands.
+ */
+
+ unsigned char cmd;
+ unsigned int response_word;
+ unsigned int checksum = 0;
+ int response_count;
+ int i;
+ list_len &= ~3; // truncate to multiple of 4 bytes.
+ if (list_len > CMDDATALEN)
+ list_len = CMDDATALEN;
+ response_count = 1;
+ for (i = 0; i < list_len; i += 4) {
+ cmd = cmddata[i];
+ if (cmd == 0)
+ continue;
+ else if (cmd == 1)
+ response_count ++;
+ else
+ goto error;
+ }
+ txhead(PIC, PIC_CMDLIST, response_count << 1);
+
+ for (i = 0; i < list_len; i+= 4) {
+ cmd = cmddata[i];
+ if (cmd == 0) {
+ // SIX command
+ pic33f_transcmd(0);
+ pic33f_trans8(cmddata[i+1]);
+ pic33f_trans8(cmddata[i+2]);
+ pic33f_trans8(cmddata[i+3]);
+
+ } else if (cmd == 1) {
+ // REGOUT command
+ response_word = pic33f_regout();
+ checksum += response_word;
+ response_count--;
+ txword(response_word);
+ }
+ }
+ txword(~checksum + 1);
+ if (response_count != 1)
+ debugstr("Response count wrong");
+ return;
+ error:
+ txdata(PIC, NOK, 0);
+}