segun veo (muy por encima) en el codigo, aplicas el seno y coseno (precalculado) a cada punto... y eso me haria el blitter mas lento... pero bueno, no descarto nada... gracias.
(si me equivoque y no haces eso, comentame)
El código no le he escrito yo, mi rotación no es tan buena.
La rotación la hace en la generación de la señal analógica de los píxeles, cambiando la función manejador que le pasa como argumento a la función que genera el sincronismo horizontal de 31 Khz, mediante un Callback, si señor. La resolución parece que es de 640x400 y la textura es de 320x200 pues sólo caben dos framebuffer como este en los 128KB de RAM generales;
Te explico:
1º) Primero parece ser que actualiza los datos necesarios para que la textura se vea rotada y ampliada/reducida en cuanto al tamaño de las líneas horizontales y verticales (efecto de zoom):
WaitVBL();
int t=VGAFrameCounter();
SetLEDs(1<<((t/3)&3));
int32_t angle=isin(t*9)&1023;
int32_t scale=(icos(t*15)+Fix(2))/2;
int32_t dx=imul(scale,icos(angle));
int32_t dy=imul(scale,isin(angle));
data.rotozoomer.dx=dx;
data.rotozoomer.dy=dy;
data.rotozoomer.x0=-dx*320-dy*200;
data.rotozoomer.y0=-(dy&0xffffff80)*320+dx*200;
data.rotozoomer.pos=PackCoordinates(data.rotozoomer.x0,data.rotozoomer.y0);
data.rotozoomer.delta=PackCoordinates(dx,dy);
//Hasta aquí se ejecuta 1 vez por cuadro
for(int y=0;y<400;y++)// Masteries, esto se ejecuta 400 veces, pues la textura a rotar ocupa toda la pantalla
{
int pos=icos(t*20);
data.rotozoomer.texture[y]=(32*(isin(y*6+pos)+Fix(1))/8192);
if(data.rotozoomer.texture[y]>31) data.rotozoomer.texture[y]=31;
}
2º) La función que genera las señales analógicas de los píxeles es la encargada de mostar la imagen rotada; se utiliza la memoria de cache para datos DSP de 64 KB para escribir en ella la textura rotada (cada valor de píxel ya transformado) y esta caché de hasta 64 KB es la que contiene los datos que busca el DMA del Timer 1, el Timer 8 marca el ritmo de funcionamiento del DMA. La CPU no interviene en estas transferencias DMA, una vez programadas se ejecutan solas, no comparte el bus de datos con la CPU, CPU y DMA pueden leer de la Data cache DSP de 64 KB al mismo tiempo. Hay dos caches de datos, la normal de 128 Bytes y la específica para DSP de 64 KB, ambas igual de rápidas. El ancho de banda de ROM y RAM, y de caches es de 480 MB/s.
static void RotozoomHSyncHandler()
{
int line=HandleVGAHSync400();
if(line<0) return;
register uint32_t r0 __asm__("r0")=data.rotozoomer.pos;
register uint32_t r1 __asm__("r1")=data.rotozoomer.delta;
register uint32_t r2 __asm__("r2")=0xf81f;
register uint32_t r3 __asm__("r3")=0x20000000+(data.rotozoomer.texture[line]<<5);
register uint32_t r4 __asm__("r4")=0x40021015;
#define P \
" adcs r0,r1 \n" \
" and r5,r0,r2 \n" \
" ldrb r6,[r3,r5] \n" \
" strb r6,[r4] \n"
__asm__ volatile(
" b .start \n"
" .align 4 \n"
".start: \n"
P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P
P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P
P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P
P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P
P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P
P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P
P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P
P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P
P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P
P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P
P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P
P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P
P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P
P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P
P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P
P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P
P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P
P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P
P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P
P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P
#undef P
".end: \n"
:
: "r" (r0), "r" (r1), "r" (r2), "r" (r3), "r" (r4)
:"r5","r6");
SetVGASignalToBlack();
data.rotozoomer.x0+=data.rotozoomer.dy;
data.rotozoomer.y0-=data.rotozoomer.dx;
data.rotozoomer.pos=PackCoordinates(data.rotozoomer.x0,data.rotozoomer.y0);
Prepara los registros internos de la CPU del 0 al 4 (y utilizará el 0, el 5 y el 6 para ir guardando los resultados) con los datos actualizados por la función del código que he mostrado antes.
Esas 4 instrucciones en ensamblador son las que colocan en esa posición de la caché de datos DSP el valor del píxel que corresponde con la rotación, como este juego de 4 instrucciones se repite 640 veces, el compilador lo detecta y prepara la CPU para funcionar en modo burst (típico de las CPUs ARM, GP2X F100/F200, WIZ y compañía también lo tienen; en GP2X F100/F200 puedes utilizar dos burst al mismo tiempo, 1 por CPU), esto quiere decir que estas instrucciones se ejecutarán desde la cache de instrucciones del procesador y los datos intermedios que se puedan generar en la cache de datos de 128 Bytes, dejando libre a los periféricos la memoria ROM, la RAM y en gran medida la cache de datos DSP. Los periféricos pueden funcionar sólos al haber programado anteriormente sus DMA.
Lo hace píxel a píxel, pero de todas formas siempre tiene que ejecutar la función que genera los valores de cada uno de los píxeles, sólo que en este caso, aplica unas pocas operaciones a cada píxel.
Y así es como rota y hace zoom de una textura que cubre la pantalla entera.
Es impresionante el dominio de la arquitectura que tiene el autor de este código, yo conozco bien esta arquitectura, pues trabajo con ella, pero ni de lejos la conozco tan en profundidad como para lograr algo así yo sólo.
¿Y si le ponemos una tarjeta SD (ya tiene el periférico para leerlas) y 16 MB de ram externos y nos montamos una recreativa de 32 bits con gráficos a 320x200x8 bit ? Lo complicado ya está hecho

el audio es más fácil que todo esto, tengo un mezclador que viene de ejemplo con la placa.
Es posible que puedas sacar ideas de aquí, splinter, los intel x86 también tienen modo burst y eso lo configura el compilador solito al generar el código máquina, es algo a lo que se le puede sacar mucho partido.