]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Experimental 68000 prefetch bus error emulation support: shift/rotate instructions...
authorToni Wilen <twilen@winuae.net>
Sun, 22 Dec 2019 14:19:00 +0000 (16:19 +0200)
committerToni Wilen <twilen@winuae.net>
Sun, 22 Dec 2019 14:19:00 +0000 (16:19 +0200)
cputest.cpp
cputest/cputestgen.ini
cputest/main.c
gencpu.cpp

index 1d84242e91b4c0bcaa0ed91005df4308906ab657..0bfd73e4390a486ff56dca2499a07c96e1b8a21e 100644 (file)
@@ -289,13 +289,15 @@ static void check_bus_error(uaecptr addr, int write, int fc)
                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;
-                       cpu_bus_error_fake = 1;
-               }
-               if ((safe_memory_mode & 2) && write) {
-                       cpu_bus_error = 2;
-                       cpu_bus_error_fake = 2;
+               if ((safe_memory_mode & 4) && !write && (fc & 2)) {
+                       cpu_bus_error |= 4;
+                       cpu_bus_error_fake |= 1;
+               } else if ((safe_memory_mode & 1) && !write && !(fc & 2)) {
+                       cpu_bus_error |= 1;
+                       cpu_bus_error_fake |= 1;
+               } else if ((safe_memory_mode & 2) && write) {
+                       cpu_bus_error |= 2;
+                       cpu_bus_error_fake |= 2;
                }
        }
 }
