From f8af96349ea464111fbef3c6528016c3dc34cdcf Mon Sep 17 00:00:00 2001 From: notaz Date: Sun, 24 Aug 2008 09:33:12 +0000 Subject: [PATCH] UIQ3 bugfixes, SVP drc indirect jumps, stuff git-svn-id: file:///home/notaz/opt/svn/PicoDrive@572 be3aeb3a-fb24-0410-a615-afba39da0efa --- Pico/Cart.c | 15 ++++++--- Pico/Debug.c | 2 +- Pico/Draw.c | 20 ++++++------ Pico/Memory.c | 5 +-- Pico/Pico.h | 2 +- Pico/PicoInt.h | 8 ++--- Pico/carthw/svp/compiler.c | 27 +++++++++++----- Pico/carthw/svp/gen_arm.c | 44 +++++++++++++++++++------- Pico/carthw/svp/stub_arm.S | 4 +-- Pico/cd/cue.c | 2 +- platform/base_readme.txt | 4 ++- platform/common/config.c | 2 +- platform/common/emu.c | 23 ++++++++------ platform/gp2x/PicoDrive.man.txt | 2 +- platform/gp2x/emu.c | 11 ++----- platform/linux/port_config.h | 6 ++++ platform/pandora/emu.c | 10 ++---- platform/psp/emu.c | 4 +-- platform/uiq3/App.cpp | 21 +++++-------- platform/uiq3/Engine.cpp | 14 +++------ platform/uiq3/Engine.h | 7 ++--- platform/uiq3/Makefile | 22 ++++++++++--- platform/uiq3/emu.c | 3 +- platform/uiq3/engine/debug.cpp | 2 +- platform/uiq3/engine/debug.h | 2 +- platform/uiq3/engine/main.cpp | 55 +++++++++++++++++++-------------- platform/uiq3/engine/vid.cpp | 26 +++++----------- platform/uiq3/port_config.h | 2 +- platform/uiq3/uiq3.mak | 5 ++- 29 files changed, 193 insertions(+), 157 deletions(-) diff --git a/Pico/Cart.c b/Pico/Cart.c index de340a1..c07bfda 100644 --- a/Pico/Cart.c +++ b/Pico/Cart.c @@ -137,8 +137,10 @@ zip_failed: if (f == NULL) goto cso_failed; +#ifndef __EPOC32__ /* we use our own buffering */ setvbuf(f, NULL, _IONBF, 0); +#endif cso = malloc(sizeof(*cso)); if (cso == NULL) @@ -192,9 +194,6 @@ cso_failed: f = fopen(path, "rb"); if (f == NULL) return NULL; - /* we use our own buffering */ - setvbuf(f, NULL, _IONBF, 0); - file = malloc(sizeof(*file)); if (file == NULL) { fclose(f); @@ -207,6 +206,12 @@ cso_failed: file->type = PMT_UNCOMPRESSED; fseek(f, 0, SEEK_SET); +#ifndef __EPOC32__ // makes things worse on Symbian + if (file->size > 0x400000) + /* we use our own buffering */ + setvbuf(f, NULL, _IONBF, 0); +#endif + return file; } @@ -445,7 +450,7 @@ int PicoCartLoad(pm_file *f,unsigned char **prom,unsigned int *psize) rom=PicoCartAlloc(size); if (rom==NULL) { elprintf(EL_STATUS, "out of memory (wanted %i)", size); - return 1; + return 2; } if (PicoCartLoadProgressCB != NULL) @@ -470,7 +475,7 @@ int PicoCartLoad(pm_file *f,unsigned char **prom,unsigned int *psize) if (bytes_read <= 0) { elprintf(EL_STATUS, "read failed"); free(rom); - return 1; + return 3; } // maybe we are loading MegaCD BIOS? diff --git a/Pico/Debug.c b/Pico/Debug.c index 50bd2e5..b2efa4d 100644 --- a/Pico/Debug.c +++ b/Pico/Debug.c @@ -53,7 +53,7 @@ char *PDebugMain(void) sprintf(dstrp, "z80Run: %i, z80_reset: %i, z80_bnk: %06x\n", Pico.m.z80Run, Pico.m.z80_reset, Pico.m.z80_bank68k<<15); MVP; z80_debug(dstrp); MVP; if (strlen(dstr) > sizeof(dstr)) - printf("warning: debug buffer overflow (%i/%i)\n", strlen(dstr), sizeof(dstr)); + elprintf(EL_STATUS, "warning: debug buffer overflow (%i/%i)\n", strlen(dstr), sizeof(dstr)); return dstr; } diff --git a/Pico/Draw.c b/Pico/Draw.c index 7dadb4b..215e9ec 100644 --- a/Pico/Draw.c +++ b/Pico/Draw.c @@ -839,7 +839,7 @@ static void DrawSpritesSHi(unsigned char *sprited) } } } -#endif +#endif // !_ASM_DRAW_C static void DrawSpritesHiAS(unsigned char *sprited, int sh) { @@ -850,6 +850,8 @@ static void DrawSpritesHiAS(unsigned char *sprited, int sh) cnt = sprited[0] & 0x7f; if (cnt == 0) return; + rendstatus |= PDRAW_SPR_LO_ON_HI; + p = &sprited[3]; // Go through sprites: @@ -1200,7 +1202,7 @@ static void FinalizeLineBGR444(int sh) } } - if (!sh && (rendstatus & PDRAW_ACC_SPRITES)) + if (!sh && (rendstatus & PDRAW_SPR_LO_ON_HI)) mask=0x3f; // accurate sprites for(i = 0; i < len; i++) @@ -1228,7 +1230,7 @@ static void FinalizeLineRGB555(int sh) { #ifndef PSP int i, mask=0xff; - if (!sh && (rendstatus & PDRAW_ACC_SPRITES)) + if (!sh && (rendstatus & PDRAW_SPR_LO_ON_HI)) mask=0x3f; // accurate sprites, upper bits are priority stuff for (i = 0; i < len; i++) @@ -1236,7 +1238,7 @@ static void FinalizeLineRGB555(int sh) #else extern void amips_clut(unsigned short *dst, unsigned char *src, unsigned short *pal, int count); extern void amips_clut_6bit(unsigned short *dst, unsigned char *src, unsigned short *pal, int count); - if (!sh && (rendstatus & PDRAW_ACC_SPRITES)) + if (!sh && (rendstatus & PDRAW_SPR_LO_ON_HI)) amips_clut_6bit(pd, ps, pal, len); else amips_clut(pd, ps, pal, len); #endif @@ -1250,7 +1252,7 @@ static void FinalizeLine8bit(int sh) int len, rs = rendstatus; static int dirty_count; - if (!sh && !(rs & PDRAW_ACC_SPRITES) && Pico.m.dirtyPal == 1 && DrawScanline < 222) + if (!sh && Pico.m.dirtyPal == 1 && DrawScanline < 222) { // a hack for mid-frame palette changes if (!(rs & PDRAW_SONIC_MODE)) @@ -1374,8 +1376,8 @@ static int DrawDisplay(int sh) if (!(PicoDrawMask & PDRAW_SPRITES_HI_ON)); else if (rendstatus & PDRAW_INTERLACE) DrawAllSpritesInterlace(1, sh); - // AS on and have both lo/hi sprites and lo before hi sprites? - else if ((sprited[1] & 0xd0) == 0xd0 && (rendstatus & PDRAW_ACC_SPRITES)) + // have sprites without layer pri bit ontop of sprites with that bit + else if ((sprited[1] & 0xd0) == 0xd0 && (PicoOpt & POPT_ACC_SPRITES)) DrawSpritesHiAS(sprited, sh); else if (sh && (sprited[1] & SPRL_MAY_HAVE_OP)) DrawSpritesSHi(sprited); @@ -1394,13 +1396,11 @@ static int DrawDisplay(int sh) return 0; } - +// MUST be called every frame PICO_INTERNAL void PicoFrameStart(void) { // prepare to do this frame rendstatus = 0; - if (PicoOpt & POPT_ACC_SPRITES) - rendstatus |= PDRAW_ACC_SPRITES; if ((Pico.video.reg[12]&6) == 6) rendstatus |= PDRAW_INTERLACE; // interlace mode diff --git a/Pico/Memory.c b/Pico/Memory.c index bdcfaab..8975fa2 100644 --- a/Pico/Memory.c +++ b/Pico/Memory.c @@ -76,8 +76,9 @@ PICO_INTERNAL u32 PicoCheckPc(u32 pc) pc&=~1; if ((pc<<8) == 0) { - printf("%i:%03i: game crash detected @ %06x\n", Pico.m.frame_count, Pico.m.scanline, SekPc); - return (int)Pico.rom + Pico.romsize; // common crash condition, can happen if acc timing is off + elprintf(EL_STATUS|EL_ANOMALY, "%i:%03i: game crash detected @ %06x\n", + Pico.m.frame_count, Pico.m.scanline, SekPc); + return (int)Pico.rom + Pico.romsize; // common crash condition, may happen with bad ROMs } PicoCpuCM68k.membase=PicoMemBase(pc&0x00ffffff); diff --git a/Pico/Pico.h b/Pico/Pico.h index ff86b1e..fb067b8 100644 --- a/Pico/Pico.h +++ b/Pico/Pico.h @@ -172,7 +172,7 @@ extern int PicoDrawMask; // internals #define PDRAW_SPRITES_MOVED (1<<0) // (asm) #define PDRAW_WND_DIFF_PRIO (1<<1) // not all window tiles use same priority -#define PDRAW_ACC_SPRITES (1<<2) // accurate sprites (copied from PicoOpt) +#define PDRAW_SPR_LO_ON_HI (1<<2) // seen sprites without layer pri bit ontop spr. with that bit #define PDRAW_INTERLACE (1<<3) #define PDRAW_DIRTY_SPRITES (1<<4) // (asm) #define PDRAW_SONIC_MODE (1<<5) // mid-frame palette changes for 8bit renderer diff --git a/Pico/PicoInt.h b/Pico/PicoInt.h index 7d4b06f..d0fc25c 100644 --- a/Pico/PicoInt.h +++ b/Pico/PicoInt.h @@ -541,10 +541,6 @@ PICO_INTERNAL void z80_reset(void); PICO_INTERNAL void z80_exit(void); extern int PsndDacLine; -#ifdef __cplusplus -} // End of extern "C" -#endif - // emulation event logging #ifndef EL_LOGMASK #define EL_LOGMASK 0 @@ -590,5 +586,9 @@ extern void lprintf(const char *fmt, ...); #define cdprintf(x...) #endif +#ifdef __cplusplus +} // End of extern "C" +#endif + #endif // PICO_INTERNAL_INCLUDED diff --git a/Pico/carthw/svp/compiler.c b/Pico/carthw/svp/compiler.c index 1ce44ab..d163eb4 100644 --- a/Pico/carthw/svp/compiler.c +++ b/Pico/carthw/svp/compiler.c @@ -1663,7 +1663,7 @@ static void emit_block_prologue(void) // check if there are enough cycles.. // note: r0 must contain PC of current block EOP_CMP_IMM(11,0,0); // cmp r11, #0 - emit_call(A_COND_LE, ssp_drc_end); + emit_jump(A_COND_LE, ssp_drc_end); } /* cond: @@ -1684,20 +1684,29 @@ static void emit_block_epilogue(int cycles, int cond, int pc, int end_pc) if (target != NULL) emit_jump(A_COND_AL, target); else { - emit_jump(A_COND_AL, ssp_drc_next); - // cause the next block to be emitted over jump instrction - tcache_ptr--; + int ops = emit_jump(A_COND_AL, ssp_drc_next); + // cause the next block to be emitted over jump instruction + tcache_ptr -= ops; } } else { - u32 *target1 = (pc < 0x400) ? ssp_block_table_iram[ssp->drc.iram_context][pc] : ssp_block_table[pc]; + u32 *target1 = (pc < 0x400) ? ssp_block_table_iram[ssp->drc.iram_context][pc] : ssp_block_table[pc]; u32 *target2 = (end_pc < 0x400) ? ssp_block_table_iram[ssp->drc.iram_context][end_pc] : ssp_block_table[end_pc]; if (target1 != NULL) emit_jump(cond, target1); - else emit_call(cond, ssp_drc_next_patch); if (target2 != NULL) emit_jump(tr_neg_cond(cond), target2); // neg_cond, to be able to swap jumps if needed - else emit_call(tr_neg_cond(cond), ssp_drc_next_patch); +#ifndef __EPOC32__ + // emit patchable branches + if (target1 == NULL) + emit_call(cond, ssp_drc_next_patch); + if (target2 == NULL) + emit_call(tr_neg_cond(cond), ssp_drc_next_patch); +#else + // won't patch indirect jumps + if (target1 == NULL || target2 == NULL) + emit_jump(A_COND_AL, ssp_drc_next); +#endif } } @@ -1708,6 +1717,7 @@ void *ssp_translate_block(int pc) int ret, end_cond = A_COND_AL, jump_pc = -1; //printf("translate %04x -> %04x\n", pc<<1, (tcache_ptr-tcache)<<2); + block_start = tcache_ptr; known_regb = 0; dirty_regb = KRREG_P; @@ -1748,7 +1758,7 @@ void *ssp_translate_block(int pc) emit_block_epilogue(ccount, end_cond, jump_pc, pc); if (tcache_ptr - tcache > SSP_TCACHE_SIZE/4) { - elprintf(EL_ANOMALY, "tcache overflow!\n"); + elprintf(EL_ANOMALY|EL_STATUS|EL_SVP, "tcache overflow!\n"); fflush(stdout); exit(1); } @@ -1825,6 +1835,7 @@ void ssp1601_dyn_reset(ssp1601_t *ssp) memset(svp->iram_rom, 0, 0x800); } + void ssp1601_dyn_run(int cycles) { if (ssp->emu_status & SSP_WAIT_MASK) return; diff --git a/Pico/carthw/svp/gen_arm.c b/Pico/carthw/svp/gen_arm.c index 46be2db..56018a7 100644 --- a/Pico/carthw/svp/gen_arm.c +++ b/Pico/carthw/svp/gen_arm.c @@ -178,27 +178,49 @@ static void emit_mov_const(int cond, int d, unsigned int val) EOP_C_DOP_IMM(cond, need_or ? A_OP_ORR : A_OP_MOV, 0, need_or ? d : 0, d, 0, val&0xff); } -static void check_offset_24(int val) +static int is_offset_24(int val) { - if (val >= (int)0xff000000 && val <= 0x00ffffff) return; - printf("offset_24 overflow %08x\n", val); - exit(1); + if (val >= (int)0xff000000 && val <= 0x00ffffff) return 1; + return 0; } -static void emit_call(int cond, void *target) +static int emit_xbranch(int cond, void *target, int is_call) { int val = (unsigned int *)target - tcache_ptr - 2; - check_offset_24(val); + int direct = is_offset_24(val); + u32 *start_ptr = tcache_ptr; - EOP_C_B(cond,1,val & 0xffffff); // bl target + if (direct) + { + EOP_C_B(cond,is_call,val & 0xffffff); // b, bl target + } + else + { +#ifdef __EPOC32__ +// elprintf(EL_SVP, "emitting indirect jmp %08x->%08x", tcache_ptr, target); + if (is_call) + EOP_ADD_IMM(14,15,0,8); // add lr,pc,#8 + EOP_C_AM2_IMM(cond,1,0,1,15,15,0); // ldrcc pc,[pc] + EOP_MOV_REG_SIMPLE(15,15); // mov pc, pc + EMIT((u32)target); +#else + // should never happen + elprintf(EL_STATUS|EL_SVP|EL_ANOMALY, "indirect jmp %08x->%08x", target, tcache_ptr); + exit(1); +#endif + } + + return tcache_ptr - start_ptr; } -static void emit_jump(int cond, void *target) +static int emit_call(int cond, void *target) { - int val = (unsigned int *)target - tcache_ptr - 2; - check_offset_24(val); + return emit_xbranch(cond, target, 1); +} - EOP_C_B(cond,0,val & 0xffffff); // b target +static int emit_jump(int cond, void *target) +{ + return emit_xbranch(cond, target, 0); } static void handle_caches(void) diff --git a/Pico/carthw/svp/stub_arm.S b/Pico/carthw/svp/stub_arm.S index 744057a..cd2daae 100644 --- a/Pico/carthw/svp/stub_arm.S +++ b/Pico/carthw/svp/stub_arm.S @@ -40,7 +40,6 @@ ssp_block_table_iram: .space SSP_BLOCKTAB_IRAM_SIZE .space SSP_BLOCKTAB_ALIGN_SIZE - .text .align 2 @@ -59,6 +58,7 @@ ssp_block_table_iram: @ r9: r4-r6 (.654) @ r10: P @ r11: cycles +@ r12: tmp #define SSP_OFFS_GR 0x400 @@ -207,7 +207,7 @@ ssp_drc_do_patch: bic r3, r3, #1 @ L bit orr r3, r3, r12,lsl #6 mov r3, r3, ror #8 @ patched branch instruction - str r3, [r1, #-4] + str r3, [r1, #-4] @ patch the bl/b to jump directly to another handler ssp_drc_dp_end: str r2, [r7, #SSP_OFFS_TMP1] diff --git a/Pico/cd/cue.c b/Pico/cd/cue.c index d02062c..9d0b498 100644 --- a/Pico/cd/cue.c +++ b/Pico/cd/cue.c @@ -9,7 +9,7 @@ #ifdef _MSC_VER #define snprintf _snprintf #endif -#ifdef UIQ3 +#ifdef __EPOC32__ #define snprintf(b,s,...) sprintf(b,##__VA_ARGS__) #endif diff --git a/platform/base_readme.txt b/platform/base_readme.txt index c0969bf..abd6a10 100644 --- a/platform/base_readme.txt +++ b/platform/base_readme.txt @@ -402,7 +402,7 @@ test your BIOS. The Sega/Mega CD unit had two blinking LEDs (red and green) on it. This option will display them on top-left corner of the screen. -@@2. "CDDA audio (using mp3s)" +@@2. "CDDA audio" This option enables CD audio playback. @@2. "PCM audio" @@ -497,6 +497,7 @@ both buttons for that action to happen). There is also option to enable 6 button pad (will allow you to configure XYZ keys), and an option to set turbo rate (in Hz) for turbo buttons. #endif +#ifndef UIQ Cheat support @@ -535,6 +536,7 @@ PATCH FILE: Sonic 2.bin.pat Put the file into your ROMs directory. Then load the .pat file as you would a ROM. Then Cheat Menu Option should appear in main menu. +#endif What is emulated? diff --git a/platform/common/config.c b/platform/common/config.c index f8fe5d0..a621893 100644 --- a/platform/common/config.c +++ b/platform/common/config.c @@ -6,7 +6,7 @@ #include #include #include -#ifdef UIQ3 +#ifdef __EPOC32__ #include #endif #include "config.h" diff --git a/platform/common/emu.c b/platform/common/emu.c index 7dbac50..eaabe08 100644 --- a/platform/common/emu.c +++ b/platform/common/emu.c @@ -44,9 +44,11 @@ extern void menu_romload_end(void); // utilities -static void strlwr_(char* string) +static void strlwr_(char *string) { - while ( (*string++ = (char)tolower(*string)) ); + char *p; + for (p = string; *p; p++) + *p = (char)tolower(*p); } static int try_rfn_cut(char *fname) @@ -345,6 +347,7 @@ int emu_ReloadRom(char *rom_fname) return 0; } get_ext(rom_fname, ext); + lprintf("gmv loaded for %s\n", rom_fname); } else if (!strcmp(ext, ".pat")) { @@ -407,7 +410,9 @@ int emu_ReloadRom(char *rom_fname) rom_loaded = 0; if ( (ret = PicoCartLoad(rom, &rom_data, &rom_size)) ) { - sprintf(menuErrorMsg, "PicoCartLoad() failed."); + if (ret == 2) sprintf(menuErrorMsg, "Out of memory"); + else if (ret == 3) sprintf(menuErrorMsg, "Read failed"); + else sprintf(menuErrorMsg, "PicoCartLoad() failed."); lprintf("%s\n", menuErrorMsg); goto fail2; } @@ -774,13 +779,13 @@ void emu_updateMovie(void) } else { // MXYZ SACB RLDU PicoPad[0] = ~movie_data[offs] & 0x8f; // ! SCBA RLDU - if(!(movie_data[offs] & 0x10)) PicoPad[0] |= 0x40; // A - if(!(movie_data[offs] & 0x20)) PicoPad[0] |= 0x10; // B - if(!(movie_data[offs] & 0x40)) PicoPad[0] |= 0x20; // A + if(!(movie_data[offs] & 0x10)) PicoPad[0] |= 0x40; // C + if(!(movie_data[offs] & 0x20)) PicoPad[0] |= 0x10; // A + if(!(movie_data[offs] & 0x40)) PicoPad[0] |= 0x20; // B PicoPad[1] = ~movie_data[offs+1] & 0x8f; // ! SCBA RLDU - if(!(movie_data[offs+1] & 0x10)) PicoPad[1] |= 0x40; // A - if(!(movie_data[offs+1] & 0x20)) PicoPad[1] |= 0x10; // B - if(!(movie_data[offs+1] & 0x40)) PicoPad[1] |= 0x20; // A + if(!(movie_data[offs+1] & 0x10)) PicoPad[1] |= 0x40; // C + if(!(movie_data[offs+1] & 0x20)) PicoPad[1] |= 0x10; // A + if(!(movie_data[offs+1] & 0x40)) PicoPad[1] |= 0x20; // B PicoPad[0] |= (~movie_data[offs+2] & 0x0A) << 8; // ! MZYX if(!(movie_data[offs+2] & 0x01)) PicoPad[0] |= 0x0400; // X if(!(movie_data[offs+2] & 0x04)) PicoPad[0] |= 0x0100; // Z diff --git a/platform/gp2x/PicoDrive.man.txt b/platform/gp2x/PicoDrive.man.txt index b13dab9..f7768b5 100644 --- a/platform/gp2x/PicoDrive.man.txt +++ b/platform/gp2x/PicoDrive.man.txt @@ -152,7 +152,7 @@ These options just show if your BIOS files were correctly detected by the emulat 4. "CD LEDs" The Sega/Mega CD unit had two blinking LEDs (red and green) on it. This option will display them on top-left corner of the screen. -5. "CDDA audio (using mp3s)" +5. "CDDA audio" This option enables CD audio playback. 6. "PCM audio" diff --git a/platform/gp2x/emu.c b/platform/gp2x/emu.c index c225f18..dc78521 100644 --- a/platform/gp2x/emu.c +++ b/platform/gp2x/emu.c @@ -283,7 +283,7 @@ static void blit(const char *fps, const char *notice) // 8bit accurate renderer if (Pico.m.dirtyPal) { - int pallen = 0x40; + int pallen = 0xc0; Pico.m.dirtyPal = 0; if (Pico.video.reg[0xC]&8) // shadow/hilight mode { @@ -293,21 +293,14 @@ static void blit(const char *fps, const char *notice) memcpy32(localPal+0xc0, localPal+0x40, 0x40); pallen = 0x100; } - else if (rendstatus & PDRAW_ACC_SPRITES) { - vidConvCpyRGB32(localPal, Pico.cram, 0x40); - memcpy32(localPal+0x40, localPal, 0x40); - memcpy32(localPal+0x80, localPal, 0x40); - memcpy32(localPal+0xc0, localPal, 0x40); - pallen = 0x100; - } else if (rendstatus & PDRAW_SONIC_MODE) { // mid-frame palette changes vidConvCpyRGB32(localPal, Pico.cram, 0x40); vidConvCpyRGB32(localPal+0x40, HighPal, 0x40); vidConvCpyRGB32(localPal+0x80, HighPal+0x40, 0x40); - pallen = 0xc0; } else { vidConvCpyRGB32(localPal, Pico.cram, 0x40); + memcpy32(localPal+0x80, localPal, 0x40); // for spr prio mess } if (pallen > 0xc0) { localPal[0xc0] = 0x0000c000; diff --git a/platform/linux/port_config.h b/platform/linux/port_config.h index 87bbe4b..b781da7 100644 --- a/platform/linux/port_config.h +++ b/platform/linux/port_config.h @@ -29,5 +29,11 @@ //#define dprintf(f,...) printf("%05i:%03i: " f "\n",Pico.m.frame_count,Pico.m.scanline,##__VA_ARGS__) #define dprintf(x...) +// platform +#define PLAT_MAX_KEYS 32 +#define PLAT_HAVE_JOY 1 +#define PATH_SEP "/" +#define PATH_SEP_C '/' + #endif //PORT_CONFIG_H diff --git a/platform/pandora/emu.c b/platform/pandora/emu.c index 2d873df..0c6935b 100644 --- a/platform/pandora/emu.c +++ b/platform/pandora/emu.c @@ -350,7 +350,7 @@ static void blit(const char *fps, const char *notice) // 8bit accurate renderer if (Pico.m.dirtyPal) { - int pallen = 0x40; + int pallen = 0xc0; Pico.m.dirtyPal = 0; if (Pico.video.reg[0xC]&8) // shadow/hilight mode { @@ -360,13 +360,6 @@ static void blit(const char *fps, const char *notice) memcpy32(localPal+0xc0, localPal+0x40, 0x40); pallen = 0x100; } - else if (rendstatus & PDRAW_ACC_SPRITES) { - vidConvCpyRGB32(localPal, Pico.cram, 0x40); - memcpy32(localPal+0x40, localPal, 0x40); - memcpy32(localPal+0x80, localPal, 0x40); - memcpy32(localPal+0xc0, localPal, 0x40); - pallen = 0x100; - } else if (rendstatus & PDRAW_SONIC_MODE) { // mid-frame palette changes vidConvCpyRGB32(localPal, Pico.cram, 0x40); vidConvCpyRGB32(localPal+0x40, HighPal, 0x40); @@ -375,6 +368,7 @@ static void blit(const char *fps, const char *notice) } else { vidConvCpyRGB32(localPal, Pico.cram, 0x40); + memcpy32(localPal+0x80, localPal, 0x40); } if (pallen > 0xc0) { localPal[0xc0] = 0x0000c000; diff --git a/platform/psp/emu.c b/platform/psp/emu.c index d3e6317..5c87355 100644 --- a/platform/psp/emu.c +++ b/platform/psp/emu.c @@ -263,7 +263,7 @@ static void do_pal_update(int allow_sh, int allow_as) localPal[0xe0] = 0; localPal[0xf0] = 0x001f; } - else if (allow_as && (rendstatus & PDRAW_ACC_SPRITES)) + else if (allow_as && (rendstatus & PDRAW_SPR_LO_ON_HI)) { memcpy32((int *)dpal+0x80/2, (void *)localPal, 0x40*2/4); } @@ -290,7 +290,7 @@ static void EmuScanPrepare(void) if (Pico.m.dirtyPal) do_pal_update(1, 1); - if ((rendstatus & PDRAW_ACC_SPRITES) && !(Pico.video.reg[0xC]&8)) + if ((rendstatus & PDRAW_SPR_LO_ON_HI) && !(Pico.video.reg[0xC]&8)) amips_clut_f = amips_clut_6bit; else amips_clut_f = amips_clut; } diff --git a/platform/uiq3/App.cpp b/platform/uiq3/App.cpp index 68a802c..7497c16 100644 --- a/platform/uiq3/App.cpp +++ b/platform/uiq3/App.cpp @@ -35,6 +35,7 @@ #include "../common/emu.h" #include "emu.h" +extern "C" char menuErrorMsg[]; //////////////////////////////////////////////////////////////// // @@ -235,26 +236,18 @@ void CPicolAppView::DisplayOpenROMDialogL() iROMLoaded = EFalse; switch (res) { - case PicoErrRomOpenFailed: - CEikonEnv::Static()->InfoWinL(_L("Error"), _L("Failed to open file.")); + case PicoErrRomOpenFailed: { + TBuf<64> mErrorBuff; + TPtrC8 buff8((TUint8*) menuErrorMsg); + mErrorBuff.Copy(buff8); + CEikonEnv::Static()->InfoWinL(_L("Error"), mErrorBuff); break; + } case PicoErrOutOfMem: CEikonEnv::Static()->InfoWinL(_L("Error"), _L("Failed to allocate memory.")); break; - case PicoErrNotRom: - CEikonEnv::Static()->InfoWinL(_L("Error"), _L("The file you selected is not a game ROM.")); - break; - - case PicoErrNoRomsInArchive: - CEikonEnv::Static()->InfoWinL(_L("Error"), _L("No game ROMs found in zipfile.")); - break; - - case PicoErrUncomp: - CEikonEnv::Static()->InfoWinL(_L("Error"), _L("Failed while unzipping ROM.")); - break; - case PicoErrEmuThread: CEikonEnv::Static()->InfoWinL(_L("Error"), _L("Failed to create emulation thread. Try to restart this application.")); break; diff --git a/platform/uiq3/Engine.cpp b/platform/uiq3/Engine.cpp index ee9b6a5..ba93c81 100644 --- a/platform/uiq3/Engine.cpp +++ b/platform/uiq3/Engine.cpp @@ -37,7 +37,6 @@ extern const char *actionNames[]; RSemaphore initSemaphore; RSemaphore pauseSemaphore; RSemaphore loadWaitSemaphore; -int pico_was_reset = 0; static CPicolAppView *appView = 0; @@ -65,9 +64,7 @@ TInt CPicoGameSession::Do(const TPicoServRqst what, TAny *param) case PicoMsgReset: if(rom_loaded) { - PicoReset(); - pico_was_reset = 1; - return ChangeRunState(PGS_Running); + return ChangeRunState(PGS_Reset); } return 1; @@ -182,13 +179,14 @@ TInt CPicoGameSession::loadROM(TPtrC16 *pptr) // If successful, in will enter PGS_Running state by itself. loadrom_fname = (char *)writeBuf.PtrZ(); loadrom_result = 0; + loadWaitSemaphore.Wait(1); // make sure sem is not set ret = ChangeRunState(PGS_ReloadRom); if(ret) return ret; - loadWaitSemaphore.Wait(20*1000*1000); + loadWaitSemaphore.Wait(60*1000*1000); if (loadrom_result == 0) - return PicoErrNotRom; + return PicoErrRomOpenFailed; emu_getGameName(buff); TPtrC8 buff8((TUint8*) buff); @@ -198,11 +196,9 @@ TInt CPicoGameSession::loadROM(TPtrC16 *pptr) // debug #ifdef __DEBUG_PRINT - TInt cells = User::CountAllocCells(); - TInt mem; + TInt mem, cells = User::CountAllocCells(); User::AllocSize(mem); DEBUGPRINT(_L("comm: cels=%d, size=%d KB"), cells, mem/1024); - ChangeRunState(PGS_DebugHeap, PGS_Running); #endif return 0; diff --git a/platform/uiq3/Engine.h b/platform/uiq3/Engine.h index b81b6af..e0a3afe 100644 --- a/platform/uiq3/Engine.h +++ b/platform/uiq3/Engine.h @@ -27,8 +27,8 @@ enum TPicoGameState { PGS_Paused, PGS_Quit, PGS_KeyConfig, - PGS_DebugHeap, PGS_ReloadRom, + PGS_Reset, }; enum TPicoServRqst { @@ -49,11 +49,8 @@ enum TPicoGenErrors { // generic errors PicoErrNoErr = 0, // OK PicoErrRomOpenFailed, PicoErrOutOfMem, - PicoErrNotRom, - PicoErrNoRomsInArchive, - PicoErrUncomp, // 5 PicoErrOutOfMemSnd, - PicoErrGenSnd, // 7 generic sound system error + PicoErrGenSnd, // generic sound system error PicoErrEmuThread }; diff --git a/platform/uiq3/Makefile b/platform/uiq3/Makefile index 9e91127..dcfff24 100644 --- a/platform/uiq3/Makefile +++ b/platform/uiq3/Makefile @@ -1,4 +1,4 @@ -# makefile for uiq3_patcher_0_2.tar.gz +# makefile for uiq3_patcher_0_2.tar.gz setup, modified export CROSS = arm-none-symbianelf- APPNAME = PicoDrive VER_MAJ = 1 @@ -141,6 +141,20 @@ engine/blit_asm.o : engine/blit.s @echo ">>>" $@ $(AS) $(ASFLAGS) $< -o $@ -# App.o can't be optimized -#App.o : App.cpp -# $(CC) $(CXXFLAGS) -O0 -c $< -o $@ + +readme.txt: ../../tools/textfilter ../base_readme.txt + ../../tools/textfilter ../base_readme.txt $@ UIQ + +# ----------- release ----------- +ifneq ($(findstring rel,$(MAKECMDGOALS)),) +ifeq ($(VER),) +$(error need VER) +endif +endif + +rel: picodrive.sis readme.txt + zip -9 -j ../../PicoDrive_uiq3_$(VER).zip $^ + mkdir bin_to_cso_mp3 + cp ../../tools/bin_to_cso_mp3/* bin_to_cso_mp3/ + zip -9 -r ../../PicoDrive_uiq3_$(VER).zip bin_to_cso_mp3 + rm -rf bin_to_cso_mp3 diff --git a/platform/uiq3/emu.c b/platform/uiq3/emu.c index 71bf872..7f42562 100644 --- a/platform/uiq3/emu.c +++ b/platform/uiq3/emu.c @@ -65,6 +65,7 @@ void emu_prepareDefaultConfig(void) defaultConfig.Frameskip = -1; // auto defaultConfig.volume = 80; defaultConfig.scaling = 0; + defaultConfig.KeyBinds[0xd5] = 1<<26; // back } /* used by config engine only, not actual menus */ @@ -102,7 +103,7 @@ const int opt2_entry_count = OPT2_ENTRY_COUNT; menu_entry cdopt_entries[] = { { "CD LEDs", MB_ONOFF, MA_CDOPT_LEDS, ¤tConfig.EmuOpt, 0x0400, 0, 0, 1, 1 }, - { "CDDA audio (using mp3s)", MB_ONOFF, MA_CDOPT_CDDA, &PicoOpt, 0x0800, 0, 0, 1, 1 }, + { "CDDA audio", MB_ONOFF, MA_CDOPT_CDDA, &PicoOpt, 0x0800, 0, 0, 1, 1 }, { "PCM audio", MB_ONOFF, MA_CDOPT_PCM, &PicoOpt, 0x0400, 0, 0, 1, 1 }, { NULL, MB_NONE, MA_CDOPT_READAHEAD, NULL, 0, 0, 0, 1, 1 }, { "SaveRAM cart", MB_ONOFF, MA_CDOPT_SAVERAM, &PicoOpt, 0x8000, 0, 0, 1, 1 }, diff --git a/platform/uiq3/engine/debug.cpp b/platform/uiq3/engine/debug.cpp index 81edbc5..46725f3 100644 --- a/platform/uiq3/engine/debug.cpp +++ b/platform/uiq3/engine/debug.cpp @@ -171,7 +171,7 @@ void ExceptionHandler(TExcType exc) #include // vsprintf // debug print from c code - extern "C" void lprintf(char *format, ...) + extern "C" void lprintf(const char *format, ...) { va_list args; char buffer[512]; diff --git a/platform/uiq3/engine/debug.h b/platform/uiq3/engine/debug.h index 8f7bebf..fb62cf6 100644 --- a/platform/uiq3/engine/debug.h +++ b/platform/uiq3/engine/debug.h @@ -16,7 +16,7 @@ #ifdef __cplusplus extern "C" #endif - void lprintf(char *format, ...); + void lprintf(const char *format, ...); #endif #else #define DEBUGPRINT(x...) diff --git a/platform/uiq3/engine/main.cpp b/platform/uiq3/engine/main.cpp index 03c3e4f..53454c9 100644 --- a/platform/uiq3/engine/main.cpp +++ b/platform/uiq3/engine/main.cpp @@ -84,8 +84,8 @@ char *loadrom_fname = NULL; int loadrom_result = 0; static timeval noticeMsgTime = { 0, 0 }; // when started showing static CGameAudioMS *gameAudio = 0; // the audio object itself -static int reset_timing; -extern int pico_was_reset; +static int reset_timing = 0; +static int pico_was_reset = 0; extern RSemaphore initSemaphore; extern RSemaphore pauseSemaphore; extern RSemaphore loadWaitSemaphore; @@ -170,21 +170,27 @@ static void TargetEpocGameL() int thissec = 0, frames_done = 0, frames_shown = 0; int target_fps, target_frametime; int i, lim_time; - //TRawEvent blevent; MainInit(); buff[0] = 0; + // try to start pico + DEBUGPRINT(_L("PicoInit()")); PicoInit(); - - // just to keep the backlight on (works only on UIQ2) - //blevent.Set(TRawEvent::EActive); + PicoDrawSetColorFormat(2); + PicoWriteSound = updateSound; // loop? for(;;) { if (gamestate == PGS_Running) { + #ifdef __DEBUG_PRINT + TInt mem, cells = User::CountAllocCells(); + User::AllocSize(mem); + DEBUGPRINT(_L("worker: cels=%d, size=%d KB"), cells, mem/1024); + #endif + // switch context to other thread User::After(50000); // prepare window and stuff @@ -203,7 +209,7 @@ static void TargetEpocGameL() if(!noticeMsgTime.tv_sec) strcpy(noticeMsg, "NTSC@SYSTEM@/@60@FPS"); } target_frametime = 1000000/target_fps; - if(!noticeMsgTime.tv_sec && pico_was_reset) + if (!noticeMsgTime.tv_sec && pico_was_reset) gettimeofday(¬iceMsgTime, 0); // prepare CD buffer @@ -263,6 +269,7 @@ static void TargetEpocGameL() frames_shown -= target_fps; if (frames_shown < 0) frames_shown = 0; if (frames_shown > frames_done) frames_shown = frames_done; } + User::ResetInactivityTime(); } @@ -331,14 +338,23 @@ static void TargetEpocGameL() CPolledActiveScheduler::Instance()->Schedule(); CGameWindow::FreeResources(); } + else if(gamestate == PGS_Reset) + { + PicoReset(); + pico_was_reset = 1; + gamestate = PGS_Running; + } else if(gamestate == PGS_ReloadRom) { loadrom_result = emu_ReloadRom(loadrom_fname); pico_was_reset = 1; if (loadrom_result) gamestate = PGS_Running; - else + else { + extern char menuErrorMsg[]; gamestate = PGS_Paused; + lprintf("%s\n", menuErrorMsg); + } DEBUGPRINT(_L("done loading ROM, retval=%i"), loadrom_result); loadWaitSemaphore.Signal(); User::After(50000); @@ -363,15 +379,8 @@ static void TargetEpocGameL() User::After(150000); } + emu_WriteConfig(0); CGameWindow::FreeResources(); - } else if(gamestate == PGS_DebugHeap) { - #ifdef __DEBUG_PRINT - TInt cells = User::CountAllocCells(); - TInt mem; - User::AllocSize(mem); - DEBUGPRINT(_L("worker: cels=%d, size=%d KB"), cells, mem/1024); - gamestate = gamestate_next; - #endif } else if(gamestate == PGS_Quit) { break; } @@ -397,11 +406,6 @@ static void MainInit() DumpMemInfo(); - // try to start pico - DEBUGPRINT(_L("PicoInit()")); - PicoDrawSetColorFormat(2); - PicoWriteSound = updateSound; - // if (pauseSemaphore.Handle() <= 0) // pauseSemaphore.CreateLocal(0); DEBUGPRINT(_L("initSemaphore.Signal()")); @@ -776,6 +780,8 @@ void CGameWindow::DoKeys(void) areaActions = 0; } } + + if (movie_data) emu_updateMovie(); } @@ -875,8 +881,11 @@ void CGameWindow::RunEvents(TUint32 which) sprintf(noticeMsg, "SAVE@SLOT@%i@SELECTED", state_slot); gettimeofday(¬iceMsgTime, 0); } - if(which & 0x0020) if(gameAudio) currentConfig.volume = gameAudio->ChangeVolume(0); - if(which & 0x0010) if(gameAudio) currentConfig.volume = gameAudio->ChangeVolume(1); + if ((which & 0x0030) && gameAudio != NULL) { + currentConfig.volume = gameAudio->ChangeVolume((which & 0x0010) ? 1 : 0); + sprintf(noticeMsg, "VOL@%02i@", currentConfig.volume); + gettimeofday(¬iceMsgTime, 0); + } } diff --git a/platform/uiq3/engine/vid.cpp b/platform/uiq3/engine/vid.cpp index bd1b3fd..ea3cf9b 100644 --- a/platform/uiq3/engine/vid.cpp +++ b/platform/uiq3/engine/vid.cpp @@ -182,7 +182,7 @@ static void drawTextM2Fat(int x, int y, const char *text) static void drawTextFpsCenter0(const char *text) { if(!text) return; - drawTextM2(214, 216, text); + drawTextM2((Pico.video.reg[12]&1) ? 234 : 214, 216, text); } static void drawTextFpsFit0(const char *text) @@ -206,7 +206,7 @@ static void drawTextFps0(const char *text) static void drawTextNoticeCenter0(const char *text) { if(!text) return; - drawTextM2(2, 216, text); + drawTextM2(42, 216, text); } static void drawTextNoticeFit0(const char *text) @@ -250,12 +250,14 @@ static void fillLocalPal(void) memcpy32(localPal+0xc0, localPal+0x40, 0x40); localPal[0xe0] = 0x00000000; // reserved pixels for OSD localPal[0xf0] = 0x00ee0000; - } else if (rendstatus & 0x20) { // mid-frame palette changes + } + else if (rendstatus & PDRAW_SONIC_MODE) { // mid-frame palette changes vidConvCpyRGB32(localPal, Pico.cram, 0x40); vidConvCpyRGB32(localPal+0x40, HighPal, 0x40); vidConvCpyRGB32(localPal+0x80, HighPal+0x40, 0x40); } else { vidConvCpyRGB32(localPal, Pico.cram, 0x40); + memcpy32(localPal+0x80, localPal, 0x40); // for sprite prio mess } } @@ -266,8 +268,6 @@ static void vidBlit_90(int full) unsigned char *ps = PicoDraw2FB+328*8; unsigned long *pd = (unsigned long *) screenbuff; - if (Pico.m.dirtyPal) fillLocalPal(); - if(Pico.video.reg[12]&1) vidConvCpy_90(pd, ps, localPal, 320/8); else { @@ -284,8 +284,6 @@ static void vidBlit_270(int full) unsigned char *ps = PicoDraw2FB+328*8; unsigned long *pd = (unsigned long *) screenbuff; - if (Pico.m.dirtyPal) fillLocalPal(); - if(Pico.video.reg[12]&1) vidConvCpy_270(pd, ps, localPal, 320/8); else { @@ -303,8 +301,6 @@ static void vidBlitCenter_0(int full) unsigned char *ps = PicoDraw2FB+328*8+8; unsigned long *pd = (unsigned long *) screenbuff; - if (Pico.m.dirtyPal) fillLocalPal(); - if(Pico.video.reg[12]&1) ps += 32; vidConvCpy_center_0(pd, ps, localPal); if(full) vidClear(pd + 224*256, 96); @@ -316,8 +312,6 @@ static void vidBlitCenter_180(int full) unsigned char *ps = PicoDraw2FB+328*8+8; unsigned long *pd = (unsigned long *) screenbuff; - if (Pico.m.dirtyPal) fillLocalPal(); - if(Pico.video.reg[12]&1) ps += 32; vidConvCpy_center_180(pd, ps, localPal); if(full) vidClear(pd + 224*256, 96); @@ -326,8 +320,6 @@ static void vidBlitCenter_180(int full) static void vidBlitFit_0(int full) { - if (Pico.m.dirtyPal) fillLocalPal(); - if(Pico.video.reg[12]&1) vidConvCpy_center2_40c_0(screenbuff, PicoDraw2FB+328*8, localPal, 168); else vidConvCpy_center2_32c_0(screenbuff, PicoDraw2FB+328*8, localPal, 168); @@ -337,8 +329,6 @@ static void vidBlitFit_0(int full) static void vidBlitFit_180(int full) { - if (Pico.m.dirtyPal) fillLocalPal(); - if(Pico.video.reg[12]&1) vidConvCpy_center2_40c_180(screenbuff, PicoDraw2FB+328*8, localPal, 168); else vidConvCpy_center2_32c_180(screenbuff, PicoDraw2FB+328*8-64, localPal, 168); @@ -348,8 +338,6 @@ static void vidBlitFit_180(int full) static void vidBlitFit2_0(int full) { - if (Pico.m.dirtyPal) fillLocalPal(); - if(Pico.video.reg[12]&1) vidConvCpy_center2_40c_0(screenbuff, PicoDraw2FB+328*8, localPal, 224); else vidConvCpy_center2_32c_0(screenbuff, PicoDraw2FB+328*8, localPal, 224); @@ -359,8 +347,6 @@ static void vidBlitFit2_0(int full) static void vidBlitFit2_180(int full) { - if (Pico.m.dirtyPal) fillLocalPal(); - if(Pico.video.reg[12]&1) vidConvCpy_center2_40c_180(screenbuff, PicoDraw2FB+328*8, localPal, 224); else vidConvCpy_center2_32c_180(screenbuff, PicoDraw2FB+328*8-64, localPal, 224); @@ -453,6 +439,7 @@ int vidInit(void *vidmem, int reinit) vidBlit = vidBlit_270; } + fillLocalPal(); vidBlit(1); PicoOpt |= 0x100; Pico.m.dirtyPal = 1; @@ -475,6 +462,7 @@ void vidDrawFrame(char *noticeStr, char *fpsStr, int num) drawTextFps(fpsStr); drawTextNotice(noticeStr); + if (Pico.m.dirtyPal) fillLocalPal(); vidBlit(!num); // copy full frame once a second } diff --git a/platform/uiq3/port_config.h b/platform/uiq3/port_config.h index 0686c26..5d0f977 100644 --- a/platform/uiq3/port_config.h +++ b/platform/uiq3/port_config.h @@ -19,7 +19,7 @@ #define CAN_HANDLE_240_LINES 0 // for now // logging emu events -#define EL_LOGMASK (EL_STATUS|EL_IDLE) // (EL_STATUS|EL_ANOMALY|EL_UIO|EL_SRAMIO|EL_INTS|EL_CDPOLL) // xffff +#define EL_LOGMASK (EL_STATUS) // |EL_SVP|EL_ANOMALY) //extern void dprintf(char *format, ...); //#define dprintf(f,...) printf("%05i:%03i: " f "\n",Pico.m.frame_count,Pico.m.scanline,##__VA_ARGS__) diff --git a/platform/uiq3/uiq3.mak b/platform/uiq3/uiq3.mak index 6221f3f..f5ad101 100644 --- a/platform/uiq3/uiq3.mak +++ b/platform/uiq3/uiq3.mak @@ -35,10 +35,9 @@ ELF2E32 = elf2e32 BMCONV = bmconv EPOCRC = EPOCROOT=$(EPOCROOT) epocrc -PATH := $(EPOCROOT)/bin:$(GCCPATH)/bin:$(GCCPATH)/$(GCCPREF)/bin:$(PATH) +PATH := $(EPOCROOT)/bin:$(GCCPATH)/bin:$(PATH) -# TODO: do we really need -mapcs? -# -march=armv5t +# -march=armv5t ? CFLAGS += -Wall -pipe -nostdinc -msoft-float CFLAGS += -DNDEBUG -D_UNICODE -D__GCCE__ -D__SYMBIAN32__ -D__EPOC32__ -D__MARM__ CFLAGS += -D__EABI__ -D__MARM_ARMV5__ -D__EXE__ -D__SUPPORT_CPP_EXCEPTIONS__ -D__MARM_ARMV5__ -- 2.39.2