From: Toni Wilen Date: Mon, 2 Dec 2019 18:03:31 +0000 (+0200) Subject: Improved BSR,Bcc,DBcc bus/address error checks added and emulation updated to handle... X-Git-Tag: 4300~31 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=e5cd7ae6e669ed9ec9a594e5e916143fd44e62fe;p=francis%2Fwinuae.git Improved BSR,Bcc,DBcc bus/address error checks added and emulation updated to handle prefetch special cases. Default stack space moved to beginning of test space to make bus error testing simpler. --- diff --git a/cputest.cpp b/cputest.cpp index 54c96c56..78507564 100644 --- a/cputest.cpp +++ b/cputest.cpp @@ -2106,9 +2106,10 @@ static int create_ea_exact(uae_u16 *opcodep, uaecptr pc, int mode, int reg, stru break; case imm0: { + uae_u16 v; if (srcdst) return -2; - uae_u16 v = rand16(); + v = rand16(); if ((imm8_cnt & 3) == 0) v &= 0xff; imm8_cnt++; @@ -2117,20 +2118,59 @@ static int create_ea_exact(uae_u16 *opcodep, uaecptr pc, int mode, int reg, stru } case imm1: { - if (srcdst) + bool vgot = false; + uae_u16 v; + if (srcdst && dp->mnemo != i_DBcc) return -2; - uae_u16 v = rand16(); + if (dp->mnemo == i_DBcc || dp->mnemo == i_BSR || dp->mnemo == i_Bcc) { + uae_u32 pct = pc + 2 - 2; + if (target <= pct + 0x7ffe && target >= pct - 0x8000) { + v = target - pct; + *eap = target; + vgot = true; + } else { + return -2; + } + } + if (!vgot) + v = rand16(); put_word_test(pc, v); return 2; } case imm2: { + bool vgot = false; + uae_u32 v; if (srcdst) return -2; - uae_u32 v = rand32(); + if (dp->mnemo == i_BSR || dp->mnemo == i_Bcc) { + if (currprefs.cpu_model < 68020) + return -2; + uae_u32 pct = pc + 2 - 2; + v = target - pct; + *eap = target; + vgot = true; + } + if (!vgot) { + v = rand32(); + } put_long_test(pc, v); return 4; } + case immi: + { + uae_u8 v = (*opcodep) & 0xff; + if (srcdst) + return -2; + if (dp->mnemo == i_BSR || dp->mnemo == i_Bcc) { + uae_u32 pct = pc - 2 + 2; + if (pct + v == target) { + *eap = target; + return 0; + } + } + return -2; + } } return -2; } @@ -2423,8 +2463,8 @@ static void execute_ins(uae_u16 opc, uaecptr endpc, uaecptr targetpc, struct ins { uae_u16 opw1 = (opcode_memory[2] << 8) | (opcode_memory[3] << 0); uae_u16 opw2 = (opcode_memory[4] << 8) | (opcode_memory[5] << 0); - if (opc == 0x4ea9 - && opw1 == 0xffff + if (opc == 0x6200 + //&& opw1 == 0xffff //&& opw2 == 0xf78c ) printf(""); @@ -2519,7 +2559,7 @@ static void execute_ins(uae_u16 opc, uaecptr endpc, uaecptr targetpc, struct ins if (!valid_address(regs.pc, 2, 0)) break; - if (targetpc != 0xffffffff && regs.pc + 2 == targetpc) { + if (targetpc != 0xffffffff && (regs.pc + 2 == targetpc || regs.pc + 2 == endpc)) { // trace after jumping to branch target // and opcode was NOP if (SPCFLAG_DOTRACE) { @@ -2970,6 +3010,13 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi uae_u32 dstaddr = 0xffffffff; uae_u32 branchtarget_old = 0xffffffff; + if (verbose) { + if (target_ea[0] != 0xffffffff) + wprintf(_T("Targeat EA SRC=%08x\n"), target_ea[0]); + if (target_ea[1] != 0xffffffff) + wprintf(_T("Targeat EA DST=%08x\n"), target_ea[1]); + } + for (int opcode = 0; opcode < 65536; opcode++) { struct instr *dp = table68k + opcode; @@ -3294,12 +3341,10 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi branch_target_swap_address = srcaddr; branch_target_swap_mode = 1; put_long_test(srcaddr, branch_target_data); - } else { - if (!is_nowrite_address(srcaddr, 2)) { - put_word_test(srcaddr, branch_target_data >> 16); - branch_target_swap_address = srcaddr; - branch_target_swap_mode = 2; - } + } else if (!is_nowrite_address(srcaddr, 2)) { + put_word_test(srcaddr, branch_target_data >> 16); + branch_target_swap_address = srcaddr; + branch_target_swap_mode = 2; } branch_target = srcaddr; dst = store_mem(dst, 1); @@ -3410,6 +3455,8 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi put_word_test(branch_target_swap_address, branch_target_data >> 16); } noaccesshistory--; + } else { + branch_target_pc = branch_target; } regs.pc = opcode_memory_start; @@ -4139,7 +4186,7 @@ int __cdecl main(int argc, char *argv[]) } v = 0; - if (ini_getval(ini, INISECTION, _T("feature_opcode_memory"), &v)) { + if (ini_getval(ini, INISECTION, _T("opcode_memory_start"), &v)) { opcode_memory_start = v; opcode_memory = test_memory + (opcode_memory_start - test_memory_start); } else { @@ -4154,8 +4201,8 @@ int __cdecl main(int argc, char *argv[]) super_stack_memory = v; user_stack_memory = super_stack_memory - (RESERVED_SUPERSTACK + RESERVED_USERSTACK_EXTRA); } else { - super_stack_memory = test_memory_end; - user_stack_memory = test_memory_end - (RESERVED_SUPERSTACK + RESERVED_USERSTACK_EXTRA); + super_stack_memory = test_memory_start + (2 * RESERVED_SUPERSTACK + RESERVED_USERSTACK_EXTRA); + user_stack_memory = test_memory_start + RESERVED_SUPERSTACK; } low_memory_size = test_low_memory_end; diff --git a/cputest/cputestgen.ini b/cputest/cputestgen.ini index 5cd2e95a..c1ac63c6 100644 --- a/cputest/cputestgen.ini +++ b/cputest/cputestgen.ini @@ -32,12 +32,16 @@ test_high_memory_end=0x01000000 high_rom=D:\amiga\roms\Kickstart v3.1 rev 40.63 (1993)(Commodore)(A500-A600-A2000)[!].rom ; main test memory start and size (real hardware must have RAM in this address space) -test_memory_start=0x780000 +test_memory_start=0x800000 ;test_memory_start=0x68800000 ;test_memory_start=0x07800000 -;test_memory_start=0x08800000 +;test_memory_start=0x00800000 ;test_memory_start=0x340000 -test_memory_size=0x080000 +test_memory_size=0x1c0000 + +; address where test instructions are located +; if not defined: mid point of test memory +opcode_memory_start=0x87ffa0 ; number of test rounds ; registers are re-randomized after each round if not in target ea mode. @@ -60,13 +64,15 @@ feature_exception3_instruction=0 ; Supports 68000 addressing modes only. ; If instruction only has destination EA, source Areg, Dreg or immediate is generated. feature_target_src_ea= -feature_target_dst_ea= +;feature_target_dst_ea=0x87fffa,0x87fffb,0x87fffc,0x87fffd,0x87fffe,0x87ffff,0x880000,0x880001,0x880002,0x880003,0x880004 ; Memory region that generates bus error (both read and write). ; Must be inside any test memory region. ; Can be used to verify bus errors if ea above is inside this memory region. -feature_safe_memory_start= -feature_safe_memory_size= +;feature_safe_memory_start=0x880000 +;feature_safe_memory_size=0x80000 +; R = read only bus error, W = write only bus error, empty or RW = both. +;feature_safe_memory_mode=R ; CCR/FPU status flags mode ; 0 = all combinations (32 CCR loops, 256 FPU loops) @@ -87,7 +93,7 @@ feature_min_interrupt_mask=0 ; Other bits are ignored. ; For example 0xa000 adds 3 extra test rounds: S=1/T1=0, S=0/T1=1 and S=1/T1=1 ; Note: instructions that generate privilege violation exception will automatically add extra S=1 round. -feature_sr_mask=0x0000 +feature_sr_mask=0xa000 ; generate loop test: label: dbf dn,label ; value: 0 = disabled, >0 = number of loops diff --git a/gencpu.cpp b/gencpu.cpp index d9614805..722990e1 100644 --- a/gencpu.cpp +++ b/gencpu.cpp @@ -860,6 +860,25 @@ static void fill_prefetch_full (void) } } +static void fill_prefetch_full_000_special(void) +{ + if (!using_prefetch) + return; + printf("\t%s (%d);\n", prefetch_word, 0); + check_prefetch_bus_error(-1, -1); + irc2ir(); + if (using_bus_error) { + printf("\topcode = regs.ir;\n"); + printf("\tif(regs.t1) opcode |= 0x10000;\n"); + } + printf("\t%s (%d);\n", prefetch_word, 2); + check_prefetch_bus_error(-2, -1); + did_prefetch = 1; + ir2irc = 0; + count_read += 2 * 1; + insn_n_cycles += 2 * 4; +} + // 68000 and 68010 only static void fill_prefetch_full_000 (void) { @@ -3271,7 +3290,7 @@ static void genmovemel_ce (uae_u16 opcode) check_bus_error("src", 0, 0, 1, NULL, 1); printf("\t\tm68k_dreg(regs, movem_index1[dmask]) = v;\n"); printf("\t\tv &= 0xffff0000;\n"); - printf("\t\tv |= % s(srca + 2); \n", srcw); + printf("\t\tv |= %s(srca + 2); \n", srcw); check_bus_error("src", 2, 0, 1, NULL, 1); printf("\t\tm68k_dreg(regs, movem_index1[dmask]) = v;\n"); printf("\t\tsrca += %d;\n", size); @@ -4301,7 +4320,7 @@ static void gen_opcode (unsigned int opcode) genamode(curi, curi->smode, "srcreg", curi->size, "src", 3, 0, 0); if (isreg(curi->smode) && curi->size == sz_long) addcycles000(2); - if (!isreg(curi->smode) && using_exception_3 && (using_prefetch || using_ce)) { + if (!isreg(curi->smode) && using_exception_3 && curi->size != sz_byte && (using_prefetch || using_ce)) { printf("\tif(srca & 1) {\n"); printf("\t\texception3_write(opcode, srca, 1, 0, 1);\n"); printf("\t\tgoto %s;\n", endlabelstr); @@ -4963,8 +4982,12 @@ static void gen_opcode (unsigned int opcode) /* PC is set and prefetch filled. */ clear_m68k_offset(); tail_ce020_done = true; - fill_prefetch_full (); - need_endlabel = 1; + if (using_prefetch || using_ce) { + fill_prefetch_full_000_special(); + } else { + fill_prefetch_full(); + } + need_endlabel = 1; branch_inst = 1; next_level_040_to_030(); break; @@ -5068,7 +5091,11 @@ static void gen_opcode (unsigned int opcode) printf ("\t}\n"); count_read += 2; clear_m68k_offset(); - fill_prefetch_full (); + if (using_prefetch || using_ce) { + fill_prefetch_full_000_special(); + } else { + fill_prefetch_full(); + } need_endlabel = 1; branch_inst = 1; next_level_040_to_030(); @@ -5107,8 +5134,12 @@ static void gen_opcode (unsigned int opcode) printf("\t}\n"); } clear_m68k_offset(); - fill_prefetch_full (); - need_endlabel = 1; + if (using_prefetch || using_ce) { + fill_prefetch_full_000_special(); + } else { + fill_prefetch_full(); + } + need_endlabel = 1; branch_inst = 1; tail_ce020_done = true; next_level_040_to_030(); @@ -5228,8 +5259,8 @@ static void gen_opcode (unsigned int opcode) check_prefetch_bus_error(-2, sp); did_prefetch = 1; ir2irc = 0; - count_read++; - insn_n_cycles += 4; + count_read += 2 * 1; + insn_n_cycles += 2 * 4; } else { fill_prefetch_full(); } @@ -5313,7 +5344,11 @@ static void gen_opcode (unsigned int opcode) } count_write += 2; clear_m68k_offset(); - fill_prefetch_full (); + if (using_prefetch || using_ce) { + fill_prefetch_full_000_special(); + } else { + fill_prefetch_full(); + } branch_inst = 1; break; case i_Bcc: @@ -5356,7 +5391,7 @@ static void gen_opcode (unsigned int opcode) push_ins_cnt(); if (using_prefetch) { incpc ("(uae_s32)src + 2"); - fill_prefetch_full_000 (); + fill_prefetch_full_000_special(); if (using_ce) printf ("\treturn;\n"); else @@ -5379,10 +5414,10 @@ static void gen_opcode (unsigned int opcode) fill_prefetch_2 (); } else if (curi->size == sz_word) { add_head_cycs (6); - fill_prefetch_full_000 (); + fill_prefetch_full_000_special(); } else { add_head_cycs (6); - fill_prefetch_full_000 (); + fill_prefetch_full_000_special(); } insn_n_cycles = curi->size == sz_byte ? 8 : 12; branch_inst = 1; @@ -5453,7 +5488,18 @@ bccl_not68020: printf ("\t\tif (src) {\n"); irc2ir (); add_head_cycs (6); - fill_prefetch_1 (2); + + if (using_prefetch || using_ce) { + printf("\topcode = regs.ir;\n"); + printf("\tif(regs.t1) opcode |= 0x10000;\n"); + printf("\t%s (%d);\n", prefetch_word, 2); + check_prefetch_bus_error(-2, -1); + did_prefetch = 1; + ir2irc = 0; + count_read++; + insn_n_cycles += 4; + } + fill_prefetch_full_020 (); returncycles ("\t\t\t", 10); printf ("\t\t}\n"); @@ -5467,7 +5513,7 @@ bccl_not68020: setpc ("oldpc + %d", m68k_pc_offset); clear_m68k_offset(); get_prefetch_020_continue (); - fill_prefetch_full_000 (); + fill_prefetch_full_000_special(); insn_n_cycles = 12; need_endlabel = 1; branch_inst = 1;