GernotFrisch
Member
- Joined
- Jan 2, 2007
- Messages
- 445
Code:
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <linux/fb.h>
#include <unistd.h>
#include <stropts.h>
#include <memory.h>
volatile int Uppermemfd;
volatile void *UpperMem=NULL;
volatile unsigned long *gp2x_memreg32=NULL;
volatile unsigned short *gp2x_memreg16=NULL;
volatile unsigned long* blitter32=NULL;
#define SCREEN_COMMON 0x3000000
#define SCREEN0 0x3101000
#define SCREEN1 0x3381000
void Flip()
{
//Wait till the blitter is ready
printf("wait for blitter\n");
while(blitter32[0x0034 >> 2] & 1) usleep(1);
printf("Wait for vlbank\n");
// VBlank
while( gp2x_memreg16[0x1182>>1]&(1<<4) );
while(!(gp2x_memreg16[0x1182>>1]&(1<<4)));
//Set the destination as 16bit and enable it for use.
blitter32[0x0000 >> 2] = (1 << 5) | (1 << 6);
//Set the address of destination
blitter32[0x0004 >> 2] = SCREEN0; // front screen buffer
//Set the pitch of destination in bytes.
blitter32[0x0008 >> 2] = 320*2;
//Set a 16bit source, enable source and say the source is not controlled by CPU(?)
blitter32[0x000C >> 2] = (1 << 8) | (1 << 7) | (1 << 5);
//Set the source address
blitter32[0x0010 >> 2] = SCREEN1; // 0x3101000 + 320*2*240;
//Set the pitch of source in bytes
blitter32[0x0014 >> 2] = 320*2;
//Do nothing with patern
blitter32[0x0020 >> 2] = 0;
//Set the size 320 by 240
blitter32[0x002C >> 2] = (240 << 16) | (320 << 0);
//Clear the source input FIFO, positive X,Y. And do a copy ROP.
blitter32[0x0030 >> 2] = (1 << 10) | (1 << 9) | (1 << 8) | 0xCC;
//Make the blitter run.
asm volatile("":::"memory");
blitter32[0x0034 >> 2] = 0x0001;
printf("Copy OK\n");
}
int main()
{
Uppermemfd = open("/dev/mem", O_RDWR);
/* map the MMSP2 registers */
gp2x_memreg32 = (unsigned long*)mmap(0, 0x10000, 3, MAP_SHARED, Uppermemfd, 0xc0000000);
gp2x_memreg16 = (unsigned short*)gp2x_memreg32;
/* map the blitter registers */
blitter32 = (volatile unsigned long*)mmap(0, 0x100, 3, MAP_SHARED, Uppermemfd, 0xe0020000);
volatile unsigned char* gp2x_mem = (volatile unsigned char*)mmap(0, 0xf00000, 3, MAP_SHARED, Uppermemfd, SCREEN_COMMON);
void* pRawFrameBuffer = (void*)&gp2x_mem[0x100000];
unsigned short* cBuffer = (unsigned short*)&gp2x_mem[0x180000];
/* init the screen to 320x240 16bpp */
gp2x_memreg16[0x28da >> 1] = 0x004ab;
gp2x_memreg16[0x290c >> 1] = 640;
/* enable the hardware acceleration */
gp2x_memreg16[0x090a >> 1] = 0xffff;
gp2x_memreg16[0x0904 >> 1] |= (1 << 10);
printf("Blitter: %p\n", blitter32);
printf("writing to back buffer\n");
memset(cBuffer, 0, 320*240*2);
printf("worked!\n");
for(int cc=0;++cc;)
{
Flip();
// some gfx garbage to see if it moves
// cBuffer[cc%(320*240)] = (cc*cc+1234);
}
return 0;
}
Output:
Blitter: 0x40010000
writing to back buffer
worked!
wait for blitter
<freezes>
What can I do / what did I do wrong?