@@ -342,6 +344,8 @@ static void previoussame(uaecptr addr, int size)
 
 void put_byte_test(uaecptr addr, uae_u32 v)
 {
+       if (!testing_active && is_nowrite_address(addr, 1))
+               return;
        check_bus_error(addr, 1, regs.s ? 5 : 1);
        uae_u8 *p = get_addr(addr, 1, 1);
        if (!out_of_test_space && !noaccesshistory && !cpu_bus_error_fake) {
@@ -361,6 +365,8 @@ void put_byte_test(uaecptr addr, uae_u32 v)
 }
 void put_word_test(uaecptr addr, uae_u32 v)
 {
+       if (!testing_active && is_nowrite_address(addr, 1))
+               return;
        check_bus_error(addr, 1, regs.s ? 5 : 1);
        if (addr & 1) {
                put_byte_test(addr + 0, v >> 8);
@@ -386,6 +392,8 @@ void put_word_test(uaecptr addr, uae_u32 v)
 }
 void put_long_test(uaecptr addr, uae_u32 v)
 {
+       if (!testing_active && is_nowrite_address(addr, 1))
+               return;
        check_bus_error(addr, 1, regs.s ? 5 : 1);
        if (addr & 1) {
                put_byte_test(addr + 0, v >> 24);
@@ -915,7 +923,7 @@ void exception2_fetch(uae_u32 opcode, uaecptr addr)
        test_exception_3_di = 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)
@@ -1276,6 +1284,11 @@ static uae_u8 *store_mem_bytes(uae_u8 *dst, uaecptr start, int len, uae_u8 *old,
                wprintf(_T(" too long byte count!\n"));
                abort();
        }
+       if (is_nowrite_address(start, 1) || is_nowrite_address(start + len - 1, 1)) {
+               wprintf(_T(" store_mem_bytes accessing safe memory area! (%08x - %08x)\n"), start, start + len - 1);
+               abort();
+       }
+
        uaecptr oldstart = start;
        uae_u8 offset = 0;
        // start
@@ -1327,7 +1340,11 @@ static uae_u8 *store_mem_writes(uae_u8 *dst, int storealways)
                validate_addr(ah->addr, 1 << ah->size);
                uaecptr addr = ah->addr;
                addr &= addressing_mask;
-               if (addr < 0x8000) {
+               if (is_nowrite_address(addr, 1)) {
+                       wprintf(_T("attempting to save safe memory address %08x!\n"), addr);
+                       abort();
+               }       
+               if (addr < 0x8000) {
                        *dst++ = CT_MEMWRITE | CT_ABSOLUTE_WORD;
                        *dst++ = (addr >> 8) & 0xff;
                        *dst++ = addr & 0xff;
@@ -3173,6 +3190,11 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
 
 
                                        uaecptr pc = opcode_memory_start + 2;
+
+                                       if (is_nowrite_address(pc, 1)) {
+                                               goto nextopcode;
+                                       }
+
                                        if (target_opcode_address != 0xffffffff) {
                                                pc -= 2;
                                                int cnt = 0;
@@ -3300,6 +3322,11 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                                pc += 4;
                                        }
 
+                                       // if instruction was long enough to hit safe area, decrease pc until we are back to normal area
+                                       while (is_nowrite_address(pc - 1, 1)) {
+                                               pc -= 2;
+                                       }
+
                                        // end word, needed to detect if instruction finished normally when
                                        // running on real hardware.
                                        uae_u32 originalendopcode = 0x4afc4e71;
@@ -3674,8 +3701,13 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                                        // 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))) {
+                                                               ((cpu_bus_error & 4) && !(safe_memory_mode & 4)) ||
+                                                               ((cpu_bus_error & 1) && !(safe_memory_mode & 1)) ||
+                                                               ((cpu_bus_error & 2) && !(safe_memory_mode & 2))) {
+                                                               skipped = 1;
+                                                       }
+                                                       // skip if feature_target_opcode_offset mode and non-prefetch bus error
+                                                       if (target_opcode_address != 0xffffffff && (cpu_bus_error & 3)) {
                                                                skipped = 1;
                                                        }
 
@@ -4208,6 +4240,30 @@ int __cdecl main(int argc, char *argv[])
        feature_exception3_instruction = 0;
        ini_getval(ini, INISECTION, _T("feature_exception3_instruction"), &feature_exception3_instruction);
 
+       safe_memory_start = 0xffffffff;
+       if (ini_getval(ini, INISECTION, _T("feature_safe_memory_start"), &v))
+               safe_memory_start = v;
+       safe_memory_end = 0xffffffff;
+       if (ini_getval(ini, INISECTION, _T("feature_safe_memory_size"), &v))
+               safe_memory_end = safe_memory_start + v;
+       safe_memory_mode = 7;
+       if (ini_getstring(ini, INISECTION, _T("feature_safe_memory_mode"), &vs)) {
+               safe_memory_mode = 0;
+               if (_totupper(vs[0]) == 'R')
+                       safe_memory_mode |= 1;
+               if (_totupper(vs[0]) == 'W')
+                       safe_memory_mode |= 2;
+               if (_totupper(vs[0]) == 'P')
+                       safe_memory_mode |= 4;
+               xfree(vs);
+       }
+       if (safe_memory_start == 0xffffffff || safe_memory_end == 0xffffffff) {
+               safe_memory_end = 0xffffffff;
+               safe_memory_start = 0xffffffff;
+               safe_memory_mode = 0;
+       }
+
+
        for (int i = 0; i < MAX_TARGET_EA; i++) {
                feature_target_ea[i][0] = 0xffffffff;
                feature_target_ea[i][1] = 0xffffffff;
@@ -4226,10 +4282,12 @@ int __cdecl main(int argc, char *argv[])
                                        *pp++ = 0;
                                }
                                TCHAR *endptr;
+                               int radix = i == 2 ? 10 : 16;
                                if (_tcslen(p) > 2 && p[0] == '0' && _totupper(p[1]) == 'X') {
                                        p += 2;
+                                       radix = 16;
                                }
-                               feature_target_ea[cnt][i] = _tcstol(p, &endptr, 16);
+                               feature_target_ea[cnt][i] = _tcstol(p, &endptr, radix);
                                if (feature_target_ea[cnt][i] & 1) {
                                        exp3cnt++;
                                }
@@ -4238,6 +4296,7 @@ int __cdecl main(int argc, char *argv[])
                        }
                        if (i == 2) {
                                target_ea_opcode_max = cnt;
+                               safe_memory_mode = 7;
                        } else if (i) {
                                target_ea_dst_max = cnt;
                        } else {
@@ -4258,27 +4317,6 @@ int __cdecl main(int argc, char *argv[])
                }
        }
 
-       safe_memory_start = 0xffffffff;
-       if (ini_getval(ini, INISECTION, _T("feature_safe_memory_start"), &v))
-               safe_memory_start = v;
-       safe_memory_end = 0xffffffff;
-       if (ini_getval(ini, INISECTION, _T("feature_safe_memory_size"), &v))
-               safe_memory_end = safe_memory_start + v;
-       safe_memory_mode = 3;
-       if (ini_getstring(ini, INISECTION, _T("feature_safe_memory_mode"), &vs)) {
-               safe_memory_mode = 0;
-               if (_totupper(vs[0]) == 'R')
-                       safe_memory_mode |= 1;
-               if (_totupper(vs[0]) == 'W')
-                       safe_memory_mode |= 2;
-               xfree(vs);
-       }
-       if (safe_memory_start == 0xffffffff || safe_memory_end == 0xffffffff) {
-               safe_memory_end = 0xffffffff;
-               safe_memory_start = 0xffffffff;
-               safe_memory_mode = 0;
-       }
-
        feature_sr_mask = 0;
        ini_getval(ini, INISECTION, _T("feature_sr_mask"), &feature_sr_mask);
        feature_min_interrupt_mask = 0;
index dfe8810aa0f7f0aee36fc199b01c35001f51b0a0..0353df5c9f48eb3950f172eb99b5dfb0511ee786 100644 (file)
@@ -69,11 +69,14 @@ feature_target_src_ea=
 ; Memory region that generates bus error (both read and write).
 ; Must be inside any test memory region.
 ; Can be used to verify bus errors if ea above is inside this memory region.
-;feature_safe_memory_start=0x880000
-;feature_safe_memory_size=0x80000
-; R = read only bus error, W = write only bus error, empty or RW = both.
+feature_safe_memory_start=0x880000
+feature_safe_memory_size=0x80000
+; R = data read only bus error
+; W = data write only bus error
+; P = prefetch bus error
+; empty or RWP = both.
 ; if enabled, all tests that don't generate matching bus error are skipped.
-;feature_safe_memory_mode=R
+feature_safe_memory_mode=R
 
 ; force odd user stack
 ; 0 = even stack
index 0808f028ba18313573de3b979fab739c5966294c..0eb1e8aa7b4e2b3a81cbd963dd661980a4b36ed7 100644 (file)
@@ -95,7 +95,7 @@ static int low_memory_offset;
 static int high_memory_offset;
 
 static uae_u32 vbr[256];
-static int exceptioncount[2][128];
+static int exceptioncount[3][128];
 static int supercnt;
 static uae_u32 endpc;
 
@@ -214,6 +214,7 @@ static struct accesshistory ahist[MAX_ACCESSHIST];
 
 static int is_valid_test_addr_read(uae_u32 a)
 {
+       a &= addressing_mask;
        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) ||
@@ -223,6 +224,7 @@ static int is_valid_test_addr_read(uae_u32 a)
 
 static int is_valid_test_addr_readwrite(uae_u32 a)
 {
+       a &= addressing_mask;
        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) ||
@@ -943,7 +945,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 && (safe_memory_mode & 1)) {
+               if ((uae_u8*)address >= safe_memory_start && (uae_u8*)address < safe_memory_end && (safe_memory_mode & (1 | 4))) {
                        outbp[0] = '?';
                        outbp[1] = '?';
                } else {
@@ -1053,8 +1055,8 @@ static void addinfo(void)
                uae_u8 *b = (uae_u8 *)regs.branchtarget - SIZE_STORED_ADDRESS_OFFSET;
                addinfo_bytes("B", b, regs.branchtarget, -SIZE_STORED_ADDRESS_OFFSET, SIZE_STORED_ADDRESS);
        }
-       sprintf(outbp, "ENDPC=%08lx\n", endpc);
-       outbp += strlen(outbp);
+       //sprintf(outbp, "ENDPC=%08lx\n", endpc);
+       //outbp += strlen(outbp);
 }
 
 struct srbit
@@ -1189,7 +1191,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;
+       int excrwp = 0;
 
        if (!excdatalen) {
                return p;
@@ -1273,7 +1275,9 @@ 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;
+                               excrwp = ((p[0] & 0x10) == 0) ? 1 : 0;
+                               if (p[0] & 2)
+                                       excrwp = 2;
                                p += 3;
                                // access address
                                v = opcode_memory_addr;
@@ -1330,7 +1334,9 @@ 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;
+                               excrwp = ((exc[8] & 1) == 0) ? 1 : 0;
+                               if (exc[9] & 2)
+                                       excrwp = 2;
                                v = opcode_memory_addr;
                                p = restore_rel_ordered(p, &v);
                                pl(exc + 10, v);
@@ -1373,7 +1379,7 @@ static uae_u8 *validate_exception(struct registers *regs, uae_u8 *p, int excnum,
                exclen = last_exception_len;
        }
 
-       exceptioncount[excrw][*gotexcnum]++;
+       exceptioncount[excrwp][*gotexcnum]++;
 
        if (exclen == 0 || *gotexcnum != excnum)
                return p;
@@ -2185,9 +2191,9 @@ 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[0][i] || exceptioncount[1][i]) {
+               if (exceptioncount[0][i] || exceptioncount[1][i] || exceptioncount[2][i]) {
                        if (i == 2 || i == 3) {
-                               printf(" E%02d=%ld/%ld", i, exceptioncount[0][i], exceptioncount[1][i]);
+                               printf(" E%02d=%ld/%ld/%ld", i, exceptioncount[0][i], exceptioncount[1][i], exceptioncount[2][i]);
                        } else {
                                printf(" E%02d=%ld", i, exceptioncount[0][i]);
                        }
index 90c5ba09f02a55627b3cdb7d567e7f4ae1f071b0..e438cbfca81377c4bbe93d95f1da8933b329935d 100644 (file)
@@ -511,6 +511,7 @@ static void add_mmu040_movem (int movem)
 
 static char bus_error_text[200];
 static int bus_error_specials;
+static char bus_error_code[1000];
 
 static void do_instruction_buserror(void)
 {
@@ -518,6 +519,8 @@ static void do_instruction_buserror(void)
                return;
        if (bus_error_text[0]) {
                printf("\tif(cpu_bus_error) {\n");
+               if (bus_error_code[0])
+                       printf("%s", bus_error_code);
                printf("%s", bus_error_text);
                printf("\t\tgoto %s;\n", endlabelstr);
                need_endlabel = 1;
@@ -882,7 +885,11 @@ static void fill_prefetch_full_000_special(void)
        irc2ir();
        if (using_bus_error) {
                printf("\topcode = regs.ir;\n");
-               printf("\tif(regs.t1) opcode |= 0x10000;\n");
+               if (g_instr->mnemo == i_RTE) {
+                       printf("\tif(oldt1) opcode |= 0x10000;\n");
+               } else {
+                       printf("\tif(regs.t1) opcode |= 0x10000;\n");
+               }
        }
        printf("\t%s (%d);\n", prefetch_word, 2);
        check_prefetch_bus_error(-2, -1);
@@ -934,19 +941,38 @@ static void dummy_prefetch (void)
        insn_n_cycles += 4;
 }
 
-static void fill_prefetch_next (void)
+static void fill_prefetch_next_noopcodecopy(const char *format, ...)
 {
        if (using_prefetch) {
                irc2ir();
                if (using_bus_error) {
-                       printf("\topcode = regs.ir;\n");
+                       bus_error_code[0] = 0;
+                       if (format) {
+                               va_list parms;
+                               va_start(parms, format);
+                               _vsnprintf(bus_error_code, sizeof(bus_error_code) - 1, format, parms);
+                               va_end(parms);
+                       }
+                       printf("\topcode |= 0x20000;\n");
+               }
+               fill_prefetch_1(m68k_pc_offset + 2);
+       }
+}
+
+static void fill_prefetch_next(void)
+{
+       if (using_prefetch) {
+               irc2ir();
+               if (using_bus_error) {
+                       int mode = g_instr->smode;
+                       if (mode == Aind || mode == Apdi || mode == Aipi || mode == Ad16 || mode == PC16 || mode == Ad8r || mode == PC8r || mode == absw || mode == absl) {
+                               printf("\topcode |= 0x20000;\n");
+                       } else {
+                               printf("\topcode = regs.ir;\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_skipopcode(void)
@@ -4039,6 +4065,7 @@ static void gen_opcode (unsigned int opcode)
        m68k_pc_offset = 2;
        g_instr = curi;
        g_srcname[0] = 0;
+       bus_error_code[0] = 0;
 
        // do not unnecessarily create useless mmuop030
        // functions when CPU is not 68030
@@ -4325,23 +4352,33 @@ static void gen_opcode (unsigned int opcode)
                break;
        case i_NEG:
                genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_RMW);
-               fill_prefetch_next ();
+               genflags(flag_sub, curi->size, "dst", "src", "0");
+               if (curi->smode == Dreg) {
+                       genastore_rev("dst", curi->smode, "srcreg", curi->size, "src");
+               }
+               fill_prefetch_next();
                if (isreg (curi->smode) && curi->size == sz_long)
                        addcycles000 (2);
                start_brace ();
-               genflags (flag_sub, curi->size, "dst", "src", "0");
-               genastore_rev ("dst", curi->smode, "srcreg", curi->size, "src");
+               if (curi->smode != Dreg) {
+                       genastore_rev("dst", curi->smode, "srcreg", curi->size, "src");
+               }
                break;
        case i_NEGX:
                genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_RMW);
+               printf("\tuae_u32 newv = 0 - src - (GET_XFLG () ? 1 : 0);\n");
+               genflags(flag_subx, curi->size, "newv", "src", "0");
+               genflags(flag_zn, curi->size, "newv", "", "");
+               if (curi->smode == Dreg) {
+                       genastore_rev("newv", curi->smode, "srcreg", curi->size, "src");
+               }
                fill_prefetch_next ();
                if (isreg (curi->smode) && curi->size == sz_long)
                        addcycles000 (2);
                start_brace ();
-               printf ("\tuae_u32 newv = 0 - src - (GET_XFLG () ? 1 : 0);\n");
-               genflags (flag_subx, curi->size, "newv", "src", "0");
-               genflags (flag_zn, curi->size, "newv", "", "");
-               genastore_rev ("newv", curi->smode, "srcreg", curi->size, "src");
+               if (curi->smode != Dreg) {
+                       genastore_rev("newv", curi->smode, "srcreg", curi->size, "src");
+               }
                break;
        case i_NBCD:
                genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_RMW);
@@ -4382,11 +4419,16 @@ static void gen_opcode (unsigned int opcode)
                next_level_000 ();
                if (cpu_level == 0) {
                        genamode(curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
+                       genflags(flag_logical, curi->size, "0", "", "");
+                       if (curi->smode == Dreg) {
+                               genastore_rev("0", curi->smode, "srcreg", curi->size, "src");
+                       }
                        fill_prefetch_next();
                        if (isreg(curi->smode) && curi->size == sz_long)
                                addcycles000(2);
-                       genflags(flag_logical, curi->size, "0", "", "");
-                       genastore_rev("0", curi->smode, "srcreg", curi->size, "src");
+                       if (curi->smode != Dreg) {
+                               genastore_rev("0", curi->smode, "srcreg", curi->size, "src");
+                       }
                } else if (cpu_level == 1) {
                        genamode(curi, curi->smode, "srcreg", curi->size, "src", 3, 0, 0);
                        if (isreg(curi->smode) && curi->size == sz_long)
@@ -4412,13 +4454,18 @@ static void gen_opcode (unsigned int opcode)
                break;
        case i_NOT:
                genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_RMW);
+               printf("\tuae_u32 dst = ~src;\n");
+               genflags(flag_logical, curi->size, "dst", "", "");
+               if (curi->smode == Dreg) {
+                       genastore_rev("dst", curi->smode, "srcreg", curi->size, "src");
+               }
                fill_prefetch_next ();
                if (isreg (curi->smode) && curi->size == sz_long)
                        addcycles000 (2);
                start_brace ();
-               printf ("\tuae_u32 dst = ~src;\n");
-               genflags (flag_logical, curi->size, "dst", "", "");
-               genastore_rev ("dst", curi->smode, "srcreg", curi->size, "src");
+               if (curi->smode != Dreg) {
+                       genastore_rev("dst", curi->smode, "srcreg", curi->size, "src");
+               }
                break;
        case i_TST:
                genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
@@ -4891,6 +4938,7 @@ static void gen_opcode (unsigned int opcode)
                        genamode (NULL, Aipi, "7", sz_word, "sr", 1, 0, GF_NOREFILL);
                        genamode (NULL, Aipi, "7", sz_long, "pc", 1, 0, GF_NOREFILL);
                        printf("\tuaecptr oldpc = %s;\n", getpc);
+                       printf("\tuae_u16 oldt1 = regs.t1;\n");
                        printf("\tregs.sr = sr;\n");
                        makefromsr();
                        printf("\tif (pc & 1) {\n");
@@ -4898,6 +4946,7 @@ static void gen_opcode (unsigned int opcode)
                        printf("\t\tgoto %s;\n", endlabelstr);
                        printf("\t}\n");
                        setpc ("pc");
+                       printf("\topcode |= 0x20000;\n");
                        if (using_debugmem) {
                                printf("\tbranch_stack_pop_rte(oldpc);\n");
                        }
@@ -4906,6 +4955,7 @@ static void gen_opcode (unsigned int opcode)
                        int old_brace_level = n_braces;
                        printf("\tuaecptr oldpc = %s;\n", getpc);
                        printf ("\tuae_u16 newsr; uae_u32 newpc;\n");
+                       printf("\tuae_u16 oldt1 = regs.t1;\n");
                        printf ("\tfor (;;) {\n");
                        printf ("\t\tuaecptr a = m68k_areg (regs, 7);\n");
                        printf ("\t\tuae_u16 sr = %s (a);\n", srcw);
@@ -5179,9 +5229,9 @@ static void gen_opcode (unsigned int opcode)
                next_level_040_to_030();
                break;
        case i_TRAPV:
-               sync_m68k_pc ();
-               fill_prefetch_next ();
-               printf ("\tif (GET_VFLG ()) {\n");
+               sync_m68k_pc();
+               fill_prefetch_next_noopcodecopy("\t\tif (GET_VFLG()) { ; } else opcode = regs.ir;\n");
+               printf ("\tif (GET_VFLG()) {\n");
                printf ("\t\tException_cpu(7);\n");
                printf ("\t\tgoto %s;\n", endlabelstr);
                printf ("\t}\n");
@@ -5800,20 +5850,21 @@ bccl_not68020:
                genamodedual (curi,
                        curi->smode, "srcreg", curi->size, "cnt", 1, 0,
                        curi->dmode, "dstreg", curi->size, "data", 1, GF_RMW);
-               //genamode (curi, curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
-               //genamode (curi, curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW);
-               fill_prefetch_next();
-               start_brace ();
                switch (curi->size) {
                case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
                case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
                default: term ();
                }
+               printf("\tCLEAR_CZNV();\n");
+               if (curi->size == sz_long) {
+                       fill_prefetch_next_noopcodecopy("\t\tSET_NFLG(val & 0x8000);SET_ZFLG(!(val & 0xffff));\n");
+               } else {
+                       fill_prefetch_next_noopcodecopy("\t\tSET_ZFLG(!(val & %s));SET_NFLG(val & %s);\n", bit_mask(curi->size), cmask(curi->size));
+               }
                printf ("\tuae_u32 sign = (%s & val) >> %d;\n", cmask (curi->size), bit_size (curi->size) - 1);
                printf ("\tint ccnt = cnt & 63;\n");
                printf ("\tcnt &= 63;\n");
-               printf ("\tCLEAR_CZNV ();\n");
                printf ("\tif (cnt >= %d) {\n", bit_size (curi->size));
                printf ("\t\tval = %s & (uae_u32)(0 - sign);\n", bit_mask (curi->size));
                printf ("\t\tSET_CFLG (sign);\n");
@@ -5839,19 +5890,20 @@ bccl_not68020:
                genamodedual (curi,
                        curi->smode, "srcreg", curi->size, "cnt", 1, 0,
                        curi->dmode, "dstreg", curi->size, "data", 1, GF_RMW);
-               //genamode (curi, curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
-               //genamode (curi, curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW);
-               fill_prefetch_next();
-               start_brace ();
                switch (curi->size) {
                case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
                case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
                default: term ();
                }
+               printf("\tCLEAR_CZNV();\n");
+               if (curi->size == sz_long) {
+                       fill_prefetch_next_noopcodecopy("\t\tSET_NFLG(val & 0x8000);SET_ZFLG(!(val & 0xffff));\n");
+               } else {
+                       fill_prefetch_next_noopcodecopy("\t\tSET_ZFLG(!(val & %s));SET_NFLG(val & %s);\n", bit_mask(curi->size), cmask(curi->size));
+               }
                printf ("\tint ccnt = cnt & 63;\n");
                printf ("\tcnt &= 63;\n");
-               printf ("\tCLEAR_CZNV ();\n");
                printf ("\tif (cnt >= %d) {\n", bit_size (curi->size));
                printf ("\t\tSET_VFLG (val != 0);\n");
                printf ("\t\tSET_CFLG (cnt == %d ? val & 1 : 0);\n",
@@ -5881,19 +5933,20 @@ bccl_not68020:
                genamodedual (curi,
                        curi->smode, "srcreg", curi->size, "cnt", 1, 0,
                        curi->dmode, "dstreg", curi->size, "data", 1, GF_RMW);
-               //genamode (curi, curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
-               //genamode (curi, curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW);
-               fill_prefetch_next();
-               start_brace ();
                switch (curi->size) {
                case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
                case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
                default: term ();
                }
+               printf("\tCLEAR_CZNV();\n");
+               if (curi->size == sz_long) {
+                       fill_prefetch_next_noopcodecopy("\t\tSET_NFLG(val & 0x8000);SET_ZFLG(!(val & 0xffff));\n");
+               } else {
+                       fill_prefetch_next_noopcodecopy("\t\tSET_ZFLG(!(val & %s));SET_NFLG(val & %s);\n", bit_mask(curi->size), cmask(curi->size));
+               }
                printf ("\tint ccnt = cnt & 63;\n");
                printf ("\tcnt &= 63;\n");
-               printf ("\tCLEAR_CZNV ();\n");
                printf ("\tif (cnt >= %d) {\n", bit_size (curi->size));
                printf ("\t\tSET_CFLG ((cnt == %d) & (val >> %d));\n",
                        bit_size (curi->size), bit_size (curi->size) - 1);
@@ -5916,54 +5969,56 @@ bccl_not68020:
                genamodedual (curi,
                        curi->smode, "srcreg", curi->size, "cnt", 1, 0,
                        curi->dmode, "dstreg", curi->size, "data", 1, GF_RMW);
-               //genamode (curi, curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
-               //genamode (curi, curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW);
-               fill_prefetch_next();
-               start_brace ();
                switch (curi->size) {
                case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
                case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
                default: term ();
                }
-               printf ("\tint ccnt = cnt & 63;\n");
-               printf ("\tcnt &= 63;\n");
-               printf ("\tCLEAR_CZNV ();\n");
-               printf ("\tif (cnt >= %d) {\n", bit_size (curi->size));
-               printf ("\t\tSET_CFLG (cnt == %d ? val & 1 : 0);\n", bit_size (curi->size));
-               duplicate_carry (1);
-               printf ("\t\tval = 0;\n");
-               if (source_is_imm1_8 (curi))
-                       printf ("\t} else {\n");
+               printf("\tCLEAR_CZNV();\n");
+               if (curi->size == sz_long) {
+                       fill_prefetch_next_noopcodecopy("\t\tSET_NFLG(val & 0x8000);SET_ZFLG(!(val & 0xffff));\n");
+               } else {
+                       fill_prefetch_next_noopcodecopy("\t\tSET_ZFLG(!(val & %s));SET_NFLG(val & %s);\n", bit_mask(curi->size), cmask(curi->size));
+               }
+               printf("\tint ccnt = cnt & 63;\n");
+               printf("\tcnt &= 63;\n");
+               printf("\tif (cnt >= %d) {\n", bit_size (curi->size));
+               printf("\t\tSET_CFLG (cnt == %d ? val & 1 : 0);\n", bit_size(curi->size));
+               duplicate_carry(1);
+               printf("\t\tval = 0;\n");
+               if (source_is_imm1_8(curi))
+                       printf("\t} else {\n");
                else
-                       printf ("\t} else if (cnt > 0) {\n");
-               printf ("\t\tval <<= (cnt - 1);\n");
-               printf ("\t\tSET_CFLG ((val & %s) >> %d);\n", cmask (curi->size), bit_size (curi->size) - 1);
+                       printf("\t} else if (cnt > 0) {\n");
+               printf("\t\tval <<= (cnt - 1);\n");
+               printf("\t\tSET_CFLG((val & %s) >> %d);\n", cmask(curi->size), bit_size(curi->size) - 1);
                duplicate_carry (1);
-               printf ("\t\tval <<= 1;\n");
-               printf ("\tval &= %s;\n", bit_mask (curi->size));
-               printf ("\t}\n");
-               genflags (flag_logical_noclobber, curi->size, "val", "", "");
-               shift_ce (curi->dmode, curi->size);
-               genastore ("val", curi->dmode, "dstreg", curi->size, "data");
+               printf("\t\tval <<= 1;\n");
+               printf("\tval &= %s;\n", bit_mask (curi->size));
+               printf("\t}\n");
+               genflags(flag_logical_noclobber, curi->size, "val", "", "");
+               shift_ce(curi->dmode, curi->size);
+               genastore("val", curi->dmode, "dstreg", curi->size, "data");
                break;
        case i_ROL:
                genamodedual (curi,
                        curi->smode, "srcreg", curi->size, "cnt", 1, 0,
                        curi->dmode, "dstreg", curi->size, "data", 1, GF_RMW);
-               //genamode (curi, curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
-               //genamode (curi, curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW);
-               fill_prefetch_next ();
-               start_brace ();
                switch (curi->size) {
                case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
                case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
                default: term ();
                }
+               printf("\tCLEAR_CZNV();\n");
+               if (curi->size == sz_long) {
+                       fill_prefetch_next_noopcodecopy("\t\tSET_NFLG(val & 0x8000);SET_ZFLG(!(val & 0xffff));\n");
+               } else {
+                       fill_prefetch_next_noopcodecopy("\t\tSET_ZFLG(!(val & %s));SET_NFLG(val & %s);\n", bit_mask(curi->size), cmask(curi->size));
+               }
                printf ("\tint ccnt = cnt & 63;\n");
                printf ("\tcnt &= 63;\n");
-               printf ("\tCLEAR_CZNV ();\n");
                if (source_is_imm1_8 (curi))
                        printf ("{");
                else
@@ -5984,19 +6039,20 @@ bccl_not68020:
                genamodedual (curi,
                        curi->smode, "srcreg", curi->size, "cnt", 1, 0,
                        curi->dmode, "dstreg", curi->size, "data", 1, GF_RMW);
-               //genamode (curi, curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
-               //genamode (curi, curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW);
-               fill_prefetch_next ();
-               start_brace ();
                switch (curi->size) {
                case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
                case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
                default: term ();
                }
+               printf("\tCLEAR_CZNV();\n");
+               if (curi->size == sz_long) {
+                       fill_prefetch_next_noopcodecopy("\t\tSET_NFLG(val & 0x8000);SET_ZFLG(!(val & 0xffff));\n");
+               } else {
+                       fill_prefetch_next_noopcodecopy("\t\tSET_ZFLG(!(val & %s));SET_NFLG(val & %s);\n", bit_mask(curi->size), cmask(curi->size));
+               }
                printf ("\tint ccnt = cnt & 63;\n");
                printf ("\tcnt &= 63;\n");
-               printf ("\tCLEAR_CZNV ();\n");
                if (source_is_imm1_8 (curi))
                        printf ("{");
                else
@@ -6017,19 +6073,20 @@ bccl_not68020:
                genamodedual (curi,
                        curi->smode, "srcreg", curi->size, "cnt", 1, 0,
                        curi->dmode, "dstreg", curi->size, "data", 1, GF_RMW);
-               //genamode (curi, curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
-               //genamode (curi, curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW);
-               fill_prefetch_next ();
-               start_brace ();
                switch (curi->size) {
                case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
                case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
                default: term ();
                }
+               printf("\tCLEAR_CZNV();\n");
+               if (curi->size == sz_long) {
+                       fill_prefetch_next_noopcodecopy("\t\tSET_NFLG(val & 0x8000);SET_ZFLG(!(val & 0xffff));SET_CFLG(GET_XFLG());\n");
+               } else {
+                       fill_prefetch_next_noopcodecopy("\t\tSET_ZFLG(!(val & %s));SET_NFLG(val & %s);SET_CFLG(GET_XFLG());\n", bit_mask(curi->size), cmask(curi->size));
+               }
                printf ("\tint ccnt = cnt & 63;\n");
                printf ("\tcnt &= 63;\n");
-               printf ("\tCLEAR_CZNV ();\n");
                if (source_is_imm1_8 (curi))
                        printf ("{");
                else {
@@ -6053,19 +6110,20 @@ bccl_not68020:
                genamodedual (curi,
                        curi->smode, "srcreg", curi->size, "cnt", 1, 0,
                        curi->dmode, "dstreg", curi->size, "data", 1, GF_RMW);
-               //genamode (curi, curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
-               //genamode (curi, curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW);
-               fill_prefetch_next ();
-               start_brace ();
                switch (curi->size) {
                case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
                case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
                default: term ();
                }
+               printf("\tCLEAR_CZNV ();\n");
+               if (curi->size == sz_long) {
+                       fill_prefetch_next_noopcodecopy("\t\tSET_NFLG(val & 0x8000);SET_ZFLG(!(val & 0xffff));SET_CFLG(GET_XFLG());\n");
+               } else {
+                       fill_prefetch_next_noopcodecopy("\t\tSET_ZFLG(!(val & %s));SET_NFLG(val & %s);SET_CFLG(GET_XFLG());\n", bit_mask(curi->size), cmask(curi->size));
+               }
                printf ("\tint ccnt = cnt & 63;\n");
                printf ("\tcnt &= 63;\n");
-               printf ("\tCLEAR_CZNV ();\n");
                if (source_is_imm1_8 (curi))
                        printf ("{");
                else {
@@ -6090,14 +6148,13 @@ bccl_not68020:
                break;
        case i_ASRW:
                genamode (curi, curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW);
-               fill_prefetch_next ();
-               start_brace ();
                switch (curi->size) {
                case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
                case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
                default: term ();
                }
+               fill_prefetch_next_noopcodecopy("\t\tCLEAR_CZNV();SET_CFLG(val & 1);SET_ZFLG(!(val >> 1));SET_NFLG(val & 0x8000);SET_XFLG(GET_CFLG());\n");
                printf ("\tuae_u32 sign = %s & val;\n", cmask (curi->size));
                printf ("\tuae_u32 cflg = val & 1;\n");
                printf ("\tval = (val >> 1) | sign;\n");
@@ -6108,14 +6165,13 @@ bccl_not68020:
                break;
        case i_ASLW:
                genamode (curi, curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW);
-               fill_prefetch_next ();
-               start_brace ();
                switch (curi->size) {
                case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
                case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
                default: term ();
                }
+               fill_prefetch_next_noopcodecopy("\t\tCLEAR_CZNV();SET_CFLG(val & %s);SET_ZFLG(!((val << 1) & 0x7fff));SET_NFLG(val & 0x4000);SET_XFLG(GET_CFLG());SET_VFLG((val & 0x8000) != ((val << 1) & 0x8000));\n", cmask(curi->size));
                printf ("\tuae_u32 sign = %s & val;\n", cmask (curi->size));
                printf ("\tuae_u32 sign2;\n");
                printf ("\tval <<= 1;\n");
@@ -6128,14 +6184,13 @@ bccl_not68020:
                break;
        case i_LSRW:
                genamode (curi, curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW);
-               fill_prefetch_next ();
-               start_brace ();
                switch (curi->size) {
                case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
                case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
                default: term ();
                }
+               fill_prefetch_next_noopcodecopy("\t\tCLEAR_CZNV();SET_CFLG(val & 1);SET_ZFLG(!(val >> 1));SET_NFLG(0);SET_XFLG(GET_CFLG());\n");
                printf ("\tuae_u32 carry = val & 1;\n");
                printf ("\tval >>= 1;\n");
                genflags (flag_logical, curi->size, "val", "", "");
@@ -6145,14 +6200,13 @@ bccl_not68020:
                break;
        case i_LSLW:
                genamode (curi, curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW);
-               fill_prefetch_next ();
-               start_brace ();
                switch (curi->size) {
                case sz_byte: printf ("\tuae_u8 val = data;\n"); break;
                case sz_word: printf ("\tuae_u16 val = data;\n"); break;
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
                default: term ();
                }
+               fill_prefetch_next_noopcodecopy("\t\tCLEAR_CZNV();SET_CFLG(val & %s);SET_ZFLG(!(val << 1));SET_NFLG(val & 0x4000);SET_XFLG(GET_CFLG());\n", cmask(curi->size));
                printf ("\tuae_u32 carry = val & %s;\n", cmask (curi->size));
                printf ("\tval <<= 1;\n");
                genflags (flag_logical, curi->size, "val", "", "");
@@ -6162,14 +6216,13 @@ bccl_not68020:
                break;
        case i_ROLW:
                genamode (curi, curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW);
-               fill_prefetch_next ();
-               start_brace ();
                switch (curi->size) {
                case sz_byte: printf ("\tuae_u8 val = data;\n"); break;
                case sz_word: printf ("\tuae_u16 val = data;\n"); break;
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
                default: term ();
                }
+               fill_prefetch_next_noopcodecopy("\t\tCLEAR_CZNV();SET_CFLG(val & %s);SET_ZFLG(!val);SET_NFLG(val & 0x4000);\n", cmask(curi->size));
                printf ("\tuae_u32 carry = val & %s;\n", cmask (curi->size));
                printf ("\tval <<= 1;\n");
                printf ("\tif (carry)  val |= 1;\n");
@@ -6179,14 +6232,13 @@ bccl_not68020:
                break;
        case i_RORW:
                genamode (curi, curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW);
-               fill_prefetch_next ();
-               start_brace ();
                switch (curi->size) {
                case sz_byte: printf ("\tuae_u8 val = data;\n"); break;
                case sz_word: printf ("\tuae_u16 val = data;\n"); break;
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
                default: term ();
                }
+               fill_prefetch_next_noopcodecopy("\t\tCLEAR_CZNV();SET_CFLG(val & 1);SET_ZFLG(!val);SET_NFLG(val & 0x0001);\n");
                printf ("\tuae_u32 carry = val & 1;\n");
                printf ("\tval >>= 1;\n");
                printf ("\tif (carry) val |= %s;\n", cmask (curi->size));
@@ -6196,14 +6248,13 @@ bccl_not68020:
                break;
        case i_ROXLW:
                genamode (curi, curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW);
-               fill_prefetch_next ();
-               start_brace ();
                switch (curi->size) {
                case sz_byte: printf ("\tuae_u8 val = data;\n"); break;
                case sz_word: printf ("\tuae_u16 val = data;\n"); break;
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
                default: term ();
                }
+               fill_prefetch_next_noopcodecopy("\t\tCLEAR_CZNV();SET_CFLG(val & 0x8000);SET_ZFLG(!((val << 1) | GET_XFLG()));SET_NFLG(val & 0x4000);SET_XFLG(GET_CFLG());\n", cmask(curi->size));
                printf ("\tuae_u32 carry = val & %s;\n", cmask (curi->size));
                printf ("\tval <<= 1;\n");
                printf ("\tif (GET_XFLG ()) val |= 1;\n");
@@ -6214,14 +6265,13 @@ bccl_not68020:
                break;
        case i_ROXRW:
                genamode (curi, curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW);
-               fill_prefetch_next ();
-               start_brace ();
                switch (curi->size) {
                case sz_byte: printf ("\tuae_u8 val = data;\n"); break;
                case sz_word: printf ("\tuae_u16 val = data;\n"); break;
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
                default: term ();
                }
+               fill_prefetch_next_noopcodecopy("\t\tCLEAR_CZNV();SET_CFLG(val & 1);SET_ZFLG(!((val >> 1) | GET_XFLG()));SET_NFLG(GET_XFLG());SET_XFLG(GET_CFLG());\n", cmask(curi->size));
                printf ("\tuae_u32 carry = val & 1;\n");
                printf ("\tval >>= 1;\n");
                printf ("\tif (GET_XFLG ()) val |= %s;\n", cmask (curi->size));