]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Address error updates and misc fixes.
authorToni Wilen <twilen@winuae.net>
Mon, 3 Feb 2020 17:28:59 +0000 (19:28 +0200)
committerToni Wilen <twilen@winuae.net>
Mon, 3 Feb 2020 17:28:59 +0000 (19:28 +0200)
cputest.cpp
gencpu.cpp
include/newcpu.h
newcpu.cpp

index 2e33edc0185f5c368cdd7f25258a18d78abfe0ae..e324a661e8f0d425e1975d8ce1929541a8f0f013 100644 (file)
@@ -1184,6 +1184,25 @@ void exception3_write(uae_u32 opcode, uae_u32 addr, int size, uae_u32 val, int f
        doexcstack();
 }
 
+void exception3_read_opcode(uae_u32 opcode, uae_u32 addr, int size, int fc)
+{
+       add_memory_cycles(1);
+       exception3_read(opcode, addr, size, fc);
+}
+
+void exception3_write_opcode(uae_u32 opcode, uae_u32 addr, int size, uae_u32 val, int fc)
+{
+       add_memory_cycles(1);
+       exception3_write(opcode, addr, size, val, fc);
+
+}
+
+uae_u16 exception3_word_read(uaecptr addr)
+{
+       add_memory_cycles(1);
+       return 0;
+}
+
 void REGPARAM2 Exception(int n)
 {
        test_exception = n;
@@ -2171,6 +2190,16 @@ static int create_ea_random(uae_u16 *opcodep, uaecptr pc, int mode, int reg, str
                                                *isconstant = 0;
                                        else
                                                *isconstant = -1;
+                               } else if (dp->mnemo == i_BSR || dp->mnemo == i_DBcc || dp->mnemo == i_Bcc ||
+                                       dp->mnemo == i_ORSR || dp->mnemo == i_ANDSR || dp->mnemo == i_EORSR) {
+                                       // don't try to test all 65536 possibilies..
+                                       uae_u16 i16 = imm16_cnt;
+                                       put_word_test(pc, imm16_cnt);
+                                       imm16_cnt += rand16() & 127;
+                                       if (i16 > imm16_cnt)
+                                               *isconstant = 0;
+                                       else
+                                               *isconstant = -1;
                                } else {
                                        put_word_test(pc, imm16_cnt++);
                                        if (imm16_cnt == 0)
@@ -4081,10 +4110,6 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                                                if (test_exception != 3) {
                                                                        skipped = 1;
                                                                }
-                                                               // need also extra exception
-                                                               if (!exception_extra_frame_type) {
-                                                                       skipped = 1;
-                                                               }
                                                        }
 
                                                        if (cpu_stopped) {
@@ -4699,9 +4724,8 @@ static int test(struct ini_data *ini, const TCHAR *sections, const TCHAR *testna
        safe_memory_end = 0xffffffff;
        if (ini_getvalx(ini, sections, _T("feature_safe_memory_size"), &v))
                safe_memory_end = safe_memory_start + v;
-       safe_memory_mode = 7;
+       safe_memory_mode = 0;
        if (ini_getstringx(ini, sections, _T("feature_safe_memory_mode"), &vs)) {
-               safe_memory_mode = 0;
                if (_totupper(vs[0]) == 'R')
                        safe_memory_mode |= 1;
                if (_totupper(vs[0]) == 'W')
@@ -4749,7 +4773,9 @@ static int test(struct ini_data *ini, const TCHAR *sections, const TCHAR *testna
                        }
                        if (i == 2) {
                                target_ea_opcode_max = cnt;
-                               safe_memory_mode = 7;
+                               if (cnt > 0) {
+                                       safe_memory_mode = 7;
+                               }
                        } else if (i) {
                                target_ea_dst_max = cnt;
                        } else {
@@ -5164,6 +5190,7 @@ static int test(struct ini_data *ini, const TCHAR *sections, const TCHAR *testna
                }
 
                if (!_tcsicmp(mode, _T("branch")) || !_tcsicmp(mode, _T("branchj")) || !_tcsicmp(mode, _T("branchs"))) {
+
                        static const TCHAR *branchs[] = {
                                _T("RTS"), _T("RTD"), _T("RTR"), _T("RTE"), _T("JSR"), _T("BSR"), NULL
                        };
@@ -5180,6 +5207,7 @@ static int test(struct ini_data *ini, const TCHAR *sections, const TCHAR *testna
                                        test_mnemo_text(path, branchs[i]);
                                }
                        }
+                       break;
                }
 
                if (!_tcsicmp(mode, _T("fall"))) {
index 5d44ef97ec0553a96ee54d51bb71594bcb595476..fd11cb2b49cc84b4ca99923032360f85cdd7dd8b 100644 (file)
@@ -3097,7 +3097,7 @@ static void genamode2x (amodes mode, const char *reg, wordsizes size, const char
                        strcpy(g_srcname, name);        
        }
 
-       if (mode >= Ad16) {
+       if (mode >= Ad16 && mode < am_unknown) {
                do_instruction_buserror();
        }
 
@@ -3155,14 +3155,6 @@ static void genamode2x (amodes mode, const char *reg, wordsizes size, const char
 
                if (cpu_level == 1) {
                        int bus_error_reg_add_old = bus_error_reg_add;
-                       // 68010 does dummy access
-                       if (getv != 2) {
-                               if ((flags & GF_REVERSE) && size == sz_long) {
-                                       out("uae_s16 d_%s = %s((%sa + 2) & ~1);\n", name, srcw, name);
-                               } else {
-                                       out("uae_s16 d_%s = %s(%sa & ~1);\n", name, srcw, name);
-                               }
-                       }
                        if (abs(bus_error_reg_add) == 4)
                                bus_error_reg_add = 0;
                        // 68010 CLR <memory>: pre and post are not added yet
@@ -3233,13 +3225,13 @@ static void genamode2x (amodes mode, const char *reg, wordsizes size, const char
 
                if (exp3rw) {
                        const char *shift = (size == sz_long && !(flags & GF_REVERSE)) ? " >> 16" : "";
-                       out("exception3_write(opcode, %sa, %d, %s%s, %d);\n",
+                       out("exception3_write_opcode(opcode, %sa, %d, %s%s, %d);\n",
                                name, size, g_srcname, shift,
                                // PC-relative: FC=2
                                (getv == 1 && (g_instr->smode == PC16 || g_instr->smode == PC8r) ? 2 : 1) | fcmodeflags);
 
                } else {
-                       out("exception3_read(opcode, %sa, %d, %d);\n",
+                       out("exception3_read_opcode(opcode, %sa, %d, %d);\n",
                                name, size,
                                // PC-relative: FC=2
                                (getv == 1 && (g_instr->smode == PC16 || g_instr->smode == PC8r) ? 2 : 1) | fcmodeflags);
@@ -4015,16 +4007,13 @@ static void movem_ex3(int write)
                                out("opcode |= 0x00020000;\n");
                        }
                        out("uaecptr srcav = srca;\n");
-                       if (cpu_level == 1) {
-                               out("uae_s16 dummy = %s(srca & ~1);\n", srcw);
-                       }
                }
                if (write) {
-                       out("exception3_write(opcode, srca, %d, srcav, %d);\n",
+                       out("exception3_write_opcode(opcode, srca, %d, srcav, %d);\n",
                                g_instr->size,
                                (g_instr->dmode == PC16 || g_instr->dmode == PC8r) ? 2 : 1);
                } else {
-                       out("exception3_read(opcode, srca, %d, %d);\n",
+                       out("exception3_read_opcode(opcode, srca, %d, %d);\n",
                                g_instr->size,
                                (g_instr->dmode == PC16 || g_instr->dmode == PC8r) ? 2 : 1);
                }
@@ -6135,10 +6124,22 @@ static void gen_opcode (unsigned int opcode)
                }
                if (cpu_level == 0) {
                        // 68000
-                       // Read SR, Read PC high, Read PC low.
-                       genamode(NULL, Aipi, "7", sz_word, "sr", 1, 0, GF_NOREFILL);
-                       genamode(NULL, Aipi, "7", sz_long, "pc", 1, 0, GF_NOREFILL);
+                       // Read SR (SP+=6), Read PC high, Read PC low.
                        out("uaecptr oldpc = %s;\n", getpc);
+                       out("uaecptr a = m68k_areg(regs, 7);\n");
+                       out("uae_u16 sr = %s(a);\n", srcw);
+                       count_read++;
+                       check_bus_error("", 0, 0, 1, NULL, 1);
+
+                       out("m68k_areg(regs, 7) += 6;\n");
+
+                       out("uae_u32 pc = %s(a + 2) << 16;\n", srcw);
+                       count_read++;
+                       check_bus_error("", 2, 0, 1, NULL, 1);
+                       out("pc |= %s(a + 2 + 2); \n", srcw);
+                       count_read++;
+                       check_bus_error("", 4, 0, 1, NULL, 1);
+
                        out("uae_u16 oldt1 = regs.t1;\n");
                        out("regs.sr = sr;\n");
                        makefromsr();
@@ -6505,6 +6506,13 @@ static void gen_opcode (unsigned int opcode)
                }
                break;
        case i_RTR:
+               if (cpu_level <= 1 && using_exception_3) {
+                       // RTR (and RTS) exception3 does not have normal 4 cycle delay
+                       out("if (m68k_areg(regs, 7) & 1) {\n");
+                       out("exception3_read(opcode, m68k_areg(regs, 7), 1, 1);\n");
+                       write_return_cycles(0);
+                       out("}\n");
+               }
                out("uaecptr oldpc = %s;\n", getpc);
                out("MakeSR();\n");
                genamode(NULL, Aipi, "7", sz_word, "sr", 1, 0, 0);
index 216b346c1f6480bd5e64fd13a07c9fe0edbcf141..74f2d9b76b8d52c52dc2e5e42cfb13c019b46258 100644 (file)
@@ -730,6 +730,8 @@ extern int fpp_cond(int condition);
 
 extern void exception3_read(uae_u32 opcode, uaecptr addr, int size, int fc);
 extern void exception3_write(uae_u32 opcode, uaecptr addr, int size, uae_u32 val, int fc);
+extern void exception3_read_opcode(uae_u32 opcode, uaecptr addr, int size, int fc);
+extern void exception3_write_opcode(uae_u32 opcode, uaecptr addr, int size, uae_u32 val, int fc);
 extern void exception3_notinstruction(uae_u32 opcode, uaecptr addr);
 extern void exception3i (uae_u32 opcode, uaecptr addr);
 extern void exception3b (uae_u32 opcode, uaecptr addr, bool w, bool i, uaecptr pc);
index 39f281f0d261961f292ef5e463340caacfe199d8..20dabbab65a2558cc216793453f1eabce87ce734 100644 (file)
@@ -2358,6 +2358,7 @@ static void exception_debug (int nr)
 
 Address/Bus Error:
 
+- [memory access causing bus/address error]
 - 8 idle cycles
 - write PC low word
 - write SR
@@ -2495,7 +2496,7 @@ static void Exception_ce000 (int nr)
                if (nr == 7) // TRAPV
                        start = 0;
                else if (nr == 2 || nr == 3)
-                       start = 4 + 8;
+                       start = 8;
        }
 
        if (start)
@@ -2521,7 +2522,7 @@ static void Exception_ce000 (int nr)
                        uae_u16 mode = (sv ? 4 : 0) | last_fc_for_exception_3;
                        mode |= last_writeaccess_for_exception_3 ? 0 : 16;
                        mode |= last_notinstruction_for_exception_3 ? 8 : 0;
-                       // undocumented bits seem to contain opcode
+                       // undocumented bits contain opcode
                        mode |= last_op_for_exception_3 & ~31;
                        m68k_areg(regs, 7) -= 14;
                        exception_in_exception = -1;
@@ -7027,6 +7028,19 @@ static void exception3_read_special(uae_u32 opcode, uaecptr addr, int size, int
 {
        exception3f(opcode, addr, false, 0, false, 0xffffffff, size, false, fc);
 }
+
+// Some hardware accepts address error aborted reads or writes as normal reads/writes.
+void exception3_read_opcode(uae_u32 opcode, uaecptr addr, int size, int fc)
+{
+       x_do_cycles(4 * cpucycleunit);
+       exception3_read(opcode, addr, size, fc);
+}
+void exception3_write_opcode(uae_u32 opcode, uaecptr addr, int size, uae_u32 val, int fc)
+{
+       x_do_cycles(4 * cpucycleunit);
+       exception3_write(opcode, addr, size, val, fc);
+}
+
 void exception3_read(uae_u32 opcode, uaecptr addr, int size, int fc)
 {
        bool ni = false;