GP2X Gp2x Demo Development


Way to wake up an old thread :p

I spent a few hours reading the full thread, since the links to part 2 and 3 of the Demo Dev PDFs are dead. There were also some dead links here, especially the ones near the end, when you had solved some issues with Exit to menu etc. and I was hoping to have a look at the finished framework v6b. Darn! :angry:

I guess it's on archive.gp32x.de somewhere?

I'm a scene coder with a bit of spare time on my hands, and was inspired by the Nom demo when I was at Breakpoint this Easter.

Dwelch's suggestion to 'turn off Linux' and have my way with the hardware was appealing to me, since it's the first thing I do when I start coding demos for any platform. Nicely own resources, nicely stop processes, then set my own ints and let the OS have a break ;)


I just translated SDL's gp2x_joystick_read to pascal, using /dev/mem and mmap to read the hw regs. I would like to go all Assembler shortly. But doesn't mmap essentially hide the physical hw reg addresses from me? I'd like to, once I own the system, to access them without any table lookups or similar. (An include was mentioned in an SDK, but the link was dead.)


- So: Is there a list of physical hw reg addresses, their bits, and their names?


I think I will also follow dwelch's advice regarding caching and communication; is there also advice / examples you guys could point me to, on how to nicely fire Linux and rehire him on exit? :)


Thankful for any advice, checking rlyeh's hello world example...

Edit: Found the SDK. :p What I'm after is how to access the hw regs in an OS friendly way. Is it safe, if I own the machine, to just go

CODE
ldr r0, nMSP_TCOUNT
mov r0, [r0]


?
 
Way to reply to my own post! :p


Last bits of spare time has been spent in gp2x-land, and I think I found the answer to my own question.


If Linux is running, the OS friendly way is to mmap the hew reg area to another part of memory. Then the pointer returned by mmap should be used to r/w those regs, uncached.

On the 940 where there is no Linux and no MMU, physical addresses are the order of the day, in which case my above example could be used, and the address space offset used.

But there's still the question if the 920 MMU would pass an asm statement's STR to the correct address without protesting. I will simply test.


But for my own purposes, I'd like to set my own vsync interrupt, so shooting Linux in the head (not least to make sure it doesn't interrupt my frame loop code, poke hw regs when I don't want to, etc) is very attractive since I'm hoping to do an all-asm demo.

Thoughts?
 
To suspend Linux:
1) Copy some code to >32MB
2) Disable all interrupts
3) Jump to the code >32MB to ensure you are free of the MMU for the next step
4) Disable the MMU, build your own table and re-enable. You may want to save the old value for later however and keep >32MB if you wish to re-hire Linux later on.
5) By default, exception vectors should be at 0xFFFF0000, so make sure you use the MMU to map this to a free space of memory. It recommended not to set the exceptions vectors at 0, as Linux may use this memory.

To re-hire Linux:
1) Ensure you are in a MMU-free part of memory, so that when you disable the mmu, you don't get a data abort through reading an invalid memory address.
2) Disable the MMU and put Linux's value back
3) Re-enable interrupts
4) Jump back to pre-32MB location you came from.

Also note, that without MMU enabled, cached and buffered will not be activated, so your code will run a lot slower.
 
Squidge said:
To suspend Linux:
1) Copy some code to >32MB
2) Disable all interrupts
3) Jump to the code >32MB to ensure you are free of the MMU for the next step
4) Disable the MMU, build your own table and re-enable. You may want to save the old value for later however and keep >32MB if you wish to re-hire Linux later on.
5) By default, exception vectors should be at 0xFFFF0000, so make sure you use the MMU to map this to a free space of memory. It recommended not to set the exceptions vectors at 0, as Linux may use this memory.

To re-hire Linux:
1) Ensure you are in a MMU-free part of memory, so that when you disable the mmu, you don't get a data abort through reading an invalid memory address.
2) Disable the MMU and put Linux's value back
3) Re-enable interrupts
4) Jump back to pre-32MB location you came from.

Also note, that without MMU enabled, cached and buffered will not be activated, so your code will run a lot slower.
Sweet! Yeah, the point is to fire and re-hire :)

I did a solid 10 hours of reading PDFs and taking notes today, and a few hours last night. I devised something similar although I generated an exception to put me in Supervisor mode while firing Linux. Safer? Necessary? Will look at both anyway.

Yeah, executing MMU-altering code in MMapped memory is bad mojo :)


Great! If I wanted to utilize (and mmap) memory < 32MB, how would I find out which memory areas are unused by the OS? (Will take a look on clib.c and asmlib.s.) Cos I could declare a huge var and load input graphics etc into that, but there might still be megs and megs of memory available!
 
Last edited by a moderator:
Back
Top