+// NOTE: important: THIS MODULE REVOLVES AROUND RETURNING TO RUNTEST/IDLE, OR
+// THE FUNCTIONAL EQUIVALENT
+//! Shift N bits over TDI/TDO. May choose LSB or MSB, and select whether to
+// terminate (TMS-high on last bit) and whether to return to RUNTEST/IDLE
+// flags should be 0 for most uses.
+// for the extreme case, flags should be (NOEND|NORETDLE|LSB)
+// other edge cases can involve a combination of those three flags
+//
+// the max bit-size that can be be shifted is 32-bits.
+// for longer shifts, use the NOEND flag (which infers NORETIDLE so the
+// additional flag is unnecessary)
+//
+// NORETIDLE is used for special cases where (as with arm) the debug
+// subsystem does not want to return to the RUN-TEST/IDLE state between
+// setting IR and DR
+unsigned long jtagtransn(unsigned long word,
+ unsigned char bitcount,
+ unsigned char flags) {
+ unsigned char bit;
+ unsigned long high = 1L;
+ unsigned long mask;
+
+ //for (bit=(bitcount-1)/8; bit>0; bit--)
+ // high <<= 8;
+ //high <<= ((bitcount-1)%8);
+ high <<= (bitcount-1);
+
+ mask = high-1;
+
+ SAVETCLK;
+ if (flags & LSB) {
+ for (bit = bitcount; bit > 0; bit--) {
+ /* write MOSI on trailing edge of previous clock */
+ if (word & 1)
+ {SETMOSI;}
+ else
+ {CLRMOSI;}
+ word >>= 1;
+
+ if (bit==1 && !(flags & NOEND))
+ SETTMS;//TMS high on last bit to exit.
+
+ jtag_tcktock();
+
+ /* read MISO on trailing edge */
+ if (READMISO){
+ word += (high);
+ }
+ }
+ } else {
+ for (bit = bitcount; bit > 0; bit--) {
+ /* write MOSI on trailing edge of previous clock */
+ if (word & high)
+ {SETMOSI;}
+ else
+ {CLRMOSI;}
+ word = (word & mask) << 1;
+
+ if (bit==1 && !(flags & NOEND))
+ SETTMS;//TMS high on last bit to exit.
+
+ jtag_tcktock();
+
+ /* read MISO on trailing edge */
+ word |= (READMISO);
+ }
+ }
+
+
+ RESTORETCLK;
+ //SETMOSI;
+
+ if (!(flags & NOEND)){
+ // exit state
+ jtag_tcktock();
+ // update state
+ if (!(flags & NORETIDLE)){
+ CLRTMS;
+ jtag_tcktock();
+ }
+ }
+ return word;
+}
+