From 053fd9b42f2cf38194f78e37c373363fc9cb9933 Mon Sep 17 00:00:00 2001 From: notaz Date: Sun, 29 Jun 2008 20:07:34 +0000 Subject: [PATCH] idle loop detection (Cyclone only, with debug stuff) git-svn-id: file:///home/notaz/opt/svn/PicoDrive@502 be3aeb3a-fb24-0410-a615-afba39da0efa --- Pico/Cart.c | 1 + Pico/Pico.c | 33 +++++-- Pico/Pico.h | 1 + Pico/PicoInt.h | 7 +- Pico/Sek.c | 125 +++++++++++++++++++++++++ cpu/Cyclone/tools/idle.h | 3 + cpu/Cyclone/tools/idle.s | 180 ++++++++++++++++++++++++++++++++++++ platform/base_readme.txt | 3 +- platform/common/emu.c | 2 - platform/common/menu.h | 1 + platform/gizmondo/menu.c | 14 +-- platform/gp2x/Makefile | 2 +- platform/gp2x/menu.c | 19 ++-- platform/gp2x/port_config.h | 2 +- platform/gp2x/version.h | 2 +- platform/psp/menu.c | 12 ++- platform/psp/version.h | 2 +- 17 files changed, 372 insertions(+), 37 deletions(-) create mode 100644 cpu/Cyclone/tools/idle.h create mode 100644 cpu/Cyclone/tools/idle.s diff --git a/Pico/Cart.c b/Pico/Cart.c index a0d38a0..e65b509 100644 --- a/Pico/Cart.c +++ b/Pico/Cart.c @@ -548,6 +548,7 @@ int PicoCartInsert(unsigned char *rom,unsigned int romsize) int PicoCartUnload(void) { if (Pico.rom != NULL) { + SekFinishIdleDet(); free(Pico.rom); Pico.rom=NULL; } diff --git a/Pico/Pico.c b/Pico/Pico.c index 9fe97bf..a7930fc 100644 --- a/Pico/Pico.c +++ b/Pico/Pico.c @@ -58,6 +58,8 @@ void PicoPower(void) { unsigned char sram_reg=Pico.m.sram_reg; // must be preserved + Pico.m.frame_count = 0; + // clear all memory of the emulated machine memset(&Pico.ram,0,(unsigned int)&Pico.rom-(unsigned int)&Pico.ram); @@ -172,6 +174,12 @@ int PicoReset(void) PicoResetMCD(); 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 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) // 96 is VR hack static const int dma_timings[] = { -96, 167, 166, 83, // vblank: 32cell: dma2vram dma2[vs|c]ram vram_fill vram_copy -102, 205, 204, 102, // vblank: 40cell: -16, 16, 15, 8, // active: 32cell: -24, 18, 17, 9 // ... + 96, 167, 166, 83, // vblank: 32cell: dma2vram dma2[vs|c]ram vram_fill vram_copy + 102, 205, 204, 102, // vblank: 40cell: + 16, 16, 15, 8, // active: 32cell: + 24, 18, 17, 9 // ... }; static const int dma_bsycles[] = { -(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)/16, (488<<8)/16, (488<<8)/15, (488<<8)/8, -(488<<8)/24, (488<<8)/18, (488<<8)/17, (488<<8)/9 + (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)/16, (488<<8)/16, (488<<8)/15, (488<<8)/8, + (488<<8)/24, (488<<8)/18, (488<<8)/17, (488<<8)/9 }; PICO_INTERNAL int CheckDMA(void) @@ -232,7 +240,7 @@ static __inline void SekRunM68k(int cyc) { int cyc_do; SekCycleAim+=cyc; - if((cyc_do=SekCycleAim-SekCycleCnt) <= 0) return; + if ((cyc_do=SekCycleAim-SekCycleCnt) <= 0) return; #if defined(EMU_CORE_DEBUG) // this means we do run-compare SekCycleCnt+=CM_compareRun(cyc_do, 0); @@ -498,10 +506,17 @@ static int PicoFrameSimple(void) return 0; } +int idle_hit_counter = 0; + int PicoFrame(void) { 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++; if (PicoAHW & PAHW_MCD) { diff --git a/Pico/Pico.h b/Pico/Pico.h index 8caf109..7e2ec69 100644 --- a/Pico/Pico.h +++ b/Pico/Pico.h @@ -47,6 +47,7 @@ void mp3_update(int *buffer, int length, int stereo); #define POPT_DIS_VDP_FIFO (1<<16) // 0x 0000 #define POPT_EN_SVP_DRC (1<<17) #define POPT_DIS_SPRITE_LIM (1<<18) +#define POPT_DIS_IDLE_DET (1<<19) extern int PicoOpt; // bitfield #define PAHW_MCD (1<<0) #define PAHW_32X (1<<1) diff --git a/Pico/PicoInt.h b/Pico/PicoInt.h index 4ac115f..bd9122a 100644 --- a/Pico/PicoInt.h +++ b/Pico/PicoInt.h @@ -259,9 +259,9 @@ struct PicoMisc unsigned char eeprom_cycle; // EEPROM SRAM cycle number unsigned char eeprom_slave; // EEPROM slave word for X24C02 and better SRAMs unsigned char prot_bytes[2]; // simple protection faking - unsigned short dma_xfers; + unsigned short dma_xfers; // 18 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! @@ -461,6 +461,8 @@ PICO_INTERNAL int SekInit(void); PICO_INTERNAL int SekReset(void); PICO_INTERNAL void SekState(int *data); PICO_INTERNAL void SekSetRealTAS(int use_real); +void SekInitIdleDet(void); +void SekFinishIdleDet(void); // cd/Sek.c PICO_INTERNAL int SekInitS68k(void); @@ -557,6 +559,7 @@ extern int PsndDacLine; #define EL_CDPOLL 0x00002000 /* MCD: log poll detection */ #define EL_SVP 0x00004000 /* SVP stuff */ #define EL_PICOHW 0x00008000 /* Pico stuff */ +#define EL_IDLE 0x00010000 /* idle loop det. */ #define EL_STATUS 0x40000000 /* status messages */ #define EL_ANOMALY 0x80000000 /* some unexpected conditions (during emulation) */ diff --git a/Pico/Sek.c b/Pico/Sek.c index ac12580..001faea 100644 --- a/Pico/Sek.c +++ b/Pico/Sek.c @@ -193,6 +193,131 @@ PICO_INTERNAL void SekSetRealTAS(int use_real) #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 static unsigned char op_flags[0x400000/2] = { 0, }; static int atexit_set = 0; diff --git a/cpu/Cyclone/tools/idle.h b/cpu/Cyclone/tools/idle.h new file mode 100644 index 0000000..254cc57 --- /dev/null +++ b/cpu/Cyclone/tools/idle.h @@ -0,0 +1,3 @@ + +void CycloneInitIdle(void); +void CycloneFinishIdle(void); diff --git a/cpu/Cyclone/tools/idle.s b/cpu/Cyclone/tools/idle.s new file mode 100644 index 0000000..81630b8 --- /dev/null +++ b/cpu/Cyclone/tools/idle.s @@ -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 + diff --git a/platform/base_readme.txt b/platform/base_readme.txt index 6561c9b..6c8e528 100644 --- a/platform/base_readme.txt +++ b/platform/base_readme.txt @@ -621,6 +621,8 @@ Additional thanks * Tasco Deluxe for his reverse engineering work on SVP and some mappers. * Bart Trzynadlowski for his SSFII and 68000 docs. * 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. * ketchupgun for the skin. #ifdef GP2X @@ -632,7 +634,6 @@ Additional thanks * A_SN for his gamma code. * craigix for supplying the GP2X hardware and making this port possible. * Alex for the icon. -* Exophase, Rokas and Lordus for various ideas. * All the people from gp32x boards for their support. #endif #ifdef GIZ diff --git a/platform/common/emu.c b/platform/common/emu.c index 0b8fdf7..fabd521 100644 --- a/platform/common/emu.c +++ b/platform/common/emu.c @@ -427,8 +427,6 @@ int emu_ReloadRom(void) return 0; } - Pico.m.frame_count = 0; - // insert CD if it was detected if (cd_state != CIT_NOT_CD) { ret = Insert_CD(romFileName, cd_state); diff --git a/platform/common/menu.h b/platform/common/menu.h index 6ecc191..bfa05c4 100644 --- a/platform/common/menu.h +++ b/platform/common/menu.h @@ -66,6 +66,7 @@ typedef enum MA_OPT2_NO_FRAME_LIMIT, /* psp */ MA_OPT2_SVP_DYNAREC, MA_OPT2_NO_SPRITE_LIM, + MA_OPT2_NO_IDLE_LOOPS, MA_OPT2_DONE, MA_OPT3_SCALE, /* psp (all OPT3) */ MA_OPT3_HSCALE32, diff --git a/platform/gizmondo/menu.c b/platform/gizmondo/menu.c index 9e1994d..3b9e55e 100644 --- a/platform/gizmondo/menu.c +++ b/platform/gizmondo/menu.c @@ -70,7 +70,7 @@ static unsigned long wait_for_input(unsigned int interesting) repeats = 0; 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; inp_prev = ret; @@ -1315,7 +1315,7 @@ static int menu_loop_options(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); 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), "Reesy & FluBBa: DrZ80 core"); 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), "jens.l: gizmondo hardware"); 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(); } diff --git a/platform/gp2x/Makefile b/platform/gp2x/Makefile index 4ebecb4..1066a85 100644 --- a/platform/gp2x/Makefile +++ b/platform/gp2x/Makefile @@ -128,7 +128,7 @@ OBJS += ../../cpu/musashi/m68kops.o ../../cpu/musashi/m68kcpu.o endif ifeq "$(use_cyclone)" "1" DEFINC += -DEMU_C68K -OBJS += ../../cpu/Cyclone/proj/Cyclone.o +OBJS += ../../cpu/Cyclone/proj/Cyclone.o ../../cpu/Cyclone/tools/idle.o endif # drz80/mz80 ifeq "$(mz80)" "1" diff --git a/platform/gp2x/menu.c b/platform/gp2x/menu.c index db4c9fa..8ec98aa 100644 --- a/platform/gp2x/menu.c +++ b/platform/gp2x/menu.c @@ -25,7 +25,7 @@ #include #ifndef _DIRENT_HAVE_D_TYPE -#error "need d_type for file browser +#error "need d_type for file browser" #endif extern int mmuhack_status; @@ -67,7 +67,7 @@ static unsigned long wait_for_input(unsigned long interesting) repeats = 0; 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; inp_prev = ret; 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 }, { 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 }, + { "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 }, }; @@ -1428,7 +1429,7 @@ static int menu_loop_options(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(); 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), "Reesy & FluBBa: DrZ80 core"); 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), "Squidge: squidgehack"); 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), "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(); } diff --git a/platform/gp2x/port_config.h b/platform/gp2x/port_config.h index fe0fcea..22b43cd 100644 --- a/platform/gp2x/port_config.h +++ b/platform/gp2x/port_config.h @@ -19,7 +19,7 @@ #define CAN_HANDLE_240_LINES 1 // 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(x...) diff --git a/platform/gp2x/version.h b/platform/gp2x/version.h index 580a8ae..d4bd447 100644 --- a/platform/gp2x/version.h +++ b/platform/gp2x/version.h @@ -1,2 +1,2 @@ -#define VERSION "1.45" +#define VERSION "1.50" diff --git a/platform/psp/menu.c b/platform/psp/menu.c index 85669ae..44c7c66 100644 --- a/platform/psp/menu.c +++ b/platform/psp/menu.c @@ -82,7 +82,7 @@ static unsigned long wait_for_input(unsigned int interesting, int is_key_config) if (!is_key_config) 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; // 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), "NJ: CZ80"); 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), "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(); } diff --git a/platform/psp/version.h b/platform/psp/version.h index 9b9d909..d4bd447 100644 --- a/platform/psp/version.h +++ b/platform/psp/version.h @@ -1,2 +1,2 @@ -#define VERSION "1.40b" +#define VERSION "1.50" -- 2.39.2