PDA

Ver la versión completa : Copiar bloques de memoria via DMA



leander
11/08/2004, 22:49
Nas, estoy usando el SDK de gamepark, y en vez de sobrecargar la CPU para el copiado de bloques (por ejemplo un bitmap al framebuffer), quisiera hacerlo por DMA (que se supone va mas rápido).

He mirado la info del API del SDK y no veo ninguna función para utilizar el DMA.

¿Acaso las funciones Gpbitblt y Gptransblt utilizan el DMA? Yo creo que no.

Quisiera tenerlo más controlado, sé que el DMA tiene 4 ports (0-3) y que hay que comprobar que el Dma esté libre para volver a utlizar.

¿Alguien sabe algo?

Me he enterado que el SDK de Mr. Mirkos posee las funciones que estoy buscando, pero.. ¿acaso no lo tiene el SDK oficial?

Wave
12/08/2004, 07:29
Pues yo diria que no tiene el sdk oficial, de todos modos la pantalla de la gp32 esta rotada, asi que o tienes los sprites rotados o el dma sirve de poco.

Darumo
12/08/2004, 10:05
asi que o tienes los sprites rotados o el dma sirve de poco.

siempre podria montarse una instruccion para la carga de Sprites que los rote al meterlos en la RAM, siempre hay soluciones para todo.

kuG
13/08/2004, 23:52
Como bien dices en el sdk de mrmirko si que se puede copiar memoria por dma. No creo que sea demasiado util para pintar sprites por pantalla... total solo copias memoria y la mayoria de sprites no los escribes en una zona de memoria continua (los sprites de igual de ancho de la pantalla no son muy comunes xD). De todas maneras si haces un juego o cualquier aplicacion con un fondo fijo si que puedes poner que se vaya copiando por dma el fondo mientras haces tus calculos, y cuando termine el dma pintas encima lo que sea.

mortimor
14/08/2004, 09:22
Por si te aburres... funcioncita by MrSpiv:


void DMA0CopyStart( unsigned char *s, unsigned char *d, long size ) {
// Stop DMA0

*dmasktrig0 |= 0x04;

// Setup source...
// select system bus (AHB)
// select address increment

*disrc0 = (long)s;

// Setup destination...
// select system bus (AHB)
// select address increment

*didst0 = (long)d;

// DMA0 con..

*dcon0 = (0 << 30) | // demand mode
(1 << 29) | // DREQ & DACK are synched to HCLK (AHB)
(0 << 28) | // disable DMA0 int
(0 << 27) | // unit transfer
(1 << 26) | // whole servmode
(0x00 << 24) | // HWSRCSEL ?? not used
(0 << 23) | // sw request mode
(1 << 22) | // auto reload off
(0x02 << 20) | // data size == word
(size >> 2); // count..

// start DMA.. and don't wait for it to finish..

*dmasktrig0 = 0x03;
}

leander
15/08/2004, 15:06
Interesante rutina, gracias!!!

De todas formas ahora mismo paso del SDK oficial y me dedico al SDK de mrmirko.

Lo malo del SDK de mrmirko:

1. Que solo hay función para añadir un solo color a la paleta y no los 256 colores de golpe, es decir la función que viene hay que meterlos color a color en la paleta de uno en uno. (256 veces).

2.No trabaja ni hay funciones con sprites en el modo de 8 bits.

LO BUENO:

Que he solucionado todo, he hecho una función que mete todos los colores de una paleta apuntado por un array DE GOLPE y de una sola vez.

Y para las funciones de sprites, he creado un clon del Gp_bitblt y Gp_bittransblt del SDK oficial para el SDK de MrMirko :D

:brindis:

Si os interesa el código lo posteo (es mucho texto a ver si cabe todo en un solo post).

leander
16/08/2004, 10:13
Bueno, ahi va:

leanderPutPalette(unsigned short *pal256)
//pal256->puntero a array de paleta (debe contener 256 colores)
{
u32 *palette = (u32*) PALETTE;
while ((rLCDCON5>>19) == 2);
int x;
for (x=0;x<256;x++) palette[x]=pal256[x];
}




leanderBlt(int tag,u8 *dest,int xpos_dest,int ypos_dest,int wpixels_start,int hpixels_start,u8 *source,int xpos_start,int ypos_start,int wsource,int hsource)
// version 0.9 beta
// CLON DEL GP_BITBLIT PARA EL SDK DE MIRKO
//13-8-04 BY LEANDER

//INT tag-> no se utiliza, pasarle NULL
//U8 *dest->puntero a destino (framebuffer)
//INT xpos_dest->posicion x en pantalla (framebuffer)
//INT ypos_dest->posicion y en pantalla (framebuffer)
//INT wpixels_start->anchura del bloque (sprite) a copiar
//INT hpixels_start->altura del bloque (sprite) a copiar
//U8 *source->puntero a imagen fuente
//INT xpos_dest->posicion x de imagen fuente
//INT ypos_dest->posicion y de imagen fuente
//INT wsource->anchura total de la imagen fuente
//INT hsource->altura total de la imagen fuente
//
//RETURN 0
//
//IMPORTANTE: Procurar que los valores introducidos no estén fuera de los
//límites del framebuffer.


{
u8 *pbuffer;
u8 *porigin;
pbuffer=dest;
porigin=source;

porigin=porigin+(xpos_start*hsource)+(hsource-hpixels_start-ypos_start); //horizontal and vertical pos source
pbuffer=pbuffer+(240*xpos_dest)+(240-ypos_dest-hpixels_start);// horizontal and vertical pos dest

int x;
for (x=0;x<wpixels_start;x++)
{
int y;
for (y=0;y<hpixels_start;y++)

{
*pbuffer++=porigin[y];
}

porigin=porigin+hsource;
pbuffer=pbuffer+240-hpixels_start;
}
}





leanderTransBlt(int tag,u8 *dest,int xpos_dest,int ypos_dest,int wpixels_start,int hpixels_start,u8 *source,int xpos_start,int ypos_start,int wsource,int hsource,int color)
// version 0.9 beta
// CLON DEL GP_BITTRANSBLIT PARA EL SDK DE MIRKO
//13-8-04 BY LEANDER

//INT tag-> no se utiliza, pasarle NULL
//U8 *dest->puntero a destino (framebuffer)
//INT xpos_dest->posicion x en pantalla (framebuffer)
//INT ypos_dest->posicion y en pantalla (framebuffer)
//INT wpixels_start->anchura del bloque (sprite) a copiar
//INT hpixels_start->altura del bloque (sprite) a copiar
//U8 *source->puntero a imagen fuente
//INT xpos_dest->posicion x de imagen fuente
//INT ypos_dest->posicion y de imagen fuente
//INT wsource->anchura total de la imagen fuente
//INT hsource->altura total de la imagen fuente
//INT color->color index de la paleta a ser transparente
//
//RETURN 0
//
//IMPORTANTE: Procurar que los valores introducidos no estén fuera de los
//límites del framebuffer.


{
u8 *pbuffer;
u8 *porigin;
pbuffer=dest;
porigin=source;


porigin=porigin+(xpos_start*hsource)+(hsource-hpixels_start-ypos_start); //horizontal and vertical pos source
pbuffer=pbuffer+(240*xpos_dest)+(240-ypos_dest-hpixels_start);// horizontal and vertical pos dest

int x;
int test=0;
for (x=0;x<wpixels_start;x++)
{
int y;
for (y=0;y<hpixels_start;y++)

{
if (porigin[y]!=color) *pbuffer=porigin[y];
pbuffer++;
}

porigin=porigin+hsource;
pbuffer=pbuffer+240-hpixels_start;
}

}