There's a very handy and fast method of finding integer square roots; I'm sure you could get this to work with fixed point:
unsigned long isqrt(v)
unsigned long v;
{
register long t = 1L<<30, r = 0, s;
# define STEP(k) s = t + r; r>>= 1; if (s <= v) { v -= s; r |= t;}
STEP(15); t >>= 2;
STEP(14); t >>= 2;
STEP(13); t >>= 2;
STEP(12); t >>= 2;
STEP(11); t >>= 2;
STEP(10); t >>= 2;
STEP(9); t >>= 2;
STEP(8); t >>= 2;
STEP(7); t >>= 2;
STEP(6); t >>= 2;
STEP(5); t >>= 2;
STEP(4); t >>= 2;
STEP(3); t >>= 2;
STEP(2); t >>= 2;
STEP(1); t >>= 2;
STEP(0);
return (unsigned long)r;
}