]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Some 68010 address error stack frame fixes.
authorToni Wilen <twilen@winuae.net>
Thu, 21 May 2020 13:49:03 +0000 (16:49 +0300)
committerToni Wilen <twilen@winuae.net>
Thu, 21 May 2020 13:49:03 +0000 (16:49 +0300)
gencpu.cpp

index 518095255e51e7c2fbaff7a89e0ed7dbc4c43ec0..f496eb51e9e43c7235af7d0815eeb7982ff00000 100644 (file)
@@ -3031,6 +3031,7 @@ static void check_address_error(const  char *name, int mode, const char *reg, in
                int setapdiback = 0;
                int fcmodeflags = 0;
                int exp3rw = getv == 2;
+               int pcextra = 0;
 
                next_level_000();
 
@@ -3066,6 +3067,9 @@ static void check_address_error(const  char *name, int mode, const char *reg, in
                                                out("src += %d;\n", mode == Aipi ? 2 : -2);
                                                out("}\n");
                                        }
+                                       if (mode >= Ad16) {
+                                               pcextra = 2;
+                                       }
                                }
                                if (size == sz_long) {
                                        if (mode == Aipi) {
@@ -3095,8 +3099,6 @@ static void check_address_error(const  char *name, int mode, const char *reg, in
                                setapdiback = 1;
                }
 
-               int pcextra = 0;
-
                // adjust MOVE write address error stacked PC
                if (g_instr->mnemo == i_MOVE && getv == 2) {
                        if (g_instr->smode >= Aind && g_instr->smode != imm && g_instr->dmode == absl) {
@@ -3329,9 +3331,13 @@ static void genamode2x (amodes mode, const char *reg, wordsizes size, const char
                } else if (!(flags & GF_APDI)) {
                        addcycles000(2);
                        count_cycles_ea += 2;
-                       pc_68000_offset_fetch += 2;
-                       if (size == sz_long)
-                               pc_68000_offset_fetch -= 2;
+                       if (cpu_level == 1) {
+                               ;
+                       } else {
+                               pc_68000_offset_fetch += 2;
+                               if (size == sz_long)
+                                       pc_68000_offset_fetch -= 2;
+                       }
                }
                break;
        case Ad16: // (d16,An)
@@ -5888,6 +5894,7 @@ static void gen_opcode (unsigned int opcode)
                                                genflags(flag_logical, curi->size, "0", "", "");
                                        }
                                }
+                               incpc("%d", m68k_pc_offset + 2);
                                out("exception3_write(opcode, srca, 1, 0, 1);\n");
                                write_return_cycles(0);
                                out("}\n");
@@ -6369,8 +6376,10 @@ static void gen_opcode (unsigned int opcode)
                }
                break;
        case i_MVSR2: // MOVE FROM SR
-               if ((curi->smode != Apdi && curi->smode != absw && curi->smode != absl) && curi->size == sz_word) {
-                       exception_pc_offset_extra = -2;
+               if (cpu_level == 0) {
+                       if ((curi->smode != Apdi && curi->smode != absw && curi->smode != absl) && curi->size == sz_word) {
+                               exception_pc_offset_extra = -2;
+                       }
                }
                genamode(curi, curi->smode, "srcreg", sz_word, "src", cpu_level == 0 ? 2 : 3, 0, cpu_level == 1 ? GF_NOFETCH : 0);
                out("MakeSR();\n");
@@ -6397,6 +6406,7 @@ static void gen_opcode (unsigned int opcode)
                exception_pc_offset_extra = 0;
                if (!isreg(curi->smode) && cpu_level == 1 && using_exception_3 && (using_prefetch || using_ce)) {
                        out("if(srca & 1) {\n");
+                       incpc("%d", m68k_pc_offset + 2);
                        out("exception3_write(opcode, srca, 1, regs.sr & 0x%x, 1);\n", curi->size == sz_byte ? 0x00ff : 0xffff);
                        write_return_cycles(0);
                        out("}\n");
@@ -7099,7 +7109,11 @@ static void gen_opcode (unsigned int opcode)
                                        } else {
                                                incpc("2");
                                        }
-                                       out("exception3_write_access(opcode, m68k_areg(regs, 7), 1, m68k_areg(regs, 7) >> 16, 1);\n");
+                                       if (cpu_level == 1) {
+                                               out("exception3_write_access(opcode, m68k_areg(regs, 7), 1, oldpc >> 16, 1);\n");
+                                       } else {
+                                               out("exception3_write_access(opcode, m68k_areg(regs, 7), 1, m68k_areg(regs, 7) >> 16, 1);\n");
+                                       }
                                        write_return_cycles(0);
                                        out("}\n");
                                }
@@ -7217,7 +7231,8 @@ static void gen_opcode (unsigned int opcode)
                                out("}\n");
                        } else if (cpu_level == 1) {
                                out("if (m68k_areg(regs, 7) & 1) {\n");
-                               out("exception3_write_access(opcode, m68k_areg(regs, 7), sz_word, oldpc, 1);\n");
+                               incpc("2");
+                               out("exception3_write_access(opcode, oldpc + s, sz_word, oldpc, 1);\n");
                                write_return_cycles(0);
                                out("}\n");
                        }
@@ -7225,7 +7240,7 @@ static void gen_opcode (unsigned int opcode)
                if (using_exception_3 && cpu_level == 1) {
                        // 68010 TODO: looks like prefetches are done first and stack writes last
                        out("if (s & 1) {\n");
-                       out("exception3_read_prefetch_only(opcode, s + oldpc);\n");
+                       out("exception3_read_prefetch_only(opcode, oldpc + s);\n");
                        write_return_cycles(0);
                        out("}\n");
                }
@@ -7328,8 +7343,10 @@ static void gen_opcode (unsigned int opcode)
                                out("uae_u16 rb = regs.irc;\n");
                                incpc("((uae_s32)src + 2) & ~1");
                                dummy_prefetch(NULL, "oldpc");
+                               out("uaecptr newpc = %s + (uae_s32)src + 2;\n", getpc);
+                               incpc("2");
                                out("regs.read_buffer = rb;\n");
-                               out("exception3_read_prefetch(opcode, %s + (uae_s32)src + 2);\n", getpc);
+                               out("exception3_read_prefetch(opcode, newpc);\n");
                        } else {
                                // Addr = new address, PC = current PC
                                out("uaecptr addr = %s + (uae_s32)src + 2;\n", getpc);
@@ -7421,7 +7438,11 @@ bccl_not68020:
                if (cpu_level <= 1 && using_exception_3) {
                        out("if (dsta & 1) {\n");
                        out("regs.ir = old_opcode;\n");
-                       incpc("%d", m68k_pc_offset + ((curi->smode == absw || curi->smode == absl) ? 0 : 2));
+                       if (cpu_level == 1) {
+                               incpc("2");
+                       } else {
+                               incpc("%d", m68k_pc_offset + ((curi->smode == absw || curi->smode == absl) ? 0 : 2));
+                       }
                        out("exception3_write_access(old_opcode, dsta, sz_word, srca >> 16, 1);\n");
                        write_return_cycles(0);
                        out("}\n");