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:
notaz 2008-06-29 20:07:34 +00:00
parent d95259bdaa
commit 053fd9b42f
17 changed files with 372 additions and 37 deletions

View file

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

View file

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

View file

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

View file

@ -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) */

View file

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

@ -0,0 +1,3 @@
void CycloneInitIdle(void);
void CycloneFinishIdle(void);

180
cpu/Cyclone/tools/idle.s Normal file
View 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

View file

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

View file

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

View file

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

View file

@ -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();
} }

View file

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

View file

@ -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, &currentConfig.EmuOpt, 0x0100, 0, 0, 1, 1 }, { "craigix's RAM timings", MB_ONOFF, MA_OPT2_RAMTIMINGS, &currentConfig.EmuOpt, 0x0100, 0, 0, 1, 1 },
{ NULL, MB_ONOFF, MA_OPT2_SQUIDGEHACK, &currentConfig.EmuOpt, 0x0010, 0, 0, 1, 1 }, { NULL, MB_ONOFF, MA_OPT2_SQUIDGEHACK, &currentConfig.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();
} }

View file

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

View file

@ -1,2 +1,2 @@
#define VERSION "1.45" #define VERSION "1.50"

View file

@ -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();
} }

View file

@ -1,2 +1,2 @@
#define VERSION "1.40b" #define VERSION "1.50"