]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Target EA mode MOVEM support. Accurate MOVEM bus error emulation added.
authorToni Wilen <twilen@winuae.net>
Thu, 17 Oct 2019 16:25:55 +0000 (19:25 +0300)
committerToni Wilen <twilen@winuae.net>
Thu, 17 Oct 2019 16:25:55 +0000 (19:25 +0300)
cputest.cpp
gencpu.cpp

index 7800d42a4925ff6b6708db9a98dfe0f0573ff064..96d46479a47541f9b8f0bc98d0a2ef974a08f136 100644 (file)
@@ -2589,6 +2589,11 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
 
        int sr_override = 0;
 
+       uae_u32 target_ea_bak[2], target_address_bak;
+       target_ea_bak[0] = target_ea[0];
+       target_ea_bak[1] = target_ea[1];
+       target_address_bak = target_address;
+
        for (;;) {
 
                if (quick)
@@ -2631,11 +2636,9 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                        if (dp->clev > cpu_lvl && lookup->mnemo != i_ILLG)
                                continue;
 
-                       // not supported yet in target mode
-                       if (target_address != 0xffffffff) {
-                               if (dp->mnemo == i_MVMEL || dp->mnemo == i_MVMLE)
-                                       continue;
-                       }
+                       target_ea[0] = target_ea_bak[0];
+                       target_ea[1] = target_ea_bak[1];
+                       target_address = target_address_bak;
 
                        int extra_loops = 3;
                        while (extra_loops-- > 0) {
@@ -2664,11 +2667,16 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                immabsl_cnt = 0;
                                imm_special = 0;
 
+                               target_ea[0] = target_ea_bak[0];
+                               target_ea[1] = target_ea_bak[1];
+                               target_address = target_address_bak;
+
                                // retry few times if out of bounds access
                                int oob_retries = 10;
                                // if instruction has immediate(s), repeat instruction test multiple times
                                // each round generates new random immediate(s)
                                int constant_loops = 32;
+
                                while (constant_loops-- > 0) {
                                        uae_u8 oldbytes[OPCODE_AREA];
                                        memcpy(oldbytes, opcode_memory, sizeof(oldbytes));
@@ -2683,6 +2691,10 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                        ahcnt = 0;
                                        multi_mode = 0;
 
+                                       target_ea[0] = target_ea_bak[0];
+                                       target_ea[1] = target_ea_bak[1];
+                                       target_address = target_address_bak;
+
                                        if (opc == 0x0156)
                                                printf("");
                                        if (subtest_count == 416)
@@ -2712,12 +2724,31 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                        uae_u8 *ao = opcode_memory + 2;
                                        uae_u16 apw1 = (ao[0] << 8) | (ao[1] << 0);
                                        uae_u16 apw2 = (ao[2] << 8) | (ao[3] << 0);
-                                       if (opc == 0x3fb2
-                                               && apw1 == 0xa190
-                                               && apw2 == 0x2770
+                                       if (opc == 0x48a8
+                                               && apw1 == 0x0000
+                                               //&& apw2 == 0xfff0
                                                )
                                                printf("");
 
+                                       if (target_address != 0xffffffff && (dp->mnemo == i_MVMEL || dp->mnemo == i_MVMLE)) {
+                                               // if MOVEM and more than 1 register: randomize address so that any MOVEM
+                                               // access can hit target address
+                                               uae_u16 mask = (opcode_memory[2] << 8) | opcode_memory[3];
+                                               int count = 0;
+                                               for (int i = 0; i < 16; i++) {
+                                                       if (mask & (1 << i))
+                                                               count++;
+                                               }
+                                               if (count > 0) {
+                                                       int diff = (rand8() % count);
+                                                       if (dp->dmode == Apdi) {
+                                                               diff = -diff;
+                                                       }
+                                                       target_address -= diff * (1 << dp->size);
+                                                       target_ea[1] = target_address;
+                                               }
+                                       }
+
                                        // if source EA modified opcode
                                        dp = table68k + opc;
 
index 4d95a11a316bfe104fd78f7c53003b076e4a8a3b..14a51e12b01c8438a9cee995eaafe9cdf1c1bf91 100644 (file)
@@ -1450,6 +1450,10 @@ static void check_bus_error(const char *name, int offset, int write, int fc)
                        // BTST special case where destination is read access
                        fc = 2;
                }
+               if (g_instr->mnemo == i_MVMEL && (g_instr->dmode == PC16 || g_instr->dmode == PC8r)) {
+                       // MOVEM to registers
+                       fc = 2;
+               }
 
                printf("\t\texception2_%s(opcode, %sa + %d, %d);\n",
                        write ? "write" : "read", name, offset,
@@ -1602,7 +1606,7 @@ static void addopcycles_ce20 (int h, int t, int c, int subhead, int flags)
 //             printf ("\tint op_cycles = get_cycles ();\n");
 }
 
-static void addop_ce020 (instr *curi, int subhead, int flags)
+static void addop_ce020 (struct instr *curi, int subhead, int flags)
 {
        if (isce020()) {
                int h = curi->head;
@@ -3156,48 +3160,57 @@ static void genmovemel (uae_u16 opcode)
 static void genmovemel_ce (uae_u16 opcode)
 {
        int size = table68k[opcode].size == sz_long ? 4 : 2;
-       printf ("\tuae_u16 mask = %s;\n", gen_nextiword (0));
-       printf ("\tuae_u32 dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n");
+       printf("\tuae_u16 mask = %s;\n", gen_nextiword (0));
+       printf("\tuae_u32 dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n");
        if (table68k[opcode].dmode == Ad8r || table68k[opcode].dmode == PC8r)
-               addcycles000 (2);
-       genamode (NULL, table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, -1, GF_AA | GF_MOVE);
+               addcycles000(2);
+       genamode(NULL, table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, -1, GF_AA | GF_MOVE);
        movem_ex3(0);
-       start_brace ();
+       start_brace();
        if (table68k[opcode].size == sz_long) {
-               printf ("\twhile (dmask) {\n");
-               printf ("\t\tuae_u32 v = %s (srca) << 16;\n", srcw);
-               printf ("\t\tv |= %s (srca + 2);\n", srcw);
-               printf ("\t\tm68k_dreg (regs, movem_index1[dmask]) = v;\n");
-               printf ("\t\tsrca += %d;\n", size);
-               printf ("\t\tdmask = movem_next[dmask];\n");
+               printf("\twhile (dmask) {\n");
+               printf("\t\tuae_u32 v = %s (srca) << 16;\n", srcw);
+               check_bus_error("src", 0, 0, 1);
+               printf("\t\tv |= %s (srca + 2);\n", srcw);
+               check_bus_error("src", 2, 0, 1);
+               printf("\t\tm68k_dreg (regs, movem_index1[dmask]) = v;\n");
+               printf("\t\tsrca += %d;\n", size);
+               printf("\t\tdmask = movem_next[dmask];\n");
                addcycles000_nonce("\t\t", 8);
-               printf ("\t}\n");
-               printf ("\twhile (amask) {\n");
-               printf ("\t\tuae_u32 v = %s (srca) << 16;\n", srcw);
-               printf ("\t\tv |= %s (srca + 2);\n", srcw);
-               printf ("\t\tm68k_areg (regs, movem_index1[amask]) = v;\n");
-               printf ("\t\tsrca += %d;\n", size);
-               printf ("\t\tamask = movem_next[amask];\n");
+               printf("\t}\n");
+               printf("\twhile (amask) {\n");
+               printf("\t\tuae_u32 v = %s (srca) << 16;\n", srcw);
+               check_bus_error("src", 0, 0, 1);
+               printf("\t\tv |= %s (srca + 2);\n", srcw);
+               check_bus_error("src", 2, 0, 1);
+               printf("\t\tm68k_areg (regs, movem_index1[amask]) = v;\n");
+               printf("\t\tsrca += %d;\n", size);
+               printf("\t\tamask = movem_next[amask];\n");
                addcycles000_nonce("\t\t", 8);
-               printf ("\t}\n");
+               printf("\t}\n");
        } else {
-               printf ("\twhile (dmask) {\n");
-               printf ("\t\tm68k_dreg (regs, movem_index1[dmask]) = (uae_s32)(uae_s16)%s (srca);\n", srcw);
-               printf ("\t\tsrca += %d;\n", size);
-               printf ("\t\tdmask = movem_next[dmask];\n");
+               printf("\twhile (dmask) {\n");
+               printf("\t\tuae_u32 v = (uae_s32)(uae_s16)%s (srca);\n", srcw);
+               check_bus_error("src", 0, 0, 1);
+               printf("\t\tm68k_dreg (regs, movem_index1[dmask]) = v;\n");
+               printf("\t\tsrca += %d;\n", size);
+               printf("\t\tdmask = movem_next[dmask];\n");
                addcycles000_nonce("\t\t", 4);
-               printf ("\t}\n");
-               printf ("\twhile (amask) {\n");
-               printf ("\t\tm68k_areg (regs, movem_index1[amask]) = (uae_s32)(uae_s16)%s (srca);\n", srcw);
-               printf ("\t\tsrca += %d;\n", size);
-               printf ("\t\tamask = movem_next[amask];\n");
+               printf("\t}\n");
+               printf("\twhile (amask) {\n");
+               printf("\t\tuae_u32 v = (uae_s32)(uae_s16)%s (srca);\n", srcw);
+               check_bus_error("src", 0, 0, 1);
+               printf("\t\tm68k_areg (regs, movem_index1[amask]) = v;\n");
+               printf("\t\tsrca += %d;\n", size);
+               printf("\t\tamask = movem_next[amask];\n");
                addcycles000_nonce("\t\t", 4);
-               printf ("\t}\n");
+               printf("\t}\n");
        }
-       printf ("\t%s (srca);\n", srcw); // and final extra word fetch that goes nowhere..
+       printf("\t%s (srca);\n", srcw); // and final extra word fetch that goes nowhere..
+       check_bus_error("src", 0, 0, 1);
        count_read++;
        if (table68k[opcode].dmode == Aipi)
-               printf ("\tm68k_areg (regs, dstreg) = srca;\n");
+               printf("\tm68k_areg (regs, dstreg) = srca;\n");
        count_ncycles++;
        fill_prefetch_next ();
 }
@@ -3279,14 +3292,18 @@ static void genmovemle_ce (uae_u16 opcode)
                        movem_ex3(1);
                        printf ("\twhile (amask) {\n");
                        printf ("\t\t%s (srca - 2, m68k_areg (regs, movem_index2[amask]));\n", dstw);
+                       check_bus_error("src", -2, 1, 1);
                        printf ("\t\t%s (srca - 4, m68k_areg (regs, movem_index2[amask]) >> 16);\n", dstw);
+                       check_bus_error("src", -4, 1, 1);
                        printf("\t\tsrca -= %d;\n", size);
                        printf ("\t\tamask = movem_next[amask];\n");
                        addcycles000_nonce("\t\t", 8);
                        printf ("\t}\n");
                        printf ("\twhile (dmask) {\n");
                        printf ("\t\t%s (srca - 2, m68k_dreg (regs, movem_index2[dmask]));\n", dstw);
+                       check_bus_error("src", -2, 1, 1);
                        printf ("\t\t%s (srca - 4, m68k_dreg (regs, movem_index2[dmask]) >> 16);\n", dstw);
+                       check_bus_error("src", -4, 1, 1);
                        printf("\t\tsrca -= %d;\n", size);
                        printf ("\t\tdmask = movem_next[dmask];\n");
                        addcycles000_nonce("\t\t", 8);
@@ -3297,14 +3314,18 @@ static void genmovemle_ce (uae_u16 opcode)
                        movem_ex3(1);
                        printf ("\twhile (dmask) {\n");
                        printf ("\t\t%s (srca, m68k_dreg (regs, movem_index1[dmask]) >> 16);\n", dstw);
+                       check_bus_error("src", 0, 1, 1);
                        printf ("\t\t%s (srca + 2, m68k_dreg (regs, movem_index1[dmask]));\n", dstw);
+                       check_bus_error("src", 2, 1, 1);
                        printf ("\t\tsrca += %d;\n", size);
                        printf ("\t\tdmask = movem_next[dmask];\n");
                        addcycles000_nonce("\t\t", 8);
                        printf ("\t}\n");
                        printf ("\twhile (amask) {\n");
                        printf ("\t\t%s (srca, m68k_areg (regs, movem_index1[amask]) >> 16);\n", dstw);
+                       check_bus_error("src", 0, 1, 1);
                        printf ("\t\t%s (srca + 2, m68k_areg (regs, movem_index1[amask]));\n", dstw);
+                       check_bus_error("src", 2, 1, 1);
                        printf ("\t\tsrca += %d;\n", size);
                        printf ("\t\tamask = movem_next[amask];\n");
                        addcycles000_nonce("\t\t", 8);
@@ -3317,12 +3338,14 @@ static void genmovemle_ce (uae_u16 opcode)
                        printf ("\twhile (amask) {\n");
                        printf ("\t\tsrca -= %d;\n", size);
                        printf ("\t\t%s (srca, m68k_areg (regs, movem_index2[amask]));\n", dstw);
+                       check_bus_error("src", 0, 1, 1);
                        printf ("\tamask = movem_next[amask];\n");
                        addcycles000_nonce("\t\t", 4);
                        printf ("\t}\n");
                        printf ("\twhile (dmask) {\n");
                        printf ("\t\tsrca -= %d;\n", size);
                        printf ("\t\t%s (srca, m68k_dreg (regs, movem_index2[dmask]));\n", dstw);
+                       check_bus_error("src", 0, 1, 1);
                        printf ("\t\tdmask = movem_next[dmask];\n");
                        addcycles000_nonce("\t\t", 4);
                        printf ("\t}\n");
@@ -3332,12 +3355,14 @@ static void genmovemle_ce (uae_u16 opcode)
                        movem_ex3(1);
                        printf ("\twhile (dmask) {\n");
                        printf ("\t\t%s (srca, m68k_dreg (regs, movem_index1[dmask]));\n", dstw);
+                       check_bus_error("src", 0, 1, 1);
                        printf ("\t\tsrca += %d;\n", size);
                        printf ("\t\tdmask = movem_next[dmask];\n");
                        addcycles000_nonce("\t\t", 4);
                        printf ("\t}\n");
                        printf ("\twhile (amask) {\n");
                        printf ("\t\t%s (srca, m68k_areg (regs, movem_index1[amask]));\n", dstw);
+                       check_bus_error("src", 0, 1, 1);
                        printf ("\t\tsrca += %d;\n", size);
                        printf ("\t\tamask = movem_next[amask];\n");
                        addcycles000_nonce("\t\t", 4);