mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 15:27:46 -04:00
idle loop detection (Cyclone only, with debug stuff)
git-svn-id: file:///home/notaz/opt/svn/PicoDrive@502 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
parent
d95259bdaa
commit
053fd9b42f
17 changed files with 372 additions and 37 deletions
|
@ -548,6 +548,7 @@ int PicoCartInsert(unsigned char *rom,unsigned int romsize)
|
||||||
int PicoCartUnload(void)
|
int PicoCartUnload(void)
|
||||||
{
|
{
|
||||||
if (Pico.rom != NULL) {
|
if (Pico.rom != NULL) {
|
||||||
|
SekFinishIdleDet();
|
||||||
free(Pico.rom);
|
free(Pico.rom);
|
||||||
Pico.rom=NULL;
|
Pico.rom=NULL;
|
||||||
}
|
}
|
||||||
|
|
33
Pico/Pico.c
33
Pico/Pico.c
|
@ -58,6 +58,8 @@ void PicoPower(void)
|
||||||
{
|
{
|
||||||
unsigned char sram_reg=Pico.m.sram_reg; // must be preserved
|
unsigned char sram_reg=Pico.m.sram_reg; // must be preserved
|
||||||
|
|
||||||
|
Pico.m.frame_count = 0;
|
||||||
|
|
||||||
// clear all memory of the emulated machine
|
// clear all memory of the emulated machine
|
||||||
memset(&Pico.ram,0,(unsigned int)&Pico.rom-(unsigned int)&Pico.ram);
|
memset(&Pico.ram,0,(unsigned int)&Pico.rom-(unsigned int)&Pico.ram);
|
||||||
|
|
||||||
|
@ -172,6 +174,12 @@ int PicoReset(void)
|
||||||
PicoResetMCD();
|
PicoResetMCD();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
// reinit, so that checksum checks pass
|
||||||
|
SekFinishIdleDet();
|
||||||
|
if (!(PicoOpt & POPT_DIS_IDLE_DET))
|
||||||
|
SekInitIdleDet();
|
||||||
|
}
|
||||||
|
|
||||||
// reset sram state; enable sram access by default if it doesn't overlap with ROM
|
// reset sram state; enable sram access by default if it doesn't overlap with ROM
|
||||||
Pico.m.sram_reg=sram_reg&0x14;
|
Pico.m.sram_reg=sram_reg&0x14;
|
||||||
|
@ -188,17 +196,17 @@ int PicoReset(void)
|
||||||
// same for Outrunners (92-121, when active is set to 24)
|
// same for Outrunners (92-121, when active is set to 24)
|
||||||
// 96 is VR hack
|
// 96 is VR hack
|
||||||
static const int dma_timings[] = {
|
static const int dma_timings[] = {
|
||||||
96, 167, 166, 83, // vblank: 32cell: dma2vram dma2[vs|c]ram vram_fill vram_copy
|
96, 167, 166, 83, // vblank: 32cell: dma2vram dma2[vs|c]ram vram_fill vram_copy
|
||||||
102, 205, 204, 102, // vblank: 40cell:
|
102, 205, 204, 102, // vblank: 40cell:
|
||||||
16, 16, 15, 8, // active: 32cell:
|
16, 16, 15, 8, // active: 32cell:
|
||||||
24, 18, 17, 9 // ...
|
24, 18, 17, 9 // ...
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int dma_bsycles[] = {
|
static const int dma_bsycles[] = {
|
||||||
(488<<8)/96, (488<<8)/167, (488<<8)/166, (488<<8)/83,
|
(488<<8)/96, (488<<8)/167, (488<<8)/166, (488<<8)/83,
|
||||||
(488<<8)/102, (488<<8)/205, (488<<8)/204, (488<<8)/102,
|
(488<<8)/102, (488<<8)/205, (488<<8)/204, (488<<8)/102,
|
||||||
(488<<8)/16, (488<<8)/16, (488<<8)/15, (488<<8)/8,
|
(488<<8)/16, (488<<8)/16, (488<<8)/15, (488<<8)/8,
|
||||||
(488<<8)/24, (488<<8)/18, (488<<8)/17, (488<<8)/9
|
(488<<8)/24, (488<<8)/18, (488<<8)/17, (488<<8)/9
|
||||||
};
|
};
|
||||||
|
|
||||||
PICO_INTERNAL int CheckDMA(void)
|
PICO_INTERNAL int CheckDMA(void)
|
||||||
|
@ -232,7 +240,7 @@ static __inline void SekRunM68k(int cyc)
|
||||||
{
|
{
|
||||||
int cyc_do;
|
int cyc_do;
|
||||||
SekCycleAim+=cyc;
|
SekCycleAim+=cyc;
|
||||||
if((cyc_do=SekCycleAim-SekCycleCnt) <= 0) return;
|
if ((cyc_do=SekCycleAim-SekCycleCnt) <= 0) return;
|
||||||
#if defined(EMU_CORE_DEBUG)
|
#if defined(EMU_CORE_DEBUG)
|
||||||
// this means we do run-compare
|
// this means we do run-compare
|
||||||
SekCycleCnt+=CM_compareRun(cyc_do, 0);
|
SekCycleCnt+=CM_compareRun(cyc_do, 0);
|
||||||
|
@ -498,10 +506,17 @@ static int PicoFrameSimple(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int idle_hit_counter = 0;
|
||||||
|
|
||||||
int PicoFrame(void)
|
int PicoFrame(void)
|
||||||
{
|
{
|
||||||
int acc;
|
int acc;
|
||||||
|
|
||||||
|
if ((Pico.m.frame_count&0x3f) == 0) {
|
||||||
|
elprintf(EL_STATUS, "ihits: %i", idle_hit_counter);
|
||||||
|
idle_hit_counter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
Pico.m.frame_count++;
|
Pico.m.frame_count++;
|
||||||
|
|
||||||
if (PicoAHW & PAHW_MCD) {
|
if (PicoAHW & PAHW_MCD) {
|
||||||
|
|
|
@ -47,6 +47,7 @@ void mp3_update(int *buffer, int length, int stereo);
|
||||||
#define POPT_DIS_VDP_FIFO (1<<16) // 0x 0000
|
#define POPT_DIS_VDP_FIFO (1<<16) // 0x 0000
|
||||||
#define POPT_EN_SVP_DRC (1<<17)
|
#define POPT_EN_SVP_DRC (1<<17)
|
||||||
#define POPT_DIS_SPRITE_LIM (1<<18)
|
#define POPT_DIS_SPRITE_LIM (1<<18)
|
||||||
|
#define POPT_DIS_IDLE_DET (1<<19)
|
||||||
extern int PicoOpt; // bitfield
|
extern int PicoOpt; // bitfield
|
||||||
#define PAHW_MCD (1<<0)
|
#define PAHW_MCD (1<<0)
|
||||||
#define PAHW_32X (1<<1)
|
#define PAHW_32X (1<<1)
|
||||||
|
|
|
@ -259,9 +259,9 @@ struct PicoMisc
|
||||||
unsigned char eeprom_cycle; // EEPROM SRAM cycle number
|
unsigned char eeprom_cycle; // EEPROM SRAM cycle number
|
||||||
unsigned char eeprom_slave; // EEPROM slave word for X24C02 and better SRAMs
|
unsigned char eeprom_slave; // EEPROM slave word for X24C02 and better SRAMs
|
||||||
unsigned char prot_bytes[2]; // simple protection faking
|
unsigned char prot_bytes[2]; // simple protection faking
|
||||||
unsigned short dma_xfers;
|
unsigned short dma_xfers; // 18
|
||||||
unsigned char pad[2];
|
unsigned char pad[2];
|
||||||
unsigned int frame_count; // mainly for movies
|
unsigned int frame_count; // 1c for movies and idle det
|
||||||
};
|
};
|
||||||
|
|
||||||
// some assembly stuff depend on these, do not touch!
|
// some assembly stuff depend on these, do not touch!
|
||||||
|
@ -461,6 +461,8 @@ PICO_INTERNAL int SekInit(void);
|
||||||
PICO_INTERNAL int SekReset(void);
|
PICO_INTERNAL int SekReset(void);
|
||||||
PICO_INTERNAL void SekState(int *data);
|
PICO_INTERNAL void SekState(int *data);
|
||||||
PICO_INTERNAL void SekSetRealTAS(int use_real);
|
PICO_INTERNAL void SekSetRealTAS(int use_real);
|
||||||
|
void SekInitIdleDet(void);
|
||||||
|
void SekFinishIdleDet(void);
|
||||||
|
|
||||||
// cd/Sek.c
|
// cd/Sek.c
|
||||||
PICO_INTERNAL int SekInitS68k(void);
|
PICO_INTERNAL int SekInitS68k(void);
|
||||||
|
@ -557,6 +559,7 @@ extern int PsndDacLine;
|
||||||
#define EL_CDPOLL 0x00002000 /* MCD: log poll detection */
|
#define EL_CDPOLL 0x00002000 /* MCD: log poll detection */
|
||||||
#define EL_SVP 0x00004000 /* SVP stuff */
|
#define EL_SVP 0x00004000 /* SVP stuff */
|
||||||
#define EL_PICOHW 0x00008000 /* Pico stuff */
|
#define EL_PICOHW 0x00008000 /* Pico stuff */
|
||||||
|
#define EL_IDLE 0x00010000 /* idle loop det. */
|
||||||
|
|
||||||
#define EL_STATUS 0x40000000 /* status messages */
|
#define EL_STATUS 0x40000000 /* status messages */
|
||||||
#define EL_ANOMALY 0x80000000 /* some unexpected conditions (during emulation) */
|
#define EL_ANOMALY 0x80000000 /* some unexpected conditions (during emulation) */
|
||||||
|
|
125
Pico/Sek.c
125
Pico/Sek.c
|
@ -193,6 +193,131 @@ PICO_INTERNAL void SekSetRealTAS(int use_real)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* idle loop detection, not to be used in CD mode */
|
||||||
|
#ifdef EMU_C68K
|
||||||
|
#include "cpu/Cyclone/tools/idle.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int *idledet_addrs = NULL;
|
||||||
|
static int idledet_count = 0, idledet_bads = 0;
|
||||||
|
int idledet_start_frame = 0;
|
||||||
|
|
||||||
|
static int jump_verify[0x10000];
|
||||||
|
extern int CycloneJumpTab[];
|
||||||
|
static unsigned char *rom_verify = NULL;
|
||||||
|
|
||||||
|
void SekInitIdleDet(void)
|
||||||
|
{
|
||||||
|
void *tmp = realloc(idledet_addrs, 0x200*4);
|
||||||
|
if (tmp == NULL) {
|
||||||
|
free(idledet_addrs);
|
||||||
|
idledet_addrs = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
idledet_addrs = tmp;
|
||||||
|
idledet_count = idledet_bads = 0;
|
||||||
|
idledet_start_frame = Pico.m.frame_count + 360;
|
||||||
|
|
||||||
|
memcpy(jump_verify, CycloneJumpTab, 0x10000*4);
|
||||||
|
rom_verify = realloc(rom_verify, Pico.romsize);
|
||||||
|
memcpy(rom_verify, Pico.rom, Pico.romsize);
|
||||||
|
#ifdef EMU_C68K
|
||||||
|
CycloneInitIdle();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int SekIsIdleCode(unsigned short *dst, int bytes)
|
||||||
|
{
|
||||||
|
printf("SekIsIdleCode %04x %i\n", *dst, bytes);
|
||||||
|
switch (bytes)
|
||||||
|
{
|
||||||
|
case 4:
|
||||||
|
if ( (*dst & 0xfff8) == 0x4a10 || // tst.b ($aX) // where should be no need to wait
|
||||||
|
(*dst & 0xfff8) == 0x4a28 || // tst.b ($xxxx,a0) // for byte change anywhere
|
||||||
|
(*dst & 0xff3f) == 0x4a38 || // tst.x ($xxxx.w), tas ($xxxx.w)
|
||||||
|
(*dst & 0xc1ff) == 0x0038 || // move.x ($xxxx.w), dX
|
||||||
|
(*dst & 0xf13f) == 0xb038) // cmp.x ($xxxx.w), dX
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
if ( ((dst[1] & 0xe0) == 0xe0 && ( // RAM
|
||||||
|
*dst == 0x4a39 || // tst.b ($xxxxxxxx)
|
||||||
|
*dst == 0x4a79 || // tst.w ($xxxxxxxx)
|
||||||
|
*dst == 0x4ab9)) || // tst.l ($xxxxxxxx)
|
||||||
|
*dst == 0x0838) // btst $X, ($xxxx.w) [6 byte op]
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
if ( (dst[2] & 0xe0) == 0xe0 && ( // RAM
|
||||||
|
*dst == 0x0839 || // btst $X, ($xxxxxxxx.w) [8 byte op]
|
||||||
|
(*dst & 0xffbf) == 0x0c39)) // cmpi.{b,w} $X, ($xxxxxxxx)
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
|
case 12:
|
||||||
|
if ((*dst & 0xf1f8) == 0x3010 && // move.w (aX), dX
|
||||||
|
(dst[1]&0xf100) == 0x0000 && // arithmetic
|
||||||
|
(dst[3]&0xf100) == 0x0000) // arithmetic
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SekRegisterIdlePatch(unsigned int pc, int oldop, int newop)
|
||||||
|
{
|
||||||
|
#ifdef EMU_C68K
|
||||||
|
pc -= PicoCpuCM68k.membase;
|
||||||
|
#endif
|
||||||
|
pc &= ~0xff000000;
|
||||||
|
elprintf(EL_IDLE, "idle: patch %06x %04x %04x #%i", pc, oldop, newop, idledet_count);
|
||||||
|
if (pc > Pico.romsize) {
|
||||||
|
if (++idledet_bads > 128) return 2; // remove detector
|
||||||
|
return 1; // don't patch
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idledet_count >= 0x200 && (idledet_count & 0x1ff) == 0) {
|
||||||
|
void *tmp = realloc(idledet_addrs, (idledet_count+0x200)*4);
|
||||||
|
if (tmp == NULL) return 1;
|
||||||
|
idledet_addrs = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
idledet_addrs[idledet_count++] = pc;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SekFinishIdleDet(void)
|
||||||
|
{
|
||||||
|
int done_something = idledet_count > 0;
|
||||||
|
#ifdef EMU_C68K
|
||||||
|
CycloneFinishIdle();
|
||||||
|
#endif
|
||||||
|
while (idledet_count > 0)
|
||||||
|
{
|
||||||
|
unsigned short *op = (unsigned short *)&Pico.rom[idledet_addrs[--idledet_count]];
|
||||||
|
if ((*op & 0xfd00) == 0x7100)
|
||||||
|
*op &= 0xff, *op |= 0x6600;
|
||||||
|
else if ((*op & 0xfd00) == 0x7500)
|
||||||
|
*op &= 0xff, *op |= 0x6700;
|
||||||
|
else if ((*op & 0xfd00) == 0x7d00)
|
||||||
|
*op &= 0xff, *op |= 0x6000;
|
||||||
|
else
|
||||||
|
elprintf(EL_STATUS|EL_IDLE, "idle: don't know how to restore %04x", *op);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (done_something)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 0x10000; i++)
|
||||||
|
if (jump_verify[i] != CycloneJumpTab[i])
|
||||||
|
printf("jumptab corruption @ %04x!\n", i), exit(1);
|
||||||
|
for (i = 0; i < Pico.romsize; i++)
|
||||||
|
if (rom_verify[i] != Pico.rom[i])
|
||||||
|
printf("ROM corruption @ %06x!\n", i), exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#if defined(EMU_M68K) && M68K_INSTRUCTION_HOOK == OPT_SPECIFY_HANDLER
|
#if defined(EMU_M68K) && M68K_INSTRUCTION_HOOK == OPT_SPECIFY_HANDLER
|
||||||
static unsigned char op_flags[0x400000/2] = { 0, };
|
static unsigned char op_flags[0x400000/2] = { 0, };
|
||||||
static int atexit_set = 0;
|
static int atexit_set = 0;
|
||||||
|
|
3
cpu/Cyclone/tools/idle.h
Normal file
3
cpu/Cyclone/tools/idle.h
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
|
||||||
|
void CycloneInitIdle(void);
|
||||||
|
void CycloneFinishIdle(void);
|
180
cpu/Cyclone/tools/idle.s
Normal file
180
cpu/Cyclone/tools/idle.s
Normal file
|
@ -0,0 +1,180 @@
|
||||||
|
@ vim:filetype=armasm
|
||||||
|
|
||||||
|
@ ranges/opcodes (idle, normal):
|
||||||
|
@ 71xx, 73xx - bne.s (8bit offset)
|
||||||
|
@ 75xx, 77xx - beq.s (8bit offset)
|
||||||
|
@ 7dxx, 7fxx - bra.s (8bit offset)
|
||||||
|
|
||||||
|
.data
|
||||||
|
.align 2
|
||||||
|
|
||||||
|
have_patches:
|
||||||
|
.word 0
|
||||||
|
|
||||||
|
.equ patch_desc_table_size, 10
|
||||||
|
|
||||||
|
patch_desc_table:
|
||||||
|
.word (0x71fa<<16) | 0x66fa, idle_detector_bcc8, idle_bne, Op6601 @ bne.s
|
||||||
|
.word (0x71f8<<16) | 0x66f8, idle_detector_bcc8, idle_bne, Op6601 @ bne.s
|
||||||
|
.word (0x71f6<<16) | 0x66f6, idle_detector_bcc8, idle_bne, Op6601 @ bne.s
|
||||||
|
.word (0x71f2<<16) | 0x66f2, idle_detector_bcc8, idle_bne, Op6601 @ bne.s
|
||||||
|
.word (0x75fa<<16) | 0x67fa, idle_detector_bcc8, idle_beq, Op6701 @ beq.s
|
||||||
|
.word (0x75f8<<16) | 0x67f8, idle_detector_bcc8, idle_beq, Op6701 @ beq.s
|
||||||
|
.word (0x75f6<<16) | 0x67f6, idle_detector_bcc8, idle_beq, Op6701 @ bne.s
|
||||||
|
.word (0x75f2<<16) | 0x67f2, idle_detector_bcc8, idle_beq, Op6701 @ bne.s
|
||||||
|
.word (0x7dfe<<16) | 0x60fe, idle_detector_dead, idle_bra, Op6001 @ bra.s
|
||||||
|
.word (0x7dfc<<16) | 0x60fc, idle_detector_dead, idle_bra, Op6001 @ bra.s
|
||||||
|
|
||||||
|
|
||||||
|
.text
|
||||||
|
.align 2
|
||||||
|
|
||||||
|
|
||||||
|
.global CycloneInitIdle
|
||||||
|
|
||||||
|
CycloneInitIdle:
|
||||||
|
ldr r3, =CycloneJumpTab
|
||||||
|
ldr r2, =patch_desc_table
|
||||||
|
mov r12,#patch_desc_table_size
|
||||||
|
|
||||||
|
cii_loop:
|
||||||
|
ldrh r0, [r2]
|
||||||
|
ldr r1, [r2, #4] @ detector
|
||||||
|
str r1, [r3, r0, lsl #2]
|
||||||
|
ldrh r0, [r2, #2]
|
||||||
|
ldr r1, [r2, #8] @ idle
|
||||||
|
add r0, r3, r0, lsl #2
|
||||||
|
str r1, [r0]
|
||||||
|
ldr r1, [r2, #12] @ normal
|
||||||
|
str r1, [r0, #0x800]
|
||||||
|
add r2, r2, #16
|
||||||
|
subs r12,r12,#1
|
||||||
|
bgt cii_loop
|
||||||
|
|
||||||
|
ldr r0, =have_patches
|
||||||
|
mov r1, #1
|
||||||
|
str r1, [r0]
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
|
||||||
|
.global CycloneFinishIdle
|
||||||
|
|
||||||
|
CycloneFinishIdle:
|
||||||
|
ldr r0, =have_patches
|
||||||
|
ldr r0, [r0]
|
||||||
|
tst r0, r0
|
||||||
|
bxeq lr
|
||||||
|
|
||||||
|
ldr r3, =CycloneJumpTab
|
||||||
|
ldr r2, =patch_desc_table
|
||||||
|
mov r12,#patch_desc_table_size
|
||||||
|
|
||||||
|
cfi_loop:
|
||||||
|
ldrh r0, [r2]
|
||||||
|
ldr r1, [r2, #12] @ normal
|
||||||
|
str r1, [r3, r0, lsl #2]
|
||||||
|
ldrh r0, [r2, #2]
|
||||||
|
ldr r1, =Op____
|
||||||
|
add r0, r3, r0, lsl #2
|
||||||
|
str r1, [r0]
|
||||||
|
str r1, [r0, #0x800]
|
||||||
|
add r2, r2, #16
|
||||||
|
subs r12,r12,#1
|
||||||
|
bgt cfi_loop
|
||||||
|
|
||||||
|
ldr r0, =have_patches
|
||||||
|
mov r1, #0
|
||||||
|
str r1, [r0]
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.macro inc_counter cond
|
||||||
|
ldr r0, =idle_hit_counter
|
||||||
|
ldr r1, [r0]
|
||||||
|
add r1, r1, #1
|
||||||
|
str\cond r1, [r0]
|
||||||
|
.endm
|
||||||
|
|
||||||
|
idle_bra:
|
||||||
|
mov r5, #4
|
||||||
|
inc_counter
|
||||||
|
b Op6001
|
||||||
|
|
||||||
|
idle_bne:
|
||||||
|
msr cpsr_flg, r10 ;@ ARM flags = 68000 flags
|
||||||
|
movne r5, #4
|
||||||
|
inc_counter ne
|
||||||
|
b Op6601
|
||||||
|
|
||||||
|
idle_beq:
|
||||||
|
msr cpsr_flg, r10 ;@ ARM flags = 68000 flags
|
||||||
|
moveq r5, #4
|
||||||
|
inc_counter eq
|
||||||
|
b Op6701
|
||||||
|
|
||||||
|
|
||||||
|
@ @@@ @
|
||||||
|
|
||||||
|
idle_detector_bcc8:
|
||||||
|
ldr r0, =(Pico+0x22208) @ Pico.m
|
||||||
|
ldr r1, =idledet_start_frame
|
||||||
|
ldr r0, [r0, #0x1c] @ ..frame_count
|
||||||
|
ldr r1, [r1]
|
||||||
|
cmp r0, r1
|
||||||
|
blt exit_detector @ not yet
|
||||||
|
|
||||||
|
mov r0, r8, asl #24 @ Shift 8-bit signed offset up...
|
||||||
|
add r0, r4, r0, asr #24 @ jump dest
|
||||||
|
bic r0, r0, #1
|
||||||
|
|
||||||
|
mov r1, #0
|
||||||
|
sub r1, r1, r8, lsl #24
|
||||||
|
mov r1, r1, lsr #24
|
||||||
|
sub r1, r1, #2
|
||||||
|
|
||||||
|
bl SekIsIdleCode
|
||||||
|
tst r0, r0
|
||||||
|
and r2, r8, #0x00ff
|
||||||
|
orr r2, r2, #0x7100
|
||||||
|
orreq r2, r2, #0x0200
|
||||||
|
tst r8, #0x0100 @ 67xx (beq)?
|
||||||
|
orrne r2, r2, #0x0400
|
||||||
|
|
||||||
|
@ r2 = patch_opcode
|
||||||
|
sub r0, r4, #2
|
||||||
|
ldrh r1, [r0]
|
||||||
|
mov r11,r2
|
||||||
|
bl SekRegisterIdlePatch
|
||||||
|
cmp r0, #1 @ 0 - ok to patch, 1 - no patch, 2 - remove detector
|
||||||
|
strlth r11,[r4, #-2]
|
||||||
|
ble exit_detector
|
||||||
|
|
||||||
|
@ remove detector from Cyclone
|
||||||
|
tst r8, #0x0100 @ 67xx (beq)?
|
||||||
|
ldreq r1, =Op6601
|
||||||
|
ldrne r1, =Op6701
|
||||||
|
|
||||||
|
ldr r3, =CycloneJumpTab
|
||||||
|
str r1, [r3, r8, lsl #2]
|
||||||
|
bx r1
|
||||||
|
|
||||||
|
exit_detector:
|
||||||
|
tst r8, #0x0100 @ 67xx (beq)?
|
||||||
|
beq Op6601
|
||||||
|
b Op6701
|
||||||
|
|
||||||
|
|
||||||
|
idle_detector_dead:
|
||||||
|
@ patch without further questions
|
||||||
|
and r2, r8, #0x00ff
|
||||||
|
orr r2, r2, #0x7d00
|
||||||
|
sub r0, r4, #2
|
||||||
|
ldrh r1, [r0]
|
||||||
|
mov r11,r2
|
||||||
|
bl SekRegisterIdlePatch
|
||||||
|
strh r11,[r4, #-2]
|
||||||
|
b Op6001
|
||||||
|
|
||||||
|
.pool
|
||||||
|
|
|
@ -621,6 +621,8 @@ Additional thanks
|
||||||
* Tasco Deluxe for his reverse engineering work on SVP and some mappers.
|
* Tasco Deluxe for his reverse engineering work on SVP and some mappers.
|
||||||
* Bart Trzynadlowski for his SSFII and 68000 docs.
|
* Bart Trzynadlowski for his SSFII and 68000 docs.
|
||||||
* Haze for his research (http://haze.mameworld.info).
|
* Haze for his research (http://haze.mameworld.info).
|
||||||
|
* Lordus, Exophase and Rokas for various ideas.
|
||||||
|
* Nemesis for his YM2612 research.
|
||||||
* Mark and Jean-loup for zlib library.
|
* Mark and Jean-loup for zlib library.
|
||||||
* ketchupgun for the skin.
|
* ketchupgun for the skin.
|
||||||
#ifdef GP2X
|
#ifdef GP2X
|
||||||
|
@ -632,7 +634,6 @@ Additional thanks
|
||||||
* A_SN for his gamma code.
|
* A_SN for his gamma code.
|
||||||
* craigix for supplying the GP2X hardware and making this port possible.
|
* craigix for supplying the GP2X hardware and making this port possible.
|
||||||
* Alex for the icon.
|
* Alex for the icon.
|
||||||
* Exophase, Rokas and Lordus for various ideas.
|
|
||||||
* All the people from gp32x boards for their support.
|
* All the people from gp32x boards for their support.
|
||||||
#endif
|
#endif
|
||||||
#ifdef GIZ
|
#ifdef GIZ
|
||||||
|
|
|
@ -427,8 +427,6 @@ int emu_ReloadRom(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Pico.m.frame_count = 0;
|
|
||||||
|
|
||||||
// insert CD if it was detected
|
// insert CD if it was detected
|
||||||
if (cd_state != CIT_NOT_CD) {
|
if (cd_state != CIT_NOT_CD) {
|
||||||
ret = Insert_CD(romFileName, cd_state);
|
ret = Insert_CD(romFileName, cd_state);
|
||||||
|
|
|
@ -66,6 +66,7 @@ typedef enum
|
||||||
MA_OPT2_NO_FRAME_LIMIT, /* psp */
|
MA_OPT2_NO_FRAME_LIMIT, /* psp */
|
||||||
MA_OPT2_SVP_DYNAREC,
|
MA_OPT2_SVP_DYNAREC,
|
||||||
MA_OPT2_NO_SPRITE_LIM,
|
MA_OPT2_NO_SPRITE_LIM,
|
||||||
|
MA_OPT2_NO_IDLE_LOOPS,
|
||||||
MA_OPT2_DONE,
|
MA_OPT2_DONE,
|
||||||
MA_OPT3_SCALE, /* psp (all OPT3) */
|
MA_OPT3_SCALE, /* psp (all OPT3) */
|
||||||
MA_OPT3_HSCALE32,
|
MA_OPT3_HSCALE32,
|
||||||
|
|
|
@ -70,7 +70,7 @@ static unsigned long wait_for_input(unsigned int interesting)
|
||||||
repeats = 0;
|
repeats = 0;
|
||||||
wait = 20;
|
wait = 20;
|
||||||
}
|
}
|
||||||
if (wait > 6 && (ret&(BTN_UP|BTN_LEFT|BTN_DOWN|BTN_RIGHT)))
|
if (wait > 6 && (ret&(BTN_UP|BTN_LEFT|BTN_DOWN|BTN_RIGHT|BTN_L|BTN_R)))
|
||||||
wait = 6;
|
wait = 6;
|
||||||
inp_prev = ret;
|
inp_prev = ret;
|
||||||
|
|
||||||
|
@ -1315,7 +1315,7 @@ static int menu_loop_options(void)
|
||||||
|
|
||||||
static void draw_menu_credits(void)
|
static void draw_menu_credits(void)
|
||||||
{
|
{
|
||||||
int tl_x = 15, tl_y = 64, y;
|
int tl_x = 15, tl_y = 56, y;
|
||||||
menu_draw_begin(1);
|
menu_draw_begin(1);
|
||||||
|
|
||||||
text_out16(tl_x, 20, "PicoDrive v" VERSION " (c) notaz, 2006-2008");
|
text_out16(tl_x, 20, "PicoDrive v" VERSION " (c) notaz, 2006-2008");
|
||||||
|
@ -1326,14 +1326,16 @@ static void draw_menu_credits(void)
|
||||||
text_out16(tl_x, (y+=10), " base code of PicoDrive");
|
text_out16(tl_x, (y+=10), " base code of PicoDrive");
|
||||||
text_out16(tl_x, (y+=10), "Reesy & FluBBa: DrZ80 core");
|
text_out16(tl_x, (y+=10), "Reesy & FluBBa: DrZ80 core");
|
||||||
text_out16(tl_x, (y+=10), "MAME devs: YM2612 and SN76496 cores");
|
text_out16(tl_x, (y+=10), "MAME devs: YM2612 and SN76496 cores");
|
||||||
text_out16(tl_x, (y+=10), "Charles MacDonald: Genesis hw docs");
|
|
||||||
text_out16(tl_x, (y+=10), "Stephane Dallongeville:");
|
|
||||||
text_out16(tl_x, (y+=10), " opensource Gens");
|
|
||||||
text_out16(tl_x, (y+=10), "Haze: Genesis hw info");
|
|
||||||
text_out16(tl_x, (y+=10), "Reesy: kgsdk wrapper, sound code");
|
text_out16(tl_x, (y+=10), "Reesy: kgsdk wrapper, sound code");
|
||||||
text_out16(tl_x, (y+=10), "jens.l: gizmondo hardware");
|
text_out16(tl_x, (y+=10), "jens.l: gizmondo hardware");
|
||||||
text_out16(tl_x, (y+=10), "ketchupgun: skin design");
|
text_out16(tl_x, (y+=10), "ketchupgun: skin design");
|
||||||
|
|
||||||
|
text_out16(tl_x, (y+=20), "special thanks (for code, docs, ideas)");
|
||||||
|
text_out16(tl_x, (y+=10), " Charles MacDonald, Haze,");
|
||||||
|
text_out16(tl_x, (y+=10), " Stephane Dallongeville,");
|
||||||
|
text_out16(tl_x, (y+=10), " Lordus, Exophase, Rokas,");
|
||||||
|
text_out16(tl_x, (y+=10), " Nemesis, Tasco Deluxe");
|
||||||
|
|
||||||
menu_draw_end();
|
menu_draw_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -128,7 +128,7 @@ OBJS += ../../cpu/musashi/m68kops.o ../../cpu/musashi/m68kcpu.o
|
||||||
endif
|
endif
|
||||||
ifeq "$(use_cyclone)" "1"
|
ifeq "$(use_cyclone)" "1"
|
||||||
DEFINC += -DEMU_C68K
|
DEFINC += -DEMU_C68K
|
||||||
OBJS += ../../cpu/Cyclone/proj/Cyclone.o
|
OBJS += ../../cpu/Cyclone/proj/Cyclone.o ../../cpu/Cyclone/tools/idle.o
|
||||||
endif
|
endif
|
||||||
# drz80/mz80
|
# drz80/mz80
|
||||||
ifeq "$(mz80)" "1"
|
ifeq "$(mz80)" "1"
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
#include <zlib/zlib.h>
|
#include <zlib/zlib.h>
|
||||||
|
|
||||||
#ifndef _DIRENT_HAVE_D_TYPE
|
#ifndef _DIRENT_HAVE_D_TYPE
|
||||||
#error "need d_type for file browser
|
#error "need d_type for file browser"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern int mmuhack_status;
|
extern int mmuhack_status;
|
||||||
|
@ -67,7 +67,7 @@ static unsigned long wait_for_input(unsigned long interesting)
|
||||||
repeats = 0;
|
repeats = 0;
|
||||||
wait = 20;
|
wait = 20;
|
||||||
}
|
}
|
||||||
if (wait > 6 && (ret&(GP2X_UP|GP2X_LEFT|GP2X_DOWN|GP2X_RIGHT)))
|
if (wait > 6 && (ret&(GP2X_UP|GP2X_LEFT|GP2X_DOWN|GP2X_RIGHT|GP2X_L|GP2X_R)))
|
||||||
wait = 6;
|
wait = 6;
|
||||||
inp_prev = ret;
|
inp_prev = ret;
|
||||||
inp_prevjoy = 0;
|
inp_prevjoy = 0;
|
||||||
|
@ -1075,6 +1075,7 @@ menu_entry opt2_entries[] =
|
||||||
{ "craigix's RAM timings", MB_ONOFF, MA_OPT2_RAMTIMINGS, ¤tConfig.EmuOpt, 0x0100, 0, 0, 1, 1 },
|
{ "craigix's RAM timings", MB_ONOFF, MA_OPT2_RAMTIMINGS, ¤tConfig.EmuOpt, 0x0100, 0, 0, 1, 1 },
|
||||||
{ NULL, MB_ONOFF, MA_OPT2_SQUIDGEHACK, ¤tConfig.EmuOpt, 0x0010, 0, 0, 1, 1 },
|
{ NULL, MB_ONOFF, MA_OPT2_SQUIDGEHACK, ¤tConfig.EmuOpt, 0x0010, 0, 0, 1, 1 },
|
||||||
{ "SVP dynarec", MB_ONOFF, MA_OPT2_SVP_DYNAREC, &PicoOpt, 0x20000, 0, 0, 1, 1 },
|
{ "SVP dynarec", MB_ONOFF, MA_OPT2_SVP_DYNAREC, &PicoOpt, 0x20000, 0, 0, 1, 1 },
|
||||||
|
{ "Disable idle loop patching",MB_ONOFF, MA_OPT2_NO_IDLE_LOOPS, &PicoOpt, 0x80000, 0, 0, 1, 1 },
|
||||||
{ "done", MB_NONE, MA_OPT2_DONE, NULL, 0, 0, 0, 1, 0 },
|
{ "done", MB_NONE, MA_OPT2_DONE, NULL, 0, 0, 0, 1, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1428,7 +1429,7 @@ static int menu_loop_options(void)
|
||||||
|
|
||||||
static void draw_menu_credits(void)
|
static void draw_menu_credits(void)
|
||||||
{
|
{
|
||||||
int tl_x = 15, tl_y = 64, y;
|
int tl_x = 15, tl_y = 56, y;
|
||||||
gp2x_pd_clone_buffer2();
|
gp2x_pd_clone_buffer2();
|
||||||
|
|
||||||
text_out16(tl_x, 20, "PicoDrive v" VERSION " (c) notaz, 2006-2008");
|
text_out16(tl_x, 20, "PicoDrive v" VERSION " (c) notaz, 2006-2008");
|
||||||
|
@ -1438,17 +1439,19 @@ static void draw_menu_credits(void)
|
||||||
text_out16(tl_x, (y+=10), " base code of PicoDrive");
|
text_out16(tl_x, (y+=10), " base code of PicoDrive");
|
||||||
text_out16(tl_x, (y+=10), "Reesy & FluBBa: DrZ80 core");
|
text_out16(tl_x, (y+=10), "Reesy & FluBBa: DrZ80 core");
|
||||||
text_out16(tl_x, (y+=10), "MAME devs: YM2612 and SN76496 cores");
|
text_out16(tl_x, (y+=10), "MAME devs: YM2612 and SN76496 cores");
|
||||||
text_out16(tl_x, (y+=10), "Charles MacDonald: Genesis hw docs");
|
|
||||||
text_out16(tl_x, (y+=10), "Stephane Dallongeville:");
|
|
||||||
text_out16(tl_x, (y+=10), " opensource Gens");
|
|
||||||
text_out16(tl_x, (y+=10), "Haze: Genesis hw info");
|
|
||||||
text_out16(tl_x, (y+=10), "rlyeh and others: minimal SDK");
|
text_out16(tl_x, (y+=10), "rlyeh and others: minimal SDK");
|
||||||
text_out16(tl_x, (y+=10), "Squidge: squidgehack");
|
text_out16(tl_x, (y+=10), "Squidge: squidgehack");
|
||||||
text_out16(tl_x, (y+=10), "Dzz: ARM940 sample");
|
text_out16(tl_x, (y+=10), "Dzz: ARM940 sample");
|
||||||
text_out16(tl_x, (y+=10), "GnoStiC / Puck2099: USB joystick");
|
text_out16(tl_x, (y+=10), "GnoStiC / Puck2099: USB joy code");
|
||||||
text_out16(tl_x, (y+=10), "craigix: GP2X hardware");
|
text_out16(tl_x, (y+=10), "craigix: GP2X hardware");
|
||||||
text_out16(tl_x, (y+=10), "ketchupgun: skin design");
|
text_out16(tl_x, (y+=10), "ketchupgun: skin design");
|
||||||
|
|
||||||
|
text_out16(tl_x, (y+=20), "special thanks (for code, docs, ideas)");
|
||||||
|
text_out16(tl_x, (y+=10), " Charles MacDonald, Haze,");
|
||||||
|
text_out16(tl_x, (y+=10), " Stephane Dallongeville,");
|
||||||
|
text_out16(tl_x, (y+=10), " Lordus, Exophase, Rokas,");
|
||||||
|
text_out16(tl_x, (y+=10), " Nemesis, Tasco Deluxe");
|
||||||
|
|
||||||
menu_flip();
|
menu_flip();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
#define CAN_HANDLE_240_LINES 1
|
#define CAN_HANDLE_240_LINES 1
|
||||||
|
|
||||||
// logging emu events
|
// logging emu events
|
||||||
#define EL_LOGMASK EL_STATUS // (EL_STATUS|EL_ANOMALY|EL_UIO|EL_SRAMIO|EL_INTS|EL_CDPOLL) // xffff
|
#define EL_LOGMASK (EL_STATUS|EL_IDLE) // (EL_STATUS|EL_ANOMALY|EL_UIO|EL_SRAMIO|EL_INTS|EL_CDPOLL) // xffff
|
||||||
|
|
||||||
//#define dprintf(f,...) printf("%05i:%03i: " f "\n",Pico.m.frame_count,Pico.m.scanline,##__VA_ARGS__)
|
//#define dprintf(f,...) printf("%05i:%03i: " f "\n",Pico.m.frame_count,Pico.m.scanline,##__VA_ARGS__)
|
||||||
#define dprintf(x...)
|
#define dprintf(x...)
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
#define VERSION "1.45"
|
#define VERSION "1.50"
|
||||||
|
|
||||||
|
|
|
@ -82,7 +82,7 @@ static unsigned long wait_for_input(unsigned int interesting, int is_key_config)
|
||||||
|
|
||||||
if (!is_key_config)
|
if (!is_key_config)
|
||||||
ret |= (ret & 0xf0000000) >> 24; // use analog as d-pad
|
ret |= (ret & 0xf0000000) >> 24; // use analog as d-pad
|
||||||
if (wait > 6 && (ret&(BTN_UP|BTN_LEFT|BTN_DOWN|BTN_RIGHT)))
|
if (wait > 6 && (ret&(BTN_UP|BTN_LEFT|BTN_DOWN|BTN_RIGHT|BTN_L|BTN_R)))
|
||||||
wait = 6;
|
wait = 6;
|
||||||
|
|
||||||
// we don't need diagonals in menus
|
// we don't need diagonals in menus
|
||||||
|
@ -1512,13 +1512,15 @@ static void draw_menu_credits(void)
|
||||||
text_out16(tl_x, (y+=10), "Chui: Fame/C");
|
text_out16(tl_x, (y+=10), "Chui: Fame/C");
|
||||||
text_out16(tl_x, (y+=10), "NJ: CZ80");
|
text_out16(tl_x, (y+=10), "NJ: CZ80");
|
||||||
text_out16(tl_x, (y+=10), "MAME devs: YM2612 and SN76496 cores");
|
text_out16(tl_x, (y+=10), "MAME devs: YM2612 and SN76496 cores");
|
||||||
text_out16(tl_x, (y+=10), "Stephane Dallongeville:");
|
|
||||||
text_out16(tl_x, (y+=10), " Gens code, base of Fame/C, CZ80");
|
|
||||||
text_out16(tl_x, (y+=10), "Charles MacDonald: Genesis hw docs");
|
|
||||||
text_out16(tl_x, (y+=10), "Haze: Genesis hw info");
|
|
||||||
text_out16(tl_x, (y+=10), "ps2dev.org people: PSP SDK/code");
|
text_out16(tl_x, (y+=10), "ps2dev.org people: PSP SDK/code");
|
||||||
text_out16(tl_x, (y+=10), "ketchupgun: skin design");
|
text_out16(tl_x, (y+=10), "ketchupgun: skin design");
|
||||||
|
|
||||||
|
text_out16(tl_x, (y+=20), "special thanks (for code, docs, ideas):");
|
||||||
|
text_out16(tl_x, (y+=10), " Charles MacDonald, Haze,");
|
||||||
|
text_out16(tl_x, (y+=10), " Stephane Dallongeville,");
|
||||||
|
text_out16(tl_x, (y+=10), " Lordus, Exophase, Rokas,");
|
||||||
|
text_out16(tl_x, (y+=10), " Nemesis, Tasco Deluxe");
|
||||||
|
|
||||||
menu_draw_end();
|
menu_draw_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
#define VERSION "1.40b"
|
#define VERSION "1.50"
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue