]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Another 68000 IPL poll timing update.
authorToni Wilen <twilen@winuae.net>
Fri, 1 Oct 2021 19:50:27 +0000 (22:50 +0300)
committerToni Wilen <twilen@winuae.net>
Fri, 1 Oct 2021 19:50:27 +0000 (22:50 +0300)
gencpu.cpp

index df66b895ee8f1c7b026796b57edc20caffca48c5..cd328b7644a48d7bfb7aab01e8b50b5921b437fc 100644 (file)
@@ -158,6 +158,7 @@ static int brace_level;
 
 static char outbuffer[30000];
 static int last_access_offset_ipl;
+static int last_access_offset_ipl_prev;
 
 static void out(const char *format, ...)
 {
@@ -245,6 +246,12 @@ static void set_last_access_ipl(void)
        last_access_offset_ipl = strlen(outbuffer);
 }
 
+static void set_last_access_ipl_prev(void)
+{
+       last_access_offset_ipl_prev = strlen(outbuffer);
+}
+
+
 NORETURN static void term (void)
 {
        out("Abort!\n");
@@ -486,7 +493,17 @@ static bool isprefetch020(void)
 
 static void check_ipl(void)
 {
-       set_last_access_ipl();
+       // So far it seems 68000 IPL fetch happens when CPU is doing
+       // memory cycle data part followed by prefetch cycle. It must
+       // happen after possible bus error has been detected but before
+       // following prefetch memory cycle.
+       if (last_access_offset_ipl_prev < 0) {
+               set_last_access_ipl();
+       } else {
+               // if memory cycle happened previously: use it.
+               last_access_offset_ipl = last_access_offset_ipl_prev;
+               ipl_fetched = 1;
+       }
 }
 
 static void check_ipl_always(void)
@@ -3636,6 +3653,8 @@ static void genamode2x (amodes mode, const char *reg, wordsizes size, const char
                addmmufixup(reg, size, mode);
        }
 
+       set_last_access_ipl_prev();
+
        if (getv == 1) {
                const char *srcbx = !(flags & GF_FC) ? srcb : "sfc_nommu_get_byte";
                const char *srcwx = !(flags & GF_FC) ? srcw : "sfc_nommu_get_word";
@@ -3881,6 +3900,8 @@ static void genastore_2 (const char *from, amodes mode, const char *reg, wordsiz
                check_address_error(to, mode, reg, size, 2, 0, flags);
        }
 
+       set_last_access_ipl_prev();
+
        switch (mode) {
        case Dreg:
                switch (size) {
@@ -4007,6 +4028,7 @@ static void genastore_2 (const char *from, amodes mode, const char *reg, wordsiz
                                                fill_prefetch_next_after(0, NULL);
                                                insn_n_cycles += 4;
                                        }
+                                       set_last_access_ipl_prev();
                                        out("%s(%sa, %s >> 16);\n", dstwx, to, from);
                                        sprintf(tmp, "%s >> 16", from);
                                        count_writew++;
@@ -4019,6 +4041,7 @@ static void genastore_2 (const char *from, amodes mode, const char *reg, wordsiz
                                        if (flags & GF_SECONDWORDSETFLAGS) {
                                                genflags(flag_logical, g_instr->size, "src", "", "");
                                        }
+                                       set_last_access_ipl_prev();
                                        out("%s(%sa + 2, %s);\n", dstwx, to, from);
                                        count_writew++;
                                        check_bus_error(to, 2, 1, 1, from, 1, pcoffset);
@@ -4055,6 +4078,7 @@ static void genastore_2 (const char *from, amodes mode, const char *reg, wordsiz
                                        if (store_dir > 1) {
                                                fill_prefetch_next_after(0, NULL);
                                        }
+                                       set_last_access_ipl_prev();
                                        out("%s(%sa, %s >> 16); \n", dstwx, to, from);
                                        sprintf(tmp, "%s >> 16", from);
                                        count_writew++;
@@ -4067,6 +4091,7 @@ static void genastore_2 (const char *from, amodes mode, const char *reg, wordsiz
                                        if (flags & GF_SECONDWORDSETFLAGS) {
                                                genflags(flag_logical, g_instr->size, "src", "", "");
                                        }
+                                       set_last_access_ipl_prev();
                                        out("%s(%sa + 2, %s); \n", dstwx, to, from);
                                        count_writew++;
                                        check_bus_error(to, 2, 1, 1, from, 1, pcoffset);
@@ -5267,6 +5292,7 @@ static void gen_opcode (unsigned int opcode)
        bus_error_code2[0] = 0;
        opcode_nextcopy = 0;
        last_access_offset_ipl = -1;
+       last_access_offset_ipl_prev = -1;
 
        loopmode = 0;
        // 68010 loop mode available if