]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
68000 write bus errors implemented.
authorToni Wilen <twilen@winuae.net>
Sat, 7 Dec 2019 19:57:55 +0000 (21:57 +0200)
committerToni Wilen <twilen@winuae.net>
Sat, 7 Dec 2019 19:57:55 +0000 (21:57 +0200)
cputest.cpp
cputest/main.c
gencpu.cpp

index 327bc330bbcf65a4e4edd56cbb9749499981fc31..e9a8e5ee3b650f180aa559eb5b130044fefa7e03 100644 (file)
@@ -72,10 +72,10 @@ static uae_u32 feature_addressing_modes[2];
 static int ad8r[2], pc8r[2];
 static int multi_mode;
 #define MAX_TARGET_EA 20
-static uae_u32 feature_target_ea[MAX_TARGET_EA][2];
-static int target_ea_src_cnt, target_ea_dst_cnt;
-static int target_ea_src_max, target_ea_dst_max;
-static uae_u32 target_ea[2];
+static uae_u32 feature_target_ea[MAX_TARGET_EA][3];
+static int target_ea_src_cnt, target_ea_dst_cnt, target_ea_opcode_cnt;
+static int target_ea_src_max, target_ea_dst_max, target_ea_opcode_max;
+static uae_u32 target_ea[3];
 
 #define HIGH_MEMORY_START (addressing_mask == 0xffffffff ? 0xffff8000 : 0x00ff8000)
 
@@ -288,11 +288,15 @@ static void check_bus_error(uaecptr addr, int write, int fc)
        if (safe_memory_start == 0xffffffff && safe_memory_end == 0xffffffff)
                return;
        if (addr >= safe_memory_start && addr < safe_memory_end) {
-               cpu_bus_error_fake = 1;
-               if ((safe_memory_mode & 1) && !write)
-                       cpu_bus_error = 1;
-               if ((safe_memory_mode & 2) && write)
+               cpu_bus_error_fake = -1;
+               if ((safe_memory_mode & 1) && !write) {
                        cpu_bus_error = 1;
+                       cpu_bus_error_fake = 1;
+               }
+               if ((safe_memory_mode & 2) && write) {
+                       cpu_bus_error = 2;
+                       cpu_bus_error_fake = 2;
+               }
        }
 }
 
