]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
68010 address error updates.
authorToni Wilen <twilen@winuae.net>
Tue, 31 Dec 2019 15:30:06 +0000 (17:30 +0200)
committerToni Wilen <twilen@winuae.net>
Tue, 31 Dec 2019 15:30:06 +0000 (17:30 +0200)
cputest.cpp
cputest/cputest_defines.h
cputest/main.c
cputest_support.cpp
gencpu.cpp
newcpu_common.cpp

index 344e9b3b33673dee4c68d09ceb6cb8fce86b3532..da5c5dc4fd61ce535e1e23edee8dc9d9ca1d023c 100644 (file)
@@ -146,6 +146,7 @@ static int high_memory_accessed;
 static int test_memory_accessed;
 static uae_u16 extra_or, extra_and;
 static uae_u32 cur_registers[MAX_REGISTERS];
+static uae_u16 read_buffer_prev;
 
 struct uae_prefs currprefs;
 
@@ -330,6 +331,7 @@ uae_u16 get_word_test_prefetch(int o)
        if (cpu_lvl < 2)
                o -= 2;
        regs.irc = get_iword_test(m68k_getpci() + o + 2);
+       read_buffer_prev = regs.read_buffer;
        regs.read_buffer = regs.irc;
        return get_iword_test(m68k_getpci() + o);
 }
@@ -459,6 +461,7 @@ uae_u32 get_byte_test(uaecptr addr)
 {
        check_bus_error(addr, 0, regs.s ? 5 : 1);
        uae_u8 *p = get_addr(addr, 1, 0);
+       read_buffer_prev = regs.read_buffer;
        regs.read_buffer = *p;
        return *p;
 }
@@ -472,6 +475,7 @@ uae_u32 get_word_test(uaecptr addr)
                uae_u8 *p = get_addr(addr, 2, 0);
                v = (p[0] << 8) | (p[1]);
        }
+       read_buffer_prev = regs.read_buffer;
        regs.read_buffer = v;
        return v;
 }
@@ -492,6 +496,7 @@ uae_u32 get_long_test(uaecptr addr)
                uae_u8 *p = get_addr(addr, 4, 0);
                v = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3]);
        }
+       read_buffer_prev = regs.read_buffer;
        regs.read_buffer = v;
        return v;
 }
@@ -946,7 +951,6 @@ void exception2_read(uae_u32 opcode, uaecptr addr, int size, int fc)
        test_exception_3_fc = fc;
        test_exception_3_size = size;
        test_exception_3_di = 1;
-       regs.read_buffer = 0;
 
        if (currprefs.cpu_model == 68000) {
                if (generates_group1_exception(regs.ir) && !(opcode & 0x20000)) {
@@ -994,7 +998,6 @@ void exception3_read(uae_u32 opcode, uae_u32 addr, int size, int fc)
        test_exception_3_fc = fc;
        test_exception_3_size = size;
        test_exception_3_di = 1;
-       regs.read_buffer = 0;
 
        if (currprefs.cpu_model == 68000) {
                if (generates_group1_exception(regs.ir) && !(opcode & 0x20000)) {
@@ -1004,6 +1007,11 @@ void exception3_read(uae_u32 opcode, uae_u32 addr, int size, int fc)
                        test_exception_3_fc |= 8;
                test_exception_opcode = regs.ir;
        }
+       if (currprefs.cpu_model == 68010) {
+               if (opcode & 0x40000) {
+                       test_exception_3_di = 0;
+               }
+       }
 
        doexcstack();
 }
@@ -1057,6 +1065,8 @@ void exception3i(uae_u32 opcode, uaecptr addr)
        test_exception_3_w = 0;
        test_exception_addr = addr;
        test_exception_opcode = opcode;
+       test_exception_3_di = 0;
+       test_exception_3_size = sz_word;
        doexcstack();
 }
 void exception3b(uae_u32 opcode, uaecptr addr, bool w, bool i, uaecptr pc)
@@ -1066,6 +1076,8 @@ void exception3b(uae_u32 opcode, uaecptr addr, bool w, bool i, uaecptr pc)
        test_exception_3_w = w;
        test_exception_addr = addr;
        test_exception_opcode = opcode;
+       test_exception_3_di = 0;
+       test_exception_3_size = sz_word;
        doexcstack();
 }
 
