GP2X Upper Memory Useage, Sound Buffer?


Daid

Member
Joined
Jun 13, 2006
Messages
267
Location
Netherlands
Website
Visit site
In my clonk port I simply trampled over the upper memory and used the full 32MB. As some point I hit the frame buffer.

Reading the FAQ here: http://wiki.gp2x.org/wiki/Development_FAQ#Memory_Layout
That's probly at 0x03101000 right?

But I also noticed that one of my textures had a large black line trough it. But it turned into colors when sounds where played. So I guess there has to be a soundbuffer out there somewhere. Any idea where it is?

I'm using the basic SDL libraries and SDL_Mixer.
 
Write a routine to fill the upper memory with its own addresses, play some sound, check what changed ;)
 
Code:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifndef WIN32
#include <sys/dir.h>
#endif
#include <unistd.h>
#include <SDL.h>
#include <SDL_Mixer.h>

#include "Keys.h"

#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <linux/fb.h>
#include <unistd.h>
#include <stropts.h>

int memfd;
long* UpperMem;

void PreLoop()
{
  memfd = open("/dev/mem", O_RDWR);
  UpperMem = (long*)mmap(0, 0x2000000, PROT_READ|PROT_WRITE, MAP_SHARED, memfd, 0x2000000);
  for(int i=0;i<0x2000000/4;i++)
	UpperMem[i] = i;
}

void PostLoop()
{
  int CorrupStart = 0;
  int NewDataCount=0;
  int NewData[0x1000];
  for(int i=0;i<0x2000000/4;i++)
  {
	if (UpperMem[i] != i)
	{
	  if (!CorrupStart)
	  {
		CorrupStart = (i*4) + 0x2000000;
		int j;
		for(j=0;j<NewDataCount;j++)
		  if (NewData[j] == UpperMem[i])
			break;
		if (j == NewDataCount && NewDataCount < 0x1000)
		{
		  NewData[j] = UpperMem[i];
		  NewDataCount++;
		}
	  }
	}else{
	  if (CorrupStart)
	  {
		printf("Corruption from %p to %p (Size: 0x%x)\n", CorrupStart, (i*4) + 0x2000000 - 1, (i*4) + 0x2000000 - CorrupStart);
		for(int j=0;j<NewDataCount;j++)
		  printf("New Data: 0x%x\n", NewData[j]);
		NewDataCount = 0;
		CorrupStart = 0;
	  }
	}
  }
  if (CorrupStart)
  {
	printf("Corruption from %p to %p (%p)\n", CorrupStart, 0x3FFFFFF, NewData);
  }
  close(memfd);
}

SDL_Surface *Screen = NULL;

void MainLoop()
{
  int bQuit = 100;
  int LastTickCount = SDL_GetTicks();
  int Cursor = 0;
  int Cursor2 = 0;
  while(bQuit)
  {
	while(LastTickCount + 17 > SDL_GetTicks());//17 ~= 1000/60 (60FPS)
		LastTickCount = SDL_GetTicks();
	  bQuit--;
		SDL_Event event;
		while (SDL_PollEvent (&event))
		{
		switch (event.type)
			{
			case GP2X_EVENT_DOWN:
			case SDL_QUIT:
				bQuit = 1;
				break;
	  }
	}
	
	SDL_FillRect(Screen, NULL, 0xF00F);
	
	SDL_Flip(Screen);
  }
}

int main(int argc, char** argv)
{
  // Initialize SDL
  if (SDL_Init (SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK) < 0)
	printf("Couldn't initialize SDL: %s\n", SDL_GetError());
  Screen = SDL_SetVideoMode (320, 240, 16, SDL_SWSURFACE );
  if (Screen == NULL)
	printf("Couldn't set 320x240x16 video mode: %s\n", SDL_GetError ());
  if (Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 1, 4096))
		printf("Error opening SDL_Mixer: %s\n", Mix_GetError ());
	Mix_AllocateChannels(16);
	Mix_Volume(-1, MIX_MAX_VOLUME);
	
	// Check and open joystick device
	if (SDL_NumJoysticks() > 0)
		if(!SDL_JoystickOpen(0))
			printf("Couldn't open joystick 0: %s\n", SDL_GetError ());
  SDL_ShowCursor(SDL_DISABLE);
  
  PreLoop();
  MainLoop();
  PostLoop();
  
  Mix_CloseAudio();
  return 0;
}
Output:
Code:
Corruption from 0x3101000 to 0x31267ff (Size: 0x25800)
New Data: 0xf00ff00f
Corruption from 0x3600000 to 0x3607fff (Size: 0x8000)
New Data: 0x0
(This is with the normal SDK from GPH, not with the SDL hardware libs)

What does that learn us? Seems like only 1 framebuffer is used. So the 2nd buffer can be used as you wish.
Somewhere along the way of using SDL_Mixer to the sound output a buffer at 0x3600000 gets used. Multiple tests show that the size depents on the 'chunksize' given in the parameters of Mix_OpenAudio. As this parameter is probly passed to SDL_OpenAudio, it's the SDL libs that create this buffer.

The buffer holds 0x8000 bytes, with 16bit samples, 0x4000 samples, that's 4 times as many as requested. I was expecting double, as one buffer gets played while you fill the other. Maybe it uses 32bit samples internaly?
 
Back
Top