From: Toni Wilen Date: Mon, 13 Jul 2015 18:05:26 +0000 (+0300) Subject: 68020/030 pipeline emulation Ad8r and PC8r addressing mode support. X-Git-Tag: 3200~133 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=5f1cae7d29276d3e2d0a928040223f873250ab3d;p=francis%2Fwinuae.git 68020/030 pipeline emulation Ad8r and PC8r addressing mode support. --- diff --git a/gencpu.cpp b/gencpu.cpp index f3210324..b9db312f 100644 --- a/gencpu.cpp +++ b/gencpu.cpp @@ -159,7 +159,7 @@ static void read_counts (void) static char endlabelstr[80]; static int endlabelno = 0; static int need_endlabel; -static int genamode_cnt; +static int genamode_cnt, genamode8r_offset[2]; static int n_braces, limit_braces; static int m68k_pc_offset, m68k_pc_offset_old; @@ -1285,7 +1285,10 @@ static void genamode2x (amodes mode, const char *reg, wordsizes size, const char rmw = true; } - genamode_cnt++; + if (mode == Ad8r || mode == PC8r) { + genamode8r_offset[genamode_cnt] = m68k_pc_total + m68k_pc_offset; + genamode_cnt++; + } start_brace (); @@ -2685,6 +2688,7 @@ static void resetvars (void) insn_n_cycles = using_prefetch ? 0 : 4; insn_n_cycles020 = 0; genamode_cnt = 0; + genamode8r_offset[0] = genamode8r_offset[1] = 0; m68k_pc_total = 0; branch_inst = 0; @@ -5513,8 +5517,8 @@ static char *outopcode (int opcode) struct cputbl_tmp { uae_s16 length; - uae_u16 disp020; - uae_u16 branch; + uae_u8 disp020[2]; + uae_u8 branch; }; static struct cputbl_tmp cputbltmp[65536]; @@ -5540,11 +5544,11 @@ static void generate_one_opcode (int rp, const char *extra) if (opcode_next_clev[rp] != cpu_level) { char *name = ua (lookuptab[idx].name); if (generate_stbl) - fprintf (stblfile, "{ %sCPUFUNC(op_%04x_%d%s), 0x%04x, %d, %d, %d }, /* %s */\n", + fprintf (stblfile, "{ %sCPUFUNC(op_%04x_%d%s), 0x%04x, %d, { %d, %d }, %d }, /* %s */\n", (using_ce || using_ce020) ? "(cpuop_func*)" : "", opcode, opcode_last_postfix[rp], extra, opcode, - cputbltmp[opcode].length, cputbltmp[opcode].disp020, cputbltmp[opcode].branch, name); + cputbltmp[opcode].length, cputbltmp[opcode].disp020[0], cputbltmp[opcode].disp020[1], cputbltmp[opcode].branch, name); xfree (name); return; } @@ -5657,17 +5661,18 @@ static void generate_one_opcode (int rp, const char *extra) if ((opcode & 0xf000) == 0xf000) m68k_pc_total = -1; cputbltmp[opcode].length = m68k_pc_total; - cputbltmp[opcode].disp020 = disp020cnt; + cputbltmp[opcode].disp020[0] = genamode8r_offset[0]; + cputbltmp[opcode].disp020[1] = genamode8r_offset[1]; cputbltmp[opcode].branch = branch_inst; if (generate_stbl) { char *name = ua (lookuptab[idx].name); if (i68000) fprintf (stblfile, "#ifndef CPUEMU_68000_ONLY\n"); - fprintf (stblfile, "{ %sCPUFUNC(op_%04x_%d%s), 0x%04x, %d, %d, %d }, /* %s */\n", + fprintf (stblfile, "{ %sCPUFUNC(op_%04x_%d%s), 0x%04x, %d, { %d, %d }, %d }, /* %s */\n", (using_ce || using_ce020) ? "(cpuop_func*)" : "", opcode, postfix, extra, opcode, - cputbltmp[opcode].length, cputbltmp[opcode].disp020, cputbltmp[opcode].branch, name); + cputbltmp[opcode].length, cputbltmp[opcode].disp020[0], cputbltmp[opcode].disp020[1], cputbltmp[opcode].branch, name); if (i68000) fprintf (stblfile, "#endif\n"); xfree (name); diff --git a/include/newcpu.h b/include/newcpu.h index 08694be4..14a96a53 100644 --- a/include/newcpu.h +++ b/include/newcpu.h @@ -59,9 +59,9 @@ typedef void REGPARAM3 cpuop_func_ce (uae_u32) REGPARAM; struct cputbl { cpuop_func *handler; uae_u16 opcode; - uae_s16 length; - uae_u16 disp020; - uae_u16 branch; + uae_s8 length; + uae_u8 disp020[2]; + uae_u8 branch; }; #ifdef JIT @@ -207,7 +207,7 @@ struct regstruct uae_u32 cacheholdingdata020; uae_u32 cacheholdingaddr020; int pipeline_pos; - bool pipeline_next; + bool pipeline_r8[2]; int pipeline_stop; int ce020memcycles; int ce020extracycles; diff --git a/newcpu.cpp b/newcpu.cpp index 1a6505a4..348d0c58 100644 --- a/newcpu.cpp +++ b/newcpu.cpp @@ -91,8 +91,8 @@ cpuop_func *cpufunctbl[65536]; struct cputbl_data { uae_s16 length; - uae_u16 disp020; - uae_u16 branch; + uae_u8 disp020[2]; + uae_u8 branch; }; static struct cputbl_data cpudatatbl[65536]; @@ -1229,7 +1229,8 @@ static void build_cpufunctbl (void) opcode = tbl[i].opcode; cpufunctbl[opcode] = tbl[i].handler; cpudatatbl[opcode].length = tbl[i].length; - cpudatatbl[opcode].disp020 = tbl[i].disp020; + cpudatatbl[opcode].disp020[0] = tbl[i].disp020[0]; + cpudatatbl[opcode].disp020[1] = tbl[i].disp020[1]; cpudatatbl[opcode].branch = tbl[i].branch; } @@ -1240,7 +1241,8 @@ static void build_cpufunctbl (void) if ((tbl[i].opcode & 0xfe00) == 0xf200) { cpufunctbl[tbl[i].opcode] = tbl[i].handler; cpudatatbl[tbl[i].opcode].length = tbl[i].length; - cpudatatbl[tbl[i].opcode].disp020 = tbl[i].disp020; + cpudatatbl[tbl[i].opcode].disp020[0] = tbl[i].disp020[0]; + cpudatatbl[tbl[i].opcode].disp020[1] = tbl[i].disp020[1]; cpudatatbl[tbl[i].opcode].branch = tbl[i].branch; } } @@ -6643,49 +6645,57 @@ static void pipeline_020(uae_u16 w, uaecptr pc) { if (regs.pipeline_pos < 0) return; -#if 0 - if (regs.pipeline_pos > 2 && regs.pipeline_next) { - // disp 020+ second word - if (w & 0x100) { - if ((w & 0x30) == 0x20) - regs.pipeline_pos += 2; - if ((w & 0x30) == 0x30) - regs.pipeline_pos += 4; - if ((w & 0x3) == 0x2) - regs.pipeline_pos += 2; - if ((w & 0x3) == 0x3) - regs.pipeline_pos += 4; - } - regs.pipeline_next = false; - } -#endif if (regs.pipeline_pos > 2) { regs.pipeline_pos -= 2; return; } + if (regs.pipeline_pos == 2) { + if (regs.pipeline_r8[0]) { + regs.pipeline_r8[0] = 0; + // disp 020+ word + if (w & 0x100) { + if ((w & 0x30) == 0x20) + regs.pipeline_pos += 2; + if ((w & 0x30) == 0x30) + regs.pipeline_pos += 4; + if ((w & 0x03) == 0x02) + regs.pipeline_pos += 2; + if ((w & 0x03) == 0x03) + regs.pipeline_pos += 4; + } + return; + } + if (regs.pipeline_r8[1]) { + regs.pipeline_r8[1] = 0; + // disp 020+ word + if (w & 0x100) { + if ((w & 0x30) == 0x20) + regs.pipeline_pos += 2; + if ((w & 0x30) == 0x30) + regs.pipeline_pos += 4; + if ((w & 0x03) == 0x02) + regs.pipeline_pos += 2; + if ((w & 0x03) == 0x03) + regs.pipeline_pos += 4; + } + return; + } + } if (regs.pipeline_stop) { regs.pipeline_stop = -1; return; } + regs.pipeline_r8[0] = cpudatatbl[w].disp020[0] != 0; + regs.pipeline_r8[1] = cpudatatbl[w].disp020[1] != 0; regs.pipeline_pos = cpudatatbl[w].length; - regs.pipeline_next = false; #if 0 if (!regs.pipeline_pos) { write_log(_T("Opcode %04x has no size PC=%08x!\n"), w, pc); } #endif - if (cpudatatbl[w].disp020) { - // not supported yet - regs.pipeline_pos = -1; -#if 0 - regs.pipeline_next = true; - regs.pipeline_pos += 2; -#endif - } - if (regs.pipeline_pos > 0 && cpudatatbl[w].branch) { regs.pipeline_pos -= 1 * 2; - if (regs.pipeline_pos <= 0) + if (regs.pipeline_pos <= 0 && !regs.pipeline_r8[0] && !regs.pipeline_r8[1]) regs.pipeline_stop = -1; else regs.pipeline_stop = 1;