SekRunPS Cyclone integration

git-svn-id: file:///home/notaz/opt/svn/PicoDrive@68 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
notaz 2007-03-14 17:59:53 +00:00
parent 8b71d0ebf9
commit 7336a99a49
12 changed files with 278 additions and 47 deletions

View file

@ -12,6 +12,7 @@
#include "../unzip/unzip.h" #include "../unzip/unzip.h"
#include "../unzip/unzip_stream.h" #include "../unzip/unzip_stream.h"
static char *rom_exts[] = { "bin", "gen", "smd", "iso" }; static char *rom_exts[] = { "bin", "gen", "smd", "iso" };
@ -78,6 +79,9 @@ zip_failed:
f = fopen(path, "rb"); f = fopen(path, "rb");
if (f == NULL) return NULL; if (f == NULL) return NULL;
/* we use our own buffering */
setvbuf(f, NULL, _IONBF, 0);
file = malloc(sizeof(*file)); file = malloc(sizeof(*file));
if (file == NULL) { if (file == NULL) {
fclose(f); fclose(f);
@ -120,7 +124,8 @@ int pm_seek(pm_file *stream, long offset, int whence)
{ {
if (stream->type == PMT_UNCOMPRESSED) 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) 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 // Allocate space for the rom plus padding
rom=PicoCartAlloc(size); 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 pm_read(rom,size,f); // Load up the rom

View file

@ -24,8 +24,13 @@ extern "C" {
#ifdef EMU_C68K #ifdef EMU_C68K
#include "../cpu/Cyclone/Cyclone.h" #include "../cpu/Cyclone/Cyclone.h"
extern struct Cyclone PicoCpu, PicoCpuS68k; extern struct Cyclone PicoCpu, PicoCpuS68k;
#define SekCyclesLeft PicoCpu.cycles // cycles left for this run #define SekCyclesLeftNoMCD PicoCpu.cycles // cycles left for this run
#define SekSetCyclesLeft(c) PicoCpu.cycles=c #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 SekPc (PicoCpu.pc-PicoCpu.membase)
#define SekPcS68k (PicoCpuS68k.pc-PicoCpuS68k.membase) #define SekPcS68k (PicoCpuS68k.pc-PicoCpuS68k.membase)
#endif #endif
@ -55,8 +60,13 @@ extern int m68k_ICount;
extern m68ki_cpu_core PicoM68kCPU; // MD's CPU extern m68ki_cpu_core PicoM68kCPU; // MD's CPU
extern m68ki_cpu_core PicoS68kCPU; // Mega CD's CPU extern m68ki_cpu_core PicoS68kCPU; // Mega CD's CPU
#ifndef SekCyclesLeft #ifndef SekCyclesLeft
#define SekCyclesLeft m68k_cycles_remaining() #define SekCyclesLeftNoMCD m68k_cycles_remaining()
#define SekSetCyclesLeft(c) SET_CYCLES(c) #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 SekPc m68k_get_reg(&PicoM68kCPU, M68K_REG_PC)
#define SekPcS68k m68k_get_reg(&PicoS68kCPU, M68K_REG_PC) #define SekPcS68k m68k_get_reg(&PicoS68kCPU, M68K_REG_PC)
#endif #endif

View file

@ -89,7 +89,8 @@ static void DmaSlow(int len)
if(Pico.m.scanline != -1) { if(Pico.m.scanline != -1) {
Pico.m.dma_bytes += len; Pico.m.dma_bytes += len;
SekSetCyclesLeft(SekCyclesLeft - CheckDMA()); if ((PicoMCD&1) && (PicoOpt & 0x2000)) SekCycleCnt+=CheckDMA();
else SekSetCyclesLeftNoMCD(SekCyclesLeftNoMCD - CheckDMA());
} else { } else {
// be approximate in non-accurate mode // be approximate in non-accurate mode
SekSetCyclesLeft(SekCyclesLeft - (len*(((488<<8)/167))>>8)); SekSetCyclesLeft(SekCyclesLeft - (len*(((488<<8)/167))>>8));

View file

@ -421,7 +421,6 @@ u16 PicoReadM68k16(u32 a)
a = (a&2) | (cell_map(a >> 2) << 2); // cell arranged a = (a&2) | (cell_map(a >> 2) << 2); // cell arranged
else a &= 0x1fffe; else a &= 0x1fffe;
d = *(u16 *)(Pico_mcd->word_ram1M[bank]+a); d = *(u16 *)(Pico_mcd->word_ram1M[bank]+a);
//d = 0xaaaa;
} else { } else {
// allow access in any mode, like Gens does // allow access in any mode, like Gens does
d = *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe)); 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 *pd = Pico_mcd->word_ram1M[!(r3 & 1)] + (((a>>1)^1)&0x1ffff);
u8 oldmask = (a&1) ? 0xf0 : 0x0f; u8 oldmask = (a&1) ? 0xf0 : 0x0f;
//if ((a & 0x3ffff) < 0x28000) return;
//return;
r3 &= 0x18; r3 &= 0x18;
d &= 0x0f; d &= 0x0f;
if (!(a&1)) d <<= 4; if (!(a&1)) d <<= 4;

View file

@ -83,45 +83,56 @@ static __inline void SekRunS68k(int cyc)
#endif #endif
} }
#define PS_STEP_M68K 8 #define PS_STEP_M68K ((488<<16)/20) // ~24
#define PS_STEP_S68K 13 //#define PS_STEP_S68K 13
#ifndef _ASM_CD_PICO_C
static __inline void SekRunPS(int cyc_m68k, int cyc_s68k) static __inline void SekRunPS(int cyc_m68k, int cyc_s68k)
{ {
int cyc_do_m68k, cyc_do_s68k, it=0; int cycn, cycn_s68k, cyc_do;
int cyc_done_m68k=0, cyc_done_s68k=0; int d_cm = 0, d_cs = 0, ex;
SekCycleAim+=cyc_m68k; SekCycleAim+=cyc_m68k;
SekCycleAimS68k+=cyc_s68k; SekCycleAimS68k+=cyc_s68k;
cyc_do_m68k=SekCycleAim-SekCycleCnt;
cyc_do_s68k=SekCycleAimS68k-SekCycleCntS68k; // fprintf(stderr, "=== start %3i/%3i [%3i/%3i] {%05i.%i} ===\n", cyc_m68k, cyc_s68k,
while (cyc_done_m68k < cyc_do_m68k || cyc_done_s68k < cyc_do_s68k) { // SekCycleAim-SekCycleCnt, SekCycleAimS68k-SekCycleCntS68k, Pico.m.frame_count, Pico.m.scanline);
it++;
if (cyc_done_m68k < cyc_do_m68k && it*PS_STEP_M68K > cyc_done_m68k) { /* 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) #if defined(EMU_C68K)
PicoCpu.cycles = PS_STEP_M68K; PicoCpu.cycles = cyc_do;
CycloneRun(&PicoCpu); CycloneRun(&PicoCpu);
cyc_done_m68k += PS_STEP_M68K - PicoCpu.cycles; SekCycleCnt += cyc_do - PicoCpu.cycles;
#elif defined(EMU_M68K) #elif defined(EMU_M68K)
m68k_set_context(&PicoM68kCPU); m68k_set_context(&PicoM68kCPU);
cyc_done_m68k += m68k_execute(PS_STEP_M68K); SekCycleCnt += (ex = m68k_execute(cyc_do));
#endif #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) #if defined(EMU_C68K)
PicoCpuS68k.cycles = PS_STEP_S68K; PicoCpuS68k.cycles = cyc_do;
CycloneRun(&PicoCpuS68k); CycloneRun(&PicoCpuS68k);
cyc_done_s68k += PS_STEP_S68K - PicoCpuS68k.cycles; SekCycleCntS68k += cyc_do - PicoCpuS68k.cycles;
#elif defined(EMU_M68K) #elif defined(EMU_M68K)
m68k_set_context(&PicoS68kCPU); m68k_set_context(&PicoS68kCPU);
cyc_done_s68k += m68k_execute(PS_STEP_S68K); SekCycleCntS68k += (ex = m68k_execute(cyc_do));
#endif #endif
} //else dprintf("s68k skipping it #%i", it);
} }
SekCycleCnt += cyc_done_m68k; //fprintf(stderr, "%3i\n", ex); d_cs += ex;
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) static __inline void check_cd_dma(void)
{ {
@ -271,7 +282,7 @@ static int PicoFrameHintsMCD(void)
//dprintf("m68k starting exec @ %06x", SekPc); //dprintf("m68k starting exec @ %06x", SekPc);
if(Pico.m.dma_bytes) SekCycleCnt+=CheckDMA(); if(Pico.m.dma_bytes) SekCycleCnt+=CheckDMA();
if((PicoOpt & 0x2000) && (Pico_mcd->m.busreq&3) == 1) { 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 { } else {
SekRun(cycles_68k); SekRun(cycles_68k);
if ((Pico_mcd->m.busreq&3) == 1) // no busreq/no reset if ((Pico_mcd->m.busreq&3) == 1) // no busreq/no reset

179
Pico/cd/Pico.s Normal file
View file

@ -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

View file

@ -93,7 +93,7 @@ void CheckInterrupt(int op)
ot(" ldrleb r1,[r7,#0x44] ;@ Get SR high: T_S__III\n"); ot(" ldrleb r1,[r7,#0x44] ;@ Get SR high: T_S__III\n");
ot(" andle r1,r1,#7 ;@ Get interrupt mask\n"); ot(" andle r1,r1,#7 ;@ Get interrupt mask\n");
ot(" cmple r0,r1 ;@ irq<=6: Is irq<=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("NoInts%x%s\n", op,ms?"":":");
ot("\n"); ot("\n");
} }
@ -109,7 +109,7 @@ static void PrintFramework()
ot(" mov r7,r0 ;@ r7 = Pointer to Cpu Context\n"); ot(" mov r7,r0 ;@ r7 = Pointer to Cpu Context\n");
ot(" ;@ r0-3 = Temporary registers\n"); ot(" ;@ r0-3 = Temporary registers\n");
ot(" ldrb r9,[r7,#0x46] ;@ r9 = Flags (NZCV)\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 r5,[r7,#0x5c] ;@ r5 = Cycles\n");
ot(" ldr r4,[r7,#0x40] ;@ r4 = Current PC + Memory Base\n"); ot(" ldr r4,[r7,#0x40] ;@ r4 = Current PC + Memory Base\n");
ot(" ;@ r8 = Current Opcode\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(" ldrleb r1,[r7,#0x44] ;@ Get SR high: T_S__III\n");
ot(" andle r1,r1,#7 ;@ Get interrupt mask\n"); ot(" andle r1,r1,#7 ;@ Get interrupt mask\n");
ot(" cmple r0,r1 ;@ irq<=6: Is irq<=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(";@ Check if interrupt used up all the cycles:\n");
ot(" subs r5,r5,#0\n"); ot(" subs r5,r5,#0\n");
ot(" blt CycloneEndNoBack\n"); ot(" blt CycloneEndNoBack\n");
@ -143,7 +143,14 @@ static void PrintFramework()
ot("CycloneEnd%s\n", ms?"":":"); ot("CycloneEnd%s\n", ms?"":":");
ot(" sub r4,r4,#2\n"); ot(" sub r4,r4,#2\n");
ot("CycloneEndNoBack%s\n", ms?"":":"); ot("CycloneEndNoBack%s\n", ms?"":":");
#ifdef CYCLONE_FOR_PICODRIVE
ot(" ldr r1,[r7,#0x54]\n");
ot(" mov r9,r9,lsr #28\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 r4,[r7,#0x40] ;@ Save Current PC + Memory Base\n");
ot(" str r5,[r7,#0x5c] ;@ Save Cycles\n"); ot(" str r5,[r7,#0x5c] ;@ Save Cycles\n");
ot(" strb r9,[r7,#0x46] ;@ Save Flags (NZCV)\n"); ot(" strb r9,[r7,#0x46] ;@ Save Flags (NZCV)\n");
@ -161,7 +168,7 @@ static void PrintFramework()
ot(";@ uncompress jump table\n"); ot(";@ uncompress jump table\n");
if (ms) ot("CycloneInit\n"); if (ms) ot("CycloneInit\n");
else 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(" add r0,r12,#0xe000*4 ;@ ctrl code pointer\n");
ot(" ldr r1,[r0,#-4]\n"); ot(" ldr r1,[r0,#-4]\n");
ot(" tst r1,r1\n"); ot(" tst r1,r1\n");
@ -187,7 +194,7 @@ static void PrintFramework()
ot(" bgt unc_loop_in\n"); ot(" bgt unc_loop_in\n");
ot(" b unc_loop\n"); ot(" b unc_loop\n");
ot("unc_finish%s\n", ms?"":":"); 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(" ;@ set a-line and f-line handlers\n");
ot(" add r0,r12,#0xa000*4\n"); ot(" add r0,r12,#0xa000*4\n");
ot(" ldr r1,[r0,#4] ;@ a-line handler\n"); ot(" ldr r1,[r0,#4] ;@ a-line handler\n");
@ -255,7 +262,7 @@ static void PrintFramework()
ot("\n"); ot("\n");
ot(";@ DoInterrupt - r0=IRQ number\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(" stmdb sp!,{lr} ;@ Push ARM return address\n");
ot(";@ Get IRQ Vector address:\n"); ot(";@ Get IRQ Vector address:\n");
@ -475,7 +482,7 @@ static void PrintJumpTable()
// space for decompressed table // space for decompressed table
ot(ms?" area |.data|, data\n":" .data\n .align 4\n\n"); ot(ms?" area |.data|, data\n":" .data\n .align 4\n\n");
ot("JumpTab%s\n", ms?"":":"); ot("CycloneJumpTab%s\n", ms?"":":");
if(ms) { if(ms) {
for(i = 0; i < 0xa000/8; i++) for(i = 0; i < 0xa000/8; i++)
ot(" dcd 0,0,0,0,0,0,0,0\n"); ot(" dcd 0,0,0,0,0,0,0,0\n");
@ -548,7 +555,7 @@ static void PrintJumpTable()
ot("\n"); ot("\n");
free(indexes); free(indexes);
#else #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 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) // 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 // 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 CycloneSetSr\n");
ot(" .global CycloneGetSr\n"); ot(" .global CycloneGetSr\n");
ot(" .global CycloneVer\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("CycloneVer: .long 0x%.4x\n",CycloneVer);
} }
ot("\n"); ot("\n");
@ -623,6 +634,8 @@ static int CycloneMake()
if (ms) ot(" END\n"); if (ms) ot(" END\n");
ot("\n\n;@ vim:filetype=armasm\n");
fclose(AsmFile); AsmFile=NULL; fclose(AsmFile); AsmFile=NULL;
#if 0 #if 0

View file

@ -1,6 +1,6 @@
CFLAGS = -Wall CFLAGS = -Wall -DCYCLONE_FOR_PICODRIVE
ALL : cyclone.s all : cyclone.s
cyclone.s : Cyclone.exe cyclone.s : Cyclone.exe
./Cyclone.exe ./Cyclone.exe

View file

@ -12,12 +12,13 @@ asm_memory = 0 # TODO
asm_render = 1 asm_render = 1
asm_ym2612 = 1 asm_ym2612 = 1
asm_misc = 1 asm_misc = 1
asm_cdpico = 1
#profile = 1 #profile = 1
#use_musashi = 1 #use_musashi = 1
#up = 1 #up = 1
DEFINC = -I../.. -I. -DARM -D__GP2X__ -D_UNZIP_SUPPORT # -DBENCHMARK 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" ifeq "$(profile)" "1"
COPT_COMMON += -fprofile-generate COPT_COMMON += -fprofile-generate
endif endif
@ -61,6 +62,10 @@ ifeq "$(asm_misc)" "1"
DEFINC += -D_ASM_MISC_C DEFINC += -D_ASM_MISC_C
OBJS += ../../Pico/misc_asm.o OBJS += ../../Pico/misc_asm.o
endif endif
ifeq "$(asm_cdpico)" "1"
DEFINC += -D_ASM_CD_PICO_C
OBJS += ../../Pico/cd/pico_asm.o
endif
# Pico - sound # Pico - sound
OBJS += ../../Pico/sound/mix_asm.o OBJS += ../../Pico/sound/mix_asm.o
OBJS += ../../Pico/sound/sound.o ../../Pico/sound/sn76496.o ../../Pico/sound/ym2612.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 PicoDrive.gpe : $(OBJS) helix/helix_mp3.a
@echo $@ @echo $@
@$(GCC) -o $@ $(COPT) $^ -lm @$(GCC) -o $@ $(COPT) $^ -lm -Wl,-Map=PicoDrive.map
ifeq ($(DEBUG),)
@$(STRIP) $@ @$(STRIP) $@
endif
# @$(GCC) $(COPT) $(OBJS) -lm -o PicoDrive_.gpe # @$(GCC) $(COPT) $(OBJS) -lm -o PicoDrive_.gpe
# @gpecomp PicoDrive_.gpe $@ # @gpecomp PicoDrive_.gpe $@
ifeq "$(up)" "1" ifeq "$(up)" "1"
@ -137,6 +144,9 @@ testrefr.gpe : test.o gp2x.o asmutils.o
../../Pico/misc_asm.o : ../../Pico/misc.s ../../Pico/misc_asm.o : ../../Pico/misc.s
@echo $< @echo $<
@$(AS) $(ASOPT) $< -o $@ @$(AS) $(ASOPT) $< -o $@
../../Pico/cd/pico_asm.o : ../../Pico/cd/Pico.s
@echo $<
@$(AS) $(ASOPT) $< -o $@
# build Cyclone # build Cyclone
../../cpu/Cyclone/proj/Cyclone.s : ../../cpu/Cyclone/proj/Cyclone.s :

View file

@ -547,7 +547,7 @@ int emu_WriteConfig(int game)
strncpy(cfg, PicoConfigFile, 511); strncpy(cfg, PicoConfigFile, 511);
cfg[511] = 0; cfg[511] = 0;
} else { } else {
romfname_ext(cfg, "cfg", ".pbcfg"); romfname_ext(cfg, "cfg/", ".pbcfg");
} }
printf("emu_WriteConfig: %s ", cfg); printf("emu_WriteConfig: %s ", cfg);

View file

@ -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), "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), "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), "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), "ReadAhead buffer %s", ra_buff); // 7
gp2x_text_out8(tl_x, (y+=10), "Done"); gp2x_text_out8(tl_x, (y+=10), "Done");

View file

@ -216,6 +216,9 @@ Changelog
+ Added data pre-buffering support, this allows to reduce frequency of short pauses + Added data pre-buffering support, this allows to reduce frequency of short pauses
in FMV games, but makes those pauses longer. in FMV games, but makes those pauses longer.
* Fixed PCM DMA transfers (intro FMV in Popful Mail). * 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 1.201
+ Added basic cheat support (GameGenie and Genecyst patches). + Added basic cheat support (GameGenie and Genecyst patches).