TPIC6B595 Shift Registers Controlling Multiple Steppers

I programmed two cases here.
One that moves all motors to a different random position,
and one that moves them to a common random position.
Compiles, but not hardware tested.
Read all the comments.
Leo..

/*
  Nano | TPIC6B595
    5V | 2 (VCC)
   GND | GND
    D8 | 8 (SRCLR)
   D10 | 12 (RCK)
   D11 | 3 (SER IN) of the first chip
   D13 | 13 (SRCK)
       | 9 to GND
       | 10, 11,19 to GND
       | 18 (SER OUT) to 3 of the next chip
*/

#include <SPI.h>
const byte motors = 48; // sets of four motors
// must be sets of four motors for SPI.transfer16, so 44 for 41 motors !
// but why not keep it simply the board number of 48
const byte clrPin = 8; // TPIC6B595 SRCLR pin8
const byte latchPin = 10; // TPIC6B595 RCK pin12
const byte rampSteps = 7; // accel/decel steps
byte rampDelay[motors]; // accel/decel delay between steps
byte lag[motors]; // speed reduction
int velocity[motors]; // signed, for direction
int nowPos[motors], newPos[motors]; // int is 16 rotations max (2.5m string with a 50mm dia wheel)
unsigned long prevMillis, prevMicros, interval; // timing
byte val[4]; // TPIC write bytes
bool torque; // reduced during homing
byte sequence, index; // patterns, motor index
int randNumber;

void setup() {
  SPI.begin();
  pinMode(clrPin, OUTPUT);
  pinMode(latchPin, OUTPUT);
  digitalWrite(clrPin, HIGH); // clear all shift register data
  randomSeed(analogRead(0));
  // load 41 (or 48) eeprom nowPos[] integers (= two bytes) here
}

void loop() {
  switch (sequence) {
    case 0: // load random positions for each motor into the new position array
      for (byte i = 0; i < motors; i++) {
        newPos[i] = random(-500, 500); // about a quarter turn max, right or left from start position
      }
      // eepromSave(); // could call eeprom write function here
      sequence = 1; // go to next case
      prevMillis = millis(); // but first mark the time
      break;
    case 1: // move all motors the same random direction/steps
      if (millis() - prevMillis > 8000) { // after 8 seconds
        randNumber = random(-1024, 1024); // max half a turn
        for (byte i = 0; i < motors; i++) {
          newPos[i] = randNumber; // all motors the same (random) new position
        }
        // eepromSave(); // could call eeprom write function here
        sequence = 2; // next case
        prevMillis = millis();
      }
      break;
    case 2: // run sequence(s) again
      if (millis() - prevMillis > 20000) { // after 20 sec
        sequence = 1;
        prevMillis = millis(); // mark
      }
      break;
  }
  goPos(); // let's step, one step each loop
}

void goPos() {
  while (micros() - prevMicros < 1953); // step interval, motor RPM limitation, 1/(15rpm/60sec*2048steps)= ~1953ms, wait if arrived here too early
  prevMicros = micros(); // update, for next interval
  for (int i = 0; i < motors; i++) {
    if (rampDelay[i]) rampDelay[i]--; // subtract one, do nothing
    else { // step
      if (newPos[i] > nowPos[i]) { // request forwards
        if (velocity[i] >= 0) { // if standing still, or going forwards
          nowPos[i]++; // one step forward
          if (newPos[i] - nowPos[i] < rampSteps) velocity[i]--; // reduce speed if almost there
          else if (velocity[i] < min(rampSteps, rampSteps - lag[i])) velocity[i]++; // increase speed if not there yet
          rampDelay[i] = max(lag[i], rampSteps - velocity[i]); // insert ramp delay
        } else { // if wrong direction
          velocity[i]++; // reduce reverse speed
          if (velocity[i] < 0) nowPos[i]--; // if still reverse, keep on going the wrong way
          rampDelay[i] = rampSteps - abs(velocity[i]); // insert ramp delay
        }
      }
      if (newPos[i] < nowPos[i]) { // request reverse
        if (velocity[i] <= 0) { // if standing still, or going reverse
          nowPos[i]--; // one step reverse
          if (nowPos[i] - newPos[i] < rampSteps) velocity[i]++; // reduce speed if almost there
          else if (abs(velocity[i]) < min(rampSteps, rampSteps - lag[i])) velocity[i]--; // increase speed if not there yet
          rampDelay[i] = max(lag[i], rampSteps + velocity[i]); // insert ramp delay
        } else { // wrong direction
          velocity[i]--; // reduce forward speed
          if (velocity[i] > 0) nowPos[i]++; // if still reverse, keep on going the wrong way
          rampDelay[i] = rampSteps - velocity[i]; // insert ramp delay
        }
      }
    }
    if (newPos[i] == nowPos[i])val[i & 3] = 0; // cut coil power when there
    else {
      if (torque) { // this block for full torque
        switch (nowPos[i] & 3) { // the two LSB translated to motor coils (full step)
          case 0: val[i & 3] = B00000011; break; // two coils at the time
          case 1: val[i & 3] = B00000110; break;
          case 2: val[i & 3] = B00001100; break;
          case 3: val[i & 3] = B00001001; break;
        }
      } else { // this block for low power
        switch (nowPos[i] & 3) {
          case 0: val[i & 3] = B00000001; break; // one coil at the time
          case 1: val[i & 3] = B00000010; break;
          case 2: val[i & 3] = B00000100; break;
          case 3: val[i & 3] = B00001000; break;
        }
      }
    }
    if ((i & 3) == 3) { // process set of four motors (faster)
      unsigned int chain = val[0] << 12 | val[1] << 8 | val[2] << 4 | val[3]; // concat
      SPI.transfer16(chain); // transfer 4-motor int
    }
  }
  digitalWrite(latchPin, HIGH); // transfer to TPIC driver outputs
  digitalWrite(latchPin, LOW); // latch time ~8us
}