]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
68020/030 pipeline emulation Ad8r and PC8r addressing mode support.
authorToni Wilen <twilen@winuae.net>
Mon, 13 Jul 2015 18:05:26 +0000 (21:05 +0300)
committerToni Wilen <twilen@winuae.net>
Mon, 13 Jul 2015 18:05:26 +0000 (21:05 +0300)
gencpu.cpp
include/newcpu.h
newcpu.cpp

index f3210324fca580c59155e94370e59405406af6fe..b9db312fec0343c1150dc941520258214a290052 100644 (file)
@@ -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);
index 08694be4883397b1890530af07418c268d9e7103..14a96a538926b4efb209ef57420f2987c8e21727 100644 (file)
@@ -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;
index 1a6505a471edbe7656284a668c5f4b9d47bb9081..348d0c588c3022837060202042dce9784db6d985 100644 (file)
@@ -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;