@@ -947,12 +951,13 @@ void exception2_read(uae_u32 opcode, uaecptr addr, int size, int fc)
        regs.read_buffer = 0;
 
        if (currprefs.cpu_model == 68000) {
-               if (generates_group1_exception(regs.ir)) {
+               if (generates_group1_exception(regs.ir) && !(opcode & 0x20000)) {
                        test_exception_3_fc |= 8;  // set N/I
                }
                if (opcode & 0x10000)
                        test_exception_3_fc |= 8;
-               test_exception_opcode = regs.ir;
+               if (!(opcode & 0x20000))
+                       test_exception_opcode = regs.ir;
        }
 
        doexcstack();
@@ -970,12 +975,13 @@ void exception2_write(uae_u32 opcode, uaecptr addr, int size, uae_u32 val, int f
        test_exception_3_di = 1;
 
        if (currprefs.cpu_model == 68000) {
-               if (generates_group1_exception(regs.ir)) {
+               if (generates_group1_exception(regs.ir) && !(opcode & 0x20000)) {
                        test_exception_3_fc |= 8;  // set N/I
                }
                if (opcode & 0x10000)
                        test_exception_3_fc |= 8;
-               test_exception_opcode = regs.ir;
+               if (!(opcode & 0x20000))
+                       test_exception_opcode = regs.ir;
        }
 
        doexcstack();
@@ -1287,12 +1293,14 @@ static uae_u8 *store_mem_bytes(uae_u8 *dst, uaecptr start, int len, uae_u8 *old)
        uaecptr oldstart = start;
        uae_u8 offset = 0;
        // start
-       for (int i = 0; i < len; i++) {
-               uae_u8 v = get_byte_test(start);
-               if (v != *old)
-                       break;
-               start++;
-               old++;
+       if (old) {
+               for (int i = 0; i < len; i++) {
+                       uae_u8 v = get_byte_test(start);
+                       if (v != *old)
+                               break;
+                       start++;
+                       old++;
+               }
        }
        // end
        offset = start - oldstart;
@@ -1301,11 +1309,13 @@ static uae_u8 *store_mem_bytes(uae_u8 *dst, uaecptr start, int len, uae_u8 *old)
                offset = 7;
        }
        len -= offset;
-       for (int i = len - 1; i >= 0; i--) {
-               uae_u8 v = get_byte_test(start + i);
-               if (v != old[i])
-                       break;
-               len--;
+       if (old) {
+               for (int i = len - 1; i >= 0; i--) {
+                       uae_u8 v = get_byte_test(start + i);
+                       if (v != old[i])
+                               break;
+                       len--;
+               }
        }
        if (!len)
                return dst;
@@ -1434,7 +1444,7 @@ static void save_data(uae_u8 *dst, const TCHAR *dir)
                fwrite(data, 1, 4, f);
                pl(data, opcode_memory_start);
                fwrite(data, 1, 4, f);
-               pl(data, (cpu_lvl << 16) | sr_undefined_mask | (addressing_mask == 0xffffffff ? 0x80000000 : 0) | (feature_min_interrupt_mask << 20));
+               pl(data, (cpu_lvl << 16) | sr_undefined_mask | (addressing_mask == 0xffffffff ? 0x80000000 : 0) | (feature_min_interrupt_mask << 20) | (safe_memory_mode << 23));
                fwrite(data, 1, 4, f);
                pl(data, currprefs.fpu_model);
                fwrite(data, 1, 4, f);
@@ -1562,8 +1572,9 @@ static int analyze_address(struct instr *dp, int srcdst, uae_u32 addr)
                out_of_test_space = false;
                return 0;
        }
-       if (ea_state_found[0] >= 2 && ea_state_found[1] >= 2 && ea_state_found[2] >= 2)
-               return 1;
+       if (ea_state_found[0] >= 2 && ea_state_found[1] >= 2 && ea_state_found[2] >= 2) {
+               ea_state_found[0] = ea_state_found[1] = ea_state_found[2] = 0;
+       }
        // zero
        if (v == 0) {
                if (ea_state_found[0] >= 2 && (ea_state_found[1] < 2 || ea_state_found[2] < 2))
@@ -2936,6 +2947,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
        uae_u32 target_address = 0xffffffff;
        target_ea[0] = 0xffffffff;
        target_ea[1] = 0xffffffff;
+       target_ea[2] = 0xffffffff;
        if (feature_target_ea[0][0] != 0xffffffff) {
                target_address = feature_target_ea[0][0];
                target_ea[0] = target_address;
@@ -2945,6 +2957,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
        }
        target_ea_src_cnt = 0;
        target_ea_dst_cnt = 0;
+       target_ea_opcode_cnt = 0;
 
        // 1.0
        fpuregisters[0].high = 0x3fff;
@@ -2993,12 +3006,13 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
 
        int sr_override = 0;
 
-       uae_u32 target_ea_bak[2], target_address_bak;
+       uae_u32 target_ea_bak[3], target_address_bak;
 
        for (;;) {
 
                target_ea_bak[0] = target_ea[0];
                target_ea_bak[1] = target_ea[1];
+               target_ea_bak[2] = target_ea[2];
                target_address_bak = target_address;
 
                if (quick)
@@ -3029,9 +3043,11 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
 
                if (verbose) {
                        if (target_ea[0] != 0xffffffff)
-                               wprintf(_T("Targeat EA SRC=%08x\n"), target_ea[0]);
+                               wprintf(_T(" Target EA SRC=%08x\n"), target_ea[0]);
                        if (target_ea[1] != 0xffffffff)
-                               wprintf(_T("Targeat EA DST=%08x\n"), target_ea[1]);
+                               wprintf(_T(" Target EA DST=%08x\n"), target_ea[1]);
+                       if (target_ea[2] != 0xffffffff)
+                               wprintf(_T(" Target EA OPCODE=%08x\n"), target_ea[2]);
                }
 
                for (int opcode = 0; opcode < 65536; opcode++) {
@@ -3052,6 +3068,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
 
                        target_ea[0] = target_ea_bak[0];
                        target_ea[1] = target_ea_bak[1];
+                       target_ea[2] = target_ea_bak[2];
                        target_address = target_address_bak;
 
                        int extra_loops = 3;
@@ -3083,6 +3100,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
 
                                target_ea[0] = target_ea_bak[0];
                                target_ea[1] = target_ea_bak[1];
+                               target_ea[2] = target_ea_bak[1];
                                target_address = target_address_bak;
 
                                reset_ea_state();
@@ -3122,6 +3140,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
 
                                        target_ea[0] = target_ea_bak[0];
                                        target_ea[1] = target_ea_bak[1];
+                                       target_ea[2] = target_ea_bak[2];
                                        target_address = target_address_bak;
 
                                        if (opc == 0x4ed0)
@@ -3215,8 +3234,8 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                                uae_u8 *bo = opcode_memory + 2;
                                                uae_u16 bopw1 = (bo[0] << 8) | (bo[1] << 0);
                                                uae_u16 bopw2 = (bo[2] << 8) | (bo[3] << 0);
-                                               if (opc == 0xf228
-                                                       && bopw1 == 0x003a
+                                               if (opc == 0x0662
+                                                       && bopw1 == 0x3dec
                                                        //&& bopw2 == 0x2770
                                                        )
                                                        printf("");
@@ -3270,7 +3289,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                                abort();
                                        }
 
-                                       dst = store_mem_bytes(dst, opcode_memory_start, pc - opcode_memory_start, oldbytes);
+                                       dst = store_mem_bytes(dst, opcode_memory_start, pc - opcode_memory_start, subtest_count > 0 ? oldbytes : NULL);
                                        ahcnt = 0;
 
 
@@ -3550,6 +3569,14 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                                        uae_u8 *pcaddr = get_addr(regs.pc, 2, 0);
 
                                                        // examine results
+
+                                                       // if only testing read bus errors, skip tests that generated only writes and vice-versa
+                                                       // skip also all tests don't generate any bus errors
+                                                       if ((cpu_bus_error == 0 && safe_memory_mode) ||
+                                                               (cpu_bus_error == 1 && !(safe_memory_mode & 1)) ||
+                                                               (cpu_bus_error == 2 && !(safe_memory_mode & 2))) {
+                                                               skipped = 1;
+                                                       }
                                                        if (cpu_stopped) {
                                                                cnt_stopped++;
                                                                // CPU stopped, skip test
@@ -3591,15 +3618,21 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                                                if (SPCFLAG_DOTRACE || test_exception == 9) {
                                                                        t_cnt++;
                                                                }
-                                                       } else {
+                                                       } else if (!skipped) {
                                                                // instruction executed successfully
                                                                ok++;
                                                                // validate branch instructions
                                                                if (isbranchinst(dp)) {
-                                                                       if ((regs.pc != branch_target_pc && regs.pc != pc - endopcodesize) || ((pcaddr[0] != 0x4a && pcaddr[1] != 0xfc) && (pcaddr[0] != 0x4e && pcaddr[1] != 0x71))) {
+                                                                       if ((regs.pc != branch_target_pc && regs.pc != pc - endopcodesize)) {
                                                                                wprintf(_T(" Branch instruction target fault\n"));
                                                                                abort();
                                                                        }
+                                                                       if (branch_target_pc < safe_memory_start || branch_target_pc >= safe_memory_end) {
+                                                                               if ((pcaddr[0] != 0x4a && pcaddr[1] != 0xfc) && (pcaddr[0] != 0x4e && pcaddr[1] != 0x71)) {
+                                                                                       wprintf(_T(" Branch instruction target fault\n"));
+                                                                                       abort();
+                                                                               }
+                                                                       }
                                                                }
                                                        }
 
@@ -4031,9 +4064,10 @@ int __cdecl main(int argc, char *argv[])
        for (int i = 0; i < MAX_TARGET_EA; i++) {
                feature_target_ea[i][0] = 0xffffffff;
                feature_target_ea[i][1] = 0xffffffff;
+               feature_target_ea[i][2] = 0xffffffff;
        }
-       for (int i = 0; i < 2; i++) {
-               if (ini_getstring(ini, INISECTION, i ? _T("feature_target_dst_ea") : _T("feature_target_src_ea"), &vs)) {
+       for (int i = 0; i < 3; i++) {
+               if (ini_getstring(ini, INISECTION, i == 2 ? _T("feature_target_opcode") : (i ? _T("feature_target_dst_ea") : _T("feature_target_src_ea")), &vs)) {
                        int cnt = 0;
                        TCHAR *p = vs;
                        while (p && *p) {
@@ -4055,7 +4089,9 @@ int __cdecl main(int argc, char *argv[])
                                p = pp;
                                cnt++;
                        }
-                       if (i) {
+                       if (i == 2) {
+                               target_ea_opcode_max = cnt;
+                       } else if (i) {
                                target_ea_dst_max = cnt;
                        } else {
                                target_ea_src_max = cnt;
index e01e8536bef31cef1efdf61b36b0ef5b4450a010..78660d0d50cc614243d136ba99d1a871e77482c9 100644 (file)
@@ -67,6 +67,7 @@ static uae_u32 test_memory_addr, test_memory_end;
 static uae_u32 test_memory_size;
 static uae_u8 *test_data;
 static uae_u8 *safe_memory_start, *safe_memory_end;
+static int safe_memory_mode;
 static uae_u32 user_stack_memory, super_stack_memory;
 static int test_data_size;
 static uae_u32 oldvbr;
@@ -93,7 +94,7 @@ static int low_memory_offset;
 static int high_memory_offset;
 
 static uae_u32 vbr[256];
-static int exceptioncount[128];
+static int exceptioncount[2][128];
 static int supercnt;
 
 static char inst_name[16+1];
@@ -209,13 +210,24 @@ static int ahcnt;
 #define MAX_ACCESSHIST 48
 static struct accesshistory ahist[MAX_ACCESSHIST];
 
+static int is_valid_test_addr_read(uae_u32 a)
+{
+       if ((uae_u8 *)a >= safe_memory_start && (uae_u8 *)a < safe_memory_end && (safe_memory_mode & 1))
+               return 0;
+       return (a >= test_low_memory_start && a < test_low_memory_end && test_low_memory_start != 0xffffffff) ||
+               (a >= test_high_memory_start && a < test_high_memory_end && test_high_memory_start != 0xffffffff) ||
+               (a >= test_memory_addr && a < test_memory_end);
+}
+
 static void endinfo(void)
 {
        printf("Last test: %lu\n", testcnt);
        uae_u8 *p = opcode_memory;
-       for (int i = 0; i < 32 * 2; i += 2) {
+       for (int i = 0; i < 4 * 2; i += 2) {
+               if (!is_valid_test_addr_read((uae_u32)(&p[i])))
+                       break;
                uae_u16 v = (p[i] << 8) | (p[i + 1]);
-               printf(" %04x", v);
+               printf("%08lx %04x\n", &p[i], v);
                if (v == 0x4afc && i > 0)
                        break;
        }
@@ -418,13 +430,54 @@ static uae_u8 *load_file(const char *path, const char *file, uae_u8 *p, int *siz
                        p += size2;
                        size -= size2;
                }
-               if (size > 0 && p >= safe_memory_start && p < safe_memory_end) {
-                       int size2 = safe_memory_end - p;
-                       if (size2 > size)
-                               size2 = size;
-                       fseek(f, size2, SEEK_CUR);
-                       p += size2;
-                       size -= size2;
+               if ((safe_memory_mode & 1)) {
+                       // if reading cause bus error: skip it
+                       if (size > 0 && p >= safe_memory_start && p < safe_memory_end) {
+                               int size2 = safe_memory_end - p;
+                               if (size2 > size)
+                                       size2 = size;
+                               fseek(f, size2, SEEK_CUR);
+                               p += size2;
+                               size -= size2;
+                       }
+               } else if (safe_memory_mode == 2) {
+                       // if only writes generate bus error: load data if different
+                       if (size > 0 && p >= safe_memory_start && p < safe_memory_end) {
+                               int size2 = safe_memory_end - p;
+                               if (size2 > size)
+                                       size2 = size;
+                               uae_u8 *tmp = malloc(size2);
+                               if (!tmp) {
+                                       printf("Couldn't allocate safe tmp memory (%ld bytes)\n", size2);
+                                       exit(0);
+                               }
+                               fread(tmp, 1, size2, f);
+                               if (memcmp(tmp, p, size2)) {
+                                       printf("Disable write bus error mode and press any key (SPACE=skip,ESC=abort)\n");
+                                       int ch = getchar();
+                                       if (ch == 27) {
+                                               exit(0);
+                                       } else if (ch == 32) {
+                                               fseek(f, size2, SEEK_CUR);
+                                               p += size2;
+                                               size -= size2;
+                                       } else {
+                                               memcpy(p, tmp, size2);
+                                               p += size2;
+                                               size -= size2;
+                                               printf("Re-enable write bus error mode and press any key (ESC=abort)\n");
+                                               if (getchar() == 27) {
+                                                       exit(0);
+                                               }
+                                       }
+                               } else {
+                                       printf("Write-only bus error mode, data already correct\n");
+                                       fseek(f, size2, SEEK_CUR);
+                                       p += size2;
+                                       size -= size2;
+                               }
+                               free(tmp);
+                       }
                }
                if (size > 0) {
                        if (fread(p, 1, size, f) != size)
@@ -841,20 +894,10 @@ static uae_u8 *restore_data(uae_u8 *p)
 static uae_u16 test_sr, test_ccrignoremask;
 static uae_u32 test_fpsr, test_fpcr;
 
-
-static int is_valid_test_addr(uae_u32 a)
-{
-       if ((uae_u8 *)a >= safe_memory_start && (uae_u8 *)a < safe_memory_end)
-               return 0;
-       return (a >= test_low_memory_start && a < test_low_memory_end && test_low_memory_start != 0xffffffff) ||
-               (a >= test_high_memory_start && a < test_high_memory_end && test_high_memory_start != 0xffffffff) ||
-               (a >= test_memory_addr && a < test_memory_end);
-}
-
 static int addr_diff(uae_u8 *ap, uae_u8 *bp, int size)
 {
        for (int i = 0; i < size; i++) {
-               if (is_valid_test_addr((uae_u32)bp)) {
+               if (is_valid_test_addr_read((uae_u32)bp)) {
                        if (*ap != *bp)
                                return 1;
                }
@@ -875,7 +918,7 @@ static void addinfo_bytes(char *name, uae_u8 *src, uae_u32 address, int offset,
                        *outbp++ = '*';
                else if (cnt > 0)
                        *outbp++ = '.';
-               if ((uae_u8*)address >= safe_memory_start && (uae_u8*)address < safe_memory_end) {
+               if ((uae_u8*)address >= safe_memory_start && (uae_u8*)address < safe_memory_end && (safe_memory_mode & 1)) {
                        outbp[0] = '?';
                        outbp[1] = '?';
                } else {
@@ -908,7 +951,7 @@ static void out_disasm(uae_u8 *mem)
        int lines = 0;
        while (lines++ < 5) {
                int v = 0;
-               if (!is_valid_test_addr((uae_u32)p) || !is_valid_test_addr((uae_u32)p + 1))
+               if (!is_valid_test_addr_read((uae_u32)p) || !is_valid_test_addr_read((uae_u32)p + 1))
                        break;
                tmpbuffer[0] = 0;
                if (!(((uae_u32)code) & 1)) {
@@ -1113,6 +1156,7 @@ static uae_u8 *validate_exception(struct registers *regs, uae_u8 *p, int excnum,
        uae_u32 v;
        uae_u8 excdatalen = *p++;
        int size;
+       int excrw = 0;
 
        if (!excdatalen) {
                return p;
@@ -1122,7 +1166,7 @@ static uae_u8 *validate_exception(struct registers *regs, uae_u8 *p, int excnum,
                // check possible extra trace
                last_exception_extra = *p++;
                if ((last_exception_extra & 0x7f) == 9) {
-                       exceptioncount[last_exception_extra & 0x7f]++;
+                       exceptioncount[0][last_exception_extra & 0x7f]++;
                        uae_u32 ret = (regs->tracedata[1] << 16) | regs->tracedata[2];
                        uae_u16 sr = regs->tracedata[0];
                        if (regs->tracecnt == 0) {
@@ -1183,8 +1227,6 @@ static uae_u8 *validate_exception(struct registers *regs, uae_u8 *p, int excnum,
                }
        }
 
-       exceptioncount[*gotexcnum]++;
-
        exc = last_exception;
        if (excdatalen != 0xff) {
                if (cpu_lvl == 0) {
@@ -1194,6 +1236,7 @@ static uae_u8 *validate_exception(struct registers *regs, uae_u8 *p, int excnum,
                                uae_u8 opcode1 = p[2];
                                exc[0] = opcode0;
                                exc[1] = (opcode1 & ~0x1f) | p[0];
+                               excrw = (p[0] & 0x10) == 0;
                                p += 3;
                                // access address
                                v = opcode_memory_addr;
@@ -1250,6 +1293,7 @@ static uae_u8 *validate_exception(struct registers *regs, uae_u8 *p, int excnum,
                        case 8:
                                exc[8] = *p++;
                                exc[9] = *p++;
+                               excrw = (exc[8] & 1) == 0;
                                v = opcode_memory_addr;
                                p = restore_rel_ordered(p, &v);
                                pl(exc + 10, v);
@@ -1291,6 +1335,9 @@ static uae_u8 *validate_exception(struct registers *regs, uae_u8 *p, int excnum,
        } else {
                exclen = last_exception_len;
        }
+
+       exceptioncount[excrw][*gotexcnum]++;
+
        if (exclen == 0 || *gotexcnum != excnum)
                return p;
        if (memcmp(exc, sp, exclen)) {
@@ -1663,7 +1710,7 @@ static void store_addr(uae_u32 s, uae_u8 *d)
                return;
        for (int i = 0; i < SIZE_STORED_ADDRESS; i++) {
                uae_u32 ss = s + (i - SIZE_STORED_ADDRESS_OFFSET);
-               if (is_valid_test_addr(ss)) {
+               if (is_valid_test_addr_read(ss)) {
                        *d++ = *((uae_u8 *)ss);
                } else {
                        *d++ = 0;
@@ -1723,6 +1770,7 @@ static void process_test(uae_u8 *p)
                        if (opcode_memory_end > (uae_u8*)pc + 32) {
                                end_test();
                                printf("Corrupted opcode memory\n");
+                               endinfo();
                                exit(0);
                        }
                }
@@ -1954,6 +2002,7 @@ static int test_mnemo(const char *path, const char *opcode)
        interrupt_mask = (lvl_mask >> 20) & 7;
        addressing_mask = (lvl_mask & 0x80000000) ? 0xffffffff : 0x00ffffff;
        sr_undefined_mask = lvl_mask & 0xffff;
+       safe_memory_mode = (lvl_mask >> 23) & 3;
        fpu_model = read_u32(f);
        test_low_memory_start = read_u32(f);
        test_low_memory_end = read_u32(f);
@@ -2087,8 +2136,12 @@ static int test_mnemo(const char *path, const char *opcode)
        printf("%lu ", testcnt);
        printf("S=%ld", supercnt);
        for (int i = 0; i < 128; i++) {
-               if (exceptioncount[i]) {
-                       printf(" E%02d=%ld", i, exceptioncount[i]);
+               if (exceptioncount[0][i] || exceptioncount[1][i]) {
+                       if (i == 2 || i == 3) {
+                               printf(" E%02d=%ld/%ld", i, exceptioncount[0][i], exceptioncount[1][i]);
+                       } else {
+                               printf(" E%02d=%ld", i, exceptioncount[0][i]);
+                       }
                }
        }
        printf("\n");
index 3e3c88e07851dcaf178d721a0ededf5a3d9a42cb..b2c0db1515983ed3e06f3bed7e623dd68a93a923 100644 (file)
@@ -936,6 +936,22 @@ static void fill_prefetch_next (void)
 //     }
 }
 
+static void fill_prefetch_next_skipopcode(void)
+{
+       if (using_prefetch) {
+               irc2ir();
+               if (using_bus_error) {
+                       printf("\topcode |= 0x20000;\n");
+               }
+               fill_prefetch_1(m68k_pc_offset + 2);
+       }
+       //      if (using_prefetch_020) {
+       //              printf ("\t%s (%d);\n", prefetch_word, m68k_pc_offset);
+       //              did_prefetch = 1;
+       //      }
+}
+
+
 static void fill_prefetch_next_empty(void)
 {
        if (using_prefetch) {
@@ -1295,10 +1311,7 @@ static void move_68000_bus_error(int offset, int size, int *setapdi, int *fcmode
 
                if (dmode == Apdi) {
 
-                       // this is buggy, bus error stack frame opcode field contains next
-                       // instruction opcode and Instruction/Not field is one!
-                       printf("\t\topcode = regs.ir;\n");
-                       *fcmodeflags |= 0x08; // "Not instruction" = 1
+                       printf("\t\tif (regs.t1) opcode |= 0x10000;\n"); // I/N set
 
                } else if (dmode == Aipi) {
 
@@ -1309,11 +1322,9 @@ static void move_68000_bus_error(int offset, int size, int *setapdi, int *fcmode
        } else if (size == sz_word) {
 
                if (dmode == Apdi) {
-                       // this is buggy, bus error stack frame opcode field contains next
-                       // instruction opcode and Instruction/Not field is one!
-                       printf("\t\topcode = regs.ir;\n");
-                       *fcmodeflags |= 0x08; // "Not instruction" = 1
-       
+
+                       printf("\t\tif (regs.t1) opcode |= 0x10000;\n"); // I/N set
+
                } else if (dmode == Aipi) {
 
                        // move.w x,(an)+: an is not increased
@@ -1477,6 +1488,8 @@ static int do_bus_error_fixes(const char *name, int offset, int write)
 
 static void check_bus_error(const char *name, int offset, int write, int size, const char *writevar, int fc)
 {
+       int mnemo = g_instr->mnemo;
+
        // check possible bus error (if 68000/010 and enabled)
        if (!using_bus_error)
                return;
@@ -1508,16 +1521,16 @@ static void check_bus_error(const char *name, int offset, int write, int size, c
 
                offset = do_bus_error_fixes(name, offset, write);
 
-               if (g_instr->mnemo == i_BTST && (g_instr->dmode == PC16 || g_instr->dmode == PC8r)) {
+               if (mnemo == i_BTST && (g_instr->dmode == PC16 || g_instr->dmode == PC8r)) {
                        // BTST special case where destination is read access
                        fc = 2;
                }
-               if (g_instr->mnemo == i_MVMEL && (g_instr->dmode == PC16 || g_instr->dmode == PC8r)) {
+               if (mnemo == i_MVMEL && (g_instr->dmode == PC16 || g_instr->dmode == PC8r)) {
                        // MOVEM to registers
                        fc = 2;
                }
 
-               if (g_instr->mnemo == i_LINK) {
+               if (mnemo == i_LINK) {
                        // a7 -> a0 copy done before A7 address error check
                        printf("\tm68k_areg(regs, srcreg) = olda;\n");
                }
@@ -1531,6 +1544,14 @@ static void check_bus_error(const char *name, int offset, int write, int size, c
                        printf("\t\topcode |= 0x%x;\n", extra);
                }
 
+               // write causing bus error and trace: set I/N
+               if (write && g_instr->size <= sz_word &&
+                       mnemo != i_MOVE &&
+                       mnemo != i_MVMEL && mnemo != i_MVMLE &&
+                       mnemo != i_MVPRM && mnemo != i_MVPMR) {         
+                       printf("\t\tif (regs.t1) opcode |= 0x10000;\n"); // I/N set
+               }
+
                //if (cpu_level == 0 && write) {
                //      printf("\t\topcode = regs.irc;\n");
                //}
@@ -4621,7 +4642,10 @@ static void gen_opcode (unsigned int opcode)
                                if (curi->mnemo == i_MOVEA && curi->size == sz_word)
                                        printf ("\tsrc = (uae_s32)(uae_s16)src;\n");
                                if (curi->dmode == Apdi) {
-                                       fill_prefetch_next ();
+                                       if (curi->size == sz_long)
+                                               fill_prefetch_next_skipopcode();
+                                       else
+                                               fill_prefetch_next();
                                        prefetch_done = 1;
                                }