mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-10-27 13:38:51 +01:00
UIQ3 bugfixes, SVP drc indirect jumps, stuff
git-svn-id: file:///home/notaz/opt/svn/PicoDrive@572 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
parent
02ba8788a0
commit
f8af96349e
29 changed files with 193 additions and 157 deletions
15
Pico/Cart.c
15
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?
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
20
Pico/Draw.c
20
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
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
#ifdef _MSC_VER
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
#ifdef UIQ3
|
||||
#ifdef __EPOC32__
|
||||
#define snprintf(b,s,...) sprintf(b,##__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue