From 7336a99a49268970e0df89d15210b98dd7798f1e Mon Sep 17 00:00:00 2001 From: notaz Date: Wed, 14 Mar 2007 17:59:53 +0000 Subject: [PATCH] SekRunPS Cyclone integration git-svn-id: file:///home/notaz/opt/svn/PicoDrive@68 be3aeb3a-fb24-0410-a615-afba39da0efa --- Pico/Cart.c | 12 ++- Pico/PicoInt.h | 18 +++- Pico/VideoPort.c | 3 +- Pico/cd/Memory.c | 4 - Pico/cd/Pico.c | 55 ++++++---- Pico/cd/Pico.s | 179 ++++++++++++++++++++++++++++++++ cpu/Cyclone/Main.cpp | 29 ++++-- cpu/Cyclone/proj/Makefile.linux | 4 +- platform/gp2x/Makefile | 14 ++- platform/gp2x/emu.c | 2 +- platform/gp2x/menu.c | 2 +- platform/readme.txt | 3 + 12 files changed, 278 insertions(+), 47 deletions(-) create mode 100644 Pico/cd/Pico.s diff --git a/Pico/Cart.c b/Pico/Cart.c index 07624738..a8650332 100644 --- a/Pico/Cart.c +++ b/Pico/Cart.c @@ -12,6 +12,7 @@ #include "../unzip/unzip.h" #include "../unzip/unzip_stream.h" + static char *rom_exts[] = { "bin", "gen", "smd", "iso" }; @@ -78,6 +79,9 @@ zip_failed: f = fopen(path, "rb"); if (f == NULL) return NULL; + /* we use our own buffering */ + setvbuf(f, NULL, _IONBF, 0); + file = malloc(sizeof(*file)); if (file == NULL) { fclose(f); @@ -120,7 +124,8 @@ int pm_seek(pm_file *stream, long offset, int whence) { if (stream->type == PMT_UNCOMPRESSED) { - return fseek(stream->file, offset, whence); + fseek(stream->file, offset, whence); + return ftell(stream->file); } else if (stream->type == PMT_ZIP) { @@ -243,7 +248,10 @@ int PicoCartLoad(pm_file *f,unsigned char **prom,unsigned int *psize) // Allocate space for the rom plus padding rom=PicoCartAlloc(size); - if (rom==NULL) return 1; // { fclose(f); return 1; } + if (rom==NULL) { + printf("out of memory (wanted %i)\n", size); + return 1; + } pm_read(rom,size,f); // Load up the rom diff --git a/Pico/PicoInt.h b/Pico/PicoInt.h index 76a33226..47ba2c9a 100644 --- a/Pico/PicoInt.h +++ b/Pico/PicoInt.h @@ -24,8 +24,13 @@ extern "C" { #ifdef EMU_C68K #include "../cpu/Cyclone/Cyclone.h" extern struct Cyclone PicoCpu, PicoCpuS68k; -#define SekCyclesLeft PicoCpu.cycles // cycles left for this run -#define SekSetCyclesLeft(c) PicoCpu.cycles=c +#define SekCyclesLeftNoMCD PicoCpu.cycles // cycles left for this run +#define SekCyclesLeft \ + (((PicoMCD&1) && (PicoOpt & 0x2000)) ? (SekCycleAim-SekCycleCnt) : SekCyclesLeftNoMCD) +#define SekSetCyclesLeftNoMCD(c) PicoCpu.cycles=c +#define SekSetCyclesLeft(c) { \ + if ((PicoMCD&1) && (PicoOpt & 0x2000)) SekCycleCnt=SekCycleAim-(c); else SekSetCyclesLeftNoMCD(c); \ +} #define SekPc (PicoCpu.pc-PicoCpu.membase) #define SekPcS68k (PicoCpuS68k.pc-PicoCpuS68k.membase) #endif @@ -55,8 +60,13 @@ extern int m68k_ICount; extern m68ki_cpu_core PicoM68kCPU; // MD's CPU extern m68ki_cpu_core PicoS68kCPU; // Mega CD's CPU #ifndef SekCyclesLeft -#define SekCyclesLeft m68k_cycles_remaining() -#define SekSetCyclesLeft(c) SET_CYCLES(c) +#define SekCyclesLeftNoMCD m68k_cycles_remaining() +#define SekCyclesLeft \ + (((PicoMCD&1) && (PicoOpt & 0x2000)) ? (SekCycleAim-SekCycleCnt) : SekCyclesLeftNoMCD) +#define SekSetCyclesLeftNoMCD(c) SET_CYCLES(c) +#define SekSetCyclesLeft(c) { \ + if ((PicoMCD&1) && (PicoOpt & 0x2000)) SekCycleCnt=SekCycleAim-(c); else SET_CYCLES(c); \ +} #define SekPc m68k_get_reg(&PicoM68kCPU, M68K_REG_PC) #define SekPcS68k m68k_get_reg(&PicoS68kCPU, M68K_REG_PC) #endif diff --git a/Pico/VideoPort.c b/Pico/VideoPort.c index 8cfaab29..997b938a 100644 --- a/Pico/VideoPort.c +++ b/Pico/VideoPort.c @@ -89,7 +89,8 @@ static void DmaSlow(int len) if(Pico.m.scanline != -1) { Pico.m.dma_bytes += len; - SekSetCyclesLeft(SekCyclesLeft - CheckDMA()); + if ((PicoMCD&1) && (PicoOpt & 0x2000)) SekCycleCnt+=CheckDMA(); + else SekSetCyclesLeftNoMCD(SekCyclesLeftNoMCD - CheckDMA()); } else { // be approximate in non-accurate mode SekSetCyclesLeft(SekCyclesLeft - (len*(((488<<8)/167))>>8)); diff --git a/Pico/cd/Memory.c b/Pico/cd/Memory.c index e8d0cdb6..5a4f28ea 100644 --- a/Pico/cd/Memory.c +++ b/Pico/cd/Memory.c @@ -421,7 +421,6 @@ u16 PicoReadM68k16(u32 a) a = (a&2) | (cell_map(a >> 2) << 2); // cell arranged else a &= 0x1fffe; d = *(u16 *)(Pico_mcd->word_ram1M[bank]+a); -//d = 0xaaaa; } else { // allow access in any mode, like Gens does d = *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe)); @@ -936,9 +935,6 @@ static void decode_write8(u32 a, u8 d, int r3) u8 *pd = Pico_mcd->word_ram1M[!(r3 & 1)] + (((a>>1)^1)&0x1ffff); u8 oldmask = (a&1) ? 0xf0 : 0x0f; - //if ((a & 0x3ffff) < 0x28000) return; - //return; - r3 &= 0x18; d &= 0x0f; if (!(a&1)) d <<= 4; diff --git a/Pico/cd/Pico.c b/Pico/cd/Pico.c index 678ef97e..4cfbbbc6 100644 --- a/Pico/cd/Pico.c +++ b/Pico/cd/Pico.c @@ -83,44 +83,55 @@ static __inline void SekRunS68k(int cyc) #endif } -#define PS_STEP_M68K 8 -#define PS_STEP_S68K 13 +#define PS_STEP_M68K ((488<<16)/20) // ~24 +//#define PS_STEP_S68K 13 +#ifndef _ASM_CD_PICO_C static __inline void SekRunPS(int cyc_m68k, int cyc_s68k) { - int cyc_do_m68k, cyc_do_s68k, it=0; - int cyc_done_m68k=0, cyc_done_s68k=0; + int cycn, cycn_s68k, cyc_do; + int d_cm = 0, d_cs = 0, ex; SekCycleAim+=cyc_m68k; SekCycleAimS68k+=cyc_s68k; - cyc_do_m68k=SekCycleAim-SekCycleCnt; - cyc_do_s68k=SekCycleAimS68k-SekCycleCntS68k; - while (cyc_done_m68k < cyc_do_m68k || cyc_done_s68k < cyc_do_s68k) { - it++; - if (cyc_done_m68k < cyc_do_m68k && it*PS_STEP_M68K > cyc_done_m68k) { + +// fprintf(stderr, "=== start %3i/%3i [%3i/%3i] {%05i.%i} ===\n", cyc_m68k, cyc_s68k, +// SekCycleAim-SekCycleCnt, SekCycleAimS68k-SekCycleCntS68k, Pico.m.frame_count, Pico.m.scanline); + + /* loop 488 downto 0 in steps of PS_STEP */ + for (cycn = (488<<16)-PS_STEP_M68K; cycn >= 0; cycn -= PS_STEP_M68K) + { + ex = 0; + cycn_s68k = (cycn + cycn/2 + cycn/8) >> 16; +//fprintf(stderr, "%3i/%3i: ", cycn>>16, cycn_s68k); + if ((cyc_do = SekCycleAim-SekCycleCnt-(cycn>>16)) > 0) { #if defined(EMU_C68K) - PicoCpu.cycles = PS_STEP_M68K; + PicoCpu.cycles = cyc_do; CycloneRun(&PicoCpu); - cyc_done_m68k += PS_STEP_M68K - PicoCpu.cycles; + SekCycleCnt += cyc_do - PicoCpu.cycles; #elif defined(EMU_M68K) m68k_set_context(&PicoM68kCPU); - cyc_done_m68k += m68k_execute(PS_STEP_M68K); + SekCycleCnt += (ex = m68k_execute(cyc_do)); #endif - } //else dprintf("m68k skipping it #%i", it); - if (cyc_done_s68k < cyc_do_s68k && it*PS_STEP_S68K > cyc_done_s68k) { + } +//fprintf(stderr, "%3i ", ex); d_cm += ex; ex = 0; + if ((cyc_do = SekCycleAimS68k-SekCycleCntS68k-cycn_s68k) > 0) { #if defined(EMU_C68K) - PicoCpuS68k.cycles = PS_STEP_S68K; + PicoCpuS68k.cycles = cyc_do; CycloneRun(&PicoCpuS68k); - cyc_done_s68k += PS_STEP_S68K - PicoCpuS68k.cycles; + SekCycleCntS68k += cyc_do - PicoCpuS68k.cycles; #elif defined(EMU_M68K) m68k_set_context(&PicoS68kCPU); - cyc_done_s68k += m68k_execute(PS_STEP_S68K); + SekCycleCntS68k += (ex = m68k_execute(cyc_do)); #endif - } //else dprintf("s68k skipping it #%i", it); + } +//fprintf(stderr, "%3i\n", ex); d_cs += ex; } - SekCycleCnt += cyc_done_m68k; - SekCycleCntS68k += cyc_done_s68k; - //dprintf("== end SekRunPS, it=%i ==", it); + +//fprintf(stderr, "== end %3i/%3i ==\n", d_cm, d_cs); } +#else +void SekRunPS(int cyc_m68k, int cyc_s68k); +#endif static __inline void check_cd_dma(void) @@ -271,7 +282,7 @@ static int PicoFrameHintsMCD(void) //dprintf("m68k starting exec @ %06x", SekPc); if(Pico.m.dma_bytes) SekCycleCnt+=CheckDMA(); if((PicoOpt & 0x2000) && (Pico_mcd->m.busreq&3) == 1) { - SekRunPS(cycles_68k, cycles_s68k); // "perfect sync" + SekRunPS(cycles_68k, cycles_s68k); // "better/perfect sync" } else { SekRun(cycles_68k); if ((Pico_mcd->m.busreq&3) == 1) // no busreq/no reset diff --git a/Pico/cd/Pico.s b/Pico/cd/Pico.s new file mode 100644 index 00000000..24e4d1c6 --- /dev/null +++ b/Pico/cd/Pico.s @@ -0,0 +1,179 @@ +@ vim:filetype=armasm + +@ SekRunPS runs PicoCpu and PicoCpuS68k interleaved in steps of PS_STEP_M68K +@ cycles. This is done without calling CycloneRun and jumping directly to +@ Cyclone code to avoid pushing/popping all the registers every time. + +@ (c) Copyright 2007, Grazvydas "notaz" Ignotas +@ All Rights Reserved + + +.equiv PS_STEP_M68K, ((488<<16)/20) @ ~24 + +@ .extern is ignored by gas, we add these here just to see what we depend on. +.extern CycloneJumpTab +.extern CycloneDoInterrupt +.extern PicoCpu +.extern PicoCpuS68k +.extern SekCycleAim +.extern SekCycleCnt +.extern SekCycleAimS68k +.extern SekCycleCntS68k + + +.text +.align 4 + + +.global SekRunPS @ cyc_m68k, cyc_s68k + +SekRunPS: + stmfd sp!, {r4-r11,lr} + sub sp, sp, #2*4 @ sp[0] = main_cycle_cnt, sp[4] = run_cycle_cnt + + @ override CycloneEnd for both contexts + ldr r7, =PicoCpu + ldr lr, =PicoCpuS68k + ldr r2, =CycloneEnd_M68k + ldr r3, =CycloneEnd_S68k + str r2, [r7,#0x54] + str r3, [lr,#0x54] + + @ update aims + ldr r8, =SekCycleAim + ldr r9, =SekCycleAimS68k + ldr r2, [r8] + ldr r3, [r9] + add r2, r2, r0 + add r3, r3, r1 + str r2, [r8] + str r3, [r9] + + ldr r1, =SekCycleCnt + ldr r0, =((488<<16)-PS_STEP_M68K) + ldr r6, =CycloneJumpTab + + @ schedule m68k for the first time.. + ldr r1, [r1] + str r0, [sp] @ main target 'left cycle' counter + sub r1, r2, r1 + subs r5, r1, r0, asr #16 + ble schedule_s68k @ m68k has not enough cycles + + str r5, [sp,#4] @ run_cycle_cnt + b CycloneRunLocal + + + +CycloneEnd_M68k: + ldr r3, =SekCycleCnt + ldr r0, [sp,#4] @ run_cycle_cnt + ldr r1, [r3] + str r4, [r7,#0x40] ;@ Save Current PC + Memory Base + strb r9, [r7,#0x46] ;@ Save Flags (NZCV) + sub r0, r0, r5 @ subtract leftover cycles (which should be negative) + add r0, r0, r1 + str r0, [r3] + +schedule_s68k: + ldr r8, =SekCycleCntS68k + ldr r9, =SekCycleAimS68k + ldr r3, [sp] + ldr r8, [r8] + ldr r9, [r9] + + sub r0, r9, r8 + add r3, r3, r3, asr #1 + add r3, r3, r3, asr #3 @ cycn_s68k = (cycn + cycn/2 + cycn/8) + + subs r5, r0, r3, asr #16 + ble schedule_m68k @ s68k has not enough cycles + + ldr r7, =PicoCpuS68k + str r5, [sp,#4] @ run_cycle_cnt + b CycloneRunLocal + + + +CycloneEnd_S68k: + ldr r3, =SekCycleCntS68k + ldr r0, [sp,#4] @ run_cycle_cnt + ldr r1, [r3] + str r4, [r7,#0x40] ;@ Save Current PC + Memory Base + strb r9, [r7,#0x46] ;@ Save Flags (NZCV) + sub r0, r0, r5 @ subtract leftover cycles (should be negative) + add r0, r0, r1 + str r0, [r3] + +schedule_m68k: + ldr r1, =PS_STEP_M68K + ldr r3, [sp] @ main_cycle_cnt + ldr r8, =SekCycleCnt + ldr r9, =SekCycleAim + subs r3, r3, r1 + bmi SekRunPS_end + + ldr r8, [r8] + ldr r9, [r9] + str r3, [sp] @ update main_cycle_cnt + sub r0, r9, r8 + + subs r5, r0, r3, asr #16 + ble schedule_s68k @ m68k has not enough cycles + + ldr r7, =PicoCpu + str r5, [sp,#4] @ run_cycle_cnt + b CycloneRunLocal + + + +SekRunPS_end: + ldr r7, =PicoCpu + ldr lr, =PicoCpuS68k + mov r0, #0 + str r0, [r7,#0x54] @ remove CycloneEnd handler + str r0, [lr,#0x54] + @ return + add sp, sp, #2*4 + ldmfd sp!, {r4-r11,pc} + + + + +CycloneRunLocal: + ;@ r0-3 = Temporary registers + ldr r4,[r7,#0x40] ;@ r4 = Current PC + Memory Base + ;@ r5 = Cycles + ;@ r6 = Opcode Jump table + ;@ r7 = Pointer to Cpu Context + ;@ r8 = Current Opcode + ldrb r9,[r7,#0x46] ;@ r9 = Flags (NZCV) + ldr r0,[r7,#0x44] + mov r9,r9,lsl #28 ;@ r9 = Flags 0xf0000000, cpsr format + ;@ r10 = Source value / Memory Base + +;@ CheckInterrupt: + movs r0,r0,lsr #24 ;@ Get IRQ level + beq NoIntsLocal + cmp r0,#6 ;@ irq>6 ? + ldrleb r1,[r7,#0x44] ;@ Get SR high: T_S__III + andle r1,r1,#7 ;@ Get interrupt mask + cmple r0,r1 ;@ irq<=6: Is irq<=mask ? + blgt CycloneDoInterrupt +;@ Check if interrupt used up all the cycles: + subs r5,r5,#0 + ldrlt r1,[r7,#0x54] + bxlt r1 ;@ jump to alternative CycloneEnd +NoIntsLocal: + +;@ Check if our processor is in stopped state and jump to opcode handler if not + ldr r0,[r7,#0x58] + ldrh r8,[r4],#2 ;@ Fetch first opcode + tst r0,r0 ;@ stopped? + ldreq pc,[r6,r8,asl #2] ;@ Jump to opcode handler + + @ stopped + ldr r1,[r7,#0x54] + mov r5,#0 + bx r1 + diff --git a/cpu/Cyclone/Main.cpp b/cpu/Cyclone/Main.cpp index 2f92c5cf..aca7f4f7 100644 --- a/cpu/Cyclone/Main.cpp +++ b/cpu/Cyclone/Main.cpp @@ -93,7 +93,7 @@ void CheckInterrupt(int op) ot(" ldrleb r1,[r7,#0x44] ;@ Get SR high: T_S__III\n"); ot(" andle r1,r1,#7 ;@ Get interrupt mask\n"); ot(" cmple r0,r1 ;@ irq<=6: Is irq<=mask ?\n"); - ot(" blgt DoInterrupt\n"); + ot(" blgt CycloneDoInterrupt\n"); ot("NoInts%x%s\n", op,ms?"":":"); ot("\n"); } @@ -109,7 +109,7 @@ static void PrintFramework() ot(" mov r7,r0 ;@ r7 = Pointer to Cpu Context\n"); ot(" ;@ r0-3 = Temporary registers\n"); ot(" ldrb r9,[r7,#0x46] ;@ r9 = Flags (NZCV)\n"); - ot(" ldr r6,=JumpTab ;@ r6 = Opcode Jump table\n"); + ot(" ldr r6,=CycloneJumpTab ;@ r6 = Opcode Jump table\n"); ot(" ldr r5,[r7,#0x5c] ;@ r5 = Cycles\n"); ot(" ldr r4,[r7,#0x40] ;@ r4 = Current PC + Memory Base\n"); ot(" ;@ r8 = Current Opcode\n"); @@ -124,7 +124,7 @@ static void PrintFramework() ot(" ldrleb r1,[r7,#0x44] ;@ Get SR high: T_S__III\n"); ot(" andle r1,r1,#7 ;@ Get interrupt mask\n"); ot(" cmple r0,r1 ;@ irq<=6: Is irq<=mask ?\n"); - ot(" blgt DoInterrupt\n"); + ot(" blgt CycloneDoInterrupt\n"); ot(";@ Check if interrupt used up all the cycles:\n"); ot(" subs r5,r5,#0\n"); ot(" blt CycloneEndNoBack\n"); @@ -143,7 +143,14 @@ static void PrintFramework() ot("CycloneEnd%s\n", ms?"":":"); ot(" sub r4,r4,#2\n"); ot("CycloneEndNoBack%s\n", ms?"":":"); +#ifdef CYCLONE_FOR_PICODRIVE + ot(" ldr r1,[r7,#0x54]\n"); ot(" mov r9,r9,lsr #28\n"); + ot(" tst r1,r1\n"); + ot(" bxne r1 ;@ jump to alternative CycloneEnd\n"); +#else + ot(" mov r9,r9,lsr #28\n"); +#endif ot(" str r4,[r7,#0x40] ;@ Save Current PC + Memory Base\n"); ot(" str r5,[r7,#0x5c] ;@ Save Cycles\n"); ot(" strb r9,[r7,#0x46] ;@ Save Flags (NZCV)\n"); @@ -161,7 +168,7 @@ static void PrintFramework() ot(";@ uncompress jump table\n"); if (ms) ot("CycloneInit\n"); else ot("CycloneInit:\n"); - ot(" ldr r12,=JumpTab\n"); + ot(" ldr r12,=CycloneJumpTab\n"); ot(" add r0,r12,#0xe000*4 ;@ ctrl code pointer\n"); ot(" ldr r1,[r0,#-4]\n"); ot(" tst r1,r1\n"); @@ -187,7 +194,7 @@ static void PrintFramework() ot(" bgt unc_loop_in\n"); ot(" b unc_loop\n"); ot("unc_finish%s\n", ms?"":":"); - ot(" ldr r12,=JumpTab\n"); + ot(" ldr r12,=CycloneJumpTab\n"); ot(" ;@ set a-line and f-line handlers\n"); ot(" add r0,r12,#0xa000*4\n"); ot(" ldr r1,[r0,#4] ;@ a-line handler\n"); @@ -255,7 +262,7 @@ static void PrintFramework() ot("\n"); ot(";@ DoInterrupt - r0=IRQ number\n"); - ot("DoInterrupt%s\n", ms?"":":"); + ot("CycloneDoInterrupt%s\n", ms?"":":"); ot(" stmdb sp!,{lr} ;@ Push ARM return address\n"); ot(";@ Get IRQ Vector address:\n"); @@ -475,7 +482,7 @@ static void PrintJumpTable() // space for decompressed table ot(ms?" area |.data|, data\n":" .data\n .align 4\n\n"); - ot("JumpTab%s\n", ms?"":":"); + ot("CycloneJumpTab%s\n", ms?"":":"); if(ms) { for(i = 0; i < 0xa000/8; i++) ot(" dcd 0,0,0,0,0,0,0,0\n"); @@ -548,7 +555,7 @@ static void PrintJumpTable() ot("\n"); free(indexes); #else - ot("JumpTab%s\n", ms?"":":"); + ot("CycloneJumpTab%s\n", ms?"":":"); len=0xfffe; // Hmmm, armasm 2.50.8684 messes up with a 0x10000 long jump table // notaz: same thing with GNU as 2.9-psion-98r2 (reloc overflow) // this is due to COFF objects using only 2 bytes for reloc count @@ -613,6 +620,10 @@ static int CycloneMake() ot(" .global CycloneSetSr\n"); ot(" .global CycloneGetSr\n"); ot(" .global CycloneVer\n"); +#ifdef CYCLONE_FOR_PICODRIVE + ot(" .global CycloneDoInterrupt\n"); + ot(" .global CycloneJumpTab\n"); +#endif ot("CycloneVer: .long 0x%.4x\n",CycloneVer); } ot("\n"); @@ -623,6 +634,8 @@ static int CycloneMake() if (ms) ot(" END\n"); + ot("\n\n;@ vim:filetype=armasm\n"); + fclose(AsmFile); AsmFile=NULL; #if 0 diff --git a/cpu/Cyclone/proj/Makefile.linux b/cpu/Cyclone/proj/Makefile.linux index 912d3e94..159bb661 100644 --- a/cpu/Cyclone/proj/Makefile.linux +++ b/cpu/Cyclone/proj/Makefile.linux @@ -1,6 +1,6 @@ -CFLAGS = -Wall +CFLAGS = -Wall -DCYCLONE_FOR_PICODRIVE -ALL : cyclone.s +all : cyclone.s cyclone.s : Cyclone.exe ./Cyclone.exe diff --git a/platform/gp2x/Makefile b/platform/gp2x/Makefile index 67bbb34a..d6ba1d5b 100644 --- a/platform/gp2x/Makefile +++ b/platform/gp2x/Makefile @@ -12,12 +12,13 @@ asm_memory = 0 # TODO asm_render = 1 asm_ym2612 = 1 asm_misc = 1 +asm_cdpico = 1 #profile = 1 #use_musashi = 1 #up = 1 DEFINC = -I../.. -I. -DARM -D__GP2X__ -D_UNZIP_SUPPORT # -DBENCHMARK -COPT_COMMON = -static -s -O3 -ftracer -fstrength-reduce -Wall -funroll-loops -fomit-frame-pointer -fstrict-aliasing -ffast-math +COPT_COMMON = -static -O3 -ftracer -fstrength-reduce -Wall -funroll-loops -fomit-frame-pointer -fstrict-aliasing -ffast-math # -s ifeq "$(profile)" "1" COPT_COMMON += -fprofile-generate endif @@ -61,6 +62,10 @@ ifeq "$(asm_misc)" "1" DEFINC += -D_ASM_MISC_C OBJS += ../../Pico/misc_asm.o endif +ifeq "$(asm_cdpico)" "1" +DEFINC += -D_ASM_CD_PICO_C +OBJS += ../../Pico/cd/pico_asm.o +endif # Pico - sound OBJS += ../../Pico/sound/mix_asm.o OBJS += ../../Pico/sound/sound.o ../../Pico/sound/sn76496.o ../../Pico/sound/ym2612.o @@ -93,8 +98,10 @@ all: PicoDrive.gpe PicoDrive.gpe : $(OBJS) helix/helix_mp3.a @echo $@ - @$(GCC) -o $@ $(COPT) $^ -lm + @$(GCC) -o $@ $(COPT) $^ -lm -Wl,-Map=PicoDrive.map +ifeq ($(DEBUG),) @$(STRIP) $@ +endif # @$(GCC) $(COPT) $(OBJS) -lm -o PicoDrive_.gpe # @gpecomp PicoDrive_.gpe $@ ifeq "$(up)" "1" @@ -137,6 +144,9 @@ testrefr.gpe : test.o gp2x.o asmutils.o ../../Pico/misc_asm.o : ../../Pico/misc.s @echo $< @$(AS) $(ASOPT) $< -o $@ +../../Pico/cd/pico_asm.o : ../../Pico/cd/Pico.s + @echo $< + @$(AS) $(ASOPT) $< -o $@ # build Cyclone ../../cpu/Cyclone/proj/Cyclone.s : diff --git a/platform/gp2x/emu.c b/platform/gp2x/emu.c index 99c80bae..a98a5be8 100644 --- a/platform/gp2x/emu.c +++ b/platform/gp2x/emu.c @@ -547,7 +547,7 @@ int emu_WriteConfig(int game) strncpy(cfg, PicoConfigFile, 511); cfg[511] = 0; } else { - romfname_ext(cfg, "cfg", ".pbcfg"); + romfname_ext(cfg, "cfg/", ".pbcfg"); } printf("emu_WriteConfig: %s ", cfg); diff --git a/platform/gp2x/menu.c b/platform/gp2x/menu.c index aa3019f6..5cab7606 100644 --- a/platform/gp2x/menu.c +++ b/platform/gp2x/menu.c @@ -744,7 +744,7 @@ static void draw_cd_menu_options(int menu_sel, char *b_us, char *b_eu, char *b_j gp2x_text_out8(tl_x, (y+=10), "CD LEDs %s", (currentConfig.EmuOpt &0x0400)?"ON":"OFF"); // 3 gp2x_text_out8(tl_x, (y+=10), "CDDA audio (using mp3s) %s", (currentConfig.PicoOpt&0x0800)?"ON":"OFF"); // 4 gp2x_text_out8(tl_x, (y+=10), "PCM audio %s", (currentConfig.PicoOpt&0x0400)?"ON":"OFF"); // 5 - gp2x_text_out8(tl_x, (y+=10), "Better sync (very slow) %s", (currentConfig.PicoOpt&0x2000)?"ON":"OFF"); // 6 + gp2x_text_out8(tl_x, (y+=10), "Better sync (slow) %s", (currentConfig.PicoOpt&0x2000)?"ON":"OFF"); // 6 gp2x_text_out8(tl_x, (y+=10), "ReadAhead buffer %s", ra_buff); // 7 gp2x_text_out8(tl_x, (y+=10), "Done"); diff --git a/platform/readme.txt b/platform/readme.txt index ecf8d150..277a89bd 100644 --- a/platform/readme.txt +++ b/platform/readme.txt @@ -216,6 +216,9 @@ Changelog + Added data pre-buffering support, this allows to reduce frequency of short pauses in FMV games, but makes those pauses longer. * Fixed PCM DMA transfers (intro FMV in Popful Mail). + + Properly implemented "decode" data transformation (Jaguar XJ220). + * Integrated "better sync" code into cyclone code, what made this mode much faster. + * Fixed a bug related to game specific config saving. 1.201 + Added basic cheat support (GameGenie and Genecyst patches). -- 2.39.5