From: Toni Wilen Date: Thu, 17 Oct 2019 16:25:55 +0000 (+0300) Subject: Target EA mode MOVEM support. Accurate MOVEM bus error emulation added. X-Git-Tag: 4300~81 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=264201ea0765cf521e19794eb22fb2a3bf79d5a9;p=francis%2Fwinuae.git Target EA mode MOVEM support. Accurate MOVEM bus error emulation added. --- diff --git a/cputest.cpp b/cputest.cpp index 7800d42a..96d46479 100644 --- a/cputest.cpp +++ b/cputest.cpp @@ -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; diff --git a/gencpu.cpp b/gencpu.cpp index 4d95a11a..14a51e12 100644 --- a/gencpu.cpp +++ b/gencpu.cpp @@ -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);