@@ -2534,6 +2546,7 @@ static void execute_ins(uaecptr endpc, uaecptr targetpc, struct instr *dp)
        testing_active_opcode = opc;
        cpu_bus_error = 0;
        cpu_bus_error_fake = 0;
+       read_buffer_prev = regs.ir;
        regs.read_buffer = regs.irc;
        regs.write_buffer = 0xf00d;
 
@@ -2810,6 +2823,9 @@ static uae_u8 *save_exception(uae_u8 *p, struct instr *dp)
                                // instruction
                                *p++ = sf[24];
                                *p++ = sf[25];
+                               // optional data input (some hardware does real memory fetch when CPU does the dummy fetch, some don't)
+                               *p++ = read_buffer_prev >> 8;
+                               *p++ = read_buffer_prev;
                                break;
                        case 0x0a: // 68020/030 address error.
                        case 0x0b: // Don't save anything extra, too many undefined fields and bits..
index 539901e0792fe757d7c416af5c4593f9c0a98aa0..037dddd7284ef717baa4cf006c28ac28d59f0cb2 100644 (file)
@@ -1,5 +1,5 @@
 
-#define DATA_VERSION 12
+#define DATA_VERSION 13
 
 #define CT_FPREG 0
 #define CT_DREG 0
index 973700d7a8b26e4644cc54fb1cc0518e0d0c6f43..e7155aab61083c0f1a0953547512e75805fc9d5f 100644 (file)
@@ -1362,7 +1362,7 @@ static uae_u8 *validate_exception(struct registers *regs, uae_u8 *p, int excnum,
                                pl(exc + 12, v);
                                exclen = 16;
                                break;
-                       case 8:
+                       case 8: // 68010 bus/address error
                                exc[8] = *p++;
                                exc[9] = *p++;
                                excrwp = ((exc[8] & 1) == 0) ? 1 : 0;
@@ -1388,6 +1388,12 @@ static uae_u8 *validate_exception(struct registers *regs, uae_u8 *p, int excnum,
                                sp[22] = sp[23] = 0;
                                // ignore undocumented data
                                exclen = 26;
+                               // read input buffer may contain either actual data read from memory or previous read data
+                               // this depends on hardware, cpu does dummy read cycle and some hardware returns memory data, some ignore it.
+                               memcpy(alternate_exception1, exc, exclen);
+                               alternate_exception1[20] = *p++;
+                               alternate_exception1[21] = *p++;
+                               alts = 1;
                                break;
                        case 0x0a:
                        case 0x0b:
index b4c653abdf419431a8ca7f0258d673615af62219..bce2b91df865bcebd34ee31d6a75c6d5f657f91d 100644 (file)
@@ -9,6 +9,8 @@
 #include "mmu_common.h"
 #include "cpummu030.h"
 
+cpuop_func *loop_mode_table[65536];
+
 void my_trim(TCHAR *s)
 {
        int len;
index ae8d4b5151c77d3ec654606ccecd12788a10401a..ad23126e77edb783e1b273ae5205ddc37fd54485 100644 (file)
@@ -2749,6 +2749,8 @@ static void genamode2x (amodes mode, const char *reg, wordsizes size, const char
                printf("\tif (%sa & 1) {\n", name);
 
                if (cpu_level == 1) {
+                       // 68010 does dummy access
+                       printf("\t\tuae_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
@@ -2763,9 +2765,6 @@ static void genamode2x (amodes mode, const char *reg, wordsizes size, const char
                        if (mode == Apdi && g_instr->size == sz_word && g_instr->mnemo != i_CLR) {
                                printf("\t\tm68k_areg(regs, %s) = %sa;\n", reg, name);
                        }
-                       if (mode == Apdi) {
-                               ;// printf("\t\tregs.read_buffer = 0;\n");
-                       }
                }
 
                if (g_instr->mnemo == i_ADDX || g_instr->mnemo == i_SUBX) {
@@ -3511,13 +3510,34 @@ static void movem_mmu030 (const char *code, int size, bool put, bool aipi, bool
 static void movem_ex3(int write)
 {
        if ((using_prefetch || using_ce) && using_exception_3) {
+
                if (write) {
                        // MOVEM write to memory won't generate address error
                        // exception if mask is zero and EA is odd.
                        printf("\tif ((amask || dmask) && (srca & 1)) {\n");
                        // MOVE.L EA,-(An) causing address error: stacked value is original An - 2, not An - 4.
-                       if (g_instr->dmode == Apdi)
+                       if (g_instr->dmode == Apdi) {
                                printf("\t\tsrca -= 2;\n");
+                       }
+                       printf("\t\tuaecptr srcav = srca;\n");
+                       if (cpu_level == 1) {
+                               if (g_instr->dmode == Apdi) {
+                                       printf("\t\tif(amask) {\n");
+                                       printf("\t\t\tsrcav = m68k_areg(regs, movem_index2[amask]);\n");
+                                       printf("\t\t} else if (dmask) {\n");
+                                       printf("\t\t\tsrcav = m68k_dreg(regs, movem_index2[dmask]);\n");
+                                       printf("\t\t}\n");
+                               } else {
+                                       printf("\t\tif(dmask) {\n");
+                                       printf("\t\t\tsrcav = m68k_dreg(regs, movem_index1[dmask]);\n");
+                                       printf("\t\t} else if (amask) {\n");
+                                       printf("\t\t\tsrcav = m68k_areg(regs, movem_index1[amask]);\n");
+                                       printf("\t\t}\n");
+                               }
+                               if (g_instr->dmode == Aind || g_instr->dmode == Apdi || g_instr->dmode == Aipi) {
+                                       printf("\t\tregs.read_buffer = mask;\n");
+                               }
+                       }
                } else {
                        // MOVEM from memory will generate address error
                        // exception if mask is zero and EA is odd.
@@ -3525,9 +3545,13 @@ static void movem_ex3(int write)
                        if (g_instr->dmode == PC16 || g_instr->dmode == PC8r) {
                                printf("\t\topcode |= 0x01020000;\n");
                        }
+                       printf("\t\tuaecptr srcav = srca;\n");
+                       if (cpu_level == 1) {
+                               printf("\t\tuae_s16 dummy = %s(srca & ~1);\n", srcw);
+                       }
                }
                if (write) {
-                       printf("\t\texception3_write(opcode, srca, %d, srca, %d);\n",
+                       printf("\t\texception3_write(opcode, srca, %d, srcav, %d);\n",
                                g_instr->size,
                                (g_instr->dmode == PC16 || g_instr->dmode == PC8r) ? 2 : 1);
                } else {
@@ -4879,13 +4903,21 @@ static void gen_opcode (unsigned int opcode)
                                addcycles000(2);
                        if (!isreg(curi->smode) && using_exception_3 && curi->size != sz_byte && (using_prefetch || using_ce)) {
                                printf("\tif(srca & 1) {\n");
+                               if (curi->smode == Aipi) {
+                                       printf("\t\tm68k_areg(regs, srcreg) -= %d;\n", 1 << curi->size);
+                               } else if (curi->smode == Apdi) {
+                                       printf("\t\tm68k_areg(regs, srcreg) += %d;\n", 1 << curi->size);
+                               } else if (curi->smode >= Ad16) {
+                                       printf("\t%s(%d);\n", prefetch_word, m68k_pc_offset + 2);
+                                       genflags(flag_logical, curi->size, "0", "", "");
+                               }
                                printf("\t\texception3_write(opcode, srca, 1, 0, 1);\n");
                                write_return_cycles("\t\t", 0);
                                printf("\t}\n");
                        }
+                       fill_prefetch_next();
                        genflags(flag_logical, curi->size, "0", "", "");
                        genastore_rev("0", curi->smode, "srcreg", curi->size, "src");
-                       fill_prefetch_next();
                } else {
                        genamode(curi, curi->smode, "srcreg", curi->size, "src", 2, 0, 0);
                        fill_prefetch_next();
@@ -6028,15 +6060,15 @@ static void gen_opcode (unsigned int opcode)
                }
                printf("\ts = (uae_s32)src + 2;\n");
                if (using_exception_3) {
-                       if (cpu_level <= 1) {
+                       if (cpu_level == 0) {
                                printf("\tif (m68k_areg(regs, 7) & 1) {\n");
                                printf("\t\tm68k_areg(regs, 7) -= 4;\n");
-                               printf("\t\texception3b(opcode,  m68k_areg(regs, 7), true, false, %s + 2);\n", getpc);
+                               printf("\t\texception3b(opcode, m68k_areg(regs, 7), true, false, %s + 2);\n", getpc);
                                write_return_cycles("\t\t", 0);
                                printf("\t}\n");
-                       } else if (0) {
-                               printf("\tif (src & 1) {\n");
-                               printf("\t\texception3b(opcode, %s + s, 0, 1, %s + s);\n", getpc, getpc);
+                       } else if (cpu_level == 1) {
+                               printf("\tif (m68k_areg(regs, 7) & 1) {\n");
+                               printf("\t\texception3b(opcode, m68k_areg(regs, 7), true, true, %s);\n", getpc);
                                write_return_cycles("\t\t", 0);
                                printf("\t}\n");
                        }
@@ -6044,6 +6076,16 @@ static void gen_opcode (unsigned int opcode)
                addcycles000 (2);
                printf("\tuaecptr oldpc = %s;\n", getpc);
                printf("\tuaecptr nextpc = oldpc + %d;\n", m68k_pc_offset);
+               if (using_exception_3 && cpu_level == 1) {
+                       // 68010 TODO: looks like prefetches are done first and stack writes last
+                       printf("\tif (s & 1) {\n");
+                       setpc("(oldpc + s) & ~1");
+                       printf("\t%s(0);\n", prefetch_word);
+                       setpc("oldpc");
+                       printf("\t\texception3b(opcode, oldpc + s, false, true, %s);\n", getpc);
+                       write_return_cycles("\t\t", 0);
+                       printf("\t}\n");
+               }
                if (using_exception_3 && cpu_level >= 2) {
                        printf("\tif (s & 1) {\n");
                        if (cpu_level < 4)
@@ -6075,9 +6117,9 @@ static void gen_opcode (unsigned int opcode)
                } else {
                        printf("\tm68k_do_bsr (nextpc, s);\n");
                }
-               if (using_exception_3 && cpu_level <= 1) {
+               if (using_exception_3 && cpu_level == 0) {
                        printf("\tif (%s & 1) {\n", getpc);
-                       printf("\t\texception3b(opcode, %s, 0, 1, %s);\n", getpc, getpc);
+                       printf("\t\texception3b(opcode, %s, false, true, %s);\n", getpc, getpc);
                        write_return_cycles("\t\t", 0);
                        printf("\t}\n");
                }
@@ -6100,7 +6142,7 @@ static void gen_opcode (unsigned int opcode)
                        if (cpu_level < 2) {
                                addcycles000 (2);
                                printf("\tif (cctrue(%d)) {\n", curi->cc);
-                               printf("\t\texception3i (opcode, %s + 1);\n", getpc);
+                               printf("\t\texception3i(opcode, %s + 1);\n", getpc);
                                write_return_cycles("\t\t", 0);
                                printf("\t}\n");
                                sync_m68k_pc ();
@@ -6117,14 +6159,20 @@ static void gen_opcode (unsigned int opcode)
                addcycles000 (2);
                if (using_exception_3 && cpu_level >= 4) {
                        printf("\tif (src & 1) {\n");
-                       printf("\t\texception3i (opcode, %s + 2 + (uae_s32)src);\n", getpc);
+                       printf("\t\texception3i(opcode, %s + 2 + (uae_s32)src);\n", getpc);
                        write_return_cycles("\t\t", 0);
                        printf("\t}\n");
                }
                printf("\tif (cctrue(%d)) {\n", curi->cc);
                if (using_exception_3 && cpu_level < 4) {
                        printf("\t\tif (src & 1) {\n");
-                       printf("\t\t\texception3i (opcode, %s + 2 + (uae_s32)src);\n", getpc);
+                       if (cpu_level == 1) {
+                               printf("\t\tuaecptr oldpc = %s;\n", getpc);
+                               incpc("((uae_s32)src + 2) & ~1");
+                               printf("\t%s(0);\n", prefetch_word);
+                               setpc("oldpc");
+                       }
+                       printf("\t\t\texception3i(opcode, %s + 2 + (uae_s32)src);\n", getpc);
                        write_return_cycles("\t\t\t", 0);
                        printf("\t\t}\n");
                }
index 83a3d9dcf9a9b5d6e50aae7838c5d453a643304f..8403991a8a5fc18f938fb1c06e0f51f4c4705511 100644 (file)
@@ -1364,7 +1364,7 @@ void Exception_build_stack_frame(uae_u32 oldpc, uae_u32 currpc, uae_u32 ssw, int
                m68k_areg(regs, 7) -= 4;
                x_put_long(m68k_areg(regs, 7), regs.mmu_effective_addr);
                break;
-       case 0x8: // address error (68010)
+       case 0x8: // bus/address error (68010)
        {
                uae_u16 in = regs.read_buffer;
                uae_u16 out = regs.write_buffer;