Double Buffering


xorg

Still Fresh
Joined
Feb 1, 2006
Messages
11
What's wrong with this? I don't see a white screen. I filled the whole area with white, but I'm being pointed to a totally different area of memory.


Code:
#include <stdint.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>


int main(int argc, char** argv)
{
	uint16_t volatile* regs;
	uint32_t mem_len;
	uint16_t* mapped_mem;
	int32_t mem_fd;


	mem_fd = open("/dev/mem", O_RDWR);

	mapped_mem = mmap(0, 0x500000, PROT_READ|PROT_WRITE, MAP_SHARED,
  mem_fd,  0x3101000);

	regs = mmap(0, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, mem_fd, 0xC0000000);

	memset(mapped_mem, 0xFF, 0x500000);

	regs[0x290E>>1] = 0x3101000 & 0xFFFF;
	regs[0x2910>>1] = 0x3101000 >> 16;
	regs[0x2912>>1] = 0x3101000 & 0xFFFF;
	regs[0x2914>>1] = 0x3101000 >> 16;

	sleep(2);

	munmap(mapped_mem, 0x500000);
	close(mem_fd);

	chdir("/usr/gp2x");
	execl("gp2xmenu", "gp2xmenu", (char*)0);
	return 0;
}
 
gfoot posted on Feb 1 2006 at 10:38 AM said:
What compiler are you using?

gcc 2.95.3
 
Last edited by a moderator:
5mb? ouch! If you only want to wipe the frame buffer, thats 320*240*2 = 150KB.

Other than that, your code should work. 0x3101000 is the normal buffer, so there's no need to select it. Note however that you shouldn't assume this address, as it could change is later firmwares - you should instead request the physical address from the frame buffer driver for each buffer you want to play with.

EDIT: Ah, gcc 2.95.3. That version doesn't work very well, I tried it ages ago. Doesn't write to hardware registers properly. You'll need to upgrade. A way around if you don't want to upgrade is that you'll need to treat all the registers as 32-bit rather than 16-bit and then do all the masking in software.
 
Squidge posted on Feb 1 2006 at 01:16 PM said:
5mb? ouch! If you only want to wipe the frame buffer, thats 320*240*2 = 150KB.

Other than that, your code should work. 0x3101000 is the normal buffer, so there's no need to select it. Note however that you shouldn't assume this address, as it could change is later firmwares - you should instead request the physical address from the frame buffer driver for each buffer you want to play with.

EDIT: Ah, gcc 2.95.3. That version doesn't work very well, I tried it ages ago. Doesn't write to hardware registers properly. You'll need to upgrade. A way around if you don't want to upgrade is that you'll need to treat all the registers as 32-bit rather than 16-bit and then do all the masking in software.


I figured it was something with the compiler, but I have not seen anyone complain about it. I assumed those values in my posted code to make it as less cluttered as possible, i know getting smem_start from the fb is more reliable in regards to dependability in the future. I tried filling the 5 megs full because i wanted to see if any part of it was visible to me. I know there's no point in having that much mapped space for the fb, hah.

I've been doing various projects and I'd simply write to the framebuffer but whenever i put in the address to the still rgb image registers, it would go somewhere else. I don't have a serial cable and I haven't messed with the USB-serial hack that was released, so I would output different data to a file. I read the value of the rgb offset regs right after i set it to an address, and it seemed that the value returned was 2-100 off for the high and low short, meaning that it pointed to some point far away from where I was looking for. I didn't know there was an "issue" with earlier versions of gcc to where I couldn't access it as 16 bits. Upgrading would be the easiest thing to do, so I'll try that later. thanks for the information, is there any article or information on what gcc does that?

I thought something was wrong when following the documentation didnt work, as well as everything compiled from source that used the registers didnt work :)
 
Last edited by a moderator:
I don't know if there's documentation stating which compilers do it, I've only noticed 2.95.3 myself as that's the exact same compiler I tried to use first with exactly the same results. Being new to the GP2X, it drove me absolutely nuts for an entire day until I found out you could only access it as 32-bit values. When the new compilers came out, I used the same technique, but other people said 16-bit values worked too, so I moved over. A lot of people didn't notice the bugs as they started on GCC4.

One other thing I noticed is that all my projects I created with 2.95 ran at almost double the speed under GCC4 :eek: and that with full optimization on both compilers. Maybe it was all the hardware hacking I was doing that was actually slowing it down, as GCC2.95 certainly didn't like it.
 
I noticed this stuff too, I couldn't work out why I could read some of the GP2X buttons but not others - it turns out the 2.95 compiler implements 16-bit memory reads and writes as two 8-bit operations, which is a bad idea if it's a memory mapped hardware register.
 
Yup, not good when your trying to learn the hardware and the compiler just makes it more difficult!
 
Back
Top