\r
#ifdef __GP2X__\r
if (PicoOpt & POPT_EXT_FM)\r
- /*YM2612PicoStateSave2_940(tat, tbt)*/;\r
+ YM2612PicoStateSave2_940(tat, tbt);\r
else\r
#endif\r
YM2612PicoStateSave2(tat, tbt);\r
\r
#ifdef __GP2X__\r
if (PicoOpt & POPT_EXT_FM)\r
- /*ret = YM2612PicoStateLoad2_940(&tat, &tbt)*/;\r
+ ret = YM2612PicoStateLoad2_940(&tat, &tbt);\r
else\r
#endif\r
ret = YM2612PicoStateLoad2(&tat, &tbt);\r
}\r
ret=0;\r
break;\r
+#endif\r
case 0x27: /* mode, timer control */\r
set_timers( v );\r
ret=0;\r
break;\r
-#endif\r
case 0x28: /* key on / off */\r
{\r
UINT8 c;\r
if(v&0x80) FM_KEYON(c,SLOT4); else FM_KEYOFF(c,SLOT4);\r
break;\r
}\r
-#if 0\r
case 0x2a: /* DAC data (YM2612) */\r
ym2612.dacout = ((int)v - 0x80) << 6; /* level unknown (notaz: 8 seems to be too much) */\r
ret=0;\r
ym2612.dacen = v & 0x80;\r
ret=0;\r
break;\r
-#endif\r
default:\r
break;\r
}\r
UINT16 unused2;\r
UINT32 keyon_field; // 20\r
UINT32 kcode_fc_sl3_3;\r
+ UINT32 reserved[2];\r
} ym_save_addon;\r
\r
typedef struct\r
{\r
UINT16 block_fnum[6];\r
UINT16 block_fnum_sl3[3];\r
- UINT16 unused;\r
+ UINT16 reserved[7];\r
} ym_save_addon2;\r
\r
\r
unsigned char *mp3_mem = 0;\r
\r
#define MP3_SIZE_MAX (0x400000 + 0x800000) // 12M\r
-#define CODE940_FILE "pico940_v2.bin"\r
+#define CODE940_FILE "pico940_v3.bin"\r
\r
int crashed_940 = 0;\r
\r
\r
//printf("%05i:%03i: ym w ([%i] %02x)\n", Pico.m.frame_count, Pico.m.scanline, a, v);\r
\r
- switch (a) {\r
+ switch (a)\r
+ {\r
case 0: /* address port 0 */\r
if (addr_A1 == 0 && ST_address == v)\r
return 0; /* address already selected, don't send this command to 940 */\r
addr_A1 = *(INT32 *) (REGS + 0x200);\r
}\r
\r
+void YM2612PicoStateSave2_940(int tat, int tbt)\r
+{\r
+ UINT8 *ym_remote_regs, *ym_local_regs;\r
+ add_job_940(JOB940_PICOSTATESAVE2);\r
+ if (CHECK_BUSY(JOB940_PICOSTATESAVE2)) wait_busy_940(JOB940_PICOSTATESAVE2);\r
+\r
+ ym_remote_regs = (UINT8 *) shared_ctl->writebuff0;\r
+ ym_local_regs = YM2612GetRegs();\r
+ if (*(UINT32 *)(ym_remote_regs + 0x100) != 0x41534d59) {\r
+ printf("code940 didn't return valid save data\n");\r
+ return;\r
+ }\r
+\r
+ /* copy addin data only */\r
+ memcpy(ym_local_regs, ym_remote_regs, 0x20);\r
+ memcpy(ym_local_regs + 0x100, ym_remote_regs + 0x100, 0x30);\r
+ memcpy(ym_local_regs + 0x0b8, ym_remote_regs + 0x0b8, 0x48);\r
+ memcpy(ym_local_regs + 0x1b8, ym_remote_regs + 0x1b8, 0x48);\r
+ *(INT32 *)(ym_local_regs + 0x108) = tat;\r
+ *(INT32 *)(ym_local_regs + 0x10c) = tbt;\r
+}\r
+\r
+int YM2612PicoStateLoad2_940(int *tat, int *tbt)\r
+{\r
+ UINT8 *ym_remote_regs, *ym_local_regs;\r
+ ym_local_regs = YM2612GetRegs();\r
+ ym_remote_regs = (UINT8 *) shared_ctl->writebuff0;\r
+\r
+ if (*(UINT32 *)(ym_local_regs + 0x100) != 0x41534d59)\r
+ return -1;\r
+\r
+ *tat = *(INT32 *)(ym_local_regs + 0x108);\r
+ *tbt = *(INT32 *)(ym_local_regs + 0x10c);\r
+\r
+ if (CHECK_BUSY(JOB940_YM2612UPDATEONE)) wait_busy_940(JOB940_YM2612UPDATEONE);\r
+\r
+ /* flush writes */\r
+ if (shared_ctl->writebuffsel == 1) {\r
+ shared_ctl->writebuff0[writebuff_ptr & 0xffff] = 0xffff;\r
+ } else {\r
+ shared_ctl->writebuff1[writebuff_ptr & 0xffff] = 0xffff;\r
+ }\r
+ shared_ctl->writebuffsel ^= 1;\r
+ writebuff_ptr = 0;\r
+ add_job_940(JOB940_PICOSTATELOAD2_PREP);\r
+ if (CHECK_BUSY(JOB940_PICOSTATELOAD2_PREP)) wait_busy_940(JOB940_PICOSTATELOAD2_PREP);\r
+\r
+ memcpy(ym_remote_regs, ym_local_regs, 0x200);\r
+\r
+ add_job_940(JOB940_PICOSTATELOAD2);\r
+ if (CHECK_BUSY(JOB940_PICOSTATELOAD2)) wait_busy_940(JOB940_PICOSTATELOAD2);\r
+\r
+ return 0;\r
+}\r
+\r
\r
static void internal_reset(void)\r
{\r
if (shared_mem != NULL) return;\r
\r
shared_mem = (unsigned char *) mmap(0, 0x210000, PROT_READ|PROT_WRITE, MAP_SHARED, memdev, 0x2000000);\r
- if(shared_mem == MAP_FAILED)\r
+ if (shared_mem == MAP_FAILED)\r
{\r
printf("mmap(shared_data) failed with %i\n", errno);\r
exit(1);\r
\r
extern char **g_argv;\r
\r
-/* none of the functions in this file should be called before this one */\r
void YM2612Init_940(int baseclock, int rate)\r
{\r
printf("YM2612Init_940()\n");\r
\r
int YM2612PicoTick_940(int n);\r
void YM2612PicoStateLoad_940(void);\r
+void YM2612PicoStateSave2_940(int tat, int tbt);\r
+int YM2612PicoStateLoad2_940(int *tat, int *tbt);\r
// is changed by other core just before we update it\r
void set_if_not_changed(int *val, int oldval, int newval);\r
\r
+void _memcpy(void *dst, const void *src, int count);\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
set_if_not_changed(&shared_ctl->mp3_offs, mp3_offs, readPtr - mp3_data);\r
}\r
\r
+static void ym_flush_writes(void)\r
+{\r
+ UINT16 *wbuff;\r
+ int i;\r
+\r
+ if (shared_ctl->writebuffsel == 1) {\r
+ wbuff = shared_ctl->writebuff1;\r
+ } else {\r
+ wbuff = shared_ctl->writebuff0;\r
+ }\r
+\r
+ /* playback all writes */\r
+ for (i = 2048; i > 0; i--) {\r
+ UINT16 d = *wbuff++;\r
+ if (d == 0xffff) break;\r
+ if (d == 0xfffe) continue;\r
+ YM2612Write_(d >> 8, d);\r
+ }\r
+}\r
+\r
static void ym_update(int *ym_buffer)\r
{\r
int i, dw;\r
YM2612Write_(d >> 8, d);\r
}\r
\r
- if (two_upds) {\r
+ if (two_upds)\r
+ {\r
int len1 = shared_ctl->length / 2;\r
shared_ctl->ym_active_chs =\r
YM2612UpdateOne_(ym_buffer, len1, shared_ctl->stereo, 1);\r
YM2612PicoStateLoad_();\r
break;\r
\r
+ case JOB940_PICOSTATESAVE2:\r
+ YM2612PicoStateSave2(0, 0);\r
+ _memcpy(shared_ctl->writebuff0, ym2612_940->REGS, 0x200);\r
+ break;\r
+\r
+ case JOB940_PICOSTATELOAD2_PREP:\r
+ ym_flush_writes();\r
+ break;\r
+\r
+ case JOB940_PICOSTATELOAD2:\r
+ _memcpy(ym2612_940->REGS, shared_ctl->writebuff0, 0x200);\r
+ YM2612PicoStateLoad2(0, 0);\r
+ break;\r
+\r
case JOB940_YM2612UPDATEONE:\r
ym_update(ym_buffer);\r
break;\r
#include "../../../Pico/sound/ym2612.h"\r
#include "../../common/helix/pub/mp3dec.h"\r
\r
-// max 16 jobs\r
+// max 16 jobs, lower num means higher prio\r
enum _940_job_t {\r
JOB940_INITALL = 1,\r
JOB940_INVALIDATE_DCACHE,\r
JOB940_YM2612UPDATEONE,\r
JOB940_MP3DECODE,\r
JOB940_PICOSTATELOAD,\r
+ JOB940_PICOSTATESAVE2,\r
+ JOB940_PICOSTATELOAD2_PREP,\r
+ JOB940_PICOSTATELOAD2,\r
};\r
\r
//#define MAX_940JOBS 2\r
LD = $(CROSS)ld\r
OBJCOPY = $(CROSS)objcopy\r
\r
-BIN = pico940_v2.bin\r
+BIN = pico940_v3.bin\r
\r
all: $(BIN)\r
\r
\r
.c.o:\r
- @echo $<\r
+ @echo ">>>" $<\r
$(GCC) $(COPT) $(DEFINC) -c $< -o $@\r
.s.o:\r
- @echo $<\r
+ @echo ">>>" $<\r
$(GCC) $(COPT) $(DEFINC) -c $< -o $@\r
\r
\r
OBJS940 += uClibc/e_rem_pio2.o uClibc/k_rem_pio2.o uClibc/e_log.o uClibc/wrappers.o\r
\r
$(BIN) : code940.gpe\r
- @echo $@\r
- @$(OBJCOPY) -O binary $< $@\r
+ @echo ">>>" $@\r
+ $(OBJCOPY) -O binary $< $@\r
\r
code940.gpe : $(OBJS940) ../../common/helix/helix_mp3.a\r
- @echo $@\r
- @$(LD) -static -e code940 -Ttext 0x0 $^ -L$(lgcc_path) -lgcc -o $@ -Map code940.map\r
+ @echo ">>>" $@\r
+ $(LD) -static -e code940 -Ttext 0x0 $^ -L$(lgcc_path) -lgcc -o $@ -Map code940.map\r
\r
940ym2612.o : ../../../Pico/sound/ym2612.c\r
- @echo $@\r
- @$(GCC) $(COPT) -Os $(DEFINC) -DEXTERNAL_YM2612 -c $< -o $@\r
+ @echo ">>>" $@\r
+ $(GCC) $(COPT) -Os $(DEFINC) -DEXTERNAL_YM2612 -c $< -o $@\r
\r
mix.o : ../../../Pico/sound/mix.s\r
- @echo $@\r
- @$(GCC) $(COPT) $(DEFINC) -DEXTERNAL_YM2612 -c $< -o $@\r
+ @echo ">>>" $@\r
+ $(GCC) $(COPT) $(DEFINC) -DEXTERNAL_YM2612 -c $< -o $@\r
misc.o : ../../../Pico/Misc.s\r
- @echo $@\r
- @$(GCC) $(COPT) $(DEFINC) -DEXTERNAL_YM2612 -c $< -o $@\r
+ @echo ">>>" $@\r
+ $(GCC) $(COPT) $(DEFINC) -DEXTERNAL_YM2612 -c $< -o $@\r
\r
../../common/helix/helix_mp3.a:\r
@make -C ../../common/helix/\r
* POSSIBILITY OF SUCH DAMAGE.
*/
-/* This was modified by Jay Monkman <jmonkman@smoothsmoothie.com> to
-* save and restore r12. This is necessary for RTEMS.
-*/
/* #include <machine/asm.h>*/
-#define ENTRY(_LABEL) \
- .global _LABEL; _LABEL:
-
.globl memcpy
+.globl _memcpy
memcpy:
-@ ENTRY(gp2x_memcpy)
-stmfd sp!, {r0, r12, lr}
-@ bl _gp2x_memcpy
+stmfd sp!, {r0, lr}
bl _memcpy
-ldmfd sp!, {r0, r12, pc}
-
+ldmfd sp!, {r0, pc}
.globl memmove
memmove:
-@ ENTRY(gp2x_memmove)
-stmfd sp!, {r0, r12, lr}
-@ bl _gp2x_memcpy
+stmfd sp!, {r0, lr}
bl _memcpy
-ldmfd sp!, {r0, r12, pc}
+ldmfd sp!, {r0, pc}
_memcpy:
-@ ENTRY(_gp2x_memcpy)
/* Determine copy direction */
cmp r1, r0
bcc Lmemcpy_backwards