From 726bbb3e08e3d4e7ed086a3c98dec0e21a386d75 Mon Sep 17 00:00:00 2001 From: notaz Date: Sun, 10 Feb 2008 20:07:36 +0000 Subject: [PATCH] svp block extractor for recompiler git-svn-id: file:///home/notaz/opt/svn/PicoDrive@354 be3aeb3a-fb24-0410-a615-afba39da0efa --- Pico/Pico.h | 10 +- Pico/carthw/svp/compiler.c | 235 +++++++++++++++++++++++++++++++++++++ Pico/carthw/svp/ssp16.c | 49 +++++--- Pico/carthw/svp/ssp16.h | 4 + Pico/carthw/svp/svp.c | 12 +- platform/linux/Makefile | 2 +- 6 files changed, 287 insertions(+), 25 deletions(-) create mode 100644 Pico/carthw/svp/compiler.c diff --git a/Pico/Pico.h b/Pico/Pico.h index efedc81..f3db4a3 100644 --- a/Pico/Pico.h +++ b/Pico/Pico.h @@ -30,11 +30,11 @@ void mp3_update(int *buffer, int length, int stereo); // Pico.c // PicoOpt bits LSb->MSb: -// enable_ym2612&dac, enable_sn76496, enable_z80, stereo_sound, -// alt_renderer, 6button_gamepad, accurate_timing, accurate_sprites, -// draw_no_32col_border, external_ym2612, enable_cd_pcm, enable_cd_cdda -// enable_cd_gfx, cd_perfect_sync, soft_32col_scaling, enable_cd_ramcart -// disable_vdp_fifo +// 00 000x enable_ym2612&dac, enable_sn76496, enable_z80, stereo_sound, +// 00 00x0 alt_renderer, 6button_gamepad, accurate_timing, accurate_sprites, +// 00 0x00 draw_no_32col_border, external_ym2612, enable_cd_pcm, enable_cd_cdda +// 00 x000 enable_cd_gfx, cd_perfect_sync, soft_32col_scaling, enable_cd_ramcart +// 0x 0000 disable_vdp_fifo, no_svp_dynarec extern int PicoOpt; extern int PicoVer; extern int PicoSkipFrame; // skip rendering frame, but still do sound (if enabled) and emulation stuff diff --git a/Pico/carthw/svp/compiler.c b/Pico/carthw/svp/compiler.c new file mode 100644 index 0000000..65399eb --- /dev/null +++ b/Pico/carthw/svp/compiler.c @@ -0,0 +1,235 @@ +// 187 blocks, 12072 bytes +// 14 IRAM blocks + +#include "../../PicoInt.h" + +#define TCACHE_SIZE (256*1024) +static unsigned short *block_table[0x5090/2]; +static unsigned short *tcache = NULL; +static unsigned short *tcache_ptr = NULL; + +static int had_jump = 0; +static int nblocks = 0; + +#define EMBED_INTERPRETER +#define ssp1601_reset ssp1601_reset_local +#define ssp1601_run ssp1601_run_local + +static unsigned int interp_get_pc(void); + +#define GET_PC interp_get_pc +#define GET_PPC_OFFS() (interp_get_pc()*2 - 2) +#define SET_PC(d) { had_jump = 1; rPC = d; } /* must return to dispatcher after this */ +//#define GET_PC() (PC - (unsigned short *)svp->iram_rom) +//#define GET_PPC_OFFS() ((unsigned int)PC - (unsigned int)svp->iram_rom - 2) +//#define SET_PC(d) PC = (unsigned short *)svp->iram_rom + d + +#include "ssp16.c" + +// ----------------------------------------------------- + +static unsigned int crctable[256] = +{ + 0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL, + 0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L, + 0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L, + 0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L, + 0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL, + 0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L, + 0x136C9856L, 0x646BA8C0L, 0xFD62F97AL, 0x8A65C9ECL, + 0x14015C4FL, 0x63066CD9L, 0xFA0F3D63L, 0x8D080DF5L, + 0x3B6E20C8L, 0x4C69105EL, 0xD56041E4L, 0xA2677172L, + 0x3C03E4D1L, 0x4B04D447L, 0xD20D85FDL, 0xA50AB56BL, + 0x35B5A8FAL, 0x42B2986CL, 0xDBBBC9D6L, 0xACBCF940L, + 0x32D86CE3L, 0x45DF5C75L, 0xDCD60DCFL, 0xABD13D59L, + 0x26D930ACL, 0x51DE003AL, 0xC8D75180L, 0xBFD06116L, + 0x21B4F4B5L, 0x56B3C423L, 0xCFBA9599L, 0xB8BDA50FL, + 0x2802B89EL, 0x5F058808L, 0xC60CD9B2L, 0xB10BE924L, + 0x2F6F7C87L, 0x58684C11L, 0xC1611DABL, 0xB6662D3DL, + 0x76DC4190L, 0x01DB7106L, 0x98D220BCL, 0xEFD5102AL, + 0x71B18589L, 0x06B6B51FL, 0x9FBFE4A5L, 0xE8B8D433L, + 0x7807C9A2L, 0x0F00F934L, 0x9609A88EL, 0xE10E9818L, + 0x7F6A0DBBL, 0x086D3D2DL, 0x91646C97L, 0xE6635C01L, + 0x6B6B51F4L, 0x1C6C6162L, 0x856530D8L, 0xF262004EL, + 0x6C0695EDL, 0x1B01A57BL, 0x8208F4C1L, 0xF50FC457L, + 0x65B0D9C6L, 0x12B7E950L, 0x8BBEB8EAL, 0xFCB9887CL, + 0x62DD1DDFL, 0x15DA2D49L, 0x8CD37CF3L, 0xFBD44C65L, + 0x4DB26158L, 0x3AB551CEL, 0xA3BC0074L, 0xD4BB30E2L, + 0x4ADFA541L, 0x3DD895D7L, 0xA4D1C46DL, 0xD3D6F4FBL, + 0x4369E96AL, 0x346ED9FCL, 0xAD678846L, 0xDA60B8D0L, + 0x44042D73L, 0x33031DE5L, 0xAA0A4C5FL, 0xDD0D7CC9L, + 0x5005713CL, 0x270241AAL, 0xBE0B1010L, 0xC90C2086L, + 0x5768B525L, 0x206F85B3L, 0xB966D409L, 0xCE61E49FL, + 0x5EDEF90EL, 0x29D9C998L, 0xB0D09822L, 0xC7D7A8B4L, + 0x59B33D17L, 0x2EB40D81L, 0xB7BD5C3BL, 0xC0BA6CADL, + 0xEDB88320L, 0x9ABFB3B6L, 0x03B6E20CL, 0x74B1D29AL, + 0xEAD54739L, 0x9DD277AFL, 0x04DB2615L, 0x73DC1683L, + 0xE3630B12L, 0x94643B84L, 0x0D6D6A3EL, 0x7A6A5AA8L, + 0xE40ECF0BL, 0x9309FF9DL, 0x0A00AE27L, 0x7D079EB1L, + 0xF00F9344L, 0x8708A3D2L, 0x1E01F268L, 0x6906C2FEL, + 0xF762575DL, 0x806567CBL, 0x196C3671L, 0x6E6B06E7L, + 0xFED41B76L, 0x89D32BE0L, 0x10DA7A5AL, 0x67DD4ACCL, + 0xF9B9DF6FL, 0x8EBEEFF9L, 0x17B7BE43L, 0x60B08ED5L, + 0xD6D6A3E8L, 0xA1D1937EL, 0x38D8C2C4L, 0x4FDFF252L, + 0xD1BB67F1L, 0xA6BC5767L, 0x3FB506DDL, 0x48B2364BL, + 0xD80D2BDAL, 0xAF0A1B4CL, 0x36034AF6L, 0x41047A60L, + 0xDF60EFC3L, 0xA867DF55L, 0x316E8EEFL, 0x4669BE79L, + 0xCB61B38CL, 0xBC66831AL, 0x256FD2A0L, 0x5268E236L, + 0xCC0C7795L, 0xBB0B4703L, 0x220216B9L, 0x5505262FL, + 0xC5BA3BBEL, 0xB2BD0B28L, 0x2BB45A92L, 0x5CB36A04L, + 0xC2D7FFA7L, 0xB5D0CF31L, 0x2CD99E8BL, 0x5BDEAE1DL, + 0x9B64C2B0L, 0xEC63F226L, 0x756AA39CL, 0x026D930AL, + 0x9C0906A9L, 0xEB0E363FL, 0x72076785L, 0x05005713L, + 0x95BF4A82L, 0xE2B87A14L, 0x7BB12BAEL, 0x0CB61B38L, + 0x92D28E9BL, 0xE5D5BE0DL, 0x7CDCEFB7L, 0x0BDBDF21L, + 0x86D3D2D4L, 0xF1D4E242L, 0x68DDB3F8L, 0x1FDA836EL, + 0x81BE16CDL, 0xF6B9265BL, 0x6FB077E1L, 0x18B74777L, + 0x88085AE6L, 0xFF0F6A70L, 0x66063BCAL, 0x11010B5CL, + 0x8F659EFFL, 0xF862AE69L, 0x616BFFD3L, 0x166CCF45L, + 0xA00AE278L, 0xD70DD2EEL, 0x4E048354L, 0x3903B3C2L, + 0xA7672661L, 0xD06016F7L, 0x4969474DL, 0x3E6E77DBL, + 0xAED16A4AL, 0xD9D65ADCL, 0x40DF0B66L, 0x37D83BF0L, + 0xA9BCAE53L, 0xDEBB9EC5L, 0x47B2CF7FL, 0x30B5FFE9L, + 0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L, 0x24B4A3A6L, + 0xBAD03605L, 0xCDD70693L, 0x54DE5729L, 0x23D967BFL, + 0xB3667A2EL, 0xC4614AB8L, 0x5D681B02L, 0x2A6F2B94L, + 0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL, 0x2D02EF8DL +}; + +static u32 chksum_crc32 (unsigned char *block, unsigned int length) +{ + register u32 crc; + unsigned long i; + + crc = 0xFFFFFFFF; + for (i = 0; i < length; i++) + { + crc = ((crc >> 8) & 0x00FFFFFF) ^ crctable[(crc ^ *block++) & 0xFF]; + } + return (crc ^ 0xFFFFFFFF); +} + +static int iram_crcs[32] = { 0, }; + +// ----------------------------------------------------- + +#define PROGRAM(x) ((unsigned short *)svp->iram_rom)[x] + +static u32 interp_get_pc(void) +{ + unsigned short *pc1 = PC; + int i; + while (pc1[-1] != 0xfe01) pc1--; // goto current block start + for (i = 0; i < 0x5090/2; i++) + if (block_table[i] == pc1) break; + + if (i == 0x5090/2) { + printf("block not found!\n"); + exit(1); + } + + return i + (PC - pc1); +} + +static void translate_block(int pc) +{ + int tmp, op, op1, icount = 0; + + block_table[pc] = tcache_ptr; + + //printf("translate %04x -> %04x\n", pc<<1, (tcache_ptr-tcache)<<1); + for (;;) + { + op = PROGRAM(pc++); + op1 = op >> 9; + *tcache_ptr++ = op; + icount++; + // need immediate? + if ((op1 & 0xf) == 4 || (op1 & 0xf) == 6) { + tmp = PROGRAM(pc++); + *tcache_ptr++ = tmp; // immediate + } + if (op1 == 0x24 || op1 == 0x26 || // call, bra + ((op1 == 0 || op1 == 1 || op1 == 4 || op1 == 5 || op1 == 9 || op1 == 0x25) && + (op & 0xf0) == 0x60)) { // ld PC + break; + } + } + *tcache_ptr++ = 0xfe01; // end of block + //printf(" %i inst\n", icount); + + if (tcache_ptr - tcache > TCACHE_SIZE/2) { + printf("tcache overflow!\n"); + fflush(stdout); + exit(1); + } + + // stats + nblocks++; + if (pc >= 0x400) printf("%i blocks, %i bytes\n", nblocks, (tcache_ptr - tcache)*2); +} + + + +// ----------------------------------------------------- + +int ssp1601_dyn_init(void) +{ + tcache = tcache_ptr = malloc(TCACHE_SIZE); + memset(tcache, 0, sizeof(TCACHE_SIZE)); + memset(block_table, 0, sizeof(block_table)); + *tcache_ptr++ = 0xfe01; + + return 0; +} + + +void ssp1601_dyn_reset(ssp1601_t *ssp) +{ + ssp1601_reset_local(ssp); +} + + +void ssp1601_dyn_run(int cycles) +{ + while (cycles > 0) + { + int pc_old = rPC; + if (block_table[rPC] == NULL) + translate_block(rPC); + + PC = block_table[rPC]; + had_jump = 0; + + //printf("enter @ %04x, PC=%04x\n", (PC - tcache)<<1, rPC<<1); + ssp1601_run_local(0x10000); + cycles -= 0x10000 - g_cycles; + + if (!had_jump) { + // no jumps + rPC += (PC - block_table[pc_old]) - 1; + } + //printf("end @ %04x, PC=%04x\n", (PC - tcache)<<1, rPC<<1); + + if (pc_old < 0x400) { + // flush IRAM cache + tcache_ptr = block_table[pc_old]; + block_table[pc_old] = NULL; + nblocks--; + } + if (pc_old >= 0x400 && rPC < 0x400) + { + int i, crc = chksum_crc32(svp->iram_rom, 0x800); + for (i = 0; i < 32; i++) + if (iram_crcs[i] == crc) break; + if (i == 32) { + for (i = 0; i < 32 && iram_crcs[i]; i++); + iram_crcs[i] = crc; + printf("%i IRAMs\n", i+1); + } + } + } +// debug_dump2file("tcache.bin", tcache, (tcache_ptr - tcache) << 1); +// exit(1); +} + diff --git a/Pico/carthw/svp/ssp16.c b/Pico/carthw/svp/ssp16.c index 9835165..3288ee3 100644 --- a/Pico/carthw/svp/ssp16.c +++ b/Pico/carthw/svp/ssp16.c @@ -184,7 +184,6 @@ * flags correspond to full 32bit accumulator * only Z and N status flags are emulated (others unused by SVP) * modifiers for 'OP a, ri' are ignored (invalid?/not used by SVP) - * 'ld d, (a)' loads from program ROM */ #include "../../PicoInt.h" @@ -543,9 +542,11 @@ static u32 read_PM0(void) if (d != (u32)-1) return d; elprintf(EL_SVP, "PM0 raw r %04x @ %04x", rPM0, GET_PPC_OFFS()); d = rPM0; +#ifndef EMBED_INTERPRETER if (!(d & 2) && (GET_PPC_OFFS() == 0x800 || GET_PPC_OFFS() == 0x1851E)) { ssp->emu_status |= SSP_WAIT_PM0; elprintf(EL_SVP, "det TIGHT loop: PM0"); } +#endif rPM0 &= ~2; // ? return d; } @@ -622,12 +623,14 @@ static void write_XST(u32 d) static u32 read_PM4(void) { u32 d = pm_io(4, 0, 0); +#ifndef EMBED_INTERPRETER if (d == 0) { switch (GET_PPC_OFFS()) { case 0x0854: ssp->emu_status |= SSP_WAIT_30FE08; elprintf(EL_SVP, "det TIGHT loop: [30fe08]"); break; case 0x4f12: ssp->emu_status |= SSP_WAIT_30FE06; elprintf(EL_SVP, "det TIGHT loop: [30fe06]"); break; } } +#endif if (d != (u32)-1) return d; // can be removed? elprintf(EL_SVP|EL_ANOMALY, "PM4 raw r %04x @ %04x", rPM4, GET_PPC_OFFS()); @@ -875,6 +878,24 @@ static u32 ptr2_read(int op) // ----------------------------------------------------- +#if defined(USE_DEBUGGER) // || defined(EMBED_INTERPRETER) +static void debug_dump2file(const char *fname, void *mem, int len) +{ + FILE *f = fopen(fname, "wb"); + unsigned short *p = mem; + int i; + if (f) { + for (i = 0; i < len/2; i++) p[i] = (p[i]<<8) | (p[i]>>8); + fwrite(mem, 1, len, f); + fclose(f); + for (i = 0; i < len/2; i++) p[i] = (p[i]<<8) | (p[i]>>8); + printf("dumped to %s\n", fname); + } + else + printf("dump failed\n"); +} +#endif + #ifdef USE_DEBUGGER static void debug_dump(void) { @@ -904,22 +925,6 @@ static void debug_dump_mem(void) } } -static void debug_dump2file(const char *fname, void *mem, int len) -{ - FILE *f = fopen(fname, "wb"); - unsigned short *p = mem; - int i; - if (f) { - for (i = 0; i < len/2; i++) p[i] = (p[i]<<8) | (p[i]>>8); - fwrite(mem, 1, len, f); - fclose(f); - for (i = 0; i < len/2; i++) p[i] = (p[i]<<8) | (p[i]>>8); - printf("dumped to %s\n", fname); - } - else - printf("dump failed\n"); -} - static int bpts[10] = { 0, }; static void debug(unsigned int pc, unsigned int op) @@ -995,7 +1000,9 @@ static #endif void ssp1601_run(int cycles) { +#ifndef EMBED_INTERPRETER SET_PC(rPC); +#endif g_cycles = cycles; while (g_cycles > 0 && !(ssp->emu_status & SSP_WAIT_MASK)) @@ -1177,6 +1184,9 @@ void ssp1601_run(int cycles) case 0x6c: OP_ORA (op & 0xff); break; case 0x7c: OP_EORA(op & 0xff); break; +#ifdef EMBED_INTERPRETER + case 0x7f: goto interp_end; /* pseudo op */ +#endif default: elprintf(EL_ANOMALY|EL_SVP, "ssp FIXME unhandled op %04x @ %04x", op, GET_PPC_OFFS()); break; @@ -1184,8 +1194,11 @@ void ssp1601_run(int cycles) g_cycles--; } - read_P(); // update P rPC = GET_PC(); +#ifdef EMBED_INTERPRETER +interp_end: +#endif + read_P(); // update P if (ssp->gr[SSP_GR0].v != 0xffff0000) elprintf(EL_ANOMALY|EL_SVP, "ssp FIXME: REG 0 corruption! %08x", ssp->gr[SSP_GR0].v); diff --git a/Pico/carthw/svp/ssp16.h b/Pico/carthw/svp/ssp16.h index ec363f0..4f4dfa0 100644 --- a/Pico/carthw/svp/ssp16.h +++ b/Pico/carthw/svp/ssp16.h @@ -58,3 +58,7 @@ typedef struct void ssp1601_reset(ssp1601_t *ssp); void ssp1601_run(int cycles); +int ssp1601_dyn_init(void); +void ssp1601_dyn_reset(ssp1601_t *ssp); +void ssp1601_dyn_run(int cycles); + diff --git a/Pico/carthw/svp/svp.c b/Pico/carthw/svp/svp.c index a29893b..3dbc269 100644 --- a/Pico/carthw/svp/svp.c +++ b/Pico/carthw/svp/svp.c @@ -33,13 +33,18 @@ static void PicoSVPReset(void) memcpy(svp->iram_rom + 0x800, Pico.rom + 0x800, 0x20000 - 0x800); ssp1601_reset(&svp->ssp1601); + if (!(PicoOpt&0x20000)) + ssp1601_dyn_reset(&svp->ssp1601); } static void PicoSVPLine(int count) { // ??? - ssp1601_run(PicoSVPCycles * count); + if (PicoOpt&0x20000) + ssp1601_run(PicoSVPCycles * count); + else + ssp1601_dyn_run(PicoSVPCycles * count); // test mode //if (Pico.m.frame_count == 13) PicoPad[0] |= 0xff; @@ -88,6 +93,11 @@ void PicoSVPInit(void) svp = (void *) ((char *)tmp + 0x200000); memset(svp, 0, sizeof(*svp)); + // init SVP compiler + if (!(PicoOpt&0x20000)) { + if (ssp1601_dyn_init()) return; + } + // init ok, setup hooks.. PicoRead16Hook = PicoSVPRead16; PicoWrite8Hook = PicoSVPWrite8; diff --git a/platform/linux/Makefile b/platform/linux/Makefile index 4150027..fd37478 100644 --- a/platform/linux/Makefile +++ b/platform/linux/Makefile @@ -44,7 +44,7 @@ OBJS += Pico/cd/Pico.o Pico/cd/Memory.o Pico/cd/Sek.o Pico/cd/LC89510.o \ # Pico - sound OBJS += Pico/sound/sound.o Pico/sound/sn76496.o Pico/sound/ym2612.o Pico/sound/mix.o # Pico - carthw -OBJS += Pico/carthw/svp/svp.o Pico/carthw/svp/Memory.o Pico/carthw/svp/ssp16.o +OBJS += Pico/carthw/svp/svp.o Pico/carthw/svp/Memory.o Pico/carthw/svp/ssp16.o Pico/carthw/svp/compiler.o # zlib OBJS += zlib/gzio.o zlib/inffast.o zlib/inflate.o zlib/inftrees.o zlib/trees.o \ zlib/deflate.o zlib/crc32.o zlib/adler32.o zlib/zutil.o zlib/compress.o zlib/uncompr.o -- 2.39.2