Ich würde noch als Optimierung die 4bits vom PORTD auf den verbleibenden jeweils 2Bits bei PORTB u. PORTC umsetzen. Man muss zwar ein bisschen mit den Bits jonglieren, wäre aber machbar, und dann hattest noch einen ganzen Port frei.
Wenn natürlich andere Überlegungen für diese Verteilung sprechen (wie zB Spezialfunktionen der Pins), dann hab ich nichts gesagt :-D

Statt waitms könnte man einen Timer benutzen, und 3 Wartevariablen für die 3 Motoren, und aus dem Takt, was der eine Timer erstellt (interruptbasiert), die Wartezeiten ausrechnen. Damit wäre dann noch für andere Dinge Rechenzeit übrig.