+++ /dev/null
-#include "940shared.h"\r
-\r
-static _940_data_t *shared_data = (_940_data_t *) 0x100000;\r
-static _940_ctl_t *shared_ctl = (_940_ctl_t *) 0x200000;\r
-YM2612 *ym2612_940;\r
-int *mix_buffer;\r
-\r
-// from init.s\r
-void wait_irq(void);\r
-void spend_cycles(int c);\r
-void cache_clean(void);\r
-void cache_clean_flush(void);\r
-\r
-// asm volatile ("mov r0, #0" ::: "r0");\r
-// asm volatile ("mcr p15, 0, r0, c7, c6, 0" ::: "r0"); /* flush dcache */\r
-// asm volatile ("mcr p15, 0, r0, c7, c10, 4" ::: "r0"); /* drain write buffer */\r
-\r
-void Main940(int startvector)\r
-{\r
- ym2612_940 = &shared_data->ym2612;\r
- mix_buffer = shared_data->mix_buffer;\r
-\r
- // debug\r
- shared_ctl->vstarts[startvector]++;\r
- asm volatile ("mcr p15, 0, r0, c7, c10, 4" ::: "r0");\r
-\r
-\r
- for (;; shared_ctl->loopc++)\r
- {\r
- int job_num;\r
-/*\r
- while (!shared_ctl->busy)\r
- {\r
- //shared_ctl->waitc++;\r
- spend_cycles(256);\r
- }\r
-*/\r
- if (!shared_ctl->busy)\r
- {\r
- wait_irq();\r
- }\r
-\r
- for (job_num = 0; job_num < MAX_940JOBS; job_num++)\r
- {\r
- switch (shared_ctl->jobs[job_num])\r
- {\r
- case JOB940_YM2612INIT:\r
- shared_ctl->writebuff0[0] = shared_ctl->writebuff1[0] = 0xffff;\r
- YM2612Init_(shared_ctl->baseclock, shared_ctl->rate);\r
- break;\r
-\r
- case JOB940_YM2612RESETCHIP:\r
- YM2612ResetChip_();\r
- break;\r
-\r
- case JOB940_PICOSTATELOAD:\r
- YM2612PicoStateLoad_();\r
- break;\r
-\r
- case JOB940_YM2612UPDATEONE: {\r
- int i, dw, *wbuff;\r
- if (shared_ctl->writebuffsel == 1) {\r
- wbuff = (int *) shared_ctl->writebuff1;\r
- } else {\r
- wbuff = (int *) shared_ctl->writebuff0;\r
- }\r
-\r
- /* playback all writes */\r
- for (i = 2048/2; i > 0; i--) {\r
- UINT16 d;\r
- dw = *wbuff++;\r
- d = dw;\r
- if (d == 0xffff) break;\r
- YM2612Write_(d >> 8, d);\r
- d = (dw>>16);\r
- if (d == 0xffff) break;\r
- YM2612Write_(d >> 8, d);\r
- }\r
-\r
- YM2612UpdateOne_(0, shared_ctl->length, shared_ctl->stereo);\r
- break;\r
- }\r
- }\r
- }\r
-\r
- shared_ctl->busy = 0;\r
-// cache_clean_flush();\r
- cache_clean();\r
-// asm volatile ("mov r0, #0" ::: "r0");\r
-// asm volatile ("mcr p15, 0, r0, c7, c10, 4" ::: "r0"); /* drain write buffer, should be done on nonbuffered write */\r
- }\r
-}\r
-\r
#include <fcntl.h>\r
#include <errno.h>\r
\r
-#include "940shared.h"\r
+#include "code940/940shared.h"\r
#include "gp2x.h"\r
#include "emu.h"\r
#include "menu.h"\r
printf("wait iterations: %i\n", i);\r
#else\r
for (i = 0; shared_ctl->busy && i < 0x10000; i++)\r
- spend_cycles(4*1024);\r
+ spend_cycles(8*1024); // tested to be best for mp3 dec\r
if (i < 0x10000) return;\r
\r
/* 940 crashed */\r
- printf("940 crashed (cnt: %i, wc: %i, ve: ", shared_ctl->loopc, shared_ctl->waitc);\r
+ printf("940 crashed (cnt: %i, ve: ", shared_ctl->loopc);\r
for (i = 0; i < 8; i++)\r
printf("%i ", shared_ctl->vstarts[i]);\r
printf(")\n");\r
/* now cause 940 to init it's ym2612 stuff */\r
shared_ctl->baseclock = baseclock;\r
shared_ctl->rate = rate;\r
- shared_ctl->jobs[0] = JOB940_YM2612INIT;\r
+ shared_ctl->jobs[0] = JOB940_INITALL;\r
shared_ctl->jobs[1] = 0;\r
shared_ctl->busy = 1;\r
\r
+++ /dev/null
-.global code940\r
-\r
-code940: @ interrupt table:\r
- b .b_reset @ reset\r
- b .b_undef @ undefined instructions\r
- b .b_swi @ software interrupt\r
- b .b_pabort @ prefetch abort\r
- b .b_dabort @ data abort\r
- b .b_reserved @ reserved\r
- b .b_irq @ IRQ\r
- b .b_fiq @ FIQ\r
-\r
-@ test\r
-.b_reset:\r
- mov r12, #0\r
- b .Begin\r
-.b_undef:\r
- mov r12, #1\r
- b .Begin\r
-.b_swi:\r
- mov r12, #2\r
- b .Begin\r
-.b_pabort:\r
- mov r12, #3\r
- b .Begin\r
-.b_dabort:\r
- mov r12, #4\r
- b .Begin\r
-.b_reserved:\r
- mov r12, #5\r
- b .Begin\r
-.b_irq:\r
- mov r12, #6\r
- mov sp, #0x100000 @ reset stack\r
- sub sp, sp, #4\r
- mov r1, #0xbe000000 @ assume we live @ 0x2000000 bank\r
- orr r2, r1, #0x3B00\r
- orr r2, r2, #0x0046\r
- mvn r3, #0\r
- strh r3, [r2] @ clear any pending interrupts from the DUALCPU unit\r
- orr r2, r1, #0x4500\r
- str r3, [r2] @ clear all pending interrupts in irq controller's SRCPND register\r
- orr r2, r2, #0x0010\r
- str r3, [r2] @ clear all pending interrupts in irq controller's INTPND register\r
- b .Enter\r
-.b_fiq:\r
- mov r12, #7\r
- b .Begin\r
-\r
-.Begin:\r
- mov sp, #0x100000 @ set the stack top (1M)\r
- sub sp, sp, #4 @ minus 4\r
-\r
- @ set up memory region 0 -- the whole 4GB address space\r
- mov r0, #(0x1f<<1)|1 @ region data\r
- mcr p15, 0, r0, c6, c0, 0 @ opcode2 ~ data/instr\r
- mcr p15, 0, r0, c6, c0, 1\r
-\r
- @ set up region 1 which is the first 2 megabytes.\r
- mov r0, #(0x14<<1)|1 @ region data\r
- mcr p15, 0, r0, c6, c1, 0\r
- mcr p15, 0, r0, c6, c1, 1\r
-\r
- @ set up region 2: 64k 0x200000-0x210000\r
- mov r0, #(0x0f<<1)|1\r
- orr r0, r0, #0x200000\r
- mcr p15, 0, r0, c6, c2, 0\r
- mcr p15, 0, r0, c6, c2, 1\r
-\r
- @ set up region 3: 64k 0xbe000000-0xbe010000 (hw control registers)\r
- mov r0, #(0x0f<<1)|1\r
- orr r0, r0, #0xbe000000\r
- mcr p15, 0, r0, c6, c3, 0\r
- mcr p15, 0, r0, c6, c3, 1\r
-\r
- @ set region 1 to be cacheable (so the first 2M will be cacheable)\r
- mov r0, #2\r
- mcr p15, 0, r0, c2, c0, 0\r
- mcr p15, 0, r0, c2, c0, 1\r
-\r
- @ set region 1 to be bufferable too (only data)\r
- mcr p15, 0, r0, c3, c0, 0\r
-\r
- @ set protection, allow accsess only to regions 1 and 2\r
- mov r0, #(3<<6)|(3<<4)|(3<<2)|(0) @ data: [full, full, full, no access] for regions [3 2 1 0]\r
- mcr p15, 0, r0, c5, c0, 0\r
- mov r0, #(0<<6)|(0<<4)|(3<<2)|(0) @ instructions: [no access, no, full, no]\r
- mcr p15, 0, r0, c5, c0, 1\r
-\r
- mrc p15, 0, r0, c1, c0, 0 @ fetch current control reg\r
- orr r0, r0, #1 @ 0x00000001: enable protection unit\r
- orr r0, r0, #4 @ 0x00000004: enable D cache\r
- orr r0, r0, #0x1000 @ 0x00001000: enable I cache\r
- orr r0, r0, #0xC0000000 @ 0xC0000000: async+fastbus\r
- mcr p15, 0, r0, c1, c0, 0 @ set control reg\r
-\r
- @ flush (invalidate) the cache (just in case)\r
- mov r0, #0\r
- mcr p15, 0, r0, c7, c6, 0\r
-\r
-.Enter:\r
- mov r0, r12\r
- bl Main940\r
-\r
- @ we should never get here\r
-.b_deadloop:\r
- b .b_deadloop\r
-\r
-\r
-\r
-@ so asm utils are also defined here:\r
-.global spend_cycles @ c\r
-\r
-spend_cycles:\r
- mov r0, r0, lsr #2 @ 4 cycles/iteration\r
- sub r0, r0, #2 @ entry/exit/init\r
-.sc_loop:\r
- subs r0, r0, #1\r
- bpl .sc_loop\r
-\r
- bx lr\r
-\r
-\r
-@ clean-flush function from ARM940T technical reference manual\r
-.global cache_clean_flush\r
-\r
-cache_clean_flush:\r
- mov r1, #0 @ init line counter\r
-ccf_outer_loop:\r
- mov r0, #0 @ segment counter\r
-ccf_inner_loop:\r
- orr r2, r1, r0 @ make segment and line address\r
- mcr p15, 0, r2, c7, c14, 2 @ clean and flush that line\r
- add r0, r0, #0x10 @ incremet secment counter\r
- cmp r0, #0x40 @ complete all 4 segments?\r
- bne ccf_inner_loop\r
- add r1, r1, #0x04000000 @ increment line counter\r
- cmp r1, #0 @ complete all lines?\r
- bne ccf_outer_loop\r
- bx lr\r
-\r
-\r
-@ clean-only version\r
-.global cache_clean\r
-\r
-cache_clean:\r
- mov r1, #0 @ init line counter\r
-cf_outer_loop:\r
- mov r0, #0 @ segment counter\r
-cf_inner_loop:\r
- orr r2, r1, r0 @ make segment and line address\r
- mcr p15, 0, r2, c7, c10, 2 @ clean that line\r
- add r0, r0, #0x10 @ incremet secment counter\r
- cmp r0, #0x40 @ complete all 4 segments?\r
- bne cf_inner_loop\r
- add r1, r1, #0x04000000 @ increment line counter\r
- cmp r1, #0 @ complete all lines?\r
- bne cf_outer_loop\r
- bx lr\r
-\r
-\r
-.global wait_irq\r
-\r
-wait_irq:\r
- mrs r0, cpsr\r
- bic r0, r0, #0x80\r
- msr cpsr_c, r0 @ enable interrupts\r
-\r
- mov r0, #0\r
- mcr p15, 0, r0, c7, c0, 4 @ wait for IRQ\r
-@ mcr p15, 0, r0, c15, c8, 2\r
- b .b_reserved\r
-\r
-.pool\r
-\r
-@ vim:filetype=ignored:\r
+++ /dev/null
-#include "../../Pico/sound/ym2612.h"\r
-\r
-enum _940_job_t {\r
- JOB940_YM2612INIT = 1,\r
- JOB940_YM2612RESETCHIP,\r
- JOB940_YM2612UPDATEONE,\r
- JOB940_PICOSTATELOAD,\r
- JOB940_NUMJOBS\r
-};\r
-\r
-#define MAX_940JOBS 2\r
-\r
-typedef struct\r
-{\r
- YM2612 ym2612; /* current state of the emulated YM2612 */\r
- int mix_buffer[44100/50*2]; /* this is where the YM2612 samples will be mixed to */\r
- short mp3_buffer[2][1152*2]; /* buffer for mp3 decoder's output */\r
-} _940_data_t;\r
-\r
-\r
-typedef struct\r
-{\r
- int jobs[MAX_940JOBS]; /* jobs for second core */\r
- int busy; /* busy status of the 940 core */\r
- int length; /* number of samples to mix (882 max) */\r
- int stereo; /* mix samples as stereo, doubles sample count automatically */\r
- int baseclock; /* ym2612 settings */\r
- int rate;\r
- int writebuffsel; /* which write buffer to use (from 940 side) */\r
- UINT16 writebuff0[2048]; /* list of writes to ym2612, 1024 for savestates, 1024 extra */\r
- UINT16 writebuff1[2048];\r
- int vstarts[8]; /* debug: number of starts from each of 8 vectors */\r
- int loopc; /* debug: main loop counter */\r
- int waitc; /* debug: wait loop counter */\r
-} _940_ctl_t;\r
\r
# you may or may not need to change this\r
#devkit_path = x:/stuff/dev/devkitgp2x/\r
-devkit_path = /usr/local/devkitPro/devkitGP2X/\r
-lgcc_path = $(devkit_path)lib/gcc/arm-linux/4.0.3/\r
CROSS = arm-linux-\r
#CROSS = $(devkit_path)bin/arm-linux-\r
\r
#use_musashi = 1\r
#up = 1\r
\r
-DEFINC = -I../.. -I. -D__GP2X__ -D_UNZIP_SUPPORT # -DBENCHMARK\r
+DEFINC = -I../.. -I. -DARM -D__GP2X__ -D_UNZIP_SUPPORT # -DBENCHMARK\r
COPT_COMMON = -static -s -O3 -ftracer -fstrength-reduce -Wall -funroll-loops -fomit-frame-pointer -fstrict-aliasing -ffast-math\r
ifeq "$(profile)" "1"\r
COPT_COMMON += -fprofile-generate\r
OBJS += ../../cpu/DrZ80/drz80.o\r
endif\r
\r
-all: PicoDrive.gpe code940.bin\r
+all: PicoDrive.gpe\r
\r
PicoDrive.gpe : $(OBJS)\r
@echo $@\r
@cmd //C copy $@ \\\\10.0.1.2\\gp2x\\mnt\\sd\\games\\PicoDrive\\\r
endif\r
\r
-up: # up940\r
+up:\r
@cp -v PicoDrive.gpe /mnt/gp2x/mnt/sd/games/PicoDrive/\r
\r
# @cmd //C copy PicoDrive.gpe \\\\10.0.1.2\\gp2x\\mnt\\sd\\games\\PicoDrive\\\r
\r
-up940:\r
- @cp -v code940.bin /mnt/gp2x/mnt/sd/games/PicoDrive/\r
-\r
-# @cmd //C copy code940.bin \\\\10.0.1.2\\gp2x\\mnt\\sd\\games\\PicoDrive\\\r
\r
testrefr.gpe : test.o gp2x.o asmutils.o\r
@echo $@\r
@make -C ../../cpu/Cyclone/proj -f Makefile.linux\r
\r
\r
-# stuff for 940 core\r
-\r
-# init, emu_control, emu\r
-OBJS940 += 940init.o 940.o 940ym2612.o\r
-# the asm code seems to be faster when run on 920, but not on 940 for some reason\r
-# OBJS940 += ../../Pico/sound/ym2612_asm.o\r
-\r
-# uClibc library code\r
-OBJS940 += uClibc/memset.o uClibc/s_floor.o uClibc/e_pow.o uClibc/e_sqrt.o uClibc/s_fabs.o\r
-OBJS940 += uClibc/s_scalbn.o uClibc/s_copysign.o uClibc/k_sin.o uClibc/k_cos.o uClibc/s_sin.o\r
-OBJS940 += uClibc/e_rem_pio2.o uClibc/k_rem_pio2.o uClibc/e_log.o uClibc/wrappers.o\r
-\r
-code940.bin : code940.gpe\r
- @echo $@\r
- @$(OBJCOPY) -O binary $< $@\r
-\r
-code940.gpe : $(OBJS940)\r
- @echo $@\r
- @$(LD) -static -e code940 -Ttext 0x0 $^ -L$(lgcc_path) -lgcc -o $@\r
-\r
-940ym2612.o : ../../Pico/sound/ym2612.c\r
- @echo $@\r
- @$(GCC) $(COPT_COMMON) -mtune=arm940t $(DEFINC) -DEXTERNAL_YM2612 -c $< -o $@\r
-\r
-\r
# cleanup\r
-clean: clean_pd clean_940\r
-tidy: tidy_pd tidy_940\r
-\r
-clean_pd: tidy_pd\r
+clean: tidy\r
@$(RM) PicoDrive.gpe\r
-tidy_pd:\r
+tidy:\r
@$(RM) $(OBJS)\r
# @make -C ../../cpu/Cyclone/proj -f Makefile.linux clean\r
\r
-clean_940: tidy_940\r
- @$(RM) code940.bin\r
-tidy_940:\r
- @$(RM) code940.gpe $(OBJS940)\r
\r
clean_prof:\r
find ../.. -name '*.gcno' -delete\r
@echo $<\r
@$(GCC) $(COPT) $(DEFINC) -fno-profile-generate -c $< -o $@\r
\r
-uClibc/e_pow.o : uClibc/e_pow.c\r
- @echo $<\r
- @$(GCC) $(COPT) $(DEFINC) -fno-profile-generate -c $< -o $@\r
-\r
-uClibc/e_sqrt.o : uClibc/e_sqrt.c\r
- @echo $<\r
- @$(GCC) $(COPT) $(DEFINC) -fno-profile-generate -c $< -o $@\r
write(sounddev, buff, len);\r
}\r
\r
+void gp2x_sound_sync(void)\r
+{\r
+ ioctl(sounddev, SOUND_PCM_SYNC, 0);\r
+}\r
\r
void gp2x_sound_volume(int l, int r)\r
{\r