original source from gpsp09-2xb_src.tar.bz2

This commit is contained in:
notaz
2009-05-21 18:48:31 +03:00
commit 2823a4c819
60 changed files with 165404 additions and 0 deletions

51
gp2x/Makefile Normal file
View File

@@ -0,0 +1,51 @@
# gpSP makefile
# Gilead Kutnick - Exophase
# GP2X port(ion) - Z
# Global definitions
PREFIX = /opt/open2x/gcc-4.1.1-glibc-2.3.6
CC = $(PREFIX)/bin/arm-open2x-linux-gcc
STRIP = $(PREFIX)/bin/arm-open2x-linux-strip
OBJS = main.o cpu.o memory.u video.o input.o sound.o gp2x.o gui.o \
cheats.o zip.o cpu_threaded.z cpu_speed.o cpuctrl.o \
gp2xminilib.o font.o display.o speedtest.o cmdline.o daemon.o \
arm_stub.o video_blend.o
BIN = gpsp.gpe
# Platform specific definitions
VPATH += ..
CFLAGS += -DARM_ARCH -DGP2X_BUILD
# NOTE: -funroll-loops will slow down compiling considerably
CFLAGS += -O3 -std=c99 -msoft-float -funsigned-char -fno-common \
-fno-builtin \
INCLUDES = `$(PREFIX)/bin/arm-open2x-linux-sdl-config --cflags`
LIBS = `$(PREFIX)/bin/arm-open2x-linux-sdl-config --libs` \
-lm -ldl -lpthread -lz -static
# Compilation:
.SUFFIXES: .c
%.z: %.c
$(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $<
%.u: %.c
$(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $<
%.o: %.c
$(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $<
%.o: %.S
$(CC) $(ASFLAGS) $(INCLUDES) -c -o $@ $<
all: $(OBJS)
$(CC) $(OBJS) $(LIBS) -o $(BIN)
$(STRIP) $(BIN)
clean:
rm -f *.o *.u *.z $(BIN)

48
gp2x/align_test.c Normal file
View File

@@ -0,0 +1,48 @@
// Betting on GCC aligning this for efficiency.
#include <stdio.h>
int main()
{
unsigned short int read_16 = 0xF1F2;
unsigned int read_32 = 0xF1F2F3F4;
unsigned short int write_16 = 0xF00D;
unsigned int write_32 = 0xF00DFEED;
// 16bit unsigned reads, we expect 0xF1F2 and 0xF20000F1
fprintf(stderr, "%04x %04x\n",
*((unsigned short int *)((char *)&read_16)),
*((unsigned short int *)((char *)&read_16 + 1)));
// 16bit signed reads, we expect 0xFFFFF1F2 and 0xFFFFFFF1
fprintf(stderr, "%04x %04x\n",
*((short int *)((char *)&read_16)),
*((short int *)((char *)&read_16 + 1)));
// 32bit reads, we expect 0xF1F2F3F4, 0xF4F1F2F3, 0xF3F4F1F2,
// and 0xF2F3F4F1
fprintf(stderr, "%08x %08x %08x %08x\n",
*((int *)((char *)&read_32)),
*((int *)((char *)&read_32 + 1)),
*((int *)((char *)&read_32 + 2)),
*((int *)((char *)&read_32 + 3)));
// 16bit writes, we expect write_16 to remain 0xF00D
*((short int *)((char *)&write_16)) = 0xF00D;
*((short int *)((char *)&write_16) + 1) = 0xF00D;
fprintf(stderr, "%04x\n", write_16);
// 32bit writes, we expect write_32 to remain 0xF00DFEED
*((int *)((char *)&write_16)) = 0xF00DFEED;
*((int *)((char *)&write_16) + 1) = 0xF00DFEED;
*((int *)((char *)&write_16) + 2) = 0xF00DFEED;
*((int *)((char *)&write_16) + 3) = 0xF00DFEED;
fprintf(stderr, "%08x\n", write_32);
return 0;
}

1392
gp2x/arm_codegen.h Normal file

File diff suppressed because it is too large Load Diff

1661
gp2x/arm_dpimacros.h Normal file

File diff suppressed because it is too large Load Diff

1952
gp2x/arm_emit.h Normal file

File diff suppressed because it is too large Load Diff

1016
gp2x/arm_stub.S Normal file

File diff suppressed because it is too large Load Diff

478
gp2x/bios_cache.S Normal file
View File

@@ -0,0 +1,478 @@
//Gp2x/gp2x/mnt/nand/bios_cache.bin: file format binary
Disassembly of section .data:
00000000 <.data>:
0: e3a00f02 mov r0, #8 ; 0x8
4: ebcb1afd bl step_debug
8: e25cc001 subs ip, ip, #1 ; 0x1
c: 5a000001 bpl 0x18
10: e3a00d05 mov r0, #320 ; 0x140
14: ebcb18d0 bl 0xff2c635c
18: eaffffff b 0x1c
1c: e3a00d05 mov r0, #320 ; 0x140
20: ebcb1af6 bl step_debug
24: e59a9034 ldr r9, [sl, #52]
28: e249900c sub r9, r9, #12 ; 0xc
2c: e59a0034 ldr r0, [sl, #52]
30: e240000c sub r0, r0, #12 ; 0xc
34: e58a0034 str r0, [sl, #52]
38: e3c99003 bic r9, r9, #3 ; 0x3
3c: e2890000 add r0, r9, #0 ; 0x0
40: e59a102c ldr r1, [sl, #44]
44: ebcb1a8e bl 0xff2c6a84
48: e2890004 add r0, r9, #4 ; 0x4
4c: e1a01007 mov r1, r7
50: ebcb1a8b bl 0xff2c6a84
54: e2890008 add r0, r9, #8 ; 0x8
58: e1a01008 mov r1, r8
5c: e3a02f51 mov r2, #324 ; 0x144
60: ebcb1a6f bl 0xff2c6a24
64: e3a00f51 mov r0, #324 ; 0x144
68: ebcb1ae4 bl step_debug
6c: e2480002 sub r0, r8, #2 ; 0x2
70: ebcb1a95 bl 0xff2c6acc
74: e1a07000 mov r7, r0
78: e3a00f52 mov r0, #328 ; 0x148
7c: ebcb1adf bl step_debug
80: e3a01e15 mov r1, #336 ; 0x150
84: e2810078 add r0, r1, #120 ; 0x78
88: e58a002c str r0, [sl, #44]
8c: e3a00f53 mov r0, #332 ; 0x14c
90: ebcb1ada bl step_debug
94: e59a002c ldr r0, [sl, #44]
98: e0800107 add r0, r0, r7, lsl #2
9c: ebcb1ac9 bl 0xff2c6bc8
a0: e1a07000 mov r7, r0
a4: e3a00e15 mov r0, #336 ; 0x150
a8: ebcb1ad4 bl step_debug
ac: ebcb194d bl 0xff2c65e8
b0: e58a002c str r0, [sl, #44]
b4: e3a00f55 mov r0, #340 ; 0x154
b8: ebcb1ad0 bl step_debug
bc: e59a9034 ldr r9, [sl, #52]
c0: e2499004 sub r9, r9, #4 ; 0x4
c4: e59a0034 ldr r0, [sl, #52]
c8: e2400004 sub r0, r0, #4 ; 0x4
cc: e58a0034 str r0, [sl, #52]
d0: e3c99003 bic r9, r9, #3 ; 0x3
d4: e2890000 add r0, r9, #0 ; 0x0
d8: e59a102c ldr r1, [sl, #44]
dc: e3a02f56 mov r2, #344 ; 0x158
e0: ebcb1a4f bl 0xff2c6a24
e4: e3a00f56 mov r0, #344 ; 0x158
e8: ebcb1ac4 bl step_debug
ec: e59a102c ldr r1, [sl, #44]
f0: e2010080 and r0, r1, #128 ; 0x80
f4: e58a002c str r0, [sl, #44]
f8: e3a00f57 mov r0, #348 ; 0x15c
fc: ebcb1abf bl step_debug
100: e59a102c ldr r1, [sl, #44]
104: e381001f orr r0, r1, #31 ; 0x1f
108: e58a002c str r0, [sl, #44]
10c: e3a00e16 mov r0, #352 ; 0x160
110: ebcb1aba bl step_debug
114: e59a002c ldr r0, [sl, #44]
118: e3a02e16 mov r2, #352 ; 0x160
11c: e3a010ff mov r1, #255 ; 0xff
120: e38114ff orr r1, r1, #-16777216 ; 0xff000000
124: ebcb190a bl 0xff2c6554
128: e3a00f59 mov r0, #356 ; 0x164
12c: ebcb1ab3 bl step_debug
130: e59a9034 ldr r9, [sl, #52]
134: e2499008 sub r9, r9, #8 ; 0x8
138: e59a0034 ldr r0, [sl, #52]
13c: e2400008 sub r0, r0, #8 ; 0x8
140: e58a0034 str r0, [sl, #52]
144: e3c99003 bic r9, r9, #3 ; 0x3
148: e2890000 add r0, r9, #0 ; 0x0
14c: e59a1008 ldr r1, [sl, #8]
150: ebcb1a4b bl 0xff2c6a84
154: e2890004 add r0, r9, #4 ; 0x4
158: e1a01008 mov r1, r8
15c: e3a02f5a mov r2, #360 ; 0x168
160: ebcb1a2f bl 0xff2c6a24
164: e3a00f5a mov r0, #360 ; 0x168
168: ebcb1aa4 bl step_debug
16c: e3a01e17 mov r1, #368 ; 0x170
170: e2818000 add r8, r1, #0 ; 0x0
174: e3a00f5b mov r0, #364 ; 0x16c
178: ebcb1aa0 bl step_debug
17c: e1a00007 mov r0, r7
180: e24cc016 sub ip, ip, #22 ; 0x16
184: eacb18be b 0xff2c6484
188: e3a00ff1 mov r0, #964 ; 0x3c4
18c: e3800b02 orr r0, r0, #2048 ; 0x800
190: ebcb1a9a bl step_debug
194: e59a9034 ldr r9, [sl, #52]
198: e2499020 sub r9, r9, #32 ; 0x20
19c: e59a0034 ldr r0, [sl, #52]
1a0: e2400020 sub r0, r0, #32 ; 0x20
1a4: e58a0034 str r0, [sl, #52]
1a8: e3c99003 bic r9, r9, #3 ; 0x3
1ac: e2890000 add r0, r9, #0 ; 0x0
1b0: e59a1010 ldr r1, [sl, #16]
1b4: ebcb1a32 bl 0xff2c6a84
1b8: e2890004 add r0, r9, #4 ; 0x4
1bc: e59a1014 ldr r1, [sl, #20]
1c0: ebcb1a2f bl 0xff2c6a84
1c4: e2890008 add r0, r9, #8 ; 0x8
1c8: e1a01005 mov r1, r5
1cc: ebcb1a2c bl 0xff2c6a84
1d0: e289000c add r0, r9, #12 ; 0xc
1d4: e59a101c ldr r1, [sl, #28]
1d8: ebcb1a29 bl 0xff2c6a84
1dc: e2890010 add r0, r9, #16 ; 0x10
1e0: e59a1020 ldr r1, [sl, #32]
1e4: ebcb1a26 bl 0xff2c6a84
1e8: e2890014 add r0, r9, #20 ; 0x14
1ec: e1a01006 mov r1, r6
1f0: ebcb1a23 bl 0xff2c6a84
1f4: e2890018 add r0, r9, #24 ; 0x18
1f8: e59a1028 ldr r1, [sl, #40]
1fc: ebcb1a20 bl 0xff2c6a84
200: e289001c add r0, r9, #28 ; 0x1c
204: e1a01008 mov r1, r8
208: e3a02ff2 mov r2, #968 ; 0x3c8
20c: e3822b02 orr r2, r2, #2048 ; 0x800
210: ebcb1a03 bl 0xff2c6a24
214: e3a00ff2 mov r0, #968 ; 0x3c8
218: e3800b02 orr r0, r0, #2048 ; 0x800
21c: ebcb1a77 bl step_debug
220: e59a0008 ldr r0, [sl, #8]
224: e1a00580 mov r0, r0, lsl #11
228: e58a0028 str r0, [sl, #40]
22c: e3a00ff3 mov r0, #972 ; 0x3cc
230: e3800b02 orr r0, r0, #2048 ; 0x800
234: ebcb1a71 bl step_debug
238: e59a0028 ldr r0, [sl, #40]
23c: e128f00b msr CPSR_f, fp
240: e1b074a0 movs r7, r0, lsr #9
244: e10fb000 mrs fp, CPSR
248: e3a00ebd mov r0, #3024 ; 0xbd0
24c: ebcb1a6b bl step_debug
250: e3a00ff5 mov r0, #980 ; 0x3d4
254: e3800b02 orr r0, r0, #2048 ; 0x800
258: e1a08000 mov r8, r0
25c: e25cc00c subs ip, ip, #12 ; 0xc
260: 5a000002 bpl 0x270
264: e3a00fe9 mov r0, #932 ; 0x3a4
268: e3800b02 orr r0, r0, #2048 ; 0x800
26c: ebcb183a bl 0xff2c635c
270: eaffffff b 0x274
274: e3a00fe9 mov r0, #932 ; 0x3a4
278: e3800b02 orr r0, r0, #2048 ; 0x800
27c: ebcb1a5f bl step_debug
280: e3570000 cmp r7, #0 ; 0x0
284: e10fb000 mrs fp, CPSR
288: e3a00fea mov r0, #936 ; 0x3a8
28c: e3800b02 orr r0, r0, #2048 ; 0x800
290: ebcb1a5a bl step_debug
294: e24cc002 sub ip, ip, #2 ; 0x2
298: e128f00b msr CPSR_f, fp
29c: 1a000007 bne 0x2c0
2a0: 5a000002 bpl 0x2b0
2a4: e3a00fef mov r0, #956 ; 0x3bc
2a8: e3800b02 orr r0, r0, #2048 ; 0x800
2ac: ebcb182a bl 0xff2c635c
2b0: ea000013 b 0x304
2b4: e3a00feb mov r0, #940 ; 0x3ac
2b8: e3800b02 orr r0, r0, #2048 ; 0x800
2bc: ebcb1a4f bl step_debug
2c0: e3c774fe bic r7, r7, #-33554432 ; 0xfe000000
2c4: e3a00ebb mov r0, #2992 ; 0xbb0
2c8: ebcb1a4c bl step_debug
2cc: e0837007 add r7, r3, r7
2d0: e3a00fed mov r0, #948 ; 0x3b4
2d4: e3800b02 orr r0, r0, #2048 ; 0x800
2d8: ebcb1a48 bl step_debug
2dc: e313040e tst r3, #234881024 ; 0xe000000
2e0: e10fb000 mrs fp, CPSR
2e4: e3a00fee mov r0, #952 ; 0x3b8
2e8: e3800b02 orr r0, r0, #2048 ; 0x800
2ec: ebcb1a43 bl step_debug
2f0: e24cc004 sub ip, ip, #4 ; 0x4
2f4: e128f00b msr CPSR_f, fp
2f8: 0a000004 beq 0x310
2fc: e317040e tst r7, #234881024 ; 0xe000000
300: e10fb000 mrs fp, CPSR
304: e3a00fef mov r0, #956 ; 0x3bc
308: e3800b02 orr r0, r0, #2048 ; 0x800
30c: ebcb1a3b bl step_debug
310: e1a00008 mov r0, r8
314: e24cc001 sub ip, ip, #1 ; 0x1
318: eacb1859 b 0xff2c6484
31c: e3a00ff5 mov r0, #980 ; 0x3d4
320: e3800b02 orr r0, r0, #2048 ; 0x800
324: ebcb1a35 bl step_debug
328: e24cc001 sub ip, ip, #1 ; 0x1
32c: e128f00b msr CPSR_f, fp
330: 1a000007 bne 0x354
334: 5a000002 bpl 0x344
338: e3a00f09 mov r0, #36 ; 0x24
33c: e3800b03 orr r0, r0, #3072 ; 0xc00
340: ebcb1805 bl 0xff2c635c
344: ea0000d6 b 0x6a4
348: e3a00ff6 mov r0, #984 ; 0x3d8
34c: e3800b02 orr r0, r0, #2048 ; 0x800
350: ebcb1a2a bl step_debug
354: e59a0028 ldr r0, [sl, #40]
358: e08404a0 add r0, r4, r0, lsr #9
35c: e58a0028 str r0, [sl, #40]
360: e3a00ff7 mov r0, #988 ; 0x3dc
364: e3800b02 orr r0, r0, #2048 ; 0x800
368: ebcb1a24 bl step_debug
36c: e59a0008 ldr r0, [sl, #8]
370: e128f00b msr CPSR_f, fp
374: e1b00ca0 movs r0, r0, lsr #25
378: e10fb000 mrs fp, CPSR
37c: e58a0008 str r0, [sl, #8]
380: e3a00ebe mov r0, #3040 ; 0xbe0
384: ebcb1a1d bl step_debug
388: e24cc003 sub ip, ip, #3 ; 0x3
38c: e128f00b msr CPSR_f, fp
390: 2a000007 bcs 0x3b4
394: 5a000002 bpl 0x3a4
398: e3a00f05 mov r0, #20 ; 0x14
39c: e3800b03 orr r0, r0, #3072 ; 0xc00
3a0: ebcb17ed bl 0xff2c635c
3a4: ea00006a b 0x554
3a8: e3a00ff9 mov r0, #996 ; 0x3e4
3ac: e3800b02 orr r0, r0, #2048 ; 0x800
3b0: ebcb1a12 bl step_debug
3b4: e2830000 add r0, r3, #0 ; 0x0
3b8: ebcb1a02 bl 0xff2c6bc8
3bc: e58a0008 str r0, [sl, #8]
3c0: e3a00ffa mov r0, #1000 ; 0x3e8
3c4: e3800b02 orr r0, r0, #2048 ; 0x800
3c8: ebcb1a0c bl step_debug
3cc: e59a0008 ldr r0, [sl, #8]
3d0: e1a00000 nop (mov r0,r0)
3d4: e58a000c str r0, [sl, #12]
3d8: e3a00ffb mov r0, #1004 ; 0x3ec
3dc: e3800b02 orr r0, r0, #2048 ; 0x800
3e0: ebcb1a06 bl step_debug
3e4: e59a0008 ldr r0, [sl, #8]
3e8: e1a00000 nop (mov r0,r0)
3ec: e58a0010 str r0, [sl, #16]
3f0: e3a00ebf mov r0, #3056 ; 0xbf0
3f4: ebcb1a01 bl step_debug
3f8: e59a0008 ldr r0, [sl, #8]
3fc: e1a00000 nop (mov r0,r0)
400: e58a0014 str r0, [sl, #20]
404: e3a00ffd mov r0, #1012 ; 0x3f4
408: e3800b02 orr r0, r0, #2048 ; 0x800
40c: ebcb19fb bl step_debug
410: e59a0008 ldr r0, [sl, #8]
414: e1a05000 mov r5, r0
418: e3a00ffe mov r0, #1016 ; 0x3f8
41c: e3800b02 orr r0, r0, #2048 ; 0x800
420: ebcb19f6 bl step_debug
424: e59a0008 ldr r0, [sl, #8]
428: e1a00000 nop (mov r0,r0)
42c: e58a001c str r0, [sl, #28]
430: e3a00fff mov r0, #1020 ; 0x3fc
434: e3800b02 orr r0, r0, #2048 ; 0x800
438: ebcb19f0 bl step_debug
43c: e59a0008 ldr r0, [sl, #8]
440: e1a00000 nop (mov r0,r0)
444: e58a0020 str r0, [sl, #32]
448: e3a00b03 mov r0, #3072 ; 0xc00
44c: ebcb19eb bl step_debug
450: e59a0008 ldr r0, [sl, #8]
454: e1a06000 mov r6, r0
458: e24cc00a sub ip, ip, #10 ; 0xa
45c: e3a00f01 mov r0, #4 ; 0x4
460: e3800b03 orr r0, r0, #3072 ; 0xc00
464: ebcb19e5 bl step_debug
468: e59a0028 ldr r0, [sl, #40]
46c: e1540000 cmp r4, r0
470: e10fb000 mrs fp, CPSR
474: e3a00f02 mov r0, #8 ; 0x8
478: e3800b03 orr r0, r0, #3072 ; 0xc00
47c: ebcb19df bl step_debug
480: e24cc002 sub ip, ip, #2 ; 0x2
484: e128f00b msr CPSR_f, fp
488: aa000021 bge 0x514
48c: e1a09004 mov r9, r4
490: e1a00004 mov r0, r4
494: e2800020 add r0, r0, #32 ; 0x20
498: e1a04000 mov r4, r0
49c: e3c99003 bic r9, r9, #3 ; 0x3
4a0: e2890000 add r0, r9, #0 ; 0x0
4a4: e59a1008 ldr r1, [sl, #8]
4a8: ebcb1975 bl 0xff2c6a84
4ac: e2890004 add r0, r9, #4 ; 0x4
4b0: e59a100c ldr r1, [sl, #12]
4b4: ebcb1972 bl 0xff2c6a84
4b8: e2890008 add r0, r9, #8 ; 0x8
4bc: e59a1010 ldr r1, [sl, #16]
4c0: ebcb196f bl 0xff2c6a84
4c4: e289000c add r0, r9, #12 ; 0xc
4c8: e59a1014 ldr r1, [sl, #20]
4cc: ebcb196c bl 0xff2c6a84
4d0: e2890010 add r0, r9, #16 ; 0x10
4d4: e1a01005 mov r1, r5
4d8: ebcb1969 bl 0xff2c6a84
4dc: e2890014 add r0, r9, #20 ; 0x14
4e0: e59a101c ldr r1, [sl, #28]
4e4: ebcb1966 bl 0xff2c6a84
4e8: e2890018 add r0, r9, #24 ; 0x18
4ec: e59a1020 ldr r1, [sl, #32]
4f0: ebcb1963 bl 0xff2c6a84
4f4: e289001c add r0, r9, #28 ; 0x1c
4f8: e1a01006 mov r1, r6
4fc: e3a02f03 mov r2, #12 ; 0xc
500: e3822b03 orr r2, r2, #3072 ; 0xc00
504: ebcb1946 bl 0xff2c6a24
508: e3a00f03 mov r0, #12 ; 0xc
50c: e3800b03 orr r0, r0, #3072 ; 0xc00
510: ebcb19ba bl step_debug
514: e24cc009 sub ip, ip, #9 ; 0x9
518: e128f00b msr CPSR_f, fp
51c: aa000006 bge 0x53c
520: 5a000002 bpl 0x530
524: e3a00f01 mov r0, #4 ; 0x4
528: e3800b03 orr r0, r0, #3072 ; 0xc00
52c: ebcb178a bl 0xff2c635c
530: eaffffc9 b 0x45c
534: e3a00ec1 mov r0, #3088 ; 0xc10
538: ebcb19b0 bl step_debug
53c: e25cc001 subs ip, ip, #1 ; 0x1
540: 5a000002 bpl 0x550
544: e3a00f09 mov r0, #36 ; 0x24
548: e3800b03 orr r0, r0, #3072 ; 0xc00
54c: ebcb1782 bl 0xff2c635c
550: ea000053 b 0x6a4
554: e3a00f05 mov r0, #20 ; 0x14
558: e3800b03 orr r0, r0, #3072 ; 0xc00
55c: ebcb19a7 bl step_debug
560: e59a0028 ldr r0, [sl, #40]
564: e1540000 cmp r4, r0
568: e10fb000 mrs fp, CPSR
56c: e3a00f06 mov r0, #24 ; 0x18
570: e3800b03 orr r0, r0, #3072 ; 0xc00
574: ebcb19a1 bl step_debug
578: e24cc002 sub ip, ip, #2 ; 0x2
57c: e128f00b msr CPSR_f, fp
580: aa00003f bge 0x684
584: e1a09003 mov r9, r3
588: e1a00003 mov r0, r3
58c: e2800020 add r0, r0, #32 ; 0x20
590: e1a03000 mov r3, r0
594: e3c99003 bic r9, r9, #3 ; 0x3
598: e2890000 add r0, r9, #0 ; 0x0
59c: ebcb1989 bl 0xff2c6bc8
5a0: e58a0008 str r0, [sl, #8]
5a4: e2890004 add r0, r9, #4 ; 0x4
5a8: ebcb1986 bl 0xff2c6bc8
5ac: e58a000c str r0, [sl, #12]
5b0: e2890008 add r0, r9, #8 ; 0x8
5b4: ebcb1983 bl 0xff2c6bc8
5b8: e58a0010 str r0, [sl, #16]
5bc: e289000c add r0, r9, #12 ; 0xc
5c0: ebcb1980 bl 0xff2c6bc8
5c4: e58a0014 str r0, [sl, #20]
5c8: e2890010 add r0, r9, #16 ; 0x10
5cc: ebcb197d bl 0xff2c6bc8
5d0: e1a05000 mov r5, r0
5d4: e2890014 add r0, r9, #20 ; 0x14
5d8: ebcb197a bl 0xff2c6bc8
5dc: e58a001c str r0, [sl, #28]
5e0: e2890018 add r0, r9, #24 ; 0x18
5e4: ebcb1977 bl 0xff2c6bc8
5e8: e58a0020 str r0, [sl, #32]
5ec: e289001c add r0, r9, #28 ; 0x1c
5f0: ebcb1974 bl 0xff2c6bc8
5f4: e1a06000 mov r6, r0
5f8: e3a00f07 mov r0, #28 ; 0x1c
5fc: e3800b03 orr r0, r0, #3072 ; 0xc00
600: ebcb197e bl step_debug
604: e1a09004 mov r9, r4
608: e1a00004 mov r0, r4
60c: e2800020 add r0, r0, #32 ; 0x20
610: e1a04000 mov r4, r0
614: e3c99003 bic r9, r9, #3 ; 0x3
618: e2890000 add r0, r9, #0 ; 0x0
61c: e59a1008 ldr r1, [sl, #8]
620: ebcb1917 bl 0xff2c6a84
624: e2890004 add r0, r9, #4 ; 0x4
628: e59a100c ldr r1, [sl, #12]
62c: ebcb1914 bl 0xff2c6a84
630: e2890008 add r0, r9, #8 ; 0x8
634: e59a1010 ldr r1, [sl, #16]
638: ebcb1911 bl 0xff2c6a84
63c: e289000c add r0, r9, #12 ; 0xc
640: e59a1014 ldr r1, [sl, #20]
644: ebcb190e bl 0xff2c6a84
648: e2890010 add r0, r9, #16 ; 0x10
64c: e1a01005 mov r1, r5
650: ebcb190b bl 0xff2c6a84
654: e2890014 add r0, r9, #20 ; 0x14
658: e59a101c ldr r1, [sl, #28]
65c: ebcb1908 bl 0xff2c6a84
660: e2890018 add r0, r9, #24 ; 0x18
664: e59a1020 ldr r1, [sl, #32]
668: ebcb1905 bl 0xff2c6a84
66c: e289001c add r0, r9, #28 ; 0x1c
670: e1a01006 mov r1, r6
674: e3a02ec2 mov r2, #3104 ; 0xc20
678: ebcb18e9 bl 0xff2c6a24
67c: e3a00ec2 mov r0, #3104 ; 0xc20
680: ebcb195e bl step_debug
684: e24cc012 sub ip, ip, #18 ; 0x12
688: e128f00b msr CPSR_f, fp
68c: aa000007 bge 0x6b0
690: 5a000002 bpl 0x6a0
694: e3a00f05 mov r0, #20 ; 0x14
698: e3800b03 orr r0, r0, #3072 ; 0xc00
69c: ebcb172e bl 0xff2c635c
6a0: eaffffab b 0x554
6a4: e3a00f09 mov r0, #36 ; 0x24
6a8: e3800b03 orr r0, r0, #3072 ; 0xc00
6ac: ebcb1953 bl step_debug
6b0: e59a9034 ldr r9, [sl, #52]
6b4: e59a0034 ldr r0, [sl, #52]
6b8: e2800020 add r0, r0, #32 ; 0x20
6bc: e58a0034 str r0, [sl, #52]
6c0: e3c99003 bic r9, r9, #3 ; 0x3
6c4: e2890000 add r0, r9, #0 ; 0x0
6c8: ebcb193e bl 0xff2c6bc8
6cc: e58a0010 str r0, [sl, #16]
6d0: e2890004 add r0, r9, #4 ; 0x4
6d4: ebcb193b bl 0xff2c6bc8
6d8: e58a0014 str r0, [sl, #20]
6dc: e2890008 add r0, r9, #8 ; 0x8
6e0: ebcb1938 bl 0xff2c6bc8
6e4: e1a05000 mov r5, r0
6e8: e289000c add r0, r9, #12 ; 0xc
6ec: ebcb1935 bl 0xff2c6bc8
6f0: e58a001c str r0, [sl, #28]
6f4: e2890010 add r0, r9, #16 ; 0x10
6f8: ebcb1932 bl 0xff2c6bc8
6fc: e58a0020 str r0, [sl, #32]
700: e2890014 add r0, r9, #20 ; 0x14
704: ebcb192f bl 0xff2c6bc8
708: e1a06000 mov r6, r0
70c: e2890018 add r0, r9, #24 ; 0x18
710: ebcb192c bl 0xff2c6bc8
714: e58a0028 str r0, [sl, #40]
718: e289001c add r0, r9, #28 ; 0x1c
71c: ebcb1929 bl 0xff2c6bc8
720: e1a08000 mov r8, r0
724: e3a00f0a mov r0, #40 ; 0x28
728: e3800b03 orr r0, r0, #3072 ; 0xc00
72c: ebcb1933 bl step_debug
730: e1a00008 mov r0, r8
734: e24cc00a sub ip, ip, #10 ; 0xa
738: eacb1751 b 0xff2c6484

256
gp2x/cmdline.c Normal file
View File

@@ -0,0 +1,256 @@
/* commandline.c for GP2X Version 2.0
Copyright (C) 2006 god_at_hell
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cpuctrl.h"
#include "gp2xminilib.h"
#include "cpuctrl.h"
void fallback(int argc, char *argv[])
{
//beginning commandline-utilizing
if (argc == 3)
{
if (atoi(argv[1]) == 0)
{
if(atoi(argv[2]) > 36){gp2x_deinit();exit(1);}
if(atoi(argv[2]) < -20){gp2x_deinit();exit(1);}
set_add_FLCDCLK(atoi(argv[2]));
}
else
{
if(atoi(argv[2]) > 10){gp2x_deinit();exit(1);}
if(atoi(argv[2]) < -5){gp2x_deinit();exit(1);}
set_add_ULCDCLK(atoi(argv[2]));
}
}
if (argc == 4)
{
if(atoi(argv[3]) > 320){gp2x_deinit();exit(1);}
if(atoi(argv[3]) < 33){gp2x_deinit();exit(1);}
if (atoi(argv[1]) == 0)
{
if(atoi(argv[2]) > 36){gp2x_deinit();exit(1);}
if(atoi(argv[2]) < -20){gp2x_deinit();exit(1);}
set_add_FLCDCLK(atoi(argv[2]));
}
else
{
if(atoi(argv[2]) > 10){gp2x_deinit();exit(1);}
if(atoi(argv[2]) < -5){gp2x_deinit();exit(1);}
set_add_ULCDCLK(atoi(argv[2]));
}
set_FCLK(atoi(argv[3]));
}
if (argc == 5)
{
if(atoi(argv[3]) > 320){gp2x_deinit();exit(1);}
if(atoi(argv[3]) < 33){gp2x_deinit();exit(1);}
if(atof(argv[4]) > 10){gp2x_deinit();exit(1);}
if(atof(argv[4]) < 0.02){gp2x_deinit();exit(1);}
if (atoi(argv[1]) == 0)
{
if(atoi(argv[2]) > 36){gp2x_deinit();exit(1);}
if(atoi(argv[2]) < -20){gp2x_deinit();exit(1);}
set_add_FLCDCLK(atoi(argv[2]));
}
else
{
if(atoi(argv[2]) > 10){gp2x_deinit();exit(1);}
if(atoi(argv[2]) < -5){gp2x_deinit();exit(1);}
set_add_ULCDCLK(atoi(argv[2]));
}
set_FCLK(atoi(argv[3]));
set_gamma(atof(argv[4]));
}
}
void cmdhelp()
{
printf ("\ngpSP2X v0.9003 Beta by Exophase/ZodTTD\r\n");
printf ("cpu_speed by god_at_hell\r\n");
printf ("Usage: cpu_speed.gpe [option1] [value1] [option2]...\r\n");
printf ("Options:\r\n");
printf (" RAM-Options\r\n");
printf (" -----------\r\n");
printf (" --cas CAS Latency. Delay in clock cycles between the registration \n\t\tof a READ command and the first bit of output data. \n\t\tValid values are 2 and 3 cycles.\r\n");
printf (" --trc ACTIVE to ACTIVE /AUTOREFRESH command delay. Defines ACTIVE \n\t\tto ACTIVE/auto refresh command period delay. \n\t\tValid values are from 1 to 16 cycles.\r\n");
printf (" --tras ACTIVE to PRECHARGE delay. Defines the delay between the ACTIVE \n\t\tand PRECHARGE commands. \n\t\tValid values are from 1 to 16 cycles.\r\n");
printf (" --twr Write recovery time in cycles.\n\t\tValid values are from 1 to 16 cycles.\r\n");
printf (" --tmrd LOAD MODE REGISTER command cycle time.\n\t\tValid values are from 1 to 16 cycles.\r\n");
printf (" --trfc AUTO REFRESH command period in cycles.\n\t\tValid values are from 1 to 16 cycles.\r\n");
printf (" --trp PRECHARGE command period in cycles.\n\t\tValid values are from 1 to 16 cycles.\r\n");
printf (" --trcd RAS to CAS Delay in cycles.\n\t\tValid values are from 1 to 16 cycles.\r\n");
printf (" --refperd Refresh Period. Defines maximum time period between \n\t\tAUTOREFRESH commands.\n\t\tValid values are from 1 to 65535 (default ~ 250) cycles.\r\n");
printf (" --ramdiv Divider for the Memory-Clock which is 1/2 of the CPU-Clock. \n\t\tValid values are from 1 to 8.\r\n");
printf ("\n CPU-Options\r\n");
printf (" -----------\r\n");
printf (" --cpuclk Sets the CPU-Frequency in Mhz. \n\t\tValid values are from 33 to 340.\r\n");
printf (" --cpudiv Divider for the CPU-Clock. \n\t\tValid values are from 1 to 8.\r\n");
printf ("\n Display-Options\r\n");
printf ("----------------\r\n");
printf (" --fpll Sets clockgenerator to fpll (for firmware 1.0 - 1.0.1).\r\n");
printf (" --upll Sets clockgenerator to upll (for the rest).\r\n");
printf (" --timing Timing Prescaler to eliminate flickering. \n\t\tValid values are: -20 to 36 with fpll.\n\t\t\t\t -6 to 10 with upll.\r\n");
printf (" --gamma Regulates the gamma. \n\t\tValid values are from 0.0001 to 15.0000.\r\n");
printf ("\n Daemon-Mode \r\n");
printf ("----------------\r\n");
printf ("Usage: cpu_speed.gpe --daemon [option1] [value1] [option2]...\r\n");
printf ("Shutdown: cpu_speed.gpe --kill[-daemon]\r\n");
printf ("Options:\r\n");
printf (" --min Sets the minimum CPU-Frequency in Mhz. \n\t\tValid values are from 33 to 340.\r\n");
printf (" --max Sets the maximum CPU-Frequency in Mhz. \n\t\tValid values are from 33 to 340.\r\n");
printf (" --start Sets the CPU-Frequency in Mhz. \n\t\tValid values are from 33 to 340.\r\n");
printf (" --step Sets the CPU-Frequency step in Mhz. \n\t\tValid values are from 1 to 340.\r\n");
printf (" --hotkey Sets the hotkey. (Default: LR) \n\t\tValid values are a combination of LRXYZAB+-S/@ or ``None''\n\t\t (+- are volume, S is Start, / is Select, @ is Stick).\r\n");
printf (" --incr Sets the increment key. (Default: +) \n\t\tValid values are a combination of LRXYZAB+-S/@ or ``None''\n\t\t (+- are volume, S is Start, / is Select, @ is Stick).\r\n");
printf (" --decr Sets the decrement key. (Default: -) \n\t\tValid values are a combination of LRXYZAB+-S/@ or ``None''\n\t\t (+- are volume, S is Start, / is Select, @ is Stick).\r\n");
printf (" --no-hotkey Alias for --hotkey None.\r\n");
printf (" --no-incr Alias for --incr None.\r\n");
printf (" --no-decr Alias for --decr None.\r\n");
printf (" --foreground Do not switch to daemon mode. (Useful for debugging)\r\n");
printf (" --background Switch to daemon mode. (Default)\r\n");
printf (" --display Enable on screen display. COMING SOON!\r\n");
printf (" --no-display Disable on screen display.\r\n");
printf ("\nNOTE:\nThe old commandline-settings are working ... read more about this in the readme\n\n");
}
void cmdline(int argc, char *argv[])
{
short i,n;
short varis = 11;
char clockgen = get_Clkgen();
char var[11][9]={"--cas","--trc","--tras","--twr","--tmrd","--trfc","--trp","--trcd","--ramdiv","--cpuclk","--cpudiv"};
short val[varis];
for(n=0;n<varis;n++) //initialize the variable-array
{
val[n] = -1;
}
short timing = -100;
int refperd = -1;
float gamma = -1.;
for(i=1; i<argc; i++)
{
if(strcmp(argv[i], "--fpll") == 0) clockgen = 0;
if(strcmp(argv[i], "--upll") == 0) clockgen = 1;
for(n=0; n<varis; n++)
{
if(strcmp(argv[i], var[n]) == 0)
{
if(i+1 == argc){printf ("%s is missing it's parameter\r\n",var[n]);gp2x_deinit();exit(1);}
val[n] = atoi(argv[i+1]);
}
}
if(strcmp(argv[i], "--refperd") == 0)
{
if(i+1 == argc){printf ("%s is missing it's parameter\r\n",argv[i]);gp2x_deinit();exit(1);}
refperd = atoi(argv[i+1]);
}
if(strcmp(argv[i], "--gamma") == 0)
{
if(i+1 == argc){printf ("%s is missing it's parameter\r\n",argv[i]);gp2x_deinit();exit(1);}
gamma = atof(argv[i+1]);
}
if(strcmp(argv[i], "--timing") == 0)
{
if(i+1 == argc){printf ("%s is missing it's parameter\r\n",argv[i]);gp2x_deinit();exit(1);}
timing = atoi(argv[i+1]);
}
}
if(clockgen == 0)
{
if(timing > -21)
{
if(timing < 37) set_add_FLCDCLK(timing);
}
else set_add_FLCDCLK(get_LCDClk(clockgen));
}
if(clockgen == 1)
{
if(timing > -7)
{
if(timing < 11) set_add_ULCDCLK(timing);
}
else set_add_ULCDCLK(get_LCDClk(clockgen));
}
if(refperd-1 > -1)
{
if(refperd-1 < 0xffff) set_REFPERD(refperd-1);
}
if(gamma > 0.)
{
if(gamma < 15.) set_gamma(gamma);
}
if(val[0]-2 > -1)
{
if(val[0]-2 < 2) set_CAS(val[0]-2);
}
if(val[1]-1 > -1)
{
if(val[1]-1 < 16) set_tRC(val[1]-1);
}
if(val[2]-1 > -1)
{
if(val[2]-1 < 16) set_tRAS(val[2]-1);
}
if(val[3]-1 > -1)
{
if(val[3]-1 < 16) set_tWR(val[3]-1);
}
if(val[4]-1 > -1)
{
if(val[4]-1 < 16) set_tMRD(val[4]-1);
}
if(val[5]-1 > -1)
{
if(val[5]-1 < 16) set_tRFC(val[5]-1);
}
if(val[6]-1 > -1)
{
if(val[6] < 16) set_tRP(val[6]-1);
}
if(val[7]-1 > -1)
{
if(val[7]-1 < 16) set_tRCD(val[7]-1);
}
if(val[8]-1 > -1)
{
if(val[8]-1 < 8) set_DCLK_Div(val[8]-1);
}
if(val[9] > 32)
{
if(val[9] < 341) set_FCLK(val[9]);
}
if(val[10]-1 > -1)
{
if(val[10]-1 < 8) set_920_Div(val[10]-1);
}
}

3
gp2x/cmdline.h Normal file
View File

@@ -0,0 +1,3 @@
void fallback(int argc, char *argv[]);
void cmdhelp();
void cmdline(int argc, char *argv[]);

1276
gp2x/cpu_speed.c Normal file

File diff suppressed because it is too large Load Diff

484
gp2x/cpuctrl.c Normal file
View File

@@ -0,0 +1,484 @@
/* cpuctrl.c for GP2X (CPU/LCD/RAM-Tuner Version 2.0)
Copyright (C) 2006 god_at_hell
original CPU-Overclocker (c) by Hermes/PS2Reality
the gamma-routine was provided by theoddbot
parts (c) Rlyehs Work
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/****************************************************************************************************************************************/
// CPU CONTROL
/****************************************************************************************************************************************/
#include <sys/mman.h>
#include <math.h>
#include <stdio.h>
#include "gp2xminilib.h"
#define SYS_CLK_FREQ 7372800
//from minimal library rlyeh
extern unsigned long gp2x_dev[4];
extern unsigned short *gp2x_memregs;
// system registers
static struct
{
unsigned short SYSCLKENREG,SYSCSETREG,FPLLVSETREG,DUALINT920,DUALINT940,DUALCTRL940,DISPCSETREG,MEMTIMEX0;
unsigned short MEMTIMEX1,MEMREFX,MLC_GAMM_BYPATH,MLC_GAMMA_A,MLC_GAMMA_D,YBNKLVL;
}
system_reg;
volatile unsigned short *MEM_REG;
unsigned MDIV,PDIV,SCALE;
volatile unsigned *arm940code;
void cpuctrl_init()
{
MEM_REG=&gp2x_memregs[0];
}
void save_system_regs()
{
system_reg.SYSCSETREG=MEM_REG[0x91c>>1];
system_reg.FPLLVSETREG=MEM_REG[0x912>>1];
system_reg.SYSCLKENREG=MEM_REG[0x904>>1];
system_reg.DUALINT920=MEM_REG[0x3B40>>1];
system_reg.DUALINT940=MEM_REG[0x3B42>>1];
system_reg.DUALCTRL940=MEM_REG[0x3B48>>1];
system_reg.DISPCSETREG=MEM_REG[0x924>>1];
system_reg.MEMTIMEX0=MEM_REG[0x3802>>1];
system_reg.MEMTIMEX1=MEM_REG[0x3804>>1];
system_reg.MEMREFX=MEM_REG[0x3808>>1];
system_reg.MLC_GAMM_BYPATH=MEM_REG[0x2880>>1];
system_reg.MLC_GAMMA_A=MEM_REG[0x295C>>1];
system_reg.MLC_GAMMA_D=MEM_REG[0x295E>>1];
system_reg.YBNKLVL=MEM_REG[0x283A>>1];
}
void load_system_regs()
{
MEM_REG[0x91c>>1]=system_reg.SYSCSETREG;
MEM_REG[0x910>>1]=system_reg.FPLLVSETREG;
MEM_REG[0x3B40>>1]=system_reg.DUALINT920;
MEM_REG[0x3B42>>1]=system_reg.DUALINT940;
MEM_REG[0x3B48>>1]=system_reg.DUALCTRL940;
MEM_REG[0x904>>1]=system_reg.SYSCLKENREG;
/* Set UPLLSETVREG to 0x4F02, which gives 80MHz */
MEM_REG[0x0914>>1] = 0x4F02;
/* Wait for clock change to start */
while (MEM_REG[0x0902>>1] & 2);
/* Wait for clock change to be verified */
while (MEM_REG[0x0916>>1] != 0x4F02);
MEM_REG[0x3802>>1]=system_reg.MEMTIMEX0;
MEM_REG[0x3804>>1]=system_reg.MEMTIMEX1;
MEM_REG[0x3808>>1]=system_reg.MEMREFX;
MEM_REG[0x2880>>1]=system_reg.MLC_GAMM_BYPATH;
MEM_REG[0x295C>>1]=system_reg.MLC_GAMMA_A;
MEM_REG[0x295E>>1]=system_reg.MLC_GAMMA_D;
MEM_REG[0x283A>>1]=system_reg.YBNKLVL;
}
void set_FCLK(unsigned MHZ)
{
printf ("set CPU-Frequency = %uMHz\r\n",MHZ);
unsigned v;
unsigned mdiv,pdiv=3,scale=0;
MHZ*=1000000;
mdiv=(MHZ*pdiv)/SYS_CLK_FREQ;
//printf ("Old value = %04X\r",MEM_REG[0x924>>1]," ");
//printf ("APLL = %04X\r",MEM_REG[0x91A>>1]," ");
mdiv=((mdiv-8)<<8) & 0xff00;
pdiv=((pdiv-2)<<2) & 0xfc;
scale&=3;
v=mdiv | pdiv | scale;
MEM_REG[0x910>>1]=v;
}
unsigned get_FCLK()
{
return MEM_REG[0x910>>1];
}
void set_add_FLCDCLK(int addclock)
{
//Set LCD controller to use FPLL
printf ("...set to FPLL-Clockgen...\r\n");
printf ("set Timing-Prescaler = %i\r\n",addclock);
MEM_REG[0x924>>1]= 0x5A00 + ((addclock)<<8);
//If you change the initial timing, don't forget to shift your intervall-borders in "cpu_speed.c"
}
void set_add_ULCDCLK(int addclock)
{
//Set LCD controller to use UPLL
printf ("...set to UPLL-Clockgen...\r\n");
printf ("set Timing-Prescaler = %i\r\n",addclock);
MEM_REG[0x0924>>1] = 0x8900 + ((addclock)<<8);
//If you change the initial timing, don't forget to shift your intervall-borders in "cpu_speed.c"
}
unsigned get_LCDClk()
{
if (MEM_REG[0x0924>>1] < 0x7A01) return((MEM_REG[0x0924>>1] - 0x5A00)>>8);
else return((MEM_REG[0x0924>>1] - 0x8900)>>8);
}
char get_Clkgen()
{
if (MEM_REG[0x0924>>1] < 0x7A01) return(0);
else return(1);
}
unsigned get_freq_UCLK()
{
unsigned i;
unsigned reg,mdiv,pdiv,scale;
i = MEM_REG[0x900>>1];
i = ((i >> 7) & 1) ;
if(i) return 0;
reg=MEM_REG[0x916>>1];
mdiv = ((reg & 0xff00) >> 8) + 8;
pdiv = ((reg & 0xfc) >> 2) + 2;
scale = reg & 3;
return ((SYS_CLK_FREQ * mdiv) / (pdiv << scale));
}
unsigned get_freq_ACLK()
{
unsigned i;
unsigned reg,mdiv,pdiv,scale;
i = MEM_REG[0x900>>1];
i = ((i >> 8) & 1) ;
if(i) return 0;
reg=MEM_REG[0x918>>1];
mdiv = ((reg & 0xff00) >> 8) + 8;
pdiv = ((reg & 0xfc) >> 2) + 2;
scale = reg & 3;
return ((SYS_CLK_FREQ * mdiv)/(pdiv << scale));
}
unsigned get_freq_920_CLK()
{
unsigned i;
unsigned reg,mdiv,pdiv,scale;
reg=MEM_REG[0x912>>1];
mdiv = ((reg & 0xff00) >> 8) + 8;
pdiv = ((reg & 0xfc) >> 2) + 2;
scale = reg & 3;
MDIV=mdiv;
PDIV=pdiv;
SCALE=scale;
i = (MEM_REG[0x91c>>1] & 7)+1;
return ((SYS_CLK_FREQ * mdiv)/(pdiv << scale))/i;
}
unsigned get_freq_940_CLK()
{
unsigned i;
unsigned reg,mdiv,pdiv,scale;
reg=MEM_REG[0x912>>1];
mdiv = ((reg & 0xff00) >> 8) + 8;
pdiv = ((reg & 0xfc) >> 2) + 2;
scale = reg & 3;
i = ((MEM_REG[0x91c>>1]>>3) & 7)+1;
return ((SYS_CLK_FREQ * mdiv) / (pdiv << scale))/i;
}
unsigned get_freq_DCLK()
{
unsigned i;
unsigned reg,mdiv,pdiv,scale;
reg=MEM_REG[0x912>>1];
mdiv = ((reg & 0xff00) >> 8) + 8;
pdiv = ((reg & 0xfc) >> 2) + 2;
scale = reg & 3;
i = ((MEM_REG[0x91c>>1]>>6) & 7)+1;
return ((SYS_CLK_FREQ * mdiv) / (pdiv << scale))/i;
}
void set_920_Div(unsigned short div)
{
printf ("set divider for CPU-Clock = %u\r\n",div+1);
unsigned short v;
v = MEM_REG[0x91c>>1] & (~0x3);
MEM_REG[0x91c>>1] = (div & 0x7) | v;
}
unsigned short get_920_Div()
{
return (MEM_REG[0x91c>>1] & 0x7);
}
void set_940_Div(unsigned short div)
{
unsigned short v;
v = (unsigned short)( MEM_REG[0x91c>>1] & (~(0x7 << 3)));
MEM_REG[0x91c>>1] = ((div & 0x7) << 3) | v;
}
unsigned short get_940_Div()
{
return ((MEM_REG[0x91c>>1] >> 3) & 0x7);
}
void set_DCLK_Div( unsigned short div )
{
printf ("set divider for RAM-Clock = %u\r\n",div+1);
unsigned short v;
v = (unsigned short)( MEM_REG[0x91c>>1] & (~(0x7 << 6)));
MEM_REG[0x91c>>1] = ((div & 0x7) << 6) | v;
}
unsigned short get_DCLK_Div()
{
return ((MEM_REG[0x91c>>1] >> 6) & 0x7);
}
unsigned short Disable_Int_920()
{
unsigned short ret;
ret=MEM_REG[0x3B40>>1];
MEM_REG[0x3B40>>1]=0;
MEM_REG[0x3B44>>1]=0xffff;
return ret;
}
unsigned short Disable_Int_940()
{
unsigned short ret;
ret=MEM_REG[0x3B42>>1];
MEM_REG[0x3B42>>1]=0;
MEM_REG[0x3B46>>1]=0xffff;
return ret;
}
unsigned get_state940()
{
return MEM_REG[0x904>>1];
}
void Enable_Int_920(unsigned short flag)
{
MEM_REG[0x3B40>>1]=flag;
}
void Enable_Int_940(unsigned short flag)
{
MEM_REG[0x3B42>>1]=flag;
}
void Disable_940()
{
Disable_Int_940();
MEM_REG[0x3B48>>1]|= (1 << 7);
MEM_REG[0x904>>1]&=0xfffe;
}
void Load_940_code(unsigned *code,int size)
{
unsigned *cp;
int i;
arm940code=(unsigned short *)mmap(0, 0x100000, PROT_READ|PROT_WRITE, MAP_SHARED, gp2x_dev[2], 0x03000000);
Disable_940();
cp=(unsigned *) code;
for (i = 0; i < size/4; i ++)
{
arm940code[i] = cp[i];
}
for (i = 0; i < 64; i ++)
{
arm940code[0x3FC0+i] = 0;
}
MEM_REG[0x3B48>>1]=(MEM_REG[0x3B48>>1] & 0xFF00) | 0x03; // allow 940
}
void clock_940_off()
{
MEM_REG[0x904>>1]&=0xfffe;
}
void clock_940_on()
{
MEM_REG[0x904>>1]|=1;
}
//--------------
//Memory Timings
//--------------
//get
unsigned get_CAS()
{
return ((MEM_REG[0x3804>>1] >> 12) & 0x1);
}
unsigned get_tRC()
{
return ((MEM_REG[0x3804>>1] >> 8) & 0xF);
}
unsigned get_tRAS()
{
return ((MEM_REG[0x3804>>1] >> 4) & 0xF);
}
unsigned get_tWR()
{
return (MEM_REG[0x3804>>1] & 0xF);
}
unsigned get_tMRD()
{
return ((MEM_REG[0x3802>>1] >> 12) & 0xF);
}
unsigned get_tRFC()
{
return ((MEM_REG[0x3802>>1] >> 8) & 0xF);
}
unsigned get_tRP()
{
return ((MEM_REG[0x3802>>1] >> 4) & 0xF);
}
unsigned get_tRCD()
{
return (MEM_REG[0x3802>>1] & 0xF);
}
unsigned get_REFPERD()
{
return MEM_REG[0x3808>>1];
}
//set
void set_CAS(unsigned short timing)
{
printf ("set CAS = %u\r\n",timing+2);
unsigned short v;
v = (unsigned short)(MEM_REG[0x3804>>1] & (~(0x1 << 12)));
MEM_REG[0x3804>>1] = ((timing & 0x1) << 12) | v;
}
void set_tRC(unsigned short timing)
{
printf ("set tRC = %u\r\n",timing+1);
unsigned short v;
v = (unsigned short)(MEM_REG[0x3804>>1] & (~(0xF << 8)));
MEM_REG[0x3804>>1] = ((timing & 0xF) << 8) | v;
}
void set_tRAS(unsigned short timing)
{
printf ("set tRAS = %u\r\n",timing+1);
unsigned short v;
v = (unsigned short)(MEM_REG[0x3804>>1] & (~(0xF << 4)));
MEM_REG[0x3804>>1] = ((timing & 0xF) << 4) | v;
}
void set_tWR(unsigned short timing)
{
printf ("set tWR = %u\r\n",timing+1);
unsigned short v;
v = (unsigned short)(MEM_REG[0x3804>>1] & (~(0xF)));
MEM_REG[0x3804>>1] = (timing & 0xF) | v;
}
void set_tMRD(unsigned short timing)
{
printf ("set tMRD = %u\r\n",timing+1);
unsigned short v;
v = (unsigned short)(MEM_REG[0x3802>>1] & (~(0xF << 12)));
MEM_REG[0x3802>>1] = ((timing & 0xF) << 12) | v;
}
void set_tRFC(unsigned short timing)
{
printf ("set tRFC = %u\r\n",timing+1);
unsigned short v;
v = (unsigned short)(MEM_REG[0x3802>>1] & (~(0xF << 8)));
MEM_REG[0x3802>>1] = ((timing & 0xF) << 8) | v;
}
void set_tRP(unsigned short timing)
{
printf ("set tRP = %u\r\n",timing+1);
unsigned short v;
v = (unsigned short)(MEM_REG[0x3802>>1] & (~(0xF << 4)));
MEM_REG[0x3802>>1] = ((timing & 0xF) << 4) | v;
}
void set_tRCD(unsigned short timing)
{
printf ("set tRCD = %u\r\n",timing+1);
unsigned short v;
v = (unsigned short)(MEM_REG[0x3802>>1] & (~(0xF)));
MEM_REG[0x3802>>1] = (timing & 0xF) | v;
}
void set_REFPERD(unsigned short timing)
{
printf ("set Refresh Period = %u\r\n",timing+1);
MEM_REG[0x3808>>1] = timing;
}
//-----
//Gamma
//-----
void set_gamma(float gamma)
{
printf ("set gamma = %f\r\n",gamma);
int i;
gamma = 1/gamma;
//enable gamma
MEM_REG[0x2880>>1]&=~(1<<12);
MEM_REG[0x295C>>1]=0;
for(i=0; i<256; i++)
{
unsigned char g;
unsigned short s;
g =(unsigned char)(255.0*pow(i/255.0,gamma));
s = (g<<8) | g;
MEM_REG[0x295E>>1]= s;
MEM_REG[0x295E>>1]= g;
}
}
unsigned get_YBNKLVL()
{
return (MEM_REG[0x283A>>1] & 0x3FF);
}
void set_YBNKLVL(unsigned short val)
{
unsigned short temp = (unsigned short)(MEM_REG[0x3808>>1] & (~(0x3FF)));
MEM_REG[0x3808>>1] = (val & 0x3FF) | temp;
}

72
gp2x/cpuctrl.h Normal file
View File

@@ -0,0 +1,72 @@
#if !defined(_CPUCTRL_)
#define _CPUCTRL_
void cpuctrl_init(); // call this at first
void save_system_regs(); // save some registers
void load_system_regs();
void set_FCLK(unsigned MHZ); // adjust the clock frequency (in Mhz units)
void set_add_ULCDCLK(int addclock);
void set_add_FLCDCLK(int addclock);
unsigned get_FCLK();
unsigned get_freq_UCLK();
unsigned get_freq_ACLK();
unsigned get_freq_920_CLK();
unsigned get_freq_940_CLK();
unsigned get_freq_DCLK();
unsigned get_LCDClk();
char get_Clkgen();
unsigned get_state940();
void set_920_Div(unsigned short div); /* 0 to 7 divider (freq=FCLK/(1+div)) */
unsigned short get_920_Div();
void set_940_Div(unsigned short div); /* 0 to 7 divider (freq=FCLK/(1+div)) */
unsigned short get_940_Div();
void set_DCLK_Div(unsigned short div); /* 0 to 7 divider (freq=FCLK/(1+div)) */
unsigned short get_DCLK_Div();
unsigned short Disable_Int_920();
unsigned short Disable_Int_940();
void Enable_Int_920(unsigned short flag);
void Enable_Int_940(unsigned short flag);
void Disable_940(); // 940t down
extern volatile unsigned *arm940code; // memory address of 940t code
void Load_940_code(unsigned *code,int size); // enable 940t, load 940t code and clock 940t off
void clock_940_off(); // 940t stops
void clock_940_on(); // 940t running
//Memory Timings
unsigned get_CAS(); //CAS Latency
unsigned get_tRC(); //ACTIVE to ACTIVE /AUTOREFRESH command delay
unsigned get_tRAS(); //ACTIVE to PRECHARGE delay
unsigned get_tWR(); //Write recovery time
unsigned get_tMRD(); //LOAD MODE REGISTER command cycle time
unsigned get_tRFC(); //AUTO REFRESH command period
unsigned get_tRP(); //PRECHARGE command period
unsigned get_tRCD(); //RAS to CAS Delay
unsigned get_REFPERD();//Refresh Period
void set_CAS();
void set_tRC();
void set_tRAS();
void set_tWR();
void set_tMRD();
void set_tRFC();
void set_tRP();
void set_tRCD();
void set_REFPERD();
void set_gamma(float gamma);
unsigned get_YBNKLVL();
void set_YBNKLVL(unsigned short val);
#endif

671
gp2x/daemon.c Normal file
View File

@@ -0,0 +1,671 @@
/* daemon.c for GP2X Version 2.0
Copyright (C) 2006 jannis harder
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include "gp2xminilib.h"
#include "cpuctrl.h"
#include "display.h"
#include "daemon.h"
extern unsigned COLORFONDO; // background-color
extern unsigned WHITE;
extern unsigned TEXTBACK;
extern unsigned char cad[256];
extern unsigned short *gp2x_memregs;
extern pthread_t gp2x_sound_thread;
int start_daemon(
unsigned int minimal_cpu_speed, unsigned int maximal_cpu_speed, unsigned int start_cpu_speed, int cpu_speed_step,
unsigned long hotkey, unsigned long incrementkey, unsigned long decrementkey,
int speed_display, int foreground,
unsigned long delay)
{
pid_t pid, sid;
if(!foreground) {
kill_running_daemon();
FILE * pidfile = fopen("/tmp/cpu_daemon.pid","w");
if(!pidfile) {
printf("couldn't write pidfile\r\n");
exit(-2);
}
pid = fork();
if(pid > 0) {
fprintf(pidfile,"%i\n",pid);
fclose(pidfile);
}
if(pid != 0)
return pid;
fclose(pidfile);
umask(0);
sid = setsid();
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
}
if(foreground)
printf("daemon ready\r\n");
nano_setup(); // loading the full minilib would be overkill and i guess some games/emus wouldn't like it
unsigned int current_cpu_speed = start_cpu_speed;
while(1) {
usleep(delay);
unsigned long keystate = gp2x_joystick_read();
unsigned int last_cpu_speed = 0;
while(
(hotkey && (keystate & hotkey) == hotkey) ||
((!hotkey) && (
(incrementkey && (keystate & incrementkey) == incrementkey) ||
(decrementkey && (keystate & decrementkey) == decrementkey)
))
) {
if(foreground && !last_cpu_speed)
printf("cpu daemon activated!\r\n");
if(incrementkey && (keystate & incrementkey) == incrementkey) {
current_cpu_speed += cpu_speed_step;
while((keystate & incrementkey) == incrementkey) usleep(100000),keystate = gp2x_joystick_read();
}
else if(decrementkey && (keystate & decrementkey) == decrementkey) {
current_cpu_speed -= cpu_speed_step;
while((keystate & decrementkey) == decrementkey) usleep(100000),keystate = gp2x_joystick_read();
}
if(current_cpu_speed < minimal_cpu_speed)
current_cpu_speed = minimal_cpu_speed;
if(current_cpu_speed > maximal_cpu_speed)
current_cpu_speed = maximal_cpu_speed;
if(last_cpu_speed != current_cpu_speed) {
set_FCLK(current_cpu_speed);
}
last_cpu_speed = current_cpu_speed;
keystate = gp2x_joystick_read();
}
}
}
int kill_running_daemon() {
FILE * pidfile = fopen("/tmp/cpu_daemon.pid","r");
char pid_buffer[14];
pid_buffer[0] = 'k';
pid_buffer[1] = 'i';
pid_buffer[2] = 'l';
pid_buffer[3] = 'l';
pid_buffer[4] = ' ';
pid_buffer[5] = 0;
if(pidfile) {
printf("found pidfile\r\n");
fgets(&(pid_buffer[5]),10,pidfile);
fclose(pidfile);
int return_code = system(pid_buffer);
if(return_code)
printf("daemon wasn't running\r\n");
else
printf("killed old daemon\r\n");
unlink("/tmp/cpu_daemon.pid");
return 1;
}
return 0;
}
void nano_setup() {
if(!gp2x_sound_thread) {
gp2x_memregs=(unsigned short *)mmap(0, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, open("/dev/mem", O_RDWR), 0xc0000000);
cpuctrl_init();
}
}
void cmd_daemon(int argc, char *argv[]) {
int cpu_div = get_920_Div();
int sysfreq=get_freq_920_CLK();
sysfreq*=cpu_div+1;
int cpufreq=sysfreq/1000000;
unsigned int minimal_value = 33;
unsigned int maximal_value = 260;
unsigned int start_value = cpufreq;
unsigned int step = 10;
unsigned long hotkey = GP2X_L | GP2X_R;
unsigned long downkey = GP2X_VOL_UP;
unsigned long upkey = GP2X_VOL_DOWN;
int foreground = 0;
int display = 1;
float delay = 1;
int i;
for( i = 2; i < argc; i++) {
if(!strcmp(argv[i],"--min")) {
if(i+1 == argc){printf ("%s is missing it's parameter\r\n",argv[i]);gp2x_deinit();exit(1);}
minimal_value = atoi(argv[i+1]);
if(minimal_value < 33)
minimal_value = 33;
}
else if(!strcmp(argv[i],"--max")) {
if(i+1 == argc){printf ("%s is missing it's parameter\r\n",argv[i]);gp2x_deinit();exit(1);}
maximal_value = atoi(argv[i+1]);
if(maximal_value > 340)
maximal_value = 340;
}
else if(!strcmp(argv[i],"--start")) {
if(i+1 == argc){printf ("%s is missing it's parameter\r\n",argv[i]);gp2x_deinit();exit(1);}
start_value = atoi(argv[i+1]);
}
else if(!strcmp(argv[i],"--step")) {
if(i+1 == argc){printf ("%s is missing it's parameter\r\n",argv[i]);gp2x_deinit();exit(1);}
step = atoi(argv[i+1]);
}
else if(!strcmp(argv[i],"--hotkey")) {
if(i+1 == argc){printf ("%s is missing it's parameter\r\n",argv[i]);gp2x_deinit();exit(1);}
hotkey = parse_key_sequence(argv[i+1]);
}
else if(!strcmp(argv[i],"--incr")) {
if(i+1 == argc){printf ("%s is missing it's parameter\r\n",argv[i]);gp2x_deinit();exit(1);}
upkey = parse_key_sequence(argv[i+1]);
}
else if(!strcmp(argv[i],"--decr")) {
if(i+1 == argc){printf ("%s is missing it's parameter\r\n",argv[i]);gp2x_deinit();exit(1);}
downkey = parse_key_sequence(argv[i+1]);
}
else if(!strcmp(argv[i],"--delay")) {
if(i+1 == argc){printf ("%s is missing it's parameter\r\n",argv[i]);gp2x_deinit();exit(1);}
delay = atof(argv[i+1]);
}
else if(!strcmp(argv[i],"--no-incr")) {
upkey = 0;
}
else if(!strcmp(argv[i],"--no-decr")) {
downkey = 0;
}
else if(!strcmp(argv[i],"--no-hotkey")) {
hotkey = 0;
}
else if(!strcmp(argv[i],"--foreground")) {
foreground = 1;
}
else if(!strcmp(argv[i],"--background")) {
foreground = 0;
}
else if(!strcmp(argv[i],"--display")) {
display = 1;
}
else if(!strcmp(argv[i],"--no-display")) {
display = 0;
}
}
if((hotkey & downkey) == downkey)
printf("warning: hotkey includes decrement keypress!\r\n");
if((hotkey & upkey) == upkey)
printf("warning: hotkey includes increment keypress!\r\n");
int pid = start_daemon(minimal_value, maximal_value, start_value, step, hotkey, upkey, downkey, display, foreground, delay* 1000000);
if(pid < 0) {
printf("couldn't start daemon\r\n");
exit(1);
}
else if(pid > 0) {
printf("daemon started\r\n");
exit(0);
}
}
unsigned long parse_key_sequence(char *key_sequence) {
unsigned long hotkey = 0;
if(!strcmp(key_sequence,"None"))
return 0;
char *mask = key_sequence;
while(*mask) {
switch(*mask) {
case 'l':
case 'L':
hotkey |= GP2X_L;
break;
case 'r':
case 'R':
hotkey |= GP2X_R;
break;
case 'a':
case 'A':
hotkey |= GP2X_A;
break;
case 'b':
case 'B':
hotkey |= GP2X_B;
break;
case 'x':
case 'X':
hotkey |= GP2X_X;
break;
case 'y':
case 'Y':
hotkey |= GP2X_Y;
break;
case '+':
hotkey |= GP2X_VOL_DOWN;
break;
case '-':
hotkey |= GP2X_VOL_UP;
break;
case 'S':
case 's':
hotkey |= GP2X_START;
break;
case '/':
hotkey |= GP2X_SELECT;
break;
case '@':
hotkey |= GP2X_PUSH;
break;
case '\n':
break;
default:
printf("unknown key %c\r\n",*mask);
}
mask++;
}
return hotkey;
}
int daemonsettings[8];
void cleardisp();
void formatkey(char * base, unsigned long keyseq) {
if(!keyseq)
strcat(base,"None");
if(keyseq & GP2X_L)
strcat(base,"L");
if(keyseq & GP2X_R)
strcat(base,"R");
if(keyseq & GP2X_A)
strcat(base,"A");
if(keyseq & GP2X_B)
strcat(base,"B");
if(keyseq & GP2X_X)
strcat(base,"X");
if(keyseq & GP2X_Y)
strcat(base,"Y");
if(keyseq & GP2X_VOL_DOWN)
strcat(base,"+");
if(keyseq & GP2X_VOL_UP)
strcat(base,"-");
if(keyseq & GP2X_START)
strcat(base,"S");
if(keyseq & GP2X_SELECT)
strcat(base,"/");
if(keyseq & GP2X_PUSH)
strcat(base,"@");
}
#define VALID_KEYS ((GP2X_L) | (GP2X_R) | (GP2X_X) | (GP2X_Y) | (GP2X_A) | (GP2X_B) | (GP2X_START) | (GP2X_SELECT) | (GP2X_VOL_UP) | (GP2X_VOL_DOWN) | (GP2X_PUSH) )
int running;
void daemon_itemhelp(int menuitem)
{
switch(menuitem) {
case 0:
v_putcad(26,8,0xffffff,COLORFONDO,"Choose a");
v_putcad(26,9,0xffffff,COLORFONDO,"minimal");
v_putcad(26,10,0xffffff,COLORFONDO,"clockspeed");
v_putcad(26,11,0xffffff,COLORFONDO,"with R/L or");
v_putcad(26,12,0xffffff,COLORFONDO,"Vol UP/Down.");
v_putcad(26,14,0xffffff,COLORFONDO,"Valid speeds");
v_putcad(26,15,0xffffff,COLORFONDO,"are:");
v_putcad(26,16,0xffffff,COLORFONDO,"33 to 340Mhz");
break;
case 1:
v_putcad(26,8,0xffffff,COLORFONDO,"Choose a");
v_putcad(26,9,0xffffff,COLORFONDO,"maximal");
v_putcad(26,10,0xffffff,COLORFONDO,"clockspeed");
v_putcad(26,11,0xffffff,COLORFONDO,"with R/L or");
v_putcad(26,12,0xffffff,COLORFONDO,"Vol UP/Down.");
v_putcad(26,14,0xffffff,COLORFONDO,"Valid speeds");
v_putcad(26,15,0xffffff,COLORFONDO,"are:");
v_putcad(26,16,0xffffff,COLORFONDO,"33 to 340Mhz");
break;
case 2:
v_putcad(26,8,0xffffff,COLORFONDO,"Choose a step");
v_putcad(26,9,0xffffff,COLORFONDO,"width for");
v_putcad(26,10,0xffffff,COLORFONDO,"changing the");
v_putcad(26,11,0xffffff,COLORFONDO,"clockspeed.");
v_putcad(26,13,0xffffff,COLORFONDO,"Use R/L or");
v_putcad(26,14,0xffffff,COLORFONDO,"Vol UP/Down.");
break;
case 3:
v_putcad(26,8,0xffffff,COLORFONDO,"Choose a");
v_putcad(26,9,0xffffff,COLORFONDO,"delay between");
v_putcad(26,10,0xffffff,COLORFONDO,"each hotkey");
v_putcad(26,11,0xffffff,COLORFONDO,"check");
v_putcad(26,13,0xffffff,COLORFONDO,"Use R/L or");
v_putcad(26,14,0xffffff,COLORFONDO,"Vol UP/Down.");
break;
case 4:
v_putcad(26,8,0xffffff,COLORFONDO,"Choose a");
v_putcad(26,9,0xffffff,COLORFONDO,"hotkey.");
v_putcad(26,10,0xffffff,COLORFONDO,"Add or delete");
v_putcad(26,11,0xffffff,COLORFONDO,"a button by");
v_putcad(26,12,0xffffff,COLORFONDO,"pressing it.");
v_putcad(26,14,0x0000DD,COLORFONDO,"Joystick is");
v_putcad(26,15,0x0000DD,COLORFONDO,"not allowed.");
break;
case 5:
v_putcad(26,8,0xffffff,COLORFONDO,"Choose a");
v_putcad(26,9,0xffffff,COLORFONDO,"key for");
v_putcad(26,10,0xffffff,COLORFONDO,"incrementing");
v_putcad(26,11,0xffffff,COLORFONDO,"the clkspeed.");
v_putcad(26,12,0xffffff,COLORFONDO,"Add or delete");
v_putcad(26,13,0xffffff,COLORFONDO,"a button by");
v_putcad(26,14,0xffffff,COLORFONDO,"pressing it.");
v_putcad(26,16,0x0000DD,COLORFONDO,"Joystick is");
v_putcad(26,17,0x0000DD,COLORFONDO,"not allowed.");
break;
case 6:
v_putcad(26,8,0xffffff,COLORFONDO,"Choose a");
v_putcad(26,9,0xffffff,COLORFONDO,"key for");
v_putcad(26,10,0xffffff,COLORFONDO,"decrementing");
v_putcad(26,11,0xffffff,COLORFONDO,"the clkspeed.");
v_putcad(26,12,0xffffff,COLORFONDO,"Add or delete");
v_putcad(26,13,0xffffff,COLORFONDO,"a button by");
v_putcad(26,14,0xffffff,COLORFONDO,"pressing it.");
v_putcad(26,16,0x0000DD,COLORFONDO,"Joystick is");
v_putcad(26,17,0x0000DD,COLORFONDO,"not allowed.");
break;
case 7:
/* v_putcad(26,8,0xffffff,COLORFONDO,"Enable or");
v_putcad(26,9,0xffffff,COLORFONDO,"disable");
v_putcad(26,10,0xffffff,COLORFONDO,"on screen");
v_putcad(26,11,0xffffff,COLORFONDO,"display.");
v_putcad(26,13,0x0000DD,COLORFONDO,"May cause");
v_putcad(26,14,0x0000DD,COLORFONDO,"conflicts");
v_putcad(26,15,0x0000DD,COLORFONDO,"with");
v_putcad(26,16,0x0000DD,COLORFONDO,"some apps!");*/
v_putcad(26,8,0x0000DD,COLORFONDO,"COMING SOON");
break;
case 8:
if(running) {
v_putcad(26,8,0xffffff,COLORFONDO,"Press B to");
v_putcad(26,9,0xffffff,COLORFONDO,"kill the");
v_putcad(26,10,0xffffff,COLORFONDO,"running");
v_putcad(26,11,0xffffff,COLORFONDO,"daemon");
v_putcad(26,12,0xffffff,COLORFONDO,"process.");
}
else {
v_putcad(26,8,0xffffff,COLORFONDO,"Press B to");
v_putcad(26,9,0xffffff,COLORFONDO,"start the ");
v_putcad(26,10,0xffffff,COLORFONDO,"daemon in the");
v_putcad(26,11,0xffffff,COLORFONDO, "background.");
}
break;
}
}
void daemonmenu() {
int menupoint = 0;
running = !access("/tmp/cpu_daemon.pid",R_OK);
unsigned long gp2x_nKeys;
while(1) {
if(daemonsettings[0] < 33)
daemonsettings[0] = 33;
if(daemonsettings[1] > 340)
daemonsettings[1] = 340;
if(daemonsettings[1] < daemonsettings[0])
daemonsettings[1] = daemonsettings[0];
if(daemonsettings[0] > daemonsettings[1])
daemonsettings[0] = daemonsettings[1];
if(daemonsettings[2] < 1)
daemonsettings[2] = 1;
if(daemonsettings[3] < 1)
daemonsettings[3] = 1;
//if(daemonsettings[7] == 10 || daemonsettings[7] == -10)
// daemonsettings[7] = 1;
//if(daemonsettings[7] == 11 || daemonsettings[7] == -9)
daemonsettings[7] = 0;
cleardisp();
v_putcad(13,2,WHITE,COLORFONDO,"Daemon Setup");
v_putcad(2,5,0xffff00,COLORFONDO,"CPU Clockspeed:");
sprintf(cad,"From: %huMhz",daemonsettings[0]);
v_putcad(2,7,0xffff,COLORFONDO,cad);
if(menupoint == 0)
v_putcad(2,7,0xffff,TEXTBACK,cad);
sprintf(cad,"To: %huMhz",daemonsettings[1]);
v_putcad(2,8,0xffff,COLORFONDO,cad);
if(menupoint == 1)
v_putcad(2,8,0xffff,TEXTBACK,cad);
sprintf(cad,"Step: %huMhz",daemonsettings[2]);
v_putcad(2,9,0xffff,COLORFONDO,cad);
if(menupoint == 2)
v_putcad(2,9,0xffff,TEXTBACK,cad);
v_putcad(2,11,0xffff00,COLORFONDO,"Buttons:");
sprintf(cad,"Delay: %0.1fsec",daemonsettings[3]/10.0f);
v_putcad(2,13,0xffff,COLORFONDO,cad);
if(menupoint == 3)
v_putcad(2,13,0xffff,TEXTBACK,cad);
sprintf(cad,"Hotkey: ");
formatkey(cad,daemonsettings[4]);
v_putcad(2,15,0xffff,COLORFONDO,cad);
if(menupoint == 4)
v_putcad(2,15,0xffff,TEXTBACK,cad);
sprintf(cad,"IncrKey: ");
formatkey(cad,daemonsettings[5]);
v_putcad(2,16,0xffff,COLORFONDO,cad);
if(menupoint == 5)
v_putcad(2,16,0xffff,TEXTBACK,cad);
sprintf(cad,"DecrKey: ");
formatkey(cad,daemonsettings[6]);
v_putcad(2,17,0xffff,COLORFONDO,cad);
if(menupoint == 6)
v_putcad(2,17,0xffff,TEXTBACK,cad);
if(menupoint >= 4 && menupoint <=6)
v_putcad(2,26,WHITE,COLORFONDO,"---------- Stick:UP/DOWN");
v_putcad(2,19,0xffff00,COLORFONDO,"Misc:");
v_putcad(2,21,0xffff,COLORFONDO,(daemonsettings[7] ? "On Screen Display: On" : "On Screen Display: Off"));
if(menupoint == 7)
v_putcad(2,21,0xffff,TEXTBACK,(daemonsettings[7] ? "On Screen Display: On" : "On Screen Display: Off"));
v_putcad(2,23,0xffff,COLORFONDO,(running ? "Kill Running Daemon" : "Start Daemon"));
if(menupoint == 8)
v_putcad(2,23,0xffff,TEXTBACK,(running ? "Kill Running Daemon" : "Start Daemon"));
daemon_itemhelp(menupoint);
gp2x_video_flip();
while(1)
{
gp2x_nKeys=gp2x_joystick_read();
if((gp2x_nKeys & GP2X_DOWN))
{
menupoint++;
if(menupoint>8) menupoint=0;
usleep(200000);
break;
}
if((gp2x_nKeys & GP2X_UP))
{
menupoint--;
if(menupoint<0) menupoint=8;
usleep(200000);
break;
}
if((menupoint >= 4) && (menupoint <= 6) && (gp2x_nKeys & VALID_KEYS))
{
daemonsettings[menupoint] ^= (gp2x_nKeys & VALID_KEYS);
usleep(200000);
break;
}
if(menupoint < 8 &&(gp2x_nKeys & GP2X_R))
{
daemonsettings[menupoint] += 10;
usleep(200000);
break;
}
if(menupoint < 4 && (gp2x_nKeys & GP2X_VOL_UP))
{
daemonsettings[menupoint] -= 1;
usleep(200000);
break;
}
if(menupoint < 4 && (gp2x_nKeys & GP2X_VOL_DOWN))
{
daemonsettings[menupoint] += 1;
usleep(200000);
break;
}
if(menupoint < 8 && (gp2x_nKeys & GP2X_L))
{
daemonsettings[menupoint] -= 10;
usleep(200000);
break;
}
if(menupoint == 8 && (gp2x_nKeys & GP2X_B))
{
if(running)
kill_running_daemon();
else {
int cpu_div = get_920_Div();
int sysfreq=get_freq_920_CLK();
sysfreq*=cpu_div+1;
int cpufreq=sysfreq/1000000;
start_daemon_by_settings();
}
usleep(200000);
running = !access("/tmp/cpu_daemon.pid",R_OK);
break;
}
if((gp2x_nKeys & GP2X_START))
{
while(1)
{
gp2x_nKeys=gp2x_joystick_read();
if(!(gp2x_nKeys & GP2X_START)) break;
}
if(running) { // update values!
start_daemon_by_settings();
}
return;
}
}
}
}
void start_daemon_by_settings() {
int cpu_div = get_920_Div();
int sysfreq=get_freq_920_CLK();
sysfreq*=cpu_div+1;
int cpufreq=sysfreq/1000000;
start_daemon(daemonsettings[0], daemonsettings[1], cpufreq, daemonsettings[2], daemonsettings[4], daemonsettings[5],
daemonsettings[6], daemonsettings[7], 0, daemonsettings[3] * 100000);
}

18
gp2x/daemon.h Normal file
View File

@@ -0,0 +1,18 @@
int start_daemon(
unsigned int minimal_cpu_speed, unsigned int maximal_cpu_speed, unsigned int start_cpu_speed, int cpu_speed_step,
unsigned long hotkey, unsigned long incrementkey, unsigned long decrmentkey,
int speed_display, int foreground,
unsigned long delay);
int kill_running_daemon();
void nano_setup();
void cmd_daemon(int argc, char *argv[]);
unsigned long parse_key_sequence(char *key_sequence);
void daemonmenu();
void formatkey(char * base, unsigned long keyseq);
void start_daemon_by_settings();

139
gp2x/display.c Normal file
View File

@@ -0,0 +1,139 @@
/* display.c for GP2X (CPU/LCD/RAM-Tuner Version 2.0)
Copyright (C) 2006 god_at_hell
original CPU-Overclocker (c) by Hermes/PS2Reality
parts (c) Rlyehs Work
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdio.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <math.h>
#include <unistd.h>
#include "gp2xminilib.h"
#include "cpuctrl.h"
#define WIDTH 320
#define HEIGHT 240
//unsigned TEXTBACK=0x900000; // text-background-color
extern unsigned char msx[]; // define la fuente externa usada para dibujar letras y numeros
void ClearScreen(unsigned val) // se usa para 'borrar' la pantalla virtual con un color
{
int n;
unsigned char *c;
unsigned short col;
c=&val;
col=gp2x_video_color15(c[0],c[1],c[2],0);
for(n=0;n<320*240;n++)
{
gp2x_screen15[n]=col;
}
}
void DrawBox(unsigned val)
{
int n;
unsigned char *c;
unsigned short col;
c=&val;
col=gp2x_video_color15(c[0],c[1],c[2],0);
for(n=320*27+2;n<320*28-1;n++)
{
gp2x_screen15[n]=col;
gp2x_screen15[n+320*209]=col;
}
for(n=320*29+4;n<320*30-3;n++)
{
gp2x_screen15[n]=col;
gp2x_screen15[n+320*169]=col;
gp2x_screen15[n+320*205]=col;
}
for(n=320*28;n<320*237;n=n+320)
{
gp2x_screen15[n+2]=col;
gp2x_screen15[n-2]=col;
}
for(n=320*30;n<320*235;n=n+320)
{
gp2x_screen15[n+4]=col;
gp2x_screen15[n-4]=col;
}
for(n=320*30;n<320*199;n=n+320)
{
gp2x_screen15[n-120]=col;
}
for(n=320*55-120;n<320*55-4;n++)
{
gp2x_screen15[n]=col;
}
}
void v_putchar( unsigned x, unsigned y, unsigned color, unsigned textback, unsigned char ch) // rutina usada para dibujar caracteres (coordenadas de 8x8)
{
int i,j,v;
unsigned char *font;
unsigned char *c;
unsigned short col,col2;
if(x>=WIDTH || y>=HEIGHT) return;
c=&color;
col=gp2x_video_color15(c[0],c[1],c[2],0);
c=&textback;
col2=gp2x_video_color15(c[0],c[1],c[2],0);
v=(y*320*8);
font = &msx[ (int)ch * 8];
for (i=0; i < 8; i++, font++)
{
for (j=0; j < 8; j++)
{
if ((*font & (128 >> j)))
{
gp2x_screen15[v+(((x<<3)+j))]=col;
}
else gp2x_screen15[v+(((x<<3)+j))]=col2;
}
v+=WIDTH;
}
}
// display array of chars
void v_putcad(int x,int y,unsigned color,unsigned textback,char *cad) // dibuja una cadena de texto
{
while(cad[0]!=0) {v_putchar(x,y,color,textback,cad[0]);cad++;x++;}
}
void gp2x_sound_frame(void *unused, unsigned char *stream, int samples)
{
int n;
short *pu;
pu=stream;
for(n=0;n<(samples);n++)
{
*pu++=0;*pu++=0;
}
}

5
gp2x/display.h Normal file
View File

@@ -0,0 +1,5 @@
void ClearScreen(unsigned val);
void DrawBox(unsigned val);
void v_putchar( unsigned x, unsigned y, unsigned color, unsigned textback, unsigned char ch);
void v_putcad(int x,int y,unsigned color,unsigned textback,char *cad);
void gp2x_sound_frame(void *unused, unsigned char *stream, int samples);

143
gp2x/font.c Normal file
View File

@@ -0,0 +1,143 @@
/*
_____ ___ ____
____| | ____| PSX2 OpenSource Project
| ___| |____ (C)2001, Gustavo Scotti (gustavo@scotti.com)
------------------------------------------------------------------------
font.c
EE UGLY DEBUG ON SCREEN - FONT BASE
This is mostly based on Duke's work
*/
//#include <tamtypes.h>
unsigned char msx[]=
"\x00\x00\x00\x00\x00\x00\x00\x00\x3c\x42\xa5\x81\xa5\x99\x42\x3c"
"\x3c\x7e\xdb\xff\xff\xdb\x66\x3c\x6c\xfe\xfe\xfe\x7c\x38\x10\x00"
"\x10\x38\x7c\xfe\x7c\x38\x10\x00\x10\x38\x54\xfe\x54\x10\x38\x00"
"\x10\x38\x7c\xfe\xfe\x10\x38\x00\x00\x00\x00\x30\x30\x00\x00\x00"
"\xff\xff\xff\xe7\xe7\xff\xff\xff\x38\x44\x82\x82\x82\x44\x38\x00"
"\xc7\xbb\x7d\x7d\x7d\xbb\xc7\xff\x0f\x03\x05\x79\x88\x88\x88\x70"
"\x38\x44\x44\x44\x38\x10\x7c\x10\x30\x28\x24\x24\x28\x20\xe0\xc0"
"\x3c\x24\x3c\x24\x24\xe4\xdc\x18\x10\x54\x38\xee\x38\x54\x10\x00"
"\x10\x10\x10\x7c\x10\x10\x10\x10\x10\x10\x10\xff\x00\x00\x00\x00"
"\x00\x00\x00\xff\x10\x10\x10\x10\x10\x10\x10\xf0\x10\x10\x10\x10"
"\x10\x10\x10\x1f\x10\x10\x10\x10\x10\x10\x10\xff\x10\x10\x10\x10"
"\x10\x10\x10\x10\x10\x10\x10\x10\x00\x00\x00\xff\x00\x00\x00\x00"
"\x00\x00\x00\x1f\x10\x10\x10\x10\x00\x00\x00\xf0\x10\x10\x10\x10"
"\x10\x10\x10\x1f\x00\x00\x00\x00\x10\x10\x10\xf0\x00\x00\x00\x00"
"\x81\x42\x24\x18\x18\x24\x42\x81\x01\x02\x04\x08\x10\x20\x40\x80"
"\x80\x40\x20\x10\x08\x04\x02\x01\x00\x10\x10\xff\x10\x10\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x20\x20\x20\x20\x00\x00\x20\x00"
"\x50\x50\x50\x00\x00\x00\x00\x00\x50\x50\xf8\x50\xf8\x50\x50\x00"
"\x20\x78\xa0\x70\x28\xf0\x20\x00\xc0\xc8\x10\x20\x40\x98\x18\x00"
"\x40\xa0\x40\xa8\x90\x98\x60\x00\x10\x20\x40\x00\x00\x00\x00\x00"
"\x10\x20\x40\x40\x40\x20\x10\x00\x40\x20\x10\x10\x10\x20\x40\x00"
"\x20\xa8\x70\x20\x70\xa8\x20\x00\x00\x20\x20\xf8\x20\x20\x00\x00"
"\x00\x00\x00\x00\x00\x20\x20\x40\x00\x00\x00\x78\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x60\x60\x00\x00\x00\x08\x10\x20\x40\x80\x00"
"\x70\x88\x98\xa8\xc8\x88\x70\x00\x20\x60\xa0\x20\x20\x20\xf8\x00"
"\x70\x88\x08\x10\x60\x80\xf8\x00\x70\x88\x08\x30\x08\x88\x70\x00"
"\x10\x30\x50\x90\xf8\x10\x10\x00\xf8\x80\xe0\x10\x08\x10\xe0\x00"
"\x30\x40\x80\xf0\x88\x88\x70\x00\xf8\x88\x10\x20\x20\x20\x20\x00"
"\x70\x88\x88\x70\x88\x88\x70\x00\x70\x88\x88\x78\x08\x10\x60\x00"
"\x00\x00\x20\x00\x00\x20\x00\x00\x00\x00\x20\x00\x00\x20\x20\x40"
"\x18\x30\x60\xc0\x60\x30\x18\x00\x00\x00\xf8\x00\xf8\x00\x00\x00"
"\xc0\x60\x30\x18\x30\x60\xc0\x00\x70\x88\x08\x10\x20\x00\x20\x00"
"\x70\x88\x08\x68\xa8\xa8\x70\x00\x20\x50\x88\x88\xf8\x88\x88\x00"
"\xf0\x48\x48\x70\x48\x48\xf0\x00\x30\x48\x80\x80\x80\x48\x30\x00"
"\xe0\x50\x48\x48\x48\x50\xe0\x00\xf8\x80\x80\xf0\x80\x80\xf8\x00"
"\xf8\x80\x80\xf0\x80\x80\x80\x00\x70\x88\x80\xb8\x88\x88\x70\x00"
"\x88\x88\x88\xf8\x88\x88\x88\x00\x70\x20\x20\x20\x20\x20\x70\x00"
"\x38\x10\x10\x10\x90\x90\x60\x00\x88\x90\xa0\xc0\xa0\x90\x88\x00"
"\x80\x80\x80\x80\x80\x80\xf8\x00\x88\xd8\xa8\xa8\x88\x88\x88\x00"
"\x88\xc8\xc8\xa8\x98\x98\x88\x00\x70\x88\x88\x88\x88\x88\x70\x00"
"\xf0\x88\x88\xf0\x80\x80\x80\x00\x70\x88\x88\x88\xa8\x90\x68\x00"
"\xf0\x88\x88\xf0\xa0\x90\x88\x00\x70\x88\x80\x70\x08\x88\x70\x00"
"\xf8\x20\x20\x20\x20\x20\x20\x00\x88\x88\x88\x88\x88\x88\x70\x00"
"\x88\x88\x88\x88\x50\x50\x20\x00\x88\x88\x88\xa8\xa8\xd8\x88\x00"
"\x88\x88\x50\x20\x50\x88\x88\x00\x88\x88\x88\x70\x20\x20\x20\x00"
"\xf8\x08\x10\x20\x40\x80\xf8\x00\x70\x40\x40\x40\x40\x40\x70\x00"
"\x00\x00\x80\x40\x20\x10\x08\x00\x70\x10\x10\x10\x10\x10\x70\x00"
"\x20\x50\x88\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf8\x00"
"\x40\x20\x10\x00\x00\x00\x00\x00\x00\x00\x70\x08\x78\x88\x78\x00"
"\x80\x80\xb0\xc8\x88\xc8\xb0\x00\x00\x00\x70\x88\x80\x88\x70\x00"
"\x08\x08\x68\x98\x88\x98\x68\x00\x00\x00\x70\x88\xf8\x80\x70\x00"
"\x10\x28\x20\xf8\x20\x20\x20\x00\x00\x00\x68\x98\x98\x68\x08\x70"
"\x80\x80\xf0\x88\x88\x88\x88\x00\x20\x00\x60\x20\x20\x20\x70\x00"
"\x10\x00\x30\x10\x10\x10\x90\x60\x40\x40\x48\x50\x60\x50\x48\x00"
"\x60\x20\x20\x20\x20\x20\x70\x00\x00\x00\xd0\xa8\xa8\xa8\xa8\x00"
"\x00\x00\xb0\xc8\x88\x88\x88\x00\x00\x00\x70\x88\x88\x88\x70\x00"
"\x00\x00\xb0\xc8\xc8\xb0\x80\x80\x00\x00\x68\x98\x98\x68\x08\x08"
"\x00\x00\xb0\xc8\x80\x80\x80\x00\x00\x00\x78\x80\xf0\x08\xf0\x00"
"\x40\x40\xf0\x40\x40\x48\x30\x00\x00\x00\x90\x90\x90\x90\x68\x00"
"\x00\x00\x88\x88\x88\x50\x20\x00\x00\x00\x88\xa8\xa8\xa8\x50\x00"
"\x00\x00\x88\x50\x20\x50\x88\x00\x00\x00\x88\x88\x98\x68\x08\x70"
"\x00\x00\xf8\x10\x20\x40\xf8\x00\x18\x20\x20\x40\x20\x20\x18\x00"
"\x20\x20\x20\x00\x20\x20\x20\x00\xc0\x20\x20\x10\x20\x20\xc0\x00"
"\x40\xa8\x10\x00\x00\x00\x00\x00\x00\x00\x20\x50\xf8\x00\x00\x00"
"\x70\x88\x80\x80\x88\x70\x20\x60\x90\x00\x00\x90\x90\x90\x68\x00"
"\x10\x20\x70\x88\xf8\x80\x70\x00\x20\x50\x70\x08\x78\x88\x78\x00"
"\x48\x00\x70\x08\x78\x88\x78\x00\x20\x10\x70\x08\x78\x88\x78\x00"
"\x20\x00\x70\x08\x78\x88\x78\x00\x00\x70\x80\x80\x80\x70\x10\x60"
"\x20\x50\x70\x88\xf8\x80\x70\x00\x50\x00\x70\x88\xf8\x80\x70\x00"
"\x20\x10\x70\x88\xf8\x80\x70\x00\x50\x00\x00\x60\x20\x20\x70\x00"
"\x20\x50\x00\x60\x20\x20\x70\x00\x40\x20\x00\x60\x20\x20\x70\x00"
"\x50\x00\x20\x50\x88\xf8\x88\x00\x20\x00\x20\x50\x88\xf8\x88\x00"
"\x10\x20\xf8\x80\xf0\x80\xf8\x00\x00\x00\x6c\x12\x7e\x90\x6e\x00"
"\x3e\x50\x90\x9c\xf0\x90\x9e\x00\x60\x90\x00\x60\x90\x90\x60\x00"
"\x90\x00\x00\x60\x90\x90\x60\x00\x40\x20\x00\x60\x90\x90\x60\x00"
"\x40\xa0\x00\xa0\xa0\xa0\x50\x00\x40\x20\x00\xa0\xa0\xa0\x50\x00"
"\x90\x00\x90\x90\xb0\x50\x10\xe0\x50\x00\x70\x88\x88\x88\x70\x00"
"\x50\x00\x88\x88\x88\x88\x70\x00\x20\x20\x78\x80\x80\x78\x20\x20"
"\x18\x24\x20\xf8\x20\xe2\x5c\x00\x88\x50\x20\xf8\x20\xf8\x20\x00"
"\xc0\xa0\xa0\xc8\x9c\x88\x88\x8c\x18\x20\x20\xf8\x20\x20\x20\x40"
"\x10\x20\x70\x08\x78\x88\x78\x00\x10\x20\x00\x60\x20\x20\x70\x00"
"\x20\x40\x00\x60\x90\x90\x60\x00\x20\x40\x00\x90\x90\x90\x68\x00"
"\x50\xa0\x00\xa0\xd0\x90\x90\x00\x28\x50\x00\xc8\xa8\x98\x88\x00"
"\x00\x70\x08\x78\x88\x78\x00\xf8\x00\x60\x90\x90\x90\x60\x00\xf0"
"\x20\x00\x20\x40\x80\x88\x70\x00\x00\x00\x00\xf8\x80\x80\x00\x00"
"\x00\x00\x00\xf8\x08\x08\x00\x00\x84\x88\x90\xa8\x54\x84\x08\x1c"
"\x84\x88\x90\xa8\x58\xa8\x3c\x08\x20\x00\x00\x20\x20\x20\x20\x00"
"\x00\x00\x24\x48\x90\x48\x24\x00\x00\x00\x90\x48\x24\x48\x90\x00"
"\x28\x50\x20\x50\x88\xf8\x88\x00\x28\x50\x70\x08\x78\x88\x78\x00"
"\x28\x50\x00\x70\x20\x20\x70\x00\x28\x50\x00\x20\x20\x20\x70\x00"
"\x28\x50\x00\x70\x88\x88\x70\x00\x50\xa0\x00\x60\x90\x90\x60\x00"
"\x28\x50\x00\x88\x88\x88\x70\x00\x50\xa0\x00\xa0\xa0\xa0\x50\x00"
"\xfc\x48\x48\x48\xe8\x08\x50\x20\x00\x50\x00\x50\x50\x50\x10\x20"
"\xc0\x44\xc8\x54\xec\x54\x9e\x04\x10\xa8\x40\x00\x00\x00\x00\x00"
"\x00\x20\x50\x88\x50\x20\x00\x00\x88\x10\x20\x40\x80\x28\x00\x00"
"\x7c\xa8\xa8\x68\x28\x28\x28\x00\x38\x40\x30\x48\x48\x30\x08\x70"
"\x00\x00\x00\x00\x00\x00\xff\xff\xf0\xf0\xf0\xf0\x0f\x0f\x0f\x0f"
"\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x3c\x3c\x00\x00\x00\xff\xff\xff\xff\xff\xff\x00\x00"
"\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\x0f\x0f\x0f\x0f\xf0\xf0\xf0\xf0"
"\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\x03\x03\x03\x03\x03\x03\x03\x03"
"\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x11\x22\x44\x88\x11\x22\x44\x88"
"\x88\x44\x22\x11\x88\x44\x22\x11\xfe\x7c\x38\x10\x00\x00\x00\x00"
"\x00\x00\x00\x00\x10\x38\x7c\xfe\x80\xc0\xe0\xf0\xe0\xc0\x80\x00"
"\x01\x03\x07\x0f\x07\x03\x01\x00\xff\x7e\x3c\x18\x18\x3c\x7e\xff"
"\x81\xc3\xe7\xff\xff\xe7\xc3\x81\xf0\xf0\xf0\xf0\x00\x00\x00\x00"
"\x00\x00\x00\x00\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x00\x00\x00\x00"
"\x00\x00\x00\x00\xf0\xf0\xf0\xf0\x33\x33\xcc\xcc\x33\x33\xcc\xcc"
"\x00\x20\x20\x50\x50\x88\xf8\x00\x20\x20\x70\x20\x70\x20\x20\x00"
"\x00\x00\x00\x50\x88\xa8\x50\x00\xff\xff\xff\xff\xff\xff\xff\xff"
"\x00\x00\x00\x00\xff\xff\xff\xff\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0"
"\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\xff\xff\xff\xff\x00\x00\x00\x00"
"\x00\x00\x68\x90\x90\x90\x68\x00\x30\x48\x48\x70\x48\x48\x70\xc0"
"\xf8\x88\x80\x80\x80\x80\x80\x00\xf8\x50\x50\x50\x50\x50\x98\x00"
"\xf8\x88\x40\x20\x40\x88\xf8\x00\x00\x00\x78\x90\x90\x90\x60\x00"
"\x00\x50\x50\x50\x50\x68\x80\x80\x00\x50\xa0\x20\x20\x20\x20\x00"
"\xf8\x20\x70\xa8\xa8\x70\x20\xf8\x20\x50\x88\xf8\x88\x50\x20\x00"
"\x70\x88\x88\x88\x50\x50\xd8\x00\x30\x40\x40\x20\x50\x50\x50\x20"
"\x00\x00\x00\x50\xa8\xa8\x50\x00\x08\x70\xa8\xa8\xa8\x70\x80\x00"
"\x38\x40\x80\xf8\x80\x40\x38\x00\x70\x88\x88\x88\x88\x88\x88\x00"
"\x00\xf8\x00\xf8\x00\xf8\x00\x00\x20\x20\xf8\x20\x20\x00\xf8\x00"
"\xc0\x30\x08\x30\xc0\x00\xf8\x00\x18\x60\x80\x60\x18\x00\xf8\x00"
"\x10\x28\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\xa0\x40"
"\x00\x20\x00\xf8\x00\x20\x00\x00\x00\x50\xa0\x00\x50\xa0\x00\x00"
"\x00\x18\x24\x24\x18\x00\x00\x00\x00\x30\x78\x78\x30\x00\x00\x00"
"\x00\x00\x00\x00\x30\x00\x00\x00\x3e\x20\x20\x20\xa0\x60\x20\x00"
"\xa0\x50\x50\x50\x00\x00\x00\x00\x40\xa0\x20\x40\xe0\x00\x00\x00"
"\x00\x38\x38\x38\x38\x38\x38\x00\x00\x00\x00\x00\x00\x00\x00";

93
gp2x/gp2x.c Normal file
View File

@@ -0,0 +1,93 @@
/* Parts used from cpuctrl */
/* cpuctrl for GP2X
Copyright (C) 2005 Hermes/PS2Reality
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/soundcard.h>
#include "../common.h"
#include "gp2x.h"
extern int main_cpuspeed(int argc, char *argv[]);
extern SDL_Surface* screen;
u32 gp2x_audio_volume = 74;
u32 gpsp_gp2x_dev_audio = 0;
u32 gpsp_gp2x_dev = 0;
volatile u16 *gpsp_gp2x_memregs;
volatile u32 *gpsp_gp2x_memregl;
static volatile u16 *MEM_REG;
s32 gp2x_load_mmuhack()
{
s32 mmufd = open("/dev/mmuhack", O_RDWR);
if(mmufd < 0)
{
system("/sbin/insmod mmuhack.o");
mmufd = open("/dev/mmuhack", O_RDWR);
}
if(mmufd < 0)
return -1;
close(mmufd);
return 0;
}
void gp2x_overclock()
{
gpsp_gp2x_dev = open("/dev/mem", O_RDWR);
gpsp_gp2x_dev_audio = open("/dev/mixer", O_RDWR);
gpsp_gp2x_memregl =
(unsigned long *)mmap(0, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED,
gpsp_gp2x_dev, 0xc0000000);
gpsp_gp2x_memregs = (unsigned short *)gpsp_gp2x_memregl;
clear_screen(0);
main_cpuspeed(0, NULL);
gp2x_sound_volume(1);
}
void gp2x_quit()
{
munmap((void *)gpsp_gp2x_memregl, 0x10000);
close(gpsp_gp2x_dev_audio);
close(gpsp_gp2x_dev);
chdir("/usr/gp2x");
execl("gp2xmenu", "gp2xmenu", NULL);
}
void gp2x_sound_volume(u32 volume_up)
{
u32 volume;
if((volume_up == 0) && (gp2x_audio_volume > 0))
gp2x_audio_volume--;
if((volume_up != 0) && (gp2x_audio_volume < 100))
gp2x_audio_volume++;
volume = (gp2x_audio_volume * 0x50) / 100;
volume = (gp2x_audio_volume << 8) | gp2x_audio_volume;
ioctl(gpsp_gp2x_dev_audio, SOUND_MIXER_WRITE_PCM, &volume);
}

50
gp2x/gp2x.h Normal file
View File

@@ -0,0 +1,50 @@
#ifndef GP2X_H
#define GP2X_H
enum
{
GP2X_UP = 1 << 0,
GP2X_LEFT = 1 << 2,
GP2X_DOWN = 1 << 4,
GP2X_RIGHT = 1 << 6,
GP2X_START = 1 << 8,
GP2X_SELECT = 1 << 9,
GP2X_L = 1 << 10,
GP2X_R = 1 << 11,
GP2X_A = 1 << 12,
GP2X_B = 1 << 13,
GP2X_X = 1 << 14,
GP2X_Y = 1 << 15,
GP2X_VOL_DOWN = 1 << 22,
GP2X_VOL_UP = 1 << 23,
GP2X_PUSH = 1 << 27
};
extern u32 gpsp_gp2x_dev_audio;
extern u32 gpsp_gp2x_dev;
extern volatile u16 *gpsp_gp2x_memregs;
extern volatile u32 *gpsp_gp2x_memregl;
void gp2x_sound_volume(u32 volume_up);
void gp2x_quit();
// call this at first
void cpuctrl_init(void);
void save_system_regs(void);
void cpuctrl_deinit(void);
void set_display_clock_div(unsigned div);
void set_FCLK(u32 MHZ);
// 0 to 7 divider (freq = FCLK / (1 + div))
void set_920_Div(u16 div);
void set_DCLK_Div(u16 div);
void Disable_940(void);
void gp2x_video_wait_vsync(void);
unsigned short get_920_Div();
void set_940_Div(u16 div);
s32 gp2x_load_mmuhack();
#endif

242
gp2x/gp2xminilib.c Normal file
View File

@@ -0,0 +1,242 @@
/*
GP2X minimal library v0.5 by rlyeh, 2005.
+ GP2X video library with double buffering.
+ GP2X soundring buffer library with double buffering.
+ GP2X joystick library.
Thanks to Squidge, Robster, snaff and NK, for the help & previous work! :-)
What's new
==========
0.5: patched sound for real stereo (using NK's solution); better init code.
0.4: lots of cleanups; sound is threaded now, double buffered too; 8 bpp video support; better exiting code.
0.3: shorter library; improved joystick diagonal detection.
0.2: better code layout; public release.
0.1: beta release
*/
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/soundcard.h>
#include <linux/fb.h>
#include <pthread.h>
#include "gp2xminilib.h"
extern void gp2x_sound_frame(void *blah, void *bufferg, int samples);
unsigned long gp2x_dev[4]={0,0,0,0}, gp2x_physvram[4];
unsigned short *gp2x_memregs, *gp2x_screen15, *gp2x_logvram15[2], gp2x_sound_buffer[4+(44100*2)*4]; //*2=stereo, *4=max buffers
volatile unsigned short gp2x_palette[512][2];
unsigned char *gp2x_screen8, *gp2x_logvram8[2];
pthread_t gp2x_sound_thread=0, gp2x_sound_thread_exit=0;
void gp2x_video_flip(void)
{
unsigned long address=gp2x_physvram[gp2x_physvram[3]];
gp2x_screen15=gp2x_logvram15[gp2x_physvram[3]^=1];
gp2x_screen8 =gp2x_logvram8 [gp2x_physvram[3] ];
gp2x_memregs[0x290E>>1]=(unsigned short)(address & 0xffff);
gp2x_memregs[0x2910>>1]=(unsigned short)(address >> 16);
gp2x_memregs[0x2912>>1]=(unsigned short)(address & 0xffff);
gp2x_memregs[0x2914>>1]=(unsigned short)(address >> 16);
}
void gp2x_video_setpalette(void)
{int i;
gp2x_memregs[0x2958>>1]=0;
for(i=0; i<512; i++) gp2x_memregs[0x295A>>1]=gp2x_palette[i][0], gp2x_memregs[0x295A>>1]=gp2x_palette[i][1];
}
unsigned long gp2x_joystick_read(void)
{
unsigned long value=(gp2x_memregs[0x1198>>1] & 0x00FF);
if(value==0xFD) value=0xFA;
if(value==0xF7) value=0xEB;
if(value==0xDF) value=0xAF;
if(value==0x7F) value=0xBE;
return ~((gp2x_memregs[0x1184>>1] & 0xFF00) | value | (gp2x_memregs[0x1186>>1] << 16));
}
#if 0
void *gp2x_sound_play(void *blah)
{
struct timespec ts;
int flip=0;
ts.tv_sec=0, ts.tv_nsec=gp2x_sound_buffer[2];
while(! gp2x_sound_thread_exit)
{
gp2x_sound_frame(blah, (void *)(&gp2x_sound_buffer[4+flip]), gp2x_sound_buffer[0]);
write(gp2x_dev[3], (void *)(&gp2x_sound_buffer[4+flip]), gp2x_sound_buffer[1]);
flip^=gp2x_sound_buffer[1];
//nanosleep(&ts, NULL);
}
return NULL;
}
#endif
void gp2x_deinit(void)
{int i;
if(gp2x_sound_thread) { gp2x_sound_thread_exit=1; for(i=0;i<1000000;i++); }
gp2x_memregs[0x28DA>>1]=0x4AB;
gp2x_memregs[0x290C>>1]=640;
close(gp2x_dev[0]);
close(gp2x_dev[1]);
close(gp2x_dev[2]);
//close(gp2x_dev[3]);
//fcloseall();
}
void gp2x_init(int bpp, int rate, int bits, int stereo, int Hz)
{
struct fb_fix_screeninfo fixed_info;
if(!gp2x_dev[0]) gp2x_dev[0] = open("/dev/fb0", O_RDWR);
if(!gp2x_dev[1]) gp2x_dev[1] = open("/dev/fb1", O_RDWR);
if(!gp2x_dev[2]) gp2x_dev[2] = open("/dev/mem", O_RDWR);
//if(!gp2x_dev[3]) gp2x_dev[3] = open("/dev/dsp", O_WRONLY);
gp2x_memregs=(unsigned short *)mmap(0, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, gp2x_dev[2], 0xc0000000);
if(!gp2x_sound_thread) { gp2x_memregs[0x0F16>>1] = 0x830a; sleep(1);
gp2x_memregs[0x0F58>>1] = 0x100c; sleep(1); }
ioctl (gp2x_dev[0], FBIOGET_FSCREENINFO, &fixed_info);
gp2x_screen15=gp2x_logvram15[0]=(unsigned short *)mmap(0, 320*240*2, PROT_WRITE, MAP_SHARED, gp2x_dev[0], 0);
gp2x_screen8=gp2x_logvram8[0]=(unsigned char *)gp2x_logvram15[0];
gp2x_physvram[0]=fixed_info.smem_start;
ioctl (gp2x_dev[1], FBIOGET_FSCREENINFO, &fixed_info);
gp2x_logvram15[1]=(unsigned short *)mmap(0, 320*240*2, PROT_WRITE, MAP_SHARED, gp2x_dev[1], 0);
gp2x_logvram8[1]=(unsigned char *)gp2x_logvram15[1];
gp2x_physvram[1]=fixed_info.smem_start;
gp2x_memregs[0x28DA>>1]=(((bpp+1)/8)<<9)|0xAB; /*8/15/16/24bpp...*/
gp2x_memregs[0x290C>>1]=320*((bpp+1)/8); /*line width in bytes*/
ioctl(gp2x_dev[3], SNDCTL_DSP_SPEED, &rate);
ioctl(gp2x_dev[3], SNDCTL_DSP_SETFMT, &bits);
ioctl(gp2x_dev[3], SNDCTL_DSP_STEREO, &stereo);
gp2x_sound_buffer[1]=(gp2x_sound_buffer[0]=(rate/Hz)) << (stereo + (bits==16));
gp2x_sound_buffer[2]=(1000000/Hz);
if(!gp2x_sound_thread) { gp2x_sound_thread = 1; //pthread_create( &gp2x_sound_thread, NULL, gp2x_sound_play, NULL);
atexit(gp2x_deinit); }
}
/*
EXAMPLE
=======
now supply your own function for 16 bits, stereo:
void gp2x_sound_frame(void *blah, void *bufferg, int samples)
{
signed short *buffer=(signed short *)bufferg;
while(samples--)
{
*buffer++=0; //Left channel
*buffer++=0; //Right channel
}
}
or 16 bits mono:
void gp2x_sound_frame(void *blah, void *bufferg, int samples)
{
signed short *buffer=(signed short *)bufferg;
while(samples--)
{
*buffer++=0; //Central channel
}
}
now the main program...
hicolor example:
int main(int argc, char *argv[])
{
//this sets video to hicolor (16 bpp)
//it also sets sound to 44100,16bits,stereo and syncs audio to 50 Hz (PAL timing)
//Warning: GP2X does not support 8bit sound sampling! (at least within Linux)
gp2x_init(16,44100,16,1,50);
while(1)
{
unsigned long pad=gp2x_joystick_read();
unsigned short color=gp2x_video_color15(255,255,255,0);
if(pad & GP2X_L) if(pad & GP2X_R) exit();
if(pad & GP2X_A) color=gp2x_color15(255,255,255,0); //white
else color=gp2x_color15(255,0,0,0); //red
gp2x_screen15[160+120*320]=color; //x=160, y=120
gp2x_video_flip();
}
}
palettized example:
int main(int argc, char *argv[])
{
//this sets video to palette mode (8 bpp)
//it also sets sound to 11025,16bits,stereo and syncs audio to 60 Hz (NSTC timing)
//Warning: GP2X does not support 8bit sound sampling! (at least within Linux)
gp2x_init(8,11025,16,1,60);
gp2x_video_color8(0,0,0,0); //color #0 is black for us
gp2x_video_color8(1,255,255,255); //color #1 is white for us
gp2x_video_color8(2,255,0,0); //color #2 is red for us
gp2x_video_setpalette();
while(1)
{
unsigned long pad=gp2x_joystick_read();
unsigned char color;
if(pad & GP2X_L) if(pad & GP2X_R) exit();
if(pad & GP2X_A) color=1; //white
else color=2; //red
gp2x_screen8[160+120*320]=color; //x=160, y=120
gp2x_video_flip();
}
}
*/

58
gp2x/gp2xminilib.h Normal file
View File

@@ -0,0 +1,58 @@
/*
GP2X minimal library v0.5 by rlyeh, 2005.
+ GP2X video library with double buffering.
+ GP2X soundring buffer library with double buffering.
+ GP2X joystick library.
Thanks to Squidge, Robster, snaff and NK, for the help & previous work! :-)
What's new
==========
0.5: patched sound for real stereo (using NK's solution); better init code.
0.4: lots of cleanups; sound is threaded now, double buffered too; 8 bpp video support; better exiting code.
0.3: shorter library; improved joystick diagonal detection.
0.2: better code layout; public release.
0.1: beta release
*/
/* .h by Hermes/PS2Reality*/
#if !defined(GP2XMINILIB)
#define GP2XMINILIB
enum { GP2X_UP=0x1, GP2X_LEFT=0x4, GP2X_DOWN=0x10, GP2X_RIGHT=0x40,
GP2X_START=1<<8, GP2X_SELECT=1<<9, GP2X_L=1<<10, GP2X_R=1<<11,
GP2X_A=1<<12, GP2X_B=1<<13, GP2X_X=1<<14, GP2X_Y=1<<15,
GP2X_VOL_UP=1<<22, GP2X_VOL_DOWN=1<<23, GP2X_PUSH=1<<27, };
#define gp2x_video_color15(R,G,B,A) (((R&0xF8)<<8)|((G&0xF8)<<3)|((B&0xF8)>>3)|(A<<5))
#define gp2x_video_color8 (C,R,G,B) gp2x_palette[C][0]=(G<<8)|B,gp2x_palette[C][1]=R;
extern unsigned short *gp2x_memregs, *gp2x_screen15, *gp2x_logvram15[2], gp2x_sound_buffer[4+(44100*2)*4]; //*2=stereo, *4=max buffers
extern unsigned long gp2x_dev[4];
void gp2x_video_flip(void);
void gp2x_video_setpalette(void);
unsigned long gp2x_joystick_read(void);
void *gp2x_sound_play(void *blah);
void gp2x_deinit(void);
void gp2x_init(int bpp, int rate, int bits, int stereo, int Hz);
#endif

135
gp2x/load_imm_test.c Normal file
View File

@@ -0,0 +1,135 @@
#include <stdio.h>
typedef unsigned int u32;
u32 arm_imm_find_nonzero(u32 imm, u32 start_bit)
{
u32 i;
for(i = start_bit; i < 32; i += 2)
{
if((imm >> i) & 0x03)
break;
}
return i;
}
u32 arm_disect_imm_32bit(u32 imm, u32 *stores, u32 *rotations)
{
u32 store_count = 0;
u32 left_shift = 0;
// Otherwise it'll return 0 things to store because it'll never
// find anything.
if(imm == 0)
{
rotations[0] = 0;
stores[0] = 0;
return 1;
}
// Find chunks of non-zero data at 2 bit alignments.
while(1)
{
left_shift = arm_imm_find_nonzero(imm, left_shift);
if(left_shift == 32)
{
// We've hit the end of the useful data.
return store_count;
}
// Hit the end, it might wrap back around to the beginning.
if(left_shift >= 24)
{
// Make a mask for the residual bits. IE, if we have
// 5 bits of data at the end we can wrap around to 3
// bits of data in the beginning. Thus the first
// thing, after being shifted left, has to be less
// than 111b, 0x7, or (1 << 3) - 1.
u32 top_bits = 32 - left_shift;
u32 residual_bits = 8 - top_bits;
u32 residual_mask = (1 << residual_bits) - 1;
if((store_count > 1) && (left_shift > 24) &&
((stores[0] << (32 - rotations[0])) < residual_mask))
{
// Then we can throw out the last bit and tack it on
// to the first bit.
u32 initial_bits = rotations[0];
stores[0] = (stores[0] << (top_bits + (32 - rotations[0]))) |
((imm >> left_shift) & 0xFF);
rotations[0] = top_bits;
return store_count;
}
else
{
// There's nothing to wrap over to in the beginning
stores[store_count] = (imm >> left_shift) & 0xFF;
rotations[store_count] = (32 - left_shift) & 0x1F;
return store_count + 1;
}
break;
}
stores[store_count] = (imm >> left_shift) & 0xFF;
rotations[store_count] = (32 - left_shift) & 0x1F;
store_count++;
left_shift += 8;
}
}
#define ror(value, shift) \
((value) >> shift) | ((value) << (32 - shift)) \
u32 arm_assemble_imm_32bit(u32 *stores, u32 *rotations, u32 store_count)
{
u32 n = ror(stores[0], rotations[0]);
u32 i;
printf("%x : %x\n", stores[0], rotations[0]);
for(i = 1; i < store_count; i++)
{
printf("%x : %x\n", stores[i], rotations[i]);
n |= ror(stores[i], rotations[i]);
}
return n;
}
int main(int argc, char *argv[])
{
u32 n = 0;
u32 stores[4];
u32 rotations[4];
u32 store_count;
u32 n2;
if(argc != 1)
{
n = strtoul(argv[1], NULL, 16);
store_count = arm_disect_imm_32bit(n, stores, rotations);
n2 = arm_assemble_imm_32bit(stores, rotations, store_count);
printf("%08x -> %08x (%d stores)\n", n, n2, store_count);
return 0;
}
do
{
store_count = arm_disect_imm_32bit(n, stores, rotations);
n2 = arm_assemble_imm_32bit(stores, rotations, store_count);
if(n != n2)
{
printf("Failure: %08x -/-> %08x\n", n, n2);
return -1;
}
n++;
} while(n != 0);
printf("Done!\n");
return 0;
}

262
gp2x/readme_gp2x.txt Normal file
View File

@@ -0,0 +1,262 @@
-- gameplaySP2X Gameboy Advance emulator for GP2X --
gpSP2X is a version of my (Exophase)'s emulator originally for Sony PSP.
A large amount of effort has been done to make it more optimized for the
ARM CPU present in the GP2X, however it is still very much a work in
progress.
See readme.txt for the PSP version readme, which contains a lot of
information relevant to the GP2X version (note that some of it does
not apply however).
Changelog:
0.9-2xb:
-- IMPORTANT-- If you're overwriting an old version, be sure to delete the
gpsp.cfg file first, or be prepared to have a bunch of weird button
settings that would require fixing.
- Fixed some bugs stunting compatability.
- Optimized alpha blends in renderer.
- Some more optimizations to dynarec output.
- Savestates should work better now.
- Cheat/misc menu won't crash the emulator.
- Main button config window works (not all buttons are in yet)
0.9-2Xa: (Exophase release)
- Redid autoframeskip. Should work more reliably.
- Rewrote dynamic recompiler from x86 source (arm_emit.h, arm_stub.S).
Has some more sophisticated behavior than the last version, more is
still to come... Should notice a slight speed improvement over the
last version.
- Tweaked GUI to be a little more useable. Buttons are now mirroring the
PSP version's.
- Code unification + cleanup amongst versions.
v9008: (zodttd release)
- Updated the way autoframeskip works. Should be better now. Still has a max
frameskip value.
- Added a slight performance increase to the dynarec.
- Added sync() to make sure files such as savestates and in-game saves are
saved properly to the GP2X.
v9006: (zodttd release)
- Initial public release
Installation:
1. Place the "gpsp.gpe" and "game_config.txt" file in a directory on your SD
card used with the GP2X.
2. Place your GBA BIOS in the directory from step 1. This file must be named
"gba_bios.bin" in all lowercase as shown, so rename it if needed.
-- NOTE --
There are two commonly available BIOSes - one is the correct one used in
production GBA's worldwide and the other is a prototype BIOS. The latter
will not cause some games to not work correctly or crash. If you attempt
to use this BIOS you will be presented with a warning before being
allowed to continue. This screen will give you a checksum of the real
BIOS image (see readme.txt for further information).
3. Place your GBA games in the directory from step 1. These files should have
a ".gba" or ".bin" file extension. Zip compressed games should be supported
and are recognized with the ".zip" file extension. Note that 32MB ROMs will
probably not run if zipped. 16MB and smaller should be OK.
4. Done. Run gpsp.gpe.
Controls:
How to use gpSP on the GP2X:
Buttons are mapped as follows (GBA/ingame buttons can be changed in the menu):
GP2X--------------------GBA
X -> A
B -> B
L TRIG -> L TRIG
R TRIG -> R TRIG
START -> START
SELECT -> SELECT
GP2X--------------------------------gpSP
-- IN-GAME --
VOL MIDDLE (UP + DOWN) -> menu
PUSH STICK -> fps display toggle (second number is
frames actually drawn)
-- IN-MENU --
B -> select option
X -> cancel/exit menu
A -> escape (up one director level in the
file selector)
When gpSP is started, you are presented with the option to overclock your
GP2X. Use the L/R TRIG to change the CPU clockspeed and press START to
continue. You may also change RAM timings here - experiment with what
works well. Note that going too high on overclocking or low on RAM
timings can cause the game to crash or the GP2X to outright freeze up.
If you do not want to overclock, press START without using L/R.
You will now be presented with a menu to choose a game. Press the IN-MENU
"SELECT" button shown above to pick a game to load.
If you would like to test gpSP for the GP2X with a homebrew (free public
domain) game, a game by Russ Prince works very well with gpSP. It is called
Bust-A-Move and is a remake of the classic game it's named after.
How to build from source:
The makefile included in the source is geared towards the Open2x toolchain.
If you use Open2x and installed it in the way recommended then it should
work okay, assuming you also have up to date HW-SDL (and have
arm-linux-sdl-config installed in the right place). The makefile is in the
gp2x directory, so go there first then just type make to build gpsp.gpe.
Might need a little tweaking if your setup is different. If you need help
you can ask me, but I'll probably nag you about why you want to build it in
the first place.
GP2X version FAQ:
Q) Help! This game doesn't work. Am I using a bad version of the ROM?
A) First, make sure you're using the correct BIOS version. If you aren't
gpSP should tell you. Other than that, there are some games that are
known to not work now (and will probably work later), and perhaps
many more games that I don't know about that don't work. I haven't
launched a full scale compatability test at this version, so it might
take a while before the compatability levels are high.
Q) Why is this version slower than the PSP version?
A) gpSP is still a work in progress. It might be possible to obtain more
speed from both this version and the PSP one too (and others in the
future). With that in mind, know that even a very agressively overclocked
GP2X is still less powerful than a PSP, generally speaking. Still, I
have a lot of ideas. It's unlikely that the GP2X version will ever be as
fast/faster than the PSP version for anyone but anything's possible.
Q) How high does my GP2X have to overclock to enjoy gpSP?
A) That depends on you. Higher overclocking will mean less frames skipped
on autoframeskip, or less frameskip needed if on manual. Or it can
make the difference between whether or not virtual 60fps can be reached.
For some games no GP2X in the world will be able to run them fullspeed,
with any amount of frameskip. A few might run well with no overclocking
and a generous level of frameskip (probably manual). If you don't care
about battery life (or you're plugged into an outlet) you should push
it as high as you can while still maintaining stability, because
chances are high that whatever you play will benefit from it. Right now
you'll probably want 260MHz if you can achieve it, but with a lot of
luck this number will lower slightly in the future (and is just a vague
ballpark figure anyway). I don't want to scare anyone off from using the
emulator, you should give it a try and see how it plays for you
regardless of how high you can overclock. Just note that this is far
from a locked smooth experience for everyone on every game.
Q) GBA has an ARM processor, GP2X has an ARM processor. GP2X is more
powerful than GBA. This emulator should run great without overclocking,
so therefore you're doing it wrong.
A) That's not a question, but I'll field it anyway. Two things: first,
"virtualization", or running the GBA code "natively" on the GP2X is
probably not possible, at least not with the way I want to do things.
For reasons why go read my blog (see below). So yes, you actually
do need more than 16.7MHz of ARM9 power to emulate the GBA's CPU.
Second: there is a whole lot of work behind emulating the pretty 2D
graphics on the GBA, something it can do in hardware a lot better than
this platform can.
End result: GBA emulation on GP2X isn't as easy as you think it is.
Q) What are you working on now? When will you release the next version?
A) See the gpSP development blog:
http://gpsp-dev.blogspot.com/
Note that I don't give release dates, ever, unless I'm right on the verge
of releasing. Be grateful that I've decided to be much more open about
the development of the emulator now.
Q) Thanks to your blog I heard that you made some improvement. Can I have
a copy of the new code?
A) No. Builds in transition often have a lot of problems, and I like for
releases to be relatively substantial. I can probably be bribed out of
them with donations though. :P
Q) Why do the menu suck so much? Why do half the options not work or not
make any sense?
A) Sorry, the menu still hasn't been modified very much to fit the GP2X
version instead of the PSP version.. hopefully this will improve in the
future.
Q) Who's in charge of the GP2X version anyway?
A) Originally, zodttd was. I, Exophase, have basically usurped control of it
now to encourage zodttd to work more on his PS1 emulator (that and I'm
possessive of gpSP and get nervous when people work on it too heavily).
zodttd will most likely still be around to work on things though.
Q) I'm a super nice person and would like to donate some of my hard earned
money to this one-off GBA emulator. Where do I send my money to?
A) Exophase: exophase@gmail.com on PayPal
zodttd: https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=heirloomer
%40pobox%2ecom&item_number=1&no_shipping=1&no_note=1&tax=0&cy_code=USD&bn=
PP%2dDonationsBF&charset=UTF%2d8
^ Click there for donating on PayPal (remove whitespace/linebreaks).
GP2X people have already donated a lot more to me than PSP people have,
even though there's an order of magnitude or two less users. And they've
donated far more to zodttd than they have to me. So I'm not going to ask
people to donate..
However I won't lie: donating ups the chances of me actually working on the
next version (for which I have a lot of ideas, but not necessarily time to
dedicate to.. that time might need more incentive to be allotted from other
things). This could change depending on my employment situation, but right
now I feel guilty doing anything that doesn't help guarantee that I'll be
able to buy food a year from now.
Q) Tell me all of your personal information.
A) Again not a question, but why not. I'm Exophase, real name: Gilead Kutnick,
male, 23 years old, current residence Bloomington, IN; straight/single/not
actively looking, almost have an MS in Computer Science (do have a BS
underneath it), likes PSP more than GP2X, will not write a Nintendo DS
emulator for either, am currently looking for a job for after I graduate.
Q) You said you're looking for a job.
A) Yes. If you have one or know someone who needs a low level oriented
programmer then I'm up for grabs. And this is my resume:
http://exophase.devzero.co.uk/resume.pdf
Credits:
Original codebase: Exophase (exophase@gmail.com)
Foundation gp2x code: zodttd
GP2X dynarec/stubs + current code maintainance: Exophase

37007
gp2x/rom_cache.S Normal file

File diff suppressed because it is too large Load Diff

205
gp2x/speedtest.c Normal file
View File

@@ -0,0 +1,205 @@
/* speedtest.c for GP2X (CPU/LCD/RAM-Tuner Version 2.0)
Copyright (C) 2006 god_at_hell
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <math.h>
#include <unistd.h>
#include "display.h"
#include "cpuctrl.h"
#include "gp2xminilib.h"
void prim()
{
//FILE *primout;
unsigned char cad[256];
char p = 0;
int primnumber;
int l = 1;
float g = 0;
int i = 3;
while(i != 500000)
{
int m = 2;
float temp = sqrt(i);
float ifloat = (float)i;
if(temp == (int)temp)
{
m = i;
p = 1;
}
while(m < temp)
{
g = ifloat/m;
if (g == (int)g)
{
m = i;
p = 1;
}
m++;
}
if (p == 0)
{
l += 1;
primnumber = i;
sprintf(cad,"%u is primnumber",i);
v_putcad(1,13,0xffffff,0xB00000,cad);
//primout = fopen("/mnt/sd/primnumber.txt", "a");
//fprintf(primout,"%u: %u\n", l, i);
//fclose(primout);
//execl("sync",NULL);
gp2x_video_flip();
}
p = 0;
i++;
}
}
void ant()
{
int i,n;
unsigned char cad[256];
short direction = 0; //clockwise ... 0 = Up, 1 = Right
unsigned short col1, col2;
col1=gp2x_video_color15(0,0,0,0);
col2=gp2x_video_color15(0xFF,0xFF,0xFF,0);
short antx = 200;
short anty = 140;
for(i = 0; i < 9000; i++)
{
for(n = 0; n < 500000; n++);
if(gp2x_screen15[(320*anty) + antx]==col1)
{
for(n = 0; n < 3; n++)
{
int m = 0;
for(m = 0; m < 3; m++)
{
gp2x_screen15[320*(anty+n)+antx+m] = col2;
}
}
sprintf(cad,"%u steps left ",8999-i);
v_putcad(1,3,0x000000,0xffffff,cad);
gp2x_video_flip();
for(n = 0; n < 3; n++)
{
int m = 0;
for(m = 0; m < 3; m++)
{
gp2x_screen15[320*(anty+n)+antx+m] = col2;
}
}
sprintf(cad,"%u steps left ",8999-i);
v_putcad(1,3,0x000000,0xffffff,cad);
gp2x_video_flip();
if(direction == 0) antx-=3;
if(direction == 1) anty-=3;
if(direction == 2) antx+=3;
if(direction == 3) anty+=3;
direction--;
if(direction < 0) direction=3;
}
if(gp2x_screen15[(320*anty) + antx]==col2)
{
for(n = 0; n < 3; n++)
{
int m = 0;
for(m = 0; m < 3; m++)
{
gp2x_screen15[320*(anty+n)+antx+m] = col1;
}
}
sprintf(cad,"%u steps left ",8999-i);
v_putcad(1,3,0x000000,0xffffff,cad);
gp2x_video_flip();
for(n = 0; n < 3; n++)
{
int m = 0;
for(m = 0; m < 3; m++)
{
gp2x_screen15[320*(anty+n)+antx+m] = col1;
}
}
sprintf(cad,"%u steps left ",8999-i);
v_putcad(1,3,0x000000,0xffffff,cad);
gp2x_video_flip();
if(direction == 0) antx+=3;
if(direction == 1) anty+=3;
if(direction == 2) antx-=3;
if(direction == 3) anty-=3;
direction++;
if(direction > 3) direction=0;
}
}
}
void speedtest(short test)
{
unsigned BACKGROUND;
if(test == 0) BACKGROUND=0xB00000;
if(test == 1) BACKGROUND=0xFFFFFF;
short start = 240;
short cpuspeed = start;
unsigned char cad[256];
FILE *speed;
do
{
speed = fopen("/mnt/sd/speed.txt", "w");
ClearScreen(BACKGROUND);
if(test == 0) v_putcad(1,1,0x00ff00,BACKGROUND,"Prim-Speedtest");
if(test == 1) v_putcad(1,1,0x006600,BACKGROUND,"Ant-Speedtest");
v_putcad(1,6,0xffffff,BACKGROUND,"Testing Speed");
if(cpuspeed > start)
{
sprintf(cad,"%uMhz checked",cpuspeed-5);
v_putcad(1,9,0xffffff,BACKGROUND,cad);
}
gp2x_video_flip();
ClearScreen(BACKGROUND);
if(test == 0) v_putcad(1,1,0x00ff00,BACKGROUND,"Prim-Speedtest");
if(test == 1) v_putcad(1,1,0x006600,BACKGROUND,"Ant-Speedtest");
v_putcad(1,6,0xffffff,BACKGROUND,"Testing Speed");
if(cpuspeed > start)
{
sprintf(cad,"%uMhz checked",cpuspeed-5);
if(test == 0) v_putcad(1,9,0xffffff,BACKGROUND,cad);
if(test == 1) v_putcad(1,9,0x000000,BACKGROUND,cad);
}
gp2x_video_flip();
fprintf (speed,"set CPU-Frequency = %uMHz\r\n",cpuspeed);
set_FCLK(cpuspeed);
if(test == 0) prim();
if(test == 1) ant();
fprintf(speed,"%uMhz checked\n\n", cpuspeed);
cpuspeed = cpuspeed + 5;
fclose(speed);
execl("sync",NULL);
}
while(1);
}

3
gp2x/speedtest.h Normal file
View File

@@ -0,0 +1,3 @@
void prim();
void ant();
void speedtest(short test);

78790
gp2x/video.S Normal file

File diff suppressed because it is too large Load Diff

181
gp2x/video_blend.S Normal file
View File

@@ -0,0 +1,181 @@
.align 2
.global expand_blend
.global expand_normal
@ Input:
@ r0 = screen_src_ptr
@ r1 = screen_dest_ptr
@ r2 = start
@ r3 = end
6:
.word io_registers
.word palette_ram_converted
.word 0x04000200 @ combine test mask
.word 0x07E0F81F @ clamp mask
.word 0x000003FE @ palette index mask
.word 0x08010020 @ saturation mask
expand_blend:
stmdb sp!, { r4, r5, r6, r9, r10, r11, r14 }
add r0, r0, r2, lsl #2 @ screen_src_ptr += start
add r1, r1, r2, lsl #1 @ screen_dest_ptr += start
sub r2, r3, r2 @ r2 = end - start
ldr r3, 6b @ r3 = io_registers
ldr r3, [r3, #0x52] @ r3 = bldalpha
mov r4, r3, lsr #8 @ r4 = bldalpha >> 8
and r3, r3, #0x1F @ r3 = blend_a
and r4, r4, #0x1F @ r4 = blend_b
cmp r3, #16 @ if(blend_a > 16)
movgt r3, #16 @ blend_a = 16
cmp r4, #16 @ if(blend_b > 16)
movgt r3, #16 @ blend_b = 16
ldr r14, 6b + 4 @ r14 = palette_ram_converted
ldr r12, 6b + 8 @ r12 = 0x04000200
ldr r11, 6b + 12 @ r11 = 0x07E0F81F
ldr r10, 6b + 16 @ r10 = 0x000003FE
add r5, r3, r4 @ r5 = blend_a + blend_b
cmp r5, #16 @ if((blend_a + blend_b) > 16)
bgt 3f @ goto loop w/saturation
@ loop w/o saturation
1:
ldr r5, [r0], #4 @ r5 = pixel_pair, screen_src_ptr++
and r6, r5, r12 @ r6 = r5 & 0x04000200
cmp r6, r12 @ if(r6 != 0x4000200)
bne 2f @ goto no_blend
and r6, r10, r5, lsl #1 @ r6 = (pixel_pair & 0x1FF) << 1
ldrh r6, [r14, r6] @ r6 = pixel_top
orr r6, r6, r6, lsl #16 @ r6 = pixel_top | (pixel_top << 16)
and r6, r6, r11 @ r6 = pixel_top_dilated
and r5, r10, r5, lsr #15 @ r5 = ((pixel_pair >> 16) & 0x1FF) << 1
ldrh r5, [r14, r5] @ r5 = pixel_bottom
orr r5, r5, r5, lsl #16 @ r5 = pixel_bottom | (pixel_bottom << 16)
and r5, r5, r11 @ r5 = pixel_bottom_dilated
mul r5, r4, r5 @ r5 = pixel_bottom * blend_b = bottom_mul
mla r5, r3, r6, r5 @ r5 = (pixel_top * blend_a) + bottom_mul
and r5, r11, r5, lsr #4 @ r5 = (color_dilated >> 4) & 0x07E0F81F
orr r5, r5, r5, lsr #16 @ r5 = color_dilated | (color_dilated >> 16)
strh r5, [r1], #2 @ *screen_dest_ptr = r5, screen_dest_ptr++
subs r2, r2, #1 @ counter--
bne 1b @ go again
ldmia sp!, { r4, r5, r6, r9, r10, r11, pc }
2:
and r5, r10, r5, lsl #1 @ r5 = (pixel_pair & 0x1FF) << 1
ldrh r5, [r14, r5] @ r5 = pixel_top
strh r5, [r1], #2 @ *screen_dest_ptr = r5, screen_dest_ptr++
subs r2, r2, #1 @ counter--
bne 1b @ go again
ldmia sp!, { r4, r5, r6, r9, r10, r11, pc }
@ loop w/saturation
3:
ldr r9, 6b + 20 @ r9 = 0x08010020
4:
ldr r5, [r0], #4 @ r5 = pixel_pair, screen_src_ptr++
and r6, r5, r12 @ r6 = r5 & 0x04000200
cmp r6, r12 @ if(r6 != 0x4000200)
bne 5f @ goto no_blend
and r6, r10, r5, lsl #1 @ r6 = (pixel_pair & 0x1FF) << 1
ldrh r6, [r14, r6] @ r6 = pixel_top
orr r6, r6, r6, lsl #16 @ r6 = pixel_top | (pixel_top << 16)
and r6, r6, r11 @ r6 = pixel_top_dilated
and r5, r10, r5, lsr #15 @ r5 = ((pixel_pair >> 16) & 0x1FF) << 1
ldrh r5, [r14, r5] @ r5 = pixel_bottom
orr r5, r5, r5, lsl #16 @ r5 = pixel_bottom | (pixel_bottom << 16)
and r5, r5, r11 @ r5 = pixel_bottom_dilated
mul r5, r4, r5 @ r5 = pixel_bottom * blend_b = bottom_mul
mla r5, r3, r6, r5 @ r5 = (pixel_top * blend_a) + bottom_mul
and r6, r9, r5, lsr #4 @ r6 = saturation bits
orr r6, r6, r6, lsr #1 @ propogate saturation down msb
orr r6, r6, r6, lsr #2 @ propogate down next two bits
orr r6, r6, r6, lsr #3 @ propogate down next three bits
orr r5, r6, r5, lsr #4 @ mask over result w/saturation
and r5, r11, r5 @ r5 = (color_dilated >> 4) & 0x07E0F81F
orr r5, r5, r5, lsr #16 @ r5 = color_dilated | (color_dilated >> 16)
strh r5, [r1], #2 @ *screen_dest_ptr = r5, screen_dest_ptr++
subs r2, r2, #1 @ counter--
bne 4b @ go again
ldmia sp!, { r4, r5, r6, r9, r10, r11, pc }
5:
and r5, r10, r5, lsl #1 @ r5 = (pixel_pair & 0x1FF) << 1
ldrh r5, [r14, r5] @ r5 = pixel_top
strh r5, [r1], #2 @ *screen_dest_ptr = r5, screen_dest_ptr++
subs r2, r2, #1 @ counter--
bne 4b @ go again
ldmia sp!, { r4, r5, r6, r9, r10, r11, pc }
@ The following function isn't complete (only works on run multiples of 8),
@ but unfortunately I don't see much potential for actually being able to
@ use it..
#define expand_pixel_pair(reg, temp) ;\
and temp, r3, reg, lsr #15 ;\
ldrh temp, [r2, temp] ;\
;\
and reg, r3, reg, lsl #1 ;\
ldrh reg, [r2, reg] ;\
;\
orr reg, reg, temp, lsl #16 ;\
@ Input:
@ r0 = screen_ptr
@ r1 = start
@ r2 = end
1:
.word palette_ram_converted
.word 0x3FE
expand_normal:
stmdb sp!, { r4, r5, r6, r7, r14 }
add r0, r0, r1, lsl #1 @ screen_ptr += start
sub r1, r2, r1 @ r1 = end - start
ldr r2, 1b @ r2 = palette_ram_converted
ldr r3, 1b + 4 @ r3 = 0x3FE
2:
ldmia r0, { r4, r5, r6, r7 }
expand_pixel_pair(r4, r14)
expand_pixel_pair(r5, r14)
expand_pixel_pair(r6, r14)
expand_pixel_pair(r7, r14)
stmia r0!, { r4, r5, r6, r7 }
subs r1, r1, #8
bne 2b
ldmia sp!, { r4, r5, r6, r7, pc }